[Support] Linuxserver.io - SWAG - Secure Web Application Gateway (Nginx/PHP/Certbot/Fail2ban)


Recommended Posts

I was wondering if anyone could take a look at my nginx default site-conf and let me know if I'm on the right track for adding a proxy for a WordPress site running in a subdirectory on a subdomain (i.e. http://wordpress.mysite.com running from /config/www/wordpress). If anything, I'm guessing that I don't need to repeat the main server's ssl certificates and settings or headers, but I've included them for now, because I wasn't sure.

 

I've been using this container for quite a while now to host reverse proxies for plex, calibre-web, and ombi, and it's been working great, so I don't want to mess everything up now 😬 Thanks!

 

# REDIRECT TRAFFIC FROM www.domain.com TO https://domain.com
server {
	listen 80;
    	server_name www.mysite.com;
    	return 301 https://mysite.com$request_uri;
}

server {
	listen 443;
    	server_name www.mysite.com;
    	return 301 https://mysite.com$request_uri;
}

server {
        listen 80;
        server_name mysite.com;
        return 301 https://mysite.com$request_uri;
}

# MAIN SERVER BLOCK
server {

	listen 443 ssl default_server;
	server_name mysite.com;

	## Certificates from LE container placement
	ssl_certificate /config/keys/letsencrypt/fullchain.pem;
	ssl_certificate_key /config/keys/letsencrypt/privkey.pem;
	
	## Strong Security recommended settings per cipherli.st
	ssl_dhparam /config/nginx/dhparams.pem; # Bit value: 4096
	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;

	## Settings to add strong security profile (A+ on securityheaders.io/ssllabs.com)
	add_header Front-End-Https on;
	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";
	add_header X-Robots-Tag none;
	add_header Content-Security-Policy "frame-ancestors https://*.$server_name https://$server_name";
	add_header Referrer-Policy "strict-origin-when-cross-origin";
	proxy_cookie_path / "/; HTTPOnly; Secure";
	more_set_headers "Server: Classified";
	more_clear_headers 'X-Powered-By';

	# Custom error pages 
	error_page 400 401 402 403 404 405 408 500 502 503 504 $scheme://$server_name/error.php?error=$status;
	error_log /config/log/nginx/error.log;

	root /config/www;
	index index.html index.htm index.php;

#SUB DIRECTORIES
	 location /plex {
	    proxy_pass http://192.168.1.107:32400/web;
	    include /config/nginx/proxy.conf;
	}
	
	 location /web {
	    proxy_pass http://192.168.1.107:32400/web;
	    include /config/nginx/proxy.conf;
	}
	
	 location /calibre-web {
	    proxy_pass              http://192.168.1.107:8083/;
	    proxy_set_header        Host            $http_host;
	    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
	    proxy_set_header        X-Scheme        $scheme;
	    proxy_set_header        X-Script-Name   /calibre-web;
	}
	
	 location ^~ /ombi {
	    proxy_pass http://192.168.1.107:3579/ombi;
	    include /config/nginx/proxy.conf;
	}  
}

# WORDPRESS SERVER
server {

	listen 443 ssl http2;
    server_name wordpress.mysite.com;

	## Certificates from LE container placement
	ssl_certificate /config/keys/letsencrypt/fullchain.pem;
	ssl_certificate_key /config/keys/letsencrypt/privkey.pem;

	## Strong Security recommended settings per cipherli.st
	ssl_dhparam /config/nginx/dhparams.pem; # Bit value: 4096
	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;

	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";
	add_header X-Robots-Tag none;
	add_header Content-Security-Policy "frame-ancestors https://*.$server_name https://$server_name"; 
	add_header X-Frame-Options "ALLOW-FROM https://*.$server_name" always; 
	add_header Referrer-Policy "strict-origin-when-cross-origin";
	proxy_cookie_path / "/; HTTPOnly; Secure"; 
	more_set_headers "Server: Classified";
	more_clear_headers 'X-Powered-By';
 
	client_max_body_size 0; 
 
 	root /config/www/wordpress/;
 	index index.php index.html index.htm;

	 location ~ /\. {
		deny all;
	} 
	 location / {
		try_files $uri $uri/ /index.php?_url=$uri&$query_string; 
	}

	 location /wp-admin {
		auth_basic "Restricted";
		auth_basic_user_file /config/nginx/.htpasswd;
	}
	 location /wp-login.php {
		auth_basic "Restricted";
		auth_basic_user_file /config/nginx/.htpasswd;
		 location ~ \.php$ {
		 fastcgi_split_path_info ^(.+\.php)(/.+)$;
		  # With php7-cgi alone:
		 fastcgi_pass 127.0.0.1:9000;
		  # With php7-fpm:
		  # fastcgi_pass unix:/var/run/php7-fpm.sock;
		 fastcgi_index index.php;
		 include /etc/nginx/fastcgi_params;
	}
}

		# PHP
	location ~ \.php$ {
 		 fastcgi_split_path_info ^(.+\.php)(/.+)$;
 		 # With php7-cgi alone:
 		 fastcgi_pass 127.0.0.1:9000;
		 # With php7-fpm:
		 # fastcgi_pass unix:/var/run/php7-fpm.sock;
		 fastcgi_index index.php;
		 include /etc/nginx/fastcgi_params;
	}
 
		 fastcgi_buffer_size 4K;
		 fastcgi_buffers 64 4k; 
}

 

