python 搭建 https 服务器:方法、困难回顾

python 搭建 https 服务器:方法、困难回顾

之前用 Python 3 实现过一个基于 TCP socket、然后手动解析 HTTP 协议数据包的简易 HTTP 服务器;这两天探索将其改装成支持 HTTPS 的版本。本文对过程中的基本方法、遇到的一系列问题等予以回顾。

一、基本思路:ssl 库的 wrap_socket()

ssl 库提供的 wrap_socket(...) 函数,能直接把原有的明文 TCP socket 包装成 ssl 加密的形式,且(似乎?)不影响其它功能。

注意,包装的是每次 accept 得到的连接、而不是一开始就创建的那个监听的连接。

假设原有 HTTP 服务器是:

import socket

class MyServer:

    def __init__(self, port):
        self.socket_1 = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
        self.socket_1.bind(('0.0.0.0', port))
        self.socket_1.listen(10)

    def run(self):
        while True:
            try:
                conn, addr = self.socket_1.accept()
                conn = self.wrap(conn)  # 预埋 socket 的包装接口
                req_bytes = conn.recv(1024)
                # ...略

    def wrap(self, conn):
        return conn

则 HTTPS 版本直接继承,并利用包装接口进行包装:

class MyHttpsServer(MyServer):

    def __init__(self, port, ssl_ctx):
        super().__init__(port)
        self.ssl_ctx = ssl_ctx

    def wrap(self, conn):
        return self.ssl_ctx.wrap_socket(conn, server_side=True)

这里的 ssl_ctx 是用 ssl 库创建的 context 对象:

# main.py

import ssl
from xxx import MyHttpsServer

ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(certfile='/path/to/xxxx.pem')
server = MyHttpsServer(10022, ssl_ctx)

(端口10022是我随便选的;certfile 后面会详细介绍)

主要参考资料:

二、证书相关文件的获取、处理

我的 https 证书是在腾讯云申请的。申请后可以下载各种格式。

腾讯云下载证书截图

得到 .jks 文件及其密码文件后,我的做法是转换成 .pem 文件。

转换的主要参考资料(两种方式):

然后就可以传入上一章的 ssl_ctx.load_cert_chain() 函数里。

三、端口不通

注:端口不通问题,可以先用 HTTP 来测试,确保问题与 ssl 无关。

0 - 常用命令

netstat -antplo
lsof -i:端口号

都可以查看端口的状态信息。

1 - 云服务商的安全组

腾讯云、阿里云的控制台应该都有安全组可以配置,要去那里把对应的端口放通。

主要参考资料:

2 - linux服务器内的防火墙

如果是 linux 系统的服务器,首先要知道它可能有好几个防火墙,而且可能互相影响……请逐个排查。

主要参考资料:

(同时感谢腾讯云技术咨询人工客服的解答!)

3 - 绑定的地址

不能用 localhost127.0.0.1 等,否则本机上 ssh 上去并 telnet localhost 10022 能连接、但公网访问就不能连接。

要用 0.0.0.0(见第一章的示例代码)。

主要参考资料:

4 - netstat 看到是 tcp6 而非 tcp

看了一些资料。但我最后好像没改动这方面,应该不用管?

主要参考资料:

四、还遇到 SSLError 问题

第三章是先用 HTTP 来测试,所以(端口通了之后)改回 HTTPS 时,别忘了客户端也改回来(尤其是我用了非标准的 10022 端口,浏览器可能不知道是 HTTPS)。(否则这种报错很难看出来)

五、Address already in use

过了一段时间突然就好了。可能是上一次运行崩溃之后,没及时释放端口?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值