Why Nginx may pass incorrect ssl sertificate? - nginx

I've got two domains hosted per single nginx server, ex. a.com and b.com. Nginx used as reverse proxy and must pass https requests to backend as http. You can find bellow my config for a.com (b.com has the same structure but linked to another ssl files):
upstream webservers {
....
}
server {
listen 443 ssl;
server_name a.com;
ssl_certificate /etc/nginx/ssl/a.crt;
ssl_certificate_key /etc/nginx/ssl/a.key;
ssl_dhparam /etc/nginx/ssl/default.dh;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://webservers;
}
}
Unfortunately, when I test curl https://b.com it fails with curl: (60) SSL: no alternative certificate subject name matches target host name b.com. When I try to open it from browser it fails with NET::ERR_CERT_COMMON_NAME_INVALID and it shows that it use a.com certificate.
Where is my mistake?
Upd#1
I have to allow HTTP to solve issue temporary.
openssl s_client -connect b.com:443 -prexit
140648924489024:error:2008F002:BIO routines:BIO_lookup_ex:system lib:../crypto/bio/b_addr.c:726:Name or service not known
connect:errno=22
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
Configurations:
# configuration file /etc/nginx/sites-enabled/a.com:
upstream a-webservers {
server 192.168.0.252 max_fails=3 fail_timeout=30s;
server 192.168.0.252 max_fails=3 fail_timeout=30s;
}
server {
listen 443 ssl;
server_name a.com;
error_log /var/log/nginx/a.com-error.log;
access_log off;
ssl_certificate /etc/nginx/ssl/a.crt;
ssl_certificate_key /etc/nginx/ssl/a.key;
ssl_dhparam /etc/nginx/ssl/default.dh;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://a-webservers;
}
}
# configuration file /etc/nginx/sites-enabled/b.com:
upstream b-webservers {
server 192.168.0.252 max_fails=3 fail_timeout=30s;
server 192.168.0.252 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
listen 443 ssl;
server_name b.com;
error_log /var/log/nginx/b.com-error.log;
access_log off;
ssl_certificate /etc/nginx/ssl/b.crt;
ssl_certificate_key /etc/nginx/ssl/b.key;
ssl_dhparam /etc/nginx/ssl/default.dh;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://b-webservers;
}
}

Related

nginx: [emerg] host not found in upstream with local IPs

I've read similar questions with same error, but nothing matches my problem, because my upstream servers have local IPs.
The server is a proxmox machine with some different vms.
One is for nginx reverse gateway/proxy, the other are vms with several docker containers.
I want to setup a fallback (backup) for one container.
The config of the nginx reverse gateway/proxy containing these machines is:
server {
listen 80;
server_name my-web.page;
return 301 http://www.my-web.page$request_uri;
}
server {
listen 80;
listen [::]:80;
server_name www.my-web.page;
location / {
return 301 https://www.my-web.page$request_uri;
}
}
server {
listen 443 ssl;
server_name my-web.page;
return 301 https://www.my-web.page$request_uri;
ssl_certificate /etc/ssl/my/my-web.page.chained.crt;
ssl_certificate_key /etc/ssl/my/my-web.page.key.pem;
}
upstream backend {
server 192.168.200.210:8030 max_fails=1 fail_timeout=600s;
server 192.168.200.211:8031 backup;
}
server {
listen 443 ssl;
ssl_certificate /etc/ssl/my/my-web.page.chained.crt;
ssl_certificate_key /etc/ssl/my/my-web.page.key.pem;
server_name www.my-web.page;
location ~ ^/$ {
# rewrite only the root page, other urls see next rule
return 301 https://www.my-web-page-microsite.de/;
}
location / {
resolver 127.0.0.1 valid=30s;
# pass to backend-client, failover to second container for the next 5 minutes
proxy_pass http://backend;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Server-Address $server_addr;
proxy_ssl_verify off;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
If something is wrong with my backend-client-servers, nginx won't start.
Isn't there a possibilty to override the check on starting/restarting nginx?

Nginx configuration like Synology reverse proxy

I am trying configuring nginx (based on bitname/nginx:latest) as equivalent of Synology reverse proxy. This is due to missing wild-card redirect at Synology. While doing so, I face many issues; therfore I am requesting help for proper nginx configuration.
requirements
HTTPS upgrade
Redirect any wild-card subdomain (443) to a port 30'000
Hide the redirect port from user visibility
WebSockets must be supported (At Synology following header: Upgrade $http_upgrade AND Connection $connection_upgrade)
Example
Browser calls http://app1.my-example.com/
re-direct to https://app1.my-example.com:30000/
Browser displays: https://app1.my-example.com/, resolving via Port 30000
Current Code (not working so far)
# Test
server {
listen 8080;
server_name ~^(.*)\.my\-example.com$;
access_log /opt/bitnami/nginx/logs/yourapp_access.log;
error_log /opt/bitnami/nginx/logs/yourapp_error.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass https://$host:30000$request_uri/;
proxy_redirect off;
}
}
# Catch malicious requests
server {
listen 8080 default_server;
listen [::]:8080 default_server;
server_name _;
return 444;
}
I was able to solve my issue and would like to share the results. The only thing I do not get is, why redirect.my-example is OK as proxy_pass. It would hit the very same route (probably an endless-loop). Feedback/Improvement would be apreciated!
# custom code for hop by hop headers
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Upgrade connection
server {
listen 8080 default_server;
listen [::]:8080 default_server;
server_name _;
return 301 https://$host$request_uri;
}
# Redirect Subdomains (incl. Web-Socket)
server {
listen 8443 ssl;
ssl_certificate /certs/server.crt;
ssl_certificate_key /certs/server.key;
server_name my-example.de portal.my-example.de;
access_log /opt/bitnami/nginx/logs/yourapp_access.log;
error_log /opt/bitnami/nginx/logs/yourapp_error.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass https://redirect.my-example.de:30000;
proxy_redirect off;
}
}
# Catch malicious requests
server {
listen 8443 default_server;
listen [::]:8443 default_server;
ssl_certificate /certs/server.crt;
ssl_certificate_key /certs/server.key;
server_name _;
return 444;
}

