767 lines
23 KiB
Python
767 lines
23 KiB
Python
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"有未运行的 PPP,count={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()
|