混拨节点适配

This commit is contained in:
2025-09-08 12:55:20 +08:00
parent 40aba1a401
commit 906ef41e50
7 changed files with 446 additions and 344 deletions

View File

@@ -1,3 +1,71 @@
## 部署流程
**参数**
- 默认网关
- 公网 CIDR
- 内网 CIDR
- RADIUS 配置
- NAT 网关
- 节点 IP 池
- 节点地区编号
- 城市数量
- 窗口数量
- 连接报告地址
- 日志报告地址
**配置网络**
刷新 mac 地址(手动)
默认网关(手动 [默认网关]
wan 口 ip手动 [公网 CIDR]
lan 口 ip[内网 CIDR]
**配置 vpn**
地址池172.17.0.0/16
ppp profile本地地址地址池
pptp & l2tp & sstp 服务端profile
ppp secrets & radius[RADIUS 配置]
路由表默认路由路由策略default => [NAT 网关]172.17.0.0/16 => vpn
**配置 nat**
ospf 路由表,黑洞路由([节点 IP 池]
实例,区域,模板;在 lan 上的 area0 区域重分发黑洞路由表上的静态路由区域
**配置脚本**
上线脚本:
- 删除旧 nat 规则
- 根据[节点地区编号][城市数量][窗口数量]生成 ipv4 地址生成 snat 规则172.16.x.x => 10.i.j.k
- 上报开始占用
下线脚本:
- 删除旧 nat 规则
- 上报解除占用
清理超时连接9 小时):
- 查找并删除在线超过 24 小时的连接
报告用户在线数量5 分钟):
- 查找并上报用户在线数量
配置脚本调度
挂载上下线脚本到 ppp profile
**配置日志**
上报到远程地址
## 单地区
### 添加 ros 后应该改什么

View File

@@ -1,4 +1,5 @@
index,name,code,gateway,public,mask,private,domain,cert
0,混拨1,hh1,43.226.58.1,43.226.58.9,24,192.168.98.1,hh,server.9.crt
1,宣城,ahxc215,43.226.58.1,43.226.58.10,24,192.168.99.1,ahxc,server.crt
2,宿州,ahsz216,43.226.58.1,43.226.58.11,24,192.168.99.2,ahsz,server.crt
3,阜阳,ahfy225,43.226.58.1,43.226.58.12,24,192.168.99.3,ahfy,server.crt
1 index name code gateway public mask private domain cert
2 0 混拨1 hh1 43.226.58.1 43.226.58.9 24 192.168.98.1 hh server.9.crt
3 1 宣城 ahxc215 43.226.58.1 43.226.58.10 24 192.168.99.1 ahxc server.crt
4 2 宿州 ahsz216 43.226.58.1 43.226.58.11 24 192.168.99.2 ahsz server.crt
5 3 阜阳 ahfy225 43.226.58.1 43.226.58.12 24 192.168.99.3 ahfy server.crt

View File

