nginx/lets-encrypt: multiple SSL domains with the same webserver configuration - nginx

I manage a dozen or so domains with SSL certs that I have generated via lets-encrypt, and I use nginx to manage the web services for these domains.
It turns out that all of these domains need to have the same nginx configuration: i.e., the same location blocks, the same root, the same site parameters, etc.
The only thing which differs for each domain are the settings for ssl_certificate, ssl_certificate_key, and ssl_trusted_certificate.
The way I have handled this is to have a dozen or so server {} blocks within my nginx configuration, each of them containing almost the same data, except for those three SSL parameters.
For example ...
server {
error_log /var/log/nginx/error.log debug;
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl http2;
server_name example-domain0.com;
ssl_certificate /etc/letsencrypt/live/example-domain0.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example-domain0.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example-domain0.com/chain.pem;
ssl_session_cache shared:SSL:128m;
add_header Strict-Transport-Security "max-age=31557600; includeSubDomains";
ssl_stapling on;
ssl_stapling_verify on;
root /usr/share/nginx/html;
index index.php index.html index.htm;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
location ~ \.json {
add_header Content-Type text/plain;
}
location ~ ^/(t)($|/.*) {
alias $1$2;
include uwsgi_params;
uwsgi_pass unix:/var/run/uwsgi/flask/$1.sock;
}
location ~ ^/(css|static|hm|cy|img|sq|rc|rl|oc|m|js)($|/.*) {
root /usr/share/nginx;
}
location ~ ^/(junk)($|/.*) {
root /usr/share/nginx/html;
allow all;
autoindex on;
}
location ~ \.php$ {
include phpsite_params;
}
}
server {
error_log /var/log/nginx/error.log debug;
listen 80;
listen [::]:80;
listen 443 ssl http2;
server_name example-domain1.com;
ssl_certificate /etc/letsencrypt/live/example-domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example-domain1.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example-domain01.com/chain.pem;
ssl_session_cache shared:SSL:128m;
add_header Strict-Transport-Security "max-age=31557600; includeSubDomains";
ssl_stapling on;
ssl_stapling_verify on;
root /usr/share/nginx/html;
index index.php index.html index.htm;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
location ~ \.json {
add_header Content-Type text/plain;
}
location ~ ^/(t)($|/.*) {
alias $1$2;
include uwsgi_params;
uwsgi_pass unix:/var/run/uwsgi/flask/$1.sock;
}
location ~ ^/(css|static|hm|cy|img|sq|rc|rl|oc|m|js)($|/.*) {
root /usr/share/nginx;
}
location ~ ^/(junk)($|/.*) {
root /usr/share/nginx/html;
allow all;
autoindex on;
}
location ~ \.php$ {
include phpsite_params;
}
}
... and then a dozen or so blocks for example-domain2.com, example-domain3.com, etc. which are identical except for the domain names and the values of those SSL parameters.
This causes lots of problems if I ever want to make site configuration changes, because then I have to make identical changes in more than a dozen places within this configuration file, and sometimes that leads to errors.
Since each SSL domain requires its own ssl_certificate, ssl_certificate_key, and ssl_trusted_certificate, I'd like to create smaller server {} blocks with only that SSL configuration info, and then factor out the other, common configuration information and only keep it in one place.
Is that possible?
Thank you very much in advance.

Oh, I didn't realize that I could use the include directive outside of a location block.
The solution to my problem is this:
server {
error_log /var/log/nginx/error.log debug;
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl http2;
server_name example-domain0.com;
ssl_certificate /etc/letsencrypt/live/example-domain0.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example-domain0.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example-domain0.com/chain.pem;
include common/site-parms.conf;
}
server {
error_log /var/log/nginx/error.log debug;
listen 80;
listen [::]:80;
listen 443 ssl http2;
server_name example-domain1.com;
ssl_certificate /etc/letsencrypt/live/example-domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example-domain1.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example-domain1.com/chain.pem;
include common/site-parms.conf;
}
... and another dozen similar server {} blocks, with all the common stuff contained in /etc/nginx/common/site-parms.conf.

Related

Nginx Multiple Domains Same IP Not Working

I am having issues with Nginx not working with multiple domains pointing to the same IP address. When accessing either domain, they both default to "catacombsfellowship.org.cnf". When accessing edmunddesoto.com, it acts as if it is catacombsfellowship.org and I get an SSL cert error where the cert is for catacombsfellowship.org.
When I run either domain by themselves, they work fine. However, they don't work seamlessly together. What am I doing wrong?
Examples:
File: edmunddesoto.com.cnf
server {
listen 80;
listen [::]:80;
server_name edmunddesoto.com default_server;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name edmunddesoto.com default_server;
root /var/www/html/edmunddesoto.com/live;
index index.php index.html index.htm index.nginx-debian.html;
ssl_certificate /etc/ssl/certs/edmunddesoto.com.crt;
ssl_certificate_key /etc/ssl/private/edmunddesoto.com.key;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
File: catacombsfellowship.org.cnf
server {
listen 80;
listen [::]:80;
server_name catacombsfellowship.org default_server;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name catacombsfellowship.org default_server;
root /var/www/html/catacombsfellowship.org/live;
index index.php index.html index.htm index.nginx-debian.html;
ssl_certificate /etc/ssl/certs/catacombsfellowship.org.crt;
ssl_certificate_key /etc/ssl/private/catacombsfellowship.org.key;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php5.6-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Ok, I figured it out. The issue was somehow it was redirecting to the www.* domains and those were not set in the server_name directive. So, by adding the www.* to the server_name directive, it fixed it.

HTTPS redirect www to non www

I got 2 domains and its supposed to work from same directory. While redirecting from http with/without www works perfectly, https www to non www don't work. Here is my config file:
server {
listen 80;
server_name domain1.com www.domain1.com;
return 301 https://domain1.com$request_uri;
}
server {
listen 80;
server_name domain2.com www.domain2.com;
return 301 https://domain2.com$request_uri;
}
server {
listen 443 ssl;
server_name www.domain1.com;
return 301 https://domain1.com$request_uri;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
}
server {
listen 443 ssl;
server_name www.domain2.com;
return 301 https://domain2.com$request_uri;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
}
server {
listen 443 ssl;
server_name domain1.com;
root /var/www/domain1.com;
index index.php index.html index.htm;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
}
}
server {
listen 443 ssl;
server_name domain2.com;
root /var/www/domain1.com;
index index.php index.html index.htm;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
}
}
Can you tell me what could be wrong with it? SSL certificate domain1.com have got inside certificates for all domains, include with/without WWW.
In case if someone will face to same issue, removal of "ssl" abbreviate fixed it. So instead of listen 443 ssl; in 301 server blocks change to listen 443;

