2025-09-30 12:33:21 +08:00
|
|
|
|
from librouteros import connect, Api
|
2025-08-18 15:48:15 +08:00
|
|
|
|
import csv
|
|
|
|
|
|
import ssl
|
|
|
|
|
|
import threading
|
|
|
|
|
|
|
2025-09-08 12:55:20 +08:00
|
|
|
|
from steps import *
|
|
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-08-18 15:48:15 +08:00
|
|
|
|
自动配置 ros 脚本,需要安装 librouteros 库:
|
|
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
```
|
2025-08-18 15:48:15 +08:00
|
|
|
|
pip install librouteros
|
2025-09-28 18:05:21 +08:00
|
|
|
|
```
|
2025-08-18 15:48:15 +08:00
|
|
|
|
|
|
|
|
|
|
配置文件格式为 CSV,包含以下字段:
|
|
|
|
|
|
|
|
|
|
|
|
- index: 配置索引,【重要】这个 index 用来生成对应 l2tp-out 用户名中的序号,每个节点都是唯一且固定的
|
|
|
|
|
|
- name: 城市名
|
|
|
|
|
|
- code: 城市代码
|
|
|
|
|
|
- gateway: 网关地址
|
|
|
|
|
|
- public: 公网 IP
|
|
|
|
|
|
- mask: 公网子网掩码
|
|
|
|
|
|
- private: 内网 IP
|
2026-02-26 15:40:34 +08:00
|
|
|
|
- domain: 节点域名
|
|
|
|
|
|
- cert: 证书文件路径
|
2025-08-18 15:48:15 +08:00
|
|
|
|
|
2026-02-26 15:40:34 +08:00
|
|
|
|
如果需要添加或修改配置项,修改 config.*.bak.csv 文件,并复制配置项到 config.csv 文件中
|
2025-08-18 15:48:15 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
如果需要修改配置内容,在下面 “配置执行步骤” 部分添加或修改函数调用
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-08-18 15:48:15 +08:00
|
|
|
|
|
2025-09-08 12:55:20 +08:00
|
|
|
|
# 配置执行步骤
|
|
|
|
|
|
steps = [
|
2026-02-26 15:40:34 +08:00
|
|
|
|
configJgOuts,
|
2025-09-08 12:55:20 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
2026-02-26 15:40:34 +08:00
|
|
|
|
threads = []
|
|
|
|
|
|
failed = []
|
|
|
|
|
|
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-08-18 15:48:15 +08:00
|
|
|
|
def main():
|
|
|
|
|
|
# 加载配置文件
|
|
|
|
|
|
config_data = []
|
2025-09-30 12:33:21 +08:00
|
|
|
|
with open("config.csv", "r", encoding="utf-8-sig") as file:
|
2025-08-18 15:48:15 +08:00
|
|
|
|
reader = csv.DictReader(file)
|
|
|
|
|
|
for row in reader:
|
|
|
|
|
|
config_data.append(row)
|
|
|
|
|
|
|
|
|
|
|
|
# 多线程执行 ros 配置
|
|
|
|
|
|
for _, config in enumerate(config_data):
|
|
|
|
|
|
thread = threading.Thread(target=start, args=(config,))
|
|
|
|
|
|
thread.start()
|
|
|
|
|
|
threads.append(thread)
|
|
|
|
|
|
|
|
|
|
|
|
# 等待所有线程完成
|
|
|
|
|
|
for thread in threads:
|
|
|
|
|
|
thread.join()
|
|
|
|
|
|
|
|
|
|
|
|
# 输出结果
|
2025-09-30 12:33:21 +08:00
|
|
|
|
print("=" * 20)
|
|
|
|
|
|
print(
|
|
|
|
|
|
"配置完成统计({}/{}), 失败项:{}".format(
|
|
|
|
|
|
len(config_data) - len(failed), len(config_data), len(failed)
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2025-08-18 15:48:15 +08:00
|
|
|
|
for _, (item, err) in enumerate(failed):
|
2025-09-30 12:33:21 +08:00
|
|
|
|
print("{},{},{},{}".format(item["public"], item["name"], item["code"], err))
|
|
|
|
|
|
|
2025-08-18 15:48:15 +08:00
|
|
|
|
|
|
|
|
|
|
def start(config):
|
2025-09-30 12:33:21 +08:00
|
|
|
|
print(
|
|
|
|
|
|
"{}: 配置{}({})".format(
|
|
|
|
|
|
str(config["index"]).zfill(3), config["name"], config["code"]
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2025-08-18 15:48:15 +08:00
|
|
|
|
|
|
|
|
|
|
# 连接到 ros
|
|
|
|
|
|
conn: Api
|
|
|
|
|
|
try:
|
|
|
|
|
|
ctx = ssl.create_default_context()
|
|
|
|
|
|
ctx.check_hostname = False
|
2026-02-26 15:40:34 +08:00
|
|
|
|
ctx.load_verify_locations(f"certs/{config['cert']}")
|
2025-08-18 15:48:15 +08:00
|
|
|
|
conn = connect(
|
2025-09-30 12:33:21 +08:00
|
|
|
|
username="admin",
|
|
|
|
|
|
password="wyongk9815",
|
|
|
|
|
|
host=config["public"],
|
2025-08-18 15:48:15 +08:00
|
|
|
|
port=8729,
|
|
|
|
|
|
ssl_wrapper=ctx.wrap_socket,
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as err:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
failed.append((config, f"连接失败: {err}"))
|
2025-08-18 15:48:15 +08:00
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 配置 ros
|
|
|
|
|
|
try:
|
2025-09-08 12:55:20 +08:00
|
|
|
|
for step in steps:
|
|
|
|
|
|
step(conn, config)
|
2025-08-18 15:48:15 +08:00
|
|
|
|
except Exception as err:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
failed.append((config, f"配置失败: {err}"))
|
2025-08-18 15:48:15 +08:00
|
|
|
|
|
|
|
|
|
|
# 关闭连接
|
|
|
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
main()
|