nginx: decrypting a query param - nginx

I have 2 servers. Server A is a Windows server running ASP.NET, and server B is a Linux server running Nginx. I need to redirect a user from Server A to Server B securely. I would like to have Server A encrypt a value like ip=132.65.78.4;user=xyz#example.com;node=abc into a query parameter of a redirect like this: https://serverb.example.com?encrypted=<encrypted value here>
Then have Server B (using a shared secret) decrypt the query param, validate the IP address the user is coming from, and then trust the values of user and node to process the request.
How can I configure nginx to do this? I can figure out the Server A part myself based on the answer. Thank you!

I would recommend making use of the "nginx lua" module, which will let you modify portions of the request with Lua code.
There are facilities in there to specifically modify the query string, so you can perform your encryption and set the "encrypted" value.
https://github.com/openresty/lua-nginx-module#ngxreqset_uri_args
In the case where you want to process request arguments, you can do this via a set_by_lua_block or set_by_lua_file
So perhaps you might do something like:
set_by_lua_block $validated {
local enc = ngx.var.arg_encrypted
local decrypted = decrypt(enc)
return do_some_validation(decrypted) and "1" or "0"
}
if ($validated = "0") {
return 403;
}

Related

Connect to mqtt.googleapis.com:8883 via proxy and another domain

For some reasons our infra blocks mqtt.googleapis.com. That's why was deployed nginx proxy with such configuration
stream {
upstream google_mqtt {
server mgtt.googleapis.com:8883;
}
server {
listen 8883;
proxy_pass google_mqtt;
}
}
Also it has external IP with domain name fake.mqtt.com
Using example here I'm testing connectivity.
If script to run against mgtt.googleapis.com:8883 everything works fine.
But if domain switch to fake.mqtt.com got an error:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'fake.mqtt.com'
For client implementation was used paho.mqtt.client.
Auth to mqtt broker realized with JWT.
def create_jwt(project_id, private_key_file, algorithm):
token = {
# The time that the token was issued at
"iat": datetime.datetime.utcnow(),
# The time the token expires.
"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=20),
# The audience field should always be set to the GCP project id.
"aud": project_id,
}
# Read the private key file.
with open(private_key_file, "r") as f:
private_key = f.read()
print(
"Creating JWT using {} from private key file {}".format(
algorithm, private_key_file
)
)
return jwt.encode(token, private_key, algorithm=algorithm)
Set JWT
client.username_pw_set(
username='unused',
password=create_jwt(project_id, private_key_file, algorithm))
TLS configuration:
client.tls_set(ca_certs='roots.pem', tls_version=ssl.PROTOCOL_TLSv1_2,)
Could you advise what to configure on nginx/paho-client side and is it working solution at all?
Or may be 3party brokers can connect to mqtt.googleapis.com? (from information i read here and on another resources - no)
You can not just arbitrarily change the domain name if you are just stream proxying, it needs to match the one presented in the certificate by the remote broker or as you have seen it will not validate.
You can force the client to not validate the server name by setting client.tls_insecure_set(True) but this is a VERY bad idea and should only be used for testing and never in production.

how-to create an insecure jupyter server

Jupyter only allows access from localhost unless I do a bunch of extra security stuff. I am running my server so that it is only accessible on a local network where anyone with access is equal in trustworthiness to localhost. How do I set up a jupyter notebook server with no extra security features?
Based on your question, I expect you want this configuration (in ~/.jupyter/jupyter_notebook_config.py):
c.NotebookApp.ip = '0.0.0.0' # listen on all IPs
c.NotebookApp.token = '' # disable authentication
There are a few security features in Jupyter (as of 4.3.1). I'll go over how to disable each one, and whether/when it makes sense to disable it:
It listens only on localhost. This can be changed to all public IP addresses:
c.NotebookApp.ip = '0.0.0.0'
Listening on public IPs should generally come with enabling HTTPS and/or password or token authentication (docs). If it's all internal on a trusted network where nothing bad ever happens, you can proceed to disable other security features:
Token authentication is enabled by default. To disable it:
c.NotebookApp.token = ''
Disabling authentication means that anyone with access to the host can run code. It seems like this is what you want. You can also enable a password:
In [1]: from notebook.auth import passwd
In [2]: passwd()
Enter password:
Verify password:
Out[2]: 'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed'
You can store this in c.NotebookApp.password.
You can also store this password in (~/.jupyter/jupyter_notebook_config.json):
{
"NotebookApp": {
"password": "sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed"
}
}
Jupyter also has CORS protections, to avoid other websites from being able to access this server. This means that when a user on your network visits example.com, javascript on that page cannot execute code on your notebook server. It sounds like you don't want to touch this, but if you are running a service that should be able to access the notebook server, you can add it to:
c.NotebookApp.allow_origin = 'https://your.other.host'
Finally, Jupyter 4.3.1 introduces an xsrf token, which is part of dealing with the same category of cross-site execution above. You don't need to touch this if users are only accessing the server directly, rather than through javascript on additional websites.
c.NotebookApp.disable_check_xsrf = True
A completely insecure notebook server, which is to say one where any website can run code on it, as long as a browser can connect to its host (this would include localhost or LAN if the browser is running from inside the LAN):
c.NotebookApp.ip = '0.0.0.0' # listen on all IPs
c.NotebookApp.token = '' # disable authentication
c.NotebookApp.allow_origin = '*' # allow access from anywhere
c.NotebookApp.disable_check_xsrf = True # allow cross-site requests
This might be desirable if you are aiming to make compute resources free for the world to use however they want via the notebook API.