Nginx. Directory of index is forbiden

I have load balancing nginx server 192.168.2.168 with the following nginx config:
upstream balancer {
server 192.168.2.165;
server 192.168.2.166 backup;
}
server {
listen 80;
server_name 192.168.2.168;
error_log /var/log/nginx/balancer-error_log;
location /something {
proxy_pass http://balancer;
}
}
Then I try 192.168.2.168/something it gives 403 Forbiden
tailf /var/log/error.log on the 192.168.2.165 shows:
*47 directory index of "/usr/share/nginx/html/glpi/" is forbidden, client: 192.168.2.168, server: localhost, request: "GET /glpi/ HTTP/1.0", host: "balancer"
But if I replace http://balancer with http://192.168.2.165 it works fine.
proxy_pass http://192.168.2.165;
What am I doing wrong and how to make upsream servers work?
The problem is solved using server_name balancer.home; instead of server_name 192.168.2.168; + I added some headers.
Here is my config:
upstream backend {
server 192.168.2.165;
server 192.168.2.166;
server 192.168.2.167 backup;
}
server {
listen 80;
server_name balancer.home;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name balancer.home;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
error_log /var/log/nginx/balancer-error_log;
access_log /var/log/nginx/balancer-access_log;
location / {
proxy_pass_header Server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://backend;
}
}
PS: On upstream servers, the same server_name as on the balance server (domain name) should be specified.

two servers on different machine with one IP

I have Nextcloud server running fine with ip 192.168.0.1
Installed collabora online server on another machine with IP 192.168.0.2
I have one public IP and two separate domains for those servers pointing at the same piblic IP
what I try to do is use nginx to distribute the traffic accordingly.
The configuration for the Nextcloud is working fine:
upstream php-handler {
server unix:/var/run/php/php7.0-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name first.domain.com;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name first.domain.com;
...
now I am putting second config for collabora server:
server {
listen 80;
listen [::]:80;
server_name second.domain.com;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name second.domain.com;
ssl_certificate /etc/ssl/private/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_password_file /etc/ssl/private/server.pass;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://second.domain.com;
}
}
I have added 192.168.0.2 second.domain.com to the hosts file
this server also has nginx running:
server {
listen 443 ssl;
server_name second.domain.com;
ssl_certificate /etc/ssl/private/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_password_file /etc/ssl/private/server.pass;
# static files
location ^~ /loleaflet {
proxy_pass https://localhost:9980;
proxy_set_header Host $http_host;
}
# WOPI discovery URL
location ^~ /hosting/discovery {
proxy_pass https://localhost:9980;
proxy_set_header Host $http_host;
}
# main websocket
location ~ ^/lool/(.*)/ws$ {
proxy_pass https://localhost:9980;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $http_host;
proxy_read_timeout 36000s;
}
# download, presentation and image upload
location ~ ^/lool {
proxy_pass https://localhost:9980;
proxy_set_header Host $http_host;
}
# Admin Console websocket
location ^~ /lool/adminws {
proxy_pass https://localhost:9980;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $http_host;
proxy_read_timeout 36000s;
}
}
the collabora window opens blank in nextcloud when i open a file
nginx on the nextcloud server gives response 400.
"GET /lool/https%3A%2F%2Ffirst.domain.com%2Fapps%2Frichdocuments%2Fwopi%2Ffiles%2F6932_ocqfsn9n2v8v%3Faccess_token%3DOObPuPjPgz7ycgmvNAklYGo1clIANWXU%26access_token_ttl%3D0%26permission%3Dedit/ws?WOPISrc=https%3A%2F%2Ffirst.domain.com%2Fapps%2Frichdocuments%2Fwopi%2Ffiles%2F6932_ocqfsn9n2v8v&compat=/ws HTTP/1.1" 400 0
So somehow I am not doing the redirection right. I need help with the nginx configurations. I know collabora server works because when I set second.domain.com 192.168.0.2 in the hosts file of the client and no redirection from nginx then it works fine

Setting up SSL on a load balancer

I currently have a load balancer with the NGINX setup:
upstream myapp1 {
least_conn;
server 192.168.0.20;
server 192.168.0.30;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
...
}
and on the clusters (192.168.0.20,192.168.0.30) the NGINX setup:
server {
listen 80;
root /var/www/website.co/public_html;
index index.php index.html index.htm;
server_name website.co www.website.co;
include /etc/nginx/commonStuff.conf; #php settings etc..
}
This works perfectly for http connections.
I am now wanting to set the server to work with a https connection for one domain (website.co). So I thought of adding this to the load balancers NGINX settings:
server {
listen 80;
listen 443 ssl;
server_name website.co www.website.co;
ssl on;
ssl_certificate /NAS/ssl/cert_chain_website.crt;
ssl_certificate_key /NAS/ssl/website.key;
location / {
proxy_pass https://myapp1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
and change the listening port on the clusters NGINX settings to 443 and keep everything else the same.
Now if I connect to http://website.co or infact anyother virtual domain on my server it returns
400 Bad Request
the plain HTTP request was sent to HTTPS port
So this means an issue with the redirect.
If I connect to https://website.co it returns:
404 Not Found
What am I doing wrong?

Resources