Nginx reverse proxy, only allow connection from hostname not ip - nginx

Is it possible to allow only users typing in xxxxxx.com (fictive), so they should make a DNS-lookup and connect. And block users who uses my public ip to connect ?
Configuration:
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name xxxxxxx.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/jenkins.access.log;
location / {
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;
# Fix the “It appears that your reverse proxy set up is broken" error.
proxy_pass http://10.0.11.32:80;
proxy_read_tenter code hereimeout 360;
proxy_redirect http://10.0.11.32:80 https://xxxxxxx.com;
}
}

The $http_host parameter is set to the value of the Host request header. nginx uses that value to select a server block. If a server block is not found, the default server is used, which is either marked as default_server or is the first server block encountered. See this documentation.
To force nginx to only accept named requests, use a catch all server block to reject anything else, for example:
server {
listen 80 default_server;
return 403;
}
server {
listen 80;
server_name www.example.com;
...
}
With the SSL protocol, it depends on whether or not you have SNI enabled. If you are not using SNI, then all SSL requests pass through the same server block, in which case you will need to use an if directive to test the value of the $http_host value. See this and this for details.

Related

NGINX routing question - I've spent some hours on this to no luck yet

I've spent hours on multiple message boards and forums looking for this config pattern in NGINX. I want a subdomain to get redirected to port 8080 before the catch-all grabs everything else that comes into the domain, including all other subdomains, and points it at 443.
The 443 redirect already works perfectly. Any and all help would be appreciated thank you.
I have adminer.server.app that I want to goto HTTP://adminer.server.app (it really goes to 8080 after NGINX would do it's thing)
Again, all other traffic is taken care of so far.
Here is a snippet of my conf file:
server {
listen 80;
listen [::]:80;
server_name server.app www.server.app;
location / {
return 301 https://$host$request_uri;
}
#for certbot challenges (renewal process)
location ~ /.well-known/acme-challenge {
allow all;
root /data/letsencrypt;
}
}
#https://adminer.server.app
server {
listen 8080;
server_name adminer.server.app;
server_tokens off;
resolver 8.8.8.8;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
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;
}
}
#https://server.app
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name server.app;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/certs/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/certs/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
return 301 https://www.server.app$request_uri;
}
I can bring the phpmyadmin up by using my IP:8080, so at the moment this isn't critical. I'm not going to expose it after I'm done configuring the MySQL anyway. Closing request for help.

Newbie - how do I configure NGINX to only serve request from a specific domain? [duplicate]

Is it possible to allow only users typing in xxxxxx.com (fictive), so they should make a DNS-lookup and connect. And block users who uses my public ip to connect ?
Configuration:
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name xxxxxxx.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/jenkins.access.log;
location / {
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;
# Fix the “It appears that your reverse proxy set up is broken" error.
proxy_pass http://10.0.11.32:80;
proxy_read_tenter code hereimeout 360;
proxy_redirect http://10.0.11.32:80 https://xxxxxxx.com;
}
}
The $http_host parameter is set to the value of the Host request header. nginx uses that value to select a server block. If a server block is not found, the default server is used, which is either marked as default_server or is the first server block encountered. See this documentation.
To force nginx to only accept named requests, use a catch all server block to reject anything else, for example:
server {
listen 80 default_server;
return 403;
}
server {
listen 80;
server_name www.example.com;
...
}
With the SSL protocol, it depends on whether or not you have SNI enabled. If you are not using SNI, then all SSL requests pass through the same server block, in which case you will need to use an if directive to test the value of the $http_host value. See this and this for details.

How to configure https nginx configuration for multiple running port in ubuntu server

