Bind SSL certificate to a port number -- Nginx - nginx

Sorry for the limited understanding of Nginx and SSL. I have a React and Django app deployed on a server running on Nginx.
The React app is accessible using "example.org"(name is faked for demo purpose) and for the Django app, I have configured it to be accessible with port 3000 ie "example.org:3000".
The domain has SSL certificates installed and certificates are seen in "example.org" but while accessing "example.org:3000", the certificates are not available to this port.
I have been trying to allow ssl certificates to the port as well but couldnt succeed. I changed nginx conf file with listen 3000 ssl without success.
Please help, is there a way or should we need to modify the ssl certificates?
Nginx config at the moment is:
server {
listen 80 default_server;
server_name example.org;
return 301 https://example.org;
}
server {
listen 443 ssl;
server_name example.org;
ssl_certificate /etc/nginx/ssl/ssl_bundle.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
root /home/ubuntu/example/build;
index index.html index.htm;
}
}

The Port has nothing to do with the certs OR TLS Termination in general. IN case my assumptions are correct and your Django app is exposing its port 3000 by itself you need a proxy configuration that terminates the TLS for you.
server {
listen 8080 ssl;
server_name example.org;
ssl_certificate /etc/nginx/ssl/ssl_bundle.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
.....
}
}
This will terminate the TLS Session for you on Port 8080 and forwards the traffic to your Django app. There are other, more advanced options, proxying traffic to your appserver but this one will do it.
Note: In case you want to proxy the traffic through NGINX make sure Port 3000 is not exposed to the public anymore.

Related

How CDN knows which Edge sever should it redirect the client to?

