Nginx 设置多个域与单个 ssl 证书到相同的上游

Nginx Setup for Multiple domains with individual ssl certificates to same upstream

所以我有多个域,其中有多个 let's encrypt ssl 证书(每个域一个),它们都指向同一个应用程序(上游)。目前我正在使用下面的代码。然而,它是相当多的代码,特别是如果我必须为每个域复制它。所以我想知道是否有一种方法可以将它组合起来,这样我就可以只用一次代码,这样可以更容易维护。

https://www.any-domain-here 的重定向有问题,最后一个主服务器块也有问题,因为两者都需要 ssl 证书,我需要包括所有不同域的证书。那么有没有一种方法可以在不复制这些代码块的情况下做到这一点?

############################
#
# Upstream
#
upstream upstream {
    least_conn;
    server app:8080;
}
upstream blog.upstream {
    least_conn;
    server app_nginx;
}
############################
#
# redirect all 80 to 443
# and allow Let's Encrypt
#
server {
    server_name ~.;
    listen 80;
    listen [::]:80;
    # config for .well-known
    include /etc/nginx/includes/letsencrypt.conf;

    location / {
        return         301 https://$host$uri;
    }
}
############################
#
# Redirect all www to non-www
#
server {
    server_name "~^www\.(.*)$" ;
    return 301 https://$request_uri ;
    ssl_certificate /etc/letsencrypt/live/www.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.domain.com/privkey.pem;
}
##########################
# HTTPS
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name domain.com;

    location /blog/ {
        proxy_set_header Host $host;
        proxy_pass  http://blog.upstream;
    }

    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
    # access_log
    access_log            /var/log/nginx/access.log;
    # proxy_pass config
    location / {
        # include proxy presets
        include /etc/nginx/includes/proxy.conf;
        proxy_pass              http://domain.com$uri;
    }
    # general ssl parameters
    include /etc/nginx/includes/ssl-params-with-preload.conf;

    root         /var/www/html;
}

我通过创建很多包含文件解决了这个问题。

我现在有以下default.conf

# don't redirect proxy
proxy_redirect  off;
# turn off global logging
access_log off;
# DON'T enable gzip as it opens up vulnerabilities
# logging format
log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';
############################
#
# redirect all 80 to 443
# and allow Let's Encrypt
#
server {
  listen 80;
  listen [::]:80;
  server_name ~. ;

  location /.well-known/acme-challenge {
    root /var/www/html;
    default_type text/plain;
    # allow all;
  }

  location / {
    return 301 https://$host$uri;
  }
}
# include website configs
include /etc/nginx/includes/nginx-server.conf;

我的nginx-server.conf内容如下:

############################
#
# Upstream
#
upstream veare_upstream {
    server veare:8080;
}
############################
#
# redirect all 80 to 443
# and allow Let's Encrypt
#
server {
    server_name www.veare.de;
    listen 80;
    listen [::]:80;

    root /var/www/html;

    location /.well-known/acme-challenge {
        default_type text/plain;
    }

    location / {
        return         301 https://$host$uri;
    }
}
############################
#
# Redirect all www to non-www
#
server {
    listen 80;
    listen [::]:80;
    server_name "~^www\.(.*)$" ;
    return 301 https://$request_uri;
}
##########################
# HTTPS
include /etc/nginx/includes/domains/*.conf;

最后一行包括我所有的域文件,例如一个是 veare.de.conf 它们的命名都与域完全一样:

############################
#
# Redirect all www to non-www
#
#
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.veare.de;
    ssl_certificate /etc/letsencrypt/live/www.veare.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.veare.de/privkey.pem;
    return 301 https://veare.de$request_uri;
}
##########################
# HTTPS
server {
    server_name veare.de;
    ssl_certificate /etc/letsencrypt/live/veare.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/veare.de/privkey.pem;

    location ^~ /.well-known/acme-challenge {
      allow all;
      # Set correct content type. According to this:
      # https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29
      # Current specification requires "text/plain" or no content header at all.
      # It seems that "text/plain" is a safe option.
      default_type "text/plain";
      root /var/www/html;
    }

    include /etc/nginx/includes/main-server.conf;
}

这非常适合我。