@@ -1,21 +1,2 @@
index,name,code,gateway,public,mask,private,domain,cert
51,宁波,zjnb138,43.226.58.1,43.226.58.60,24,192.168.99.51,zjnb,server.60.crt
52,杭州,zjhz143,43.226.58.1,43.226.58.61,24,192.168.99.52,zjhz,server.61.crt
53,绍兴,zjsx136,43.226.58.1,43.226.58.62,24,192.168.99.53,zjsx,server.62.crt
54,丽水,zjls139,43.226.58.1,43.226.58.63,24,192.168.99.54,zjls,server.63.crt
55,温州,zjwz134,43.226.58.1,43.226.58.64,24,192.168.99.55,zjwz,server.64.crt
56,湖州,zjhz142,43.226.58.1,43.226.58.65,24,192.168.99.56,zjhuz,server.65.crt
57,舟山,zjzs133,43.226.58.1,43.226.58.66,24,192.168.99.57,zjzs,server.66.crt
58,衢州,zjqz137,43.226.58.1,43.226.58.67,24,192.168.99.58,zjqz,server.67.crt
59,金华,zjjh140,43.226.58.1,43.226.58.68,24,192.168.99.59,zjjh,server.68.crt
60,海口,hnhk172,43.226.58.1,43.226.58.69,24,192.168.99.60,hnhk,server.69.crt
61,文昌,hnwc170,43.226.58.1,43.226.58.70,24,192.168.99.61,hnwc,server.70.crt
62,三亚,hnsy171,43.226.58.1,43.226.58.71,24,192.168.99.62,hnsya,server.71.crt
63,上海,sh130,43.226.58.1,43.226.58.72,24,192.168.99.63,sh,server.72.crt
64,昆明,ynkm144,43.226.58.1,43.226.58.73,24,192.168.99.64,ynkm,server.73.crt
65,呼和浩特,nmghhht192,43.226.58.1,43.226.58.74,24,192.168.99.65,nmghhht,server.74.crt
66,赤峰,nmgcf194,43.226.58.1,43.226.58.75,24,192.168.99.66,nmgcf,server.75.crt
67,鄂尔多斯,nmgeeds193,43.226.58.1,43.226.58.76,24,192.168.99.67,nmgeeds,server.76.crt
68,通辽,nmgtl190,43.226.58.1,43.226.58.77,24,192.168.99.68,nmgtl,server.77.crt
69,包头,nmgbt195,43.226.58.1,43.226.58.78,24,192.168.99.69,nmgbt,server.78.crt
70,呼伦贝尔,nmghlbe191,43.226.58.1,43.226.58.79,24,192.168.99.70,nmghlbe,server.79.crt
0,混拨1,hh1,43.226.58.1,43.226.58.9,24,192.168.98.1,hh,server.9.crt
1 index name code gateway public mask private domain cert
2 51 0 宁波 混拨1 zjnb138 hh1 43.226.58.1 43.226.58.60 43.226.58.9 24 192.168.99.51 192.168.98.1 zjnb hh server.60.crt server.9.crt
52 杭州 zjhz143 43.226.58.1 43.226.58.61 24 192.168.99.52 zjhz server.61.crt
53 绍兴 zjsx136 43.226.58.1 43.226.58.62 24 192.168.99.53 zjsx server.62.crt
54 丽水 zjls139 43.226.58.1 43.226.58.63 24 192.168.99.54 zjls server.63.crt
55 温州 zjwz134 43.226.58.1 43.226.58.64 24 192.168.99.55 zjwz server.64.crt
56 湖州 zjhz142 43.226.58.1 43.226.58.65 24 192.168.99.56 zjhuz server.65.crt
57 舟山 zjzs133 43.226.58.1 43.226.58.66 24 192.168.99.57 zjzs server.66.crt
58 衢州 zjqz137 43.226.58.1 43.226.58.67 24 192.168.99.58 zjqz server.67.crt
59 金华 zjjh140 43.226.58.1 43.226.58.68 24 192.168.99.59 zjjh server.68.crt
60 海口 hnhk172 43.226.58.1 43.226.58.69 24 192.168.99.60 hnhk server.69.crt
61 文昌 hnwc170 43.226.58.1 43.226.58.70 24 192.168.99.61 hnwc server.70.crt
62 三亚 hnsy171 43.226.58.1 43.226.58.71 24 192.168.99.62 hnsya server.71.crt
63 上海 sh130 43.226.58.1 43.226.58.72 24 192.168.99.63 sh server.72.crt
64 昆明 ynkm144 43.226.58.1 43.226.58.73 24 192.168.99.64 ynkm server.73.crt
65 呼和浩特 nmghhht192 43.226.58.1 43.226.58.74 24 192.168.99.65 nmghhht server.74.crt
66 赤峰 nmgcf194 43.226.58.1 43.226.58.75 24 192.168.99.66 nmgcf server.75.crt
67 鄂尔多斯 nmgeeds193 43.226.58.1 43.226.58.76 24 192.168.99.67 nmgeeds server.76.crt
68 通辽 nmgtl190 43.226.58.1 43.226.58.77 24 192.168.99.68 nmgtl server.77.crt
69 包头 nmgbt195 43.226.58.1 43.226.58.78 24 192.168.99.69 nmgbt server.78.crt
70 呼伦贝尔 nmghlbe191 43.226.58.1 43.226.58.79 24 192.168.99.70 nmghlbe server.79.crt