Nginx re-directions from "www" to "non www" and from "http" to "https"?

I have my app hosted in the base URL: https://myapp.com/
Now I want to add re-directions from "www" to "non www" / "http" to "https", where:
https://myapp.com/
https://www.myapp.com/
http://myapp.com/
http://www.myapp.com/
Last 3 URLs should 301 redirect to the first one.
Right now second URL is not redirected and the last 2 are redirected using a 307 redirection instead of 301.
Here is my nginx configuration:
server {
listen 80;
server_name myapp.com www.myapp.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name myapp.com www.myapp.com;
server_tokens off;
ssl_certificate /etc/nginx/conf.d/self-signed-fullchain.pem;
ssl_certificate_key /etc/nginx/conf.d/self-signed-privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/conf.d/ssl-dhparams.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~ ^/(api)/ {
proxy_pass http://myapp:3000;
}
}
So how can I actually do this?
Just add one more server block with server_name www.myapp.com;, and add redirect:
return 301 https://myapp.com$request_uri;
Edit main server block to server_name myapp.com;
Should be something like that:
server {
listen 80;
server_name myapp.com www.myapp.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name www.myapp.com;
server_tokens off;
ssl_certificate /etc/nginx/conf.d/self-signed-fullchain.pem;
ssl_certificate_key /etc/nginx/conf.d/self-signed-privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/conf.d/ssl-dhparams.pem;
return 301 https://myapp.com$request_uri;
}
server {
listen 443 ssl;
server_name myapp.com;
server_tokens off;
ssl_certificate /etc/nginx/conf.d/self-signed-fullchain.pem;
ssl_certificate_key /etc/nginx/conf.d/self-signed-privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/conf.d/ssl-dhparams.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~ ^/(api)/ {
proxy_pass http://myapp:3000;
}
}

Nginx HTTPS SSL redirection doesn't work in Ubuntu 18.04

I've tired to configure an Nginx server with SSL but the site is not open but with https:// it's open normally.
Here is my Nginx configuration:
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
client_max_body_size 20M;
root /var/www/mysite.in/site;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm;
server_name _;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
}
listen 443;
listen [::]:443;
server_name www.mysite.com;
#ssl on;
ssl_certificate /etc/nginx/ssl/mysite.com.chained.crt;
ssl_certificate_key /etc/nginx/ssl/main_private.key;
}
The SSL was generated in GoDaddy, I've found lots of solutions, but so far none of them are working.
How can I resolve this error?
You have to create two servers(http and https) in your config and create redirect from http to https:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name www.mysite.com;
return 301 https://$host$request_uri;
}
server {
listen 443;
listen [::]:443;
server_name www.mysite.com;
client_max_body_size 20M;
root /var/www/mysite.in/site;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm;
server_name _;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
}
ssl on;
ssl_certificate /etc/nginx/ssl/mysite.com.chained.crt;
ssl_certificate_key /etc/nginx/ssl/main_private.key;
}

.php files are downloaded instead of displayed

First of all, yes there are lots of questions like these but none of the solutions worked for me.
I have a similar server to compare to and I looked at the configs and it seems to work, whereas this new setup doesn't.
I already tried mendling with the configs without any prevail.
My nginx.conf:
[default content]
#I just appended this line:
client_max_body_size 10M;
My virtual host file:
server {
listen 80;
listen [::]:80;
# root /var/www/mywebsite.com/public_html;
# index index.html;
server_name mywebsite.com www.mywebsite.com;
# access_log /var/log/nginx/mywebsite.com.access.log;
# error_log /var/log/nginx/mywebsite.com.error.log;
include snippets/letsencrypt.conf;
return 301 https://$host$request_uri;
# location / {
# try_files $uri $uri/ =404;
}
server {
listen 443 ssl http2;
server_name www.mywebsite.com;
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/mywebsite.com/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
return 301 https://mywebsite.com$request_uri;
}
server {
listen 443 ssl http2;
server_name mywebsite.com;
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/mywebsite.com/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
root /var/www/mywebsite.com/public_html;
index index.php;
# . . . other code
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
}
#location / {
# try_files $uri $uri/ /index.php?$args;
#}
#location ~ \.php$ {
# fastcgi_split_path_info ^(/wordpress)(/.*)$;
#}
include snippets/phpmyadmin.conf;
}
P.S Yes, I am using WordPress.
So it seems that it was just a cache issue so I had to wait and it worked afterwards. The config is OK. Case closed.

Resources