I'm trying to learn more about how CDN works. How does it knows which Edge sever should it redirect the client to for lowest latency? Thank you.
For this purpose, Upstream configuration is used in Nginx webserver.
nginx redirect users's requests to the destination server.
sample of Nginx upstream is as bellow.
upstream example.com {
server example.com;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
access_log /var/log/nginx/access.log custom;
location / {
proxy_pass http://example.com;
}

Nginx - Upstream Configuration Issue

I noticed something on an nginx config. There are 2 upstream blocks configured that are exactly the same:
upstream test1.example.com {
server flaskapp.example.com:5000
}
server {
listen 443 ssl;
proxy_pass test1.example.com;
ssl_certificate /opt/certs/example1.com.crt;
ssl_certificate_key /opt/example1.com.key;
ssl_protocols TLSv1.2;
ssl ciphers "ECDHE-ECDSA-AES128-GCM-SHA256"
}
upstream test2.example.com {
server flaskapp.example.com:5000
}
server {
listen 443 ssl;
proxy_pass test2.test.com;
ssl_certificate /opt/certs/test.com.crt;
ssl_certificate_key /opt/test.com.key;
ssl_protocols TLSv1.2;
ssl ciphers "ECDHE-ECDSA-AES128-GCM-SHA256"
}
I have 2 server blocks listening on port 443. So I have the same server listening for 2 separate connections on the same block... if that makes sense.
My thought was that this would fail because the same server listening for incoming https connections to test1 and test2.example.com wouldn't know 'where' to route the requests too. But that's not what's happening.
If I go to https://test1.example.com I am routed to the correct app. And https works as expected.
If I go to https://test2.example.com I am routed to the correct app. But https does not work as expected. This is confusing because both certs are wildcard certs. I am unsure why 1 succeeded and one failed.
If I comment out the first upstream block:
# upstream test1.example.com { server flaskapp.example.com:5000 }
# server {proxy_pass test1.example.com; }
Something stranger happens. Connecting to https://test2.test.com gives me a 'failed to connect to server' error message in my web browser. And the logs show this as the error:
No "ssl_certificate" is defined in server listening on SSL port while SSL handshaking
This is for test1.example.com, and I know the wildcard cert works. I'm using it elsewhere. So I'm unsure why I'm getting a 'failed to connect to server' error when I go to test1.example.com in this manner.
A few things to note:
Both test1.example.com and test2.test.com point to the same nginx server.
If both upstream/server blocks are working then test1.example.com shows the site is ssl secure. That is expected. But test2.test.com shows the website is insecure. This leads me to believe that only the first server/upstream block is working as expected. And the 2nd server/upstream block is being ignored.
actually does make sense, in that a server shouldn't be listening for incoming connections to the same port, and route to different servers. The proxy doesn't know what to do with 1 of the connections (bad explanation on my part).
But that doesn't explain why the 2nd server/upstream block would outright fail. Even when test2.example.com is the only server/upstream block configured.
Any advice is appreciate, thank you for your time and consideration. This is something I've been struggling to understand and make heads/tails of.
bossrhino
I think you need to use server_name directive. Because your web server listens on same ip and the same port for two subdomains.
I guess this config file should work properly:
upstream test1.example.com {
server flaskapp.example.com:5000
}
server {
listen 443 ssl;
server_name test1.example.com;
proxy_pass test1.example.com;
ssl_certificate /opt/certs/example1.com.crt;
ssl_certificate_key /opt/example1.com.key;
ssl_protocols TLSv1.2;
ssl ciphers "ECDHE-ECDSA-AES128-GCM-SHA256"
}
upstream test2.example.com {
server flaskapp.example.com:5000
}
server {
listen 443 ssl;
server_name test2.example.com;
proxy_pass test2.test.com;
ssl_certificate /opt/certs/test.com.crt;
ssl_certificate_key /opt/test.com.key;
ssl_protocols TLSv1.2;
ssl ciphers "ECDHE-ECDSA-AES128-GCM-SHA256"
}

S3 virtual-host style nginx configuration for subdomains

I am trying to get a min.io server up and running with virtual-host style and am failing to configure nginx to do so correctly.
Expected result
bucket.s3.domain.com works to access bucket
Actual result
bucket.s3.domain.com is redirected to s3.domain.com/bucket – this does not generate virtual host style URLs.
My config (I omitted default port 80 to 443 redirect and other not relevant docker containers):
http {
upstream minio-s3 {
server 127.0.0.1:9000;
}
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/s3.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/s3.domain.com/privkey.pem;
server_name s3.domain.com;
location / {
proxy_pass http://minio-s3;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/s3.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/s3.domain.com/privkey.pem;
server_name "~^(?<subdomain>[^.]+).s3.domain.com";
location / {
proxy_pass http://127.0.0.1/$subdomain$request_uri;
proxy_set_header Host s3.domain.com;
}
}
Notes
Nginx running on Ubuntu Server LTS 20.04 (no Docker)
Min.io running on Docker port 9000
MINIO_DOMAIN is correctly set to s3.domain.com
bucket subdomain is correctly set
wildcard certificate for *.s3.domain.com is configured
Questions
How can I configure Min.io (besides passing env MINIO_DOMAIN) to use virtual host style URLs together with nginx?
How can I set up nginx to support this case?
So the answer to my original question is pretty simple:
Only one server block is needed, the subdomain regex is added to the server name and min.io resolves this correctly
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/s3.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/s3.domain.com/privkey.pem;
server_name "~^(?<subdomain>[^.]+).s3.domain.com" s3.domain.com;
location / {
proxy_pass http://minio-s3;
I hope this helps someone struggling with the same.
Virtual host in in short with Min.io:
Register domain, subdomain (per bucket)
Point domains all to your server (CNAME etc.)
Generate certificates with certbot (domain, wildcard for subdomains)
Launch min.io passing MINIO_DOMAIN as environment variable
Point all domains to Min.io application (domain and subdomains)

SSL certificate returned for multiple server blocks

I have an nginx configuration with multiple virtual hosts and subdomains. Each subdomain needs to have a different SSL certificate bound. Here is the configuration for my first subdomain:
server {
listen 443;
server_name a.website.com;
ssl on;
ssl_certificate /etc/nginx/ssl/a/a.crt;
ssl_certificate_key /etc/nginx/ssl/a/a.rsa;
.....
The configuration for my second:
server {
listen 443;
listen 3443;
server_name b.website.com;
ssl on;
ssl_certificate /etc/nginx/ssl/b/b.crt;
ssl_certificate_key /etc/nginx/ssl/b/b.key;
....
The problem is if I go to b.website.com, the SSL certificate for both a.website.com and b.website.com are returned when I expect only b.website.com to be bound. I validated this using ssllabs.
Any advice?
I didn't notice that in ssllabs the second certificate was only returned if SNI wasn't enabled which makes sense because both certs are on the same IP. Apparently the integration we're working with doesn't support SNI (crazy I know) so I guess I have to spin up another server.

https works for local IP address but not for local IP with application port

I have Mattermost installed in my server, currently I can login to it by browsing through http://192.168.x.x:8066, I've installed a self-signed cerrtificate for this IP, but when I tried to browse it with https://192.168.x.x:8065, it failed to redirect to the Mattermost page.
Below is the configuration of my nginx.conf:
server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
listen 443;
server_name 192.168.3.201:8066;
ssl on;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
}
However, when I just browse the URL without port 8066 , it displays the default nginx page with no errors.
What's wrong with my nginx.conf file? I'm still new to nginx FYI.
Any suggestions will be very much appreciated.
I suggest you follow the example nginx configuration from the documentation here. Start with that config file, updating server_name to be the domain name you want mattermost to be reachable from, and server to be the IP address and port on which mattermost is listening.
Once you've got that working, you can continue through the instructions to #9 which covers setting up SSL.

Resources