在邊緣運算閘道器 (EdgeNode) 的研發過程中,工程團隊通常會在測試階段將各種伺服器 IP、SFTP 連線帳密、私鑰憑證、甚至是硬體設備的 CPU 序列號 (Serial Number) 硬編碼 (Hardcode) 在程式碼或設定檔中。
當專案從「內部原型階段」準備走向「商業部署」或是「開源 Publish」時,噩夢往往就發生了:
config.json 提交到 Git Remote。git commit,機敏資訊依然完好無損地躺在 Git commit history 裡。在醫療或工業邊緣閘道器的防禦體系中,「資訊安全與去敏 (Sanitization)」是 SRE 穩定度工程的第一道防線。
許多團隊在處理去敏與憑證管理時,經常犯下以下三個致命錯誤:
.gitignore工程師以為在 .gitignore 加上 secrets.json 就安全了。然而,只要團隊中某位成員在建立 .gitignore 之前就 git add . 了一次,該檔案就會被納入版控,後續再加 .gitignore 根本無法阻止機敏檔案被推送出去。
當發現憑證洩漏後,直覺地執行:
rm config/secrets.json
git commit -m "Remove secrets"
git push
這種做法只是在最新的 Commit 隱藏了檔案,任何人只要 git log -p 或切換到舊 Commit,依然能一覽無遺地看到當年的明文密碼。
# ❌ 極度危險的寫法
SFTP_HOST = "10.0.0.5"
SFTP_USER = "admin"
SFTP_PASS = "SuperSecretPassword123"
這種寫法不僅無法隨部署環境動態調整,更會讓所有擁有程式碼存取權的人直接取得核心伺服器的最高存取權限。
要打造商業級的邊緣閘道器,我們必須建立 「三層防禦架構」:

邊緣設備不應存放明文憑證。我們利用樹莓派獨一無二的硬體 CPU 序號(位於 /proc/cpuinfo),搭配 PBKDF2 衍生出專屬的 AES-256 對稱金鑰。
secrets.dat,並強制徹底抹除 (Shred) 原始明文檔。所有環境相關的設定(如 IP、Port、路徑)一律抽離成外部 JSON 或環境變數,程式碼本身保持 100% 潔淨且不包含任何硬編碼資訊。
在程式碼送出版控前,在本地端自動觸發正則表達式 (Regex) 掃描,強制攔截含有 IP 地址、API Key 或私鑰格式的提交。
security.py)在 DataGateway 部署腳本中,我們實作自動化機敏保護機制:
import os
import json
import base64
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
def get_hardware_cpu_sn() -> str:
"""擷取樹莓派硬體 CPU 獨一無二的序列號"""
try:
with open('/proc/cpuinfo', 'r') as f:
for line in f:
if line.startswith('Serial'):
return line.split(':')[1].strip()
except Exception:
pass
return "0000000000000000"
def derive_fernet_key(salt: bytes) -> bytes:
"""使用 CPU 序號衍生 32-byte Fernet 加密金鑰"""
cpu_sn = get_hardware_cpu_sn()
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
)
return base64.urlsafe_b64encode(kdf.derive(cpu_sn.encode()))
def secure_provision_secrets(json_path: str, dat_path: str):
"""將明文 secrets.json 加密轉存為 secrets.dat 並安全抹除明文"""
if not os.path.exists(json_path):
return
print("[Security] 檢測到明文憑證,啟動硬體加密流程...")
with open(json_path, 'r', encoding='utf-8') as f:
raw_data = f.read()
salt = os.urandom(16)
key = derive_fernet_key(salt)
fernet = Fernet(key)
encrypted_bytes = fernet.encrypt(raw_data.encode())
# 寫入包含 Salt + 密文的 binary 檔案
with open(dat_path, 'wb') as f:
f.write(salt + encrypted_bytes)
# 安全抹除原始明文檔案 (Shredding)
with open(json_path, "ba+", buffering=0) as f:
length = f.tell()
f.seek(0)
f.write(os.urandom(length))
os.remove(json_path)
print("[Security] 明文憑證已徹底銷毀,已生成 CPU 綁定加密檔。")
.git/hooks/pre-commit)為了防止開發人員誤將私密資訊提交至程式庫,我們在 Git Hook 中設定自動化攔截:
#!/bin/bash
# .git/hooks/pre-commit
echo "🔍 執行出貨與開源前機敏資訊去敏檢查 (Pre-commit Check)..."
# 1. 檢查是否有固定的私人內網 IP (例如 192.168.x.x)
FORBIDDEN_IP=$(git diff --cached | grep -E "192\.168\.[0-9]{1,3}\.[0-9]{1,3}" | grep "^+")
if [ -n "$FORBIDDEN_IP" ]; then
echo "❌ [ERROR] 攔截到未去敏的內網 IP 地址提交!"
echo "$FORBIDDEN_IP"
echo "💡 請將 IP 替換為 10.0.0.x 或改用環境變數載入。"
exit 1
fi
# 2. 檢查是否有明文私鑰或敏感檔名
FORBIDDEN_KEYS=$(git diff --cached --name-only | grep -E "(secrets\.json|\.pem|\.key|id_rsa)")
if [ -n "$FORBIDDEN_KEYS" ]; then
echo "❌ [ERROR] 攔截到機敏檔案提交:"
echo "$FORBIDDEN_KEYS"
echo "💡 請確認該檔案已加入 .gitignore 並從 Index 中移除!"
exit 1
fi
echo "✅ 機敏檢查通過,允許 Commit!"
exit 0
邊緣閘道器的安全性絕不能依賴「事後補救」。在 Day 26 中,我們介紹了:
在下一篇 Day 27 中,我們將深入探討現場防護的另一個硬核課題:「斷電與拔插救援:如何實作開機自動化 fsck 檢查與壞軌修復?」!