开发必备!一行命令生成自签名证书的 HTTPS 接口

275 阅读2分钟

一、终极一行命令

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()"

效果

  1. 生成私钥 server.key 和证书 server.crt
  2. 启动 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!"}';
    }
}