💐 Sync 2025-11-05 00:13:10

This commit is contained in:
actions-user
2025-11-05 00:13:10 +08:00
parent 251207fb9c
commit e112520fb4
24 changed files with 4104 additions and 3316 deletions

View File

@@ -5,6 +5,9 @@
[ $(uname -m) = "x86_64" ] && alias board_name="echo x86_64" [ $(uname -m) = "x86_64" ] && alias board_name="echo x86_64"
# OTA
OTA_URL="https://api.kejizero.xyz/openwrt/ota.json"
# theme # theme
if [ -d "/www/luci-static/argon" ] && [ -z "$(uci -q get luci.main.pollinterval)" ]; then if [ -d "/www/luci-static/argon" ] && [ -z "$(uci -q get luci.main.pollinterval)" ]; then
uci set luci.main.mediaurlbase='/luci-static/argon' uci set luci.main.mediaurlbase='/luci-static/argon'
@@ -94,17 +97,17 @@ devices_setup()
sed -i '/openwrt_core/d' /etc/opkg/distfeeds.conf sed -i '/openwrt_core/d' /etc/opkg/distfeeds.conf
sed -i "\$a\src/gz openwrt_core https://core.kejizero.xyz/aarch64_generic/$(grep Version /usr/lib/opkg/info/kernel.control | awk '{print $2}')" /etc/opkg/distfeeds.conf sed -i "\$a\src/gz openwrt_core https://core.kejizero.xyz/aarch64_generic/$(grep Version /usr/lib/opkg/info/kernel.control | awk '{print $2}')" /etc/opkg/distfeeds.conf
} }
uci set ota.config.api_url="https://api.kejizero.xyz/openwrt/rockchip.json" uci set ota.config.api_url="$OTA_URL"
uci commit ota uci commit ota
;; ;;
x86_64) x86_64)
[ $(uname -r | awk -F. '{print $1}') = 6 ] && { [ $(uname -r | awk -F. '{print $1}') = 6 ] && {
[ -f /sys/kernel/btf/vmlinux ] && [ ! -d "/usr/share/openwrt_core" ] && { [ -f /sys/kernel/btf/vmlinux ] && [ ! -d "/usr/share/openwrt_core" ] && {
sed -i '/openwrt_core/d' /etc/opkg/distfeeds.conf sed -i '/openwrt_core/d' /etc/opkg/distfeeds.conf
sed -i "\$a\src/gz openwrt_core https://core.kejizero.xyz/x86_64/${openwrt_core}/$(grep Version /usr/lib/opkg/info/kernel.control | awk '{print $2}')" /etc/opkg/distfeeds.conf sed -i "\$a\src/gz openwrt_core https://core.kejizero.xyz/x86_64/$(grep Version /usr/lib/opkg/info/kernel.control | awk '{print $2}')" /etc/opkg/distfeeds.conf
} }
} }
uci set ota.config.api_url="https://api.kejizero.xyz/openwrt/x86_64.json" uci set ota.config.api_url="$OTA_URL"
uci commit ota uci commit ota
;; ;;
esac esac

View File

@@ -10,7 +10,7 @@ LUCI_DEPENDS:=+luci-base +luci-lib-jsonc +curl +bandix
PKG_MAINTAINER:=timsaya PKG_MAINTAINER:=timsaya
PKG_VERSION:=0.6.2 PKG_VERSION:=0.6.3
PKG_RELEASE:=1 PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk

View File

