2025-09-08 12:55:20 +08:00
|
|
|
|
import re
|
2025-09-28 18:05:21 +08:00
|
|
|
|
from librouteros import Api
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-28 18:05:21 +08:00
|
|
|
|
配置步骤,每个步骤都可以安全幂等执行,配置混合节点的出口的函数可能会很慢,因为出口比较多
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
|
|
|
|
|
|
def configNet(conn: Api, config):
|
|
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
配置网络
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
|
|
|
|
|
# 配置路由
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes = conn.path("ip", "route")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for route in routes:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if route["routing-table"] == "1":
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes.update(**{".id": route[".id"], "gateway": config["gateway"]})
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("更新默认路由失败: {}".format(e))
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# 配置地址
|
2025-09-30 12:33:21 +08:00
|
|
|
|
addrs = conn.path("ip", "address")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for addr in addrs:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if addr["interface"] == "lan":
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
addrs.update(**{".id": addr[".id"], "address": config["private"]})
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("更新 WAN 地址失败: {}".format(e))
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# 刷新 mac 地址
|
2025-09-30 12:33:21 +08:00
|
|
|
|
eths = conn.path("interface", "ethernet")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for eth in eths:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if eth["name"] == "lan":
|
|
|
|
|
|
tuple(eths("reset-mac-address", **{".id": eth[".id"]}))
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"配置网络失败: {e}")
|
|
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# ====================
|
|
|
|
|
|
# 极狐配置
|
|
|
|
|
|
# ====================
|
|
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
|
|
|
|
|
|
def configJhOuts(conn: Api, config):
|
|
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
配置 vpn 出口负载均衡
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
|
|
|
|
|
count = 20
|
|
|
|
|
|
|
|
|
|
|
|
# 配置 ppp
|
2025-09-30 12:33:21 +08:00
|
|
|
|
ppps = conn.path("interface", "l2tp-client")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# 删除旧的 ppp
|
|
|
|
|
|
for ppp in ppps:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if ppp["name"].startswith("l2tp-out"):
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
ppps.remove(ppp[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除 PPP 失败: {}".format(e))
|
|
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
# 添加新的 ppp
|
2025-09-30 12:33:21 +08:00
|
|
|
|
for i in range(1, count + 1):
|
|
|
|
|
|
ppps.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": "l2tp-out{}".format(i),
|
|
|
|
|
|
"connect-to": "192.168.25{}.25{}".format(
|
|
|
|
|
|
(i - 1) % 3 + 1, (i - 1) % 3 + 1
|
|
|
|
|
|
),
|
|
|
|
|
|
"user": "jdzz{}dt{}".format(i, config["index"]),
|
|
|
|
|
|
"password": "123231",
|
|
|
|
|
|
"disabled": "no",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
# 配置路由
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes = conn.path("ip", "route")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# 删除旧的路由表
|
|
|
|
|
|
for route in routes:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if str(route["routing-table"]).startswith("r"):
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes.remove(route[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除路由表失败: {}".format(e))
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# 添加新的路由表
|
2025-09-30 12:33:21 +08:00
|
|
|
|
for i in range(1, count + 1):
|
|
|
|
|
|
routeName = "r{}".format(i)
|
|
|
|
|
|
routeOut = "l2tp-out{}".format(i)
|
2025-09-08 12:55:20 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"dst-address": "0.0.0.0/0",
|
|
|
|
|
|
"gateway": routeOut,
|
|
|
|
|
|
"routing-table": routeName,
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-08 12:55:20 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"添加路由表失败: {e}")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"配置出口失败: {e}")
|
|
|
|
|
|
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
def configJhMixOuts(conn: Api, config):
|
|
|
|
|
|
"""
|
2025-09-28 18:05:21 +08:00
|
|
|
|
配置 vpn 出口负载均衡 (混合模式)
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-25 13:36:12 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
ppps = conn.path("interface", "l2tp-client")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for ppp in ppps:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if ppp["name"].startswith("l2tp-out"):
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
ppps.remove(ppp[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除 PPP 失败: {}".format(e))
|
|
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for i in range(30):
|
|
|
|
|
|
for j in range(10):
|
2025-09-30 12:33:21 +08:00
|
|
|
|
n = j * 30 + i
|
|
|
|
|
|
k = n % 3 + 1
|
|
|
|
|
|
|
|
|
|
|
|
ppps.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": f"l2tp-out{n+1}",
|
|
|
|
|
|
"connect-to": f"192.168.25{k}.25{k}",
|
|
|
|
|
|
"user": f"jdzz{j+11}dt{i+221}",
|
|
|
|
|
|
"password": "123231",
|
|
|
|
|
|
"disabled": "no",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
routes = conn.path("ip", "route")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for route in routes:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if str(route["routing-table"]).startswith("r"):
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes.remove(route[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除路由表失败: {}".format(e))
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
for i in range(300):
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routeName = f"r{i+1}"
|
|
|
|
|
|
routeOut = f"l2tp-out{i+1}"
|
2025-09-25 13:36:12 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"dst-address": "0.0.0.0/0",
|
|
|
|
|
|
"gateway": routeOut,
|
|
|
|
|
|
"routing-table": routeName,
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-25 13:36:12 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"添加路由表失败: {e}")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"配置出口失败: {e}")
|
2025-09-25 13:36:12 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
|
|
|
|
|
|
def configJhScripts(conn: Api, config):
|
|
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
配置脚本
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
|
|
|
|
|
# 配置脚本
|
2025-09-30 12:33:21 +08:00
|
|
|
|
scripts = conn.path("system", "script")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for script in scripts:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if script["name"] == "up":
|
|
|
|
|
|
with open("scripts/up.rsc", "rb") as file:
|
|
|
|
|
|
upScript = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.update(**{".id": script[".id"], "source": upScript})
|
|
|
|
|
|
elif script["name"] == "down":
|
|
|
|
|
|
with open("scripts/down.rsc", "rb") as file:
|
|
|
|
|
|
downScript = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.update(**{".id": script[".id"], "source": downScript})
|
|
|
|
|
|
elif script["name"] == "onlinestatus":
|
|
|
|
|
|
with open("scripts/onlinestatus.rsc", "rb") as file:
|
|
|
|
|
|
onlineStatusScript = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.update(
|
|
|
|
|
|
**{
|
|
|
|
|
|
".id": script[".id"],
|
|
|
|
|
|
"source": onlineStatusScript.replace(
|
|
|
|
|
|
"<IP>", config["public"]
|
|
|
|
|
|
),
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
elif script["name"] == "pppoestatus":
|
|
|
|
|
|
with open("scripts/pppoestatus.rsc", "rb") as file:
|
|
|
|
|
|
pppoeStatusScript = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.update(
|
|
|
|
|
|
**{
|
|
|
|
|
|
".id": script[".id"],
|
|
|
|
|
|
"source": pppoeStatusScript.replace(
|
|
|
|
|
|
"<IP>", config["public"]
|
|
|
|
|
|
),
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# todo 配置计划任务
|
2025-09-30 12:33:21 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"配置脚本失败: {e}")
|
|
|
|
|
|
|
2025-09-25 13:36:12 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
def configJhLogs(conn: Api, config):
|
|
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
配置日志处理
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
|
|
|
|
|
# 添加日志过滤器
|
2025-09-30 12:33:21 +08:00
|
|
|
|
filters = conn.path("ip", "firewall", "filter")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for filter in filters:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if filter["comment"] == "natlog":
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
filters.remove(filter[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除过滤器失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
filters.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"chain": "forward",
|
|
|
|
|
|
"action": "log",
|
|
|
|
|
|
"comment": "natlog",
|
|
|
|
|
|
"dst-address": "10.0.0.0/8",
|
|
|
|
|
|
"protocol": "tcp",
|
|
|
|
|
|
"connection-nat-state": "srcnat",
|
|
|
|
|
|
"tcp-flags": "syn",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
filters.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"chain": "forward",
|
|
|
|
|
|
"action": "log",
|
|
|
|
|
|
"comment": "natlog",
|
|
|
|
|
|
"src-address": "10.0.0.0/8",
|
|
|
|
|
|
"protocol": "udp",
|
|
|
|
|
|
"dst-port": "!53",
|
|
|
|
|
|
"connection-nat-state": "!srcnat",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
# 添加日志动作
|
2025-09-30 12:33:21 +08:00
|
|
|
|
actions = conn.path("system", "logging", "action")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
for action in actions:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if action["name"] in ["logremote", "logremoteidc"]:
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
actions.remove(action[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除日志动作失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
actions.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": "logremote",
|
|
|
|
|
|
"target": "remote",
|
|
|
|
|
|
"src-address": "0.0.0.0",
|
|
|
|
|
|
"remote": "106.119.167.38",
|
|
|
|
|
|
"remote-port": "5775",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
actions.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": "logremoteidc",
|
|
|
|
|
|
"target": "remote",
|
|
|
|
|
|
"src-address": "0.0.0.0",
|
|
|
|
|
|
"remote": "192.168.100.255",
|
|
|
|
|
|
"remote-port": "5775",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
# 配置日志动作
|
2025-09-30 12:33:21 +08:00
|
|
|
|
logs = conn.path("system", "logging")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
for log in logs:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if "firewall" in log["topics"] and "info" in log["topics"]:
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
logs.remove(log[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除日志配置失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
logs.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"topics": "firewall,info",
|
|
|
|
|
|
"prefix": config["code"],
|
|
|
|
|
|
"action": "logremote",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
logs.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"topics": "firewall,info",
|
|
|
|
|
|
"prefix": config["code"],
|
|
|
|
|
|
"action": "logremoteidc",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"配置日志处理失败: {e}")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
|
|
|
|
|
|
def configJhDrop(conn: Api, config):
|
|
|
|
|
|
"""
|
2025-09-28 18:05:21 +08:00
|
|
|
|
配置丢弃规则
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
|
|
|
|
|
domains = [
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"kasut.org",
|
|
|
|
|
|
"chigua41.xyz",
|
|
|
|
|
|
"chigua35.info",
|
|
|
|
|
|
"chigua32.life",
|
|
|
|
|
|
"iufsvayufgiwlj6ok.com",
|
|
|
|
|
|
"kaixr.top",
|
|
|
|
|
|
"qiopqc.cn",
|
|
|
|
|
|
"lsdhgsduyccnja18.com",
|
|
|
|
|
|
"tongyan01.club",
|
|
|
|
|
|
"nenmei37.club",
|
|
|
|
|
|
"69lesbi.com",
|
|
|
|
|
|
"ero-labs.cool",
|
|
|
|
|
|
"soxue100.com",
|
|
|
|
|
|
"24news.world",
|
|
|
|
|
|
"aaa215.click",
|
|
|
|
|
|
"qqqqqdfggjkgfgfhe.cc",
|
|
|
|
|
|
"lovefootjob.com",
|
|
|
|
|
|
"hadesex.com",
|
2025-09-28 18:05:21 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
ips = [
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"23.231.144.26",
|
|
|
|
|
|
"23.231.183.17",
|
|
|
|
|
|
"23.231.182.57",
|
|
|
|
|
|
"23.231.182.56",
|
|
|
|
|
|
"154.92.94.91",
|
|
|
|
|
|
"154.92.94.163",
|
|
|
|
|
|
"192.250.241.167",
|
|
|
|
|
|
"192.250.192.242",
|
2025-09-28 18:05:21 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# 非法网站列表
|
2025-09-30 12:33:21 +08:00
|
|
|
|
layer7 = conn.path("ip", "firewall", "layer7-protocol")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
for item in layer7:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if item["name"] == "illegal":
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
layer7.remove(item[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除 Layer7 规则失败: {}".format(e))
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
layer7.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": "illegal",
|
|
|
|
|
|
"regexp": f'({"|".join([re.escape(domain) for domain in domains])})[/:]?.*',
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
# 非法 IP 列表
|
2025-09-30 12:33:21 +08:00
|
|
|
|
addressLists = conn.path("ip", "firewall", "address-list")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
for item in addressLists:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if item["list"] == "illegal":
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
ips.remove(item["address"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
for ip in ips:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
addressLists.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"list": "illegal",
|
|
|
|
|
|
"address": ip,
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
# 添加丢弃规则
|
2025-09-30 12:33:21 +08:00
|
|
|
|
filters = conn.path("ip", "firewall", "filter")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
for item in filters:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
if item["comment"] == "drop illegal websites":
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
filters.remove(item[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除过滤器失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
elif item["comment"] == "drop illegal ips":
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
filters.remove(item[".id"])
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除过滤器失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
filters.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"chain": "forward",
|
|
|
|
|
|
"action": "drop",
|
|
|
|
|
|
"layer7-protocol": "illegal",
|
|
|
|
|
|
"comment": "drop illegal websites",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
filters.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"chain": "forward",
|
|
|
|
|
|
"action": "drop",
|
|
|
|
|
|
"src-address-list": "illegal",
|
|
|
|
|
|
"comment": "drop illegal ips",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"配置丢弃规则失败: {e}")
|
|
|
|
|
|
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
# ====================
|
|
|
|
|
|
# 极光配置
|
|
|
|
|
|
# ====================
|
2025-09-08 12:55:20 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
|
|
|
|
|
|
def configJgAuth(conn: Api, config):
|
|
|
|
|
|
"""
|
|
|
|
|
|
配置极光认证授权
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
l2tp = conn.path("interface", "l2tp-server", "server")
|
|
|
|
|
|
l2tp.update(**{"enabled": "yes", "use-ipsec": "yes", "ipsec-secret": "byjd231"})
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置 l2tp 服务器失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
radius = conn.path("radius")
|
|
|
|
|
|
for item in radius:
|
|
|
|
|
|
radius.remove(item[".id"])
|
|
|
|
|
|
|
|
|
|
|
|
radius.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"service": "ppp",
|
|
|
|
|
|
"address": "106.119.166.87",
|
|
|
|
|
|
"secret": "juipwyk123...",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置 radius 失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def configJgOuts(conn: Api, config):
|
|
|
|
|
|
"""
|
2025-09-28 18:05:21 +08:00
|
|
|
|
配置 vpn 出口负载均衡
|
2025-09-30 12:33:21 +08:00
|
|
|
|
"""
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
count = 20
|
|
|
|
|
|
|
|
|
|
|
|
# 配置 ppp
|
2025-09-30 12:33:21 +08:00
|
|
|
|
try:
|
|
|
|
|
|
ppps = conn.path("interface", "l2tp-client")
|
|
|
|
|
|
|
|
|
|
|
|
for ppp in ppps:
|
|
|
|
|
|
if ppp["name"].startswith("l2tp-out"):
|
|
|
|
|
|
try:
|
|
|
|
|
|
ppps.remove(ppp[".id"])
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError("删除 PPP 失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(1, count + 1):
|
|
|
|
|
|
ppps.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": f"l2tp-out{i}",
|
|
|
|
|
|
"connect-to": f"192.168.0.{int(config['gate'])+1}",
|
|
|
|
|
|
"user": f"bydj{config['gate']}api{(int(config['index'])-1) * count + i}",
|
|
|
|
|
|
"password": "byjd231",
|
|
|
|
|
|
"disabled": "no",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置 PPP 失败: {e}")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
# 配置路由
|
|
|
|
|
|
try:
|
|
|
|
|
|
routes = conn.path("ip", "route")
|
|
|
|
|
|
|
|
|
|
|
|
for route in routes:
|
|
|
|
|
|
if str(route["routing-table"]).startswith("r"):
|
|
|
|
|
|
try:
|
|
|
|
|
|
routes.remove(route[".id"])
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError("删除路由表失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(1, count + 1):
|
|
|
|
|
|
routeName = "r{}".format(i)
|
|
|
|
|
|
routeOut = "l2tp-out{}".format(i)
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"dst-address": "0.0.0.0/0",
|
|
|
|
|
|
"gateway": routeOut,
|
|
|
|
|
|
"routing-table": routeName,
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"添加路由表失败: {e}")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置路由失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置出口失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def configJgMixOuts(conn: Api, config):
|
|
|
|
|
|
"""
|
|
|
|
|
|
配置 vpn 出口负载均衡
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
count = 300
|
|
|
|
|
|
|
|
|
|
|
|
# 配置 ppp
|
|
|
|
|
|
try:
|
|
|
|
|
|
ppps = conn.path("interface", "l2tp-client")
|
|
|
|
|
|
|
|
|
|
|
|
for ppp in ppps:
|
|
|
|
|
|
if ppp["name"].startswith("l2tp-out"):
|
|
|
|
|
|
ppps.remove(ppp[".id"])
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(1, count + 1):
|
|
|
|
|
|
ppps.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": f"l2tp-out{i}",
|
|
|
|
|
|
"connect-to": f"192.168.0.{int(config['gate'])+1}",
|
|
|
|
|
|
"user": f"bydj{config['gate']}api{(int(config['index'])-1) * count + i}",
|
|
|
|
|
|
"password": "byjd231",
|
|
|
|
|
|
"disabled": "no",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置 PPP 失败: {e}")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# 配置路由
|
2025-09-30 12:33:21 +08:00
|
|
|
|
try:
|
|
|
|
|
|
routes = conn.path("ip", "route")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
for route in routes:
|
|
|
|
|
|
if str(route["routing-table"]).startswith("r"):
|
|
|
|
|
|
routes.remove(route[".id"])
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(1, count + 1):
|
|
|
|
|
|
routeName = "r{}".format(i)
|
|
|
|
|
|
routeOut = "l2tp-out{}".format(i)
|
2025-09-28 18:05:21 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
routes.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"dst-address": "0.0.0.0/0",
|
|
|
|
|
|
"gateway": routeOut,
|
|
|
|
|
|
"routing-table": routeName,
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"添加路由表失败: {e}")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置路由失败: {e}")
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
2025-09-30 12:33:21 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置出口失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def configJgScripts(conn: Api, config):
|
|
|
|
|
|
"""
|
|
|
|
|
|
配置脚本
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 配置脚本
|
|
|
|
|
|
scripts = conn.path("system", "script")
|
|
|
|
|
|
|
|
|
|
|
|
for script in scripts:
|
2025-09-08 12:55:20 +08:00
|
|
|
|
try:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
scripts.remove(script[".id"])
|
2025-09-08 12:55:20 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError("删除脚本失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
path = "scripts/jg"
|
|
|
|
|
|
|
|
|
|
|
|
with open(f"{path}/up.rsc", "rb") as file:
|
|
|
|
|
|
up = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.add(**{"name": "up", "source": up})
|
|
|
|
|
|
|
|
|
|
|
|
with open(f"{path}/down.rsc", "rb") as file:
|
|
|
|
|
|
down = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.add(**{"name": "down", "source": down})
|
|
|
|
|
|
|
|
|
|
|
|
with open("scripts/jg/onlinestatus.rsc", "rb") as file:
|
|
|
|
|
|
onlineStatus = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
onlineStatus = onlineStatus.replace("<IP>", config["public"])
|
|
|
|
|
|
scripts.add(**{"name": "onlinestatus", "source": onlineStatus})
|
|
|
|
|
|
|
|
|
|
|
|
with open(f"{path}/pppoestatus.rsc", "rb") as file:
|
|
|
|
|
|
pppoeStatus = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
pppoeStatus = pppoeStatus.replace("<IP>", config["public"])
|
|
|
|
|
|
scripts.add(**{"name": "pppoestatus", "source": pppoeStatus})
|
|
|
|
|
|
|
|
|
|
|
|
with open(f"{path}/l2tpstatus.rsc", "rb") as file:
|
|
|
|
|
|
l2tpstatus = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.add(**{"name": "l2tpstatus", "source": l2tpstatus})
|
|
|
|
|
|
|
|
|
|
|
|
with open(f"{path}/outtime.rsc", "rb") as file:
|
|
|
|
|
|
outtime = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.add(**{"name": "outtime", "source": outtime})
|
|
|
|
|
|
|
|
|
|
|
|
with open(f"{path}/rmroute.rsc", "rb") as file:
|
|
|
|
|
|
rmroute = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.add(**{"name": "rmroute", "source": rmroute})
|
|
|
|
|
|
|
|
|
|
|
|
with open(f"{path}/ros.rsc", "rb") as file:
|
|
|
|
|
|
ros = str(file.read(), encoding="utf-8")
|
|
|
|
|
|
scripts.add(**{"name": "ros", "source": ros})
|
|
|
|
|
|
|
|
|
|
|
|
scripts.add(**{"name": "num", "source": "0"})
|
|
|
|
|
|
scripts.add(**{"name": "addressname", "source": str(config["code"])})
|
|
|
|
|
|
|
|
|
|
|
|
# 配置计划任务
|
|
|
|
|
|
schedulers = conn.path("system", "scheduler")
|
|
|
|
|
|
for scheduler in schedulers:
|
|
|
|
|
|
if scheduler["name"] == "l2tpstatus":
|
|
|
|
|
|
schedulers.remove(scheduler[".id"])
|
|
|
|
|
|
schedulers.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": "l2tpstatus",
|
|
|
|
|
|
"interval": "5m",
|
|
|
|
|
|
"on-event": "/system script run l2tpstatus",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
except Exception as e:
|
2025-09-30 12:33:21 +08:00
|
|
|
|
raise RuntimeError(f"配置脚本失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def configJgLogs(conn: Api, config):
|
|
|
|
|
|
"""
|
|
|
|
|
|
配置日志处理
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 添加日志过滤器
|
|
|
|
|
|
filters = conn.path("ip", "firewall", "filter")
|
|
|
|
|
|
for filter in filters:
|
|
|
|
|
|
if filter["comment"] == "natlog":
|
|
|
|
|
|
try:
|
|
|
|
|
|
filters.remove(filter[".id"])
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError("删除过滤器失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
filters.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"chain": "forward",
|
|
|
|
|
|
"action": "log",
|
|
|
|
|
|
"comment": "natlog",
|
|
|
|
|
|
"dst-address": "10.0.0.0/8",
|
|
|
|
|
|
"protocol": "tcp",
|
|
|
|
|
|
"connection-nat-state": "srcnat",
|
|
|
|
|
|
"tcp-flags": "syn",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
filters.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"chain": "forward",
|
|
|
|
|
|
"action": "log",
|
|
|
|
|
|
"comment": "natlog",
|
|
|
|
|
|
"src-address": "10.0.0.0/8",
|
|
|
|
|
|
"protocol": "udp",
|
|
|
|
|
|
"dst-port": "!53",
|
|
|
|
|
|
"connection-nat-state": "!srcnat",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# 添加日志动作
|
|
|
|
|
|
actions = conn.path("system", "logging", "action")
|
|
|
|
|
|
|
|
|
|
|
|
for action in actions:
|
|
|
|
|
|
if action["name"] in ["logremote", "logremoteidc"]:
|
|
|
|
|
|
try:
|
|
|
|
|
|
actions.remove(action[".id"])
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError("删除日志动作失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
actions.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": "logremote",
|
|
|
|
|
|
"target": "remote",
|
|
|
|
|
|
"src-address": "0.0.0.0",
|
|
|
|
|
|
"remote": "106.119.166.79",
|
|
|
|
|
|
"remote-port": "5775",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
actions.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"name": "logremoteidc",
|
|
|
|
|
|
"target": "remote",
|
|
|
|
|
|
"src-address": "0.0.0.0",
|
|
|
|
|
|
"remote": "192.168.255.9",
|
|
|
|
|
|
"remote-port": "5775",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# 配置日志动作
|
|
|
|
|
|
logs = conn.path("system", "logging")
|
|
|
|
|
|
|
|
|
|
|
|
for log in logs:
|
|
|
|
|
|
if "firewall" in log["topics"] and "info" in log["topics"]:
|
|
|
|
|
|
try:
|
|
|
|
|
|
logs.remove(log[".id"])
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError("删除日志配置失败: {}".format(e))
|
|
|
|
|
|
|
|
|
|
|
|
logs.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"topics": "firewall,info",
|
|
|
|
|
|
"prefix": config["code"],
|
|
|
|
|
|
"action": "logremote",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
logs.add(
|
|
|
|
|
|
**{
|
|
|
|
|
|
"topics": "firewall,info",
|
|
|
|
|
|
"prefix": config["code"],
|
|
|
|
|
|
"action": "logremoteidc",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise RuntimeError(f"配置日志处理失败: {e}")
|
|
|
|
|
|
|
2025-09-28 18:05:21 +08:00
|
|
|
|
|
|
|
|
|
|
# ====================
|
|
|
|
|
|
# 临时
|
|
|
|
|
|
# ====================
|