HOW-TO: Set up NGINX to reverse proxy your jails w/ Certbot

ZodiacUHD

Patron
Joined
Aug 28, 2015
Messages
226
Uhm, ok... Very stupid question: is your ip linked to the domain? (sorry if it sounds as "did you try turning it off and on again?")
 

silverback

Contributor
Joined
Jun 26, 2016
Messages
134
Then yeah, I'm on warden. And yes, I had tried just random.com, here's the result.

Code:
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for random.com
Waiting for verification...
Cleaning up challenges
Exiting abnormally:
Traceback (most recent call last):
  File "/opt/eff.org/certbot/venv/bin/letsencrypt", line 11, in <module>
	sys.exit(main())
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/main.py", line 1364, in main
	return config.func(config, plugins)
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/main.py", line 1254, in certonly
	lineage = _get_and_save_cert(le_client, config, domains, certname, lineage)
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/main.py", line 120, in _get_and_save_cert
	lineage = le_client.obtain_and_enroll_certificate(domains, certname)
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/client.py", line 391, in obtain_and_enroll_certificate
	cert, chain, key, _ = self.obtain_certificate(domains)
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/client.py", line 334, in obtain_certificate
	orderr = self._get_order_and_authorizations(csr.data, self.config.allow_subset_of_names)
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/client.py", line 370, in _get_order_and_authorizations
	authzr = self.auth_handler.handle_authorizations(orderr, best_effort)
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/auth_handler.py", line 82, in handle_authorizations
	self._respond(aauthzrs, resp, best_effort)
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/auth_handler.py", line 155, in _respond
	self._poll_challenges(aauthzrs, chall_update, best_effort)
  File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/auth_handler.py", line 226, in _poll_challenges
	raise errors.FailedChallenges(all_failed_achalls)
FailedChallenges: Failed authorization procedure. random.com (http-01): urn:ietf:params:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://random.com/.well-known/acme-challenge/oBpbM2kFZ1OjG1pnbSYx-6wGsvjz_0sNwFJWscEQF20: Timeout during connect (likely firewall problem)
Please see the logfiles in /var/log/letsencrypt for more details.

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: random.com
   Type:   connection
   Detail: Fetching
   http://random.com/.well-known/acme-challenge/oBpbM2kFZ1OjG1pnbSYx-6wGsvjz_0sNwFJWscEQF20:
   Timeout during connect (likely firewall problem)

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

I also got this when my router web interface was using 443. I had to move that to a different port.
 

SilentStrike

Cadet
Joined
Nov 4, 2017
Messages
9
Uhm, ok... Very stupid question: is your IP linked to the domain? (sorry if it sounds as "did you try turning it off and on again?")

It is, whenever I'm not trying to setup FreeNAS, I revert to my nginx server that's on my PC and it works. I simply change the port redirection on my router and it's fine.
On a random note though, my port redirect is really to the jail .200, not my freenas machine, which is .101

I also got this when my router web interface was using 443. I had to move that to a different port.

My router web interface is on port 80, not 443.
I've also tried to add a route to my jail (.200) on port 80, which changed my router web interface to port 8080.

All of these scenarios generate the same error.
 

ZodiacUHD

Patron
Joined
Aug 28, 2015
Messages
226
It is, whenever I'm not trying to setup FreeNAS, I revert to my nginx server that's on my PC and it works. I simply change the port redirection on my router and it's fine.
On a random note though, my port redirect is really to the jail .200, not my freenas machine, which is .101



My router web interface is on port 80, not 443.
I've also tried to add a route to my jail (.200) on port 80, which changed my router web interface to port 8080.

All of these scenarios generate the same error.

I think you should try to leave only port 80 and 443 open for your nginx jail. Try not have anything else, not even your router. See how that goes.
 

SilentStrike

Cadet
Joined
Nov 4, 2017
Messages
9
I think you should try to leave only port 80 and 443 open for your nginx jail. Try not have anything else, not even your router. See how that goes.

