Files
config-ros/steps.py
2026-02-26 15:40:34 +08:00

767 lines
23 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import re
from librouteros import Api
"""
配置步骤,每个步骤都可以安全幂等执行,配置混合节点的出口的函数可能会很慢,因为出口比较多
"""
def configNet(conn: Api, config):
"""
配置网络
"""
try:
# 配置路由
routes = conn.path("ip", "route")
for route in routes:
if route["routing-table"] == "1":
try:
routes.update(**{".id": route[".id"], "gateway": config["gateway"]})
except Exception as e:
raise RuntimeError("更新默认路由失败: {}".format(e))
# 配置地址
addrs = conn.path("ip", "address")
for addr in addrs:
if addr["interface"] == "lan":
try:
addrs.update(**{".id": addr[".id"], "address": config["private"]})
except Exception as e:
raise RuntimeError("更新 WAN 地址失败: {}".format(e))
# 刷新 mac 地址
eths = conn.path("interface", "ethernet")
for eth in eths:
if eth["name"] == "lan":
tuple(eths("reset-mac-address", **{".id": eth[".id"]}))
except Exception as e:
raise RuntimeError(f"配置网络失败: {e}")
# ====================
# 极狐配置
# ====================
def configJhOuts(conn: Api, config):
"""
配置 vpn 出口负载均衡
"""
try:
count = 20
# 配置 ppp
ppps = conn.path("interface", "l2tp-client")
# 删除旧的 ppp
for ppp in ppps:
if ppp["name"].startswith("l2tp-out"):
try:
ppps.remove(ppp[".id"])
except Exception as e:
raise RuntimeError("删除 PPP 失败: {}".format(e))
# 添加新的 ppp
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",
}
)
# 配置路由
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)
try:
routes.add(
**{
"dst-address": "0.0.0.0/0",
"gateway": routeOut,
"routing-table": routeName,
}
)
except Exception as e:
raise RuntimeError(f"添加路由表失败: {e}")
except Exception as e:
raise RuntimeError(f"配置出口失败: {e}")
def configJhMixOuts(conn: Api, config):
"""
配置 vpn 出口负载均衡 (混合模式)
"""
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))
index = (int(config["index"]) - 1) * 10
for i in range(30):
for j in range(10):
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 + 1 + index}dt{i + 221}",
"password": "123231",
"disabled": "no",
}
)
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(300):
routeName = f"r{i + 1}"
routeOut = f"l2tp-out{i + 1}"
try:
routes.add(
**{
"dst-address": "0.0.0.0/0",
"gateway": routeOut,
"routing-table": routeName,
}
)
except Exception as e:
raise RuntimeError(f"添加路由表失败: {e}")
except Exception as e:
raise RuntimeError(f"配置出口失败: {e}")
def configJhScripts(conn: Api, config):
"""
配置脚本
"""
try:
# 配置脚本
scripts = conn.path("system", "script")
for script in scripts:
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"]
),
}
)
# todo 配置计划任务
except Exception as e:
raise RuntimeError(f"配置脚本失败: {e}")
def configJhLogs(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.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",
}
)
# 配置日志动作
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}")
def configJhDrop(conn: Api, config):
"""
配置丢弃规则
"""
try:
domains = [
"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",
]
ips = [
"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",
]
# 非法网站列表
layer7 = conn.path("ip", "firewall", "layer7-protocol")
for item in layer7:
if item["name"] == "illegal":
try:
layer7.remove(item[".id"])
except Exception as e:
raise RuntimeError("删除 Layer7 规则失败: {}".format(e))
layer7.add(
**{
"name": "illegal",
"regexp": f"({'|'.join([re.escape(domain) for domain in domains])})[/:]?.*",
}
)
# 非法 IP 列表
addressLists = conn.path("ip", "firewall", "address-list")
for item in addressLists:
if item["list"] == "illegal":
try:
ips.remove(item["address"])
except Exception as e:
continue
for ip in ips:
addressLists.add(
**{
"list": "illegal",
"address": ip,
}
)
# 添加丢弃规则
filters = conn.path("ip", "firewall", "filter")
for item in filters:
if item["comment"] == "drop illegal websites":
try:
filters.remove(item[".id"])
except Exception as e:
raise RuntimeError("删除过滤器失败: {}".format(e))
elif item["comment"] == "drop illegal ips":
try:
filters.remove(item[".id"])
except Exception as e:
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",
}
)
except Exception as e:
raise RuntimeError(f"配置丢弃规则失败: {e}")
# ====================
# 极光配置
# ====================
def configJgAuth(conn: Api, config):
"""
配置极光认证授权
"""
try:
l2tp = conn.path("interface", "l2tp-server", "server")
l2tp.update(**{"enabled": "yes", "use-ipsec": "yes", "ipsec-secret": "1234"})
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):
"""
配置 vpn 出口负载均衡
"""
try:
count = 10
window = 20
# 配置 ppp
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"byjd{config['gate']}api{(int(config['index']) - 1) * window + i}",
"password": "byjd231",
"disabled": "no",
}
)
except Exception as e:
raise RuntimeError(f"配置 PPP 失败: {e}")
# 配置路由
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)
try:
routes.add(
**{
"dst-address": "0.0.0.0/0",
"gateway": routeOut,
"routing-table": routeName,
}
)
except Exception as e:
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"byjd{config['gate']}api{(int(config['index']) - 1) * count + i}",
"password": "byjd231",
"disabled": "no",
}
)
except Exception as e:
raise RuntimeError(f"配置 PPP 失败: {e}")
# 配置路由
try:
routes = conn.path("ip", "route")
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)
try:
routes.add(
**{
"dst-address": "0.0.0.0/0",
"gateway": routeOut,
"routing-table": routeName,
}
)
except Exception as e:
raise RuntimeError(f"添加路由表失败: {e}")
except Exception as e:
raise RuntimeError(f"配置路由失败: {e}")
except Exception as e:
raise RuntimeError(f"配置出口失败: {e}")
def configJgScripts(conn: Api, config):
"""
配置脚本
"""
try:
# 配置脚本
scripts = conn.path("system", "script")
for script in scripts:
try:
scripts.remove(script[".id"])
except Exception as e:
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",
}
)
except Exception as e:
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}")
# ====================
# 临时
# ====================
def temp(conn: Api, config):
ppps = conn.path("interface", "l2tp-client")
count = 0
for ppp in ppps:
count += 1
if ppp["name"].startswith("l2tp-out") and ppp["running"] != True:
break
if count < 20:
raise RuntimeError(f"有未运行的 PPPcount={count}")
# file = open(f"outs/{config['code']}.csv", "w", encoding="utf-8")
# file.write("ros,name,connect-to,user,running\n")
# for ppp in ppps:
# file.write("{},{},{},{},{}\n".format(
# config["name"],
# ppp["name"],
# ppp["connect-to"],
# ppp["user"],
# ppp["running"],
# ))
# file.close()