336
main.py
View File

@@ -1,9 +1,10 @@
import re
from librouteros import connect,Api
import csv
import ssl
import threading
from steps import *
'''
自动配置 ros 脚本,需要安装 librouteros 库:
@@ -27,6 +28,12 @@ pip install librouteros
threads = []
failed = []
# 配置执行步骤
steps = [
configLogs
]
def main():
# 加载配置文件
config_data = []
@@ -68,337 +75,18 @@ def start(config):
ssl_wrapper=ctx.wrap_socket,
)
except Exception as err:
failed.append((config, err))
failed.append((config, f'连接失败: {err}'))
return
# 配置 ros
try:
addDrop(conn, config)
for step in steps:
step(conn, config)
except Exception as err:
failed.append((config, err))
failed.append((config, f'配置失败: {err}'))
# 关闭连接
conn.close()
def configDefault(conn:Api,config):
configNet(conn, config)
configOuts(conn, config)
configScripts(conn, config)
def configNet(conn:Api,config):
'''
配置网络
'''
# 配置路由
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:
print('更新默认路由失败: {}'.format(e))
continue
# 配置地址
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:
print('更新 WAN 地址失败: {}'.format(e))
continue
# 刷新 mac 地址
eths = conn.path('interface', 'ethernet')
for eth in eths:
if eth['name'] == 'lan':
tuple(eths('reset-mac-address', **{
'.id': eth['.id']
}))
def configOuts(conn:Api,config):
'''
配置 vpn 出口负载均衡
'''
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:
print('删除 PPP 失败: {}'.format(e))
continue
# 添加新的 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:
print('删除路由表失败: {}'.format(e))
continue
# 添加新的路由表
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:
print('添加路由表失败: {}'.format(e))
continue
def configScripts(conn:Api,config):
'''
配置脚本
'''
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'])
})
def configLogs(conn:Api,config):
'''
配置日志处理
'''
# 添加日志过滤器
filters = conn.path('ip', 'firewall', 'filter')
for filter in filters:
if filter['comment'] == 'natlog':
try:
filters.remove(filter['.id'])
except Exception as e:
print('删除过滤器失败: {}'.format(e))
continue
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:
print('删除日志动作失败: {}'.format(e))
continue
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:
print('删除日志配置失败: {}'.format(e))
continue
logs.add(**{
'topics': 'firewall,info',
'prefix': config['code'],
'action': 'logremote',
})
logs.add(**{
'topics': 'firewall,info',
'prefix': config['code'],
'action': 'logremoteidc',
})
def addDrop(conn:Api, config):
'''
添加丢弃规则
'''
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:
print('删除 Layer7 规则失败: {}'.format(e))
continue
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:
print('删除过滤器失败: {}'.format(e))
continue
elif item['comment'] == 'drop illegal ips':
try:
filters.remove(item['.id'])
except Exception as e:
print('删除过滤器失败: {}'.format(e))
continue
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',
})
main()

16
scripts/down_ppp.rsc Normal file
View File

@@ -0,0 +1,16 @@
:log debug "用户 $"remote-address" 下线"
# 删除旧的分配规则
:local "snat-address" [/ip/firewall/nat/get [find src-address $"remote-address"] to-addresses]
/ip/firewall/nat/remove [find where src-address $"remote-address"]
:log debug "删除旧的 nat 规则"
# 上报调度服务
:local edge ($"snat-address"&0.0.0.255<<8)
:local city (($"snat-address"&0.0.255.0>>8)+1)
:local localip (172.16.0.0|$edge|$city)
:log debug "上报到调度服务 http://192.168.250.250:18702/server/ros/down/ip/$localip"
/tool fetch url="http://192.168.250.250:18702/server/ros/down/ip/$localip" mode=http
/file remove "$localip"

26
scripts/up_ppp.rsc Normal file
View File

@@ -0,0 +1,26 @@
:log debug "用户 $"remote-address" 上线"
# 删除旧的分配规则
/ip/firewall/nat/remove [find where src-address $"remote-address"]
:log debug "删除旧的 nat 规则"
# 分配出口 IP
:local RosIndex [/system/script/environment/get RosIndex value]
:local CityCount [/system/script/environment/get CityCount value]
:local EdgeCount [/system/script/environment/get EdgeCount value]
:local edge [:rndnum from=1 to=$EdgeCount]
:local city [:rndnum from=2 to=$CityCount]
:local "snat-address" "10.$RosIndex.$city.$edge"
/ip/firewall/nat/add chain=srcnat src-address=$"remote-address" action=src-nat to-addresses=$"snat-address" comment="snat $"remote-address" => $"snat-address""
:log debug "添加新的 nat 规则 snat $"remote-address" => $"snat-address""
# 上报调度服务
:local cityP ($city + 1)
:local localip "172.16.$edge.$cityP"
:log debug "上报到调度服务 http://192.168.250.250:18702/server/ros/up/ip/$localip"
/tool/fetch url="http://192.168.250.250:18702/server/ros/up/ip/$localip" mode=http
/file remove "$localip"

322
steps.py Normal file
View File

@@ -0,0 +1,322 @@
import re
from librouteros import connect,Api
def configDefault(conn:Api,config):
configNet(conn, config)
configOuts(conn, config)
configScripts(conn, config)
def configNet(conn:Api,config):
'''
配置网络
'''
# 配置路由
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:
print('更新默认路由失败: {}'.format(e))
continue
# 配置地址
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:
print('更新 WAN 地址失败: {}'.format(e))
continue
# 刷新 mac 地址
eths = conn.path('interface', 'ethernet')
for eth in eths:
if eth['name'] == 'lan':
tuple(eths('reset-mac-address', **{
'.id': eth['.id']
}))
def configOuts(conn:Api,config):
'''
配置 vpn 出口负载均衡
'''
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:
print('删除 PPP 失败: {}'.format(e))
continue
# 添加新的 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:
print('删除路由表失败: {}'.format(e))
continue
# 添加新的路由表
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:
print('添加路由表失败: {}'.format(e))
continue
def configScripts(conn:Api,config):
'''
配置脚本
'''
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'])
})
def configLogs(conn:Api,config):
'''
配置日志处理
'''
# 添加日志过滤器
filters = conn.path('ip', 'firewall', 'filter')
for filter in filters:
if filter['comment'] == 'natlog':
try:
filters.remove(filter['.id'])
except Exception as e:
print('删除过滤器失败: {}'.format(e))
continue
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:
print('删除日志动作失败: {}'.format(e))
continue
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:
print('删除日志配置失败: {}'.format(e))
continue
logs.add(**{
'topics': 'firewall,info',
'prefix': config['code'],
'action': 'logremote',
})
logs.add(**{
'topics': 'firewall,info',
'prefix': config['code'],
'action': 'logremoteidc',
})
def addDrop(conn:Api, config):
'''
添加丢弃规则
'''
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:
print('删除 Layer7 规则失败: {}'.format(e))
continue
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:
print('删除过滤器失败: {}'.format(e))
continue
elif item['comment'] == 'drop illegal ips':
try:
filters.remove(item['.id'])
except Exception as e:
print('删除过滤器失败: {}'.format(e))
continue
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',
})