Yeah, I've tried that.. Same result. What else could be screwing it up? Any other setting on my router? Or maybe it's my domain setup?
 

thijsjek

Dabbler
Joined
Aug 12, 2017
Messages
19
Hello, I tried to fiddle around a bit, but I can't get the redirect towards SSL getting to work.
Found out, even though I was using lastest nginx tls1.3 didn't work. Other issue was the return https://$host$request_uri; didn't properly work, when uncommented it works
Code:
worker_processes  auto;

events {
	worker_connections  1024;
}

http {
	include	   mime.types;
	default_type  application/octet-stream;
	sendfile		on;
	tcp_nopush	  on;
	keepalive_timeout  65;
	gzip  on;
	server_tokens off;

#	server {
#		listen	   80;
#		listen  [::]:80;
#		server_name  ...;
#		return 301 https://$host$request_uri; #http --> https
#		error_page   500 502 503 504  /50x.html;
#		location = /50x.html {
#		   root   /usr/local/www/nginx-dist;
#	  }
#	}

	# HTTPS server
	server {
		listen	   80;
		listen  [::]:80;
		listen	   443 ssl http2;
		listen  [::]:443 ssl http2;
		server_name ...;

# SSL settings
		ssl_protocols TLSv1.2# Requires nginx >= 1.13.0 else use TLSv1.2
		ssl_prefer_server_ciphers on;
		ssl_dhparam /usr/local/etc/letsencrypt/live/.../dhparam.pem; # openssl dhparam -out dhparam.pem 4096
		ssl_certificate /usr/local/etc/letsencrypt/live/.../fullchain.pem;
		ssl_certificate_key /usr/local/etc/letsencrypt/live/.../privkey.pem;
		ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
		ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
		ssl_session_timeout  10m;
		ssl_session_cache shared:SSL:10m;
		ssl_session_tickets off; # Requires nginx >= 1.5.9
		ssl_stapling on; # Requires nginx >= 1.3.7
		ssl_stapling_verify on; # Requires nginx => 1.3.7
		resolver 8.8.8.8 8.8.4.4 valid=300s;
		resolver_timeout 5s;
		add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
		add_header X-Frame-Options DENY;
		add_header X-Content-Type-Options nosniff;
		add_header X-XSS-Protection "1; mode=block";

# Locations
		location /.well-known {
		root /usr/local/www;
		}
		location /emby {
		proxy_pass http://192.168.178.10:8096;
		proxy_redirect off;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		}
		location /nextcloud {
		proxy_pass http://192.168.192.18:80;
		proxy_redirect off;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		}
		location /transmission {
		proxy_pass http://192.168.178.14:9091/transmission/web;
		proxy_redirect off;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		}
	}
}
 
Last edited:

ZodiacUHD

Patron
Joined
Aug 28, 2015
Messages
226
I am also having the same problem with redirects to htpps. Are you on iocage or warden?
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
@thijsjek you have your redirect commented out so there is no redirect to https listed.
 

thijsjek

Dabbler
Joined
Aug 12, 2017
Messages
19
I am also having the same problem with redirects to htpps. Are you on iocage or warden?

I don't know why, but if I keep it uncommented, still I got redirected to https. Really strange. But with the redirect it breaks. The above config works for everything except nextcloud.
 

Itay1778

Patron
Joined
Jan 29, 2018
Messages
269
Hi everybody.
I followed the guide step by step.
And it just does not work I always get a 404 Not Found.
And https does not work at all open port 443 in router I created the certificate and it does not work.

And I want to use subdomain not example.com/ab.
What I want to use is: ab.example.com.
Can this guide work on it?

And I have already most of my subdomain has been a certificate can I use it or must create a new one?

Thanks Itay
 

Itay1778

Patron
Joined
Jan 29, 2018
Messages
269
Hi everybody.
I followed the guide step by step.
And it just does not work I always get a 404 Not Found.
And https does not work at all open port 443 in router I created the certificate and it does not work.