Facing a unique type of issue for hosting multiple port (5000, 5001) in ubuntu server. I am using Nginx to configure two subdomains in the directory "/etc/nginx/site-availabe" and I delink default configuration. but the main issue is when listen to port ":80" is working fine for both subdomain but when configured for both SSL cert file and listen to 443 is only pointing to port 5000 for both subdomain, not for 5001 port. I will share my config file if I have any config problem.
This setting for 5001 port
server {
listen 80;
server_name lenderapp.xxx.in;
return 301 https://lenderapp.xxx.in$request_uri;
# rewrite ^(.*) https://lenderapp.xxx.in$1 permanent;
}
server {
listen 443;
ssl on;
server_name www.lenderapp.xxx.in;
#root /home/dmin/OProjects/lender_demo;
error_log /var/log/nginx/error_lenderapp.log error;
access_log /var/log/nginx/lenderapp_access.log;
ssl_certificate /home/admin/OProjects/ssl_cert/lender_cert/ssl_cert.cert;
ssl_certificate_key /home/admin/OProjects/ssl_cert/lender_cert/ssl_cert_key.key;
location /{
proxy_pass http://0.0.0.0:5001;
root /home/admin/OProjects/lender_demo;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Now 2nd setting for port 5000
server {
listen 80;
server_name bcadmin.xxx.in;
return 301 https://bcadmin.xxx.in$request_uri;
#rewrite ^(.*) https://bcadmin.xxx.in$1 permanent;
}
server {
listen 443 ssl http2;
server_name www.bcadmin.tradefi.in;
root /home/admin/OProjects/admin_console;
error_log /var/log/nginx/lenderapp.log error;
access_log /var/log/nginx/lenderapp_access.log;
ssl_certificate /home/admin/OProjects/ssl_cert/ssl_cert.cert;
ssl_certificate_key /home/admin/OProjects/ssl_cert/ssl_cert_key.key;
location /{
proxy_pass 'http://0.0.0.0:5000';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Please help me guys... I need help badly
Cannot see a real error in you config on first glance. But using 0.0.0.0 as target IP - this IP is kind of "any IP". You should stick to 127.0.0.1 for local redirects. Also ssl on is deprecated since 06/2018...
I would recommend to split your config into several files to keep a better overview. It will make the config more readable and will really help you on daily routines (and enhancements).
For your config my approach would be the following. I am using this config for > 35 domains without problems on one of my servers. It will not just work, but also give you an A+ rating on SSLtest. This config adopts your log- and cert file names - that in my opinion are not optimal ;)
Main Config
# This block redirect any :80 traffic to its https counterpart.
server {
listen 80 default_server;
listen [::]:80 default_server; # <-- ipv6
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2; # <-- ipv6
server_name www.lenderapp.xxx.in;
error_log /var/log/nginx/error_lenderapp.log error;
access_log /var/log/nginx/lenderapp_access.log;
include params/ssl;
ssl_certificate /home/admin/OProjects/ssl_cert/lender_cert/ssl_cert.cert;
ssl_certificate_key /home/admin/OProjects/ssl_cert/lender_cert/ssl_cert_key.key;
location / {
proxy_pass http://127.0.0.1:5001;
include params/proxy_full;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2; # <-- ipv6
server_name www.bcadmin.tradefi.in;
error_log /var/log/nginx/lenderapp.log error;
access_log /var/log/nginx/lenderapp_access.log;
include params/ssl;
ssl_certificate /home/admin/OProjects/ssl_cert/ssl_cert.cert;
ssl_certificate_key /home/admin/OProjects/ssl_cert/ssl_cert_key.key;
location / {
proxy_pass http://127.0.0.1:5000;
include params/proxy_full;
}
}
params/ssl (for my /etc/nginx/params/proxy_full)
Caution: You'll need a dhparam file inside params to make it work. Use openssl dhparam -out /etc/nginx/params/dhparam.pem 4096 to create one if not existent.
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_dhparam params/dhparam.pem;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4;
resolver_timeout 5s;
params/proxy_full (for my /etc/nginx/params/proxy_full)
add_header X-Upstream $upstream_addr;
proxy_http_version 1.1;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto https;

TFS behind Nginx reverse proxy

Trying to configure Team Foundation Server behind Nginx reverse proxy.
Also, I'm using a self-signed SSL Certificate.
Getting ERR_TOO_MANY_REDIRECTS
Here is my nginx configuration:
server {
listen 80 default;
server_name tfs.domain.com;
return 301 https://$host$request_uri;
}
upstream tfs.domain.com {
server 12.34.56.78:80; #local tfs address
keepalive 16;
}
server {
listen 443 ssl;
server_name tfs.domain.com;
ssl_certificate /etc/nginx/ssl/tfs.domain.com.pem;
ssl_certificate_key /etc/nginx/ssl/tfs.domain.com.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://12.34.56.78:80; #local tfs address
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect http:// $scheme://;
}
access_log /var/log/nginx/tfs.domain.com/443-access.log;
error_log /var/log/nginx/tfs.domain.com/443-error.log;
}
What I'm doing wrong?
Just try to set the proxy_redirect explicitly:
e.g.:
proxy_redirect http://localhost:8080 https://tfs.domain.com;
You can reference below article to configure the nginx (It should be similar with TFS):
How To Configure Nginx with SSL as a Reverse Proxy for Jenkins
And this thread may helps: https://serverfault.com/questions/754351/what-is-a-correct-ways-to-allow-login-to-an-iis-site-through-a-reverse-proxy
Besides, you can reference below articles to troubleshoot the ERR_TOO_MANY_REDIRECTS issue:
How to Fix ERR_TOO_MANY_REDIRECTS on Your WordPress Site
How to Fix Err Too Many Redirects Error

Nginx: WebSocket wildcard location

I use a nginx instance in front of a Go service.
I want to redirect anything on port 80 to https. [done]
All (non-websocket) https requests at /* should go to https://localhost:8443/* [done]
All websocket https requests at /ws/* should go to https://localhost:8443/ws/* [missing]
My current config:
ssl_certificate ...
ssl_certificate_key ...
ssl_ciphers ...
ssl_prefer_server_ciphers on;
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name www.mydomain.com mydomain.com;
add_header Strict-Transport-Security "max-age=31536000";
location /ws { <--- This only works for /ws but not /ws/app1
proxy_pass http://localhost:8443/ws;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / { <--- Catches anything, even without wildcard ?!
proxy_pass http://localhost:8443;
}
}
server {
listen 443 ssl;
server_name *.mydomain.com;
return 444;
}
Why is this necessary ? Well, as I understand, you have to set the upgrade headers explicitly, so I guess you have to specify another location.
Ideally, I would just use one location, but then websockets are blocked (because upgrade headers never make it to the Go service...)
I'm not a nginx expert, so bear with me =).
[EDIT]
I got it working now. I'm not sure if its ok to always set_header Upgrade/Connection, even if it's not a websocket request, but my Go service doesn't give a ****, so it works for me =]
ssl_certificate ...
ssl_certificate_key ...
ssl_ciphers ...
ssl_prefer_server_ciphers on;
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name www.mydomain.com mydomain.com;
add_header Strict-Transport-Security "max-age=31536000";
location / { <--- Catches anything, even without wildcard ?!
proxy_pass http://localhost:8443;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
server {
listen 443 ssl;
server_name *.mydomain.com;
return 444;
}
Check out the article at https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms
You are not using any location_match, so the match is a prefix match.
Use ~ as the location match modifier to have it interpreted as a regular expression.
The line location /ws should match every query starting with /ws.

Resources