Link to comment
1 hour ago, zandrsn said:

I was wondering if anyone could take a look at my nginx default site-conf and let me know if I'm on the right track for adding a proxy for a WordPress site running in a subdirectory on a subdomain (i.e. http://wordpress.mysite.com running from /config/www/wordpress). If anything, I'm guessing that I don't need to repeat the main server's ssl certificates and settings or headers, but I've included them for now, because I wasn't sure.

 

I've been using this container for quite a while now to host reverse proxies for plex, calibre-web, and ombi, and it's been working great, so I don't want to mess everything up now 😬 Thanks!

 


# REDIRECT TRAFFIC FROM www.domain.com TO https://domain.com
server {
	listen 80;
    	server_name www.mysite.com;
    	return 301 https://mysite.com$request_uri;
}

server {
	listen 443;
    	server_name www.mysite.com;
    	return 301 https://mysite.com$request_uri;
}

server {
        listen 80;
        server_name mysite.com;
        return 301 https://mysite.com$request_uri;
}

# MAIN SERVER BLOCK
server {

	listen 443 ssl default_server;
	server_name mysite.com;

	## Certificates from LE container placement
	ssl_certificate /config/keys/letsencrypt/fullchain.pem;
	ssl_certificate_key /config/keys/letsencrypt/privkey.pem;
	
	## Strong Security recommended settings per cipherli.st
	ssl_dhparam /config/nginx/dhparams.pem; # Bit value: 4096
	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;

	## Settings to add strong security profile (A+ on securityheaders.io/ssllabs.com)
	add_header Front-End-Https on;
	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";
	add_header X-Robots-Tag none;
	add_header Content-Security-Policy "frame-ancestors https://*.$server_name https://$server_name";
	add_header Referrer-Policy "strict-origin-when-cross-origin";
	proxy_cookie_path / "/; HTTPOnly; Secure";
	more_set_headers "Server: Classified";
	more_clear_headers 'X-Powered-By';

	# Custom error pages 
	error_page 400 401 402 403 404 405 408 500 502 503 504 $scheme://$server_name/error.php?error=$status;
	error_log /config/log/nginx/error.log;

	root /config/www;
	index index.html index.htm index.php;

#SUB DIRECTORIES
	 location /plex {
	    proxy_pass http://192.168.1.107:32400/web;
	    include /config/nginx/proxy.conf;
	}
	
	 location /web {
	    proxy_pass http://192.168.1.107:32400/web;
	    include /config/nginx/proxy.conf;
	}
	
	 location /calibre-web {
	    proxy_pass              http://192.168.1.107:8083/;
	    proxy_set_header        Host            $http_host;
	    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
	    proxy_set_header        X-Scheme        $scheme;
	    proxy_set_header        X-Script-Name   /calibre-web;
	}
	
	 location ^~ /ombi {
	    proxy_pass http://192.168.1.107:3579/ombi;
	    include /config/nginx/proxy.conf;
	}  
}