And I want to use subdomain not example.com/ab.
What I want to use is: ab.example.com.
Can this guide work on it?

And I have already most of my subdomain has been a certificate can I use it or must create a new one?

Thanks Itay
Hey
Can someone please help me?
 

adrianwi

Guru
Joined
Oct 15, 2013
Messages
1,231
How about starting with some basics:

Is your domain that you used to create the Lets Encrypt certificate directed to your WAN IP?
Is your router forwarding traffic on port 80/443 to the jail you've just created?
 

Itay1778

Patron
Joined
Jan 29, 2018
Messages
269
How about starting with some basics:

Is your domain that you used to create the Lets Encrypt certificate directed to your WAN IP?
Is your router forwarding traffic on port 80/443 to the jail you've just created?
Yes and yes
I've already created some certificate
And ports 80 and 443 are open to a jail reverse proxy
 

adrianwi

Guru
Joined
Oct 15, 2013
Messages
1,231
Ok. Have you followed this guide exactly i.e. are you using ssl_common.conf and proxy_setup.conf? Did you create the Lets Encrypt certificates using this guide too?

If so, can you post the .conf files in
Code:
 tags, along with nginx.conf.
 

Itay1778

Patron
Joined
Jan 29, 2018
Messages
269
Ok. Have you followed this guide exactly i.e. are you using ssl_common.conf and proxy_setup.conf? Did you create the Lets Encrypt certificates using this guide too?

If so, can you post the .conf files in
Code:
 tags, along with nginx.conf.
I managed to make it work fine at least right now.
I used parts of Ubuntu's guide and it worked

So what I used:
nginx.conf
Code:
#user  nobody;
worker_processes  1;

# This default error log path is compiled-in to make sure configuration parsing
# errors are logged somewhere, especially during unattended boot when stderr
# isn't normally logged anywhere. This path will be touched on every nginx
# start regardless of error log location configured here. See
# https://trac.nginx.org/nginx/ticket/147 for more info.
#
#error_log  /var/log/nginx/error.log;
#

#pid		logs/nginx.pid;


events {
	worker_connections  1024;
}


http {
	include	   mime.types;
	default_type  application/octet-stream;

	#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
	#				  '$status $body_bytes_sent "$http_referer" '
	#				  '"$http_user_agent" "$http_x_forwarded_for"';

	#access_log  logs/access.log  main;

	sendfile		on;
	#tcp_nopush	 on;

	#keepalive_timeout  0;
	keepalive_timeout  65;

	#gzip  on;

server {
   listen 80;
   listen [::]:80;
   server_name my domain;
   return 301 https://$host$request_uri;
}
	server {
		listen 443 ssl;
		server_name my domain;
		include ssl_common.conf;
		include proxy_setup.conf;

		#charset koi8-r;

		#access_log  logs/host.access.log  main;
	   
		  location \ {
 
			root   /usr/local/www/nginx;
			index  index.html index.htm;
	   }

		#error_page  404			  /404.html;

		# redirect server error pages to the static page /50x.html
		#
		error_page   500 502 503 504  /50x.html;
		location = /50x.html {
			root   /usr/local/www/nginx-dist;
		}

		# proxy the PHP scripts to Apache listening on 127.0.0.1:80
		#
		#location ~ \.php$ {
		#	proxy_pass   http://127.0.0.1;
		#}

		# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
		#
		#location ~ \.php$ {
		#	root		   html;
		#	fastcgi_pass   127.0.0.1:9000;
		#	fastcgi_index  index.php;
		#	fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
		#	include		fastcgi_params;
		#}

		# deny access to .htaccess files, if Apache's document root
		# concurs with nginx's one
		#
		#location ~ /\.ht {
		#	deny  all;
		#}
  }

}

proxy_setup
Code:
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		  https://Internal IP;
	proxy_read_timeout  90;

	proxy_redirect	  https://Internal IP https://my domain;
}


