从 Let's Encrypt 请求您的初始证书

从 Let's Encrypt 请求您的初始证书

介绍

我有一台开发服务器(目前运行的是 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

是的,您可以将其用作nginxhttps 的端点并通过 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

相关内容