TCP 控制 Socket Server
概觀
控制 socket server 是 gevent 為基礎的 TCP listener,將收到的 LoadDensity 動作 JSON 透過網路執行。硬化版協定加入 length-prefix framing、選用 TLS,以及共享密鑰 token;舊版未驗證模式仍保留以維持相容。
模式
模式 |
註記 |
|---|---|
|
單次 |
|
4-byte big-endian 長度前綴 + JSON body。對 partial read 與超大 payload 較安全(1 MiB 上限)。 |
|
以 ``ssl.create_default_context``(TLS 1.2+)包裝連線,需 cert/key 檔案。 |
驗證
傳入 token=``(或設定 ``LOAD_DENSITY_SOCKET_TOKEN)即可要求共享密鑰。一旦設定:
quit_server沒有正確 token 將被拒絕。所有指令 payload 必須使用 envelope
{"token": "...", "command": [...action JSON...]},可以"op": "quit"表示停機。
Token 以 hmac.compare_digest 比對,避免 timing oracle。
啟動 server
Python:
from je_load_density import start_load_density_socket_server
start_load_density_socket_server(
host="0.0.0.0",
port=9940,
framed=True,
token="ROTATE_ME",
certfile="/etc/loaddensity/server.crt",
keyfile="/etc/loaddensity/server.key",
)
CLI:
python -m je_load_density serve \
--host 0.0.0.0 --port 9940 --framed \
--token "$LOAD_DENSITY_SOCKET_TOKEN"
傳送指令(framed 模式)
import json, socket, struct
payload = json.dumps({
"token": "ROTATE_ME",
"command": {"load_density": [["LD_summary", {}]]}
}).encode("utf-8")
sock = socket.create_connection(("127.0.0.1", 9940))
sock.sendall(struct.pack("!I", len(payload)) + payload)
while True:
header = sock.recv(4)
if not header:
break
(length,) = struct.unpack("!I", header)
chunk = sock.recv(length)
if chunk == b"Return_Data_Over_JE\n":
break
print(chunk.decode("utf-8"))
sock.close()
關閉
Legacy 模式:傳送字面字串
quit_server。Framed 模式(含 token):傳送
{"token": "...", "op": "quit"}。
Server 列印 Server shutdown complete 後結束。
注意事項
啟動時會呼叫
gevent.monkey.patch_all(),整合時請留意。token 可由環境變數
LOAD_DENSITY_SOCKET_TOKEN讀取,避免將密鑰寫進指令參數。