ssl_common (I think this is the only file I have not changed anything here)
Code:
ssl_prefer_server_ciphers on;
ssl_certificate /usr/local/etc/letsencrypt/live/my domain/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/my domain/privkey.pem;
# Disable SSLv2 and SSLv3 (BEAST and POODLE attacks)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Enable our strong DH Key
ssl_dhparam /usr/local/etc/ssl/dhparams.pem;
# Cipher-list for PFS.
ssl_ciphers
"EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_ecdh_curve secp384r1;
# Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Requires nginx >= 1.5.9
ssl_stapling on;
# Requires nginx >= 1.3.7
ssl_stapling_verify on;
# Requires nginx => 1.3.7
resolver 8.8.8.8 4.4.4.4 valid=300s;
resolver_timeout 5s;
# HSTS Support
add_header Strict-Transport-Security "max-age=63072000;includeSubdomains; preload";
# These headers can break applications, be careful!
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;



I have a few questions and I would be happy if you or someone could answer them.

1. I already have a Lets Encrypt certificate in most of the subdomain I can save and use them or I must use the reverse proxy certificate and those who do not already have the certificate will the reverse proxy use itself?

2. Settings I set through the guides I took from them Are they good and secure? Do you recommend changing something that should be better and more secure?

3. I'm going to use only the subdomains and not in the subdirectory do you recommend using any subdomains in his private file or is there a problem to use them all in one file?

The sources I used
For a Lets Encrypt certificate
https://certbot.eff.org/lets-encrypt/freebsd-nginx

The ubuntu guide
https://www.digitalocean.com/commun...nginx-with-ssl-as-a-reverse-proxy-for-jenkins

nginx http to https
https://bjornjohansen.no/redirect-to-https-with-nginx

And this guide
 

adrianwi

Guru
Joined
Oct 15, 2013
Messages
1,231
Good to hear you got it working.

1. I think it makes life easier if all the certificates are generated in the reverse proxy jail, and you can set-up a cron task to renew them automatically.

2. I think some of my security settings were copied from this thread, but test it yourself at https://www.ssllabs.com/

3. I think I mentioned in the other thread, I create separate service.conf files in a sites-enabled folder for mine (I have nextcloud.conf, emby.conf, calibre.conf, wordpress.conf, etc.) although I'm sure you can build a single file. The configuration is slightly different for subdomains as you are not using the /location and you'll need separate SSL certificates or at least a Letsencrypt wildcard one as www.domain.com won't work for subdomain.domain.com, where it does for www.domain.com/location.
 

Itay1778

Patron
Joined
Jan 29, 2018
Messages
269
Good to hear you got it working.

1. I think it makes life easier if all the certificates are generated in the reverse proxy jail, and you can set-up a cron task to renew them automatically.

2. I think some of my security settings were copied from this thread, but test it yourself at https://www.ssllabs.com/

3. I think I mentioned in the other thread, I create separate service.conf files in a sites-enabled folder for mine (I have nextcloud.conf, emby.conf, calibre.conf, wordpress.conf, etc.) although I'm sure you can build a single file. The configuration is slightly different for subdomains as you are not using the /location and you'll need separate SSL certificates or at least a Letsencrypt wildcard one as www.domain.com won't work for subdomain.domain.com, where it does for www.domain.com/location.
Something I did not understand how to set it up the ssl I hope you can help me.

How do I set the ssl certificate for each subdomain
I already have the Lets Encrypt Certificate but where do I set it?
Just adds another path in ssl_common.conf?
 

adrianwi

Guru
Joined
Oct 15, 2013
Messages
1,231
I don't use a ssl_common.conf file and replicate everything within each of my services.conf files.

I suspect you could keep all the ciphers and protocol stuff in the ssl_common.conf file and just move the cert and key lines into the service file, but I've not set mine up like that.
 

Itay1778

Patron
Joined
Jan 29, 2018
Messages
269
I don't use a ssl_common.conf file and replicate everything within each of my services.conf files.

