💐 Sync 2025-11-05 00:13:10
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
|
||||
[ $(uname -m) = "x86_64" ] && alias board_name="echo x86_64"
|
||||
|
||||
# OTA
|
||||
OTA_URL="https://api.kejizero.xyz/openwrt/ota.json"
|
||||
|
||||
# theme
|
||||
if [ -d "/www/luci-static/argon" ] && [ -z "$(uci -q get luci.main.pollinterval)" ]; then
|
||||
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 "\$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
|
||||
;;
|
||||
x86_64)
|
||||
[ $(uname -r | awk -F. '{print $1}') = 6 ] && {
|
||||
[ -f /sys/kernel/btf/vmlinux ] && [ ! -d "/usr/share/openwrt_core" ] && {
|
||||
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
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -10,7 +10,7 @@ LUCI_DEPENDS:=+luci-base +luci-lib-jsonc +curl +bandix
|
||||
|
||||
PKG_MAINTAINER:=timsaya
|
||||
|
||||
PKG_VERSION:=0.6.2
|
||||
PKG_VERSION:=0.6.3
|
||||
PKG_RELEASE:=1
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
@@ -371,7 +371,7 @@ return view.extend({
|
||||
var style = E('style', {}, `
|
||||
.bandix-connection-container {
|
||||
margin: 0;
|
||||
padding: 24px;
|
||||
padding: 8px;
|
||||
background-color: ${darkMode ? '#1E1E1E' : '#f8fafc'};
|
||||
min-height: calc(100vh - 100px);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
|
||||
@@ -25,6 +25,7 @@ const translations = {
|
||||
'界面语言': '界面语言',
|
||||
'选择 Bandix 流量监控的显示语言': '选择 Bandix 流量监控的显示语言',
|
||||
'设备信息': '设备信息',
|
||||
'设备列表': '设备列表',
|
||||
'LAN 流量': 'LAN 流量',
|
||||
'WAN 流量': 'WAN 流量',
|
||||
'限速设置': '限速设置',
|
||||
@@ -103,7 +104,9 @@ const translations = {
|
||||
'升序': '升序',
|
||||
'降序': '降序',
|
||||
'按速度排序': '按速度排序',
|
||||
'按用量排序': '按用量排序'
|
||||
'按用量排序': '按用量排序',
|
||||
'简易模式': '简易模式',
|
||||
'详细模式': '详细模式'
|
||||
},
|
||||
'zh-tw': {
|
||||
'Bandix 流量监控': 'Bandix 流量監控',
|
||||
@@ -122,6 +125,7 @@ const translations = {
|
||||
'界面语言': '介面語言',
|
||||
'选择 Bandix 流量监控的显示语言': '選擇 Bandix 流量監控的顯示語言',
|
||||
'设备信息': '設備資訊',
|
||||
'设备列表': '設備列表',
|
||||
'LAN 流量': '局域網流量',
|
||||
'WAN 流量': '跨網路流量',
|
||||
'限速设置': '限速設定',
|
||||
@@ -200,7 +204,9 @@ const translations = {
|
||||
'升序': '升序',
|
||||
'降序': '降序',
|
||||
'按速度排序': '按速度排序',
|
||||
'按用量排序': '按用量排序'
|
||||
'按用量排序': '按用量排序',
|
||||
'简易模式': '簡易模式',
|
||||
'详细模式': '詳細模式'
|
||||
},
|
||||
'en': {
|
||||
'Bandix 流量监控': 'Bandix Traffic Monitor',
|
||||
@@ -219,6 +225,7 @@ const translations = {
|
||||
'界面语言': 'Interface Language',
|
||||
'选择 Bandix 流量监控的显示语言': 'Select the display language for Bandix Traffic Monitor',
|
||||
'设备信息': 'Device Info',
|
||||
'设备列表': 'Device List',
|
||||
'LAN 流量': 'LAN Traffic',
|
||||
'WAN 流量': 'WAN Traffic',
|
||||
'限速设置': 'Rate Limit',
|
||||
@@ -297,7 +304,9 @@ const translations = {
|
||||
'升序': 'Ascending',
|
||||
'降序': 'Descending',
|
||||
'按速度排序': 'Sort by Speed',
|
||||
'按用量排序': 'Sort by Traffic'
|
||||
'按用量排序': 'Sort by Traffic',
|
||||
'简易模式': 'Simple Mode',
|
||||
'详细模式': 'Detailed Mode'
|
||||
},
|
||||
'fr': {
|
||||
'Bandix 流量监控': 'Moniteur de Trafic Bandix',
|
||||
@@ -316,6 +325,7 @@ const translations = {
|
||||
'界面语言': 'Langue de l\'interface',
|
||||
'选择 Bandix 流量监控的显示语言': 'Sélectionner la langue d\'affichage pour le Moniteur de Trafic Bandix',
|
||||
'设备信息': 'Informations sur l\'appareil',
|
||||
'设备列表': 'Liste des appareils',
|
||||
'LAN 流量': 'Trafic LAN',
|
||||
'WAN 流量': 'Trafic WAN',
|
||||
'限速设置': 'Limitation de débit',
|
||||
@@ -389,7 +399,9 @@ const translations = {
|
||||
'升序': 'Croissant',
|
||||
'降序': 'Décroissant',
|
||||
'按速度排序': 'Trier par vitesse',
|
||||
'按用量排序': 'Trier par volume'
|
||||
'按用量排序': 'Trier par volume',
|
||||
'简易模式': 'Mode simple',
|
||||
'详细模式': 'Mode détaillé'
|
||||
},
|
||||
'ja': {
|
||||
'Bandix 流量监控': 'Bandix トラフィックモニター',
|
||||
@@ -408,6 +420,7 @@ const translations = {
|
||||
'界面语言': 'インターフェース言語',
|
||||
'选择 Bandix 流量监控的显示语言': 'Bandix トラフィックモニターの表示言語を選択',
|
||||
'设备信息': 'デバイス情報',
|
||||
'设备列表': 'デバイスリスト',
|
||||
'LAN 流量': 'LAN トラフィック',
|
||||
'WAN 流量': 'WAN トラフィック',
|
||||
'限速设置': '速度制限',
|
||||
@@ -481,7 +494,9 @@ const translations = {
|
||||
'升序': '昇順',
|
||||
'降序': '降順',
|
||||
'按速度排序': '速度順',
|
||||
'按用量排序': '使用量順'
|
||||
'按用量排序': '使用量順',
|
||||
'简易模式': 'シンプルモード',
|
||||
'详细模式': '詳細モード'
|
||||
},
|
||||
'ru': {
|
||||
'Bandix 流量监控': 'Монитор Трафика Bandix',
|
||||
@@ -500,6 +515,7 @@ const translations = {
|
||||
'界面语言': 'Язык интерфейса',
|
||||
'选择 Bandix 流量监控的显示语言': 'Выберите язык отображения для Монитора Трафика Bandix',
|
||||
'设备信息': 'Информация об устройстве',
|
||||
'设备列表': 'Список устройств',
|
||||
'LAN 流量': 'Трафик LAN',
|
||||
'WAN 流量': 'Трафик WAN',
|
||||
'限速设置': 'Ограничение скорости',
|
||||
@@ -573,7 +589,9 @@ const translations = {
|
||||
'升序': 'По возрастанию',
|
||||
'降序': 'По убыванию',
|
||||
'按速度排序': 'По скорости',
|
||||
'按用量排序': 'По объёму'
|
||||
'按用量排序': 'По объёму',
|
||||
'简易模式': 'Простой режим',
|
||||
'详细模式': 'Подробный режим'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -781,7 +799,7 @@ return view.extend({
|
||||
// 添加现代化样式,支持暗黑模式
|
||||
var style = E('style', {}, `
|
||||
.bandix-container {
|
||||
padding: 24px;
|
||||
padding: 8px;
|
||||
background-color: ${darkMode ? '#1E1E1E' : '#f8fafc'};
|
||||
min-height: 100vh;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
@@ -802,6 +820,48 @@ return view.extend({
|
||||
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 {
|
||||
background-color: ${darkMode ? '#333333' : '#f3f4f6'};
|
||||
border: 1px solid ${darkMode ? '#252526' : '#d1d5db'};
|
||||
@@ -833,7 +893,7 @@ return view.extend({
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, ${darkMode ? '0.3' : '0.1'});
|
||||
overflow: hidden;
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid ${darkMode ? '#252526' : '#3333331c'};
|
||||
}
|
||||
|
||||
@@ -861,7 +921,7 @@ return view.extend({
|
||||
|
||||
.bandix-table th {
|
||||
background-color: ${darkMode ? '#333333' : '#f9fafb'};
|
||||
padding: 16px 20px;
|
||||
padding: 6px 12px;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
color: ${darkMode ? '#e2e8f0' : '#374151'};
|
||||
@@ -940,7 +1000,7 @@ return view.extend({
|
||||
}
|
||||
|
||||
.bandix-table td {
|
||||
padding: 16px 20px;
|
||||
padding: 6px 12px;
|
||||
border: none;
|
||||
vertical-align: middle;
|
||||
word-wrap: break-word;
|
||||
@@ -981,7 +1041,7 @@ return view.extend({
|
||||
.device-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.device-name {
|
||||
@@ -1026,7 +1086,7 @@ return view.extend({
|
||||
.traffic-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.traffic-row {
|
||||
@@ -1107,7 +1167,7 @@ return view.extend({
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
@@ -1506,6 +1566,21 @@ return view.extend({
|
||||
|
||||
// 主要内容卡片
|
||||
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('table', { 'class': 'bandix-table' }, [
|
||||
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' }, [
|
||||
E('div', { 'class': 'modal' }, [
|
||||
@@ -3028,6 +3129,10 @@ function formatRetentionSeconds(seconds, language) {
|
||||
showRateLimitModal(device);
|
||||
});
|
||||
|
||||
// 获取当前显示模式
|
||||
var deviceMode = localStorage.getItem('bandix_device_mode') || 'simple';
|
||||
var isDetailedMode = deviceMode === 'detailed';
|
||||
|
||||
// 构建设备信息元素
|
||||
var deviceInfoElements = [
|
||||
E('div', { 'class': 'device-name' }, [
|
||||
@@ -3039,6 +3144,8 @@ function formatRetentionSeconds(seconds, language) {
|
||||
E('div', { 'class': 'device-ip' }, device.ip)
|
||||
];
|
||||
|
||||
// 详细模式下显示更多信息
|
||||
if (isDetailedMode) {
|
||||
// 只有当有设备有 IPv6 时才添加 IPv6 行
|
||||
if (hasAnyIPv6) {
|
||||
var lanIPv6 = filterLanIPv6(device.ipv6_addresses);
|
||||
@@ -3061,6 +3168,7 @@ function formatRetentionSeconds(seconds, language) {
|
||||
E('span', { 'style': 'color: #9ca3af; font-size: 0.75rem;' }, formatLastOnlineTime(device.last_online_ts, language))
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
var row = E('tr', {}, [
|
||||
// 设备信息
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=25.9.23
|
||||
PKG_VERSION:=25.11.1
|
||||
PKG_RELEASE:=1
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
|
||||
@@ -3,7 +3,26 @@ local appname = "passwall"
|
||||
local datatypes = api.datatypes
|
||||
|
||||
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)
|
||||
local nbsp = string.char(0xC2, 0xA0) -- 不间断空格(U+00A0)
|
||||
@@ -30,10 +49,14 @@ protocol = s:option(MultiValue, "protocol", translate("Protocol"))
|
||||
protocol:value("http")
|
||||
protocol:value("tls")
|
||||
protocol:value("bittorrent")
|
||||
protocol.widget = "checkbox"
|
||||
protocol.default = nil
|
||||
|
||||
o = s:option(MultiValue, "inbound", translate("Inbound Tag"))
|
||||
o:value("tproxy", translate("Transparent proxy"))
|
||||
o:value("socks", "Socks")
|
||||
o.widget = "checkbox"
|
||||
o.default = nil
|
||||
|
||||
network = s:option(ListValue, "network", translate("Network"))
|
||||
network:value("tcp,udp", "TCP UDP")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -74,14 +74,14 @@
|
||||
101.237.40.0/24
|
||||
101.240.0.0/14
|
||||
101.245.0.0/22
|
||||
101.245.12.0/22
|
||||
101.245.128.0/22
|
||||
101.245.136.0/22
|
||||
101.245.128.0/20
|
||||
101.245.144.0/22
|
||||
101.245.152.0/21
|
||||
101.245.16.0/21
|
||||
101.245.160.0/20
|
||||
101.245.32.0/19
|
||||
101.245.64.0/18
|
||||
101.245.8.0/23
|
||||
101.245.8.0/21
|
||||
101.246.172.0/22
|
||||
101.246.176.0/20
|
||||
101.247.0.0/18
|
||||
@@ -184,7 +184,8 @@
|
||||
103.116.120.0/23
|
||||
103.116.123.0/24
|
||||
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.117.16.0/22
|
||||
103.117.220.0/22
|
||||
@@ -226,7 +227,9 @@
|
||||
103.134.136.0/22
|
||||
103.135.100.0/24
|
||||
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.137.60.0/24
|
||||
103.138.156.0/23
|
||||
@@ -271,10 +274,8 @@
|
||||
103.151.179.0/24
|
||||
103.151.216.0/23
|
||||
103.151.228.0/23
|
||||
103.151.5.0/24
|
||||
103.152.170.0/23
|
||||
103.152.186.0/23
|
||||
103.152.190.0/23
|
||||
103.152.224.0/24
|
||||
103.152.28.0/23
|
||||
103.152.56.0/23
|
||||
@@ -286,12 +287,10 @@
|
||||
103.154.30.0/23
|
||||
103.154.41.0/24
|
||||
103.155.110.0/23
|
||||
103.155.120.0/23
|
||||
103.155.76.0/23
|
||||
103.156.174.0/23
|
||||
103.156.186.0/23
|
||||
103.156.68.0/23
|
||||
103.157.138.0/23
|
||||
103.158.0.0/23
|
||||
103.159.124.0/23
|
||||
103.16.124.0/22
|
||||
@@ -318,7 +317,6 @@
|
||||
103.177.28.0/23
|
||||
103.179.78.0/23
|
||||
103.180.108.0/23
|
||||
103.181.164.0/23
|
||||
103.181.234.0/24
|
||||
103.183.122.0/23
|
||||
103.183.124.0/23
|
||||
@@ -352,7 +350,7 @@
|
||||
103.197.0.0/22
|
||||
103.197.228.0/22
|
||||
103.198.124.0/22
|
||||
103.198.180.0/22
|
||||
103.198.180.0/23
|
||||
103.198.216.0/21
|
||||
103.198.224.0/20
|
||||
103.198.244.0/22
|
||||
@@ -377,7 +375,8 @@
|
||||
103.202.96.0/20
|
||||
103.203.140.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.204.72.0/22
|
||||
103.205.188.0/22
|
||||
@@ -393,7 +392,7 @@
|
||||
103.21.140.0/22
|
||||
103.21.176.0/22
|
||||
103.210.160.0/22
|
||||
103.210.171.0/24
|
||||
103.210.170.0/23
|
||||
103.211.220.0/22
|
||||
103.211.44.0/22
|
||||
103.212.1.0/24
|
||||
@@ -404,9 +403,8 @@
|
||||
103.212.48.0/23
|
||||
103.213.132.0/22
|
||||
103.213.160.0/19
|
||||
103.213.48.0/23
|
||||
103.213.50.0/24
|
||||
103.213.62.0/23
|
||||
103.213.48.0/21
|
||||
103.213.60.0/22
|
||||
103.213.64.0/19
|
||||
103.213.96.0/22
|
||||
103.214.48.0/22
|
||||
@@ -474,7 +472,6 @@
|
||||
103.232.144.0/22
|
||||
103.232.166.0/23
|
||||
103.233.128.0/22
|
||||
103.233.136.0/23
|
||||
103.233.138.0/24
|
||||
103.233.162.0/23
|
||||
103.233.4.0/22
|
||||
@@ -503,7 +500,6 @@
|
||||
103.237.28.0/23
|
||||
103.237.8.0/22
|
||||
103.238.0.0/21
|
||||
103.238.130.0/24
|
||||
103.238.132.0/22
|
||||
103.238.144.0/22
|
||||
103.238.16.0/22
|
||||
@@ -517,7 +513,6 @@
|
||||
103.238.98.0/24
|
||||
103.239.152.0/22
|
||||
103.239.184.0/23
|
||||
103.239.187.0/24
|
||||
103.239.192.0/22
|
||||
103.239.204.0/22
|
||||
103.239.224.0/22
|
||||
@@ -536,12 +531,9 @@
|
||||
103.242.130.0/24
|
||||
103.242.168.0/23
|
||||
103.242.172.0/22
|
||||
103.242.200.0/24
|
||||
103.242.202.0/24
|
||||
103.242.212.0/22
|
||||
103.243.136.0/22
|
||||
103.243.252.0/22
|
||||
103.244.164.0/22
|
||||
103.244.232.0/22
|
||||
103.244.59.0/24
|
||||
103.244.64.0/22
|
||||
@@ -568,7 +560,7 @@
|
||||
103.250.32.0/22
|
||||
103.251.124.0/22
|
||||
103.251.160.0/22
|
||||
103.251.204.0/23
|
||||
103.251.204.0/24
|
||||
103.251.207.0/24
|
||||
103.251.240.0/22
|
||||
103.251.32.0/22
|
||||
@@ -638,7 +630,7 @@
|
||||
103.38.232.0/22
|
||||
103.38.252.0/23
|
||||
103.38.40.0/22
|
||||
103.38.76.0/24
|
||||
103.38.76.0/22
|
||||
103.38.84.0/22
|
||||
103.38.92.0/23
|
||||
103.39.200.0/21
|
||||
@@ -672,7 +664,9 @@
|
||||
103.44.240.0/20
|
||||
103.44.56.0/22
|
||||
103.44.80.0/22
|
||||
103.45.128.0/19
|
||||
103.45.160.0/22
|
||||
103.45.168.0/24
|
||||
103.45.172.0/22
|
||||
103.45.176.0/20
|
||||
103.45.248.0/22
|
||||
@@ -692,7 +686,6 @@
|
||||
103.49.196.0/24
|
||||
103.49.198.0/23
|
||||
103.5.192.0/22
|
||||
103.50.38.0/24
|
||||
103.51.62.0/23
|
||||
103.52.100.0/22
|
||||
103.52.104.0/23
|
||||
@@ -709,7 +702,6 @@
|
||||
103.56.104.0/22
|
||||
103.56.152.0/22
|
||||
103.56.184.0/22
|
||||
103.56.32.0/22
|
||||
103.56.60.0/22
|
||||
103.56.76.0/22
|
||||
103.57.12.0/22
|
||||
@@ -719,8 +711,8 @@
|
||||
103.59.124.0/22
|
||||
103.59.148.0/22
|
||||
103.59.164.0/22
|
||||
103.59.168.0/23
|
||||
103.6.220.0/22
|
||||
103.6.228.0/24
|
||||
103.60.164.0/22
|
||||
103.60.228.0/23
|
||||
103.60.236.0/22
|
||||
@@ -753,6 +745,7 @@
|
||||
103.72.113.0/24
|
||||
103.72.120.0/22
|
||||
103.72.172.0/24
|
||||
103.72.224.0/24
|
||||
103.73.116.0/22
|
||||
103.73.136.0/21
|
||||
103.73.144.0/22
|
||||
@@ -774,7 +767,6 @@
|
||||
103.78.126.0/23
|
||||
103.78.228.0/22
|
||||
103.78.60.0/22
|
||||
103.79.120.0/22
|
||||
103.79.200.0/22
|
||||
103.79.228.0/24
|
||||
103.79.24.0/22
|
||||
@@ -1026,6 +1018,7 @@
|
||||
111.222.0.0/16
|
||||
111.223.12.0/22
|
||||
111.224.0.0/14
|
||||
111.228.0.0/18
|
||||
111.229.0.0/16
|
||||
111.230.0.0/15
|
||||
111.235.156.0/22
|
||||
@@ -1096,11 +1089,7 @@
|
||||
113.45.128.0/17
|
||||
113.45.64.0/19
|
||||
113.45.96.0/22
|
||||
113.46.0.0/17
|
||||
113.46.128.0/18
|
||||
113.46.192.0/19
|
||||
113.46.224.0/20
|
||||
113.46.240.0/21
|
||||
113.46.0.0/16
|
||||
113.47.0.0/18
|
||||
113.47.104.0/22
|
||||
113.47.110.0/24
|
||||
@@ -1174,6 +1163,7 @@
|
||||
114.135.0.0/16
|
||||
114.138.0.0/15
|
||||
114.141.128.0/18
|
||||
114.142.136.0/23
|
||||
114.196.0.0/15
|
||||
114.212.0.0/14
|
||||
114.216.0.0/13
|
||||
@@ -1221,15 +1211,18 @@
|
||||
115.175.0.0/18
|
||||
115.175.104.0/22
|
||||
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.192.0/19
|
||||
115.175.224.0/20
|
||||
115.175.252.0/22
|
||||
115.175.64.0/19
|
||||
115.175.96.0/21
|
||||
115.182.0.0/15
|
||||
115.190.0.0/17
|
||||
115.190.128.0/18
|
||||
115.190.192.0/20
|
||||
115.190.0.0/16
|
||||
115.191.0.0/18
|
||||
115.191.64.0/20
|
||||
115.192.0.0/11
|
||||
115.224.0.0/12
|
||||
115.24.0.0/14
|
||||
@@ -1238,7 +1231,7 @@
|
||||
115.32.0.0/19
|
||||
115.32.32.0/21
|
||||
115.32.56.0/21
|
||||
115.32.64.0/20
|
||||
115.32.64.0/19
|
||||
115.44.0.0/14
|
||||
115.48.0.0/12
|
||||
115.84.0.0/18
|
||||
@@ -1305,6 +1298,7 @@
|
||||
116.205.0.0/16
|
||||
116.207.0.0/16
|
||||
116.208.0.0/14
|
||||
116.213.45.0/24
|
||||
116.214.128.0/22
|
||||
116.214.132.0/23
|
||||
116.214.134.0/24
|
||||
@@ -1326,6 +1320,7 @@
|
||||
116.66.36.0/24
|
||||
116.66.48.0/23
|
||||
116.66.53.0/24
|
||||
116.66.54.0/23
|
||||
116.66.98.0/24
|
||||
116.68.136.0/21
|
||||
116.68.176.0/21
|
||||
@@ -1385,6 +1380,8 @@
|
||||
117.72.16.0/23
|
||||
117.72.160.0/19
|
||||
117.72.192.0/19
|
||||
117.72.24.0/21
|
||||
117.72.240.0/21
|
||||
117.72.248.0/22
|
||||
117.72.255.0/24
|
||||
117.72.32.0/19
|
||||
@@ -1416,16 +1413,16 @@
|
||||
118.126.32.0/19
|
||||
118.126.64.0/18
|
||||
118.132.0.0/14
|
||||
118.143.198.0/23
|
||||
118.143.215.0/24
|
||||
118.144.0.0/16
|
||||
118.145.0.0/19
|
||||
118.145.112.0/21
|
||||
118.145.128.0/19
|
||||
118.145.160.0/21
|
||||
118.145.176.0/20
|
||||
118.145.192.0/18
|
||||
118.145.32.0/20
|
||||
118.145.64.0/19
|
||||
118.145.96.0/20
|
||||
118.178.0.0/16
|
||||
118.180.0.0/14
|
||||
118.184.0.0/22
|
||||
@@ -1497,8 +1494,8 @@
|
||||
118.194.240.0/21
|
||||
118.194.32.0/19
|
||||
118.195.0.0/16
|
||||
118.196.0.0/18
|
||||
118.196.64.0/19
|
||||
118.196.0.0/17
|
||||
118.196.128.0/19
|
||||
118.199.0.0/16
|
||||
118.202.0.0/15
|
||||
118.212.0.0/15
|
||||
@@ -1573,7 +1570,6 @@
|
||||
119.18.226.0/24
|
||||
119.18.234.0/24
|
||||
119.18.236.0/23
|
||||
119.18.239.0/24
|
||||
119.2.128.0/17
|
||||
119.23.0.0/16
|
||||
119.233.128.0/17
|
||||
@@ -1609,7 +1605,6 @@
|
||||
119.37.192.0/21
|
||||
119.37.2.0/24
|
||||
119.38.0.0/21
|
||||
119.38.128.0/18
|
||||
119.38.192.0/19
|
||||
119.39.0.0/16
|
||||
119.4.0.0/14
|
||||
@@ -1711,7 +1706,10 @@
|
||||
120.136.20.0/22
|
||||
120.192.0.0/10
|
||||
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.48.0.0/16
|
||||
120.49.0.0/17
|
||||
@@ -1927,18 +1925,15 @@
|
||||
123.4.0.0/14
|
||||
123.49.192.0/23
|
||||
123.49.194.0/24
|
||||
123.49.196.0/24
|
||||
123.49.229.0/24
|
||||
123.49.232.0/24
|
||||
123.49.240.0/22
|
||||
123.49.244.0/24
|
||||
123.49.246.0/23
|
||||
123.49.240.0/21
|
||||
123.52.0.0/14
|
||||
123.56.0.0/15
|
||||
123.58.0.0/19
|
||||
123.58.160.0/20
|
||||
123.58.179.0/24
|
||||
123.58.180.0/22
|
||||
123.58.180.0/24
|
||||
123.58.182.0/23
|
||||
123.58.184.0/24
|
||||
123.58.186.0/23
|
||||
123.58.188.0/22
|
||||
@@ -2006,9 +2001,10 @@
|
||||
124.196.56.0/23
|
||||
124.196.58.0/24
|
||||
124.196.66.0/24
|
||||
124.196.72.0/24
|
||||
124.196.77.0/24
|
||||
124.196.80.0/22
|
||||
124.196.84.0/24
|
||||
124.196.84.0/23
|
||||
124.200.0.0/16
|
||||
124.202.0.0/16
|
||||
124.203.176.0/20
|
||||
@@ -2034,7 +2030,6 @@
|
||||
124.64.0.0/15
|
||||
124.66.0.0/17
|
||||
124.67.0.0/16
|
||||
124.68.252.0/23
|
||||
124.70.0.0/16
|
||||
124.71.0.0/17
|
||||
124.71.128.0/18
|
||||
@@ -2152,7 +2147,6 @@
|
||||
140.75.0.0/16
|
||||
143.14.49.0/24
|
||||
143.20.147.0/24
|
||||
143.20.66.0/24
|
||||
143.64.0.0/16
|
||||
144.0.0.0/16
|
||||
144.12.0.0/16
|
||||
@@ -2168,7 +2162,6 @@
|
||||
144.7.0.0/17
|
||||
145.14.71.0/24
|
||||
145.14.72.0/22
|
||||
145.14.79.0/24
|
||||
145.14.81.0/24
|
||||
145.14.82.0/24
|
||||
145.14.84.0/24
|
||||
@@ -2203,7 +2196,6 @@
|
||||
150.242.80.0/22
|
||||
150.242.96.0/22
|
||||
150.255.0.0/16
|
||||
151.241.174.0/24
|
||||
152.104.128.0/17
|
||||
152.136.0.0/16
|
||||
153.0.0.0/16
|
||||
@@ -2218,12 +2210,8 @@
|
||||
154.208.144.0/20
|
||||
154.208.160.0/21
|
||||
154.208.172.0/23
|
||||
154.213.4.0/23
|
||||
154.218.6.0/23
|
||||
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.72.42.0/24
|
||||
154.72.44.0/24
|
||||
@@ -2271,7 +2259,6 @@
|
||||
16.2.142.0/23
|
||||
160.19.208.0/22
|
||||
160.19.76.0/23
|
||||
160.19.82.0/24
|
||||
160.191.0.0/24
|
||||
160.20.18.0/23
|
||||
160.202.152.0/22
|
||||
@@ -2300,7 +2287,6 @@
|
||||
163.177.0.0/16
|
||||
163.179.0.0/16
|
||||
163.204.0.0/16
|
||||
163.223.173.0/24
|
||||
163.223.178.0/23
|
||||
163.228.0.0/16
|
||||
163.244.246.0/24
|
||||
@@ -2311,7 +2297,9 @@
|
||||
163.53.60.0/22
|
||||
163.53.88.0/21
|
||||
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
|
||||
167.139.0.0/16
|
||||
167.148.46.0/24
|
||||
@@ -2483,7 +2471,6 @@
|
||||
192.144.128.0/17
|
||||
192.163.11.0/24
|
||||
192.232.97.0/24
|
||||
192.55.46.0/24
|
||||
193.112.0.0/16
|
||||
193.119.10.0/23
|
||||
193.119.12.0/23
|
||||
@@ -2498,13 +2485,11 @@
|
||||
193.119.4.0/24
|
||||
193.119.6.0/24
|
||||
193.119.8.0/24
|
||||
194.119.13.0/24
|
||||
194.119.15.0/24
|
||||
193.233.49.0/24
|
||||
194.127.229.0/24
|
||||
194.138.202.0/23
|
||||
194.138.245.0/24
|
||||
194.15.39.0/24
|
||||
195.114.203.0/24
|
||||
198.208.112.0/23
|
||||
198.208.17.0/24
|
||||
198.208.19.0/24
|
||||
@@ -2580,9 +2565,11 @@
|
||||
202.179.240.0/20
|
||||
202.181.120.0/21
|
||||
202.181.28.0/24
|
||||
202.189.16.0/21
|
||||
202.189.16.0/20
|
||||
202.189.3.0/24
|
||||
202.189.32.0/20
|
||||
202.189.4.0/22
|
||||
202.189.48.0/22
|
||||
202.189.8.0/21
|
||||
202.192.0.0/12
|
||||
202.38.128.0/23
|
||||
@@ -2645,8 +2632,6 @@
|
||||
202.91.224.0/20
|
||||
202.91.240.0/21
|
||||
202.91.248.0/22
|
||||
202.91.36.0/24
|
||||
202.91.38.0/24
|
||||
202.93.252.0/22
|
||||
202.95.0.0/19
|
||||
202.96.0.0/13
|
||||
@@ -2689,7 +2674,6 @@
|
||||
203.12.204.0/23
|
||||
203.12.91.0/24
|
||||
203.12.93.0/24
|
||||
203.12.95.0/24
|
||||
203.129.10.0/23
|
||||
203.129.12.0/22
|
||||
203.129.8.0/24
|
||||
@@ -2723,9 +2707,12 @@
|
||||
203.166.188.0/23
|
||||
203.166.191.0/24
|
||||
203.168.0.0/22
|
||||
203.168.129.0/24
|
||||
203.168.16.0/23
|
||||
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.174.4.0/24
|
||||
203.174.7.0/24
|
||||
@@ -2781,7 +2768,6 @@
|
||||
203.215.236.0/24
|
||||
203.223.21.0/24
|
||||
203.25.208.0/20
|
||||
203.25.48.0/24
|
||||
203.25.52.0/24
|
||||
203.3.112.0/21
|
||||
203.3.80.0/21
|
||||
@@ -2961,8 +2947,6 @@
|
||||
203.99.20.0/22
|
||||
203.99.24.0/21
|
||||
204.13.175.0/24
|
||||
207.226.153.0/24
|
||||
207.226.154.0/24
|
||||
210.12.0.0/16
|
||||
210.13.0.0/17
|
||||
210.13.192.0/19
|
||||
@@ -3244,12 +3228,17 @@
|
||||
218.240.128.0/19
|
||||
218.240.160.0/21
|
||||
218.240.168.0/24
|
||||
218.240.176.0/21
|
||||
218.240.184.0/24
|
||||
218.240.176.0/20
|
||||
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.16.0/21
|
||||
218.241.24.0/22
|
||||
218.241.96.0/19
|
||||
218.241.96.0/20
|
||||
218.242.0.0/16
|
||||
218.244.0.0/19
|
||||
218.244.128.0/18
|
||||
@@ -3322,7 +3311,8 @@
|
||||
219.234.80.0/20
|
||||
219.234.96.0/19
|
||||
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.207.0/24
|
||||
219.235.224.0/22
|
||||
@@ -3362,6 +3352,7 @@
|
||||
220.152.128.0/17
|
||||
220.154.0.0/20
|
||||
220.154.128.0/22
|
||||
220.154.132.0/23
|
||||
220.154.140.0/24
|
||||
220.154.144.0/24
|
||||
220.154.16.0/22
|
||||
@@ -3481,7 +3472,6 @@
|
||||
222.59.252.0/22
|
||||
222.64.0.0/11
|
||||
223.0.1.0/24
|
||||
223.0.10.0/24
|
||||
223.0.12.0/23
|
||||
223.0.126.0/24
|
||||
223.0.15.0/24
|
||||
@@ -3489,7 +3479,7 @@
|
||||
223.0.2.0/24
|
||||
223.0.30.0/24
|
||||
223.0.40.0/23
|
||||
223.0.8.0/23
|
||||
223.0.8.0/22
|
||||
223.128.0.0/15
|
||||
223.144.0.0/12
|
||||
223.160.0.0/20
|
||||
@@ -3549,6 +3539,7 @@
|
||||
223.4.0.0/14
|
||||
223.64.0.0/10
|
||||
223.8.0.0/13
|
||||
23.133.188.0/24
|
||||
23.161.8.0/24
|
||||
23.236.111.0/24
|
||||
27.0.128.0/24
|
||||
@@ -3574,6 +3565,7 @@
|
||||
27.50.128.0/17
|
||||
27.8.0.0/13
|
||||
27.98.224.0/19
|
||||
27.99.128.0/17
|
||||
31.56.66.0/24
|
||||
31.57.10.0/24
|
||||
31.57.248.0/24
|
||||
@@ -3626,6 +3618,7 @@
|
||||
40.126.64.0/18
|
||||
40.162.0.0/16
|
||||
40.72.0.0/15
|
||||
42.0.128.0/17
|
||||
42.100.0.0/14
|
||||
42.120.0.0/15
|
||||
42.122.0.0/16
|
||||
@@ -3696,7 +3689,6 @@
|
||||
43.195.0.0/20
|
||||
43.196.0.0/16
|
||||
43.224.12.0/22
|
||||
43.224.23.0/24
|
||||
43.224.24.0/22
|
||||
43.224.240.0/24
|
||||
43.224.52.0/23
|
||||
@@ -3714,8 +3706,13 @@
|
||||
43.226.128.0/19
|
||||
43.226.164.0/22
|
||||
43.226.236.0/22
|
||||
43.226.32.0/19
|
||||
43.226.64.0/20
|
||||
43.226.32.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.140.0/22
|
||||
43.227.152.0/21
|
||||
@@ -3724,7 +3721,10 @@
|
||||
43.227.192.0/19
|
||||
43.227.252.0/22
|
||||
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.116.0/22
|
||||
43.228.204.0/22
|
||||
@@ -3761,7 +3761,7 @@
|
||||
43.240.200.0/23
|
||||
43.240.202.0/24
|
||||
43.240.204.0/22
|
||||
43.240.220.0/22
|
||||
43.240.216.0/21
|
||||
43.240.56.0/21
|
||||
43.240.72.0/22
|
||||
43.241.16.0/22
|
||||
@@ -3863,11 +3863,11 @@
|
||||
44.30.28.0/24
|
||||
44.31.216.0/24
|
||||
44.31.28.0/24
|
||||
44.31.42.0/24
|
||||
44.31.81.0/24
|
||||
44.31.96.0/24
|
||||
44.32.143.0/24
|
||||
44.32.188.0/24
|
||||
44.32.191.0/24
|
||||
44.32.192.0/24
|
||||
45.112.232.0/22
|
||||
45.113.20.0/22
|
||||
@@ -3913,6 +3913,7 @@
|
||||
45.127.129.0/24
|
||||
45.127.131.0/24
|
||||
45.127.144.0/21
|
||||
45.135.149.0/24
|
||||
45.147.6.0/24
|
||||
45.151.47.0/24
|
||||
45.157.88.0/24
|
||||
@@ -3938,6 +3939,7 @@
|
||||
45.250.28.0/22
|
||||
45.250.32.0/21
|
||||
45.250.40.0/22
|
||||
45.251.0.0/23
|
||||
45.251.120.0/22
|
||||
45.251.20.0/22
|
||||
45.251.8.0/22
|
||||
@@ -3965,9 +3967,7 @@
|
||||
45.254.8.0/23
|
||||
45.255.152.0/22
|
||||
45.40.192.0/18
|
||||
45.59.106.0/24
|
||||
45.65.20.0/22
|
||||
45.87.101.0/24
|
||||
45.9.11.0/24
|
||||
47.112.0.0/13
|
||||
47.120.0.0/14
|
||||
@@ -3975,11 +3975,11 @@
|
||||
47.96.0.0/12
|
||||
49.112.0.0/13
|
||||
49.120.0.0/14
|
||||
49.128.203.0/24
|
||||
49.128.220.0/24
|
||||
49.128.223.0/24
|
||||
49.140.0.0/15
|
||||
49.208.0.0/14
|
||||
49.213.62.0/24
|
||||
49.221.128.0/19
|
||||
49.221.26.0/23
|
||||
49.221.64.0/19
|
||||
@@ -4051,7 +4051,6 @@
|
||||
58.240.0.0/12
|
||||
58.30.0.0/15
|
||||
58.32.0.0/11
|
||||
58.66.192.0/18
|
||||
58.67.128.0/17
|
||||
58.68.236.0/24
|
||||
58.68.247.0/24
|
||||
@@ -4114,7 +4113,6 @@
|
||||
59.152.36.0/24
|
||||
59.152.38.0/23
|
||||
59.153.116.0/22
|
||||
59.153.136.0/22
|
||||
59.153.164.0/22
|
||||
59.153.168.0/24
|
||||
59.153.32.0/22
|
||||
@@ -4218,8 +4216,7 @@
|
||||
8.148.0.0/19
|
||||
8.148.128.0/17
|
||||
8.148.36.0/22
|
||||
8.148.40.0/23
|
||||
8.148.43.0/24
|
||||
8.148.40.0/22
|
||||
8.148.64.0/18
|
||||
8.149.0.0/16
|
||||
8.150.0.0/20
|
||||
@@ -4229,13 +4226,12 @@
|
||||
8.160.0.0/15
|
||||
8.162.0.0/18
|
||||
8.163.0.0/16
|
||||
8.164.0.0/16
|
||||
8.164.0.0/14
|
||||
81.173.18.0/23
|
||||
81.173.20.0/22
|
||||
81.173.28.0/24
|
||||
81.68.0.0/14
|
||||
82.156.0.0/15
|
||||
84.247.114.0/24
|
||||
84.54.2.0/23
|
||||
85.237.205.0/24
|
||||
94.191.0.0/17
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
2001:dd8:1::/48
|
||||
2001:dd9::/48
|
||||
2001:df0:ac40::/48
|
||||
2001:df1:61c0::/48
|
||||
2001:df3:3a80::/48
|
||||
2001:df3:8b80::/48
|
||||
2001:df5:4740::/48
|
||||
2001:df7:1480::/48
|
||||
2400:1160::/32
|
||||
2400:3200::/32
|
||||
@@ -78,7 +78,7 @@
|
||||
2400:9380:9009::/48
|
||||
2400:9380:900a::/48
|
||||
2400:9380:9020::/47
|
||||
2400:9380:9040::/47
|
||||
2400:9380:9040::/48
|
||||
2400:9380:9050::/47
|
||||
2400:9380:9060::/48
|
||||
2400:9380:9071::/48
|
||||
@@ -104,6 +104,7 @@
|
||||
2400:a860:1::/48
|
||||
2400:a860:2::/47
|
||||
2400:a860:4::/47
|
||||
2400:a860:6::/48
|
||||
2400:a980::/29
|
||||
2400:ae00:1981::/48
|
||||
2400:b200::/32
|
||||
@@ -115,7 +116,6 @@
|
||||
2400:cb80:e40::/44
|
||||
2400:da00::/32
|
||||
2400:dd00::/28
|
||||
2400:ebc0::/32
|
||||
2400:ee00::/32
|
||||
2400:f6e0::/32
|
||||
2400:f720::/32
|
||||
@@ -131,7 +131,6 @@
|
||||
2401:20::/40
|
||||
2401:2780::/32
|
||||
2401:2e00::/32
|
||||
2401:33c0::/32
|
||||
2401:3480:2000::/48
|
||||
2401:3480:3000::/36
|
||||
2401:3480::/36
|
||||
@@ -201,23 +200,38 @@
|
||||
2401:de00::/32
|
||||
2401:ec00::/32
|
||||
2401:f860:100::/40
|
||||
2401:f860:7::/48
|
||||
2401:f860:86::/47
|
||||
2401:f860:88::/47
|
||||
2401:f860:90::/46
|
||||
2401:f860:94::/47
|
||||
2401:f860:90::/45
|
||||
2401:f860:a::/47
|
||||
2401:f860:c::/46
|
||||
2401:f860:f100::/40
|
||||
2401:f860:f6::/48
|
||||
2401:f860:f9::/48
|
||||
2401:fa00:40::/43
|
||||
2402:1440::/32
|
||||
2402:1460::/32
|
||||
2402:2000::/32
|
||||
2402:20e0:f000::/48
|
||||
2402:3180:8000::/33
|
||||
2402:3180::/46
|
||||
2402:3c00::/32
|
||||
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:4e00::/32
|
||||
2402:5e40::/32
|
||||
@@ -228,9 +242,7 @@
|
||||
2402:6fc0::/48
|
||||
2402:7040::/32
|
||||
2402:7d80:240::/47
|
||||
2402:7d80:6666::/48
|
||||
2402:7d80:8888::/48
|
||||
2402:7d80:9999::/48
|
||||
2402:7d80::/48
|
||||
2402:840:d000::/46
|
||||
2402:840:e000::/46
|
||||
@@ -296,6 +308,7 @@
|
||||
2403:a140:10::/48
|
||||
2403:a200::/32
|
||||
2403:ac00::/32
|
||||
2403:ad80:101c::/48
|
||||
2403:ad80:8008::/48
|
||||
2403:b400::/32
|
||||
2403:c80::/32
|
||||
@@ -393,7 +406,6 @@
|
||||
2406:52c0::/32
|
||||
2406:5340:6666::/48
|
||||
2406:5340:8888::/48
|
||||
2406:5ac0::/32
|
||||
2406:6100::/32
|
||||
2406:840:8100::/40
|
||||
2406:840:9000::/44
|
||||
@@ -402,8 +414,7 @@
|
||||
2406:840:9961::/48
|
||||
2406:840:9962::/47
|
||||
2406:840:996c::/48
|
||||
2406:840:a7fe::/48
|
||||
2406:840:a800::/37
|
||||
2406:840:c200::/40
|
||||
2406:840:e080::/44
|
||||
2406:840:e0cf::/48
|
||||
2406:840:e0e0::/46
|
||||
@@ -415,11 +426,12 @@
|
||||
2406:840:e230::/44
|
||||
2406:840:e260::/48
|
||||
2406:840:e2cf::/48
|
||||
2406:840:e600::/45
|
||||
2406:840:e608::/46
|
||||
2406:840:e621::/48
|
||||
2406:840:e600::/46
|
||||
2406:840:e604::/47
|
||||
2406:840:e606::/48
|
||||
2406:840:e60d::/48
|
||||
2406:840:e620::/47
|
||||
2406:840:e666::/47
|
||||
2406:840:e720::/44
|
||||
2406:840:e770::/48
|
||||
2406:840:e777::/48
|
||||
2406:840:e80f::/48
|
||||
@@ -447,15 +459,16 @@
|
||||
2406:840:fc80::/42
|
||||
2406:840:fcc0::/44
|
||||
2406:840:fcd0::/48
|
||||
2406:840:fcf0::/46
|
||||
2406:840:fcf4::/47
|
||||
2406:840:fd40::/42
|
||||
2406:840:fd80::/44
|
||||
2406:840:fd9f::/48
|
||||
2406:840:fda0::/43
|
||||
2406:840:fdc0::/44
|
||||
2406:840:fdd1::/48
|
||||
2406:840:fde5::/48
|
||||
2406:840:fde6::/47
|
||||
2406:840:fe27::/48
|
||||
2406:840:fe60::/44
|
||||
2406:840:fe90::/46
|
||||
2406:840:fe94::/48
|
||||
2406:840:fe96::/47
|
||||
@@ -473,11 +486,12 @@
|
||||
2406:840:fecc::/47
|
||||
2406:840:fecf::/48
|
||||
2406:840:fed1::/48
|
||||
2406:840:fed6::/48
|
||||
2406:840:fed8::/48
|
||||
2406:840:fedb::/48
|
||||
2406:840:fedc::/47
|
||||
2406:840:fedc::/48
|
||||
2406:840:fedf::/48
|
||||
2406:840:fef0::/48
|
||||
2406:840:fef0::/47
|
||||
2406:840:fef3::/48
|
||||
2406:840:fef4::/48
|
||||
2406:840:fef6::/47
|
||||
@@ -720,7 +734,6 @@
|
||||
2408:8406:cc0::/42
|
||||
2408:8406:d00::/41
|
||||
2408:8406:d80::/42
|
||||
2408:8407:500::/43
|
||||
2408:8409:100::/41
|
||||
2408:8409:1800::/40
|
||||
2408:8409:180::/42
|
||||
@@ -916,7 +929,7 @@
|
||||
2408:842a::/31
|
||||
2408:842c::/32
|
||||
2408:842e::/32
|
||||
2408:8431::/32
|
||||
2408:8430::/31
|
||||
2408:8434::/30
|
||||
2408:8438::/31
|
||||
2408:843c::/30
|
||||
@@ -1173,8 +1186,10 @@
|
||||
240a:420a::/31
|
||||
240a:4224:9000::/44
|
||||
240a:4224:a000::/44
|
||||
240a:4224:c000::/44
|
||||
240a:4224:d000::/44
|
||||
240a:4224:e000::/44
|
||||
240a:4225:1000::/44
|
||||
240a:4230::/31
|
||||
240a:4242::/31
|
||||
240a:4280::/26
|
||||
@@ -1199,14 +1214,15 @@
|
||||
240e::/20
|
||||
2602:2e0:ff::/48
|
||||
2602:f7ee:ee::/48
|
||||
2602:f92a:a471::/48
|
||||
2602:f92a:a473::/48
|
||||
2602:f92a:a478::/48
|
||||
2602:f92a:d1ff::/48
|
||||
2602:f92a:dead::/48
|
||||
2602:f92a:e100::/44
|
||||
2602:f93b:400::/38
|
||||
2602:f9ba:10c::/48
|
||||
2602:f9ba:a8::/48
|
||||
2602:feda:182::/47
|
||||
2602:fab0:11::/48
|
||||
2602:feda:1bf::/48
|
||||
2602:feda:1d1::/48
|
||||
2602:feda:1df::/48
|
||||
@@ -1230,8 +1246,6 @@
|
||||
2804:1e48:9002::/48
|
||||
2a01:f100:100::/48
|
||||
2a01:f100:1f8::/48
|
||||
2a01:ffc7:100::/40
|
||||
2a03:5840:126::/48
|
||||
2a04:3e00:1002::/48
|
||||
2a04:f580:8010::/47
|
||||
2a04:f580:8090::/48
|
||||
@@ -1246,7 +1260,6 @@
|
||||
2a04:f580:9060::/48
|
||||
2a04:f580:9070::/48
|
||||
2a04:f580:9080::/48
|
||||
2a04:f580:9090::/48
|
||||
2a04:f580:9210::/48
|
||||
2a04:f580:9212::/47
|
||||
2a04:f580:9220::/48
|
||||
@@ -1264,18 +1277,15 @@
|
||||
2a06:3603::/32
|
||||
2a06:3604::/30
|
||||
2a06:9f81:4600::/43
|
||||
2a06:9f81:4640::/44
|
||||
2a06:9f81:4660::/44
|
||||
2a06:9f81:4620::/44
|
||||
2a06:9f81:4640::/43
|
||||
2a06:a005:1c40::/44
|
||||
2a06:a005:260::/43
|
||||
2a06:a005:280::/43
|
||||
2a06:a005:2a0::/44
|
||||
2a06:a005:8d0::/44
|
||||
2a06:a005:9e0::/44
|
||||
2a06:a005:a13::/48
|
||||
2a06:a005:e9a::/48
|
||||
2a09:54c6:3000::/36
|
||||
2a09:54c6:6000::/35
|
||||
2a09:54c6:b000::/36
|
||||
2a09:54c6:c000::/36
|
||||
2a09:54c6:e000::/36
|
||||
@@ -1292,9 +1302,10 @@
|
||||
2a0b:2542::/48
|
||||
2a0b:4b81:1001::/48
|
||||
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:d40::/44
|
||||
2a0e:97c0:5ef::/48
|
||||
2a0e:97c0:83f::/48
|
||||
2a0e:9b00::/29
|
||||
@@ -1302,7 +1313,7 @@
|
||||
2a0e:aa06:440::/48
|
||||
2a0e:aa06:490::/44
|
||||
2a0e:aa06:4e0::/44
|
||||
2a0e:aa06:500::/44
|
||||
2a0e:aa06:501::/48
|
||||
2a0e:aa06:520::/48
|
||||
2a0e:aa06:525::/48
|
||||
2a0e:aa06:541::/48
|
||||
@@ -1317,14 +1328,12 @@
|
||||
2a0e:aa07:e0e0::/44
|
||||
2a0e:aa07:e151::/48
|
||||
2a0e:aa07:e155::/48
|
||||
2a0e:aa07:e15f::/48
|
||||
2a0e:aa07:e160::/47
|
||||
2a0e:aa07:e162::/48
|
||||
2a0e:aa07:e16a::/48
|
||||
2a0e:aa07:e1a0::/44
|
||||
2a0e:aa07:e1e1::/48
|
||||
2a0e:aa07:e1e2::/47
|
||||
2a0e:aa07:e1e4::/47
|
||||
2a0e:aa07:e1e6::/48
|
||||
2a0e:aa07:e1e0::/44
|
||||
2a0e:aa07:e200::/44
|
||||
2a0e:aa07:e210::/48
|
||||
2a0e:aa07:e21c::/47
|
||||
@@ -1342,7 +1351,15 @@
|
||||
2a0e:b107:c10::/48
|
||||
2a0e:b107:da0::/44
|
||||
2a0e:b107:dce::/48
|
||||
2a0f:1cc5:f00::/47
|
||||
2a0f:1cc5:f02::/48
|
||||
2a0f:1cc5:f05::/48
|
||||
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:f5d0::/44
|
||||
2a0f:7803:f5e0::/43
|
||||
@@ -1356,39 +1373,33 @@
|
||||
2a0f:7803:fa24::/46
|
||||
2a0f:7803:faf3::/48
|
||||
2a0f:7803:fe41::/48
|
||||
2a0f:7803:fe44::/46
|
||||
2a0f:7803:fe4e::/48
|
||||
2a0f:7803:fe45::/48
|
||||
2a0f:7803:fe81::/48
|
||||
2a0f:7803:fe82::/48
|
||||
2a0f:7804:f650::/44
|
||||
2a0f:7804:f9f0::/44
|
||||
2a0f:7807::/32
|
||||
2a0f:7d07::/32
|
||||
2a0f:85c1:ba5::/48
|
||||
2a0f:85c1:bfe::/48
|
||||
2a0f:85c1:ca0::/44
|
||||
2a0f:85c1:ce1::/48
|
||||
2a0f:85c1:cf1::/48
|
||||
2a0f:85c1:d90::/48
|
||||
2a0f:9400:6110::/48
|
||||
2a0f:9400:7700::/48
|
||||
2a0f:ac00::/29
|
||||
2a0f:ea47:fc1d::/48
|
||||
2a10:2f00:15a::/48
|
||||
2a10:67c2:2::/48
|
||||
2a10:ccc0:d00::/46
|
||||
2a10:ccc0:d0a::/47
|
||||
2a10:ccc0:d0c::/47
|
||||
2a10:ccc6:66c4::/48
|
||||
2a10:ccc6:66c6::/48
|
||||
2a10:ccc6:66c8::/47
|
||||
2a10:ccc6:66ca::/48
|
||||
2a10:ccc6:66cc::/47
|
||||
2a10:ccc6:66c8::/48
|
||||
2a10:ccc6:66cc::/46
|
||||
2a12:f8c3::/36
|
||||
2a13:1800:10::/48
|
||||
2a13:1800:300::/44
|
||||
2a13:1800:80::/44
|
||||
2a13:1800::/48
|
||||
2a13:1801:180::/43
|
||||
2a13:a5c3:ff10::/44
|
||||
2a13:a5c3:ff21::/48
|
||||
2a13:a5c3:ff50::/44
|
||||
2a13:a5c7:1800::/40
|
||||
@@ -1397,10 +1408,8 @@
|
||||
2a13:a5c7:2121::/48
|
||||
2a13:a5c7:2301::/48
|
||||
2a13:a5c7:2302::/48
|
||||
2a13:a5c7:23c0::/42
|
||||
2a13:a5c7:2600::/40
|
||||
2a13:a5c7:23c0::/48
|
||||
2a13:a5c7:2801::/48
|
||||
2a13:a5c7:2803::/48
|
||||
2a13:a5c7:3108::/48
|
||||
2a13:a5c7:31a0::/43
|
||||
2a13:a5c7:3301::/48
|
||||
@@ -1411,7 +1420,7 @@
|
||||
2a14:67c1:20::/44
|
||||
2a14:67c1:702::/47
|
||||
2a14:67c1:704::/48
|
||||
2a14:67c1:70::/47
|
||||
2a14:67c1:70::/48
|
||||
2a14:67c1:73::/48
|
||||
2a14:67c1:74::/48
|
||||
2a14:67c1:a010::/44
|
||||
@@ -1421,14 +1430,10 @@
|
||||
2a14:67c1:a02a::/48
|
||||
2a14:67c1:a02f::/48
|
||||
2a14:67c1:a040::/47
|
||||
2a14:67c1:a061::/48
|
||||
2a14:67c1:a064::/48
|
||||
2a14:67c1:a090::/45
|
||||
2a14:67c1:a099::/48
|
||||
2a14:67c1:a100::/43
|
||||
2a14:67c1:a125::/48
|
||||
2a14:67c1:a144::/48
|
||||
2a14:67c1:a150::/44
|
||||
2a14:67c1:b000::/48
|
||||
2a14:67c1:b065::/48
|
||||
2a14:67c1:b066::/48
|
||||
@@ -1438,80 +1443,72 @@
|
||||
2a14:67c1:b107::/48
|
||||
2a14:67c1:b130::/46
|
||||
2a14:67c1:b134::/47
|
||||
2a14:67c1:b136::/48
|
||||
2a14:67c1:b140::/48
|
||||
2a14:67c1:b4a1::/48
|
||||
2a14:67c1:b4a2::/48
|
||||
2a14:67c1:b4a8::/47
|
||||
2a14:67c1:b4aa::/48
|
||||
2a14:67c1:b4c0::/45
|
||||
2a14:67c1:b4d0::/44
|
||||
2a14:67c1:b4e0::/43
|
||||
2a14:67c1:b500::/47
|
||||
2a14:67c1:b549::/48
|
||||
2a14:67c1:b561::/48
|
||||
2a14:67c1:b563::/48
|
||||
2a14:67c1:b566::/48
|
||||
2a14:67c1:b581::/48
|
||||
2a14:67c1:b578::/48
|
||||
2a14:67c1:b582::/48
|
||||
2a14:67c1:b586::/48
|
||||
2a14:67c1:b588::/47
|
||||
2a14:67c1:b590::/47
|
||||
2a14:67c1:b590::/48
|
||||
2a14:67c1:b599::/48
|
||||
2a14:67c5:1900::/40
|
||||
2a14:67c1:b5a1::/48
|
||||
2a14:67c1:c300::/40
|
||||
2a14:7580:740::/44
|
||||
2a14:7580:750::/47
|
||||
2a14:7580:9200::/40
|
||||
2a14:7580:9208::/48
|
||||
2a14:7580:9220::/44
|
||||
2a14:7580:9400::/39
|
||||
2a14:7580:9600::/46
|
||||
2a14:7580:960c::/48
|
||||
2a14:7580:d000::/37
|
||||
2a14:7580:d800::/39
|
||||
2a14:7580:da00::/40
|
||||
2a14:7580:e200::/40
|
||||
2a14:7580:fa01::/48
|
||||
2a14:7580:fe00::/40
|
||||
2a14:7580:fff4::/48
|
||||
2a14:7580:fff7::/48
|
||||
2a14:7580:fffa::/48
|
||||
2a14:7581:30b5::/48
|
||||
2a14:7581:3100::/40
|
||||
2a14:7581:3400::/47
|
||||
2a14:7581:9010::/44
|
||||
2a14:7581:b10::/48
|
||||
2a14:7581:b12::/48
|
||||
2a14:7581:b15::/48
|
||||
2a14:7581:3401::/48
|
||||
2a14:7581:b12::/47
|
||||
2a14:7581:b14::/47
|
||||
2a14:7581:b20::/46
|
||||
2a14:7581:b32::/47
|
||||
2a14:7581:b40::/48
|
||||
2a14:7581:b44::/48
|
||||
2a14:7581:b46::/47
|
||||
2a14:7581:b48::/48
|
||||
2a14:7581:b4a::/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:ba2::/47
|
||||
2a14:7581:ba4::/48
|
||||
2a14:7581:bbb::/48
|
||||
2a14:7581:bc2::/48
|
||||
2a14:7581:bcd::/48
|
||||
2a14:7581:bff::/48
|
||||
2a14:7581:ffb::/48
|
||||
2a14:7581:ffd::/48
|
||||
2a14:7583:f201::/48
|
||||
2a14:7583:f203::/48
|
||||
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:f500::/48
|
||||
2a14:7583:f701::/48
|
||||
2a14:7583:f702::/47
|
||||
2a14:7583:f704::/47
|
||||
2a14:7583:f707::/48
|
||||
2a14:7583:f708::/48
|
||||
2a14:7583:f704::/46
|
||||
2a14:7583:f708::/47
|
||||
2a14:7583:f70a::/48
|
||||
2a14:7583:f743::/48
|
||||
2a14:7583:f764::/48
|
||||
2a14:7584::/36
|
||||
2a14:7c0:4a01::/48
|
||||
2a14:7c0:5103::/48
|
||||
2c0f:f7a8:8011::/48
|
||||
2c0f:f7a8:8050::/48
|
||||
2c0f:f7a8:805f::/48
|
||||
|
||||
@@ -117,6 +117,7 @@
|
||||
91vps.club
|
||||
92ccav.com
|
||||
991.com
|
||||
996.icu
|
||||
99btgc01.com
|
||||
99cn.info
|
||||
9bis.com
|
||||
@@ -303,6 +304,7 @@ apetube.com
|
||||
api-secure.recaptcha.net
|
||||
api-verify.recaptcha.net
|
||||
api.ai
|
||||
api.palworldgame.com
|
||||
api.pureapk.com
|
||||
api.recaptcha.net
|
||||
api.steampowered.com
|
||||
@@ -360,6 +362,7 @@ asia-gaming.com
|
||||
asiaharvest.org
|
||||
asianage.com
|
||||
asianews.it
|
||||
asianfanfics.com
|
||||
asiansexdiary.com
|
||||
asiaone.com
|
||||
asiatgp.com
|
||||
@@ -748,7 +751,6 @@ btc98.com
|
||||
btcbank.bank
|
||||
btctrade.im
|
||||
btdig.com
|
||||
btdigg.org
|
||||
btguard.com
|
||||
btku.me
|
||||
btku.org
|
||||
@@ -1166,6 +1168,7 @@ csuchen.de
|
||||
csw.org.uk
|
||||
ct.org.tw
|
||||
ctao.org
|
||||
ctinets.com
|
||||
ctinews.com
|
||||
ctitv.com.tw
|
||||
ctowc.org
|
||||
@@ -1341,6 +1344,7 @@ dnvod.tv
|
||||
doc.new
|
||||
docker.com
|
||||
docker.io
|
||||
dockerstatus.com
|
||||
docs.deno.com
|
||||
docs.new
|
||||
doctorvoice.org
|
||||
@@ -1797,6 +1801,8 @@ freedominfonetweb.wordpress.com
|
||||
freedomsherald.org
|
||||
freeforums.org
|
||||
freegao.com
|
||||
freegpt.es
|
||||
freegpt.tech
|
||||
freehongkong.org
|
||||
freeilhamtohti.org
|
||||
freekazakhs.org
|
||||
@@ -2691,6 +2697,7 @@ internet.org
|
||||
internetdefenseleague.org
|
||||
internetfreedom.org
|
||||
internetpopculture.com
|
||||
interseclab.org
|
||||
inthenameofconfuciusmovie.com
|
||||
investigating.wordpress.com
|
||||
invidio.us
|
||||
@@ -3656,6 +3663,7 @@ occupytiananmen.com
|
||||
ocreampies.com
|
||||
ocry.com
|
||||
october-review.org
|
||||
octocaptcha.com
|
||||
oculus.com
|
||||
oculuscdn.com
|
||||
odysee.com
|
||||
@@ -4463,6 +4471,7 @@ solana.com
|
||||
solarsystem.nasa.gov
|
||||
solidaritetibet.org
|
||||
solidfiles.com
|
||||
solscan.io
|
||||
solv.finance
|
||||
somee.com
|
||||
songjianjun.com
|
||||
@@ -4683,8 +4692,10 @@ tanc.org
|
||||
tangren.us
|
||||
tanks.gg
|
||||
taoism.net
|
||||
tap.io
|
||||
tapanwap.com
|
||||
tapatalk.com
|
||||
taptap.io
|
||||
tardigrade.io
|
||||
tarr.uspto.gov
|
||||
taup.net
|
||||
@@ -4994,6 +5005,7 @@ trt.net.tr
|
||||
trtc.com.tw
|
||||
truebuddha-md.org
|
||||
trulyergonomic.com
|
||||
trustwallet.com
|
||||
truthsocial.com
|
||||
truveo.com
|
||||
tryheart.jp
|
||||
@@ -5301,6 +5313,7 @@ vijayatemple.org
|
||||
vilanet.me
|
||||
vilavpn.com
|
||||
vimeo.com
|
||||
vimeocdn.com
|
||||
vimperator.org
|
||||
vincnd.com
|
||||
vine.co
|
||||
@@ -5449,6 +5462,7 @@ webpkgcache.com
|
||||
webrtc.org
|
||||
webrush.net
|
||||
webs-tv.net
|
||||
websdr.org
|
||||
website.informer.com
|
||||
website.new
|
||||
websitepulse.com
|
||||
@@ -5519,6 +5533,7 @@ wikilivres.info
|
||||
wikimapia.org
|
||||
wikimedia.org
|
||||
wikinews.org
|
||||
wikipedia.com
|
||||
wikipedia.org
|
||||
wikisource.org
|
||||
wikiversity.org
|
||||
@@ -5693,6 +5708,7 @@ xn--ngstr-lra8j.com
|
||||
xn--noss43i.com
|
||||
xn--oiq.cc
|
||||
xn--p8j9a0d9c9a.xn--q9jyb4c
|
||||
xn--u2u927b.com
|
||||
xnpool.com
|
||||
xnxx.com
|
||||
xpdo.net
|
||||
@@ -5818,6 +5834,7 @@ z-lib.gd
|
||||
z-lib.gl
|
||||
z-lib.io
|
||||
z-lib.org
|
||||
z-library.ec
|
||||
z-library.sk
|
||||
zacebook.com
|
||||
zalmos.com
|
||||
|
||||
@@ -7,6 +7,8 @@ PKG_VERSION:=190
|
||||
PKG_RELEASE:=3
|
||||
|
||||
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_V2ray \
|
||||
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_PKGARCH:=all
|
||||
LUCI_DEPENDS:= \
|
||||
+coreutils +coreutils-base64 +dns2tcp +dnsmasq-full +@PACKAGE_dnsmasq_full_ipset +ipset +kmod-ipt-nat +jq \
|
||||
+ip-full +iptables +iptables-mod-tproxy +lua +lua-neturl +libuci-lua +microsocks \
|
||||
+tcping +resolveip +shadowsocksr-libev-ssr-check +curl +nping \
|
||||
+coreutils +coreutils-base64 +dns2tcp +dnsmasq-full \
|
||||
+jq +ip-full +lua +lua-neturl +libuci-lua +microsocks \
|
||||
+tcping +resolveip +curl +nping \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:curl \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \
|
||||
+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_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-local \
|
||||
+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
|
||||
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
select PACKAGE_luci-lib-ipkg 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
|
||||
prompt "Shadowsocks Client Selection"
|
||||
default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client if aarch64||arm||i386||mips||mipsel||x86_64
|
||||
|
||||
@@ -30,6 +30,7 @@ function index()
|
||||
entry({"admin", "services", "shadowsocksr", "delete"}, call("act_delete"))
|
||||
--[[Backup]]
|
||||
entry({"admin", "services", "shadowsocksr", "backup"}, call("create_backup")).leaf = true
|
||||
|
||||
end
|
||||
|
||||
function subscribe()
|
||||
@@ -48,36 +49,70 @@ end
|
||||
function act_ping()
|
||||
local e = {}
|
||||
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 wsPath = luci.http.formvalue("wsPath")
|
||||
local wsPath = luci.http.formvalue("wsPath") or ""
|
||||
local tls = luci.http.formvalue("tls")
|
||||
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 prefix = tls=='1' and "https://" or "http://"
|
||||
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)
|
||||
e.socket = string.match(result,"http_code=(%d+)")=="101"
|
||||
e.ping = tonumber(string.match(result, "time_connect=(%d+.%d%d%d)"))*1000
|
||||
|
||||
local use_nft = luci.sys.call("command -v nft >/dev/null") == 0
|
||||
local iret = false
|
||||
|
||||
if use_nft then
|
||||
iret = luci.sys.call("nft add element inet ss_spec ss_spec_wan_ac { " .. domain .. " } 2>/dev/null") == 0
|
||||
else
|
||||
iret = luci.sys.call("ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null") == 0
|
||||
end
|
||||
|
||||
if transport == "ws" then
|
||||
local prefix = tls == '1' and "https://" or "http://"
|
||||
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
|
||||
)
|
||||
e.socket = string.match(result,"http_code=(%d+)") == "101"
|
||||
local ping_time = tonumber(string.match(result, "time_connect=(%d+.%d%d%d)"))
|
||||
e.ping = ping_time and ping_time * 1000 or nil
|
||||
else
|
||||
-- TCP ping
|
||||
local socket = nixio.socket("inet", "stream")
|
||||
socket:setopt("socket", "rcvtimeo", 3)
|
||||
socket:setopt("socket", "sndtimeo", 3)
|
||||
e.socket = socket:connect(domain, port)
|
||||
socket:close()
|
||||
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))
|
||||
if (e.ping == "") then
|
||||
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)
|
||||
if (e.ping == "") then
|
||||
-- UDP ping test using nping
|
||||
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))
|
||||
|
||||
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
|
||||
if (iret == 0) then
|
||||
luci.sys.call(" ipset del ss_spec_wan_ac " .. domain)
|
||||
end
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
@@ -101,28 +136,46 @@ function check_port()
|
||||
local s
|
||||
local server_name = ""
|
||||
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)
|
||||
if s.alias then
|
||||
server_name = s.alias
|
||||
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
|
||||
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", "sndtimeo", 3)
|
||||
ret = socket:connect(s.server, s.server_port)
|
||||
if tostring(ret) == "true" then
|
||||
local ret = socket:connect(s.server, s.server_port)
|
||||
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
|
||||
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
|
||||
if iret == 0 then
|
||||
|
||||
-- 删除临时 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)
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({ret = retstring})
|
||||
end
|
||||
|
||||
@@ -4,14 +4,22 @@ local uci = require "luci.model.uci".cursor()
|
||||
-- 获取 LAN IP 地址
|
||||
function lanip()
|
||||
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
|
||||
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
|
||||
|
||||
-- 取任意一个 global IPv4 地址
|
||||
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
|
||||
|
||||
return lan_ip
|
||||
|
||||
@@ -264,7 +264,7 @@ s = m:section(NamedSection, sid, "servers")
|
||||
s.anonymous = true
|
||||
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.template = "shadowsocksr/ssrurl"
|
||||
o.value = sid
|
||||
@@ -1285,15 +1285,26 @@ o = s:option(ListValue, "tuic_alpn", translate("TUIC ALPN"))
|
||||
o.default = ""
|
||||
o:value("", translate("Default"))
|
||||
o:value("h3")
|
||||
o:value("h2")
|
||||
o:value("h3,h2")
|
||||
o:value("spdy/3.1")
|
||||
o:value("h3,spdy/3.1")
|
||||
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 ]]--
|
||||
o = s:option(Flag, "insecure", translate("allowInsecure"))
|
||||
o.rmempty = false
|
||||
o:depends("tls", true)
|
||||
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.")
|
||||
|
||||
-- [[ Hysteria2 TLS pinSHA256 ]] --
|
||||
|
||||
@@ -8,14 +8,22 @@ local uci = require "luci.model.uci".cursor()
|
||||
-- 获取 LAN IP 地址
|
||||
function lanip()
|
||||
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
|
||||
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
|
||||
|
||||
-- 取任意一个 global IPv4 地址
|
||||
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
|
||||
|
||||
return lan_ip
|
||||
|
||||
@@ -75,9 +75,9 @@ function export_ssr_url(btn, urlname, sid) {
|
||||
textarea.select();
|
||||
try {
|
||||
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) {
|
||||
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 {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
if (!s) return false;
|
||||
var ssrurl = prompt("<%:Paste sharing link here%>", "");
|
||||
if (ssrurl == null || ssrurl == "") {
|
||||
s.innerHTML = "<font color='red'><%:User cancelled.%></font>";
|
||||
s.innerHTML = "<font style=\'color:red\'><%:User cancelled.%></font>";
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "";
|
||||
@@ -97,18 +97,6 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
ssrurl = ssrurl.replace(/&([a-zA-Z]+);/g, '&').replace(/\s*#\s*/, '#').trim(); //一些奇葩的链接用"&"当做"&","#"前后带空格
|
||||
var ssu = ssrurl.split('://');
|
||||
//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");
|
||||
event.initEvent("change", true, true);
|
||||
switch (ssu[0]) {
|
||||
@@ -189,14 +177,16 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
|
||||
// 再分离 ? 或 /?(参数)
|
||||
var queryIndex = (url0 = url0.replace('/?', '?')).indexOf("?");
|
||||
var queryStr = "";
|
||||
var query = "";
|
||||
if (queryIndex >= 0) {
|
||||
queryStr = url0.substring(queryIndex + 1);
|
||||
query = url0.substring(queryIndex + 1);
|
||||
url0 = url0.substring(0, queryIndex);
|
||||
}
|
||||
|
||||
var params = Object.fromEntries(new URLSearchParams(queryStr));
|
||||
var params = Object.fromEntries(new URLSearchParams(query));
|
||||
|
||||
if ( ! params.type) {
|
||||
// 普通 SS 导入逻辑
|
||||
// 判断是否 SIP002 格式(即含 @)
|
||||
if (url0.indexOf("@") !== -1) {
|
||||
// === SIP002 格式 ===
|
||||
@@ -319,6 +309,149 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
}
|
||||
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
||||
return false;
|
||||
} else {
|
||||
try {
|
||||
// Xray SS 导入逻辑
|
||||
// 拆分 @,判断是否是 base64 userinfo 的格式
|
||||
var parts = url0.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://" + url0 + (param ? "#" + encodeURIComponent(param) : ""));
|
||||
|
||||
} catch(e) {
|
||||
alert(e);
|
||||
return false;
|
||||
}
|
||||
// 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.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 (params.security === "tls") {
|
||||
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;
|
||||
}
|
||||
case "ssr":
|
||||
var sstr = b64decsafe((ssu[1] || "").replace(/#.*/, "").trim());
|
||||
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');
|
||||
var rem = pdict['remarks'];
|
||||
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;
|
||||
case "trojan":
|
||||
try {
|
||||
@@ -360,6 +493,30 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!params.get("type")) {
|
||||
// 普通 Trojan 导入逻辑
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "trojan";
|
||||
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 || "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("peer") || 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("tfo") === "1") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.fast_open')[0].checked = true; // 设置 fast_open 为 true
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.fast_open')[0].dispatchEvent(event); // 触发事件
|
||||
}
|
||||
|
||||
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
||||
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);
|
||||
@@ -379,7 +536,6 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
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" :
|
||||
@@ -445,8 +601,9 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
break;
|
||||
}
|
||||
|
||||
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
|
||||
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
||||
return false;
|
||||
}
|
||||
case "vmess":
|
||||
var sstr = b64DecodeUnicode((ssu[1] || "").replace(/#.*/, "").trim());
|
||||
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].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;
|
||||
case "vless":
|
||||
try {
|
||||
@@ -664,153 +821,85 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
}
|
||||
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
||||
return false;
|
||||
case "shadowsocks":
|
||||
try {
|
||||
// 处理完整 ss:// 链接
|
||||
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);
|
||||
case "tuic":
|
||||
var url0 = (ssu[1] || "");
|
||||
var param = "";
|
||||
|
||||
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);
|
||||
return false;
|
||||
// 再分离 ? 或 /?(参数)
|
||||
var queryIndex = (url0 = url0.replace('/?', '?')).indexOf("?");
|
||||
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") {
|
||||
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);
|
||||
var params = Object.fromEntries(new URLSearchParams(query));
|
||||
|
||||
setElementValue('cbid.shadowsocksr.' + sid + '.tls_alpn', params.get("alpn") || "");
|
||||
setElementValue('cbid.shadowsocksr.' + sid + '.fingerprint', params.get("fp") || "");
|
||||
setElementValue('cbid.shadowsocksr.' + sid + '.tls_host', params.get("sni") || "");
|
||||
}
|
||||
switch (params.get("type")) {
|
||||
case "ws":
|
||||
if (params.get("security") !== "tls") {
|
||||
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")) : "");
|
||||
}
|
||||
var sipIndex = url0.indexOf("@");
|
||||
var userInfo = url0.substring(0, sipIndex); // 格式:uuid:password
|
||||
var hostPart = url0.substring(sipIndex + 1); // 格式:hostname:port
|
||||
var userInfoSplitIndex = userInfo.indexOf(":");
|
||||
if(userInfoSplitIndex < 0) {
|
||||
// 格式错误
|
||||
s.innerHTML = "<font style='color:red'><%:Userinfo format error.%></font>";
|
||||
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;
|
||||
default:
|
||||
s.innerHTML = "<font color='red'><%:Invalid format.%></font>";
|
||||
s.innerHTML = "<font style=\'color:red\'><%:Invalid format.%></font>";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1258,8 +1258,18 @@ start_server() {
|
||||
[ "$(uci_get_by_name $1 enable 0)" == "0" ] && return 1
|
||||
let server_count=server_count+1
|
||||
if [ "$server_count" == "1" ]; then
|
||||
if ! (iptables-save -t filter | grep SSR-SERVER-RULE >/dev/null); then
|
||||
iptables -N SSR-SERVER-RULE && iptables -t filter -I INPUT -j SSR-SERVER-RULE
|
||||
if command -v nft >/dev/null 2>&1; then
|
||||
# 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
|
||||
local type=$(uci_get_by_name $1 type)
|
||||
@@ -1287,17 +1297,15 @@ start_server() {
|
||||
echolog "Server:Socks5 Server$server_count Started!"
|
||||
;;
|
||||
esac
|
||||
ssr_server_port=$(uci show shadowsocksr | grep 'server_config.*server_port' | awk -F"'" '{print $2}' | tr "\n" " ")
|
||||
if [ -n "$ssr_server_port" ]; then
|
||||
uci -q delete firewall.shadowsocksr_server
|
||||
uci set firewall.shadowsocksr_server=rule
|
||||
uci set firewall.shadowsocksr_server.name="shadowsocksr_server"
|
||||
uci set firewall.shadowsocksr_server.target="ACCEPT"
|
||||
uci set firewall.shadowsocksr_server.src="wan"
|
||||
uci set firewall.shadowsocksr_server.dest_port="$ssr_server_port"
|
||||
uci set firewall.shadowsocksr_server.enabled="1"
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall reload >/dev/null 2>&1
|
||||
server_port=$(uci_get_by_name $1 server_port)
|
||||
if command -v nft >/dev/null 2>&1; then
|
||||
# nftables / fw4
|
||||
nft add rule inet fw4 SSR-SERVER-RULE tcp dport $server_port accept
|
||||
nft add rule inet fw4 SSR-SERVER-RULE udp dport $server_port accept
|
||||
else
|
||||
# iptables / fw3
|
||||
iptables -t filter -A SSR-SERVER-RULE -p tcp --dport $server_port -j ACCEPT
|
||||
iptables -t filter -A SSR-SERVER-RULE -p udp --dport $server_port -j ACCEPT
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -1307,6 +1315,25 @@ start_server() {
|
||||
if [ ! -f $FWI ]; then
|
||||
echo '#!/bin/sh' >$FWI
|
||||
fi
|
||||
if command -v nft >/dev/null 2>&1; then
|
||||
# nftables / fw4
|
||||
extract_rules() {
|
||||
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
|
||||
nft flush chain inet fw4 SSR-SERVER-RULE 2>/dev/null || true
|
||||
nft -f - <<-EOT
|
||||
table inet fw4 {
|
||||
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/"
|
||||
@@ -1318,6 +1345,7 @@ start_server() {
|
||||
$(extract_rules)
|
||||
EOT
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
config_load $NAME
|
||||
@@ -1455,6 +1483,28 @@ stop() {
|
||||
unlock
|
||||
set_lock
|
||||
/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
|
||||
$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
|
||||
@@ -1465,7 +1515,7 @@ stop() {
|
||||
( \
|
||||
# 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 ; \
|
||||
sleep 1s; \
|
||||
sleep 3s; \
|
||||
# Force kill hanged programs
|
||||
$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
|
||||
fi
|
||||
uci -q delete firewall.shadowsocksr_server
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall reload >/dev/null 2>&1
|
||||
del_cron
|
||||
unset_lock
|
||||
}
|
||||
|
||||
@@ -1,37 +1,7 @@
|
||||
aaplimg.com
|
||||
account.synology.com
|
||||
apple-cloudkit.com
|
||||
apple.co
|
||||
apple.com
|
||||
apple.com.cn
|
||||
appstore.com
|
||||
bilibili.com
|
||||
bilibili.cn
|
||||
bilivideo.com
|
||||
bilivideo.cn
|
||||
biliapi.com
|
||||
biliapi.net
|
||||
bilibili.cn
|
||||
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
|
||||
apple.com
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
# Detect firewall version and set appropriate tools
|
||||
detect_firewall() {
|
||||
if command -v fw4 >/dev/null 2>&1 && [ -f /usr/share/nftables.d/ruleset-post/99-shadowsocksr.nft ]; then
|
||||
USE_NFT=1
|
||||
NFT="nft"
|
||||
elif command -v nft >/dev/null 2>&1 && [ "$(uci get firewall.@defaults[0].syn_flood 2>/dev/null)" != "" ] && [ ! -f /etc/config/firewall3 ]; then
|
||||
if command -v nft >/dev/null 2>&1 && \
|
||||
[ -n "$(uci get firewall.@defaults[0].syn_flood 2>/dev/null)" ] && \
|
||||
! grep -q "fw3" /etc/init.d/firewall 2>/dev/null; then
|
||||
USE_NFT=1
|
||||
NFT="nft"
|
||||
FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file
|
||||
else
|
||||
USE_NFT=0
|
||||
IPT="iptables -t nat" # alias of iptables
|
||||
@@ -26,6 +26,7 @@ detect_firewall() {
|
||||
detect_firewall
|
||||
|
||||
TAG="_SS_SPEC_RULE_" # comment tag
|
||||
|
||||
usage() {
|
||||
cat <<-EOF
|
||||
Usage: ssr-rules [options]
|
||||
@@ -83,11 +84,15 @@ flush_r() {
|
||||
flush_nftables() {
|
||||
# Remove nftables rules and sets
|
||||
$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
|
||||
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
|
||||
|
||||
[ -n "$FWI" ] && echo '#!/bin/sh' >"$FWI"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -128,43 +133,43 @@ ipset_r() {
|
||||
}
|
||||
|
||||
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
|
||||
$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 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 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 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 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 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 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 netflix '{ type ipv4_addr; flags interval; }' 2>/dev/null
|
||||
|
||||
# Add IP addresses to sets
|
||||
for ip in $LAN_GM_IP; do
|
||||
$NFT add element inet ss_spec gmlan { $ip }
|
||||
$NFT add element inet ss_spec gmlan "{ $ip }"
|
||||
done
|
||||
for ip in $LAN_FP_IP; do
|
||||
$NFT add element inet ss_spec fplan { $ip }
|
||||
$NFT add element inet ss_spec fplan "{ $ip }"
|
||||
done
|
||||
for ip in $LAN_BP_IP; do
|
||||
$NFT add element inet ss_spec bplan { $ip }
|
||||
$NFT add element inet ss_spec bplan "{ $ip }"
|
||||
done
|
||||
for ip in $WAN_BP_IP; do
|
||||
$NFT add element inet ss_spec whitelist { $ip }
|
||||
$NFT add element inet ss_spec whitelist "{ $ip }"
|
||||
done
|
||||
for ip in $WAN_FW_IP; do
|
||||
$NFT add element inet ss_spec blacklist { $ip }
|
||||
$NFT add element inet ss_spec blacklist "{ $ip }"
|
||||
done
|
||||
|
||||
# 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 $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
|
||||
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
|
||||
|
||||
# Set up mode-specific rules
|
||||
@@ -212,19 +217,19 @@ ipset_nft() {
|
||||
|
||||
# Shunt/Netflix rules
|
||||
if [ "$SHUNT_PORT" != "0" ]; then
|
||||
for ip in $(cat ${SHUNT_LIST:=/dev/null} 2>/dev/null); do
|
||||
$NFT add element inet ss_spec netflix { $ip }
|
||||
for ip in $(cat "${SHUNT_LIST:=/dev/null}" 2>/dev/null); do
|
||||
$NFT add element inet ss_spec netflix "{ $ip }"
|
||||
done
|
||||
case "$SHUNT_PORT" in
|
||||
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
|
||||
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 @netflix redirect to :"$SHUNT_PORT"
|
||||
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"
|
||||
else
|
||||
$NFT add element inet ss_spec whitelist { $SHUNT_IP }
|
||||
$NFT add element inet ss_spec whitelist "{ $SHUNT_IP }"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@@ -233,12 +238,12 @@ ipset_nft() {
|
||||
}
|
||||
|
||||
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 -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
|
||||
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
|
||||
router)
|
||||
ipset -! -R <<-EOF || return 1
|
||||
@@ -267,34 +272,34 @@ ipset_iptables() {
|
||||
;;
|
||||
esac
|
||||
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
|
||||
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
|
||||
ipset -N whitelist 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 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
|
||||
fi
|
||||
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_BP_IP; do ipset -! add whitelist "$ip"; done
|
||||
for ip in $WAN_FW_IP; do ipset -! add blacklist "$ip"; done
|
||||
if [ "$SHUNT_PORT" != "0" ]; then
|
||||
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
|
||||
0) ;;
|
||||
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
|
||||
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 -m set --match-set netflix dst -j REDIRECT --to-ports "$SHUNT_PORT"
|
||||
if [ "$SHUNT_PROXY" = "1" ]; then
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp -d "$SHUNT_IP" -j REDIRECT --to-ports "$local_port"
|
||||
else
|
||||
ipset -! add whitelist $SHUNT_IP
|
||||
ipset -! add whitelist "$SHUNT_IP"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@@ -312,28 +317,38 @@ fw_rule() {
|
||||
}
|
||||
|
||||
fw_rule_nft() {
|
||||
# Create forward chain for nftables
|
||||
$NFT add chain inet ss_spec ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 0.0.0.0/8 return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 10.0.0.0/8 return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 127.0.0.0/8 return
|
||||
$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
|
||||
$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
|
||||
$NFT add rule inet ss_spec ss_spec_wan_fw ip daddr 240.0.0.0/4 return
|
||||
# Create forward chain with better error handling
|
||||
if ! $NFT list chain inet ss_spec ss_spec_wan_fw >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_wan_fw 2>/dev/null || {
|
||||
loger 3 "Failed to create forward chain"
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
# Exclude special local addresses
|
||||
$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
|
||||
$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."
|
||||
exit 1
|
||||
}
|
||||
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."
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
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 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 -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."
|
||||
exit 1
|
||||
}
|
||||
@@ -366,13 +381,13 @@ ac_rule() {
|
||||
ac_rule_nft() {
|
||||
local MATCH_SET_CONDITION=""
|
||||
if [ -n "$LAN_AC_IP" ]; then
|
||||
# Create LAN access control set
|
||||
$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
|
||||
$NFT add element inet ss_spec ss_spec_lan_ac { $ip }
|
||||
# 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
|
||||
for ip in ${LAN_AC_IP#?}; do
|
||||
[ -n "$ip" ] && $NFT add element inet ss_spec ss_spec_lan_ac "{ $ip }" 2>/dev/null
|
||||
done
|
||||
|
||||
case "${LAN_AC_IP:0:1}" in
|
||||
case "${LAN_AC_IP%${LAN_AC_IP#?}}" in
|
||||
w | W)
|
||||
MATCH_SET_CONDITION="ip saddr @ss_spec_lan_ac"
|
||||
;;
|
||||
@@ -386,22 +401,23 @@ ac_rule_nft() {
|
||||
esac
|
||||
fi
|
||||
|
||||
# Create prerouting rules
|
||||
# Build a rule in the prerouting hook chain that jumps to business chain with conditions
|
||||
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
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport $EXT_ARGS $MATCH_SET_CONDITION comment "\"$TAG\"" goto ss_spec_wan_ac
|
||||
else
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac tcp dport $EXT_ARGS comment "\"$TAG\"" goto ss_spec_wan_ac
|
||||
# add a more specific rule at the top of ss_spec_prerouting
|
||||
$NFT insert rule inet ss_spec ss_spec_prerouting tcp $MATCH_SET_CONDITION comment "\"$TAG\"" jump ss_spec_wan_ac 2>/dev/null
|
||||
fi
|
||||
else
|
||||
# For each Interface, find its actual ifname and add an iifname-limited prerouting rule
|
||||
for name in $Interface; do
|
||||
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)
|
||||
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)
|
||||
if [ -n "$IFNAME" ]; 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
|
||||
$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
|
||||
done
|
||||
@@ -409,21 +425,21 @@ ac_rule_nft() {
|
||||
|
||||
case "$OUTPUT" in
|
||||
1)
|
||||
# Add output rules
|
||||
$NFT add chain inet ss_spec ss_spec_output { type nat hook output priority dstnat\; }
|
||||
$NFT add rule inet ss_spec ss_spec_output tcp dport $EXT_ARGS comment "\"$TAG\"" goto ss_spec_wan_ac
|
||||
# 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; }' 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output tcp comment "\"$TAG\"" jump ss_spec_wan_ac 2>/dev/null
|
||||
;;
|
||||
2)
|
||||
# Router mode output rules
|
||||
$NFT add set inet ss_spec ssr_gen_router { type ipv4_addr\; flags interval\; } 2>/dev/null
|
||||
# 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
|
||||
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
|
||||
$NFT add chain inet ss_spec ss_spec_router
|
||||
$NFT add rule inet ss_spec ss_spec_router ip daddr @ssr_gen_router return
|
||||
$NFT add rule inet ss_spec ss_spec_router goto ss_spec_wan_fw
|
||||
$NFT add chain inet ss_spec ss_spec_output { type nat hook output priority dstnat\; }
|
||||
$NFT add rule inet ss_spec ss_spec_output tcp dport comment "\"$TAG\"" goto 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 2>/dev/null
|
||||
$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; }' 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output tcp comment "\"$TAG\"" jump ss_spec_router 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
@@ -431,7 +447,7 @@ ac_rule_nft() {
|
||||
|
||||
ac_rule_iptables() {
|
||||
if [ -n "$LAN_AC_IP" ]; then
|
||||
case "${LAN_AC_IP:0:1}" in
|
||||
case "${LAN_AC_IP%${LAN_AC_IP#?}}" in
|
||||
w | W)
|
||||
MATCH_SET="-m set --match-set ss_spec_lan_ac src"
|
||||
;;
|
||||
@@ -446,14 +462,14 @@ ac_rule_iptables() {
|
||||
fi
|
||||
ipset -! -R <<-EOF || return 1
|
||||
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
|
||||
if [ -z "$Interface" ]; then
|
||||
$IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
|
||||
else
|
||||
for name in $Interface; do
|
||||
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)
|
||||
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)
|
||||
[ -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
|
||||
fi
|
||||
@@ -487,75 +503,85 @@ tp_rule() {
|
||||
}
|
||||
|
||||
tp_rule_nft() {
|
||||
# Set up routing for TPROXY
|
||||
ip rule add fwmark 0x01/0x01 table 100
|
||||
ip route add local 0.0.0.0/0 dev lo table 100
|
||||
[ -n "$TPROXY" ] || return 0
|
||||
|
||||
# Create TPROXY chain in mangle table
|
||||
# set up routing table for tproxy
|
||||
ip rule add fwmark 0x01/0x01 table 100 2>/dev/null
|
||||
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 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
|
||||
$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 ip daddr 10.0.0.0/8 return
|
||||
$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 169.254.0.0/16 return
|
||||
$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 192.168.0.0/16 return
|
||||
$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 240.0.0.0/4 return
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp dport != 53 ip daddr $SERVER return
|
||||
# basic return rules in tproxy chain
|
||||
$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 0.0.0.0/8 return 2>/dev/null
|
||||
$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 127.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 2>/dev/null
|
||||
$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 192.168.0.0/16 return 2>/dev/null
|
||||
$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 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
|
||||
$NFT add element inet ss_spec whitelist { $SERVER }
|
||||
$NFT add element inet ss_spec whitelist "{ $SERVER }" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Access control rules
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @bplan return
|
||||
# access control and tproxy rules
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy udp ip saddr @bplan return 2>/dev/null
|
||||
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
|
||||
$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
|
||||
|
||||
# Handle different run modes for nftables
|
||||
case "$RUNMODE" in
|
||||
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 @china return
|
||||
$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 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 daddr @ss_spec_wan_ac return 2>/dev/null
|
||||
$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 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 2>/dev/null
|
||||
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
|
||||
$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
|
||||
;;
|
||||
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 dport 80 drop
|
||||
$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 2>/dev/null
|
||||
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
|
||||
$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)
|
||||
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 $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 saddr @oversea tproxy to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
|
||||
$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
|
||||
$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)
|
||||
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
|
||||
$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
|
||||
;;
|
||||
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() {
|
||||
@@ -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 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 ! --dport 53 -d $SERVER -j RETURN
|
||||
[ "$server" != "$SERVER" ] && ipset -! add whitelist $SERVER
|
||||
$ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d "$SERVER" -j RETURN
|
||||
[ "$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 $PROXY_PORTS -m set --match-set fplan src -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
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
|
||||
else
|
||||
for name in $Interface; do
|
||||
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)
|
||||
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)
|
||||
[ -n "$IFNAME" ] && $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
|
||||
done
|
||||
fi
|
||||
@@ -653,15 +679,17 @@ gen_include() {
|
||||
|
||||
gen_include_nft() {
|
||||
# Generate nftables include file for firewall4
|
||||
cat <<-EOF >>$FWI
|
||||
[ -n "$FWI" ] && echo '#!/bin/sh' >"$FWI"
|
||||
cat <<-'EOF' >>"$FWI"
|
||||
# Clear existing ss_spec tables
|
||||
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
|
||||
|
||||
# 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
|
||||
chmod +x "$FWI"
|
||||
}
|
||||
|
||||
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
|
||||
;;
|
||||
b)
|
||||
WAN_BP_IP=$(for ip in $OPTARG; do echo $ip; done)
|
||||
WAN_BP_IP=$(for ip in $OPTARG; do echo "$ip"; done)
|
||||
;;
|
||||
w)
|
||||
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
|
||||
done
|
||||
|
||||
if [ -z "$server" -o -z "$local_port" ]; then
|
||||
if [ -z "$server" ] || [ -z "$local_port" ]; then
|
||||
usage 2
|
||||
fi
|
||||
|
||||
if ! echo "$local_port" | grep -qE '^[0-9]+$'; then
|
||||
loger 3 "Invalid local port: $local_port"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$TPROXY" in
|
||||
1)
|
||||
SERVER=$server
|
||||
@@ -782,7 +815,10 @@ case "$TPROXY" in
|
||||
;;
|
||||
esac
|
||||
|
||||
flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include
|
||||
RET=$?
|
||||
[ "$RET" = 0 ] || loger 3 "Start failed!"
|
||||
exit $RET
|
||||
if flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include; then
|
||||
loger 5 "Rules applied successfully"
|
||||
exit 0
|
||||
else
|
||||
loger 3 "Start failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -331,8 +331,8 @@ end
|
||||
mux = (server.v2ray_protocol ~= "wireguard") and {
|
||||
-- mux
|
||||
enabled = (server.mux == "1"), -- Mux
|
||||
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 最大并发
|
||||
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 最大并发连接数
|
||||
xudpProxyUDP443 = (server.mux == "1" and (server.xudpProxyUDP443 or "reject")) or nil -- 对被代理的 UDP/443 流量处理方式
|
||||
} or nil
|
||||
}
|
||||
@@ -631,6 +631,8 @@ local tuic = {
|
||||
return nil
|
||||
end
|
||||
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,
|
||||
zero_rtt_handshake = (server.zero_rtt_handshake == "1") and true or false,
|
||||
send_window = tonumber(server.send_window),
|
||||
@@ -715,3 +717,4 @@ function config:handleIndex(index)
|
||||
end
|
||||
local f = config:new()
|
||||
f:handleIndex(server.type)
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ config server_subscribe
|
||||
option auto_update_day_time '2'
|
||||
option auto_update_min_time '0'
|
||||
option user_agent 'v2rayN/9.99'
|
||||
option filter_words '过期时间/剩余流量/QQ群/官网/防失联地址/回国'
|
||||
option filter_words '过期/套餐/剩余/QQ群/官网/防失联/回国'
|
||||
|
||||
config access_control
|
||||
option lan_ac_mode '0'
|
||||
|
||||
@@ -42,6 +42,7 @@ local v2_ss = luci.sys.exec('type -t -p ' .. ss_program .. ' 2>/dev/null') ~= ""
|
||||
local has_ss_type = luci.sys.exec('type -t -p ' .. ss_program .. ' 2>/dev/null') ~= "" and ss_type
|
||||
local v2_tj = luci.sys.exec('type -t -p trojan') ~= "" and "trojan" or "v2ray"
|
||||
local hy2_type = luci.sys.exec('type -t -p hysteria') ~= "" and "hysteria2"
|
||||
local tuic_type = luci.sys.exec('type -t -p tuic-client') ~= "" and "tuic"
|
||||
local log = function(...)
|
||||
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " "))
|
||||
end
|
||||
@@ -173,34 +174,6 @@ local function isCompleteJSON(str)
|
||||
local success, _ = pcall(jsonParse, str)
|
||||
return success
|
||||
end
|
||||
local function detectNodeType(rawContent)
|
||||
-- 去掉 # 前后空格,处理 HTML 转义 &
|
||||
local content = trim(rawContent:gsub("&[a-zA-Z]+;", "&"):gsub("%s*#%s*", "#"))
|
||||
|
||||
-- 找到 # 分隔位置
|
||||
local idx_sp = content:find("#") or 0
|
||||
local info = content:sub(1, idx_sp > 0 and idx_sp - 1 or #content):gsub("/%?", "?")
|
||||
|
||||
-- 拆 base64 主体和 ? 参数部分
|
||||
local uri_main, query_str = info:match("^([^?]+)%??(.*)$")
|
||||
|
||||
local params = {}
|
||||
if query_str and query_str ~= "" then
|
||||
for _, v in ipairs(split(query_str, '&')) do
|
||||
local t = split(v, '=')
|
||||
if #t >= 2 then
|
||||
params[t[1]] = UrlDecode(t[2])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 判断是否是 Xray-SS 节点
|
||||
if params["type"] then
|
||||
return "shadowsocks"
|
||||
else
|
||||
return "ss"
|
||||
end
|
||||
end
|
||||
-- 处理数据
|
||||
local function processData(szType, content)
|
||||
local result = {type = szType, local_port = 1234, kcp_param = '--nocomp'}
|
||||
@@ -211,14 +184,6 @@ local function processData(szType, content)
|
||||
end
|
||||
end
|
||||
|
||||
-- 协议头识别
|
||||
if szType == "ss" then
|
||||
local nodeType = detectNodeType(content)
|
||||
if nodeType == "shadowsocks" then
|
||||
szType = "shadowsocks" -- 替换类型
|
||||
end
|
||||
end
|
||||
|
||||
if szType == "hysteria2" or szType == "hy2" then
|
||||
local url = URL.parse("http://" .. content)
|
||||
local params = url.query
|
||||
@@ -261,7 +226,7 @@ local function processData(szType, content)
|
||||
end
|
||||
if params.alpn then
|
||||
local alpn = {}
|
||||
for v in params.alpn:gmatch("[^,]+") do
|
||||
for v in params.alpn:gmatch("[^,;|%s]+") do
|
||||
table.insert(alpn, v)
|
||||
end
|
||||
result.tls_alpn = alpn
|
||||
@@ -353,8 +318,10 @@ local function processData(szType, content)
|
||||
result.xhttp_host = info.host
|
||||
result.xhttp_path = info.path
|
||||
-- 检查 extra 参数是否存在且非空
|
||||
result.enable_xhttp_extra = (info.extra and info.extra ~= "") and "1" or nil
|
||||
result.xhttp_extra = (info.extra and info.extra ~= "") and info.extra or nil
|
||||
if params.extra and params.extra ~= "" then
|
||||
result.enable_xhttp_extra = "1"
|
||||
result.xhttp_extra = params.extra
|
||||
end
|
||||
-- 尝试解析 JSON 数据
|
||||
local success, Data = pcall(jsonParse, info.extra or "")
|
||||
if success and type(Data) == "table" then
|
||||
@@ -435,20 +402,21 @@ local function processData(szType, content)
|
||||
result.security = info.security
|
||||
end
|
||||
elseif szType == "ss" then
|
||||
local content = trim(content:gsub("&[a-zA-Z]+;", "&"):gsub("%s*#%s*", "#"))
|
||||
local idx_sp = content:find("#") or 0
|
||||
local alias = ""
|
||||
if idx_sp > 0 then
|
||||
alias = UrlDecode(content:sub(idx_sp + 1))
|
||||
alias = content:sub(idx_sp + 1, -1)
|
||||
content = content:sub(0, idx_sp - 1):gsub("/%?", "?")
|
||||
end
|
||||
local info = content:sub(1, idx_sp > 0 and idx_sp - 1 or #content):gsub("/%?", "?")
|
||||
result.alias = UrlDecode(alias)
|
||||
|
||||
-- 拆 base64 主体和 ? 参数部分
|
||||
local uri_main, query_str = info:match("^([^?]+)%??(.*)$")
|
||||
--log("SS 节点格式:", uri_main)
|
||||
local info = content
|
||||
local find_index, query = info:match("^([^?]+)%??(.*)$")
|
||||
--log("SS 节点格式:", find_index)
|
||||
local params = {}
|
||||
if query_str and query_str ~= "" then
|
||||
for _, v in ipairs(split(query_str, '&')) do
|
||||
if query and query ~= "" then
|
||||
for _, v in ipairs(split(query, '&')) do
|
||||
local t = split(v, '=')
|
||||
if #t >= 2 then
|
||||
params[t[1]] = UrlDecode(t[2])
|
||||
@@ -456,28 +424,29 @@ local function processData(szType, content)
|
||||
end
|
||||
end
|
||||
|
||||
local is_old_format = uri_main:find("@") and not uri_main:find("://.*@")
|
||||
local base64_str, host_port, userinfo, server, port, method, password
|
||||
if not params.type or params.type == "" then
|
||||
local is_old_format = find_index:find("@") and not find_index:find("://.*@")
|
||||
local old_base64, host_port, userinfo, server, port, method, password
|
||||
|
||||
if is_old_format then
|
||||
-- 旧格式:base64(method:pass)@host:port
|
||||
base64_str, host_port = uri_main:match("^([^@]+)@(.-)$")
|
||||
log("SS 节点旧格式解析:", base64_str)
|
||||
if not base64_str or not host_port then
|
||||
log("SS 节点旧格式解析失败:", uri_main)
|
||||
old_base64, host_port = find_index:match("^([^@]+)@(.-)$")
|
||||
log("SS 节点旧格式解析:", old_base64)
|
||||
if not old_base64 or not host_port then
|
||||
log("SS 节点旧格式解析失败:", find_index)
|
||||
return nil
|
||||
end
|
||||
local decoded = base64Decode(UrlDecode(base64_str))
|
||||
local decoded = base64Decode(UrlDecode(old_base64))
|
||||
if not decoded then
|
||||
log("SS base64 解码失败(旧格式):", base64_str)
|
||||
log("SS base64 解码失败(旧格式):", old_base64)
|
||||
return nil
|
||||
end
|
||||
userinfo = decoded
|
||||
else
|
||||
-- 新格式:base64(method:pass@host:port)
|
||||
local decoded = base64Decode(UrlDecode(uri_main))
|
||||
local decoded = base64Decode(UrlDecode(find_index))
|
||||
if not decoded then
|
||||
log("SS base64 解码失败(新格式):", uri_main)
|
||||
log("SS base64 解码失败(新格式):", find_index)
|
||||
return nil
|
||||
end
|
||||
userinfo, host_port = decoded:match("^(.-)@(.-)$")
|
||||
@@ -488,13 +457,13 @@ local function processData(szType, content)
|
||||
end
|
||||
|
||||
-- 解析加密方式和密码(允许密码包含冒号)
|
||||
local split_pos = userinfo:find(":")
|
||||
if not split_pos then
|
||||
local meth_pass = userinfo:find(":")
|
||||
if not meth_pass then
|
||||
log("SS 用户信息格式错误:", userinfo)
|
||||
return nil
|
||||
end
|
||||
method = userinfo:sub(1, split_pos - 1)
|
||||
password = userinfo:sub(split_pos + 1)
|
||||
method = userinfo:sub(1, meth_pass - 1)
|
||||
password = userinfo:sub(meth_pass + 1)
|
||||
|
||||
-- 判断密码是否经过url编码
|
||||
local function isURLEncodedPassword(pwd)
|
||||
@@ -527,23 +496,13 @@ local function processData(szType, content)
|
||||
end
|
||||
|
||||
-- 填充 result
|
||||
result.alias = alias
|
||||
result.type = v2_ss
|
||||
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
|
||||
result.has_ss_type = has_ss_type
|
||||
result.encrypt_method_ss = method
|
||||
result.password = password
|
||||
result.server = server
|
||||
result.server_port = port
|
||||
|
||||
-- 仅在 v2ray + shadowsocks 协议时处理 ECH
|
||||
if v2_ss == "v2ray" and result.v2ray_protocol == "shadowsocks" then
|
||||
if params.ech and params.ech ~= "" then
|
||||
result.enable_ech = "1"
|
||||
result.ech_config = ech
|
||||
end
|
||||
end
|
||||
|
||||
-- 插件处理
|
||||
if params.plugin then
|
||||
local plugin_info = UrlDecode(params.plugin)
|
||||
@@ -604,6 +563,113 @@ local function processData(szType, content)
|
||||
-- log("不支持的SS加密方法:", method)
|
||||
result.server = nil
|
||||
end
|
||||
else
|
||||
local url = URL.parse("http://" .. info)
|
||||
local params = url.query
|
||||
|
||||
v2_ss = "v2ray"
|
||||
result.type = v2_ss
|
||||
result.v2ray_protocol = "shadowsocks"
|
||||
result.server = url.host
|
||||
result.server_port = url.port
|
||||
|
||||
-- 判断 @ 前部分是否为 Base64
|
||||
local is_base64 = base64Decode(UrlDecode(url.user))
|
||||
if is_base64:find(":") then
|
||||
-- 新格式:method:password
|
||||
result.encrypt_method_ss, result.password = is_base64:match("^(.-):(.*)$")
|
||||
else
|
||||
-- 旧格式:UUID 直接作为密码
|
||||
result.password = url.user
|
||||
result.encrypt_method_ss = params.encryption or "none"
|
||||
end
|
||||
|
||||
result.transport = params.type or "raw"
|
||||
if result.transport == "tcp" then
|
||||
result.transport = "raw"
|
||||
end
|
||||
if result.transport == "splithttp" then
|
||||
result.transport = "xhttp"
|
||||
end
|
||||
result.tls = (params.security == "tls" or params.security == "xtls") and "1" or "0"
|
||||
if params.alpn and params.alpn ~= "" then
|
||||
local alpn = {}
|
||||
for v in params.alpn:gmatch("[^,;|%s]+") do
|
||||
table.insert(alpn, v)
|
||||
end
|
||||
result.tls_alpn = params.alpn
|
||||
end
|
||||
result.tls_host = params.sni
|
||||
result.tls_flow = (params.security == "tls" or params.security == "reality") and params.flow or nil
|
||||
result.fingerprint = params.fp
|
||||
result.reality = (params.security == "reality") and "1" or "0"
|
||||
result.reality_publickey = params.pbk and UrlDecode(params.pbk) or nil
|
||||
result.reality_shortid = params.sid
|
||||
result.reality_spiderx = params.spx and UrlDecode(params.spx) or nil
|
||||
-- 检查 ech 参数是否存在且非空
|
||||
if params.ech and params.ech ~= "" then
|
||||
result.enable_ech = "1"
|
||||
result.ech_config = params.ech
|
||||
end
|
||||
-- 检查 pqv 参数是否存在且非空
|
||||
if params.pqv and params.pqv ~= "" then
|
||||
result.enable_mldsa65verify = "1"
|
||||
result.reality_mldsa65verify = params.pqv
|
||||
end
|
||||
if result.transport == "ws" then
|
||||
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.ws_path = params.path and UrlDecode(params.path) or "/"
|
||||
elseif result.transport == "httpupgrade" then
|
||||
result.httpupgrade_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.httpupgrade_path = params.path and UrlDecode(params.path) or "/"
|
||||
elseif result.transport == "xhttp" or result.transport == "splithttp" then
|
||||
result.xhttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.xhttp_mode = params.mode or "auto"
|
||||
result.xhttp_path = params.path and UrlDecode(params.path) or "/"
|
||||
-- 检查 extra 参数是否存在且非空
|
||||
if params.extra and params.extra ~= "" then
|
||||
result.enable_xhttp_extra = "1"
|
||||
result.xhttp_extra = params.extra
|
||||
end
|
||||
-- 尝试解析 JSON 数据
|
||||
local success, Data = pcall(jsonParse, params.extra or "")
|
||||
if success and type(Data) == "table" then
|
||||
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
|
||||
or (Data.downloadSettings and Data.downloadSettings.address)
|
||||
result.download_address = address and address ~= "" and address or nil
|
||||
else
|
||||
-- 如果解析失败,清空下载地址
|
||||
result.download_address = nil
|
||||
end
|
||||
-- make it compatible with bullshit, "h2" transport is non-existent at all
|
||||
elseif result.transport == "http" or result.transport == "h2" then
|
||||
result.transport = "h2"
|
||||
result.h2_host = params.host and UrlDecode(params.host) or nil
|
||||
result.h2_path = params.path and UrlDecode(params.path) or nil
|
||||
elseif result.transport == "kcp" then
|
||||
result.kcp_guise = params.headerType or "none"
|
||||
result.seed = params.seed
|
||||
result.mtu = 1350
|
||||
result.tti = 50
|
||||
result.uplink_capacity = 5
|
||||
result.downlink_capacity = 20
|
||||
result.read_buffer_size = 2
|
||||
result.write_buffer_size = 2
|
||||
elseif result.transport == "quic" then
|
||||
result.quic_guise = params.headerType or "none"
|
||||
result.quic_security = params.quicSecurity or "none"
|
||||
result.quic_key = params.key
|
||||
elseif result.transport == "grpc" then
|
||||
result.serviceName = params.serviceName
|
||||
result.grpc_mode = params.mode or "gun"
|
||||
elseif result.transport == "tcp" or result.transport == "raw" then
|
||||
result.tcp_guise = params.headerType or "none"
|
||||
if result.tcp_guise == "http" then
|
||||
result.tcp_host = params.host and UrlDecode(params.host) or nil
|
||||
result.tcp_path = params.path and UrlDecode(params.path) or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif szType == "sip008" then
|
||||
result.type = v2_ss
|
||||
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
|
||||
@@ -637,87 +703,82 @@ local function processData(szType, content)
|
||||
result.server = nil
|
||||
end
|
||||
elseif szType == "trojan" then
|
||||
local params = {}
|
||||
local idx_sp = 0
|
||||
local alias = ""
|
||||
|
||||
-- 提取别名(如果存在)
|
||||
local alias = ""
|
||||
if content:find("#") then
|
||||
idx_sp = content:find("#")
|
||||
local idx_sp = content:find("#")
|
||||
alias = content:sub(idx_sp + 1, -1)
|
||||
content = content:sub(0, idx_sp - 1)
|
||||
end
|
||||
local info = content:sub(1, idx_sp > 0 and idx_sp - 1 or #content)
|
||||
local hostInfo = split(info, "@")
|
||||
|
||||
-- 基础验证
|
||||
if #hostInfo < 2 then
|
||||
--log("Trojan节点格式错误: 缺少@符号")
|
||||
return nil
|
||||
end
|
||||
|
||||
local userinfo = hostInfo[1]
|
||||
local hostPort = hostInfo[2]
|
||||
|
||||
-- 分离服务器地址和端口
|
||||
local hostParts = split(hostPort, ":")
|
||||
|
||||
local server = hostParts[1]
|
||||
local port = hostParts[2]
|
||||
|
||||
-- 验证服务器地址和端口
|
||||
if #hostParts < 2 then
|
||||
--log("Trojan节点格式错误: 缺少端口号")
|
||||
return nil
|
||||
end
|
||||
|
||||
result.alias = UrlDecode(alias)
|
||||
result.type = v2_tj
|
||||
result.v2ray_protocol = "trojan"
|
||||
result.server = server
|
||||
result.password = userinfo
|
||||
|
||||
-- 分离和提取 password
|
||||
local Info = content
|
||||
local params = {}
|
||||
if Info:find("@") then
|
||||
local contents = split(Info, "@")
|
||||
result.password = UrlDecode(contents[1])
|
||||
local port = "443"
|
||||
Info = (contents[2] or ""):gsub("/%?", "?")
|
||||
|
||||
-- 分离主机和 query 参数(key=value&key2=value2)
|
||||
local query = split(Info, "%?")
|
||||
local host_port = query[1]
|
||||
for _, v in pairs(split(query[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
if #t > 1 then
|
||||
params[string.lower(t[1])] = UrlDecode(t[2])
|
||||
end
|
||||
end
|
||||
|
||||
-- 提取服务器地址和端口
|
||||
if host_port:find(":") then
|
||||
local sp = split(host_port, ":")
|
||||
result.server_port = sp[#sp]
|
||||
result.server = sp[1]
|
||||
else
|
||||
result.server = host_port
|
||||
end
|
||||
|
||||
-- 默认设置
|
||||
-- 按照官方的建议 默认验证ssl证书
|
||||
result.insecure = "0"
|
||||
result.tls = "1"
|
||||
|
||||
-- 解析查询参数(如果存在)
|
||||
if port:find("?") then
|
||||
local queryParts = split(port, "?")
|
||||
result.server_port = queryParts[1]
|
||||
|
||||
-- 解析查询参数
|
||||
for _, v in pairs(split(queryParts[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
if #t >= 2 then
|
||||
params[t[1]] = t[2]
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理参数
|
||||
if params.alpn then
|
||||
-- 处理 alpn 参数
|
||||
result.tls_alpn = params.alpn
|
||||
end
|
||||
|
||||
if params.sni then
|
||||
if params.peer or params.sni then
|
||||
-- 未指定peer(sni)默认使用remote addr
|
||||
result.tls_host = params.sni
|
||||
result.tls_host = params.peer or params.sni
|
||||
end
|
||||
|
||||
if params.allowInsecure then
|
||||
-- 处理 insecure 参数
|
||||
if params.allowinsecure == "1" or params.allowinsecure == "0" then
|
||||
result.insecure = params.allowInsecure
|
||||
else
|
||||
result.insecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
|
||||
end
|
||||
end
|
||||
if params.tfo then
|
||||
-- 处理 fast open 参数
|
||||
result.fast_open = params.tfo
|
||||
end
|
||||
else
|
||||
result.server_port = port
|
||||
end
|
||||
|
||||
-- 如果 Tojan 程序未安装则跳过订阅
|
||||
if not v2_tj then
|
||||
if not v2_tj or v2_tj == "" then
|
||||
return nil
|
||||
end
|
||||
|
||||
if params.type and params.type ~= "" then
|
||||
v2_tj = "v2ray"
|
||||
result.type = v2_tj
|
||||
result.v2ray_protocol = "trojan"
|
||||
if v2_tj ~= "trojan" then
|
||||
if params.fp then
|
||||
-- 处理 fingerprint 参数
|
||||
@@ -747,8 +808,10 @@ local function processData(szType, content)
|
||||
result.xhttp_mode = params.mode or "auto"
|
||||
result.xhttp_path = params.path and UrlDecode(params.path) or "/"
|
||||
-- 检查 extra 参数是否存在且非空
|
||||
result.enable_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil
|
||||
result.xhttp_extra = (params.extra and params.extra ~= "") and params.extra or nil
|
||||
if params.extra and params.extra ~= "" then
|
||||
result.enable_xhttp_extra = "1"
|
||||
result.xhttp_extra = params.extra
|
||||
end
|
||||
-- 尝试解析 JSON 数据
|
||||
local success, Data = pcall(jsonParse, params.extra or "")
|
||||
if success and type(Data) == "table" then
|
||||
@@ -786,6 +849,9 @@ local function processData(szType, content)
|
||||
result.tcp_path = params.path and UrlDecode(params.path) or nil
|
||||
end
|
||||
end
|
||||
else
|
||||
result.type = v2_tj
|
||||
end
|
||||
end
|
||||
elseif szType == "vless" then
|
||||
local url = URL.parse("http://" .. content)
|
||||
@@ -798,62 +864,85 @@ local function processData(szType, content)
|
||||
result.server_port = url.port
|
||||
result.vmess_id = url.user
|
||||
result.vless_encryption = params.encryption or "none"
|
||||
|
||||
-- 处理传输类型
|
||||
result.transport = params.type or "raw"
|
||||
if result.transport == "tcp" then
|
||||
result.transport = "raw"
|
||||
end
|
||||
if result.transport == "splithttp" then
|
||||
elseif result.transport == "splithttp" then
|
||||
result.transport = "xhttp"
|
||||
elseif result.transport == "http" then
|
||||
result.transport = "h2"
|
||||
end
|
||||
result.tls = (params.security == "tls" or params.security == "xtls") and "1" or "0"
|
||||
|
||||
-- TLS / Reality 标志
|
||||
local security = params.security or ""
|
||||
result.tls = (security == "tls" or security == "xtls") and "1" or "0"
|
||||
result.reality = (security == "reality") and "1" or "0"
|
||||
|
||||
-- 统一 TLS / Reality 公共字段
|
||||
result.tls_host = params.sni
|
||||
result.fingerprint = params.fp
|
||||
result.tls_flow = (security == "tls" or security == "reality") and params.flow or nil
|
||||
|
||||
-- 处理 alpn 列表
|
||||
if params.alpn and params.alpn ~= "" then
|
||||
local alpn = {}
|
||||
for v in params.alpn:gmatch("[^,]+") do
|
||||
for v in params.alpn:gmatch("[^,;|%s]+") do
|
||||
table.insert(alpn, v)
|
||||
end
|
||||
result.tls_alpn = alpn
|
||||
end
|
||||
result.tls_host = params.sni
|
||||
result.tls_flow = (params.security == "tls" or params.security == "reality") and params.flow or nil
|
||||
result.fingerprint = params.fp
|
||||
result.reality = (params.security == "reality") and "1" or "0"
|
||||
|
||||
-- Reality 参数
|
||||
if security == "reality" then
|
||||
result.reality_publickey = params.pbk and UrlDecode(params.pbk) or nil
|
||||
result.reality_shortid = params.sid
|
||||
result.reality_spiderx = params.spx and UrlDecode(params.spx) or nil
|
||||
-- 检查 ech 参数是否存在且非空
|
||||
result.enable_ech = (params.ech and params.ech ~= "") and "1" or nil
|
||||
result.ech_config = (params.ech and params.ech ~= "") and params.ech or nil
|
||||
-- 检查 pqv 参数是否存在且非空
|
||||
result.enable_mldsa65verify = (params.pqv and params.pqv ~= "") and "1" or nil
|
||||
result.reality_mldsa65verify = (params.pqv and params.pqv ~= "") and params.pqv or nil
|
||||
|
||||
-- PQ 验证参数
|
||||
if params.pqv and params.pqv ~= "" then
|
||||
result.enable_mldsa65verify = "1"
|
||||
result.reality_mldsa65verify = params.pqv
|
||||
end
|
||||
end
|
||||
|
||||
-- ECH 参数(TLS 才有)
|
||||
if security == "tls" and params.ech and params.ech ~= "" then
|
||||
result.enable_ech = "1"
|
||||
result.ech_config = params.ech
|
||||
end
|
||||
|
||||
-- 各种传输类型
|
||||
if result.transport == "ws" then
|
||||
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.ws_host = (result.tls ~= "1" and result.reality ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.ws_path = params.path and UrlDecode(params.path) or "/"
|
||||
|
||||
elseif result.transport == "httpupgrade" then
|
||||
result.httpupgrade_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.httpupgrade_host = (result.tls ~= "1" and result.reality ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.httpupgrade_path = params.path and UrlDecode(params.path) or "/"
|
||||
elseif result.transport == "xhttp" or result.transport == "splithttp" then
|
||||
result.xhttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
|
||||
elseif result.transport == "xhttp" then
|
||||
result.xhttp_host = (result.tls ~= "1" and result.reality ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.xhttp_mode = params.mode or "auto"
|
||||
result.xhttp_path = params.path and UrlDecode(params.path) or "/"
|
||||
-- 检查 extra 参数是否存在且非空
|
||||
result.enable_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil
|
||||
result.xhttp_extra = (params.extra and params.extra ~= "") and params.extra or nil
|
||||
-- 尝试解析 JSON 数据
|
||||
if params.extra and params.extra ~= "" then
|
||||
result.enable_xhttp_extra = "1"
|
||||
result.xhttp_extra = params.extra
|
||||
end
|
||||
local success, Data = pcall(jsonParse, params.extra or "")
|
||||
if success and type(Data) == "table" then
|
||||
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
|
||||
or (Data.downloadSettings and Data.downloadSettings.address)
|
||||
result.download_address = address and address ~= "" and address or nil
|
||||
else
|
||||
-- 如果解析失败,清空下载地址
|
||||
result.download_address = nil
|
||||
end
|
||||
-- make it compatible with bullshit, "h2" transport is non-existent at all
|
||||
elseif result.transport == "http" or result.transport == "h2" then
|
||||
result.transport = "h2"
|
||||
|
||||
elseif result.transport == "h2" then
|
||||
result.h2_host = params.host and UrlDecode(params.host) or nil
|
||||
result.h2_path = params.path and UrlDecode(params.path) or nil
|
||||
|
||||
elseif result.transport == "kcp" then
|
||||
result.kcp_guise = params.headerType or "none"
|
||||
result.seed = params.seed
|
||||
@@ -863,125 +952,123 @@ local function processData(szType, content)
|
||||
result.downlink_capacity = 20
|
||||
result.read_buffer_size = 2
|
||||
result.write_buffer_size = 2
|
||||
|
||||
elseif result.transport == "quic" then
|
||||
result.quic_guise = params.headerType or "none"
|
||||
result.quic_security = params.quicSecurity or "none"
|
||||
result.quic_key = params.key
|
||||
|
||||
elseif result.transport == "grpc" then
|
||||
result.serviceName = params.serviceName
|
||||
result.grpc_mode = params.mode or "gun"
|
||||
elseif result.transport == "tcp" or result.transport == "raw" then
|
||||
|
||||
elseif result.transport == "raw" then
|
||||
result.tcp_guise = params.headerType or "none"
|
||||
if result.tcp_guise == "http" then
|
||||
result.tcp_host = params.host and UrlDecode(params.host) or nil
|
||||
result.tcp_path = params.path and UrlDecode(params.path) or nil
|
||||
end
|
||||
end
|
||||
elseif szType == "shadowsocks" then
|
||||
local content = trim(content:gsub("&[a-zA-Z]+;", "&"):gsub("%s*#%s*", "#"))
|
||||
local idx_sp = content:find("#") or 0
|
||||
elseif szType == "tuic" then
|
||||
-- 提取别名(如果存在)
|
||||
local alias = ""
|
||||
if idx_sp > 0 then
|
||||
alias = UrlDecode(content:sub(idx_sp + 1))
|
||||
if content:find("#") then
|
||||
local idx_sp = content:find("#")
|
||||
alias = content:sub(idx_sp + 1, -1)
|
||||
content = content:sub(0, idx_sp - 1)
|
||||
end
|
||||
local info = content:sub(1, idx_sp > 0 and idx_sp - 1 or #content)
|
||||
local url = URL.parse("http://" .. info)
|
||||
local params = url.query
|
||||
result.alias = UrlDecode(alias)
|
||||
|
||||
result.alias = alias
|
||||
result.type = "v2ray"
|
||||
result.v2ray_protocol = "shadowsocks"
|
||||
result.server = url.host
|
||||
result.server_port = url.port
|
||||
-- 分离和提取 uuid 和 password
|
||||
local Info = content
|
||||
if Info:find("@") then
|
||||
local contents = split(Info, "@")
|
||||
if contents[1]:find(":") then
|
||||
local userinfo = split(contents[1], ":")
|
||||
result.tuic_uuid = UrlDecode(userinfo[1])
|
||||
result.tuic_passwd = UrlDecode(userinfo[2])
|
||||
end
|
||||
Info = (contents[2] or ""):gsub("/%?", "?")
|
||||
end
|
||||
|
||||
-- 判断 @ 前部分是否为 Base64
|
||||
local is_base64_decoded = base64Decode(UrlDecode(url.user))
|
||||
if is_base64_decoded:find(":") then
|
||||
-- 新格式:method:password
|
||||
result.encrypt_method_ss, result.password = is_base64_decoded:match("^(.-):(.*)$")
|
||||
-- 分离主机和 query 参数(key=value&key2=value2)
|
||||
local query = split(Info, "%?")
|
||||
local host_port = query[1]
|
||||
local params = {}
|
||||
for _, v in pairs(split(query[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
if #t > 1 then
|
||||
params[string.lower(t[1])] = UrlDecode(t[2])
|
||||
end
|
||||
end
|
||||
|
||||
-- 提取服务器地址和端口
|
||||
if host_port:find(":") then
|
||||
local sp = split(host_port, ":")
|
||||
result.server_port = sp[#sp]
|
||||
result.server = sp[1]
|
||||
else
|
||||
-- 旧格式:UUID 直接作为密码
|
||||
result.password = url.user
|
||||
result.encrypt_method_ss = params.encryption or "none"
|
||||
result.server = host_port
|
||||
end
|
||||
|
||||
result.transport = params.type or "raw"
|
||||
if result.transport == "tcp" then
|
||||
result.transport = "raw"
|
||||
end
|
||||
if result.transport == "splithttp" then
|
||||
result.transport = "xhttp"
|
||||
end
|
||||
result.tls = (params.security == "tls" or params.security == "xtls") and "1" or "0"
|
||||
result.type = tuic_type
|
||||
result.tuic_ip = params.ip or ""
|
||||
result.udp_relay_mode = params.udp_relay_mode or "native"
|
||||
result.congestion_control = params.congestion_control or "cubic"
|
||||
result.heartbeat = params.heartbeat or "3"
|
||||
result.timeout = params.timeout or "8"
|
||||
result.gc_interval = params.gc_interval or "3"
|
||||
result.gc_lifetime = params.gc_lifetime or "15"
|
||||
result.send_window = params.send_window or "20971520"
|
||||
result.receive_window = params.receive_window or "10485760"
|
||||
result.tuic_max_package_size = params.max_packet_size or "1500"
|
||||
|
||||
-- alpn 支持逗号或分号分隔
|
||||
if params.alpn and params.alpn ~= "" then
|
||||
local alpn = {}
|
||||
for v in params.alpn:gmatch("[^,]+") do
|
||||
for v in params.alpn:gmatch("[^,;|%s]+") do
|
||||
table.insert(alpn, v)
|
||||
end
|
||||
result.tls_alpn = alpn
|
||||
result.tuic_alpn = alpn
|
||||
end
|
||||
result.tls_host = params.sni
|
||||
result.tls_flow = (params.security == "tls" or params.security == "reality") and params.flow or nil
|
||||
result.fingerprint = params.fp
|
||||
result.reality = (params.security == "reality") and "1" or "0"
|
||||
result.reality_publickey = params.pbk and UrlDecode(params.pbk) or nil
|
||||
result.reality_shortid = params.sid
|
||||
result.reality_spiderx = params.spx and UrlDecode(params.spx) or nil
|
||||
-- 检查 ech 参数是否存在且非空
|
||||
result.enable_ech = (params.ech and params.ech ~= "") and "1" or nil
|
||||
result.ech_config = (params.ech and params.ech ~= "") and params.ech or nil
|
||||
-- 检查 pqv 参数是否存在且非空
|
||||
result.enable_mldsa65verify = (params.pqv and params.pqv ~= "") and "1" or nil
|
||||
result.reality_mldsa65verify = (params.pqv and params.pqv ~= "") and params.pqv or nil
|
||||
if result.transport == "ws" then
|
||||
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.ws_path = params.path and UrlDecode(params.path) or "/"
|
||||
elseif result.transport == "httpupgrade" then
|
||||
result.httpupgrade_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.httpupgrade_path = params.path and UrlDecode(params.path) or "/"
|
||||
elseif result.transport == "xhttp" or result.transport == "splithttp" then
|
||||
result.xhttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.xhttp_mode = params.mode or "auto"
|
||||
result.xhttp_path = params.path and UrlDecode(params.path) or "/"
|
||||
-- 检查 extra 参数是否存在且非空
|
||||
result.enable_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil
|
||||
result.xhttp_extra = (params.extra and params.extra ~= "") and params.extra or nil
|
||||
-- 尝试解析 JSON 数据
|
||||
local success, Data = pcall(jsonParse, params.extra or "")
|
||||
if success and type(Data) == "table" then
|
||||
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
|
||||
or (Data.downloadSettings and Data.downloadSettings.address)
|
||||
result.download_address = address and address ~= "" and address or nil
|
||||
|
||||
-- 处理 disable_sni 参数
|
||||
if params.disable_sni then
|
||||
if params.disable_sni == "1" or params.disable_sni == "0" then
|
||||
result.disable_sni = params.disable_sni
|
||||
else
|
||||
-- 如果解析失败,清空下载地址
|
||||
result.download_address = nil
|
||||
result.disable_sni = string.lower(params.disable_sni) == "true" and "1" or "0"
|
||||
end
|
||||
-- make it compatible with bullshit, "h2" transport is non-existent at all
|
||||
elseif result.transport == "http" or result.transport == "h2" then
|
||||
result.transport = "h2"
|
||||
result.h2_host = params.host and UrlDecode(params.host) or nil
|
||||
result.h2_path = params.path and UrlDecode(params.path) or nil
|
||||
elseif result.transport == "kcp" then
|
||||
result.kcp_guise = params.headerType or "none"
|
||||
result.seed = params.seed
|
||||
result.mtu = 1350
|
||||
result.tti = 50
|
||||
result.uplink_capacity = 5
|
||||
result.downlink_capacity = 20
|
||||
result.read_buffer_size = 2
|
||||
result.write_buffer_size = 2
|
||||
elseif result.transport == "quic" then
|
||||
result.quic_guise = params.headerType or "none"
|
||||
result.quic_security = params.quicSecurity or "none"
|
||||
result.quic_key = params.key
|
||||
elseif result.transport == "grpc" then
|
||||
result.serviceName = params.serviceName
|
||||
result.grpc_mode = params.mode or "gun"
|
||||
elseif result.transport == "tcp" or result.transport == "raw" then
|
||||
result.tcp_guise = params.headerType or "none"
|
||||
if result.tcp_guise == "http" then
|
||||
result.tcp_host = params.host and UrlDecode(params.host) or nil
|
||||
result.tcp_path = params.path and UrlDecode(params.path) or nil
|
||||
end
|
||||
|
||||
-- 处理 zero_rtt_handshake 参数
|
||||
if params.zero_rtt_handshake then
|
||||
if params.zero_rtt_handshake == "1" or params.zero_rtt_handshake == "0" then
|
||||
result.zero_rtt_handshake = params.zero_rtt_handshake
|
||||
else
|
||||
result.zero_rtt_handshake = string.lower(params.zero_rtt_handshake) == "true" and "1" or "0"
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理 dual_stack 参数
|
||||
if params.dual_stack then
|
||||
if params.dual_stack == "1" or params.dual_stack == "0" then
|
||||
result.dual_stack = params.dual_stack
|
||||
else
|
||||
result.dual_stack = string.lower(params.dual_stack) == "true" and "1" or "0"
|
||||
end
|
||||
-- 处理 ipstack_prefer 参数
|
||||
if params.ipstack_prefer and params.ipstack_prefer ~= "" then
|
||||
result.ipstack_prefer = params.ipstack_prefer
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理 insecure 参数
|
||||
if params.allowInsecure then
|
||||
if params.allowinsecure == "1" or params.allowinsecure == "0" then
|
||||
result.insecure = params.allowInsecure
|
||||
else
|
||||
result.insecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -997,7 +1084,7 @@ local function processData(szType, content)
|
||||
result.alias = nil
|
||||
local switch_enable = result.switch_enable
|
||||
result.switch_enable = nil
|
||||
result.hashkey = md5(jsonStringify(result))
|
||||
result.hashkey = md5(jsonStringify(result) .. "_" .. (alias or ""))
|
||||
result.alias = alias
|
||||
result.switch_enable = switch_enable
|
||||
return result
|
||||
@@ -1181,22 +1268,25 @@ local execute = function()
|
||||
-- 其他 base64 格式
|
||||
else
|
||||
-- ssd 外的格式
|
||||
nodes = split(base64Decode(raw):gsub(" ", "_"), "\n")
|
||||
nodes = split(base64Decode(raw):gsub("\r\n", "\n"), "\n")
|
||||
end
|
||||
for _, v in ipairs(nodes) do
|
||||
if v then
|
||||
if v and not string.match(v, "^%s*$") then
|
||||
xpcall(function()
|
||||
local result
|
||||
if szType then
|
||||
result = processData(szType, v)
|
||||
elseif not szType then
|
||||
local node = trim(v)
|
||||
local dat = split(node, "://")
|
||||
-- 一些奇葩的链接用"&"、"<"当做"&","#"前后带空格
|
||||
local link = node:gsub("&[a-zA-Z]+;", "&"):gsub("%s*#%s*", "#")
|
||||
local dat = split(link, "://")
|
||||
if dat and dat[1] and dat[2] then
|
||||
local dat3 = ""
|
||||
if dat[3] then
|
||||
dat3 = "://" .. dat[3]
|
||||
end
|
||||
if dat[1] == 'ss' or dat[1] == 'trojan' then
|
||||
if dat[1] == 'ss' or dat[1] == 'trojan' or dat[1] == 'tuic' then
|
||||
result = processData(dat[1], dat[2] .. dat3)
|
||||
else
|
||||
result = processData(dat[1], base64Decode(dat[2]))
|
||||
@@ -1209,6 +1299,7 @@ local execute = function()
|
||||
if result then
|
||||
-- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
|
||||
if not result.server or not result.server_port
|
||||
or result.server == "127.0.0.1"
|
||||
or result.alias == "NULL"
|
||||
or check_filer(result)
|
||||
or result.server:match("[^0-9a-zA-Z%-_%.%s]")
|
||||
@@ -1222,6 +1313,9 @@ local execute = function()
|
||||
cache[groupHash][result.hashkey] = nodeResult[index][#nodeResult[index]]
|
||||
end
|
||||
end
|
||||
end, function(err)
|
||||
log(string.format("解析节点出错: %s\n原始数据: %s", tostring(err), tostring(v)))
|
||||
end)
|
||||
end
|
||||
end
|
||||
log('成功解析节点数量: ' .. #nodes)
|
||||
@@ -1304,7 +1398,7 @@ local execute = function()
|
||||
luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &")
|
||||
end
|
||||
end
|
||||
log('新增节点数量: ' .. add, '删除节点数量: ' .. del)
|
||||
log('新增节点数量: ' .. add .. ', 删除节点数量: ' .. del)
|
||||
log('订阅更新成功')
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user