@@ -371,7 +371,7 @@ return view.extend({
var style = E('style', {}, ` var style = E('style', {}, `
.bandix-connection-container { .bandix-connection-container {
margin: 0; margin: 0;
padding: 24px; padding: 8px;
background-color: ${darkMode ? '#1E1E1E' : '#f8fafc'}; background-color: ${darkMode ? '#1E1E1E' : '#f8fafc'};
min-height: calc(100vh - 100px); min-height: calc(100vh - 100px);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

View File

@@ -25,6 +25,7 @@ const translations = {
'界面语言': '界面语言', '界面语言': '界面语言',
'选择 Bandix 流量监控的显示语言': '选择 Bandix 流量监控的显示语言', '选择 Bandix 流量监控的显示语言': '选择 Bandix 流量监控的显示语言',
'设备信息': '设备信息', '设备信息': '设备信息',
'设备列表': '设备列表',
'LAN 流量': 'LAN 流量', 'LAN 流量': 'LAN 流量',
'WAN 流量': 'WAN 流量', 'WAN 流量': 'WAN 流量',
'限速设置': '限速设置', '限速设置': '限速设置',
@@ -103,7 +104,9 @@ const translations = {
'升序': '升序', '升序': '升序',
'降序': '降序', '降序': '降序',
'按速度排序': '按速度排序', '按速度排序': '按速度排序',
'按用量排序': '按用量排序' '按用量排序': '按用量排序',
'简易模式': '简易模式',
'详细模式': '详细模式'
}, },
'zh-tw': { 'zh-tw': {
'Bandix 流量监控': 'Bandix 流量監控', 'Bandix 流量监控': 'Bandix 流量監控',
@@ -122,6 +125,7 @@ const translations = {
'界面语言': '介面語言', '界面语言': '介面語言',
'选择 Bandix 流量监控的显示语言': '選擇 Bandix 流量監控的顯示語言', '选择 Bandix 流量监控的显示语言': '選擇 Bandix 流量監控的顯示語言',
'设备信息': '設備資訊', '设备信息': '設備資訊',
'设备列表': '設備列表',
'LAN 流量': '局域網流量', 'LAN 流量': '局域網流量',
'WAN 流量': '跨網路流量', 'WAN 流量': '跨網路流量',
'限速设置': '限速設定', '限速设置': '限速設定',
@@ -200,7 +204,9 @@ const translations = {
'升序': '升序', '升序': '升序',
'降序': '降序', '降序': '降序',
'按速度排序': '按速度排序', '按速度排序': '按速度排序',
'按用量排序': '按用量排序' '按用量排序': '按用量排序',
'简易模式': '簡易模式',
'详细模式': '詳細模式'
}, },
'en': { 'en': {
'Bandix 流量监控': 'Bandix Traffic Monitor', 'Bandix 流量监控': 'Bandix Traffic Monitor',
@@ -219,6 +225,7 @@ const translations = {
'界面语言': 'Interface Language', '界面语言': 'Interface Language',
'选择 Bandix 流量监控的显示语言': 'Select the display language for Bandix Traffic Monitor', '选择 Bandix 流量监控的显示语言': 'Select the display language for Bandix Traffic Monitor',
'设备信息': 'Device Info', '设备信息': 'Device Info',
'设备列表': 'Device List',
'LAN 流量': 'LAN Traffic', 'LAN 流量': 'LAN Traffic',
'WAN 流量': 'WAN Traffic', 'WAN 流量': 'WAN Traffic',
'限速设置': 'Rate Limit', '限速设置': 'Rate Limit',
@@ -297,7 +304,9 @@ const translations = {
'升序': 'Ascending', '升序': 'Ascending',
'降序': 'Descending', '降序': 'Descending',
'按速度排序': 'Sort by Speed', '按速度排序': 'Sort by Speed',
'按用量排序': 'Sort by Traffic' '按用量排序': 'Sort by Traffic',
'简易模式': 'Simple Mode',
'详细模式': 'Detailed Mode'
}, },
'fr': { 'fr': {
'Bandix 流量监控': 'Moniteur de Trafic Bandix', 'Bandix 流量监控': 'Moniteur de Trafic Bandix',
@@ -316,6 +325,7 @@ const translations = {
'界面语言': 'Langue de l\'interface', '界面语言': 'Langue de l\'interface',
'选择 Bandix 流量监控的显示语言': 'Sélectionner la langue d\'affichage pour le Moniteur de Trafic Bandix', '选择 Bandix 流量监控的显示语言': 'Sélectionner la langue d\'affichage pour le Moniteur de Trafic Bandix',
'设备信息': 'Informations sur l\'appareil', '设备信息': 'Informations sur l\'appareil',
'设备列表': 'Liste des appareils',
'LAN 流量': 'Trafic LAN', 'LAN 流量': 'Trafic LAN',
'WAN 流量': 'Trafic WAN', 'WAN 流量': 'Trafic WAN',
'限速设置': 'Limitation de débit', '限速设置': 'Limitation de débit',
@@ -389,7 +399,9 @@ const translations = {
'升序': 'Croissant', '升序': 'Croissant',
'降序': 'Décroissant', '降序': 'Décroissant',
'按速度排序': 'Trier par vitesse', '按速度排序': 'Trier par vitesse',
'按用量排序': 'Trier par volume' '按用量排序': 'Trier par volume',
'简易模式': 'Mode simple',
'详细模式': 'Mode détaillé'
}, },
'ja': { 'ja': {
'Bandix 流量监控': 'Bandix トラフィックモニター', 'Bandix 流量监控': 'Bandix トラフィックモニター',
@@ -408,6 +420,7 @@ const translations = {
'界面语言': 'インターフェース言語', '界面语言': 'インターフェース言語',
'选择 Bandix 流量监控的显示语言': 'Bandix トラフィックモニターの表示言語を選択', '选择 Bandix 流量监控的显示语言': 'Bandix トラフィックモニターの表示言語を選択',
'设备信息': 'デバイス情報', '设备信息': 'デバイス情報',
'设备列表': 'デバイスリスト',
'LAN 流量': 'LAN トラフィック', 'LAN 流量': 'LAN トラフィック',
'WAN 流量': 'WAN トラフィック', 'WAN 流量': 'WAN トラフィック',
'限速设置': '速度制限', '限速设置': '速度制限',
@@ -481,7 +494,9 @@ const translations = {
'升序': '昇順', '升序': '昇順',
'降序': '降順', '降序': '降順',
'按速度排序': '速度順', '按速度排序': '速度順',
'按用量排序': '使用量順' '按用量排序': '使用量順',
'简易模式': 'シンプルモード',
'详细模式': '詳細モード'
}, },
'ru': { 'ru': {
'Bandix 流量监控': 'Монитор Трафика Bandix', 'Bandix 流量监控': 'Монитор Трафика Bandix',
@@ -500,6 +515,7 @@ const translations = {
'界面语言': 'Язык интерфейса', '界面语言': 'Язык интерфейса',
'选择 Bandix 流量监控的显示语言': 'Выберите язык отображения для Монитора Трафика Bandix', '选择 Bandix 流量监控的显示语言': 'Выберите язык отображения для Монитора Трафика Bandix',
'设备信息': 'Информация об устройстве', '设备信息': 'Информация об устройстве',
'设备列表': 'Список устройств',
'LAN 流量': 'Трафик LAN', 'LAN 流量': 'Трафик LAN',
'WAN 流量': 'Трафик WAN', 'WAN 流量': 'Трафик WAN',
'限速设置': 'Ограничение скорости', '限速设置': 'Ограничение скорости',
@@ -573,7 +589,9 @@ const translations = {
'升序': 'По возрастанию', '升序': 'По возрастанию',
'降序': 'По убыванию', '降序': 'По убыванию',
'按速度排序': 'По скорости', '按速度排序': 'По скорости',
'按用量排序': 'По объёму' '按用量排序': 'По объёму',
'简易模式': 'Простой режим',
'详细模式': 'Подробный режим'
} }
}; };
@@ -781,7 +799,7 @@ return view.extend({
// 添加现代化样式,支持暗黑模式 // 添加现代化样式,支持暗黑模式
var style = E('style', {}, ` var style = E('style', {}, `
.bandix-container { .bandix-container {
padding: 24px; padding: 8px;
background-color: ${darkMode ? '#1E1E1E' : '#f8fafc'}; background-color: ${darkMode ? '#1E1E1E' : '#f8fafc'};
min-height: 100vh; min-height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
@@ -802,6 +820,48 @@ return view.extend({
margin: 0; margin: 0;
} }
.bandix-header-right {
display: flex;
align-items: center;
gap: 12px;
}
.device-mode-group {
display: inline-flex;
border-radius: 4px;
overflow: hidden;
border: 1px solid ${darkMode ? '#252526' : '#d1d5db'};
}
.device-mode-btn {
background-color: ${darkMode ? '#333333' : '#ffffff'};
border: none;
border-right: 1px solid ${darkMode ? '#252526' : '#d1d5db'};
padding: 0 8px;
font-size: 0.75rem;
line-height: 1.4;
color: ${darkMode ? '#94a3b8' : '#6b7280'};
cursor: pointer;
user-select: none;
transition: all 0.15s ease;
white-space: nowrap;
height: 20px;
}
.device-mode-btn:last-child {
border-right: none;
}
.device-mode-btn:hover:not(.active) {
background-color: ${darkMode ? '#3a3a3a' : '#f9fafb'};
color: ${darkMode ? '#e2e8f0' : '#374151'};
}
.device-mode-btn.active {
background-color: #3b82f6;
color: white;
}
.bandix-badge { .bandix-badge {
background-color: ${darkMode ? '#333333' : '#f3f4f6'}; background-color: ${darkMode ? '#333333' : '#f3f4f6'};
border: 1px solid ${darkMode ? '#252526' : '#d1d5db'}; border: 1px solid ${darkMode ? '#252526' : '#d1d5db'};
@@ -833,7 +893,7 @@ return view.extend({
border-radius: 12px; border-radius: 12px;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, ${darkMode ? '0.3' : '0.1'}); box-shadow: 0 1px 3px 0 rgba(0, 0, 0, ${darkMode ? '0.3' : '0.1'});
overflow: hidden; overflow: hidden;
margin-bottom: 24px; margin-bottom: 8px;
border: 1px solid ${darkMode ? '#252526' : '#3333331c'}; border: 1px solid ${darkMode ? '#252526' : '#3333331c'};
} }
@@ -861,7 +921,7 @@ return view.extend({
.bandix-table th { .bandix-table th {
background-color: ${darkMode ? '#333333' : '#f9fafb'}; background-color: ${darkMode ? '#333333' : '#f9fafb'};
padding: 16px 20px; padding: 6px 12px;
text-align: left; text-align: left;
font-weight: 600; font-weight: 600;
color: ${darkMode ? '#e2e8f0' : '#374151'}; color: ${darkMode ? '#e2e8f0' : '#374151'};
@@ -940,7 +1000,7 @@ return view.extend({
} }
.bandix-table td { .bandix-table td {
padding: 16px 20px; padding: 6px 12px;
border: none; border: none;
vertical-align: middle; vertical-align: middle;
word-wrap: break-word; word-wrap: break-word;
@@ -981,7 +1041,7 @@ return view.extend({
.device-info { .device-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 2px;
} }
.device-name { .device-name {
@@ -1026,7 +1086,7 @@ return view.extend({
.traffic-info { .traffic-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 4px;
} }
.traffic-row { .traffic-row {
@@ -1107,7 +1167,7 @@ return view.extend({
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px; gap: 20px;
margin-bottom: 24px; margin-bottom: 8px;
} }
.stats-card { .stats-card {
@@ -1506,6 +1566,21 @@ return view.extend({
// 主要内容卡片 // 主要内容卡片
E('div', { 'class': 'bandix-card' }, [ E('div', { 'class': 'bandix-card' }, [
E('div', { 'class': 'bandix-card-header history-header' }, [
E('div', { 'class': 'bandix-card-title' }, [
getTranslation('设备列表', language)
]),
E('div', { 'class': 'device-mode-group' }, [
E('button', {
'class': 'device-mode-btn' + (localStorage.getItem('bandix_device_mode') !== 'detailed' ? ' active' : ''),
'data-mode': 'simple'
}, getTranslation('简易模式', language)),
E('button', {
'class': 'device-mode-btn' + (localStorage.getItem('bandix_device_mode') === 'detailed' ? ' active' : ''),
'data-mode': 'detailed'
}, getTranslation('详细模式', language))
])
]),
E('div', { 'id': 'traffic-status' }, [ E('div', { 'id': 'traffic-status' }, [
E('table', { 'class': 'bandix-table' }, [ E('table', { 'class': 'bandix-table' }, [
E('thead', {}, [ E('thead', {}, [
@@ -1523,6 +1598,32 @@ return view.extend({
]) ])
]); ]);
// 设备信息模式切换
var deviceModeButtons = view.querySelectorAll('.device-mode-btn');
deviceModeButtons.forEach(function(btn) {
btn.addEventListener('click', function() {
var newMode = this.getAttribute('data-mode');
// 如果已经是当前模式,不做任何操作
if (this.classList.contains('active')) {
return;
}
// 保存到 localStorage
localStorage.setItem('bandix_device_mode', newMode);
// 更新按钮状态
deviceModeButtons.forEach(function(b) {
b.classList.remove('active');
});
this.classList.add('active');
// 刷新设备列表以应用新的显示模式
updateDeviceData();
});
});
// 创建限速设置模态框 // 创建限速设置模态框
var modal = E('div', { 'class': 'modal-overlay', 'id': 'rate-limit-modal' }, [ var modal = E('div', { 'class': 'modal-overlay', 'id': 'rate-limit-modal' }, [
E('div', { 'class': 'modal' }, [ E('div', { 'class': 'modal' }, [
@@ -3028,6 +3129,10 @@ function formatRetentionSeconds(seconds, language) {
showRateLimitModal(device); showRateLimitModal(device);
}); });
// 获取当前显示模式
var deviceMode = localStorage.getItem('bandix_device_mode') || 'simple';
var isDetailedMode = deviceMode === 'detailed';
// 构建设备信息元素 // 构建设备信息元素
var deviceInfoElements = [ var deviceInfoElements = [
E('div', { 'class': 'device-name' }, [ E('div', { 'class': 'device-name' }, [
@@ -3039,28 +3144,31 @@ function formatRetentionSeconds(seconds, language) {
E('div', { 'class': 'device-ip' }, device.ip) E('div', { 'class': 'device-ip' }, device.ip)
]; ];
// 只有当有设备有 IPv6 时才添加 IPv6 行 // 详细模式下显示更多信息
if (hasAnyIPv6) { if (isDetailedMode) {
var lanIPv6 = filterLanIPv6(device.ipv6_addresses); // 只有当有设备有 IPv6 时才添加 IPv6 行
if (lanIPv6.length > 0) { if (hasAnyIPv6) {
var allIPv6 = device.ipv6_addresses ? device.ipv6_addresses.join(', ') : ''; var lanIPv6 = filterLanIPv6(device.ipv6_addresses);
deviceInfoElements.push(E('div', { if (lanIPv6.length > 0) {
'class': 'device-ipv6', var allIPv6 = device.ipv6_addresses ? device.ipv6_addresses.join(', ') : '';
'title': allIPv6 deviceInfoElements.push(E('div', {
}, lanIPv6.join(', '))); 'class': 'device-ipv6',
} else { 'title': allIPv6
deviceInfoElements.push(E('div', { 'class': 'device-ipv6' }, '-')); }, lanIPv6.join(', ')));
} else {
deviceInfoElements.push(E('div', { 'class': 'device-ipv6' }, '-'));
}
} }
}
// 添加 MAC 和最后上线信息 // 添加 MAC 和最后上线信息
deviceInfoElements.push( deviceInfoElements.push(
E('div', { 'class': 'device-mac' }, device.mac), E('div', { 'class': 'device-mac' }, device.mac),
E('div', { 'class': 'device-last-online' }, [ E('div', { 'class': 'device-last-online' }, [
E('span', { 'style': 'color: #6b7280; font-size: 0.75rem;' }, getTranslation('最后上线', language) + ': '), E('span', { 'style': 'color: #6b7280; font-size: 0.75rem;' }, getTranslation('最后上线', language) + ': '),
E('span', { 'style': 'color: #9ca3af; font-size: 0.75rem;' }, formatLastOnlineTime(device.last_online_ts, language)) E('span', { 'style': 'color: #9ca3af; font-size: 0.75rem;' }, formatLastOnlineTime(device.last_online_ts, language))
]) ])
); );
}
var row = E('tr', {}, [ var row = E('tr', {}, [
// 设备信息 // 设备信息

View File

@@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall PKG_NAME:=luci-app-passwall
PKG_VERSION:=25.9.23 PKG_VERSION:=25.11.1
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)

View File

@@ -3,7 +3,26 @@ local appname = "passwall"
local datatypes = api.datatypes local datatypes = api.datatypes
m = Map(appname, "Sing-Box/Xray " .. translate("Shunt Rule")) m = Map(appname, "Sing-Box/Xray " .. translate("Shunt Rule"))
m.redirect = api.url() m.redirect = api.url("rule")
if not arg[1] or not m:get(arg[1]) then
luci.http.redirect(m.redirect)
end
-- Add inline CSS to map description
m.description = (m.description or "") .. "\n" .. [[
<style>
div[id^="cbid.passwall."] .cbi-value-field {
display: flex;
flex-wrap: wrap;
gap: 1em;
}
div[id^="cbid.passwall."] .cbi-checkbox {
display: inline-flex;
align-items: center;
}
</style>
]]
function clean_text(text) function clean_text(text)
local nbsp = string.char(0xC2, 0xA0) -- 不间断空格U+00A0 local nbsp = string.char(0xC2, 0xA0) -- 不间断空格U+00A0
@@ -30,10 +49,14 @@ protocol = s:option(MultiValue, "protocol", translate("Protocol"))
protocol:value("http") protocol:value("http")
protocol:value("tls") protocol:value("tls")
protocol:value("bittorrent") protocol:value("bittorrent")
protocol.widget = "checkbox"
protocol.default = nil
o = s:option(MultiValue, "inbound", translate("Inbound Tag")) o = s:option(MultiValue, "inbound", translate("Inbound Tag"))
o:value("tproxy", translate("Transparent proxy")) o:value("tproxy", translate("Transparent proxy"))
o:value("socks", "Socks") o:value("socks", "Socks")
o.widget = "checkbox"
o.default = nil
network = s:option(ListValue, "network", translate("Network")) network = s:option(ListValue, "network", translate("Network"))
network:value("tcp,udp", "TCP UDP") network:value("tcp,udp", "TCP UDP")

File diff suppressed because it is too large Load Diff

View File

@@ -74,14 +74,14 @@
101.237.40.0/24 101.237.40.0/24
101.240.0.0/14 101.240.0.0/14
101.245.0.0/22 101.245.0.0/22
101.245.12.0/22 101.245.128.0/20
101.245.128.0/22
101.245.136.0/22
101.245.144.0/22 101.245.144.0/22
101.245.152.0/21
101.245.16.0/21 101.245.16.0/21
101.245.160.0/20
101.245.32.0/19 101.245.32.0/19
101.245.64.0/18 101.245.64.0/18
101.245.8.0/23 101.245.8.0/21
101.246.172.0/22 101.246.172.0/22
101.246.176.0/20 101.246.176.0/20
101.247.0.0/18 101.247.0.0/18
@@ -184,7 +184,8 @@
103.116.120.0/23 103.116.120.0/23
103.116.123.0/24 103.116.123.0/24
103.116.138.0/23 103.116.138.0/23
103.116.76.0/22 103.116.76.0/23
103.116.78.0/24
103.116.92.0/22 103.116.92.0/22
103.117.16.0/22 103.117.16.0/22
103.117.220.0/22 103.117.220.0/22
@@ -226,7 +227,9 @@
103.134.136.0/22 103.134.136.0/22
103.135.100.0/24 103.135.100.0/24
103.135.160.0/22 103.135.160.0/22
103.135.192.0/21 103.135.192.0/23
103.135.195.0/24
103.135.196.0/22
103.135.236.0/24 103.135.236.0/24
103.137.60.0/24 103.137.60.0/24
103.138.156.0/23 103.138.156.0/23
@@ -271,10 +274,8 @@
103.151.179.0/24 103.151.179.0/24
103.151.216.0/23 103.151.216.0/23
103.151.228.0/23 103.151.228.0/23
103.151.5.0/24
103.152.170.0/23 103.152.170.0/23
103.152.186.0/23 103.152.186.0/23
103.152.190.0/23
103.152.224.0/24 103.152.224.0/24
103.152.28.0/23 103.152.28.0/23
103.152.56.0/23 103.152.56.0/23
@@ -286,12 +287,10 @@
103.154.30.0/23 103.154.30.0/23
103.154.41.0/24 103.154.41.0/24
103.155.110.0/23 103.155.110.0/23
103.155.120.0/23
103.155.76.0/23 103.155.76.0/23
103.156.174.0/23 103.156.174.0/23
103.156.186.0/23 103.156.186.0/23
103.156.68.0/23 103.156.68.0/23
103.157.138.0/23
103.158.0.0/23 103.158.0.0/23
103.159.124.0/23 103.159.124.0/23
103.16.124.0/22 103.16.124.0/22
@@ -318,7 +317,6 @@
103.177.28.0/23 103.177.28.0/23
103.179.78.0/23 103.179.78.0/23
103.180.108.0/23 103.180.108.0/23
103.181.164.0/23
103.181.234.0/24 103.181.234.0/24
103.183.122.0/23 103.183.122.0/23
103.183.124.0/23 103.183.124.0/23
@@ -352,7 +350,7 @@
103.197.0.0/22 103.197.0.0/22
103.197.228.0/22 103.197.228.0/22
103.198.124.0/22 103.198.124.0/22
103.198.180.0/22 103.198.180.0/23
103.198.216.0/21 103.198.216.0/21
103.198.224.0/20 103.198.224.0/20
103.198.244.0/22 103.198.244.0/22
@@ -377,7 +375,8 @@
103.202.96.0/20 103.202.96.0/20
103.203.140.0/22 103.203.140.0/22
103.203.216.0/22 103.203.216.0/22
103.203.56.0/22 103.203.56.0/23
103.203.59.0/24
103.203.96.0/22 103.203.96.0/22
103.204.72.0/22 103.204.72.0/22
103.205.188.0/22 103.205.188.0/22
@@ -393,7 +392,7 @@
103.21.140.0/22 103.21.140.0/22
103.21.176.0/22 103.21.176.0/22
103.210.160.0/22 103.210.160.0/22
103.210.171.0/24 103.210.170.0/23
103.211.220.0/22 103.211.220.0/22
103.211.44.0/22 103.211.44.0/22
103.212.1.0/24 103.212.1.0/24
@@ -404,9 +403,8 @@
103.212.48.0/23 103.212.48.0/23
103.213.132.0/22 103.213.132.0/22
103.213.160.0/19 103.213.160.0/19
103.213.48.0/23 103.213.48.0/21
103.213.50.0/24 103.213.60.0/22
103.213.62.0/23
103.213.64.0/19 103.213.64.0/19
103.213.96.0/22 103.213.96.0/22
103.214.48.0/22 103.214.48.0/22
@@ -474,7 +472,6 @@
103.232.144.0/22 103.232.144.0/22
103.232.166.0/23 103.232.166.0/23
103.233.128.0/22 103.233.128.0/22
103.233.136.0/23
103.233.138.0/24 103.233.138.0/24
103.233.162.0/23 103.233.162.0/23
103.233.4.0/22 103.233.4.0/22
@@ -503,7 +500,6 @@
103.237.28.0/23 103.237.28.0/23
103.237.8.0/22 103.237.8.0/22
103.238.0.0/21 103.238.0.0/21
103.238.130.0/24
103.238.132.0/22 103.238.132.0/22
103.238.144.0/22 103.238.144.0/22
103.238.16.0/22 103.238.16.0/22
@@ -517,7 +513,6 @@
103.238.98.0/24 103.238.98.0/24
103.239.152.0/22 103.239.152.0/22
103.239.184.0/23 103.239.184.0/23
103.239.187.0/24
103.239.192.0/22 103.239.192.0/22
103.239.204.0/22 103.239.204.0/22
103.239.224.0/22 103.239.224.0/22
@@ -536,12 +531,9 @@
103.242.130.0/24 103.242.130.0/24
103.242.168.0/23 103.242.168.0/23
103.242.172.0/22 103.242.172.0/22
103.242.200.0/24
103.242.202.0/24
103.242.212.0/22 103.242.212.0/22
103.243.136.0/22 103.243.136.0/22
103.243.252.0/22 103.243.252.0/22
103.244.164.0/22
103.244.232.0/22 103.244.232.0/22
103.244.59.0/24 103.244.59.0/24
103.244.64.0/22 103.244.64.0/22
@@ -568,7 +560,7 @@
103.250.32.0/22 103.250.32.0/22
103.251.124.0/22 103.251.124.0/22
103.251.160.0/22 103.251.160.0/22
103.251.204.0/23 103.251.204.0/24
103.251.207.0/24 103.251.207.0/24
103.251.240.0/22 103.251.240.0/22
103.251.32.0/22 103.251.32.0/22
@@ -638,7 +630,7 @@
103.38.232.0/22 103.38.232.0/22
103.38.252.0/23 103.38.252.0/23
103.38.40.0/22 103.38.40.0/22
103.38.76.0/24 103.38.76.0/22
103.38.84.0/22 103.38.84.0/22
103.38.92.0/23 103.38.92.0/23
103.39.200.0/21 103.39.200.0/21
@@ -672,7 +664,9 @@
103.44.240.0/20 103.44.240.0/20
103.44.56.0/22 103.44.56.0/22
103.44.80.0/22 103.44.80.0/22
103.45.128.0/19
103.45.160.0/22 103.45.160.0/22
103.45.168.0/24
103.45.172.0/22 103.45.172.0/22
103.45.176.0/20 103.45.176.0/20
103.45.248.0/22 103.45.248.0/22
@@ -692,7 +686,6 @@
103.49.196.0/24 103.49.196.0/24
103.49.198.0/23 103.49.198.0/23
103.5.192.0/22 103.5.192.0/22
103.50.38.0/24
103.51.62.0/23 103.51.62.0/23
103.52.100.0/22 103.52.100.0/22
103.52.104.0/23 103.52.104.0/23
@@ -709,7 +702,6 @@
103.56.104.0/22 103.56.104.0/22
103.56.152.0/22 103.56.152.0/22
103.56.184.0/22 103.56.184.0/22
103.56.32.0/22
103.56.60.0/22 103.56.60.0/22
103.56.76.0/22 103.56.76.0/22
103.57.12.0/22 103.57.12.0/22
@@ -719,8 +711,8 @@
103.59.124.0/22 103.59.124.0/22
103.59.148.0/22 103.59.148.0/22
103.59.164.0/22 103.59.164.0/22
103.59.168.0/23
103.6.220.0/22 103.6.220.0/22
103.6.228.0/24
103.60.164.0/22 103.60.164.0/22
103.60.228.0/23 103.60.228.0/23
103.60.236.0/22 103.60.236.0/22
@@ -753,6 +745,7 @@
103.72.113.0/24 103.72.113.0/24
103.72.120.0/22 103.72.120.0/22
103.72.172.0/24 103.72.172.0/24
103.72.224.0/24
103.73.116.0/22 103.73.116.0/22
103.73.136.0/21 103.73.136.0/21
103.73.144.0/22 103.73.144.0/22
@@ -774,7 +767,6 @@
103.78.126.0/23 103.78.126.0/23
103.78.228.0/22 103.78.228.0/22
103.78.60.0/22 103.78.60.0/22
103.79.120.0/22
103.79.200.0/22 103.79.200.0/22
103.79.228.0/24 103.79.228.0/24
103.79.24.0/22 103.79.24.0/22
@@ -1026,6 +1018,7 @@
111.222.0.0/16 111.222.0.0/16
111.223.12.0/22 111.223.12.0/22
111.224.0.0/14 111.224.0.0/14
111.228.0.0/18
111.229.0.0/16 111.229.0.0/16
111.230.0.0/15 111.230.0.0/15
111.235.156.0/22 111.235.156.0/22
@@ -1096,11 +1089,7 @@
113.45.128.0/17 113.45.128.0/17
113.45.64.0/19 113.45.64.0/19
113.45.96.0/22 113.45.96.0/22
113.46.0.0/17 113.46.0.0/16
113.46.128.0/18
113.46.192.0/19
113.46.224.0/20
113.46.240.0/21
113.47.0.0/18 113.47.0.0/18
113.47.104.0/22 113.47.104.0/22
113.47.110.0/24 113.47.110.0/24
@@ -1174,6 +1163,7 @@
114.135.0.0/16 114.135.0.0/16
114.138.0.0/15 114.138.0.0/15
114.141.128.0/18 114.141.128.0/18
114.142.136.0/23
114.196.0.0/15 114.196.0.0/15
114.212.0.0/14 114.212.0.0/14
114.216.0.0/13 114.216.0.0/13
@@ -1221,15 +1211,18 @@
115.175.0.0/18 115.175.0.0/18
115.175.104.0/22 115.175.104.0/22
115.175.108.0/23 115.175.108.0/23
115.175.120.0/21 115.175.110.0/24
115.175.112.0/20
115.175.128.0/18 115.175.128.0/18
115.175.192.0/19 115.175.192.0/19
115.175.224.0/20 115.175.224.0/20
115.175.252.0/22
115.175.64.0/19 115.175.64.0/19
115.175.96.0/21
115.182.0.0/15 115.182.0.0/15
115.190.0.0/17 115.190.0.0/16
115.190.128.0/18 115.191.0.0/18
115.190.192.0/20 115.191.64.0/20
115.192.0.0/11 115.192.0.0/11
115.224.0.0/12 115.224.0.0/12
115.24.0.0/14 115.24.0.0/14
@@ -1238,7 +1231,7 @@
115.32.0.0/19 115.32.0.0/19
115.32.32.0/21 115.32.32.0/21
115.32.56.0/21 115.32.56.0/21
115.32.64.0/20 115.32.64.0/19
115.44.0.0/14 115.44.0.0/14
115.48.0.0/12 115.48.0.0/12
115.84.0.0/18 115.84.0.0/18
@@ -1305,6 +1298,7 @@
116.205.0.0/16 116.205.0.0/16
116.207.0.0/16 116.207.0.0/16
116.208.0.0/14 116.208.0.0/14
116.213.45.0/24
116.214.128.0/22 116.214.128.0/22
116.214.132.0/23 116.214.132.0/23
116.214.134.0/24 116.214.134.0/24
@@ -1326,6 +1320,7 @@
116.66.36.0/24 116.66.36.0/24
116.66.48.0/23 116.66.48.0/23
116.66.53.0/24 116.66.53.0/24
116.66.54.0/23
116.66.98.0/24 116.66.98.0/24
116.68.136.0/21 116.68.136.0/21
116.68.176.0/21 116.68.176.0/21
@@ -1385,6 +1380,8 @@
117.72.16.0/23 117.72.16.0/23
117.72.160.0/19 117.72.160.0/19
117.72.192.0/19 117.72.192.0/19
117.72.24.0/21
117.72.240.0/21
117.72.248.0/22 117.72.248.0/22
117.72.255.0/24 117.72.255.0/24
117.72.32.0/19 117.72.32.0/19
@@ -1416,16 +1413,16 @@
118.126.32.0/19 118.126.32.0/19
118.126.64.0/18 118.126.64.0/18
118.132.0.0/14 118.132.0.0/14
118.143.198.0/23
118.143.215.0/24
118.144.0.0/16 118.144.0.0/16
118.145.0.0/19 118.145.0.0/19
118.145.112.0/21
118.145.128.0/19 118.145.128.0/19
118.145.160.0/21 118.145.160.0/21
118.145.176.0/20 118.145.176.0/20
118.145.192.0/18 118.145.192.0/18
118.145.32.0/20 118.145.32.0/20
118.145.64.0/19 118.145.64.0/19
118.145.96.0/20
118.178.0.0/16 118.178.0.0/16
118.180.0.0/14 118.180.0.0/14
118.184.0.0/22 118.184.0.0/22
@@ -1497,8 +1494,8 @@
118.194.240.0/21 118.194.240.0/21
118.194.32.0/19 118.194.32.0/19
118.195.0.0/16 118.195.0.0/16
118.196.0.0/18 118.196.0.0/17
118.196.64.0/19 118.196.128.0/19
118.199.0.0/16 118.199.0.0/16
118.202.0.0/15 118.202.0.0/15
118.212.0.0/15 118.212.0.0/15
@@ -1573,7 +1570,6 @@
119.18.226.0/24 119.18.226.0/24
119.18.234.0/24 119.18.234.0/24
119.18.236.0/23 119.18.236.0/23
119.18.239.0/24
119.2.128.0/17 119.2.128.0/17
119.23.0.0/16 119.23.0.0/16
119.233.128.0/17 119.233.128.0/17
@@ -1609,7 +1605,6 @@
119.37.192.0/21 119.37.192.0/21
119.37.2.0/24 119.37.2.0/24
119.38.0.0/21 119.38.0.0/21
119.38.128.0/18
119.38.192.0/19 119.38.192.0/19
119.39.0.0/16 119.39.0.0/16
119.4.0.0/14 119.4.0.0/14
@@ -1711,7 +1706,10 @@
120.136.20.0/22 120.136.20.0/22
120.192.0.0/10 120.192.0.0/10
120.24.0.0/14 120.24.0.0/14
120.31.0.0/16 120.31.128.0/20
120.31.144.0/24
120.31.66.0/23
120.31.68.0/22
120.32.0.0/12 120.32.0.0/12
120.48.0.0/16 120.48.0.0/16
120.49.0.0/17 120.49.0.0/17
@@ -1927,18 +1925,15 @@
123.4.0.0/14 123.4.0.0/14
123.49.192.0/23 123.49.192.0/23
123.49.194.0/24 123.49.194.0/24
123.49.196.0/24
123.49.229.0/24 123.49.229.0/24
123.49.232.0/24 123.49.232.0/24
123.49.240.0/22 123.49.240.0/21
123.49.244.0/24
123.49.246.0/23
123.52.0.0/14 123.52.0.0/14
123.56.0.0/15 123.56.0.0/15
123.58.0.0/19 123.58.0.0/19
123.58.160.0/20 123.58.160.0/20
123.58.179.0/24 123.58.180.0/24
123.58.180.0/22 123.58.182.0/23
123.58.184.0/24 123.58.184.0/24
123.58.186.0/23 123.58.186.0/23
123.58.188.0/22 123.58.188.0/22
@@ -2006,9 +2001,10 @@
124.196.56.0/23 124.196.56.0/23
124.196.58.0/24 124.196.58.0/24
124.196.66.0/24 124.196.66.0/24
124.196.72.0/24
124.196.77.0/24 124.196.77.0/24
124.196.80.0/22 124.196.80.0/22
124.196.84.0/24 124.196.84.0/23
124.200.0.0/16 124.200.0.0/16
124.202.0.0/16 124.202.0.0/16
124.203.176.0/20 124.203.176.0/20
@@ -2034,7 +2030,6 @@
124.64.0.0/15 124.64.0.0/15
124.66.0.0/17 124.66.0.0/17
124.67.0.0/16 124.67.0.0/16
124.68.252.0/23
124.70.0.0/16 124.70.0.0/16
124.71.0.0/17 124.71.0.0/17
124.71.128.0/18 124.71.128.0/18
@@ -2152,7 +2147,6 @@
140.75.0.0/16 140.75.0.0/16
143.14.49.0/24 143.14.49.0/24
143.20.147.0/24 143.20.147.0/24
143.20.66.0/24
143.64.0.0/16 143.64.0.0/16
144.0.0.0/16 144.0.0.0/16
144.12.0.0/16 144.12.0.0/16
@@ -2168,7 +2162,6 @@
144.7.0.0/17 144.7.0.0/17
145.14.71.0/24 145.14.71.0/24
145.14.72.0/22 145.14.72.0/22
145.14.79.0/24
145.14.81.0/24 145.14.81.0/24
145.14.82.0/24 145.14.82.0/24
145.14.84.0/24 145.14.84.0/24
@@ -2203,7 +2196,6 @@
150.242.80.0/22 150.242.80.0/22
150.242.96.0/22 150.242.96.0/22
150.255.0.0/16 150.255.0.0/16
151.241.174.0/24
152.104.128.0/17 152.104.128.0/17
152.136.0.0/16 152.136.0.0/16
153.0.0.0/16 153.0.0.0/16
@@ -2218,12 +2210,8 @@
154.208.144.0/20 154.208.144.0/20
154.208.160.0/21 154.208.160.0/21
154.208.172.0/23 154.208.172.0/23
154.213.4.0/23
154.218.6.0/23 154.218.6.0/23
154.223.168.0/24 154.223.168.0/24
154.223.179.0/24
154.223.180.0/24
154.38.104.0/22
154.48.237.0/24 154.48.237.0/24
154.72.42.0/24 154.72.42.0/24
154.72.44.0/24 154.72.44.0/24
@@ -2271,7 +2259,6 @@
16.2.142.0/23 16.2.142.0/23
160.19.208.0/22 160.19.208.0/22
160.19.76.0/23 160.19.76.0/23
160.19.82.0/24
160.191.0.0/24 160.191.0.0/24
160.20.18.0/23 160.20.18.0/23
160.202.152.0/22 160.202.152.0/22
@@ -2300,7 +2287,6 @@
163.177.0.0/16 163.177.0.0/16
163.179.0.0/16 163.179.0.0/16
163.204.0.0/16 163.204.0.0/16
163.223.173.0/24
163.223.178.0/23 163.223.178.0/23
163.228.0.0/16 163.228.0.0/16
163.244.246.0/24 163.244.246.0/24
@@ -2311,7 +2297,9 @@
163.53.60.0/22 163.53.60.0/22
163.53.88.0/21 163.53.88.0/21
163.61.202.0/23 163.61.202.0/23
163.61.214.0/24 163.61.214.0/23
165.101.122.0/23
165.101.70.0/23
166.111.0.0/16 166.111.0.0/16
167.139.0.0/16 167.139.0.0/16
167.148.46.0/24 167.148.46.0/24
@@ -2483,7 +2471,6 @@
192.144.128.0/17 192.144.128.0/17
192.163.11.0/24 192.163.11.0/24
192.232.97.0/24 192.232.97.0/24
192.55.46.0/24
193.112.0.0/16 193.112.0.0/16
193.119.10.0/23 193.119.10.0/23
193.119.12.0/23 193.119.12.0/23
@@ -2498,13 +2485,11 @@
193.119.4.0/24 193.119.4.0/24
193.119.6.0/24 193.119.6.0/24
193.119.8.0/24 193.119.8.0/24
194.119.13.0/24 193.233.49.0/24
194.119.15.0/24
194.127.229.0/24 194.127.229.0/24
194.138.202.0/23 194.138.202.0/23
194.138.245.0/24 194.138.245.0/24
194.15.39.0/24 194.15.39.0/24
195.114.203.0/24
198.208.112.0/23 198.208.112.0/23
198.208.17.0/24 198.208.17.0/24
198.208.19.0/24 198.208.19.0/24
@@ -2580,9 +2565,11 @@
202.179.240.0/20 202.179.240.0/20
202.181.120.0/21 202.181.120.0/21
202.181.28.0/24 202.181.28.0/24
202.189.16.0/21 202.189.16.0/20
202.189.3.0/24 202.189.3.0/24
202.189.32.0/20
202.189.4.0/22 202.189.4.0/22
202.189.48.0/22
202.189.8.0/21 202.189.8.0/21
202.192.0.0/12 202.192.0.0/12
202.38.128.0/23 202.38.128.0/23
@@ -2645,8 +2632,6 @@
202.91.224.0/20 202.91.224.0/20
202.91.240.0/21 202.91.240.0/21
202.91.248.0/22 202.91.248.0/22
202.91.36.0/24
202.91.38.0/24
202.93.252.0/22 202.93.252.0/22
202.95.0.0/19 202.95.0.0/19
202.96.0.0/13 202.96.0.0/13
@@ -2689,7 +2674,6 @@
203.12.204.0/23 203.12.204.0/23
203.12.91.0/24 203.12.91.0/24
203.12.93.0/24 203.12.93.0/24
203.12.95.0/24
203.129.10.0/23 203.129.10.0/23
203.129.12.0/22 203.129.12.0/22
203.129.8.0/24 203.129.8.0/24
@@ -2723,9 +2707,12 @@
203.166.188.0/23 203.166.188.0/23
203.166.191.0/24 203.166.191.0/24
203.168.0.0/22 203.168.0.0/22
203.168.129.0/24
203.168.16.0/23 203.168.16.0/23
203.168.18.0/24 203.168.18.0/24
203.168.8.0/24 203.168.5.0/24
203.168.6.0/23
203.168.8.0/21
203.170.58.0/23 203.170.58.0/23
203.174.4.0/24 203.174.4.0/24
203.174.7.0/24 203.174.7.0/24
@@ -2781,7 +2768,6 @@
203.215.236.0/24 203.215.236.0/24
203.223.21.0/24 203.223.21.0/24
203.25.208.0/20 203.25.208.0/20
203.25.48.0/24
203.25.52.0/24 203.25.52.0/24
203.3.112.0/21 203.3.112.0/21
203.3.80.0/21 203.3.80.0/21
@@ -2961,8 +2947,6 @@
203.99.20.0/22 203.99.20.0/22
203.99.24.0/21 203.99.24.0/21
204.13.175.0/24 204.13.175.0/24
207.226.153.0/24
207.226.154.0/24
210.12.0.0/16 210.12.0.0/16
210.13.0.0/17 210.13.0.0/17
210.13.192.0/19 210.13.192.0/19
@@ -3244,12 +3228,17 @@
218.240.128.0/19 218.240.128.0/19
218.240.160.0/21 218.240.160.0/21
218.240.168.0/24 218.240.168.0/24
218.240.176.0/21 218.240.176.0/20
218.240.184.0/24 218.241.112.0/22
218.241.116.0/23
218.241.118.0/24
218.241.121.0/24
218.241.122.0/23
218.241.124.0/22
218.241.128.0/17 218.241.128.0/17
218.241.16.0/21 218.241.16.0/21
218.241.24.0/22 218.241.24.0/22
218.241.96.0/19 218.241.96.0/20
218.242.0.0/16 218.242.0.0/16
218.244.0.0/19 218.244.0.0/19
218.244.128.0/18 218.244.128.0/18
@@ -3322,7 +3311,8 @@
219.234.80.0/20 219.234.80.0/20
219.234.96.0/19 219.234.96.0/19
219.235.0.0/20 219.235.0.0/20
219.235.128.0/19 219.235.128.0/20
219.235.144.0/21
219.235.192.0/23 219.235.192.0/23
219.235.207.0/24 219.235.207.0/24
219.235.224.0/22 219.235.224.0/22
@@ -3362,6 +3352,7 @@
220.152.128.0/17 220.152.128.0/17
220.154.0.0/20 220.154.0.0/20
220.154.128.0/22 220.154.128.0/22
220.154.132.0/23
220.154.140.0/24 220.154.140.0/24
220.154.144.0/24 220.154.144.0/24
220.154.16.0/22 220.154.16.0/22
@@ -3481,7 +3472,6 @@
222.59.252.0/22 222.59.252.0/22
222.64.0.0/11 222.64.0.0/11
223.0.1.0/24 223.0.1.0/24
223.0.10.0/24
223.0.12.0/23 223.0.12.0/23
223.0.126.0/24 223.0.126.0/24
223.0.15.0/24 223.0.15.0/24
@@ -3489,7 +3479,7 @@
223.0.2.0/24 223.0.2.0/24
223.0.30.0/24 223.0.30.0/24
223.0.40.0/23 223.0.40.0/23
223.0.8.0/23 223.0.8.0/22
223.128.0.0/15 223.128.0.0/15
223.144.0.0/12 223.144.0.0/12
223.160.0.0/20 223.160.0.0/20
@@ -3549,6 +3539,7 @@
223.4.0.0/14 223.4.0.0/14
223.64.0.0/10 223.64.0.0/10
223.8.0.0/13 223.8.0.0/13
23.133.188.0/24
23.161.8.0/24 23.161.8.0/24
23.236.111.0/24 23.236.111.0/24
27.0.128.0/24 27.0.128.0/24
@@ -3574,6 +3565,7 @@
27.50.128.0/17 27.50.128.0/17
27.8.0.0/13 27.8.0.0/13
27.98.224.0/19 27.98.224.0/19
27.99.128.0/17
31.56.66.0/24 31.56.66.0/24
31.57.10.0/24 31.57.10.0/24
31.57.248.0/24 31.57.248.0/24
@@ -3626,6 +3618,7 @@
40.126.64.0/18 40.126.64.0/18
40.162.0.0/16 40.162.0.0/16
40.72.0.0/15 40.72.0.0/15
42.0.128.0/17
42.100.0.0/14 42.100.0.0/14
42.120.0.0/15 42.120.0.0/15
42.122.0.0/16 42.122.0.0/16
@@ -3696,7 +3689,6 @@
43.195.0.0/20 43.195.0.0/20
43.196.0.0/16 43.196.0.0/16
43.224.12.0/22 43.224.12.0/22
43.224.23.0/24
43.224.24.0/22 43.224.24.0/22
43.224.240.0/24 43.224.240.0/24
43.224.52.0/23 43.224.52.0/23
@@ -3714,8 +3706,13 @@
43.226.128.0/19 43.226.128.0/19
43.226.164.0/22 43.226.164.0/22
43.226.236.0/22 43.226.236.0/22
43.226.32.0/19 43.226.32.0/20
43.226.64.0/20 43.226.48.0/24
43.226.50.0/23
43.226.52.0/22
43.226.56.0/21
43.226.64.0/21
43.226.76.0/22
43.227.104.0/22 43.227.104.0/22
43.227.140.0/22 43.227.140.0/22
43.227.152.0/21 43.227.152.0/21
@@ -3724,7 +3721,10 @@
43.227.192.0/19 43.227.192.0/19
43.227.252.0/22 43.227.252.0/22
43.227.56.0/21 43.227.56.0/21
43.227.64.0/21 43.227.64.0/22
43.227.69.0/24
43.227.70.0/23
43.227.80.0/20
43.228.0.0/19 43.228.0.0/19
43.228.116.0/22 43.228.116.0/22
43.228.204.0/22 43.228.204.0/22
@@ -3761,7 +3761,7 @@
43.240.200.0/23 43.240.200.0/23
43.240.202.0/24 43.240.202.0/24
43.240.204.0/22 43.240.204.0/22
43.240.220.0/22 43.240.216.0/21
43.240.56.0/21 43.240.56.0/21
43.240.72.0/22 43.240.72.0/22
43.241.16.0/22 43.241.16.0/22
@@ -3863,11 +3863,11 @@
44.30.28.0/24 44.30.28.0/24
44.31.216.0/24 44.31.216.0/24
44.31.28.0/24 44.31.28.0/24
44.31.42.0/24
44.31.81.0/24 44.31.81.0/24
44.31.96.0/24 44.31.96.0/24
44.32.143.0/24 44.32.143.0/24
44.32.188.0/24 44.32.188.0/24
44.32.191.0/24
44.32.192.0/24 44.32.192.0/24
45.112.232.0/22 45.112.232.0/22
45.113.20.0/22 45.113.20.0/22
@@ -3913,6 +3913,7 @@
45.127.129.0/24 45.127.129.0/24
45.127.131.0/24 45.127.131.0/24
45.127.144.0/21 45.127.144.0/21
45.135.149.0/24
45.147.6.0/24 45.147.6.0/24
45.151.47.0/24 45.151.47.0/24
45.157.88.0/24 45.157.88.0/24
@@ -3938,6 +3939,7 @@
45.250.28.0/22 45.250.28.0/22
45.250.32.0/21 45.250.32.0/21
45.250.40.0/22 45.250.40.0/22
45.251.0.0/23
45.251.120.0/22 45.251.120.0/22
45.251.20.0/22 45.251.20.0/22
45.251.8.0/22 45.251.8.0/22
@@ -3965,9 +3967,7 @@
45.254.8.0/23 45.254.8.0/23
45.255.152.0/22 45.255.152.0/22
45.40.192.0/18 45.40.192.0/18
45.59.106.0/24
45.65.20.0/22 45.65.20.0/22
45.87.101.0/24
45.9.11.0/24 45.9.11.0/24
47.112.0.0/13 47.112.0.0/13
47.120.0.0/14 47.120.0.0/14
@@ -3975,11 +3975,11 @@
47.96.0.0/12 47.96.0.0/12
49.112.0.0/13 49.112.0.0/13
49.120.0.0/14 49.120.0.0/14
49.128.203.0/24
49.128.220.0/24 49.128.220.0/24
49.128.223.0/24 49.128.223.0/24
49.140.0.0/15 49.140.0.0/15
49.208.0.0/14 49.208.0.0/14
49.213.62.0/24
49.221.128.0/19 49.221.128.0/19
49.221.26.0/23 49.221.26.0/23
49.221.64.0/19 49.221.64.0/19
@@ -4051,7 +4051,6 @@
58.240.0.0/12 58.240.0.0/12
58.30.0.0/15 58.30.0.0/15
58.32.0.0/11 58.32.0.0/11
58.66.192.0/18
58.67.128.0/17 58.67.128.0/17
58.68.236.0/24 58.68.236.0/24
58.68.247.0/24 58.68.247.0/24
@@ -4114,7 +4113,6 @@
59.152.36.0/24 59.152.36.0/24
59.152.38.0/23 59.152.38.0/23
59.153.116.0/22 59.153.116.0/22
59.153.136.0/22
59.153.164.0/22 59.153.164.0/22
59.153.168.0/24 59.153.168.0/24
59.153.32.0/22 59.153.32.0/22
@@ -4218,8 +4216,7 @@
8.148.0.0/19 8.148.0.0/19
8.148.128.0/17 8.148.128.0/17
8.148.36.0/22 8.148.36.0/22
8.148.40.0/23 8.148.40.0/22
8.148.43.0/24
8.148.64.0/18 8.148.64.0/18
8.149.0.0/16 8.149.0.0/16
8.150.0.0/20 8.150.0.0/20
@@ -4229,13 +4226,12 @@
8.160.0.0/15 8.160.0.0/15
8.162.0.0/18 8.162.0.0/18
8.163.0.0/16 8.163.0.0/16
8.164.0.0/16 8.164.0.0/14
81.173.18.0/23 81.173.18.0/23
81.173.20.0/22 81.173.20.0/22
81.173.28.0/24 81.173.28.0/24
81.68.0.0/14 81.68.0.0/14
82.156.0.0/15 82.156.0.0/15
84.247.114.0/24
84.54.2.0/23 84.54.2.0/23
85.237.205.0/24 85.237.205.0/24
94.191.0.0/17 94.191.0.0/17

View File

@@ -17,9 +17,9 @@
2001:dd8:1::/48 2001:dd8:1::/48
2001:dd9::/48 2001:dd9::/48
2001:df0:ac40::/48 2001:df0:ac40::/48
2001:df1:61c0::/48
2001:df3:3a80::/48 2001:df3:3a80::/48
2001:df3:8b80::/48 2001:df3:8b80::/48
2001:df5:4740::/48
2001:df7:1480::/48 2001:df7:1480::/48
2400:1160::/32 2400:1160::/32
2400:3200::/32 2400:3200::/32
@@ -78,7 +78,7 @@
2400:9380:9009::/48 2400:9380:9009::/48
2400:9380:900a::/48 2400:9380:900a::/48
2400:9380:9020::/47 2400:9380:9020::/47
2400:9380:9040::/47 2400:9380:9040::/48
2400:9380:9050::/47 2400:9380:9050::/47
2400:9380:9060::/48 2400:9380:9060::/48
2400:9380:9071::/48 2400:9380:9071::/48
@@ -104,6 +104,7 @@
2400:a860:1::/48 2400:a860:1::/48
2400:a860:2::/47 2400:a860:2::/47
2400:a860:4::/47 2400:a860:4::/47
2400:a860:6::/48
2400:a980::/29 2400:a980::/29
2400:ae00:1981::/48 2400:ae00:1981::/48
2400:b200::/32 2400:b200::/32
@@ -115,7 +116,6 @@
2400:cb80:e40::/44 2400:cb80:e40::/44
2400:da00::/32 2400:da00::/32
2400:dd00::/28 2400:dd00::/28
2400:ebc0::/32
2400:ee00::/32 2400:ee00::/32
2400:f6e0::/32 2400:f6e0::/32
2400:f720::/32 2400:f720::/32
@@ -131,7 +131,6 @@
2401:20::/40 2401:20::/40
2401:2780::/32 2401:2780::/32
2401:2e00::/32 2401:2e00::/32
2401:33c0::/32
2401:3480:2000::/48 2401:3480:2000::/48
2401:3480:3000::/36 2401:3480:3000::/36
2401:3480::/36 2401:3480::/36
@@ -201,23 +200,38 @@
2401:de00::/32 2401:de00::/32
2401:ec00::/32 2401:ec00::/32
2401:f860:100::/40 2401:f860:100::/40
2401:f860:7::/48
2401:f860:86::/47 2401:f860:86::/47
2401:f860:88::/47 2401:f860:88::/47
2401:f860:90::/46 2401:f860:90::/45
2401:f860:94::/47
2401:f860:a::/47 2401:f860:a::/47
2401:f860:c::/46 2401:f860:c::/46
2401:f860:f100::/40
2401:f860:f6::/48 2401:f860:f6::/48
2401:f860:f9::/48
2401:fa00:40::/43 2401:fa00:40::/43
2402:1440::/32 2402:1440::/32
2402:1460::/32
2402:2000::/32 2402:2000::/32
2402:20e0:f000::/48 2402:20e0:f000::/48
2402:3180:8000::/33 2402:3180:8000::/33
2402:3180::/46 2402:3180::/46
2402:3c00::/32 2402:3c00::/32
2402:3f80:1400::/40 2402:3f80:1400::/40
2402:4440::/32 2402:4440:9000::/39
2402:4440:9200::/48
2402:4440:9400::/48
2402:4440:9600::/48
2402:4440:9800::/48
2402:4440:9810::/48
2402:4440:9900::/48
2402:4440:9a00::/48
2402:4440:9b00::/48
2402:4440:9c00::/48
2402:4440:9d00::/48
2402:4440:9e00::/48
2402:4440:a000::/39
2402:4440:a800::/46
2402:4440:a810::/46
2402:4b80::/32 2402:4b80::/32
2402:4e00::/32 2402:4e00::/32
2402:5e40::/32 2402:5e40::/32
@@ -228,9 +242,7 @@
2402:6fc0::/48 2402:6fc0::/48
2402:7040::/32 2402:7040::/32
2402:7d80:240::/47 2402:7d80:240::/47
2402:7d80:6666::/48
2402:7d80:8888::/48 2402:7d80:8888::/48
2402:7d80:9999::/48
2402:7d80::/48 2402:7d80::/48
2402:840:d000::/46 2402:840:d000::/46
2402:840:e000::/46 2402:840:e000::/46
@@ -296,6 +308,7 @@
2403:a140:10::/48 2403:a140:10::/48
2403:a200::/32 2403:a200::/32
2403:ac00::/32 2403:ac00::/32
2403:ad80:101c::/48
2403:ad80:8008::/48 2403:ad80:8008::/48
2403:b400::/32 2403:b400::/32
2403:c80::/32 2403:c80::/32
@@ -393,7 +406,6 @@
2406:52c0::/32 2406:52c0::/32
2406:5340:6666::/48 2406:5340:6666::/48
2406:5340:8888::/48 2406:5340:8888::/48
2406:5ac0::/32
2406:6100::/32 2406:6100::/32
2406:840:8100::/40 2406:840:8100::/40
2406:840:9000::/44 2406:840:9000::/44
@@ -402,8 +414,7 @@
2406:840:9961::/48 2406:840:9961::/48
2406:840:9962::/47 2406:840:9962::/47
2406:840:996c::/48 2406:840:996c::/48
2406:840:a7fe::/48 2406:840:c200::/40
2406:840:a800::/37
2406:840:e080::/44 2406:840:e080::/44
2406:840:e0cf::/48 2406:840:e0cf::/48
2406:840:e0e0::/46 2406:840:e0e0::/46
@@ -415,11 +426,12 @@
2406:840:e230::/44 2406:840:e230::/44
2406:840:e260::/48 2406:840:e260::/48
2406:840:e2cf::/48 2406:840:e2cf::/48
2406:840:e600::/45 2406:840:e600::/46
2406:840:e608::/46 2406:840:e604::/47
2406:840:e621::/48 2406:840:e606::/48
2406:840:e60d::/48
2406:840:e620::/47
2406:840:e666::/47 2406:840:e666::/47
2406:840:e720::/44
2406:840:e770::/48 2406:840:e770::/48
2406:840:e777::/48 2406:840:e777::/48
2406:840:e80f::/48 2406:840:e80f::/48
@@ -447,15 +459,16 @@
2406:840:fc80::/42 2406:840:fc80::/42
2406:840:fcc0::/44 2406:840:fcc0::/44
2406:840:fcd0::/48 2406:840:fcd0::/48
2406:840:fcf0::/46
2406:840:fcf4::/47
2406:840:fd40::/42 2406:840:fd40::/42
2406:840:fd80::/44 2406:840:fd80::/44
2406:840:fd9f::/48 2406:840:fd9f::/48
2406:840:fda0::/43 2406:840:fda0::/43
2406:840:fdc0::/44 2406:840:fdc0::/44
2406:840:fdd1::/48 2406:840:fdd1::/48
2406:840:fde5::/48
2406:840:fde6::/47
2406:840:fe27::/48 2406:840:fe27::/48
2406:840:fe60::/44
2406:840:fe90::/46 2406:840:fe90::/46
2406:840:fe94::/48 2406:840:fe94::/48
2406:840:fe96::/47 2406:840:fe96::/47
@@ -473,11 +486,12 @@
2406:840:fecc::/47 2406:840:fecc::/47
2406:840:fecf::/48 2406:840:fecf::/48
2406:840:fed1::/48 2406:840:fed1::/48
2406:840:fed6::/48
2406:840:fed8::/48 2406:840:fed8::/48
2406:840:fedb::/48 2406:840:fedb::/48
2406:840:fedc::/47 2406:840:fedc::/48
2406:840:fedf::/48 2406:840:fedf::/48
2406:840:fef0::/48 2406:840:fef0::/47
2406:840:fef3::/48 2406:840:fef3::/48
2406:840:fef4::/48 2406:840:fef4::/48
2406:840:fef6::/47 2406:840:fef6::/47
@@ -720,7 +734,6 @@
2408:8406:cc0::/42 2408:8406:cc0::/42
2408:8406:d00::/41 2408:8406:d00::/41
2408:8406:d80::/42 2408:8406:d80::/42
2408:8407:500::/43
2408:8409:100::/41 2408:8409:100::/41
2408:8409:1800::/40 2408:8409:1800::/40
2408:8409:180::/42 2408:8409:180::/42
@@ -916,7 +929,7 @@
2408:842a::/31 2408:842a::/31
2408:842c::/32 2408:842c::/32
2408:842e::/32 2408:842e::/32
2408:8431::/32 2408:8430::/31
2408:8434::/30 2408:8434::/30
2408:8438::/31 2408:8438::/31
2408:843c::/30 2408:843c::/30
@@ -1173,8 +1186,10 @@
240a:420a::/31 240a:420a::/31
240a:4224:9000::/44 240a:4224:9000::/44
240a:4224:a000::/44 240a:4224:a000::/44
240a:4224:c000::/44
240a:4224:d000::/44 240a:4224:d000::/44
240a:4224:e000::/44 240a:4224:e000::/44
240a:4225:1000::/44
240a:4230::/31 240a:4230::/31
240a:4242::/31 240a:4242::/31
240a:4280::/26 240a:4280::/26
@@ -1199,14 +1214,15 @@
240e::/20 240e::/20
2602:2e0:ff::/48 2602:2e0:ff::/48
2602:f7ee:ee::/48 2602:f7ee:ee::/48
2602:f92a:a471::/48
2602:f92a:a473::/48
2602:f92a:a478::/48 2602:f92a:a478::/48
2602:f92a:d1ff::/48
2602:f92a:dead::/48 2602:f92a:dead::/48
2602:f92a:e100::/44 2602:f92a:e100::/44
2602:f93b:400::/38 2602:f93b:400::/38
2602:f9ba:10c::/48 2602:f9ba:10c::/48
2602:f9ba:a8::/48 2602:f9ba:a8::/48
2602:feda:182::/47 2602:fab0:11::/48
2602:feda:1bf::/48 2602:feda:1bf::/48
2602:feda:1d1::/48 2602:feda:1d1::/48
2602:feda:1df::/48 2602:feda:1df::/48
@@ -1230,8 +1246,6 @@
2804:1e48:9002::/48 2804:1e48:9002::/48
2a01:f100:100::/48 2a01:f100:100::/48
2a01:f100:1f8::/48 2a01:f100:1f8::/48
2a01:ffc7:100::/40
2a03:5840:126::/48
2a04:3e00:1002::/48 2a04:3e00:1002::/48
2a04:f580:8010::/47 2a04:f580:8010::/47
2a04:f580:8090::/48 2a04:f580:8090::/48
@@ -1246,7 +1260,6 @@
2a04:f580:9060::/48 2a04:f580:9060::/48
2a04:f580:9070::/48 2a04:f580:9070::/48
2a04:f580:9080::/48 2a04:f580:9080::/48
2a04:f580:9090::/48
2a04:f580:9210::/48 2a04:f580:9210::/48
2a04:f580:9212::/47 2a04:f580:9212::/47
2a04:f580:9220::/48 2a04:f580:9220::/48
@@ -1264,18 +1277,15 @@
2a06:3603::/32 2a06:3603::/32
2a06:3604::/30 2a06:3604::/30
2a06:9f81:4600::/43 2a06:9f81:4600::/43
2a06:9f81:4640::/44 2a06:9f81:4620::/44
2a06:9f81:4660::/44 2a06:9f81:4640::/43
2a06:a005:1c40::/44 2a06:a005:1c40::/44
2a06:a005:260::/43 2a06:a005:260::/43
2a06:a005:280::/43 2a06:a005:280::/43
2a06:a005:2a0::/44 2a06:a005:2a0::/44
2a06:a005:8d0::/44 2a06:a005:8d0::/44
2a06:a005:9e0::/44
2a06:a005:a13::/48 2a06:a005:a13::/48
2a06:a005:e9a::/48
2a09:54c6:3000::/36 2a09:54c6:3000::/36
2a09:54c6:6000::/35
2a09:54c6:b000::/36 2a09:54c6:b000::/36
2a09:54c6:c000::/36 2a09:54c6:c000::/36
2a09:54c6:e000::/36 2a09:54c6:e000::/36
@@ -1292,9 +1302,10 @@
2a0b:2542::/48 2a0b:2542::/48
2a0b:4b81:1001::/48 2a0b:4b81:1001::/48
2a0b:4e07:b8::/47 2a0b:4e07:b8::/47
2a0c:9a40:84e0::/48 2a0c:9a40:8fc1::/48
2a0c:9a40:8fc2::/47
2a0c:9a40:8fc4::/48
2a0c:b641:571::/48 2a0c:b641:571::/48
2a0c:b641:d40::/44
2a0e:97c0:5ef::/48 2a0e:97c0:5ef::/48
2a0e:97c0:83f::/48 2a0e:97c0:83f::/48
2a0e:9b00::/29 2a0e:9b00::/29
@@ -1302,7 +1313,7 @@
2a0e:aa06:440::/48 2a0e:aa06:440::/48
2a0e:aa06:490::/44 2a0e:aa06:490::/44
2a0e:aa06:4e0::/44 2a0e:aa06:4e0::/44
2a0e:aa06:500::/44 2a0e:aa06:501::/48
2a0e:aa06:520::/48 2a0e:aa06:520::/48
2a0e:aa06:525::/48 2a0e:aa06:525::/48
2a0e:aa06:541::/48 2a0e:aa06:541::/48
@@ -1317,14 +1328,12 @@
2a0e:aa07:e0e0::/44 2a0e:aa07:e0e0::/44
2a0e:aa07:e151::/48 2a0e:aa07:e151::/48
2a0e:aa07:e155::/48 2a0e:aa07:e155::/48
2a0e:aa07:e15f::/48
2a0e:aa07:e160::/47 2a0e:aa07:e160::/47
2a0e:aa07:e162::/48 2a0e:aa07:e162::/48
2a0e:aa07:e16a::/48 2a0e:aa07:e16a::/48
2a0e:aa07:e1a0::/44 2a0e:aa07:e1a0::/44
2a0e:aa07:e1e1::/48 2a0e:aa07:e1e0::/44
2a0e:aa07:e1e2::/47
2a0e:aa07:e1e4::/47
2a0e:aa07:e1e6::/48
2a0e:aa07:e200::/44 2a0e:aa07:e200::/44
2a0e:aa07:e210::/48 2a0e:aa07:e210::/48
2a0e:aa07:e21c::/47 2a0e:aa07:e21c::/47
@@ -1342,7 +1351,15 @@
2a0e:b107:c10::/48 2a0e:b107:c10::/48
2a0e:b107:da0::/44 2a0e:b107:da0::/44
2a0e:b107:dce::/48 2a0e:b107:dce::/48
2a0f:1cc5:f00::/47
2a0f:1cc5:f02::/48
2a0f:1cc5:f05::/48
2a0f:5707:ac00::/47 2a0f:5707:ac00::/47
2a0f:6284:4b00::/40
2a0f:6284:4c30::/48
2a0f:6284:4c40::/43
2a0f:6284:4c60::/44
2a0f:6284:4c80::/43
2a0f:7803:e300::/40 2a0f:7803:e300::/40
2a0f:7803:f5d0::/44 2a0f:7803:f5d0::/44
2a0f:7803:f5e0::/43 2a0f:7803:f5e0::/43
@@ -1356,39 +1373,33 @@
2a0f:7803:fa24::/46 2a0f:7803:fa24::/46
2a0f:7803:faf3::/48 2a0f:7803:faf3::/48
2a0f:7803:fe41::/48 2a0f:7803:fe41::/48
2a0f:7803:fe44::/46 2a0f:7803:fe45::/48
2a0f:7803:fe4e::/48
2a0f:7803:fe81::/48 2a0f:7803:fe81::/48
2a0f:7803:fe82::/48 2a0f:7803:fe82::/48
2a0f:7804:f650::/44 2a0f:7804:f650::/44
2a0f:7804:f9f0::/44 2a0f:7804:f9f0::/44
2a0f:7807::/32
2a0f:7d07::/32 2a0f:7d07::/32
2a0f:85c1:ba5::/48 2a0f:85c1:ba5::/48
2a0f:85c1:bfe::/48
2a0f:85c1:ca0::/44 2a0f:85c1:ca0::/44
2a0f:85c1:ce1::/48 2a0f:85c1:ce1::/48
2a0f:85c1:cf1::/48 2a0f:85c1:cf1::/48
2a0f:85c1:d90::/48
2a0f:9400:6110::/48 2a0f:9400:6110::/48
2a0f:9400:7700::/48 2a0f:9400:7700::/48
2a0f:ac00::/29 2a0f:ac00::/29
2a0f:ea47:fc1d::/48
2a10:2f00:15a::/48 2a10:2f00:15a::/48
2a10:67c2:2::/48
2a10:ccc0:d00::/46 2a10:ccc0:d00::/46
2a10:ccc0:d0a::/47 2a10:ccc0:d0a::/47
2a10:ccc0:d0c::/47 2a10:ccc0:d0c::/47
2a10:ccc6:66c4::/48 2a10:ccc6:66c8::/48
2a10:ccc6:66c6::/48 2a10:ccc6:66cc::/46
2a10:ccc6:66c8::/47
2a10:ccc6:66ca::/48
2a10:ccc6:66cc::/47
2a12:f8c3::/36 2a12:f8c3::/36
2a13:1800:10::/48 2a13:1800:10::/48
2a13:1800:300::/44 2a13:1800:300::/44
2a13:1800:80::/44 2a13:1800:80::/44
2a13:1800::/48 2a13:1800::/48
2a13:1801:180::/43 2a13:1801:180::/43
2a13:a5c3:ff10::/44
2a13:a5c3:ff21::/48 2a13:a5c3:ff21::/48
2a13:a5c3:ff50::/44 2a13:a5c3:ff50::/44
2a13:a5c7:1800::/40 2a13:a5c7:1800::/40
@@ -1397,10 +1408,8 @@
2a13:a5c7:2121::/48 2a13:a5c7:2121::/48
2a13:a5c7:2301::/48 2a13:a5c7:2301::/48
2a13:a5c7:2302::/48 2a13:a5c7:2302::/48
2a13:a5c7:23c0::/42 2a13:a5c7:23c0::/48
2a13:a5c7:2600::/40
2a13:a5c7:2801::/48 2a13:a5c7:2801::/48
2a13:a5c7:2803::/48
2a13:a5c7:3108::/48 2a13:a5c7:3108::/48
2a13:a5c7:31a0::/43 2a13:a5c7:31a0::/43
2a13:a5c7:3301::/48 2a13:a5c7:3301::/48
@@ -1411,7 +1420,7 @@
2a14:67c1:20::/44 2a14:67c1:20::/44
2a14:67c1:702::/47 2a14:67c1:702::/47
2a14:67c1:704::/48 2a14:67c1:704::/48
2a14:67c1:70::/47 2a14:67c1:70::/48
2a14:67c1:73::/48 2a14:67c1:73::/48
2a14:67c1:74::/48 2a14:67c1:74::/48
2a14:67c1:a010::/44 2a14:67c1:a010::/44
@@ -1421,14 +1430,10 @@
2a14:67c1:a02a::/48 2a14:67c1:a02a::/48
2a14:67c1:a02f::/48 2a14:67c1:a02f::/48
2a14:67c1:a040::/47 2a14:67c1:a040::/47
2a14:67c1:a061::/48
2a14:67c1:a064::/48 2a14:67c1:a064::/48
2a14:67c1:a090::/45
2a14:67c1:a099::/48
2a14:67c1:a100::/43 2a14:67c1:a100::/43
2a14:67c1:a125::/48 2a14:67c1:a125::/48
2a14:67c1:a144::/48 2a14:67c1:a144::/48
2a14:67c1:a150::/44
2a14:67c1:b000::/48 2a14:67c1:b000::/48
2a14:67c1:b065::/48 2a14:67c1:b065::/48
2a14:67c1:b066::/48 2a14:67c1:b066::/48
@@ -1438,80 +1443,72 @@
2a14:67c1:b107::/48 2a14:67c1:b107::/48
2a14:67c1:b130::/46 2a14:67c1:b130::/46
2a14:67c1:b134::/47 2a14:67c1:b134::/47
2a14:67c1:b136::/48
2a14:67c1:b140::/48 2a14:67c1:b140::/48
2a14:67c1:b4a1::/48 2a14:67c1:b4a1::/48
2a14:67c1:b4a2::/48 2a14:67c1:b4a2::/48
2a14:67c1:b4a8::/47
2a14:67c1:b4aa::/48
2a14:67c1:b4c0::/45 2a14:67c1:b4c0::/45
2a14:67c1:b4d0::/44
2a14:67c1:b4e0::/43 2a14:67c1:b4e0::/43
2a14:67c1:b500::/47 2a14:67c1:b500::/47
2a14:67c1:b549::/48 2a14:67c1:b549::/48
2a14:67c1:b561::/48 2a14:67c1:b561::/48
2a14:67c1:b563::/48 2a14:67c1:b563::/48
2a14:67c1:b566::/48 2a14:67c1:b566::/48
2a14:67c1:b581::/48 2a14:67c1:b578::/48
2a14:67c1:b582::/48 2a14:67c1:b582::/48
2a14:67c1:b586::/48
2a14:67c1:b588::/47 2a14:67c1:b588::/47
2a14:67c1:b590::/47 2a14:67c1:b590::/48
2a14:67c1:b599::/48 2a14:67c1:b599::/48
2a14:67c5:1900::/40 2a14:67c1:b5a1::/48
2a14:67c1:c300::/40
2a14:7580:740::/44 2a14:7580:740::/44
2a14:7580:750::/47 2a14:7580:750::/47
2a14:7580:9200::/40 2a14:7580:9208::/48
2a14:7580:9220::/44
2a14:7580:9400::/39 2a14:7580:9400::/39
2a14:7580:9600::/46
2a14:7580:960c::/48
2a14:7580:d000::/37 2a14:7580:d000::/37
2a14:7580:d800::/39 2a14:7580:d800::/39
2a14:7580:da00::/40 2a14:7580:da00::/40
2a14:7580:e200::/40 2a14:7580:e200::/40
2a14:7580:fa01::/48
2a14:7580:fe00::/40 2a14:7580:fe00::/40
2a14:7580:fff4::/48 2a14:7580:fff4::/48
2a14:7580:fff7::/48 2a14:7580:fff7::/48
2a14:7580:fffa::/48 2a14:7580:fffa::/48
2a14:7581:30b5::/48
2a14:7581:3100::/40 2a14:7581:3100::/40
2a14:7581:3400::/47 2a14:7581:3401::/48
2a14:7581:9010::/44 2a14:7581:b12::/47
2a14:7581:b10::/48 2a14:7581:b14::/47
2a14:7581:b12::/48
2a14:7581:b15::/48
2a14:7581:b20::/46 2a14:7581:b20::/46
2a14:7581:b32::/47 2a14:7581:b40::/48
2a14:7581:b44::/48 2a14:7581:b44::/48
2a14:7581:b46::/47
2a14:7581:b48::/48
2a14:7581:b4a::/48
2a14:7581:b60::/48 2a14:7581:b60::/48
2a14:7581:b62::/47
2a14:7581:b64::/46
2a14:7581:b6c::/47
2a14:7581:b6e::/48
2a14:7581:b82::/47
2a14:7581:ba0::/48 2a14:7581:ba0::/48
2a14:7581:ba2::/47
2a14:7581:ba4::/48
2a14:7581:bbb::/48 2a14:7581:bbb::/48
2a14:7581:bc2::/48
2a14:7581:bcd::/48 2a14:7581:bcd::/48
2a14:7581:bff::/48 2a14:7581:bff::/48
2a14:7581:ffb::/48 2a14:7581:ffb::/48
2a14:7581:ffd::/48
2a14:7583:f201::/48 2a14:7583:f201::/48
2a14:7583:f203::/48 2a14:7583:f203::/48
2a14:7583:f300::/46 2a14:7583:f300::/46
2a14:7583:f304::/48 2a14:7583:f304::/47
2a14:7583:f460::/44
2a14:7583:f4f1::/48
2a14:7583:f4fe::/48 2a14:7583:f4fe::/48
2a14:7583:f500::/48 2a14:7583:f500::/48
2a14:7583:f701::/48 2a14:7583:f701::/48
2a14:7583:f702::/47 2a14:7583:f702::/47
2a14:7583:f704::/47 2a14:7583:f704::/46
2a14:7583:f707::/48 2a14:7583:f708::/47
2a14:7583:f708::/48 2a14:7583:f70a::/48
2a14:7583:f743::/48 2a14:7583:f743::/48
2a14:7583:f764::/48 2a14:7583:f764::/48
2a14:7584::/36 2a14:7584::/36
2a14:7c0:4a01::/48 2a14:7c0:4a01::/48
2a14:7c0:5103::/48
2c0f:f7a8:8011::/48 2c0f:f7a8:8011::/48
2c0f:f7a8:8050::/48 2c0f:f7a8:8050::/48
2c0f:f7a8:805f::/48 2c0f:f7a8:805f::/48

View File

@@ -117,6 +117,7 @@
91vps.club 91vps.club
92ccav.com 92ccav.com
991.com 991.com
996.icu
99btgc01.com 99btgc01.com
99cn.info 99cn.info
9bis.com 9bis.com
@@ -303,6 +304,7 @@ apetube.com
api-secure.recaptcha.net api-secure.recaptcha.net
api-verify.recaptcha.net api-verify.recaptcha.net
api.ai api.ai
api.palworldgame.com
api.pureapk.com api.pureapk.com
api.recaptcha.net api.recaptcha.net
api.steampowered.com api.steampowered.com
@@ -360,6 +362,7 @@ asia-gaming.com
asiaharvest.org asiaharvest.org
asianage.com asianage.com
asianews.it asianews.it
asianfanfics.com
asiansexdiary.com asiansexdiary.com
asiaone.com asiaone.com
asiatgp.com asiatgp.com
@@ -748,7 +751,6 @@ btc98.com
btcbank.bank btcbank.bank
btctrade.im btctrade.im
btdig.com btdig.com
btdigg.org
btguard.com btguard.com
btku.me btku.me
btku.org btku.org
@@ -1166,6 +1168,7 @@ csuchen.de
csw.org.uk csw.org.uk
ct.org.tw ct.org.tw
ctao.org ctao.org
ctinets.com
ctinews.com ctinews.com
ctitv.com.tw ctitv.com.tw
ctowc.org ctowc.org
@@ -1341,6 +1344,7 @@ dnvod.tv
doc.new doc.new
docker.com docker.com
docker.io docker.io
dockerstatus.com
docs.deno.com docs.deno.com
docs.new docs.new
doctorvoice.org doctorvoice.org
@@ -1797,6 +1801,8 @@ freedominfonetweb.wordpress.com
freedomsherald.org freedomsherald.org
freeforums.org freeforums.org
freegao.com freegao.com
freegpt.es
freegpt.tech
freehongkong.org freehongkong.org
freeilhamtohti.org freeilhamtohti.org
freekazakhs.org freekazakhs.org
@@ -2691,6 +2697,7 @@ internet.org
internetdefenseleague.org internetdefenseleague.org
internetfreedom.org internetfreedom.org
internetpopculture.com internetpopculture.com
interseclab.org
inthenameofconfuciusmovie.com inthenameofconfuciusmovie.com
investigating.wordpress.com investigating.wordpress.com
invidio.us invidio.us
@@ -3656,6 +3663,7 @@ occupytiananmen.com
ocreampies.com ocreampies.com
ocry.com ocry.com
october-review.org october-review.org
octocaptcha.com
oculus.com oculus.com
oculuscdn.com oculuscdn.com
odysee.com odysee.com
@@ -4463,6 +4471,7 @@ solana.com
solarsystem.nasa.gov solarsystem.nasa.gov
solidaritetibet.org solidaritetibet.org
solidfiles.com solidfiles.com
solscan.io
solv.finance solv.finance
somee.com somee.com
songjianjun.com songjianjun.com
@@ -4683,8 +4692,10 @@ tanc.org
tangren.us tangren.us
tanks.gg tanks.gg
taoism.net taoism.net
tap.io
tapanwap.com tapanwap.com
tapatalk.com tapatalk.com
taptap.io
tardigrade.io tardigrade.io
tarr.uspto.gov tarr.uspto.gov
taup.net taup.net
@@ -4994,6 +5005,7 @@ trt.net.tr
trtc.com.tw trtc.com.tw
truebuddha-md.org truebuddha-md.org
trulyergonomic.com trulyergonomic.com
trustwallet.com
truthsocial.com truthsocial.com
truveo.com truveo.com
tryheart.jp tryheart.jp
@@ -5301,6 +5313,7 @@ vijayatemple.org
vilanet.me vilanet.me
vilavpn.com vilavpn.com
vimeo.com vimeo.com
vimeocdn.com
vimperator.org vimperator.org
vincnd.com vincnd.com
vine.co vine.co
@@ -5449,6 +5462,7 @@ webpkgcache.com
webrtc.org webrtc.org
webrush.net webrush.net
webs-tv.net webs-tv.net
websdr.org
website.informer.com website.informer.com
website.new website.new
websitepulse.com websitepulse.com
@@ -5519,6 +5533,7 @@ wikilivres.info
wikimapia.org wikimapia.org
wikimedia.org wikimedia.org
wikinews.org wikinews.org
wikipedia.com
wikipedia.org wikipedia.org
wikisource.org wikisource.org
wikiversity.org wikiversity.org
@@ -5693,6 +5708,7 @@ xn--ngstr-lra8j.com
xn--noss43i.com xn--noss43i.com
xn--oiq.cc xn--oiq.cc
xn--p8j9a0d9c9a.xn--q9jyb4c xn--p8j9a0d9c9a.xn--q9jyb4c
xn--u2u927b.com
xnpool.com xnpool.com
xnxx.com xnxx.com
xpdo.net xpdo.net
@@ -5818,6 +5834,7 @@ z-lib.gd
z-lib.gl z-lib.gl
z-lib.io z-lib.io
z-lib.org z-lib.org
z-library.ec
z-library.sk z-library.sk
zacebook.com zacebook.com
zalmos.com zalmos.com

View File

@@ -7,6 +7,8 @@ PKG_VERSION:=190
PKG_RELEASE:=3 PKG_RELEASE:=3
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
@@ -39,9 +41,9 @@ PKG_CONFIG_DEPENDS:= \
LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Tuic/ShadowTLS/Hysteria/Socks5/Tun LuCI interface LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Tuic/ShadowTLS/Hysteria/Socks5/Tun LuCI interface
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
LUCI_DEPENDS:= \ LUCI_DEPENDS:= \
+coreutils +coreutils-base64 +dns2tcp +dnsmasq-full +@PACKAGE_dnsmasq_full_ipset +ipset +kmod-ipt-nat +jq \ +coreutils +coreutils-base64 +dns2tcp +dnsmasq-full \
+ip-full +iptables +iptables-mod-tproxy +lua +lua-neturl +libuci-lua +microsocks \ +jq +ip-full +lua +lua-neturl +libuci-lua +microsocks \
+tcping +resolveip +shadowsocksr-libev-ssr-check +curl +nping \ +tcping +resolveip +curl +nping \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:curl \ +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \ +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \ +PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \
@@ -68,14 +70,40 @@ LUCI_DEPENDS:= \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Xray_Plugin:xray-plugin \ +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Xray_Plugin:xray-plugin \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-local \ +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-redir \ +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server:shadowsocksr-libev-ssr-server \ +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server:shadowsocksr-libev-ssr-check \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan +PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan
define Package/$(PKG_NAME)/config define Package/$(PKG_NAME)/config
select PACKAGE_luci-lib-ipkg if PACKAGE_$(PKG_NAME)
select PACKAGE_luci-lua-runtime if PACKAGE_$(PKG_NAME) select PACKAGE_luci-lua-runtime if PACKAGE_$(PKG_NAME)
choice
prompt "Transparent Proxy Backend"
default PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy if ! PACKAGE_firewall4
default PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy if PACKAGE_firewall4
config PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy
bool "Iptables Transparent Proxy"
select PACKAGE_dnsmasq_full_ipset
select PACKAGE_ipset
select PACKAGE_iptables
select PACKAGE_iptables-zz-legacy
select PACKAGE_iptables-mod-conntrack-extra
select PACKAGE_iptables-mod-iprange
select PACKAGE_iptables-mod-socket
select PACKAGE_iptables-mod-tproxy
select PACKAGE_kmod-ipt-nat
config PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy
bool "Nftables Transparent Proxy"
select PACKAGE_dnsmasq_full_nftset
select PACKAGE_nftables
select PACKAGE_kmod-nft-socket
select PACKAGE_kmod-nft-tproxy
select PACKAGE_kmod-nft-nat
endchoice
choice choice
prompt "Shadowsocks Client Selection" prompt "Shadowsocks Client Selection"
default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client if aarch64||arm||i386||mips||mipsel||x86_64 default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client if aarch64||arm||i386||mips||mipsel||x86_64

View File

@@ -28,8 +28,9 @@ function index()
entry({"admin", "services", "shadowsocksr", "reset"}, call("act_reset")) entry({"admin", "services", "shadowsocksr", "reset"}, call("act_reset"))
entry({"admin", "services", "shadowsocksr", "restart"}, call("act_restart")) entry({"admin", "services", "shadowsocksr", "restart"}, call("act_restart"))
entry({"admin", "services", "shadowsocksr", "delete"}, call("act_delete")) entry({"admin", "services", "shadowsocksr", "delete"}, call("act_delete"))
--[[Backup]] --[[Backup]]
entry({"admin", "services", "shadowsocksr", "backup"}, call("create_backup")).leaf = true entry({"admin", "services", "shadowsocksr", "backup"}, call("create_backup")).leaf = true
end end
function subscribe() function subscribe()
@@ -46,40 +47,74 @@ function act_status()
end end
function act_ping() function act_ping()
local e = {} local e = {}
local domain = luci.http.formvalue("domain") local domain = luci.http.formvalue("domain")
local port = luci.http.formvalue("port") local port = tonumber(luci.http.formvalue("port") or 0)
local transport = luci.http.formvalue("transport") local transport = luci.http.formvalue("transport")
local wsPath = luci.http.formvalue("wsPath") local wsPath = luci.http.formvalue("wsPath") or ""
local tls = luci.http.formvalue("tls") local tls = luci.http.formvalue("tls")
e.index = luci.http.formvalue("index") e.index = luci.http.formvalue("index")
local iret = luci.sys.call("ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null")
if transport == "ws" then local use_nft = luci.sys.call("command -v nft >/dev/null") == 0
local prefix = tls=='1' and "https://" or "http://" local iret = false
local address = prefix..domain..':'..port..wsPath
local result = luci.sys.exec("curl --http1.1 -m 2 -ksN -o /dev/null -w 'time_connect=%{time_connect}\nhttp_code=%{http_code}' -H 'Connection: Upgrade' -H 'Upgrade: websocket' -H 'Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==' -H 'Sec-WebSocket-Version: 13' "..address) if use_nft then
e.socket = string.match(result,"http_code=(%d+)")=="101" iret = luci.sys.call("nft add element inet ss_spec ss_spec_wan_ac { " .. domain .. " } 2>/dev/null") == 0
e.ping = tonumber(string.match(result, "time_connect=(%d+.%d%d%d)"))*1000 else
else iret = luci.sys.call("ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null") == 0
local socket = nixio.socket("inet", "stream") end
socket:setopt("socket", "rcvtimeo", 3)
socket:setopt("socket", "sndtimeo", 3) if transport == "ws" then
e.socket = socket:connect(domain, port) local prefix = tls == '1' and "https://" or "http://"
socket:close() local address = prefix .. domain .. ':' .. port .. wsPath
e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, domain)) local result = luci.sys.exec(
if (e.ping == "") then "curl --http1.1 -m 2 -ksN -o /dev/null " ..
e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null" % domain) "-w 'time_connect=%{time_connect}\nhttp_code=%{http_code}' " ..
if (e.ping == "") then "-H 'Connection: Upgrade' -H 'Upgrade: websocket' " ..
-- UDP ping test using nping "-H 'Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==' " ..
e.ping = luci.sys.exec(string.format("echo -n $(nping --udp -c 1 -p %s %s 2>/dev/null | grep -o 'Avg rtt: [0-9.]*ms' | awk '{print $3}' | sed 's/ms//' | head -1) 2>/dev/null", port, domain)) "-H 'Sec-WebSocket-Version: 13' " .. address
end )
end e.socket = string.match(result,"http_code=(%d+)") == "101"
end local ping_time = tonumber(string.match(result, "time_connect=(%d+.%d%d%d)"))
if (iret == 0) then e.ping = ping_time and ping_time * 1000 or nil
luci.sys.call(" ipset del ss_spec_wan_ac " .. domain) else
end -- TCP ping
luci.http.prepare_content("application/json") local socket = nixio.socket("inet", "stream")
luci.http.write_json(e) socket:setopt("socket", "rcvtimeo", 3)
socket:setopt("socket", "sndtimeo", 3)
e.socket = socket:connect(domain, port)
socket:close()
e.ping = tonumber(luci.sys.exec(string.format(
"tcping -q -c 1 -i 1 -t 2 -p %d %s 2>/dev/null | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}'",
port, domain
)))
if not e.ping then
e.ping = tonumber(luci.sys.exec(string.format(
"ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}'",
domain
)))
end
if not e.ping then
e.ping = tonumber(luci.sys.exec(string.format(
"nping --udp -c 1 -p %d %s 2>/dev/null | grep -o 'Avg rtt: [0-9.]*ms' | awk '{print $3}' | sed 's/ms//' | head -1",
port, domain
)))
end
end
if iret then
if use_nft then
luci.sys.call("nft delete element inet ss_spec ss_spec_wan_ac { " .. domain .. " } 2>/dev/null")
else
luci.sys.call("ipset del ss_spec_wan_ac " .. domain .. " 2>/dev/null")
end
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end end
function check_status() function check_status()
@@ -101,28 +136,46 @@ function check_port()
local s local s
local server_name = "" local server_name = ""
local uci = require "luci.model.uci".cursor() local uci = require "luci.model.uci".cursor()
local iret = 1 local use_nft = luci.sys.call("command -v nft >/dev/null") == 0
uci:foreach("shadowsocksr", "servers", function(s) uci:foreach("shadowsocksr", "servers", function(s)
if s.alias then if s.alias then
server_name = s.alias server_name = s.alias
elseif s.server and s.server_port then elseif s.server and s.server_port then
server_name = "%s:%s" % {s.server, s.server_port} server_name = s.server .. ":" .. s.server_port
end end
iret = luci.sys.call("ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null")
socket = nixio.socket("inet", "stream") -- 临时加入 set
local iret = false
if use_nft then
iret = luci.sys.call("nft add element inet ss_spec ss_spec_wan_ac { " .. s.server .. " } 2>/dev/null") == 0
else
iret = luci.sys.call("ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null") == 0
end
-- TCP 测试
local socket = nixio.socket("inet", "stream")
socket:setopt("socket", "rcvtimeo", 3) socket:setopt("socket", "rcvtimeo", 3)
socket:setopt("socket", "sndtimeo", 3) socket:setopt("socket", "sndtimeo", 3)
ret = socket:connect(s.server, s.server_port) local ret = socket:connect(s.server, s.server_port)
if tostring(ret) == "true" then socket:close()
socket:close()
retstring = retstring .. "<font><b style='color:green'>[" .. server_name .. "] OK.</b></font><br />" if ret then
retstring = retstring .. string.format("<font><b style='color:green'>[%s] OK.</b></font><br />", server_name)
else else
retstring = retstring .. "<font><b style='color:red'>[" .. server_name .. "] Error.</b></font><br />" retstring = retstring .. string.format("<font><b style='color:red'>[%s] Error.</b></font><br />", server_name)
end end
if iret == 0 then
luci.sys.call("ipset del ss_spec_wan_ac " .. s.server) -- 删除临时 set
if iret then
if use_nft then
luci.sys.call("nft delete element inet ss_spec ss_spec_wan_ac { " .. s.server .. " } 2>/dev/null")
else
luci.sys.call("ipset del ss_spec_wan_ac " .. s.server)
end
end end
end) end)
luci.http.prepare_content("application/json") luci.http.prepare_content("application/json")
luci.http.write_json({ret = retstring}) luci.http.write_json({ret = retstring})
end end

View File

@@ -4,14 +4,22 @@ local uci = require "luci.model.uci".cursor()
-- 获取 LAN IP 地址 -- 获取 LAN IP 地址
function lanip() function lanip()
local lan_ip local lan_ip
lan_ip = luci.sys.exec("uci -q get network.lan.ipaddr 2>/dev/null | awk -F '/' '{print $1}' | tr -d '\n'")
-- 尝试从 UCI 直接读取
lan_ip = luci.sys.exec("uci -q get network.lan.ipaddr 2>/dev/null | awk -F'/' '{print $1}' | tr -d '\\n'")
-- 尝试从 LAN 接口信息中读取(优先 ifname再 fallback 到 device
if not lan_ip or lan_ip == "" then if not lan_ip or lan_ip == "" then
lan_ip = luci.sys.exec("ip address show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) | grep -w 'inet' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -1 | tr -d '\n'") lan_ip = luci.sys.exec([[
ip -4 addr show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) 2>/dev/null \
| grep -w 'inet' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^127\.' | head -n1 | tr -d '\n']])
end end
-- 取任意一个 global IPv4 地址
if not lan_ip or lan_ip == "" then if not lan_ip or lan_ip == "" then
lan_ip = luci.sys.exec("ip addr show | grep -w 'inet' | grep 'global' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -n 1 | tr -d '\n'") lan_ip = luci.sys.exec([[
ip -4 addr show scope global 2>/dev/null \
| grep -w 'inet' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^127\.' | head -n1 | tr -d '\n']])
end end
return lan_ip return lan_ip

View File

@@ -264,7 +264,7 @@ s = m:section(NamedSection, sid, "servers")
s.anonymous = true s.anonymous = true
s.addremove = false s.addremove = false
o = s:option(DummyValue, "ssr_url", "SS/SSR/V2RAY/TROJAN/HYSTERIA2 URL") o = s:option(DummyValue, "ssr_url", "SS/SSR/V2RAY/TROJAN/TUIC/HYSTERIA2 URL")
o.rawhtml = true o.rawhtml = true
o.template = "shadowsocksr/ssrurl" o.template = "shadowsocksr/ssrurl"
o.value = sid o.value = sid
@@ -1285,15 +1285,26 @@ o = s:option(ListValue, "tuic_alpn", translate("TUIC ALPN"))
o.default = "" o.default = ""
o:value("", translate("Default")) o:value("", translate("Default"))
o:value("h3") o:value("h3")
o:value("h2")
o:value("h3,h2")
o:value("spdy/3.1") o:value("spdy/3.1")
o:value("h3,spdy/3.1") o:value("h3,spdy/3.1")
o:depends("type", "tuic") o:depends("type", "tuic")
-- IP STACK PREFERENCE
o = s:option(ListValue, "ipstack_prefer", translate("IP Stack Preference"))
o.default = ""
o:value("", translate("Default"))
o:value("v4first")
o:value("v6first")
o:depends("tuic_dual_stack", true)
-- [[ allowInsecure ]]-- -- [[ allowInsecure ]]--
o = s:option(Flag, "insecure", translate("allowInsecure")) o = s:option(Flag, "insecure", translate("allowInsecure"))
o.rmempty = false o.rmempty = false
o:depends("tls", true) o:depends("tls", true)
o:depends("type", "hysteria2") o:depends("type", "hysteria2")
o:depends("type", "tuic")
o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.") o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.")
-- [[ Hysteria2 TLS pinSHA256 ]] -- -- [[ Hysteria2 TLS pinSHA256 ]] --

View File

@@ -8,14 +8,22 @@ local uci = require "luci.model.uci".cursor()
-- 获取 LAN IP 地址 -- 获取 LAN IP 地址
function lanip() function lanip()
local lan_ip local lan_ip
lan_ip = luci.sys.exec("uci -q get network.lan.ipaddr 2>/dev/null | awk -F '/' '{print $1}' | tr -d '\n'")
-- 尝试从 UCI 直接读取
lan_ip = luci.sys.exec("uci -q get network.lan.ipaddr 2>/dev/null | awk -F'/' '{print $1}' | tr -d '\\n'")
-- 尝试从 LAN 接口信息中读取(优先 ifname再 fallback 到 device
if not lan_ip or lan_ip == "" then if not lan_ip or lan_ip == "" then
lan_ip = luci.sys.exec("ip address show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) | grep -w 'inet' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -1 | tr -d '\n'") lan_ip = luci.sys.exec([[
ip -4 addr show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) 2>/dev/null \
| grep -w 'inet' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^127\.' | head -n1 | tr -d '\n']])
end end
-- 取任意一个 global IPv4 地址
if not lan_ip or lan_ip == "" then if not lan_ip or lan_ip == "" then
lan_ip = luci.sys.exec("ip addr show | grep -w 'inet' | grep 'global' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -n 1 | tr -d '\n'") lan_ip = luci.sys.exec([[
ip -4 addr show scope global 2>/dev/null \
| grep -w 'inet' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^127\.' | head -n1 | tr -d '\n']])
end end
return lan_ip return lan_ip

View File

@@ -75,9 +75,9 @@ function export_ssr_url(btn, urlname, sid) {
textarea.select(); textarea.select();
try { try {
document.execCommand("copy"); // Security exception may be thrown by some browsers. document.execCommand("copy"); // Security exception may be thrown by some browsers.
s.innerHTML = "<font color='green'><%:Copy SSR to clipboard successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Copy SSR to clipboard successfully.%></font>";
} catch (ex) { } catch (ex) {
s.innerHTML = "<font color='red'><%:Unable to copy SSR to clipboard.%></font>"; s.innerHTML = "<font style=\'color:red\'><%:Unable to copy SSR to clipboard.%></font>";
} finally { } finally {
document.body.removeChild(textarea); document.body.removeChild(textarea);
} }
@@ -89,7 +89,7 @@ function import_ssr_url(btn, urlname, sid) {
if (!s) return false; if (!s) return false;
var ssrurl = prompt("<%:Paste sharing link here%>", ""); var ssrurl = prompt("<%:Paste sharing link here%>", "");
if (ssrurl == null || ssrurl == "") { if (ssrurl == null || ssrurl == "") {
s.innerHTML = "<font color='red'><%:User cancelled.%></font>"; s.innerHTML = "<font style=\'color:red\'><%:User cancelled.%></font>";
return false; return false;
} }
s.innerHTML = ""; s.innerHTML = "";
@@ -97,18 +97,6 @@ function import_ssr_url(btn, urlname, sid) {
ssrurl = ssrurl.replace(/&([a-zA-Z]+);/g, '&').replace(/\s*#\s*/, '#').trim(); //一些奇葩的链接用"&amp;"当做"&""#"前后带空格 ssrurl = ssrurl.replace(/&([a-zA-Z]+);/g, '&').replace(/\s*#\s*/, '#').trim(); //一些奇葩的链接用"&amp;"当做"&""#"前后带空格
var ssu = ssrurl.split('://'); var ssu = ssrurl.split('://');
//console.log(ssu.length); //console.log(ssu.length);
if (ssu[0] === "ss") {
var queryStr = "";
if (ssu[1].indexOf("?") > -1) {
queryStr = ssu[1].split("?")[1]; // 提取 ? 后面的参数
}
var params = new URLSearchParams(queryStr);
if (params.get("type")) {
// 替换协议头
ssrurl = ssrurl.replace(/^ss:\/\//i, "shadowsocks://");
var ssu = ssrurl.split('://');
}
}
var event = document.createEvent("HTMLEvents"); var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true); event.initEvent("change", true, true);
switch (ssu[0]) { switch (ssu[0]) {
@@ -189,136 +177,281 @@ function import_ssr_url(btn, urlname, sid) {
// 再分离 ? 或 /?(参数) // 再分离 ? 或 /?(参数)
var queryIndex = (url0 = url0.replace('/?', '?')).indexOf("?"); var queryIndex = (url0 = url0.replace('/?', '?')).indexOf("?");
var queryStr = ""; var query = "";
if (queryIndex >= 0) { if (queryIndex >= 0) {
queryStr = url0.substring(queryIndex + 1); query = url0.substring(queryIndex + 1);
url0 = url0.substring(0, queryIndex); url0 = url0.substring(0, queryIndex);
} }
var params = Object.fromEntries(new URLSearchParams(queryStr)); var params = Object.fromEntries(new URLSearchParams(query));
// 判断是否 SIP002 格式(即含 @ if ( ! params.type) {
if (url0.indexOf("@") !== -1) { // 普通 SS 导入逻辑
// === SIP002 格式 === // 判断是否 SIP002 格式(即含 @
var sipIndex = url0.indexOf("@"); if (url0.indexOf("@") !== -1) {
// 先 URL 解码 base64 再解码 // === SIP002 格式 ===
var userInfoB64 = decodeURIComponent(url0.substring(0, sipIndex)); var sipIndex = url0.indexOf("@");
var userInfo = b64decsafe(userInfoB64); // 先 URL 解码 base64 再解码
var userInfoSplitIndex = userInfo.indexOf(":"); var userInfoB64 = decodeURIComponent(url0.substring(0, sipIndex));
if(userInfoSplitIndex < 0) { var userInfo = b64decsafe(userInfoB64);
// 格式错误 var userInfoSplitIndex = userInfo.indexOf(":");
s.innerHTML = "<font style='color:red'><%:Userinfo format error.%></font>"; if(userInfoSplitIndex < 0) {
break; // 格式错误
} s.innerHTML = "<font style='color:red'><%:Userinfo format error.%></font>";
var method = userInfo.substring(0, userInfoSplitIndex); break;
var password = userInfo.substring(userInfoSplitIndex + 1); }
var serverPart = url0.substring(sipIndex + 1); var method = userInfo.substring(0, userInfoSplitIndex);
var serverInfo = serverPart.split(":"); var password = userInfo.substring(userInfoSplitIndex + 1);
var serverPart = url0.substring(sipIndex + 1);
var serverInfo = serverPart.split(":");
var server = serverInfo[0]; var server = serverInfo[0];
var port = serverInfo[1]; var port = serverInfo[1];
var plugin = "", pluginOpts = ""; var plugin = "", pluginOpts = "";
if (params.plugin) { if (params.plugin) {
var pluginParams = decodeURIComponent(params.plugin).split(";"); var pluginParams = decodeURIComponent(params.plugin).split(";");
plugin = pluginParams.shift(); plugin = pluginParams.shift();
pluginOpts = pluginParams.join(";"); pluginOpts = pluginParams.join(";");
} }
} else {
// === Base64 SS2022 / 普通格式 的整体编码格式 ===
// 先 URL 解码整个字符串
var decodedUrl0 = decodeURIComponent(url0);
var sstr = b64decsafe(decodedUrl0);
if (!sstr) {
s.innerHTML = "<font style='color:red'><%:Base64 sstr failed.%></font>";
break;
}
// 支持 SS2022 / 普通格式
var regex2022 = /^([^:]+):([^:]+):([^@]+)@([^:]+):(\d+)$/;
var regexNormal = /^([^:]+):([^@]+)@([^:]+):(\d+)$/;
var m2022 = sstr.match(regex2022);
var mNormal = sstr.match(regexNormal);
if (m2022) {
var method = m2022[1];
var password = m2022[2] + ":" + m2022[3];
var server = m2022[4];
var port = m2022[5];
} else if (mNormal) {
var method = mNormal[1];
var password = mNormal[2];
var server = mNormal[3];
var port = mNormal[4];
} else { } else {
s.innerHTML = "<font style='color:red'><%:SS URL base64 sstr format not recognized.%></font>"; // === Base64 SS2022 / 普通格式 的整体编码格式 ===
break; // 先 URL 解码整个字符串
} var decodedUrl0 = decodeURIComponent(url0);
var sstr = b64decsafe(decodedUrl0);
if (!sstr) {
s.innerHTML = "<font style='color:red'><%:Base64 sstr failed.%></font>";
break;
}
var plugin = "", pluginOpts = ""; // 支持 SS2022 / 普通格式
if (params["shadow-tls"]) { var regex2022 = /^([^:]+):([^:]+):([^@]+)@([^:]+):(\d+)$/;
try { var regexNormal = /^([^:]+):([^@]+)@([^:]+):(\d+)$/;
var decoded_tls = JSON.parse(atob(decodeURIComponent(params["shadow-tls"])));
plugin = "shadow-tls"; var m2022 = sstr.match(regex2022);
var versionFlag = ""; var mNormal = sstr.match(regexNormal);
if (decoded_tls.version && !isNaN(decoded_tls.version)) {
versionFlag = "v" + decoded_tls.version + "=1;"; if (m2022) {
var method = m2022[1];
var password = m2022[2] + ":" + m2022[3];
var server = m2022[4];
var port = m2022[5];
} else if (mNormal) {
var method = mNormal[1];
var password = mNormal[2];
var server = mNormal[3];
var port = mNormal[4];
} else {
s.innerHTML = "<font style='color:red'><%:SS URL base64 sstr format not recognized.%></font>";
break;
}
var plugin = "", pluginOpts = "";
if (params["shadow-tls"]) {
try {
var decoded_tls = JSON.parse(atob(decodeURIComponent(params["shadow-tls"])));
plugin = "shadow-tls";
var versionFlag = "";
if (decoded_tls.version && !isNaN(decoded_tls.version)) {
versionFlag = "v" + decoded_tls.version + "=1;";
}
pluginOpts = versionFlag + "host=" + (decoded_tls.host || "") + ";passwd=" + (decoded_tls.password || "");
} catch (e) {
console.log("shadow-tls decode failed:", e);
} }
pluginOpts = versionFlag + "host=" + (decoded_tls.host || "") + ";passwd=" + (decoded_tls.password || "");
} catch (e) {
console.log("shadow-tls decode failed:", e);
} }
} }
}
// 判断密码是否经过url编码 // 判断密码是否经过url编码
const isURLEncodedPassword = function(pwd) { const isURLEncodedPassword = function(pwd) {
if (!/%[0-9A-Fa-f]{2}/.test(pwd)) return false; if (!/%[0-9A-Fa-f]{2}/.test(pwd)) return false;
try {
const decoded = decodeURIComponent(pwd.replace(/\+/g, "%20"));
const reencoded = encodeURIComponent(decoded);
return reencoded === pwd;
} catch (e) {
return false;
}
}
if (isURLEncodedPassword(password)) {
password = decodeURIComponent(password); // 解码URL编码
} else {
password = password; // 保持原始值
}
// === 填充配置项 ===
var has_ss_type = (ss_type === "ss-rust") ? "ss-rust" : "ss-libev";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.has_ss_type')[0].value = has_ss_type;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.has_ss_type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = server;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].dispatchEvent(event);
if (plugin && plugin !== "none") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].checked = true; // 设置 enable_plugin 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].dispatchEvent(event);
if (plugin !== undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
}
} else {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].checked = false;
}
if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURIComponent(param);
}
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false;
} else {
try { try {
const decoded = decodeURIComponent(pwd.replace(/\+/g, "%20")); // Xray SS 导入逻辑
const reencoded = encodeURIComponent(decoded); // 拆分 @,判断是否是 base64 userinfo 的格式
return reencoded === pwd; var parts = url0.split("@");
} catch (e) { if (parts.length > 1) {
// @ 前是 base64(method:password),后面是 server:port?params
var userinfo = b64decsafe(parts[0]);
var sepIndex = userinfo.indexOf(":");
if (sepIndex > -1) {
method = userinfo.slice(0, sepIndex);
password = userinfo.slice(sepIndex + 1); //一些链接用明文uuid做密码
}
}
var url = new URL("http://" + url0 + (param ? "#" + encodeURIComponent(param) : ""));
} catch(e) {
alert(e);
return false; return false;
} }
} // Check if the elements exist before trying to modify them
if (isURLEncodedPassword(password)) { function setElementValue(name, value) {
password = decodeURIComponent(password); // 解码URL编码 const element = document.getElementsByName(name)[0];
} else { if (element) {
password = password; // 保持原始值 if (typeof value === 'boolean') {
} element.checked = value;
} else {
// === 填充配置项 === element.value = value;
var has_ss_type = (ss_type === "ss-rust") ? "ss-rust" : "ss-libev"; }
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.has_ss_type')[0].value = has_ss_type;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.has_ss_type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = server;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].dispatchEvent(event);
if (plugin && plugin !== "none") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].checked = true; // 设置 enable_plugin 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].dispatchEvent(event);
if (plugin !== undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
} }
} else { function dispatchEventIfExists(name, event) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].checked = false; const element = document.getElementsByName(name)[0];
} if (element) {
element.dispatchEvent(event);
}
}
setElementValue('cbid.shadowsocksr.' + sid + '.alias', url.hash ? decodeURIComponent(url.hash.slice(1)) : "");
setElementValue('cbid.shadowsocksr.' + sid + '.type', "v2ray");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.type', event);
setElementValue('cbid.shadowsocksr.' + sid + '.v2ray_protocol', "shadowsocks");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.v2ray_protocol', event);
setElementValue('cbid.shadowsocksr.' + sid + '.server', url.hostname);
setElementValue('cbid.shadowsocksr.' + sid + '.server_port', url.port || "80");
setElementValue('cbid.shadowsocksr.' + sid + '.password', password || url.username);
setElementValue('cbid.shadowsocksr.' + sid + '.transport',
params.type === "http" ? "h2" :
(["xhttp", "splithttp"].includes(params.type) ? "xhttp" :
(["tcp", "raw"].includes(params.type) ? "raw" :
(params.type || "raw")))
);
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.transport', event);
setElementValue('cbid.shadowsocksr.' + sid + '.encrypt_method_ss', method || params.encryption || "none");
if ([ "tls", "xtls", "reality" ].includes(params.security)) {
setElementValue('cbid.shadowsocksr.' + sid + '.' + params.security, true);
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.' + params.security, event);
if (param != undefined) { if (params.security === "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURIComponent(param); if (params.ech && params.ech.trim() !== "") {
setElementValue('cbid.shadowsocksr.' + sid + '.enable_ech', true); // 设置 enable_ech 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_ech', event); // 触发事件
setElementValue('cbid.shadowsocksr.' + sid + '.ech_config', params.ech || "");
}
if (params.allowInsecure === "1") {
setElementValue('cbid.shadowsocksr.' + sid + '.insecure', true); // 设置 insecure 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.insecure', event); // 触发事件
}
}
if (params.security === "reality") {
setElementValue('cbid.shadowsocksr.' + sid + '.reality_publickey', params.pbk ? decodeURIComponent(params.pbk) : "");
setElementValue('cbid.shadowsocksr.' + sid + '.reality_shortid', params.sid || "");
setElementValue('cbid.shadowsocksr.' + sid + '.reality_spiderx', params.spx ? decodeURIComponent(params.spx) : "");
if (params.pqv && params.pqv.trim() !== "") {
setElementValue('cbid.shadowsocksr.' + sid + '.enable_mldsa65verify', true); // 设置 enable_mldsa65verify 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_mldsa65verify', event); // 触发事件
setElementValue('cbid.shadowsocksr.' + sid + '.reality_mldsa65verify', params.pqv || "");
}
}
setElementValue('cbid.shadowsocksr.' + sid + '.tls_flow', params.flow || "none");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tls_flow', event);
setElementValue('cbid.shadowsocksr.' + sid + '.tls_alpn', params.alpn || "");
setElementValue('cbid.shadowsocksr.' + sid + '.fingerprint', params.fp || "");
setElementValue('cbid.shadowsocksr.' + sid + '.tls_host', params.sni || "");
}
switch (params.type) {
case "ws":
if (params.security !== "tls") {
setElementValue('cbid.shadowsocksr.' + sid + '.ws_host', params.host ? decodeURIComponent(params.host) : "");
}
setElementValue('cbid.shadowsocksr.' + sid + '.ws_path', params.path ? decodeURIComponent(params.path) : "/");
break;
case "httpupgrade":
if (params.security !== "tls") {
setElementValue('cbid.shadowsocksr.' + sid + '.httpupgrade_host', params.host ? decodeURIComponent(params.host) : "");
}
setElementValue('cbid.shadowsocksr.' + sid + '.httpupgrade_path', params.path ? decodeURIComponent(params.path) : "/");
break;
case "xhttp":
case "splithttp":
if (params.security !== "tls") {
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_host', params.host ? decodeURIComponent(params.host) : "");
}
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_mode', params.mode || "auto");
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_path', params.path ? decodeURIComponent(params.path) : "/");
if (params.extra && params.extra.trim() !== "") {
setElementValue('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', true); // 设置 enable_xhttp_extra 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', event); // 触发事件
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_extra', params.extra || "");
}
break;
case "kcp":
setElementValue('cbid.shadowsocksr.' + sid + '.kcp_guise', params.headerType || "none");
setElementValue('cbid.shadowsocksr.' + sid + '.seed', params.seed || "");
break;
case "http":
/* this is non-standard, bullshit */
case "h2":
setElementValue('cbid.shadowsocksr.' + sid + '.h2_host', params.host ? decodeURIComponent(params.host) : "");
setElementValue('cbid.shadowsocksr.' + sid + '.h2_path', params.path ? decodeURIComponent(params.path) : "");
break;
case "quic":
setElementValue('cbid.shadowsocksr.' + sid + '.quic_guise', params.headerType || "none");
setElementValue('cbid.shadowsocksr.' + sid + '.quic_security', params.quicSecurity || "none");
setElementValue('cbid.shadowsocksr.' + sid + '.quic_key', params.key || "");
break;
case "grpc":
setElementValue('cbid.shadowsocksr.' + sid + '.serviceName', params.serviceName || "");
setElementValue('cbid.shadowsocksr.' + sid + '.grpc_mode', params.mode || "gun");
break;
case "tcp":
case "raw":
setElementValue('cbid.shadowsocksr.' + sid + '.tcp_guise', params.headerType || "none");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tcp_guise', event);
if (params.headerType === "http") {
setElementValue('cbid.shadowsocksr.' + sid + '.http_host', params.host ? decodeURIComponent(params.host) : "");
setElementValue('cbid.shadowsocksr.' + sid + '.http_path', params.path ? decodeURIComponent(params.path) : "");
}
break;
}
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false;
} }
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false;
case "ssr": case "ssr":
var sstr = b64decsafe((ssu[1] || "").replace(/#.*/, "").trim()); var sstr = b64decsafe((ssu[1] || "").replace(/#.*/, "").trim());
var ploc = sstr.indexOf("/?"); var ploc = sstr.indexOf("/?");
@@ -349,7 +482,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam'); document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam');
var rem = pdict['remarks']; var rem = pdict['remarks'];
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = b64decutf8safe(rem); if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = b64decutf8safe(rem);
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
case "trojan": case "trojan":
try { try {
@@ -360,93 +493,117 @@ function import_ssr_url(btn, urlname, sid) {
return false; return false;
} }
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : ""; if (!params.get("type")) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "v2ray"; // 普通 Trojan 导入逻辑
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].value = "trojan"; document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "trojan";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname; document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80"; document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = decodeURIComponent(url.username); document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = decodeURIComponent(url.username);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true; document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("sni"); document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("peer") || params.get("sni");
if (params.get("allowInsecure") === "1") { if (params.get("allowInsecure") === "1") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true; // 设置 insecure 为 true document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true; // 设置 insecure 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event); // 触发事件 document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event); // 触发事件
}
if (params.get("ech") && params.get("ech").trim() !== "") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].checked = true; // 设置 enable_ech 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ech_config')[0].value = params.get("ech");
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value =
params.get("type") == "http" ? "h2" :
(["xhttp", "splithttp"].includes(params.get("type")) ? "xhttp" :
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
(params.get("type") || "raw")));
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
if (params.get("security") === "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_alpn')[0].value = params.get("alpn") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.fingerprint')[0].value = params.get("fp") || "";
}
switch (params.get("type")) {
case "ws":
if (params.get("security") !== "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
} }
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/"; if (params.get("tfo") === "1") {
break; document.getElementsByName('cbid.shadowsocksr.' + sid + '.fast_open')[0].checked = true; // 设置 fast_open 为 true
case "httpupgrade": document.getElementsByName('cbid.shadowsocksr.' + sid + '.fast_open')[0].dispatchEvent(event); // 触发事件
if (params.get("security") !== "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
} }
document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
break;
case "xhttp":
case "splithttp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_mode')[0].value = params.get("mode") || "auto";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
if (params.get("extra") && params.get("extra").trim() !== "") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].checked = true; // 设置 enable_xhttp_extra 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_extra')[0].value = params.get("extra") || "";
}
break;
case "kcp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = params.get("seed") || "";
break;
case "http":
/* this is non-standard, bullshit */
case "h2":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
break;
case "quic":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = params.get("key") || "";
break;
case "grpc":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
break;
case "raw":
case "tcp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].dispatchEvent(event);
if (params.get("headerType") === "http") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
}
break;
}
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
} else {
// Xray Trojan 导入逻辑
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "v2ray";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].value = "trojan";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = decodeURIComponent(url.username);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("sni");
if (params.get("allowInsecure") === "1") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true; // 设置 insecure 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event); // 触发事件
}
if (params.get("ech") && params.get("ech").trim() !== "") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].checked = true; // 设置 enable_ech 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ech_config')[0].value = params.get("ech");
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value =
params.get("type") == "http" ? "h2" :
(["xhttp", "splithttp"].includes(params.get("type")) ? "xhttp" :
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
(params.get("type") || "raw")));
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
if (params.get("security") === "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_alpn')[0].value = params.get("alpn") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.fingerprint')[0].value = params.get("fp") || "";
}
switch (params.get("type")) {
case "ws":
if (params.get("security") !== "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
break;
case "httpupgrade":
if (params.get("security") !== "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
break;
case "xhttp":
case "splithttp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_mode')[0].value = params.get("mode") || "auto";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
if (params.get("extra") && params.get("extra").trim() !== "") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].checked = true; // 设置 enable_xhttp_extra 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_extra')[0].value = params.get("extra") || "";
}
break;
case "kcp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = params.get("seed") || "";
break;
case "http":
/* this is non-standard, bullshit */
case "h2":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
break;
case "quic":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = params.get("key") || "";
break;
case "grpc":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
break;
case "raw":
case "tcp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].dispatchEvent(event);
if (params.get("headerType") === "http") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
}
break;
}
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false;
}
case "vmess": case "vmess":
var sstr = b64DecodeUnicode((ssu[1] || "").replace(/#.*/, "").trim()); var sstr = b64DecodeUnicode((ssu[1] || "").replace(/#.*/, "").trim());
var ploc = sstr.indexOf("/?"); var ploc = sstr.indexOf("/?");
@@ -532,7 +689,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].checked = true; document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].dispatchEvent(event);
} }
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
case "vless": case "vless":
try { try {
@@ -664,153 +821,85 @@ function import_ssr_url(btn, urlname, sid) {
} }
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
case "shadowsocks": case "tuic":
try { var url0 = (ssu[1] || "");
// 处理完整 ss:// 链接 var param = "";
var urlinfo = ssu[1];
// 拆分 @,判断是否是 base64 userinfo 的格式
var parts = urlinfo.split("@");
if (parts.length > 1) {
// @ 前是 base64(method:password),后面是 server:port?params
var userinfo = b64decsafe(parts[0]);
var sepIndex = userinfo.indexOf(":");
if (sepIndex > -1) {
method = userinfo.slice(0, sepIndex);
password = userinfo.slice(sepIndex + 1); //一些链接用明文uuid做密码
}
}
var url = new URL("http://" + urlinfo);
var params = url.searchParams; // 先分离 #alias
var hashIndex = url0.indexOf("#");
if (hashIndex >= 0) {
param = url0.substring(hashIndex + 1);
url0 = url0.substring(0, hashIndex);
}
} catch(e) { // 再分离 ? 或 /?(参数)
alert(e); var queryIndex = (url0 = url0.replace('/?', '?')).indexOf("?");
return false; var query = "";
if (queryIndex >= 0) {
query = url0.substring(queryIndex + 1);
url0 = url0.substring(0, queryIndex);
} }
// Check if the elements exist before trying to modify them
function setElementValue(name, value) {
const element = document.getElementsByName(name)[0];
if (element) {
if (typeof value === 'boolean') {
element.checked = value;
} else {
element.value = value;
}
}
}
function dispatchEventIfExists(name, event) {
const element = document.getElementsByName(name)[0];
if (element) {
element.dispatchEvent(event);
}
}
setElementValue('cbid.shadowsocksr.' + sid + '.alias', url.hash ? decodeURIComponent(url.hash.slice(1)) : "");
setElementValue('cbid.shadowsocksr.' + sid + '.type', "v2ray");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.type', event);
setElementValue('cbid.shadowsocksr.' + sid + '.v2ray_protocol', "shadowsocks");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.v2ray_protocol', event);
setElementValue('cbid.shadowsocksr.' + sid + '.server', url.hostname);
setElementValue('cbid.shadowsocksr.' + sid + '.server_port', url.port || "80");
setElementValue('cbid.shadowsocksr.' + sid + '.password', password || url.username);
setElementValue('cbid.shadowsocksr.' + sid + '.transport',
params.get("type") === "http" ? "h2" :
(["xhttp", "splithttp"].includes(params.get("type")) ? "xhttp" :
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
(params.get("type") || "raw")))
);
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.transport', event);
setElementValue('cbid.shadowsocksr.' + sid + '.encrypt_method_ss', method || params.get("encryption") || "none");
if ([ "tls", "xtls", "reality" ].includes(params.get("security"))) {
setElementValue('cbid.shadowsocksr.' + sid + '.' + params.get("security"), true);
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.' + params.get("security"), event);
if (params.get("security") === "tls") { var params = Object.fromEntries(new URLSearchParams(query));
if (params.get("ech") && params.get("ech").trim() !== "") {
setElementValue('cbid.shadowsocksr.' + sid + '.enable_ech', true); // 设置 enable_ech 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_ech', event); // 触发事件
setElementValue('cbid.shadowsocksr.' + sid + '.ech_config', params.get("ech") || "");
}
if (params.get("allowInsecure") === "1") {
setElementValue('cbid.shadowsocksr.' + sid + '.insecure', true); // 设置 insecure 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.insecure', event); // 触发事件
}
}
if (params.get("security") === "reality") {
setElementValue('cbid.shadowsocksr.' + sid + '.reality_publickey', params.get("pbk") ? decodeURIComponent(params.get("pbk")) : "");
setElementValue('cbid.shadowsocksr.' + sid + '.reality_shortid', params.get("sid") || "");
setElementValue('cbid.shadowsocksr.' + sid + '.reality_spiderx', params.get("spx") ? decodeURIComponent(params.get("spx")) : "");
if (params.get("pqv") && params.get("pqv").trim() !== "") {
setElementValue('cbid.shadowsocksr.' + sid + '.enable_mldsa65verify', true); // 设置 enable_mldsa65verify 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_mldsa65verify', event); // 触发事件
setElementValue('cbid.shadowsocksr.' + sid + '.reality_mldsa65verify', params.get("pqv") || "");
}
}
setElementValue('cbid.shadowsocksr.' + sid + '.tls_flow', params.get("flow") || "none");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tls_flow', event);
setElementValue('cbid.shadowsocksr.' + sid + '.tls_alpn', params.get("alpn") || ""); var sipIndex = url0.indexOf("@");
setElementValue('cbid.shadowsocksr.' + sid + '.fingerprint', params.get("fp") || ""); var userInfo = url0.substring(0, sipIndex); // 格式uuid:password
setElementValue('cbid.shadowsocksr.' + sid + '.tls_host', params.get("sni") || ""); var hostPart = url0.substring(sipIndex + 1); // 格式hostname:port
} var userInfoSplitIndex = userInfo.indexOf(":");
switch (params.get("type")) { if(userInfoSplitIndex < 0) {
case "ws": // 格式错误
if (params.get("security") !== "tls") { s.innerHTML = "<font style='color:red'><%:Userinfo format error.%></font>";
setElementValue('cbid.shadowsocksr.' + sid + '.ws_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.shadowsocksr.' + sid + '.ws_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
break;
case "httpupgrade":
if (params.get("security") !== "tls") {
setElementValue('cbid.shadowsocksr.' + sid + '.httpupgrade_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.shadowsocksr.' + sid + '.httpupgrade_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
break;
case "xhttp":
case "splithttp":
if (params.get("security") !== "tls") {
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_mode', params.get("mode") || "auto");
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
if (params.get("extra") && params.get("extra").trim() !== "") {
setElementValue('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', true); // 设置 enable_xhttp_extra 为 true
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', event); // 触发事件
setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_extra', params.get("extra") || "");
}
break;
case "kcp":
setElementValue('cbid.shadowsocksr.' + sid + '.kcp_guise', params.get("headerType") || "none");
setElementValue('cbid.shadowsocksr.' + sid + '.seed', params.get("seed") || "");
break;
case "http":
/* this is non-standard, bullshit */
case "h2":
setElementValue('cbid.shadowsocksr.' + sid + '.h2_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
setElementValue('cbid.shadowsocksr.' + sid + '.h2_path', params.get("path") ? decodeURIComponent(params.get("path")) : "");
break;
case "quic":
setElementValue('cbid.shadowsocksr.' + sid + '.quic_guise', params.get("headerType") || "none");
setElementValue('cbid.shadowsocksr.' + sid + '.quic_security', params.get("quicSecurity") || "none");
setElementValue('cbid.shadowsocksr.' + sid + '.quic_key', params.get("key") || "");
break;
case "grpc":
setElementValue('cbid.shadowsocksr.' + sid + '.serviceName', params.get("serviceName") || "");
setElementValue('cbid.shadowsocksr.' + sid + '.grpc_mode', params.get("mode") || "gun");
break;
case "tcp":
case "raw":
setElementValue('cbid.shadowsocksr.' + sid + '.tcp_guise', params.get("headerType") || "none");
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tcp_guise', event);
if (params.get("headerType") === "http") {
setElementValue('cbid.shadowsocksr.' + sid + '.http_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
setElementValue('cbid.shadowsocksr.' + sid + '.http_path', params.get("path") ? decodeURIComponent(params.get("path")) : "");
}
break; break;
} }
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
var method = userInfo.substring(0, userInfoSplitIndex);
var password = userInfo.substring(userInfoSplitIndex + 1);
var url = new URL("http://" + hostPart); // 用 URL 提取 host 与 port
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_uuid')[0].value = method;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_ip')[0].value = params.ip || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_passwd')[0].value = password;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.udp_relay_mode')[0].value = params.udp_relay_mode || "native";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.congestion_control')[0].value = params.congestion_control || "cubic";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_alpn')[0].value = params.alpn || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.heartbeat')[0].value = params.heartbeat || "3";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.timeout')[0].value = params.timeout || "8";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.gc_interval')[0].value = params.gc_interval || "3";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.gc_lifetime')[0].value = params.gc_lifetime || "15";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.send_window')[0].value = params.send_window || "20971520";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.receive_window')[0].value = params.receive_window || "10485760";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_max_package_size')[0].value = params.max_packet_size || "1500";
if (params["disable_sni"] === "1" || params["disable_sni"] === "true") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.disable_sni')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.disable_sni')[0].dispatchEvent(event);
}
if (params["zero_rtt_handshake"] === "1" || params["zero_rtt_handshake"] === "true") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.zero_rtt_handshake')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.zero_rtt_handshake')[0].dispatchEvent(event);
}
if (params["dual_stack"] === "1" || params["dual_stack"] === "true") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_dual_stack')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_dual_stack')[0].dispatchEvent(event);
if (params.ipstack_prefer && params.ipstack_prefer.trim() !== "") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ipstack_prefer')[0].value = params.ipstack_prefer;
}
}
if (params["allowInsecure"] === "1" || params["allowInsecure"] === "true") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event);
}
if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURIComponent(param);
}
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
default: default:
s.innerHTML = "<font color='red'><%:Invalid format.%></font>"; s.innerHTML = "<font style=\'color:red\'><%:Invalid format.%></font>";
return false; return false;
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1258,8 +1258,18 @@ start_server() {
[ "$(uci_get_by_name $1 enable 0)" == "0" ] && return 1 [ "$(uci_get_by_name $1 enable 0)" == "0" ] && return 1
let server_count=server_count+1 let server_count=server_count+1
if [ "$server_count" == "1" ]; then if [ "$server_count" == "1" ]; then
if ! (iptables-save -t filter | grep SSR-SERVER-RULE >/dev/null); then if command -v nft >/dev/null 2>&1; then
iptables -N SSR-SERVER-RULE && iptables -t filter -I INPUT -j SSR-SERVER-RULE # nftables / fw4
if ! nft list chain inet fw4 SSR-SERVER-RULE >/dev/null 2>&1; then
nft add chain inet fw4 SSR-SERVER-RULE
nft insert rule inet fw4 input jump SSR-SERVER-RULE
fi
else
# iptables / fw3
if ! (iptables-save -t filter | grep -q "SSR-SERVER-RULE"); then
iptables -N SSR-SERVER-RULE
iptables -t filter -I INPUT -j SSR-SERVER-RULE
fi
fi fi
fi fi
local type=$(uci_get_by_name $1 type) local type=$(uci_get_by_name $1 type)
@@ -1287,17 +1297,15 @@ start_server() {
echolog "Server:Socks5 Server$server_count Started!" echolog "Server:Socks5 Server$server_count Started!"
;; ;;
esac esac
ssr_server_port=$(uci show shadowsocksr | grep 'server_config.*server_port' | awk -F"'" '{print $2}' | tr "\n" " ") server_port=$(uci_get_by_name $1 server_port)
if [ -n "$ssr_server_port" ]; then if command -v nft >/dev/null 2>&1; then
uci -q delete firewall.shadowsocksr_server # nftables / fw4
uci set firewall.shadowsocksr_server=rule nft add rule inet fw4 SSR-SERVER-RULE tcp dport $server_port accept
uci set firewall.shadowsocksr_server.name="shadowsocksr_server" nft add rule inet fw4 SSR-SERVER-RULE udp dport $server_port accept
uci set firewall.shadowsocksr_server.target="ACCEPT" else
uci set firewall.shadowsocksr_server.src="wan" # iptables / fw3
uci set firewall.shadowsocksr_server.dest_port="$ssr_server_port" iptables -t filter -A SSR-SERVER-RULE -p tcp --dport $server_port -j ACCEPT
uci set firewall.shadowsocksr_server.enabled="1" iptables -t filter -A SSR-SERVER-RULE -p udp --dport $server_port -j ACCEPT
uci commit firewall
/etc/init.d/firewall reload >/dev/null 2>&1
fi fi
return 0 return 0
} }
@@ -1307,17 +1315,37 @@ start_server() {
if [ ! -f $FWI ]; then if [ ! -f $FWI ]; then
echo '#!/bin/sh' >$FWI echo '#!/bin/sh' >$FWI
fi fi
extract_rules() { if command -v nft >/dev/null 2>&1; then
echo "*filter" # nftables / fw4
iptables-save -t filter | grep SSR-SERVER-RULE | sed -e "s/^-A INPUT/-I INPUT/" extract_rules() {
echo 'COMMIT' nft list chain inet fw4 SSR-SERVER-RULE 2>/dev/null | \
} grep -v 'chain SSR-SERVER-RULE' | grep -v '^\s*{' | grep -v '^\s*}' | sed 's/ counter//g'
cat <<-EOF >>$FWI }
iptables-save -c | grep -v "SSR-SERVER" | iptables-restore -c cat <<-EOF >>$FWI
iptables-restore -n <<-EOT nft flush chain inet fw4 SSR-SERVER-RULE 2>/dev/null || true
$(extract_rules) nft -f - <<-EOT
EOT table inet fw4 {
EOF chain SSR-SERVER-RULE {
type filter hook input priority 0; policy accept;
$(extract_rules)
}
}
EOT
EOF
else
# iptables / fw3
extract_rules() {
echo "*filter"
iptables-save -t filter | grep SSR-SERVER-RULE | sed -e "s/^-A INPUT/-I INPUT/"
echo 'COMMIT'
}
cat <<-EOF >>$FWI
iptables-save -c | grep -v "SSR-SERVER" | iptables-restore -c
iptables-restore -n <<-EOT
$(extract_rules)
EOT
EOF
fi
} }
config_load $NAME config_load $NAME
@@ -1455,6 +1483,28 @@ stop() {
unlock unlock
set_lock set_lock
/usr/bin/ssr-rules -f /usr/bin/ssr-rules -f
if command -v nft >/dev/null 2>&1; then
# nftables / fw4
#local srulecount=$(nft list ruleset 2>/dev/null | grep -c 'SSR-SERVER-RULE')
#local srulecount=$(nft list chain inet fw4 SSR-SERVER-RULE 2>/dev/null | grep -c 'dport')
local srulecount=$(nft list chain inet fw4 SSR-SERVER-RULE | grep -vE '^\s*(chain|{|})' | wc -l)
else
# iptables / fw3
local srulecount=$(iptables -L | grep SSR-SERVER-RULE | wc -l)
fi
if [ $srulecount -gt 0 ]; then
if command -v nft >/dev/null 2>&1; then
# nftables / fw4
nft flush chain inet fw4 SSR-SERVER-RULE 2>/dev/null || true
nft delete rule inet fw4 input jump SSR-SERVER-RULE 2>/dev/null || true
nft delete chain inet fw4 SSR-SERVER-RULE 2>/dev/null || true
else
# iptables / fw3
iptables -F SSR-SERVER-RULE
iptables -t filter -D INPUT -j SSR-SERVER-RULE
iptables -X SSR-SERVER-RULE 2>/dev/null
fi
fi
if [ -z "$switch_server" ]; then if [ -z "$switch_server" ]; then
$PS -w | grep -v "grep" | grep ssr-switch | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 & $PS -w | grep -v "grep" | grep ssr-switch | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
rm -f /var/lock/ssr-switch.lock rm -f /var/lock/ssr-switch.lock
@@ -1465,7 +1515,7 @@ stop() {
( \ ( \
# Graceful kill first, so programs have the chance to stop its subprocesses # Graceful kill first, so programs have the chance to stop its subprocesses
$PS -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill >/dev/null 2>&1 ; \ $PS -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill >/dev/null 2>&1 ; \
sleep 1s; \ sleep 3s; \
# Force kill hanged programs # Force kill hanged programs
$PS -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 ; \ $PS -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 ; \
) )
@@ -1488,9 +1538,6 @@ stop() {
/etc/init.d/dnsmasq restart >/dev/null 2>&1 /etc/init.d/dnsmasq restart >/dev/null 2>&1
fi fi
uci -q delete firewall.shadowsocksr_server
uci commit firewall
/etc/init.d/firewall reload >/dev/null 2>&1
del_cron del_cron
unset_lock unset_lock
} }

View File

@@ -1,37 +1,7 @@
aaplimg.com bilibili.com
account.synology.com bilibili.cn
apple-cloudkit.com bilivideo.com
apple.co bilivideo.cn
apple.com
apple.com.cn
appstore.com
biliapi.com biliapi.com
biliapi.net biliapi.net
bilibili.cn apple.com
bilibili.com
bilivideo.cn
bilivideo.com
bing.com
cdn-apple.com
checkip.dyndns.org
checkip.synology.com
checkipv6.synology.com
checkport.synology.com
crashlytics.com
ddns.synology.com
gitmirror.com
icloud-content.com
icloud.com
icloud.com.cn
images-cn.ssl-images-amazon.com
mirrorlist.centos.org
mzstatic.com
office365.com
officecdn-microsoft-com.akamaized.net
teamviewer.com
whatismyip.akamai.com
windows.com
windowsupdate.com
worldbank.org
worldscientific.com
www-cdn.icloud.com.akadns.net

View File

@@ -9,12 +9,12 @@
# Detect firewall version and set appropriate tools # Detect firewall version and set appropriate tools
detect_firewall() { detect_firewall() {
if command -v fw4 >/dev/null 2>&1 && [ -f /usr/share/nftables.d/ruleset-post/99-shadowsocksr.nft ]; then if command -v nft >/dev/null 2>&1 && \
USE_NFT=1 [ -n "$(uci get firewall.@defaults[0].syn_flood 2>/dev/null)" ] && \
NFT="nft" ! grep -q "fw3" /etc/init.d/firewall 2>/dev/null; then
elif command -v nft >/dev/null 2>&1 && [ "$(uci get firewall.@defaults[0].syn_flood 2>/dev/null)" != "" ] && [ ! -f /etc/config/firewall3 ]; then USE_NFT=1
USE_NFT=1 NFT="nft"
NFT="nft" FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file
else else
USE_NFT=0 USE_NFT=0
IPT="iptables -t nat" # alias of iptables IPT="iptables -t nat" # alias of iptables
@@ -26,6 +26,7 @@ detect_firewall() {
detect_firewall detect_firewall
TAG="_SS_SPEC_RULE_" # comment tag TAG="_SS_SPEC_RULE_" # comment tag
usage() { usage() {
cat <<-EOF cat <<-EOF
Usage: ssr-rules [options] Usage: ssr-rules [options]
@@ -83,10 +84,14 @@ flush_r() {
flush_nftables() { flush_nftables() {
# Remove nftables rules and sets # Remove nftables rules and sets
$NFT delete table inet ss_spec 2>/dev/null $NFT delete table inet ss_spec 2>/dev/null
$NFT delete table ip ss_spec 2>/dev/null
$NFT delete table ip ss_spec_mangle 2>/dev/null
# Clean up routing rules # Clean up routing rules
ip rule del fwmark 0x01/0x01 table 100 2>/dev/null ip rule del fwmark 0x01/0x01 table 100 2>/dev/null
ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null
[ -n "$FWI" ] && echo '#!/bin/sh' >"$FWI"
return 0 return 0
} }
@@ -128,43 +133,43 @@ ipset_r() {
} }
ipset_nft() { ipset_nft() {
[ -f "$IGNORE_LIST" ] && /usr/share/shadowsocksr/chinaipset.sh $IGNORE_LIST [ -f "$IGNORE_LIST" ] && /usr/share/shadowsocksr/chinaipset.sh "$IGNORE_LIST"
# Create nftables table and sets # Create nftables table and sets
$NFT add table inet ss_spec 2>/dev/null $NFT add table inet ss_spec 2>/dev/null
$NFT add set inet ss_spec ss_spec_wan_ac { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec ss_spec_wan_ac '{ type ipv4_addr; flags interval; }' 2>/dev/null
$NFT add set inet ss_spec gmlan { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec gmlan '{ type ipv4_addr; flags interval; }' 2>/dev/null
$NFT add set inet ss_spec fplan { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec fplan '{ type ipv4_addr; flags interval; }' 2>/dev/null
$NFT add set inet ss_spec bplan { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec bplan '{ type ipv4_addr; flags interval; }' 2>/dev/null
$NFT add set inet ss_spec whitelist { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec whitelist '{ type ipv4_addr; flags interval; }' 2>/dev/null
$NFT add set inet ss_spec blacklist { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec blacklist '{ type ipv4_addr; flags interval; }' 2>/dev/null
$NFT add set inet ss_spec netflix { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec netflix '{ type ipv4_addr; flags interval; }' 2>/dev/null
# Add IP addresses to sets # Add IP addresses to sets
for ip in $LAN_GM_IP; do for ip in $LAN_GM_IP; do
$NFT add element inet ss_spec gmlan { $ip } $NFT add element inet ss_spec gmlan "{ $ip }"
done done
for ip in $LAN_FP_IP; do for ip in $LAN_FP_IP; do
$NFT add element inet ss_spec fplan { $ip } $NFT add element inet ss_spec fplan "{ $ip }"
done done
for ip in $LAN_BP_IP; do for ip in $LAN_BP_IP; do
$NFT add element inet ss_spec bplan { $ip } $NFT add element inet ss_spec bplan "{ $ip }"
done done
for ip in $WAN_BP_IP; do for ip in $WAN_BP_IP; do
$NFT add element inet ss_spec whitelist { $ip } $NFT add element inet ss_spec whitelist "{ $ip }"
done done
for ip in $WAN_FW_IP; do for ip in $WAN_FW_IP; do
$NFT add element inet ss_spec blacklist { $ip } $NFT add element inet ss_spec blacklist "{ $ip }"
done done
# Create main chain for WAN access control # Create main chain for WAN access control
$NFT add chain inet ss_spec ss_spec_wan_ac { type nat hook prerouting priority dstnat\; } $NFT add chain inet ss_spec ss_spec_wan_ac '{ type nat hook prerouting priority dstnat; }' 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport 53 ip daddr 127.0.0.0/8 return $NFT add rule inet ss_spec ss_spec_wan_ac tcp dport 53 ip daddr 127.0.0.0/8 return
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport != 53 ip daddr $server return $NFT add rule inet ss_spec ss_spec_wan_ac tcp dport != 53 ip daddr "$server" return
# Add special IP ranges to WAN AC set # Add special IP ranges to WAN AC set
for ip in $(gen_spec_iplist); do for ip in $(gen_spec_iplist); do
$NFT add element inet ss_spec ss_spec_wan_ac { $ip } $NFT add element inet ss_spec ss_spec_wan_ac "{ $ip }"
done done
# Set up mode-specific rules # Set up mode-specific rules
@@ -212,19 +217,19 @@ ipset_nft() {
# Shunt/Netflix rules # Shunt/Netflix rules
if [ "$SHUNT_PORT" != "0" ]; then if [ "$SHUNT_PORT" != "0" ]; then
for ip in $(cat ${SHUNT_LIST:=/dev/null} 2>/dev/null); do for ip in $(cat "${SHUNT_LIST:=/dev/null}" 2>/dev/null); do
$NFT add element inet ss_spec netflix { $ip } $NFT add element inet ss_spec netflix "{ $ip }"
done done
case "$SHUNT_PORT" in case "$SHUNT_PORT" in
1) 1)
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport $PROXY_PORTS ip daddr @netflix redirect to :$local_port $NFT add rule inet ss_spec ss_spec_wan_ac tcp dport "$PROXY_PORTS" ip daddr @netflix redirect to :"$local_port"
;; ;;
*) *)
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport $PROXY_PORTS ip daddr @netflix redirect to :$SHUNT_PORT $NFT add rule inet ss_spec ss_spec_wan_ac tcp dport "$PROXY_PORTS" ip daddr @netflix redirect to :"$SHUNT_PORT"
if [ "$SHUNT_PROXY" == "1" ]; then if [ "$SHUNT_PROXY" = "1" ]; then
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport $PROXY_PORTS ip daddr $SHUNT_IP redirect to :$local_port $NFT add rule inet ss_spec ss_spec_wan_ac tcp dport "$PROXY_PORTS" ip daddr "$SHUNT_IP" redirect to :"$local_port"
else else
$NFT add element inet ss_spec whitelist { $SHUNT_IP } $NFT add element inet ss_spec whitelist "{ $SHUNT_IP }"
fi fi
;; ;;
esac esac
@@ -233,12 +238,12 @@ ipset_nft() {
} }
ipset_iptables() { ipset_iptables() {
[ -f "$IGNORE_LIST" ] && /usr/share/shadowsocksr/chinaipset.sh $IGNORE_LIST [ -f "$IGNORE_LIST" ] && /usr/share/shadowsocksr/chinaipset.sh "$IGNORE_LIST"
$IPT -N SS_SPEC_WAN_AC 2>/dev/null $IPT -N SS_SPEC_WAN_AC 2>/dev/null
$IPT -I SS_SPEC_WAN_AC -p tcp --dport 53 -d 127.0.0.0/8 -j RETURN $IPT -I SS_SPEC_WAN_AC -p tcp --dport 53 -d 127.0.0.0/8 -j RETURN
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN $IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d "$server" -j RETURN
ipset -N gmlan hash:net 2>/dev/null ipset -N gmlan hash:net 2>/dev/null
for ip in $LAN_GM_IP; do ipset -! add gmlan $ip; done for ip in $LAN_GM_IP; do ipset -! add gmlan "$ip"; done
case "$RUNMODE" in case "$RUNMODE" in
router) router)
ipset -! -R <<-EOF || return 1 ipset -! -R <<-EOF || return 1
@@ -267,34 +272,34 @@ ipset_iptables() {
;; ;;
esac esac
ipset -N fplan hash:net 2>/dev/null ipset -N fplan hash:net 2>/dev/null
for ip in $LAN_FP_IP; do ipset -! add fplan $ip; done for ip in $LAN_FP_IP; do ipset -! add fplan "$ip"; done
$IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW $IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW
ipset -N bplan hash:net 2>/dev/null ipset -N bplan hash:net 2>/dev/null
for ip in $LAN_BP_IP; do ipset -! add bplan $ip; done for ip in $LAN_BP_IP; do ipset -! add bplan "$ip"; done
$IPT -I SS_SPEC_WAN_AC -m set --match-set bplan src -j RETURN $IPT -I SS_SPEC_WAN_AC -m set --match-set bplan src -j RETURN
ipset -N whitelist hash:net 2>/dev/null ipset -N whitelist hash:net 2>/dev/null
ipset -N blacklist hash:net 2>/dev/null ipset -N blacklist hash:net 2>/dev/null
$IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist dst -j SS_SPEC_WAN_FW $IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist dst -j SS_SPEC_WAN_FW
$IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN $IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN
if [ $(ipset list music -name -quiet | grep music) ]; then if ipset list music -name -quiet >/dev/null 2>&1; then
$IPT -I SS_SPEC_WAN_AC -m set --match-set music dst -j RETURN 2>/dev/null $IPT -I SS_SPEC_WAN_AC -m set --match-set music dst -j RETURN 2>/dev/null
fi fi
for ip in $WAN_BP_IP; do ipset -! add whitelist $ip; done for ip in $WAN_BP_IP; do ipset -! add whitelist "$ip"; done
for ip in $WAN_FW_IP; do ipset -! add blacklist $ip; done for ip in $WAN_FW_IP; do ipset -! add blacklist "$ip"; done
if [ "$SHUNT_PORT" != "0" ]; then if [ "$SHUNT_PORT" != "0" ]; then
ipset -N netflix hash:net 2>/dev/null ipset -N netflix hash:net 2>/dev/null
for ip in $(cat ${SHUNT_LIST:=/dev/null} 2>/dev/null); do ipset -! add netflix $ip; done for ip in $(cat "${SHUNT_LIST:=/dev/null}" 2>/dev/null); do ipset -! add netflix "$ip"; done
case "$SHUNT_PORT" in case "$SHUNT_PORT" in
0) ;; 0) ;;
1) 1)
$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $local_port $IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports "$local_port"
;; ;;
*) *)
$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $SHUNT_PORT $IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports "$SHUNT_PORT"
if [ "$SHUNT_PROXY" == "1" ]; then if [ "$SHUNT_PROXY" = "1" ]; then
$IPT -I SS_SPEC_WAN_AC -p tcp -d $SHUNT_IP -j REDIRECT --to-ports $local_port $IPT -I SS_SPEC_WAN_AC -p tcp -d "$SHUNT_IP" -j REDIRECT --to-ports "$local_port"
else else
ipset -! add whitelist $SHUNT_IP ipset -! add whitelist "$SHUNT_IP"
fi fi
;; ;;
esac esac
@@ -312,28 +317,38 @@ fw_rule() {
} }
fw_rule_nft() { fw_rule_nft() {
# Create forward chain for nftables # Create forward chain with better error handling
$NFT add chain inet ss_spec ss_spec_wan_fw if ! $NFT list chain inet ss_spec ss_spec_wan_fw >/dev/null 2>&1; then
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 0.0.0.0/8 return $NFT add chain inet ss_spec ss_spec_wan_fw 2>/dev/null || {
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 10.0.0.0/8 return loger 3 "Failed to create forward chain"
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 127.0.0.0/8 return return 1
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 169.254.0.0/16 return }
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 172.16.0.0/12 return fi
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 192.168.0.0/16 return
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 224.0.0.0/4 return # Exclude special local addresses
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 240.0.0.0/4 return $NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 0.0.0.0/8 return 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 10.0.0.0/8 return 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 127.0.0.0/8 return 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 169.254.0.0/16 return 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 172.16.0.0/12 return 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 192.168.0.0/16 return 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 224.0.0.0/4 return 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 240.0.0.0/4 return 2>/dev/null
# redirect/translation: when PROXY_PORTS present, redirect those tcp ports to local_port
if [ -n "$PROXY_PORTS" ]; then if [ -n "$PROXY_PORTS" ]; then
$NFT add rule inet ss_spec ss_spec_wan_fw tcp $PROXY_PORTS redirect to :$local_port 2>/dev/null || { $NFT add rule inet ss_spec ss_spec_wan_fw tcp dport "$PROXY_PORTS" redirect to :"$local_port" 2>/dev/null || {
loger 3 "Can't redirect, please check nftables." loger 3 "Can't redirect, please check nftables."
exit 1 exit 1
} }
else else
$NFT add rule inet ss_spec ss_spec_wan_fw tcp dport != 22 redirect to :$local_port 2>/dev/null || { # default: redirect everything except ssh(22)
$NFT add rule inet ss_spec ss_spec_wan_fw tcp dport != 22 redirect to :"$local_port" 2>/dev/null || {
loger 3 "Can't redirect, please check nftables." loger 3 "Can't redirect, please check nftables."
exit 1 exit 1
} }
fi fi
return 0 return 0
} }
@@ -347,7 +362,7 @@ fw_rule_iptables() {
$IPT -A SS_SPEC_WAN_FW -d 192.168.0.0/16 -j RETURN $IPT -A SS_SPEC_WAN_FW -d 192.168.0.0/16 -j RETURN
$IPT -A SS_SPEC_WAN_FW -d 224.0.0.0/4 -j RETURN $IPT -A SS_SPEC_WAN_FW -d 224.0.0.0/4 -j RETURN
$IPT -A SS_SPEC_WAN_FW -d 240.0.0.0/4 -j RETURN $IPT -A SS_SPEC_WAN_FW -d 240.0.0.0/4 -j RETURN
$IPT -A SS_SPEC_WAN_FW -p tcp $PROXY_PORTS -j REDIRECT --to-ports $local_port 2>/dev/null || { $IPT -A SS_SPEC_WAN_FW -p tcp $PROXY_PORTS -j REDIRECT --to-ports "$local_port" 2>/dev/null || {
loger 3 "Can't redirect, please check the iptables." loger 3 "Can't redirect, please check the iptables."
exit 1 exit 1
} }
@@ -366,13 +381,13 @@ ac_rule() {
ac_rule_nft() { ac_rule_nft() {
local MATCH_SET_CONDITION="" local MATCH_SET_CONDITION=""
if [ -n "$LAN_AC_IP" ]; then if [ -n "$LAN_AC_IP" ]; then
# Create LAN access control set # Create LAN access control set if needed
$NFT add set inet ss_spec ss_spec_lan_ac { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec ss_spec_lan_ac '{ type ipv4_addr; flags interval; }' 2>/dev/null
for ip in ${LAN_AC_IP:1}; do for ip in ${LAN_AC_IP#?}; do
$NFT add element inet ss_spec ss_spec_lan_ac { $ip } [ -n "$ip" ] && $NFT add element inet ss_spec ss_spec_lan_ac "{ $ip }" 2>/dev/null
done done
case "${LAN_AC_IP:0:1}" in case "${LAN_AC_IP%${LAN_AC_IP#?}}" in
w | W) w | W)
MATCH_SET_CONDITION="ip saddr @ss_spec_lan_ac" MATCH_SET_CONDITION="ip saddr @ss_spec_lan_ac"
;; ;;
@@ -385,23 +400,24 @@ ac_rule_nft() {
;; ;;
esac esac
fi fi
# Create prerouting rules # Build a rule in the prerouting hook chain that jumps to business chain with conditions
if [ -z "$Interface" ]; then if [ -z "$Interface" ]; then
# generic prerouting jump already exists (see ipset_nft), but if we have MATCH_SET_CONDITION we add a more specific rule
if [ -n "$MATCH_SET_CONDITION" ]; then if [ -n "$MATCH_SET_CONDITION" ]; then
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport $EXT_ARGS $MATCH_SET_CONDITION comment "\"$TAG\"" goto ss_spec_wan_ac # add a more specific rule at the top of ss_spec_prerouting
else $NFT insert rule inet ss_spec ss_spec_prerouting tcp $MATCH_SET_CONDITION comment "\"$TAG\"" jump ss_spec_wan_ac 2>/dev/null
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport $EXT_ARGS comment "\"$TAG\"" goto ss_spec_wan_ac
fi fi
else else
# For each Interface, find its actual ifname and add an iifname-limited prerouting rule
for name in $Interface; do for name in $Interface; do
local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null) local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null)
[ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network.$name.device 2>/dev/null) [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null)
if [ -n "$IFNAME" ]; then if [ -n "$IFNAME" ]; then
if [ -n "$MATCH_SET_CONDITION" ]; then if [ -n "$MATCH_SET_CONDITION" ]; then
$NFT add rule inet ss_spec ss_spec_wan_ac iifname $IFNAME tcp dport $EXT_ARGS $MATCH_SET_CONDITION comment "\"$TAG\"" goto ss_spec_wan_ac $NFT insert rule inet ss_spec ss_spec_prerouting iifname "$IFNAME" tcp $MATCH_SET_CONDITION comment "\"$TAG\"" jump ss_spec_wan_ac 2>/dev/null
else else
$NFT add rule inet ss_spec ss_spec_wan_ac iifname $IFNAME tcp dport $EXT_ARGS comment "\"$TAG\"" goto ss_spec_wan_ac $NFT insert rule inet ss_spec ss_spec_prerouting iifname "$IFNAME" tcp comment "\"$TAG\"" jump ss_spec_wan_ac 2>/dev/null
fi fi
fi fi
done done
@@ -409,21 +425,21 @@ ac_rule_nft() {
case "$OUTPUT" in case "$OUTPUT" in
1) 1)
# Add output rules # create output hook chain & route output traffic into router chain
$NFT add chain inet ss_spec ss_spec_output { type nat hook output priority dstnat\; } $NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority dstnat; }' 2>/dev/null
$NFT add rule inet ss_spec ss_spec_output tcp dport $EXT_ARGS comment "\"$TAG\"" goto ss_spec_wan_ac $NFT add rule inet ss_spec ss_spec_output tcp comment "\"$TAG\"" jump ss_spec_wan_ac 2>/dev/null
;; ;;
2) 2)
# Router mode output rules # router mode output chain: create ssr_gen_router set & router chain
$NFT add set inet ss_spec ssr_gen_router { type ipv4_addr\; flags interval\; } 2>/dev/null $NFT add set inet ss_spec ssr_gen_router '{ type ipv4_addr; flags interval; }' 2>/dev/null
for ip in $(gen_spec_iplist); do for ip in $(gen_spec_iplist); do
$NFT add element inet ss_spec ssr_gen_router { $ip } [ -n "$ip" ] && $NFT add element inet ss_spec ssr_gen_router "{ $ip }" 2>/dev/null
done done
$NFT add chain inet ss_spec ss_spec_router $NFT add chain inet ss_spec ss_spec_router 2>/dev/null
$NFT add rule inet ss_spec ss_spec_router ip daddr @ssr_gen_router return $NFT add rule inet ss_spec ss_spec_router ip daddr @ssr_gen_router return 2>/dev/null
$NFT add rule inet ss_spec ss_spec_router goto ss_spec_wan_fw $NFT add rule inet ss_spec ss_spec_router jump ss_spec_wan_fw 2>/dev/null
$NFT add chain inet ss_spec ss_spec_output { type nat hook output priority dstnat\; } $NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority dstnat; }' 2>/dev/null
$NFT add rule inet ss_spec ss_spec_output tcp dport comment "\"$TAG\"" goto ss_spec_router $NFT add rule inet ss_spec ss_spec_output tcp comment "\"$TAG\"" jump ss_spec_router 2>/dev/null
;; ;;
esac esac
return 0 return 0
@@ -431,7 +447,7 @@ ac_rule_nft() {
ac_rule_iptables() { ac_rule_iptables() {
if [ -n "$LAN_AC_IP" ]; then if [ -n "$LAN_AC_IP" ]; then
case "${LAN_AC_IP:0:1}" in case "${LAN_AC_IP%${LAN_AC_IP#?}}" in
w | W) w | W)
MATCH_SET="-m set --match-set ss_spec_lan_ac src" MATCH_SET="-m set --match-set ss_spec_lan_ac src"
;; ;;
@@ -446,14 +462,14 @@ ac_rule_iptables() {
fi fi
ipset -! -R <<-EOF || return 1 ipset -! -R <<-EOF || return 1
create ss_spec_lan_ac hash:net create ss_spec_lan_ac hash:net
$(for ip in ${LAN_AC_IP:1}; do echo "add ss_spec_lan_ac $ip"; done) $(for ip in ${LAN_AC_IP#?}; do echo "add ss_spec_lan_ac $ip"; done)
EOF EOF
if [ -z "$Interface" ]; then if [ -z "$Interface" ]; then
$IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC $IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
else else
for name in $Interface; do for name in $Interface; do
local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null) local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null)
[ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network.$name.device 2>/dev/null) [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null)
[ -n "$IFNAME" ] && $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC [ -n "$IFNAME" ] && $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
done done
fi fi
@@ -487,75 +503,85 @@ tp_rule() {
} }
tp_rule_nft() { tp_rule_nft() {
# Set up routing for TPROXY [ -n "$TPROXY" ] || return 0
ip rule add fwmark 0x01/0x01 table 100
ip route add local 0.0.0.0/0 dev lo table 100 # set up routing table for tproxy
ip rule add fwmark 0x01/0x01 table 100 2>/dev/null
# Create TPROXY chain in mangle table ip route add local 0.0.0.0/0 dev lo table 100 2>/dev/null
# create mangle table and tproxy chain
$NFT add table ip ss_spec_mangle 2>/dev/null $NFT add table ip ss_spec_mangle 2>/dev/null
$NFT add chain ip ss_spec_mangle ss_spec_tproxy { type filter hook prerouting priority mangle\; } # use priority mangle for compatibility with other rules
$NFT add chain ip ss_spec_mangle ss_spec_tproxy '{ type filter hook prerouting priority mangle; }' 2>/dev/null
# Add basic return rules
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport 53 return # basic return rules in tproxy chain
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 0.0.0.0/8 return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport 53 return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 10.0.0.0/8 return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 0.0.0.0/8 return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 127.0.0.0/8 return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 10.0.0.0/8 return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 169.254.0.0/16 return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 127.0.0.0/8 return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 172.16.0.0/12 return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 169.254.0.0/16 return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 192.168.0.0/16 return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 172.16.0.0/12 return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 224.0.0.0/4 return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 192.168.0.0/16 return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 240.0.0.0/4 return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 224.0.0.0/4 return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport != 53 ip daddr $SERVER return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr 240.0.0.0/4 return 2>/dev/null
# Handle different UDP server # avoid redirecting to udp server address - 修正变量名
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport != 53 ip daddr "$server" return 2>/dev/null
# if server != SERVER add SERVER to whitelist set (so tproxy won't touch it)
if [ "$server" != "$SERVER" ]; then if [ "$server" != "$SERVER" ]; then
$NFT add element inet ss_spec whitelist { $SERVER } $NFT add element inet ss_spec whitelist "{ $SERVER }" 2>/dev/null
fi fi
# Access control rules # access control and tproxy rules
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @bplan return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @bplan return 2>/dev/null
if [ -n "$PROXY_PORTS" ]; then if [ -n "$PROXY_PORTS" ]; then
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp $PROXY_PORTS ip saddr @fplan tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport "$PROXY_PORTS" ip saddr @fplan tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
else else
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @fplan tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @fplan tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
fi fi
# Handle different run modes for nftables # Handle different run modes for nftables
case "$RUNMODE" in case "$RUNMODE" in
router) router)
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr @ss_spec_wan_ac return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr @ss_spec_wan_ac return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr @china return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr @china return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport 80 drop $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport 80 drop 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @gmlan ip daddr != @china tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @gmlan ip daddr != @china tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
if [ -n "$PROXY_PORTS" ]; then if [ -n "$PROXY_PORTS" ]; then
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp $PROXY_PORTS ip daddr != @ss_spec_wan_ac tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport "$PROXY_PORTS" ip daddr != @ss_spec_wan_ac tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
else else
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr != @ss_spec_wan_ac tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr != @ss_spec_wan_ac tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
fi fi
;; ;;
gfw) gfw)
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr @china return $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip daddr @china return 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport 80 drop $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport 80 drop 2>/dev/null
if [ -n "$PROXY_PORTS" ]; then if [ -n "$PROXY_PORTS" ]; then
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp $PROXY_PORTS ip daddr @gfwlist tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport "$PROXY_PORTS" ip daddr @gfwlist tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
fi fi
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @gmlan ip daddr != @china tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @gmlan ip daddr != @china tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
;; ;;
oversea) oversea)
if [ -n "$PROXY_PORTS" ]; then if [ -n "$PROXY_PORTS" ]; then
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp $PROXY_PORTS ip saddr @oversea tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport "$PROXY_PORTS" ip saddr @oversea tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp $PROXY_PORTS ip daddr @china tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport "$PROXY_PORTS" ip daddr @china tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
fi fi
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @gmlan tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @gmlan tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
;; ;;
all) all)
if [ -n "$PROXY_PORTS" ]; then if [ -n "$PROXY_PORTS" ]; then
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp $PROXY_PORTS tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport "$PROXY_PORTS" tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
else else
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp tproxy to :$LOCAL_PORT meta mark set 0x01 $NFT add rule ip ss_spec_mangle ss_spec_tproxy udp tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
fi fi
;; ;;
esac esac
# insert jump from ip prerouting to our tproxy chain
$NFT add rule ip ss_spec_mangle prerouting udp comment "\"$TAG\"" jump ss_spec_tproxy 2>/dev/null
return 0
} }
tp_rule_iptables() { tp_rule_iptables() {
@@ -572,8 +598,8 @@ tp_rule_iptables() {
$ipt -A SS_SPEC_TPROXY -p udp -d 192.168.0.0/16 -j RETURN $ipt -A SS_SPEC_TPROXY -p udp -d 192.168.0.0/16 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 224.0.0.0/4 -j RETURN $ipt -A SS_SPEC_TPROXY -p udp -d 224.0.0.0/4 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 240.0.0.0/4 -j RETURN $ipt -A SS_SPEC_TPROXY -p udp -d 240.0.0.0/4 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d $SERVER -j RETURN $ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d "$SERVER" -j RETURN
[ "$server" != "$SERVER" ] && ipset -! add whitelist $SERVER [ "$server" != "$SERVER" ] && ipset -! add whitelist "$SERVER"
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set bplan src -j RETURN $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set bplan src -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
case "$RUNMODE" in case "$RUNMODE" in
@@ -603,8 +629,8 @@ tp_rule_iptables() {
$ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY $ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
else else
for name in $Interface; do for name in $Interface; do
local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null) local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null)
[ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network.$name.device 2>/dev/null) [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null)
[ -n "$IFNAME" ] && $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY [ -n "$IFNAME" ] && $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
done done
fi fi
@@ -653,15 +679,17 @@ gen_include() {
gen_include_nft() { gen_include_nft() {
# Generate nftables include file for firewall4 # Generate nftables include file for firewall4
cat <<-EOF >>$FWI [ -n "$FWI" ] && echo '#!/bin/sh' >"$FWI"
cat <<-'EOF' >>"$FWI"
# Clear existing ss_spec tables # Clear existing ss_spec tables
nft delete table inet ss_spec 2>/dev/null nft delete table inet ss_spec 2>/dev/null
nft delete table ip ss_spec 2>/dev/null nft delete table ip ss_spec 2>/dev/null
nft delete table ip ss_spec_mangle 2>/dev/null nft delete table ip ss_spec_mangle 2>/dev/null
# Restore shadowsocks nftables rules # Restore shadowsocks nftables rules
$(nft list ruleset | grep -A 1000 "table inet ss_spec\|table ip ss_spec") nft list ruleset | awk '/table (inet|ip) ss_spec/{flag=1} flag'
EOF EOF
chmod +x "$FWI"
} }
gen_include_iptables() { gen_include_iptables() {
@@ -709,7 +737,7 @@ while getopts ":m:s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUfgrczh" arg; do
LAN_BP_IP=$OPTARG LAN_BP_IP=$OPTARG
;; ;;
b) b)
WAN_BP_IP=$(for ip in $OPTARG; do echo $ip; done) WAN_BP_IP=$(for ip in $OPTARG; do echo "$ip"; done)
;; ;;
w) w)
WAN_FW_IP=$OPTARG WAN_FW_IP=$OPTARG
@@ -767,10 +795,15 @@ while getopts ":m:s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUfgrczh" arg; do
esac esac
done done
if [ -z "$server" -o -z "$local_port" ]; then if [ -z "$server" ] || [ -z "$local_port" ]; then
usage 2 usage 2
fi fi
if ! echo "$local_port" | grep -qE '^[0-9]+$'; then
loger 3 "Invalid local port: $local_port"
exit 1
fi
case "$TPROXY" in case "$TPROXY" in
1) 1)
SERVER=$server SERVER=$server
@@ -782,7 +815,10 @@ case "$TPROXY" in
;; ;;
esac esac
flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include if flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include; then
RET=$? loger 5 "Rules applied successfully"
[ "$RET" = 0 ] || loger 3 "Start failed!" exit 0
exit $RET else
loger 3 "Start failed!"
exit 1
fi

View File

@@ -331,8 +331,8 @@ end
mux = (server.v2ray_protocol ~= "wireguard") and { mux = (server.v2ray_protocol ~= "wireguard") and {
-- mux -- mux
enabled = (server.mux == "1"), -- Mux enabled = (server.mux == "1"), -- Mux
concurrency = (server.mux == "1" and (tonumber(server.concurrency) or -1)) or nil, -- TCP 最大并发 concurrency = (server.mux == "1" and (tonumber(server.concurrency) or -1)) or nil, -- TCP 最大并发连接数
xudpConcurrency = (server.mux == "1" and (tonumber(server.xudpConcurrency) or 16)) or nil, -- UDP 最大并发 xudpConcurrency = (server.mux == "1" and (tonumber(server.xudpConcurrency) or 16)) or nil, -- UDP 最大并发连接数
xudpProxyUDP443 = (server.mux == "1" and (server.xudpProxyUDP443 or "reject")) or nil -- 对被代理的 UDP/443 流量处理方式 xudpProxyUDP443 = (server.mux == "1" and (server.xudpProxyUDP443 or "reject")) or nil -- 对被代理的 UDP/443 流量处理方式
} or nil } or nil
} }
@@ -631,6 +631,8 @@ local tuic = {
return nil return nil
end end
end)() or nil, end)() or nil,
ipstack_prefer = (server.tuic_dual_stack == "1") and server.ipstack_prefer or nil,
skip_cert_verify = (server.insecure == "1" or server.insecure == true or server.insecure == "true"),
disable_sni = (server.disable_sni == "1") and true or false, disable_sni = (server.disable_sni == "1") and true or false,
zero_rtt_handshake = (server.zero_rtt_handshake == "1") and true or false, zero_rtt_handshake = (server.zero_rtt_handshake == "1") and true or false,
send_window = tonumber(server.send_window), send_window = tonumber(server.send_window),
@@ -715,3 +717,4 @@ function config:handleIndex(index)
end end
local f = config:new() local f = config:new()
f:handleIndex(server.type) f:handleIndex(server.type)

View File

@@ -27,7 +27,7 @@ config server_subscribe
option auto_update_day_time '2' option auto_update_day_time '2'
option auto_update_min_time '0' option auto_update_min_time '0'
option user_agent 'v2rayN/9.99' option user_agent 'v2rayN/9.99'
option filter_words '过期时间/剩余流量/QQ群/官网/防失联地址/回国' option filter_words '过期/套餐/剩余/QQ群/官网/防失联/回国'
config access_control config access_control
option lan_ac_mode '0' option lan_ac_mode '0'

File diff suppressed because it is too large Load Diff