Let‘s Encrypt免费证书的应用示例

前言

最近在搞苹果应用上架的问题,据说用HTTP会被拒,但貌似不绝对,2017年苹果曾发公告说必须要求HTTPS,紧接着便说延缓这个决定,也就是说现在用HTTP也不一定会被限制,但是确实存在风险,所以想着最近把HTTP请求升级成HTTPS,本着折腾的精神(其实还是穷)搞一搞免费证书,Let’s Encrypt 这个组织之前一篇文章《使用 Let’s Encrypt 获取免费SSL证书》 曾讲到过,我们今天来说下这个证书怎么用,算是给我自己出个教程,拯救一下我记忆力减退的大脑~

证书申请

使用Let’s Encrypt申请SSL证书,可以选择 DNS-01 验证或者 HTTP-01 验证,其中 HTTP-01 可以利用类似 nginx 插件完成证书的自动更新,因为我的环境有点尴尬,80端口总是被各种服务占用,一直也没有成功,但还是列举下步骤,等待后面尝试

sudo yum install epel-release
sudo yum install certbot python2-certbot-nginx # 安装依赖,Ubuntu安装python-certbot-nginx
sudo certbot --nginx -d www.example.com # 生成验证SSL证书
sudo systemctl list-timers # 验证自动续期是否已经配置
sudo certbot renew --dry-run # 确保自动续期正常工作
sudo systemctl reload nginx # 诚信加载配置
openssl s_client -connect www.example.com:443 # 测试证书是否可用

使用 DNS-01 验证可以生成证书后手动配置,命令很简单 sudo certbot certonly --manual --preferred-challenges dns -d www.example.com,具体步骤我就不重复写了,参考上篇

证书介绍

假设我为 checkssl.008ct.space 成功生成了证书,那么会得到以下4个文件,分别介绍一下它们

[root@VM-0-3-centos live]# ll /etc/letsencrypt/live/checkssl.008ct.space/
total 4
lrwxrwxrwx 1 root root  38 Feb 28 13:45 cert.pem -> ../../archive/checkssl.008ct.space/cert1.pem
lrwxrwxrwx 1 root root  39 Feb 28 13:45 chain.pem -> ../../archive/checkssl.008ct.space/chain1.pem
lrwxrwxrwx 1 root root  43 Feb 28 13:45 fullchain.pem -> ../../archive/checkssl.008ct.space/fullchain1.pem
lrwxrwxrwx 1 root root  41 Feb 28 13:45 privkey.pem -> ../../archive/checkssl.008ct.space/privkey1.pem
-rw-r--r-- 1 root root 692 Feb 28 13:45 README

cert.pem

  • 这是 服务器证书(Server Certificate),它是 Let’s Encrypt 为你的域名生成的证书,代表你的服务器身份。
  • 它包含了你的公钥和其他证书信息。
  • 你需要将它配置到 Nginx 中,以便客户端能够验证服务器的身份。

chain.pem

  • 这是 中间证书(Intermediate Certificate),它链接了你的证书和根证书(Root Certificate)。
  • 客户端在验证服务器证书时,需要通过链条的中间证书才能找到受信任的根证书。因此,chain.pem 文件有助于建立证书链的完整性。

fullchain.pem

  • 这是将 服务器证书中间证书 合并在一起的文件。它包含了 cert.pemchain.pem 的内容,客户端验证时需要的是完整的证书链。
  • 推荐在 Nginx 配置中使用 fullchain.pem,因为它包含了所有必要的证书链信息。

privkey.pem

  • 这是 私钥(Private Key),它是你服务器的私密密钥。它用来加密和解密 SSL/TLS 会话。
  • 该文件必须与证书配对,并且应该非常小心地保管,避免泄露。泄露私钥会导致证书被滥用。

使用步骤

证书已经生成好了,假设我们之前有一个引用,支持http和websocket协议,HTTP监听8881端口,WS监听8882端口,通过域名 checkssl.008ct.space 访问,现在需要把他们改成支持HTTPS和WSS,直接修改应用的代价比较大,同时加解密放到应用程序上带来性能损失,这里就可以利用nginx来完成SSL终止,具体操作如下:

搭建简易demo应用

直接用 python3 写一个web应用就行,将以下内容保存到文件app.py中, 通过 python3 app.py 运行即可

import asyncio
import threading
import websockets
from flask import Flask