I suspect you could keep all the ciphers and protocol stuff in the ssl_common.conf file and just move the cert and key lines into the service file, but I've not set mine up like that.
I did not think it would work.
All the time I knew the nginx he had only made problems but today he's worked out
I say just because what I did tried it in the past and he only told me errors and now it works

I managed to make him distinguish domains from subdomain
Simply duplicate the
Code:
server {
   listen 80;
   listen [::]:80;
   server_name my domain;
   return 301 https://$host$request_uri;
}
	server {
		listen 443 ssl;
		server_name my domain;
		include ssl_common.conf;
		include proxy_setup.conf;



And I opened a file ( proxy_setup) for every service I use and just modified it in nginx.conf when I duplicated and it worked.
In the past I did this is said error can not be because there is duplication and it has made life difficult

And for the certificate I created a file ( ssl_common) separately for each service that needs it's and it worked.
Otherwise only one works in one file
 

Ixian

Patron
Joined
May 11, 2015
Messages
218
Fantastic guide. I set up a reverse proxy with FreeNAS 4 years ago for another home project and it was a complete PITA tracking everything down and getting it right. This made it all really easy.

I have ssl redirects pointing to my jail servers and SSL Labs gave me an A+ :) And auto-renewal for my letsencrypt cert.

Here's my ssl_common.conf, modified for tighter security, etc:

Code:
ssl_prefer_server_ciphers on;
ssl_certificate  /etc/letsencrypt/live/EXAMPLE.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/EXAMPLE.com/privkey.pem;
# Disable SSLv2 and SSLv3 (BEAST and POODLE attacks)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Enable our strong DH Key
ssl_dhparam /usr/local/etc/ssl/dhparams.pem;
# Cipher-list for PFS.
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-
SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:E
CDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AE
S128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES
256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:H
IGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_ecdh_curve secp384r1;
# Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Requires nginx >= 1.5.9
ssl_stapling on;
# Requires nginx >= 1.3.7
ssl_stapling_verify on;
# Requires nginx => 1.3.7
resolver 8.8.8.8 4.4.4.4 valid=300s;
resolver_timeout 5s;
# HSTS Support
add_header Strict-Transport-Security "max-age=63072000;includeSubdomains; preload";
# These headers can break applications, be careful!
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-Xss-Protection "1; mode=block" always;
add_header X-Frame-Options "SAMEORIGIN" always;
proxy_hide_header X-Powered-By;
add_header 'Referrer-Policy' 'no-referrer';
add_header Content-Security-Policy "frame-ancestors EXAMPLE.com;";



And this is my ngix.conf - updated with some suggestions later in the thread for better performance as well as port 80>443 remapping and some security settings:
Code:
worker_processes  2;
events {
	worker_connections  8192;
}

http {
	include	   mime.types;
	default_type  application/octet-stream;
		server_tokens off;

		gzip on;
		gzip_disable "msie6";

		gzip_comp_level 6;
		gzip_min_length 1100;
		gzip_buffers 16 8k;
		gzip_proxied any;
		gzip_types
	text/plain
	text/css
	text/js
	text/xml
	text/javascript
	application/javascript
	application/x-javascript
	application/json
	application/xml
	application/rss+xml
	image/svg+xml;

	tcp_nodelay on;

	sendfile		off;

	server_names_hash_bucket_size 128;
	map_hash_bucket_size 64;

## Start: Timeouts ##
	client_body_timeout   10;
	client_header_timeout 10;
	keepalive_timeout	 30;
	send_timeout		  10;
	keepalive_requests	10;
## End: Timeouts ##

## Default Listening ##

server {
	listen 80 default_server;
	listen [::]:80 default_server;
	server_name _;

		  return 301 https://$host$request_uri;
}

server {
listen [::]:80;
listen 80;
listen [::]:443 ssl;
listen 443 ssl;
server_name EXAMPLE.com;
include ssl_common.conf;
include proxy_setup.conf;
}
}
 
Top