# WORDPRESS SERVER
server {

	listen 443 ssl http2;
    server_name wordpress.mysite.com;

	## Certificates from LE container placement
	ssl_certificate /config/keys/letsencrypt/fullchain.pem;
	ssl_certificate_key /config/keys/letsencrypt/privkey.pem;

	## Strong Security recommended settings per cipherli.st
	ssl_dhparam /config/nginx/dhparams.pem; # Bit value: 4096
	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;

	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";
	add_header X-Robots-Tag none;
	add_header Content-Security-Policy "frame-ancestors https://*.$server_name https://$server_name"; 
	add_header X-Frame-Options "ALLOW-FROM https://*.$server_name" always; 
	add_header Referrer-Policy "strict-origin-when-cross-origin";
	proxy_cookie_path / "/; HTTPOnly; Secure"; 
	more_set_headers "Server: Classified";
	more_clear_headers 'X-Powered-By';
 
	client_max_body_size 0; 
 
 	root /config/www/wordpress/;
 	index index.php index.html index.htm;

	 location ~ /\. {
		deny all;
	} 
	 location / {
		try_files $uri $uri/ /index.php?_url=$uri&$query_string; 
	}

	 location /wp-admin {
		auth_basic "Restricted";
		auth_basic_user_file /config/nginx/.htpasswd;
	}
	 location /wp-login.php {
		auth_basic "Restricted";
		auth_basic_user_file /config/nginx/.htpasswd;
		 location ~ \.php$ {
		 fastcgi_split_path_info ^(.+\.php)(/.+)$;
		  # With php7-cgi alone:
		 fastcgi_pass 127.0.0.1:9000;
		  # With php7-fpm:
		  # fastcgi_pass unix:/var/run/php7-fpm.sock;
		 fastcgi_index index.php;
		 include /etc/nginx/fastcgi_params;
	}
}

		# PHP
	location ~ \.php$ {
 		 fastcgi_split_path_info ^(.+\.php)(/.+)$;
 		 # With php7-cgi alone:
 		 fastcgi_pass 127.0.0.1:9000;
		 # With php7-fpm:
		 # fastcgi_pass unix:/var/run/php7-fpm.sock;
		 fastcgi_index index.php;
		 include /etc/nginx/fastcgi_params;
	}
 
		 fastcgi_buffer_size 4K;
		 fastcgi_buffers 64 4k; 
}

 

On the surface it looks about right. 

 

Actually you had to repeat the ssl info because it is in a different server block. 

Link to comment
4 hours ago, aptalca said:

Actually you had to repeat the ssl info because it is in a different server block.  

2

Awesome, thanks for the help. I thought that might be the case, which is why I included them, but I wasn't exactly sure how that worked.

 

I guess I'll report back if I stumble upon any issues.

Link to comment
14 hours ago, tillkrueger said:

bingo! it is finally resolving without the www...thanks so much for your guidance, aptalca!

@tillkrueger this may be too late to be helpful, or you may have already seen it, but I wanted to mention this How-To for setting up WordPress with LetsEncrypt on Unraid: https://technicalramblings.com/blog/how-to-set-up-a-wordpress-site-with-letsencrypt-and-mariadb-on-unraid/

 

I found it quite helpful. Cheers.

  • Like 1
Link to comment

thanks for that link, zandrsn...a thorough treatment of this challenge, indeed, albeit too late for me. I managed to get it to work by scouring for disparate pieces of information, and piecing it together that way, plus some guidance from aptalca, but this link should be displayed prominently on the top of this thread, maybe, as it skilfully addresses one of the more popular reasons why people may want to run a server on their unRAID system.

Thanks again!

Link to comment

I noticed that when I go into PMA (phpmyadmin), it says "Server connection: SSL is not being used".

Not sure whether I tried the right thing, but after a few Google searches, I installed the Really Simple SSL plugin, which first warned me:

"You run a Multisite installation with subdomains, but your site doesn't have a wildcard certificate. This leads to issues when activating SSL networkwide since subdomains will be forced over SSL as well while they don't have a valid certificate. Activate SSL per site or install a wildcard certificate to fix this."

which is curious, as I installed WP Multi with the subdirectories option, which is also reflected in in my wp-config.php file:

define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'collabatory.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

why would that be?

In any case, just to give it a try, and weary of the wildcard certificate warning, recommending not to activate networkwide, I chose "Activate SSL per site"...after going back to PMA, though, I still get then "Server connection: SSL is not being used" warning.

Am I thinking too simplistically here? Are there other steps required to have all aspects of my Wordpress site (and all sites, if I can get it to work networkwide) be recognised as being SSL?

Link to comment

looking for some help. I'm guessing its something easy but I can't figure it out. 

User uid: 99
User gid: 100
-------------------------------------

[cont-init.d] 10-adduser: exited 0.
[cont-init.d] 20-config: executing...
[cont-init.d] 20-config: exited 0.
[cont-init.d] 30-keygen: executing...
using keys found in /config/keys
[cont-init.d] 30-keygen: exited 0.
[cont-init.d] 50-config: executing...
Variables set:
PUID=99
PGID=100
TZ=America/Chicago
URL=cdkauffmann.com
SUBDOMAINS=server,nextcloud,sonarr
EXTRA_DOMAINS=
ONLY_SUBDOMAINS=true
DHLEVEL=2048
VALIDATION=http
DNSPLUGIN=
[email protected]
STAGING=