Deny access if the client is using a different SSL certificate

I have scoured this forum the best I could but found no plausible answer, google was no help either.
I have a FLEX 3 application using AMFPHP over HTTPS (Flex RemoteObject). I would like to prevent the client from making any HTTPS requests if the browser client SSL cert is not the one provided by my server, thus making it more difficult for Charles, Burp, etc. to read the data going to the server by proxying the connection.
When someone uses one of these proxy server there is a certificate error as i.e. Charles provides its own cert to the browser and makes the HTTPS connection to the server as a normal client, so on the server end there is no difference.
Is there any way to only allow connections if my cert is the one being used at the client?
Using SecureSockets (needed to upgrade to SDK 4.6) I was able to check the validity of the SSL certificate the browser was using.
The default behavior is that any incorrect cert (analog to the browser cert warning) will cause SecureSockets to fail. This makes creating a check very easy using the sample code in the Adobe documentation:
private var secureSocket:SecureSocket = new SecureSocket();
public function SecureSocketExample()
{
secureSocket.addEventListener( Event.CONNECT, onConnect )
secureSocket.addEventListener( IOErrorEvent.IO_ERROR, onError );
try
{
secureSocket.connect( "ip address here", 443 );
}
catch ( error:Error )
{
trace ( error.toString() );
}
}
Doc is here
Adding this to the creationComplete listener is enough to make sure the user hasn't followed an insecure cert or man in the middle. The rest of the application's communication can occur over "normal" SSL AMF channel.
One generic approach could be to use Strict Transport Security

ASP.NET website problem while requesting XML data from remote server

I am writing code in asp.net to get XML data from external webserver.
*.cs Code
connection string: URL of external(third party) server for XML data
WebRequest req = WebRequest.Create(connectionString);
req.Proxy = WebProxy.GetDefaultProxy();
req.Proxy.Credentials = CredentialCache.DefaultCredentials;
req.Timeout = 1000;
using (WebResponse resp = req.GetResponse())
{
// reading data from XML file
}
Key Point
1. GetDefaultProxy() return information about proxy
2. Default Credentials() return username password which i have written in web.config as shown below
Web.config
<identity impersonate="true"
username="Username of PC where website is running"
password="password"/>
Problem Statement:
After installing website setup : Above code working fine at WindowsXP but the same code doesn't work at Windows server 2003. I am not able to find out what extra we need to configure in Windows Server 2003.
Please help me to find out the solution?
[EDIT]
Very random beheviour is observed at server. Sometimes the data comes and appear at client(browser) when we logged into windows server 2003.
But when we loggedout from server and try to request for data from client(browser) at another PC. It appear for very short duration. After say wait of 1 hour the data doesn't comes for new request.
An error message might be useful??
But at a guess I'd say it's that the proxy isn't configured on the 2003 server.
Check the firewall on Windows Server 2003 and make sure port 80 outbound is allowed (assuming that is the port used by the web service).
This might help. It's about proxy and .NET app.

How to allow secure login across multiple domains

I have a web based application that allows a user to point their DNS at my IP and my app will serve up their content based on the domain name I see in the HTTP host header. I should point out this is done by the application, not by the actual HTTP server(apache), it is a rebranded app sort of thing. The problem I have is that I would like the users to be able to login through a form on the served page and somehow stay within the domain of the user. This is easy, unless you want security. I would have to have a SSL cert installed for every domain to pull this off. Right now I can do it by submitting the form to a domain with an SSL cert installed, but due to browser security I can't exactly set the required cookies on the original domain.
Does anyone know a way I can securely log in users through the app that does not involve installing a lot of ssl certs. I can think of some convoluted ways using redirects or other mechanisms, but it is not that clean. I don't mind a submit to the secure url and a redirect, it's just setting the cookie can't be done.
I've done this before using the following method...
Create auth key on server 1.
create_auth_key
expires = time + expire_time
data = username + '|' + password + expires
secret = 'my secret key'
hash = md5( data + secret )
key = base64( data ) + hash
On server two you pass the newly created authkey
valid_auth_key(key)
hash = key[-hash_size:]
b64data = key[:-hash_size]
data = base64decode( b64data )
data_hash = md5( data + secret )
if data_hash != hash:
return false # invalid hash
data_parts = data.split('|')
user = data_parts[0]
password = data_parts[1]
expires = data_parts[2]
if now > expires:
return false # url expired
return true
It's kind of quick and dirty but only relies on simple data passed via URL. The down side is that a specific url is all that's required to login and someone could share that url for a period of time. You also have to make sure your expiration time is not greater than the time difference between servers.
A common trick is to pass data in the URL. Facebook Connect does this. You can redirect from one domain to the other with a session token in the URL and then verify the token (perhaps convert to a cookie) when the request comes in on the other domain. Edit: the MSDN article that Facebook links to has much more detail.

Resources