# 创建 Flask 应用(HTTP 服务)
app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello from HTTP server on port 8881!"

# WebSocket 处理函数
async def websocket_handler(websocket, path):
    print(f"New WebSocket connection: {websocket.remote_address}")
    await websocket.send("Hello from WebSocket server on port 8882!")
    await websocket.wait_closed()

# 启动 Flask 应用的线程(HTTP 服务)
def start_flask():
    app.run(host='0.0.0.0', port=8881)

# 启动 WebSocket 服务的线程
def start_websocket():
    # 为子线程创建一个新的事件循环
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    start_server = websockets.serve(websocket_handler, "0.0.0.0", 8882)
    loop.run_until_complete(start_server)
    loop.run_forever()

# 启动两个服务(HTTP 和 WebSocket)
if __name__ == '__main__':
    # 启动 HTTP 服务
    flask_thread = threading.Thread(target=start_flask)
    flask_thread.start()

    # 启动 WebSocket 服务
    websocket_thread = threading.Thread(target=start_websocket)
    websocket_thread.start()

新建nginx配置文件

在目录 /etc/nginx/conf.d/ 下创建 checkssl.conf 文件,编写内容如下:

server {
    listen 8871 ssl;
    server_name checkssl.008ct.space;

    # SSL 配置
    ssl_certificate /etc/letsencrypt/live/checkssl.008ct.space/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/checkssl.008ct.space/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;

    # HTTP 转发到 8881 端口
    location / {
        proxy_pass http://127.0.0.1:8881;  # 转发到 HTTP 服务(Flask)
        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;
    }
}

server {
    listen 8872 ssl;
    server_name checkssl.008ct.space;

    # SSL 配置
    ssl_certificate /etc/letsencrypt/live/checkssl.008ct.space/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/checkssl.008ct.space/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;

    # WebSocket 转发到 8882 端口
    location / {
        proxy_pass http://127.0.0.1:8882;  # 转发到 WebSocket 服务
        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;

        # WebSocket 配置
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
    }
}

编写完成重新加载配置文件,使用命令 nginx -s reload

测试SSL是否生效

测试 HTTPS 直接在浏览器访问 https://checkssl.008ct.space:8871 就行了,在地址栏会显示一把小锁表示网站安全,但是测试 WSS 就不能直接用浏览器了,可以使用python脚本或者js脚本来测试,这里我们用html页面内嵌js来发送WSS请求,点击按钮后发现也是能正常访问服务的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket Test</title>
</head>
<body>
    <h1>WebSocket Test</h1>
    <button onclick="connect()">Connect to WebSocket</button>
    <div id="message"></div>

    <script>
        let socket;

        function connect() {
            socket = new WebSocket('wss://checkssl.008ct.space:8872');

            socket.onopen = function() {
                document.getElementById('message').innerHTML = 'Connected to WebSocket!';
                socket.send("Hello Server!");
            };

            socket.onmessage = function(event) {
                document.getElementById('message').innerHTML = 'Message from server: ' + event.data;
            };

            socket.onerror = function(error) {
                document.getElementById('message').innerHTML = 'Error: ' + error.message;
            };

            socket.onclose = function() {
                document.getElementById('message').innerHTML = 'WebSocket connection closed.';
            };
        }
    </script>
</body>
</html>

发现一个秘密,一直我还以为自己使用这只有90天有效期的 Let's Encrypt 的有点麻烦,今天才发现Vercel平台免费颁发的证书都是这种,不过也够用了,AWS的证书倒是会标记组织为 Amazon

总结

  • 选择 HTTP-01 验证需要占用80端口,可以通过插件实现SSL证书的自动续期
  • 使用 DNS-01 验证得手动添加DNS记录,命令就一条 sudo certbot certonly --manual --preferred-challenges dns -d www.example.com
  • Nginx可以完成SSL终止,将HTTPS转为HTTP,将WSS转为WS,降低应用服务器的负载
  • Let’s Encrypt 颁发的证书有效期是 90 天,减少了证书被泄露或滥用的潜在的风险,鼓励用户采用自动化续期机制

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

父王只是想用自己的经验为你谋个幸福,但现在看来,父辈的经验,毕竟是过往,未必全对,你的路还需你去闯。今后,忠于自己内心的选择吧~

2025-2-22 08:30:00 在这个和父亲第一次一起看电影的影院里,屏幕上出现了这段话,一切都像是被安排好了一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertS

常来“玩”啊~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值