NGNIX reverse proxy with client certificate - nginx

I have front end serverA and back end serverB. the actual application is hosted on serverB. When the client makes call to API, serverB will have to authenticate using client certificate that is sent by client.
We have installed Ngnix in serverA to proxy_pass the traffic received from clients to serverB.
when the client make call to serverA with client certificate, the client certificate is not sent by Ngnix to serverB and due to this serverB reject the request from client.
Is there any way we can redirect the request to serverB along with client certificate that is originally sent by clients?
Below is my Ngnix configuration.
If Ngnix is not capable of doing this, is there any other opensource tool avaialable with this functionality?
server {
listen 443 ssl;
server_name localhost;
ssl_certificate cert.pem;
ssl_certificate_key cert.pem;
ssl on;
location / {
root html;
index index.html index.htm;
proxy_pass "https://localhost:8099";
}
}

Sorry, maybe late for that, but hope it helps.
You can proxy requests with client certificate by sending the variable $ssl_client_cert in a request header when proxying to the back end serverB.

Related

Signalr running behind Nginx reverse proxy

I have really no knowledge on how to configure signalr of back-end server on Nginx box. I did lot of googling tried those but did not work so any information/help would be greatly welcomed.
Nginx server : https://20.20.20.20/
Backend server : http://10.10.10.10/
I have configured Nginx as reverse proxy on windows server 2012. I have configured my back-end server on Nginx server using the below mentioned configuration file.
So my proxy is working absolutely fine. Whenever client hits the Nginx it redirects call to the backend server.
The problem currently that I am facing is my client wants to connect to the backend server for signalr communication. The client(mobile app) uses login server details to connect the signalr, in the normal workflow the login server and signalr both are same but incase of reverse proxy the login server is actually Nginx so it is trying to connect to Nginx and failing to connect.
Are there any setting that we can make at Nginx to pass through signalr calls made by client.
My configuration below
server {
listen 443 ssl;
server_name localhost;
ssl_certificate "E:/Cer15/nginx.crt";
ssl_certificate_key "E:/Cer15/nginx.key";
location / {
root html;
index index.html index.htm;
proxy_pass http://10.10.10.10/mywebservice;
}
}
Thanks,
Vinod

Nginx subdomain routing during DNS propagation when switching data center

