用python简单起个https服务器
字数 1318 2025-08-24 07:48:33
Python搭建自签名HTTPS服务器详细教程
前言
在日常开发和安全测试中,我们经常需要快速搭建一个HTTP服务器来托管文件。Python内置的python -m http.server命令虽然方便,但传输是明文的,存在安全隐患。本教程将详细介绍如何使用Python搭建一个自签名的HTTPS服务器,实现加密传输。
准备工作
确保你的系统已安装:
- Python 3.x
- OpenSSL库
- pyOpenSSL模块(可通过
pip install pyopenssl安装)
完整代码实现
# Python 3
# Usage: python3 SimpleHTTPSServer.py port
from OpenSSL import crypto, SSL
from socket import gethostname
from pprint import pprint
from time import gmtime, mktime
import os
import http.server, ssl
import argparse
parser = argparse.ArgumentParser(description="SimpleHTTPSServer\nUsage: python3 SimpleHTTPSServer.py 443")
parser.add_argument("port", type=int, default=443, nargs="?", help="Port Number, default is 443")
args = parser.parse_args()
CERT_PATH = "server.crt"
KEY_PATH = "server.key"
PEM_PATH = "server.pem"
def create_self_signed_cert(cert_path, key_path, pem_path):
# 创建密钥对
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 1024)
# 创建自签名证书
cert = crypto.X509()
cert.get_subject().C = "UK"
cert.get_subject().ST = "London"
cert.get_subject().L = "London"
cert.get_subject().O = "Dummy Company Ltd"
cert.get_subject().OU = "Dummy Company Ltd"
cert.get_subject().CN = os.gethostname()
cert.set_serial_number(1000)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(10*365*24*60*60)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(k)
cert.sign(k, 'sha1')
# 保存证书和密钥
if (not os.path.exists(cert_path)):
open(cert_path, "wb").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
if (not os.path.exists(key_path)):
open(key_path, "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
if (not os.path.exists(pem_path)):
open(pem_path, "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
open(pem_path, "ab").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
def create_https_server(cert_path, key_path, port):
server_address = ('0.0.0.0', port)
try:
httpd = http.server.HTTPServer(server_address, http.server.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(
httpd.socket,
server_side=True,
certfile='server.pem',
ssl_version=ssl.PROTOCOL_TLS
)
except:
exit("[ERR] Port %d has been taken." % (port))
print("Serving HTTPS on 0.0.0.0 port %d ..." % (port))
httpd.serve_forever()
if __name__ == "__main__":
create_self_signed_cert(CERT_PATH, KEY_PATH, PEM_PATH)
create_https_server(CERT_PATH, KEY_PATH, args.port)
代码解析
1. 创建自签名证书
create_self_signed_cert函数负责生成自签名证书:
- 密钥生成:使用RSA算法生成1024位的密钥对
- 证书信息设置:
- C (Country): 国家代码,示例中使用"UK"
- ST (State/Province): 州/省,示例为"London"
- L (Locality): 城市,示例为"London"
- O (Organization): 组织名称,示例为"Dummy Company Ltd"
- OU (Organizational Unit): 组织单位
- CN (Common Name): 主机名,使用
os.gethostname()获取
- 有效期设置:10年有效期
- 文件保存:
- server.crt: 证书文件
- server.key: 私钥文件
- server.pem: 合并的证书和私钥文件
2. 创建HTTPS服务器
create_https_server函数创建HTTPS服务器:
- 监听指定端口(默认为443)
- 使用Python内置的
http.server.HTTPServer - 通过
ssl.wrap_socket将普通socket包装为SSL socket - 使用之前生成的server.pem作为证书
使用方法
- 将代码保存为
SimpleHTTPSServer.py - 运行命令:
如果不指定端口号,默认使用443端口python SimpleHTTPSServer.py [端口号]
访问注意事项
由于使用的是自签名证书:
- 浏览器访问:会被标记为不安全,需要手动信任
- 命令行工具下载:
- 使用wget时需要添加
--no-check-certificate参数:wget --no-check-certificate https://your-ip:port/file - 使用curl时需要添加
-k或--insecure参数
- 使用wget时需要添加
安全优势
- 流量加密:所有传输内容都会被加密,Wireshark等工具无法直接查看明文
- 规避IDS检测:加密传输可以绕过一些基于流量特征的入侵检测系统
- 防止敏感信息泄露:相比HTTP明文传输更安全
自定义修改建议
- 证书信息:可以修改
create_self_signed_cert函数中的证书信息,如国家、组织名称等 - 密钥强度:可以将RSA密钥长度从1024提升到2048或更高
- 哈希算法:可以将sha1改为更安全的sha256
总结
本教程详细介绍了如何使用Python快速搭建一个自签名的HTTPS服务器,相比普通的HTTP服务器,它提供了加密传输功能,更适合传输敏感文件或在不安全的网络环境中使用。虽然自签名证书在浏览器中会显示警告,但对于内部使用或临时文件共享场景非常实用。