Nginx 作为反向代理与 acme (letsencrypt)

来自 Alpine Linux

简介

此设置将允许您通过单个 IP 地址访问多个服务器/容器,并额外提供集中生成 letsencrypt 证书和安全的 https (根据 ssllabs ssltest)。请注意,您首先需要设置一个常规的 HTTP 服务器,以便能够生成 HTTPS 证书和密钥。在您生成它们之后,您可以添加基于 HTTPS 主机的配置。

有关 Nginx 的一般信息、启动/停止服务等,请参阅 NGINX 页面。

安装

对于本指南,我们需要三个工具:NGINXacme-clientopenssl(用于生成 Diffie–Hellman 参数)。

apk update apk add nginx acme-client openssl

设置

NGINX HTTP

全局配置

第一步是重构我们的全局 nginx.conf。其目标是低流量 http 服务器,为了提高性能,请在顶层进行更改。

内容为 /etc/nginx/nginx.conf

# /etc/nginx/nginx.conf user nginx; worker_processes 1; # use "auto" to use all available cores (high performance) # Configures default error logger. error_log /var/log/nginx/error.log warn; # Log warn, error, crit, alert, emerg events { # The maximum number of simultaneous connections that can be opened by a worker process. worker_connections 1024; # increase if you need more connections } http { # server_names_hash_bucket_size controls the maximum length # of a virtual host entry (ie the length of the domain name). server_names_hash_bucket_size 64; # controls the maximum length of a virtual host entry (ie domain name) server_tokens off; # hide who we are, don't show nginx version to clients sendfile off; # can cause issues # nginx will find this file in the config directory set at nginx build time # Includes mapping of file name extensions to MIME types of responses include mime.types; # fallback in case we can't determine a type default_type application/octet-stream; # buffering causes issues, disable it # increase buffer size. still useful even when buffering is off proxy_buffering off; proxy_buffer_size 4k; # allow the server to close the connection after a client stops responding. Frees up socket-associated memory. reset_timedout_connection on; # Specifies the main log format. log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # Sets the path, format, and configuration for a buffered log write. # Buffer log writes to speed up IO, or disable them altogether access_log /var/log/nginx/access.log main buffer=16k; #access_log off; # include virtual hosts configs include conf.d/*.conf; }

SSL 配置

配置一个包含所有 SSL 参数的文件,我们可以在以后的虚拟主机配置中包含它。
安全设置的灵感来自 Mozilla SSL 配置生成器。另请阅读 https://hstspreload.org,了解有关 HSTS 的详细信息。

内容为 /etc/nginx/conf.d/ssl-params.inc

# secure nginx, see https://ssl-config.mozilla.org ssl_protocols TLSv1.3 ssl_prefer_server_ciphers off; ssl_session_timeout 1d; 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; # https://hstspreload.org add_header Strict-Transport-Security "max-age=63072000" always; # By default, HSTS header is not added to subdomain requests. If you have subdomains and want # HSTS to apply to all of them, you should add the includeSubDomains variable like this: #add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none;

每个站点配置文件 (conf.d)

自 Alpine v3.5 起,我们在 /etc/nginx/conf.d 目录中附带了 NGINXdefault.conf

要为另一个网站添加支持,您可以将扩展名为 .conf 的文件添加到此目录

内容为 /etc/nginx/conf.d/alpinelinux.org.conf

server { listen 80; server_name alpinelinux.org; location / { include conf.d/proxy_set_header.inc; proxy_pass http://downstream_http_server_host; } }

通用配置包含

如果您需要设置多个代理设置,您可以包含重复的数据,如下所示

内容为 /etc/nginx/conf.d/proxy_set_header.inc

proxy_set_header X-Forwarded-By $server_addr:$server_port; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host;


acme-client

为了使 NGINX 支持 https,我们需要添加证书和对 ACME(自动证书管理环境)响应的支持。

ACME 响应

内容为 /etc/nginx/conf.d/acme.inc

# Allow access to the ACME Challenge for Let's Encrypt location ^~ /.well-known/acme-challenge { allow all; alias /var/www/acme; }

并将此添加到您的代理配置中

内容为 /etc/nginx/conf.d/alpinelinux.org.conf

server { listen 80; server_name alpinelinux.org; include conf.d/acme.inc; location / { include conf.d/proxy_set_header.inc; proxy_pass http://downstream_http_server_host; } }

自动生成证书

创建以下文件

内容为 /etc/periodic/weekly/acme-client

#!/bin/sh hosts="alpinelinux.org" for host in $hosts; do acme-client -a https://letsencrypt.openssl.ac.cn/documents/LE-SA-v1.2-November-15-2017.pdf -Nnmv $host && renew=1 done [ "$renew" = 1 ] && rc-service nginx reload

使其可执行

chmod +x /etc/periodic/weekly/acme-client

此脚本将每周运行,以验证您的证书是否已过期,并在需要时续订它们。

如果您有多个域名,您可以将它们添加到 hosts= 变量中,每个域名之间用空格分隔。这将为每个域名创建单独的证书和密钥

hosts="alpinelinux.org example.com foo.org bar.io"

初始生成密钥和证书

要创建初始证书和密钥,您必须在第一次手动运行此命令

/etc/periodic/weekly/acme-client

观看输出,看看是否一切顺利。完成后,您应该在以下位置拥有文件

/etc/ssl/acme/alpinelinux.nl/fullchain.pem
/etc/ssl/acme/private/alpinelinux.org/privkey.pem


NGINX HTTPS

每个站点的 HTTPS 配置

在前一个 HTTP 配置下方添加以下内容

内容为 /etc/nginx/conf.d/alpinelinux.org.conf

server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name alpinelinux.org ssl on; ssl_certificate /etc/ssl/acme/alpinelinux.org/fullchain.pem; ssl_certificate_key /etc/ssl/acme/private/alpinelinux.org/privkey.pem; include /etc/nginx/conf.d/ssl-params.inc; # SSL 参数 location / { include conf.d/proxy_set_header.inc; proxy_pass http://downstream_http_server_host; } }

将 HTTP 重定向到 HTTPS

共享配置

创建以下文件

内容为 /etc/nginx/conf.d/redirect_http.inc

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

更新主机配置

内容为 /etc/nginx/conf.d/alpinelinux.org.conf

server { listen 80; server_name alpinelinux.org; include conf.d/acme.inc; include conf.d/redirect_http.inc; }


包含 IPv6 支持的完整主机示例

内容为 /etc/nginx/conf.d/alpinelinux.org.conf

server { listen 80; listen [::]:80; server_name alpinelinux.org; include conf.d/acme.inc; include conf.d/redirect_http.inc; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name alpinelinux.org; ssl on; ssl_certificate /etc/ssl/acme/alpinelinux.org/fullchain.pem; ssl_certificate_key /etc/ssl/acme/private/alpinelinux.org/privkey.pem; include /etc/nginx/conf.d/ssl-params.inc; # SSL 参数 location / { include conf.d/proxy_set_header.inc; proxy_pass http://downstream_http_server_host; } }