![从 Let's Encrypt 请求您的初始证书](https://linux22.com/image/680196/%E4%BB%8E%20Let's%20Encrypt%20%E8%AF%B7%E6%B1%82%E6%82%A8%E7%9A%84%E5%88%9D%E5%A7%8B%E8%AF%81%E4%B9%A6.png)
介绍
我有一台开发服务器(目前运行的是 Ubuntu 14.04 LTS),我已经使用它一段时间了,用于在不同的端口上托管各种开发工具。由于端口可能很难记住,我决定为我的所有服务使用端口 80,并根据主机名在内部进行端口转发。
我不需要写 domain.com:5432,而是可以直接通过 sub.domain.com 来访问它。
例如,使用端口 7547 并在 sub.domain.com 上运行的应用程序 X 具有以下 nginx 配置:
upstream sub {
server 127.0.0.1:7547;
}
server {
listen 80;
server_name sub.domain.com www.sub.domain.com;
access_log /var/log/nginx/sub.log combined;
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_pass http://127.0.0.1:7547;
proxy_set_header Authorization "";
}
}
问题
鉴于我选择的当前配置结构,是否可以使用 letsencrypt 并在 https 下运行不同的服务?
答案1
是的,你可以让 nginx 代理向 HTTP 服务器发出请求,然后它自己通过 HTTPS 响应客户端。在执行此操作时,你需要确保 nginx<->proxy 连接不太可能被你预期的攻击者嗅探到。足够安全的方法可能包括:
- 代理到同一主机(和你一样)
- 代理到防火墙后面的其他主机
代理到公共互联网上的另一台主机可能不够安全。
以下是使用与代理相同的 Web 服务器获取 Let's Encrypt 证书的说明。
从 Let's Encrypt 请求您的初始证书
修改您的子句以允许从本地目录提供server
子目录服务,例如:.well-known
server {
listen 80;
listen [::]:80;
server_name sub.domain.com www.sub.domain.com;
[…]
location /.well-known {
alias /var/www/sub.domain.com/.well-known;
}
location / {
# proxy commands go here
[…]
}
}
http://sub.domain.com/.well-known
是 Let's Encrypt 服务器寻找其发布的挑战的答案的地方。
然后您可以使用certbot客户端使用网页根目录插件(作为 root):
certbot certonly --webroot -w /var/www/sub.domain.com/ -d sub.domain.com -d www.sub.domain.com
您的密钥、证书和证书链现在将安装在/etc/letsencrypt/live/sub.domain.com/
配置 nginx 以使用你的证书
首先创建一个新的服务器子句,如下所示:
server {
listen 443 ssl;
listen [::]:443 ssl;
# if you wish, you can use the below lines for listen instead
# which enables HTTP/2
# requires nginx version >= 1.9.5
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
server_name sub.domain.com www.sub.domain.com;
ssl_certificate /etc/letsencrypt/live/sub.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sub.domain.com/privkey.pem;
# Turn on OCSP stapling as recommended at
# https://letsencrypt.org/docs/integration-guide/
# requires nginx version >= 1.3.7
ssl_stapling on;
ssl_stapling_verify on;
# Uncomment this line only after testing in browsers,
# as it commits you to continuing to serve your site over HTTPS
# in future
# add_header Strict-Transport-Security "max-age=31536000";
access_log /var/log/nginx/sub.log combined;
# maintain the .well-known directory alias for renewals
location /.well-known {
alias /var/www/sub.domain.com/.well-known;
}
location / {
# proxy commands go here as in your port 80 configuration
[…]
}
}
重新加载 nginx:
service nginx reload
https://sub.domain.com
通过访问https://www.sub.domain.com
您的浏览器(以及您特别希望支持的任何其他浏览器)并检查它们是否报告证书错误来验证 HTTPS 现在是否正常工作。
推荐:另请查看raymii.org:nginx 上的强 SSL 安全性 并测试您的配置SSL 实验室。
(推荐)将 HTTP 请求重定向到 HTTPS
一旦您确认您的网站可以使用该版本的 URL,就应该将用户重定向到该网站的 HTTPS 版本,https://
以避免因为某些用户访问 而向他们提供不安全的内容。http://sub.domain.com
将整个端口 80server
子句替换为:
server {
listen 80;
listen [::]:80;
server_name sub.domain.com www.sub.domain.com;
rewrite ^ https://$host$request_uri? permanent;
}
您现在还应该取消注释端口 443 配置中的此行,以便浏览器记住不要尝试该站点的 HTTP 版本:
add_header Strict-Transport-Security "max-age=31536000";
自动续订证书
您可以使用此命令(以 root 身份)更新 certbot 已知的所有证书,并使用新证书(与您现有的证书具有相同的路径)重新加载 nginx:
certbot renew --renew-hook "service nginx reload"
certbot 只会尝试更新超过 60 天的证书,因此运行此命令是安全的(并且推荐!)非常有规律,并尽可能自动执行。例如,您可以在 中输入以下命令/etc/crontab
:
# at 4:47am/pm, renew all Let's Encrypt certificates over 60 days old
47 4,16 * * * root certbot renew --quiet --renew-hook "service nginx reload"
您可以使用试运行来测试续订,这将联系 Let's Encrypt 暂存服务器来对联系您的域进行真正的测试,但惯于存储生成的证书:
certbot --dry-run renew
或者,您可以通过以下方式强制提前续订:
certbot renew --force-renew --renew-hook "service nginx reload"
注意:您可以根据需要多次试运行,但真正的续订需要Let's Encrypt 速率限制。
答案2
是的,您可以将其用作nginx
https 的端点并通过 http 与后端协作。例如我的配置:
server {
server_name host;
listen 443 ssl;
...
location /svn/ {
auth_ldap 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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:1080/svn/;
proxy_redirect http://localhost:1080/ https://host/;
}
...
}
但据我所知,使用 let's encrypt 时,您必须在获取证书时指向所有子域,如果这是一个问题,那么您可以选择 urlhttps://host/service
而不是https://service.host