相信有上线过自己的网站、小程序经验的同学深有体会,给服务加上 SSL 证书还挺麻烦的,尤其是没有运维经验的同学。本来最省事的方法是买个证书,但是一看价格,还是算了吧,动辄就是几万块一年。作为个人来说,这跟抢钱有什么区别。
现在不管是网站、小程序还是其他的需要请求后端服务的地方,基本都要求 HTTPS 协议了,就拿小程序来说,如果你的服务接口不是 HTTPS 协议,都没办法发布。
以前只要你买一个云服务器就能每年领一个证书,现在能领一年免费证书的云厂商几乎没有了,所以只能自己想办法了。
目标只有一个,免费又简单。
我上线的所有网站和小程序都是用今天要介绍的方式配置的,简单又方便。
接下来演示一下给一个网站配置 HTTPS 和 SSL 免费证书的整个过程。
好的,正文开始。
安装 Nginx
注意,下面的所有操作都是基于 Ubuntu 22.04完成。
使用如下命令安装 Nginx,注意,使用这种方式安装的不是最新版的 Nginx,如果安装最新版Nginx 还需要使用其他方式,比如源码安装、使用特定的安装源等。
sudo apt install -y nginx
安装完成后,使用 systemctl status nginx可以查看 Nginx 的状态,看到active(running) 表示成功启动了。
这时候防火墙如果没有限制的话,直接访问 ip 会看到 Nginx 默认首页。
下面是 Nginx 常用的命令,包括查看状态、启动、停止、重启和设置开机启动。
## 查看状态 systemctl status nginx # 启动 systemctl start nginx # 停止 systemctl stop nginx # 重启 systemctl restart nginx # 设置开机启动 systemctl enable nginx
配置文件
稍后设置 HTTPS 和证书会修改配置文件,所以配置文件在哪儿必须要搞清楚,这也算是基础中的基础了。通过 whereis nginx命令就可以看到 nginx 所有文件的目录。
一般情况下,系统自动安装的 Nginx,默认配置在/etc/nginx目录下,里面包含了各种配置信息,其中 nginx.conf是主配置文件,也是我们常用的配置各种参数、服务器、主机、HTTPS 这些的地方。
而在比较新版本的 Nginx 中关于 HTTP 和 HTTPS 主机配置的部分建议放到 /etc/nginx/sites-enabled 里,在 nginx.conf中有 include /etc/nginx/sites-enabled/*;对这个目录所有配置文件的引用。当然了,你都配置在 nginx.conf中也完全没关系。
配置域名和Server
解析域名
首先到你购买域名的服务商那里给你想要使用的域名添加一个解析,记录类型为 A ,表示将域名解析到一个 IP 地址上。
codeuphub.com是我要用的域名,这样解析完之后,使用ping命令ping这个域名,有如下结果表示解析生效了。
配置 HTTP Server 验证
接下来我在服务器根目录创建一个web子目录,当做网站的根目录,并且在其中放入你的网站内容,这里为了方便演示,我只放了一个 index.html文件。
然后打开 /etc/nginx/sites-enabled/default这个配置文件(当然了,你也可以放到 nginx.conf中),找到其中 listen 为80的 server 节点,这就是控制 HTTP 协议请求的配置。
修改内容如下,注意 location节点下,root 配置上网站的根目录,也就是我创建的 web 目录。
server { listen 80 default_server; listen [::]:80 default_server; root /web; server_name _; location / { try_files $uri $uri/ =404; } }
然后使用systemctl restart nginx 重启 Nginx,或者使用 nginx -s reload重新加载一下。
然后访问域名,我的域名是 http://tools66.online,就可以看到 web目录中的页面了。
试一下 HTTPS
接下来,我们配置一个 HTTPS 的Server,也就是监听 443 端口的。像下面这样配置,然后重启 Nginx 。
server { listen 443 ssl; listen [::]:443 ssl; server_name tools66.online; client_max_body_size 100m; location / { root /web; index index.html; } }
毋庸置疑,出现的结果肯定是下面这样。
原因就是没有 SSL 证书,接下来就到重点了,开始配置免费的 SSL 证书。
配置 SSL 证书
现在有很多免费的 SSL 证书网站可供选择,例如ZeroSSL、LetSencrypt 等等,每个网站都提供了申请免费证书的方式,但是现在的所有免费证书都只有 3 个月的有效期,过期就要重新申请,重新配置。而且申请免费证书需要专门的客户端工具,整套流程下来,很麻烦。
在IT圈中,任何操作复杂的工具最终都会被抽象得越来越简单。acme 就是将申请免费证书、自动部署这个过程简单化的工具,并且可以自动续期,也就是在证书到达有效期之前自动申请新证书,自动部署使其生效,让你感觉不到证书其实已经换了。
安装 acme
在服务器上,使用下面的命令行快速安装acme,email 配置为你自己的邮箱。
curl https://get.acme.sh | sh -s email=my@example.com
然后稍等片刻,如下图,出现Install success 的提示表示安装成功了。通过安装日志,可以看到安装目录,并且还看到创建一个 cron job,这个job就是自动更新证书的定时任务。
还有一种克隆仓库的安装方式。
git clone https://github.com/acmesh-official/acme.sh.git cd ./acme.sh ./acme.sh --install
安装位置在这里,也就是当前用户home目录中。
Installing to /root/.acme.sh Installed to /root/.acme.sh/acme.sh Installing alias to '/root/.bashrc'
acme生成证书
初次使用,可能需要注册账号,一个邮箱即可(此步可先跳过,等到执行具体命令时如果提示,再注册不迟)
acme.sh --register-account -m huzhichenghigher@126.com
acme 默认使用的是 ZeroSSL,但是 ZeroSSL 不是很稳定,如果可能的话,可以切换到letsencrypt,当然了,不切换也无所谓。
acme.sh --set-default-ca --server letsencrypt
生成证书
有两种方式生成证书,一种是 HTTP 方式,另一种是 DNS 方式。
比较推荐使用 DNS 方式,域名不用备案,而且可以自动更新续期。
HTTP 方式
下面这个命令是 HTTP 方式,-d 后面是域名,--webroot 后面是网站根目录。这种方式会在你的服务器根目录生成一个验证文件,然后通过80端口访问
但是先别着急执行啊,这种方式在国内有个问题,就是你的域名必须要先备案,要不然 80 端口会被工信部的未备案提示页面拦截,导致没办法生成证书。
所以域名在国内或者服务器在国内,最好还是别用这种方式。
acme.sh --issue -d tools66.online --webroot /web/
DNS 方式和自动更新
这种方式是比较推荐的方式,不管你的域名在阿里云还是什么平台,你不需要任何服务器, 不需要任何公网 ip, 只需要 dns 的解析记录即可完成验证。有一些服务是不提供服务器的,只要根据他们的规则就可以运行服务,例如 GitHub Page、Vercel这些,所以,没办法进到服务器中,不能用 HTTP 方式验证,因为HTTP方式需要在服务器生成文件。
在这里 https://github.com/acmesh-official/acme.sh/wiki/dnsapi2 ,可以看到所支持的域名供应商,只要能在这里面找到的,都支持 DNS 方式验证,基本上市面上你能买到域名的地方都可以用这种方式,阿里云、华为云、腾讯云等等都在其中,里面有具体的参数说明。
以阿里云为例,因为我这个域名 tools66.online是在阿里云买的。
在 https://ram.console.aliyun.com/manage/ak 这个页面中,生成一个 key 和 secret,然后将这两个值导入环境变量。
export Ali_Key="LTAIcccc" export Ali_Secret="pIRISKS15ffd"
之后再执行生成证书的命令。
acme.sh --issue --dns dns_ali -d tools66.online
当看到以下结果时,表示证书生成成功了
安装和配置 SSL 证书
接下来打开 /etc/nginx/sites-enabled/default,修改前面配置的 HTTPS Server 的部分,主要就是加入了 ssl_certificate 和 ssl_certificate_key ,指定了/etc/nginx/ssl目录下,这个目录要提前创建好,acme不会自动创建的。
server { listen 443 ssl; listen [::]:443 ssl; server_name tools66.online; ssl_certificate /etc/nginx/ssl/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/tools66.online.key; client_max_body_size 100m; location / { root /web; index index.html; } }
然后就到了最后一步,将acme生成的证书拷贝证书到指定目录。
证书生成后会在 acme 的默认目录下,但是不建议直接使用这个目录下的文件,所以,要使用下面的命令将证书拷贝到指定的位置。
然后执行下面的命令来将证书复制到前面 Nginx 配置中指定的证书目录中,注意最后 --reloadcmd 命令里是做了 Nginx 强制重载的操作。
acme.sh --installcert -d tools66.online \ --key-file /etc/nginx/ssl/tools66.online.key \ --fullchain-file /etc/nginx/ssl/fullchain.cer \ --reloadcmd "service nginx force-reload"
当出现下面的结果时,就表示成功了。
这时候,再次访问 https 的地址,就能正常看到页面了。
你现在访问 https://www.codeuphub.coom 这个地址,就是用这个方式安装的 SSL 证书。
自动更新acme
现在证书已经可以自动更新了,但是 acme 还没有。因为各个免费 SSL 证书平台的规则不是一成不变的,随着他们的更新,acem也会相应的修改规则。
所以,你可以在服务器上执行下面的命令,设置acme 自动升级,保证可用性。
acme.sh --upgrade --auto-upgrade