快速架設Python HTTPS服務
0. 前言
內網有一些接口是https的,由于開發調試需要,需要自建https環境供測試使用。
1. 使用 OpenSSL 生成密鑰和證書文件
mkdir -p /tmp/ca && cd /tmp/ca
openssl req -newkey rsa:2048 -nodes -keyout example.key -x509 -days 365 -out example.crt
這是一個使用 OpenSSL 工具生成自簽名證書的命令。它會要求你輸入一些相關信息,例如Country Name、State of Province Name、Locality Name等。你可以根據自己的實際情況進行填寫。
執行完上述命令后,當前目錄下就會生成 example.key 和 example.crt 文件。example.key 是私鑰文件,而 example.crt 是自簽名證書文件。
以下是各個選項的解釋:
req是 OpenSSL 工具的一個子命令,用于處理證書簽名請求。-newkey rsa:2048選項表示要創建一個新的 RSA 密鑰,并將其長度設置為 2048 位。這個密鑰將用于后續的證書請求和簽名操作。-nodes選項表示不要對私鑰進行加密,即使私鑰被泄露也不會對其進行保護。這在測試和開發過程中很有用,但在生產環境中不建議使用。-keyout example.key選項指定了生成的私鑰文件的路徑和名稱。-x509選項表示生成一個自簽名的 X.509 格式證書,而不是一個證書請求。-days 365選項表示證書的有效期為一年,可以根據需要進行更改。-out example.crt選項指定了生成的證書文件的路徑和名稱。
以上信息由ChatGPT生成的。
2. 啟動Python 3的HTTPS服務器
青春版
import json
import ssl
from http.server import HTTPServer, BaseHTTPRequestHandler
class MyRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
message = {"data": "hello"}
self.wfile.write(bytes(json.dumps(message), 'utf-8'))
if __name__ == '__main__':
# 創建 SSL/TLS 上下文
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
# 加載證書和密鑰
context.load_cert_chain(certfile='/tmp/ca/example.crt', keyfile="/tmp/ca/example.key")
# 創建 HTTP 服務器,并使用 wrap_socket() 方法包裝 socket
httpd = HTTPServer(('localhost', 4443), MyRequestHandler)
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
# 啟動服務器
httpd.serve_forever()
雙模版
import json
import ssl
import threading
from http.server import HTTPServer, BaseHTTPRequestHandler
class MyRequestHandler(BaseHTTPRequestHandler):
message = {"data": "hello"}
def send_json_response(self, content):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(content.encode(encoding='utf-8'))
def do_GET(self):
print("Headers: ", self.headers)
self.send_json_response(json.dumps(self.message))
def start_http_server(http_host, http_port):
print(f'Serving on port {http_port} (HTTP) ...')
HTTPServer((http_host, http_port), MyRequestHandler).serve_forever()
def start_https_server(http_host, http_port):
# 創建 SSL/TLS 上下文
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
# 加載證書和密鑰
context.load_cert_chain(certfile='/tmp/ca/example.crt', keyfile="/tmp/ca/example.key")
# 創建 HTTP 服務器,并使用 wrap_socket() 方法包裝 socket
httpd = HTTPServer((http_host, http_port), MyRequestHandler)
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
# 啟動服務器
print(f'Serving on port {http_port} (HTTPS) ...')
httpd.serve_forever()
if __name__ == '__main__':
# 啟動HTTP服務
http_thread = threading.Thread(target=start_http_server, args=('localhost', 8000))
http_thread.start()
# 啟動HTTPS服務
https_thread = threading.Thread(target=start_https_server, args=('localhost', 8443))
https_thread.start()
IPv6雙模版
import json
import socket
import ssl
import threading
from http.server import HTTPServer, BaseHTTPRequestHandler
class HTTPServerV6(HTTPServer):
address_family = socket.AF_INET6
class MyRequestHandler(BaseHTTPRequestHandler):
message = {"data": "hello"}
def send_json_response(self, content):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(content.encode(encoding='utf-8'))
def do_GET(self):
print("Headers: ", self.headers)
self.send_json_response(json.dumps(self.message))
def start_http_server(http_host, http_port):
print(f'Serving on port {http_port} (HTTP) ...')
HTTPServerV6((http_host, http_port), MyRequestHandler).serve_forever()
def start_https_server(http_host, http_port):
# 創建 SSL/TLS 上下文
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
# 加載證書和密鑰
context.load_cert_chain(certfile='/tmp/ca/example.crt', keyfile="/tmp/ca/example.key")
# 創建 HTTP 服務器,并使用 wrap_socket() 方法包裝 socket
httpd = HTTPServerV6((http_host, http_port), MyRequestHandler)
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
# 啟動服務器
print(f'Serving on port {http_port} (HTTPS) ...')
httpd.serve_forever()
if __name__ == '__main__':
# 啟動HTTP服務
http_thread = threading.Thread(target=start_http_server, args=('::', 8000))
http_thread.start()
# 啟動HTTPS服務
https_thread = threading.Thread(target=start_https_server, args=('::', 8443))
https_thread.start()

浙公網安備 33010602011771號