2048 bit DH parameters present
SUBDOMAINS entered, processing
SUBDOMAINS entered, processing
Only subdomains, no URL in cert
Sub-domains processed are: -d server.cdkauffmann.com -d nextcloud.cdkauffmann.com -d sonarr.cdkauffmann.com
E-mail address entered: [email protected]
http validation is selected
Generating new certificate
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for nextcloud.cdkauffmann.com
http-01 challenge for server.cdkauffmann.com
http-01 challenge for sonarr.cdkauffmann.com
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. server.cdkauffmann.com (http-01): urn:ietf:params:acme:error:unknownHost :: The server could not resolve a domain name :: No valid IP addresses found for server.cdkauffmann.com, sonarr.cdkauffmann.com (http-01): urn:ietf:params:acme:error:unknownHost :: The server could not resolve a domain name :: No valid IP addresses found for sonarr.cdkauffmann.com, nextcloud.cdkauffmann.com (http-01): urn:ietf:params:acme:error:unknownHost :: The server could not resolve a domain name :: No valid IP addresses found for nextcloud.cdkauffmann.com
IMPORTANT NOTES:
- The following errors were reported by the server:

Domain: server.cdkauffmann.com
Type: unknownHost
Detail: No valid IP addresses found for server.cdkauffmann.com

Domain: sonarr.cdkauffmann.com
Type: unknownHost
Detail: No valid IP addresses found for sonarr.cdkauffmann.com

Domain: nextcloud.cdkauffmann.com
Type: unknownHost
Detail: No valid IP addresses found for nextcloud.cdkauffmann.com

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.
ERROR: Cert does not exist! Please see the validation error above. The issue may be due to incorrect dns or port forwarding settings. Please fix your settings and recreate the container

 

Link to comment

I'm definitely no expert on this, but it seems that you don't have your domain pointing to the correct IP address (your public IP) and/or port forwarding isn't setup correctly to send ports 80 and 443 to your servers private IP and ports for letsencrypt you set up. 

 

Are you using dynamic DNS or do you have a static public IP address?

Link to comment

new to all this so it takes me a little bit. I use duckdns so I am guessing it would be dynamic. How would I tell if my domain is pointing to the correct address and/or make sure port forwarding is working?  Are there some other screenshots I can take that would help you determine what the problem is? I am also getting my domain name from Godaddy, guessing that one of the dns records on their website is not set up correctly?

 

Edited by cdkauffmann
add more info
Link to comment
7 hours ago, guyonphone said:

Hello,

I have Unraid 6.6.6

I have Sabnzbd 2.3.5

It is reporting incorrect Values for Free Space. 

uvpJg8e.png

 

Any ideas on how to correct?

 

Thanks

 

What does this got to do with letsencrypt? 

Edited by saarg
Can't spell...
Link to comment

Do changes made on Godaddy go into effect right away or do I have to wait 24 hours? Still having problems and want to keep working on troubleshooting them but if it takes time for Godaddy, I don't want to start making more changes just to find out if I would have waited that everything was working. 

Edited by cdkauffmann
Link to comment
46 minutes ago, strike said:

I don't use sonarr, but in radarr you have to set the "base URL", I think you have to do the same in sonarr or else you'll be stuck at the loading screen.

Well, I was under the impression that was only needed for sub folder configuration (I'm using subdomains) , but I tried it anyways and still the same, unfortunately. 

 

Does anyone have this working with sonarr and radarr? Oddly enough, lidarr does work.

Link to comment
31 minutes ago, Coolsaber57 said:

Well, I was under the impression that was only needed for sub folder configuration (I'm using subdomains) , but I tried it anyways and still the same, unfortunately. 

 

Does anyone have this working with sonarr and radarr? Oddly enough, lidarr does work.

Are you using the preset proxy confs? 

Link to comment
4 hours ago, cdkauffmann said:

Do changes made on Godaddy go into effect right away or do I have to wait 24 hours? Still having problems and want to keep working on troubleshooting them but if it takes time for Godaddy, I don't want to start making more changes just to find out if I would have waited that everything was working. 

You can use dnschecker.org to see propagation

Link to comment
56 minutes ago, aptalca said:

This isn't the thread for the video guide so you'll have to provide more info on what exactly you did

oh man, I had this whole post written out detailing my steps when I noticed there there are two sections where i needed update the name of my container so that it resolves the right IP.  Updated the 2nd place (i use binhex's container) and it works great.  Sorry for wasting your time.

 

 

Edited by Coolsaber57
Link to comment
1 hour ago, Coolsaber57 said:

oh man, I had this whole post written out detailing my steps when I noticed there there are two sections where i needed update the name of my container so that it resolves the right IP.  Updated the 2nd place (i use binhex's container) and it works great.  Sorry for wasting your time.

 

 

Sounds like you just had to retrace your steps to identify the issue. 

 

Glad it works now 

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.