一、终极一行命令
bash
复制
bash
复制
openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days 365 -subj "/CN=localhost" && python3 -c "from http.server import HTTPServer, BaseHTTPRequestHandler; import ssl; httpd = HTTPServer(('0.0.0.0', 443), BaseHTTPRequestHandler); httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='server.key', certfile='server.crt', server_side=True); httpd.serve_forever()"
效果:
- 生成私钥
server.key和证书server.crt。 - 启动 HTTPS 服务,监听
0.0.0.0:443,响应所有请求。
二、逐行解析
步骤 1:生成自签名证书
bash
复制
bash
复制
openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days 365 -subj "/CN=localhost"
-
参数拆解:
-x509:直接生成自签名证书(跳过 CSR)。-newkey rsa:4096:生成 4096 位 RSA 密钥(更安全)。-nodes:私钥不加密(避免服务启动时输入密码)。-subj "/CN=localhost":证书绑定域名(可改为127.0.0.1或实际 IP)。
步骤 2:启动 Python3 HTTPS 服务
bash
复制
bash
复制
python3 -c "from http.server import HTTPServer, BaseHTTPRequestHandler; import ssl; httpd = HTTPServer(('0.0.0.0', 443), BaseHTTPRequestHandler); httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='server.key', certfile='server.crt', server_side=True); httpd.serve_forever()"
-
代码功能:
- 创建 HTTPS 服务器,绑定所有 IP 的 443 端口。
- 使用
ssl.wrap_socket加载证书和私钥。 - 默认响应状态码 200,无内容(需自定义逻辑可修改
BaseHTTPRequestHandler)。
三、验证与服务扩展
1. 测试 HTTPS 接口
bash
复制
bash
复制
curl -k -v https://localhost # -k 忽略证书验证
预期输出:
plaintext
复制
plaintext
复制
< HTTP/1.1 200 OK
< Server: BaseHTTP/0.6 Python/3.8.10
< Date: Tue, 01 Jan 2024 00:00:00 GMT
< Content-Length: 0
2. 自定义请求处理逻辑
修改 Python 代码,实现特定响应(示例返回 JSON):
python
复制
python
复制
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(b'{"status": "HTTPS OK"}')
# 替换原代码中的 BaseHTTPRequestHandler 为 MyHandler
重启服务后测试:
bash
复制
bash
复制
curl -k https://localhost
# 输出:{"status": "HTTPS OK"}
四、常见问题与解决方案
问题 1:端口 443 权限不足
报错:PermissionError: [Errno 13] Permission denied
解决:
bash
复制
bash
复制
sudo setcap 'cap_net_bind_service=+ep' /usr/bin/python3 # 允许 Python 绑定 443 端口(Linux)
# 或使用非特权端口(如 8443),修改代码中的端口号
问题 2:浏览器提示“不安全”
解决:
- 临时访问:地址栏输入
thisisunsafe(Chrome 强制跳过警告)。 - 永久信任:将
server.crt导入系统根证书(操作方法)。
问题 3:证书绑定多域名/IP
改进命令:
bash
复制
bash
复制
openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days 365 \
-subj "/CN=My Server" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.com"
五、生产环境替代方案
1. 使用可信证书(Let's Encrypt)
bash
复制
bash
复制
certbot certonly --standalone -d example.com # 需 80/443 端口未被占用
2. 容器化部署(Docker + Nginx)
dockerfile
复制
markdown
复制
FROM nginx:alpine
COPY server.crt /etc/nginx/certs/
COPY server.key /etc/nginx/certs/
COPY nginx.conf /etc/nginx/conf.d/default.conf
nginx.conf 示例:
nginx
复制
nginx
复制
server {
listen 443 ssl;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
location / {
return 200 '{"message": "HTTPS in Docker!"}';
}
}