自從去年臨時換成MikroTik路由器後,功耗和效能都非常滿意,臺灣代理商送來時就有預設的Firewall Rules,完全沒有問題,唯一的不滿就是註解在網路介面看到時是亂碼,詢問代理商說要用 WinBox v3 Windows 版本才能正常顯示註解。WinBox v3還有另一個問題,在高解析度螢幕上文字非常小。
我在家使用的主力是 mac 和 Linux,我也不喜歡使用 WinBox,能夠使用瀏覽器才方便。
雖然沒有太多時間去研究,但基本上所有的路由器都可以匯出文字,所以找Gemini討論。首先,Gemini教我如何匯出,開啟 Terminal,輸入
/export file=my_config
接下來會在 Files 看到 my_config.rsc ,這是純文字的指令,其中會有Big5中文編碼後的註解
add action=accept chain=input comment="\B6\B6\A7\C7\A6\EC\B8m\A5\B2\B6\B7\A9T\
\A9w--> \B6\B6\A7\C70 (\A9\F1\A6\E6\A6\A8\A5\\\B5n\A4J\AB\E1\AA\BAIP)" \
dst-port=21,22,23,8291 protocol=tcp src-address-list=login-ok
轉換成UTF-8應該是以下這樣,利用新版WinBox貼上註解後也證實如此。
add action=accept chain=input comment="\E9\A0\86\E5\BA\8F\E4\BD\8D\E7\BD\AE\E5\
\BF\85\E9\A0\88\E5\9B\BA\E5\AE\9A--> \E9\A0\86\E5\BA\8F0 (\E6\94\BE\E8\A1\
\8C\E6\88\90\E5\8A\9F\E7\99\BB\E5\85\A5\E5\BE\8C\E7\9A\84IP)" dst-port=\
21,22,23,8291 protocol=tcp src-address-list=login-ok
在 MikroTik 的 .rsc 檔案中,當字串包含非 ASCII 字元(如中文)時,它會用 \XX 的格式來表示。其中註解文字應為:順序位置必須固定--> 順序0 (放行成功登入後的IP)
所以我們要做的事情就是把這個檔案編碼改為UTF-8, 存檔後刪除原有設定,再重新匯入設定檔。
/import file-name=my_config_utf8.rsc verbose=yes
所以在與雙子座多輪對話後,寫出一支轉換 my_config.rsc 變為 my_config_utf8.rsc 的程式,這程式還會列出修改的中文字, 對於不敢直接覆蓋原檔案,可手動修改註解。
import re
import os
def decode_mikrotik_string(mt_str):
# 移除 MikroTik 為了斷行加的反斜線與換行符
cleaned_str = mt_str.replace('\\\n', '').replace('\\\r\n', '').replace(' ', '')
result_bytes = bytearray()
i = 0
while i < len(cleaned_str):
if cleaned_str[i] == '\\':
if i + 1 < len(cleaned_str) and cleaned_str[i+1] == '\\':
result_bytes.append(ord('\\'))
i += 2
elif i + 2 < len(cleaned_str) and re.match(r'[0-9A-Fa-f]{2}', cleaned_str[i+1:i+3]):
hex_val = int(cleaned_str[i+1:i+3], 16)
result_bytes.append(hex_val)
i += 3
else:
result_bytes.append(ord('\\'))
i += 1
else:
result_bytes.append(ord(cleaned_str[i]))
i += 1
try:
return result_bytes.decode('big5')
except:
return cleaned_str
def process_with_report(filename):
if not os.path.exists(filename):
print(f"找不到檔案: {filename}")
return
with open(filename, 'r', encoding='ascii', errors='ignore') as f:
content = f.read()
# 建立對照報告
report = [f"=== MikroTik 註解對照表 ({filename}) ===", f"{'行號':<6} | {'原本亂碼 (部分)':<30} | {'轉換後中文'}\n" + "-"*80]
# 用來存放 UTF-8 內容
output_content = content
# 匹配 comment="..." 或跨行 comment=\n "..."
# 根據 source 2-4,有些註解是跨行的
pattern = re.compile(r'comment="([\s\S]*?)"|comment=\\\s*\n\s*"([\s\S]*?)"')
all_matches = list(pattern.finditer(content))
# 倒著取代,才不會影響字串 index
for match in reversed(all_matches):
raw_val = match.group(1) if match.group(1) else match.group(2)
decoded_val = decode_mikrotik_string(raw_val)
# 找出該匹配所在的行號
line_num = content[:match.start()].count('\n') + 1
if decoded_val != raw_val:
report.append(f"Line {line_num:<3} | {raw_val[:28].replace('\\',''):<30} | {decoded_val}")
# 取代為中文版
start, end = match.span()
output_content = output_content[:start] + f'comment="{decoded_val}"' + output_content[end:]
# 儲存 UTF-8 檔案
with open(filename.replace('.rsc', '_utf8.rsc'), 'w', encoding='utf-8') as f:
f.write(output_content)
# 儲存對照報告
with open('comparison_report.txt', 'w', encoding='utf-8') as f:
f.write('\n'.join(report))
print(f"[*] 轉換完成!已產生:")
print(f" 1. {filename.replace('.rsc', '_utf8.rsc')} (可用於匯入)")
print(f" 2. comparison_report.txt (手動比對用)")
if __name__ == "__main__":
process_with_report('my_config.rsc')
留言