I have three servers: One serving data through an API with IP address 11.111.11.11, one serving static resources with IP address 22.222.22.22 and one Nginx reverse proxy with IP address 33.333.33.33 routing data to the other two.
I have 3 type A DNS records for example.com, www.example.com and api.example.com all pointing to the Nginx server with IP address 33.333.33.33. It then redirects the requests either to itself or to one of the other two servers depending on the protocol and subdomain in the request. The Nginx server blocks look like this:
# Redirect static request to HTTPS with no subdomain
server {
listen 80 default_server;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
# Redirect API request to HTTPS
server {
listen 80;
server_name api.example.com;
return 301 https://api.example.com$request_uri;
}
# Redirect API request to same without subdomain
server {
listen 443 ssl;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
# Route to static server
server {
listen 443 ssl;
server_name example.com;
### SSL conf...
location / {
proxy_pass http://22.222.22.22:8080;
}
}
# Route to API server
server {
listen 443 ssl;
server_name api.example.com;
### SSL conf...
location / {
proxy_pass http://11.111.11.11:8080;
}
}
Pretty basic stuff.
Now I have been for forced to switch data center. I now have a copy of the exact same setup at the new data center, but the IP addresses are now instead 44.444.44.44, 55.555.55.55 and 66.666.66.66.
Now comes the tricky part. I now want to update the DNS records (which can take up to 24h) to all point to the Nginx server with IP address 66.666.66.66 in the new data center without downtime.
To enable this I'm thinking of changing the configuration of the old Nginx server so that it routes all traffic to the new Nginx server. However, this will (probably) not work, since the routing is done using the request subdomains, and that information is lost in the redirect. I am unable to route traffic from the old Nginx server to the new API and static servers, since the servers talk to each other over a private network. The traffic also has to keep its encryption when on the internet, and can only be sent decrypted within the same data center.
How can I do this data center switch, while having no down time during the DNS propagation?

client authentication when using nginx proxy_pass

My question is about nginx directive "proxy_pass".
I have an http server and I need to redirect requests using https.
I'm using the following statement:
proxy_pass https://secure.server
In wireshark I see that there is a SSL handshake, but client (nginx proxy_pass https:) did not send certificate on server's SSL certificate request.
Verifying client certificate is necessary by server. How can I force proxy_pass to send client certificate when using https ?
Below is part of nginx.conf configuration file:
server {
listen 8888;
server_name _;
error_page 405 =200 $uri;
ssl_certificate /usr/local/cert.pem;
ssl_certificate_key /usr/local/cert.pem
ssl_client_certificate /usr/local/ca.cer;
location ~ /uri/(.+) {
proxy_pass https://secure.server;
break;
}
}
You need to enable SSL client certificate verification.
Add this under the other SSL configurations:
ssl_verify_client on;
See more information here.
I'm looking for the same solution as well.
I found SEnginx, which has a module called "Proxy HTTPS Client Certificate". From the description it seems that is should allow for client certificates, but I could not get it to work for me. The backend server simply would not prompt the client for a certificate.
Following is the link to SEnginx.
Also: Here is a possible explanation as to why this might not be possible.
During ssl handshake, the server will send "client certificate ca names". (ie) The server will accept the client certificates only from those CAs. Client will send send client certificate only if it has a cert signed by those CA.
So in your case, verify
1. The CA names send by server for client cert request. This will be the CAs you have configured in the truststore of the server. (ie) During ssl handshake look for CertificateRequest message
Make sure you client cert is signed by one of those CA
Best option is to verify with curl, both your client and server certificates are configured properly
curl -vvv --cert /usr/local/cert.pem https://secure.server
If you are not able to figure out with the curl output, please paste the curl output

How to configure nginx to proxy another service serving http and https on different ports?

Use case:
Using nginx as a frontend for several websites / services running on both 80 and 443 (several virtual hosts).
Having service x running on localhost that serves http:8090 and https:8099
How do I need to configure nginx so people can access using only the name, without specifying the port.
This a fairly normal setup. Configure the hosts served directly on Nginx as normal. Since they need to listen on both 80 and 443, each host entry would have this in it:
server {
listen 80;
listen 443 ssl;
}
The Nginx SSL docs has the full details.
Then proxy traffic for one server{} definition to the backend service:
server {
server_name example.com;
location / { proxy_pass http://127.0.0.1:8090; }
}
You only need one proxy connection to the backend server, either 'http' or 'https'. If the connection between the two servers is secure, you can 'http', even for connections that arrive to nginx over https. This might be appropriate if the service is on the same machine. Otherwise, all the traffic could be proxied through https if the connection between nginx and the backend server needs to be secured.
We use the following with our host:
http {
server {
server_name ~^(www\.)?(?<domain>.+)$;
listen *:80;
location / {
proxy_pass $scheme://<origin>$uri$is_args$args;
include basic-proxy-settings.conf;
}
}
server {
server_name ~^(www\.)?(?<domain>.+)$;
listen *:443 ssl;
location / {
proxy_pass $scheme://<origin>$uri$is_args$args;
include basic-proxy-settings.conf;
}
include ssl-settings.conf;
}
}
This allows our upstream proxy to talk to our origin server over HTTP when a request is made by a client for an insecure resource, and over SSL/HTTPS when a request is made for a secure one. It also allows our origin servers to be in charge of forcing redirects to secure connections, etc.
Next time, why not provide a code sample detailing what you've tried, what has worked, and what hasn't?

Is there a way to have nginx route ssl requests to 443 to two different apps?

I need to set up nginx so that requests via SSL to port 443 are routed to Rails Application A or Application B (say a PHP app) depending on the request path. Is this even possible to configure?
Yes, it is possible and depends on how is your backend applications handled. You need to use location to match request path and route request to appropriate backend with proxy_pass, fastcgi_pass etc.
Example:
server {
listen 443;
ssl on;
location /appa/ {
proxy_pass http://appa_backend/;
}
location /appb/ {
proxy_pass http://appb_backend/;
}
}

Resources