欢迎光临
我们一直在努力

使用 Let's Encrypt 和 Nginx 从同一服务器托管多个 HTTPS 域名

现在网站越来越需要 HTTPS,而这正是顺应了发展趋势。Chrome 现已将带有密码或信用卡字段的 HTTP 网站明确标记为“不安全的”。在过去的一年里,我一直在将我的客户端网站切换到 HTTPS 上。事实证明,作为系统管理员的工作总是这样做,也存在与此相关的隐藏的挑战。

在我们深入下面的细节之前,我们先弄清写这篇文章的目的。

从同一服务器上托管多个 HTTPS 网站的问题与 HTTPS 连接的建立方式有关。安全的(读取:不是pwned)HTTPS 是在 TLS 上运行。当 TLS 连接建立时,我们倾向于认为它是与网站构建的。在技术上这是不正确的。 TLS 连接是连接到特定的 IP 地址。一旦你连接到那个 IP,服务器会假定这就是你想访问的网站。这意味着您不能在同一 IP 地址的主机上托管的多个 HTTPS 网站。

SNI(服务器名称标识)是一项在 21 世纪初期就被引入的协议,引入的目的就是为了解决这个问题。它是一种用于在浏览器设置一个 TLS 连接时向网页服务器发送一个域名的方法。通过在初次握手阶段传入域名,网页服务器就可以知道你想要访问的是哪一个域,从而让其为正确的那一个提供服务。

不过尽管其已经得到了广泛的支持,但也有不被支持的情况。我自己就曾在处理对 SNI 的依赖时掉进了移动端浏览器的坑。从另外一方面来看,IP 地址是廉价的,好像是 1 $/月,或者还要更便宜。因此你索性可以为你的 HTTPS 站点单独弄一个 IP,这样做所避免掉的一些在终端/浏览器组合上遇到的头疼事儿,花费的代价可能百倍不止。

对于初学者而言,首先需要给每一个你准备从同一台服务器上托管在 HTTPS 上的域名获取一个 IP。大多数像 Linode 以及 AWS 这样的托管平台都提供了为任何东西添加 IP 的能力。

$ ping you.new.ip.addr PING you.new.ip.addr (you.new.ip.addr): 56 data bytes Request timeout for icmp_seq 0 Request timeout for icmp_seq 1 ...
# Something like this probably already exists auto eth0 iface eth0 inet static address X.X.X.X/24 gateway X.X.X.1 dns-nameservers 8.8.8.8 8.8.4.4 dns-search your.dns.info dns-options rotate
# Add support for our new IP addresses iface eth0:1 inet static address Y.Y.Y.Y/24 dns-nameservers 8.8.8.8 8.8.4.4 iface eth0:2 inet static address Z.Z.Z.Z/24 dns-nameservers 8.8.8.8 8.8.4.4

尽管我在之前已经说的很详细了,但是在这里我还是想再提一点。使用 Let’s Encrypt,我们有几种选择来取得证书。

# First we need the Let's Encrypt bin sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
# Get a cert for a domain (include all subdomains that apply to this file path, including www) /opt/letsencrypt/letsencrypt-auto certonly --webroot \ -d 'mysite.com,www.mysite.com' -w /var/www/mysite/public # Get a cert for a domain and subdomain with different filesystem paths /opt/letsencrypt/letsencrypt-auto certonly --webroot \ -d 'mysite.com,www.mysite.com' -w /var/www/mysite/public \ -d 'blog.mysite.com' -w /var/www/mysite_blog/ # Get a cert for an entirely new domain name /opt/letsencrypt/letsencrypt-auto certonly --webroot \ -d 'newsite.com,www.newsite.com' -w /var/www/newsite/public

接下来,我们需要做一点 HTTPS 配置的修改,目的是使 nginx 从 域名+端口 认证方法切换到一种 ip+端口 的认证系统。这是在我们 HTTPS 服务器模块中改变监听(listen)指令最简单的配置方式 (并且在我的使用中一直没有问题) 。

server { # Old method: # listen 443 ssl; # Ip-based: listen X.X.X.X:443 ssl; server_name: mysite.com www.mysite.com; # ... }

最后,当我们在服务器上维护多个站点时,我们真的应该依赖某种方法自动更新我们的 Let’s Encrypt 证书。没人愿意每三个月去手动更新一次。很幸运,Let’s Encrypt 官方提供了一段代码来处理这个问题 ,而我们只需要创建一个计划任务,采用 cron 定时任务命令定期自动运行(这段代码) 。现在,我们创建一个文件 /etc/letsencrypt/auto_renew.sh。把下面的代码添加进来,你也可以自己做些修改,实现你想要的功能。

#!/bin/sh # This script renews all the Let's Encrypt certificates with a validity < 30 days if ! /opt/letsencrypt/letsencrypt-auto renew > /var/log/letsencrypt/renew.log 2>&1 ; then echo Automated renewal failed: cat /var/log/letsencrypt/renew.log exit 1 fi nginx -t && nginx -s reload
@daily /etc/letsencrypt/auto_renew.sh

技术革新领域正在飞速发展,尽管这种发展在用户的隐私和安全方面并无助益。虽然没有明确言明,但是用户变成客户的过程在交互中已经隐含了双方的信任。不管是作为开发人员、工程师还是系统管理员,我们都有责任保障用户权益。

保障用户用 app 发出的任何连接都安全可靠是最佳方案。显然,没有一定程度上安全的连接难以轻松实现。Let’s Encrypt 巧妙降低了进入开发领域的壁垒,成为开发人员亟需掌握的一步。由此可知,所有以避免为客户网站提供安全支持为目的的借口都是疏忽和无知。

希望本文对解决问题有所助益。

总结:如果你对从一个服务器托管多个 HTTPS 域名一无所知,使用 Let’s Encrypt 和 Nginx 吧!轻松解决问题。

赞(0)
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:使用 Let's Encrypt 和 Nginx 从同一服务器托管多个 HTTPS 域名
文章链接:https://www.jmwz.net/1074.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
分享到: 更多 (0)