mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-06 11:36:50 +03:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ef15f7340 | ||
|
|
41563a5828 | ||
|
|
2e99ee3a17 | ||
|
|
a8db33dd28 | ||
|
|
1295e0dcb2 | ||
|
|
b6bec0fc51 | ||
|
|
769d263be2 | ||
|
|
470f11699c | ||
|
|
852b6c043a | ||
|
|
f5cafd5573 | ||
|
|
3562b913a2 | ||
|
|
f4ac9dcc77 | ||
|
|
f5a629afcf | ||
|
|
aea201bf24 | ||
|
|
1313c3b26f | ||
|
|
a3f4e942c3 | ||
|
|
4d8e4c1c13 | ||
|
|
0cb5c2daae | ||
|
|
19fbfff555 | ||
|
|
75a2ed1e29 | ||
|
|
759b6748c6 | ||
|
|
0a27784f85 | ||
|
|
3b95ac2bc3 | ||
|
|
5c51d99d73 | ||
|
|
904b90e012 | ||
|
|
5fb8343cf8 | ||
|
|
014f0f4bdf | ||
|
|
dd44e0156e | ||
|
|
927b8a53b0 | ||
|
|
7ba20905d5 | ||
|
|
5b15a56502 | ||
|
|
c31df68bec | ||
|
|
0a5229f4f6 | ||
|
|
5ecb6ef997 | ||
|
|
340c2b3505 | ||
|
|
515c0be38b | ||
|
|
59c59bcb17 | ||
|
|
e5eff41a0f | ||
|
|
bb1c06951c | ||
|
|
4999840340 | ||
|
|
6c5a271105 | ||
|
|
e336bb831c |
@@ -1,68 +1,76 @@
|
||||
# Shadowsocks
|
||||
Тут всё просто
|
||||
|
||||
## Shadowsocks-old
|
||||
## Shadowsocks
|
||||
```
|
||||
ss://YWVzLTI1Ni1nY206RmJwUDJnSStPczJKK1kzdkVhTnVuOUZ2ZjJZYUhNUlN1L1BBdEVqMks1VT0@example.com:80?type=tcp#example-ss-old
|
||||
ss://MjAyMi1ibGFrZTMtYWVzLTI1Ni1nY206ZG1DbHkvWmgxNVd3OStzK0dGWGlGVElrcHc3Yy9xQ0lTYUJyYWk3V2hoWT0@127.0.0.1:25144?type=tcp#shadowsocks-no-client
|
||||
ss://MjAyMi1ibGFrZTMtYWVzLTI1Ni1nY206S3FiWXZiNkhwb1RmTUt0N2VGcUZQSmJNNXBXaHlFU0ZKTXY2dEp1Ym1Fdz06dzRNMEx5RU9OTGQ5SWlkSGc0endTbzN2R3h4NS9aQ3hId0FpaWlxck5hcz0@127.0.0.1:26627?type=tcp#shadowsocks-client
|
||||
ss://2022-blake3-aes-256-gcm:dmCly/Zh15Ww9+s+GFXiFTIkpw7c/qCISaBrai7WhhY=@127.0.0.1:27214?type=tcp#shadowsocks-plain-user
|
||||
```
|
||||
|
||||
## Shadowsocks-2022
|
||||
## VLESS
|
||||
```
|
||||
ss://2022-blake3-aes-128-gcm:5NgF%2B9eM8h4OnrTbHp%2B8UA%3D%3D%3Am8tbs5aKLYG7dN9f3xsiKA%3D%3D@example.com:80#example-ss2022
|
||||
# tcp
|
||||
vless://94792286-7bbe-4f33-8b36-18d1bbf70723@127.0.0.1:34520?type=tcp&encryption=none&security=none#vless-tcp-none
|
||||
vless://e95163dc-905e-480a-afe5-20b146288679@127.0.0.1:16399?type=tcp&encryption=none&security=reality&pbk=tqhSkeDR6jsqC-BYCnZWBrdL33g705ba8tV5-ZboWTM&fp=chrome&sni=google.com&sid=f6&spx=%2F#vless-tcp-reality
|
||||
vless://2e9e8288-060e-4da2-8b9f-a1c81826feb7@127.0.0.1:19316?type=tcp&encryption=none&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com#vless-tcp-tls
|
||||
vless://0235c833-dc29-4202-8a7b-1bbba5b516a2@127.0.0.1:22993?type=tcp&encryption=none&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&allowInsecure=1&sni=google.com#vless-tcp-tls-insecure
|
||||
vless://17776137-e747-4268-a84d-99fd798accac@127.0.0.1:48076?type=tcp&encryption=none&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com&ech=AFP%2BDQBPAAAgACDJXiKG5eoCHfd1MbMxgccxgrbGisBPPe3bz1KVIETUXQAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAAAAAA%3D%3D#vless-tcp-tls-ech
|
||||
|
||||
# mKCP
|
||||
vless://72e201d7-7841-4a32-b266-4aa3eb776d51@127.0.0.1:17270?type=kcp&encryption=none&headerType=none&seed=AirziWi4ng&security=none#vless-mKCP
|
||||
|
||||
# WebSocket
|
||||
vless://d86daef7-565b-4ecd-a9ee-bac847ad38e6@127.0.0.1:12928?type=ws&encryption=none&path=%2Fwspath&host=google.com&security=none#vless-websocket-none
|
||||
vless://fe0f0941-09a9-4e46-bc69-e00190d7bb9c@127.0.0.1:10156?type=ws&encryption=none&path=%2Fwspath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com#vless-websocket-tls
|
||||
vless://599e8659-e2ef-47d9-bf72-2f9b4b673474@127.0.0.1:36567?type=ws&encryption=none&path=%2Fwspath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&allowInsecure=1&sni=google.com#vless-websocket-tls-insecure
|
||||
vless://4d21ce62-8723-4c4d-93e3-d586b107aa40@127.0.0.1:51394?type=ws&encryption=none&path=%2Fwspath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com&ech=AF3%2BDQBZAAAgACD7fjrtDMlcigKXFBKoLn6UDB9%2BWR6HBZpY96DlBiD%2BIwAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAApnb29nbGUuY29tAAA%3D#vless-websocket-tls-ech
|
||||
|
||||
# gRPC
|
||||
vless://974b39e3-f7bf-42b9-933c-16699c635e77@127.0.0.1:15633?type=grpc&encryption=none&serviceName=TunService&authority=&security=none#vless-gRPC-none
|
||||
vless://651e7eca-5152-46f1-baf2-d502e0af7b27@127.0.0.1:28535?type=grpc&encryption=none&serviceName=TunService&authority=authority&security=reality&pbk=nhZ7NiKfcqESa5ZeBFfsq9o18W-OWOAHLln9UmuVXSk&fp=chrome&sni=google.com&sid=11cbaeaa&spx=%2F#vless-gRPC-reality
|
||||
vless://af1f8b5f-26c9-4fe8-8ce7-6d6366c5c9ce@127.0.0.1:47904?type=grpc&encryption=none&serviceName=TunService&authority=authority&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com#vless-gRPC-tls
|
||||
vless://95f2c4bb-abcb-47ba-bfad-e181c03e4659@127.0.0.1:34530?type=grpc&encryption=none&serviceName=TunService&authority=authority&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&allowInsecure=1&sni=google.com#vless-gRPC-tls-insecure
|
||||
vless://bd39490f-9a4f-49b2-96b6-824190cf89e9@127.0.0.1:27779?type=grpc&encryption=none&serviceName=TunService&authority=authority&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com&ech=AF3%2BDQBZAAAgACBc%2FiNdo4QkTt9eQCQgkOiJVSfA9G6UWAyipaBFtBD%2FVQAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAApnb29nbGUuY29tAAA%3D#vless-gRPC-tls-ech
|
||||
|
||||
# HTTPUpgrade
|
||||
vless://2b98f144-847f-42f7-8798-e1a32d27bdc7@127.0.0.1:47154?type=httpupgrade&encryption=none&path=%2Fhttpupgradepath&host=google.com&security=none#vless-httpupgrade-none
|
||||
vless://76dbd0ff-1a35-4f0c-a9ba-3c5890b7dea6@127.0.0.1:50639?type=httpupgrade&encryption=none&path=%2Fhttpupgradepath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com#vless-httpupgrade-tls
|
||||
vless://6d229881-50ed-4f3f-995d-bd3e725fdbff@127.0.0.1:57616?type=httpupgrade&encryption=none&path=%2Fhttpupgradepath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&allowInsecure=1&sni=google.com#vless-httpupgrade-tls-insecure
|
||||
vless://1897e9e4-6f5d-4a85-9512-9192e76c3f04@127.0.0.1:38658?type=httpupgrade&encryption=none&path=%2Fhttpupgradepath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com&ech=AF3%2BDQBZAAAgACCmXTMzlrdcCk2FyINAWKZ4DBxq4%2BCgmJ69v%2BmH4EMlEQAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAApnb29nbGUuY29tAAA%3D#vless-httpupgrade-tls-ech
|
||||
|
||||
# XHTTP
|
||||
vless://c2841505-ec32-4b8d-b6dd-3e19d648c321@127.0.0.1:45507?type=xhttp&encryption=none&path=%2Fxhttppath&host=xhttp&mode=auto&security=none#vless-xhttp
|
||||
```
|
||||
|
||||
## Trojan
|
||||
```
|
||||
ss://MjAyMi1ibGFrZTMtYWVzLTEyOC1nY206Y21lZklCdDhwMTJaZm1QWUplMnNCNThRd3R3NXNKeVpUV0Z6ZENKV2taOD06eEJHZUxiMWNPTjFIeE9CenF6UlN0VFdhUUh6YWM2cFhRVFNZd2dVV2R1RT0@example.com:81?type=tcp#example-ss2022
|
||||
```
|
||||
Может быть без `?type=tcp`
|
||||
# tcp
|
||||
trojan://04agAQapcl@127.0.0.1:33641?type=tcp&security=none#trojan-tcp-none
|
||||
trojan://cME3ZlUrYF@127.0.0.1:43772?type=tcp&security=reality&pbk=DckTwU6p6pTX9QxFXOi6vH4Vzt_RCE1vMCnj2c6hvjw&fp=chrome&sni=google.com&sid=221a80cf94&spx=%2F#trojan-tcp-reality
|
||||
trojan://EJjpAj02lg@127.0.0.1:11381?type=tcp&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com#trojan-tcp-tls
|
||||
trojan://ZP2Ik5sxN3@127.0.0.1:16247?type=tcp&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&allowInsecure=1&sni=google.com#trojan-tcp-tls-insecure
|
||||
trojan://90caP481ay@127.0.0.1:59708?type=tcp&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&ech=AF3%2BDQBZAAAgACC2y%2BAe4dqthLNpfvmtE6g%2BnaJ%2FciK6P%2BREbRLkR%2Fg%2FEgAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAApnb29nbGUuY29tAAA%3D&sni=google.com#trojan-tcp-tls-ech
|
||||
|
||||
# VLESS
|
||||
# mKCP
|
||||
trojan://N5v7iIOe9G@127.0.0.1:36319?type=kcp&headerType=none&seed=P91wFIfjzZ&security=none#trojan-mKCP
|
||||
|
||||
## Reality
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@example.com:443?type=tcp&security=reality&pbk=ARQzddtXPJZHinwkPbgVpah9uwPTuzdjU9GpbUkQJkc&fp=chrome&sni=sni.server.com&sid=6cabf01472a3&spx=%2F&flow=xtls-rprx-vision#vless-reality
|
||||
```
|
||||
# WebSocket
|
||||
trojan://G3cE9phv1g@127.0.0.1:57370?type=ws&path=%2Fwspath&host=google.com&security=none#trojan-websocket-none
|
||||
trojan://FBok41WczO@127.0.0.1:59919?type=ws&path=%2Fwspath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com#trojan-websocket-tls
|
||||
trojan://bhwvndUBPA@127.0.0.1:22969?type=ws&path=%2Fwspath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&allowInsecure=1&sni=google.com#trojan-websocket-tls-insecur
|
||||
trojan://pwiduqFUWO@127.0.0.1:46765?type=ws&path=%2Fwspath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&ech=AF3%2BDQBZAAAgACCFcQYEtwrFOidJJLYHvSiN%2BljRgaAIrNHoVnio3uXAOwAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAApnb29nbGUuY29tAAA%3D&sni=google.com#trojan-websocket-tls-ech
|
||||
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@123.123.123.123:2082?security=reality&sni=sni.server.com&alpn=h2,http/1.1&allowInsecure=1&fp=chrome&pbk=ARQzddtXPJZHinwkPbgVpah9uwPTuzdjU9GpbUkQJkc&sid=6cabf01472a3&type=grpc&encryption=none#vless-reality-strange
|
||||
```
|
||||
# gRPC
|
||||
trojan://WMR7qkKhsV@127.0.0.1:27897?type=grpc&serviceName=TunService&authority=authority&security=none#trojan-gRPC-none
|
||||
trojan://KVuRNsu6KG@127.0.0.1:46077?type=grpc&serviceName=TunService&authority=authority&security=reality&pbk=Xn59i4gum3ppCICS6-_NuywrhHIVVAH54b2mjd5CFkE&fp=chrome&sni=google.com&sid=e5be&spx=%2F#trojan-gRPC-reality
|
||||
trojan://7BJtbywy8h@127.0.0.1:10627?type=grpc&serviceName=TunService&authority=authority&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com#trojan-gRPC-tls
|
||||
trojan://TI3PakvtP4@127.0.0.1:10435?type=grpc&serviceName=TunService&authority=authority&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&allowInsecure=1&sni=google.com#trojan-gRPC-tls-insecure
|
||||
trojan://mbzoVKL27h@127.0.0.1:38681?type=grpc&serviceName=TunService&authority=authority&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&ech=AF3%2BDQBZAAAgACCq72Ru3VbFlDpKttl3LccmInu8R2oAsCr8wzyxB0vZZQAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAApnb29nbGUuY29tAAA%3D&sni=google.com#trojan-gRPC-tls-ech
|
||||
|
||||
## TLS
|
||||
1.
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@example.com:443?type=tcp&security=tls&fp=&alpn=h3%2Ch2%2Chttp%2F1.1#vless-tls
|
||||
```
|
||||
# HTTPUpgrade
|
||||
trojan://uc44gBwOKQ@127.0.0.1:29085?type=httpupgrade&path=%2Fhttpupgradepath&host=google.com&security=none#trojan-httpupgrade-none
|
||||
trojan://MhNxbcVB14@127.0.0.1:32700?type=httpupgrade&path=%2Fhttpupgradepath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&sni=google.com#trojan-httpupgrade-tls
|
||||
trojan://7SOQFUpLob@127.0.0.1:28474?type=httpupgrade&path=%2Fhttpupgradepath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&allowInsecure=1&sni=google.com#trojan-httpupgrade-tls-insecure
|
||||
trojan://ou8pLSyx9N@127.0.0.1:17737?type=httpupgrade&path=%2Fhttpupgradepath&host=google.com&security=tls&fp=chrome&alpn=h2%2Chttp%2F1.1&ech=AF3%2BDQBZAAAgACB%2FlkIkit%2BblFzE7PtbYDVF3NXK8olXJ5a7YwY%2Biy9QQwAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAApnb29nbGUuY29tAAA%3D&sni=google.com#trojan-httpupgrade-tls-ech
|
||||
|
||||
2.
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@example.com:443?security=tls&sni=sni.server.com&fp=chrome&type=tcp&flow=xtls-rprx-vision&encryption=none#vless-tls-withot-alpn
|
||||
```
|
||||
3.
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@example.com:443/?type=ws&encryption=none&path=%2Fwebsocket&security=tls&sni=sni.server.com&fp=chrome#vless-tls-ws
|
||||
```
|
||||
|
||||
4.
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@example.com:443?security=tls&sni=sni.server.com&type=ws&path=/?ed%3D2560&host=sni.server.com&encryption=none#vless-tls-ws-2
|
||||
```
|
||||
|
||||
5.
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@example.com:443?security=tls&sni=sni.server.com&fp=chrome&type=ws&path=/websocket&encryption=none#vless-tls-ws-3
|
||||
```
|
||||
|
||||
6.
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@example.com:443/?type=ws&encryption=none&path=%2Fwebsocket&security=tls&sni=sni.server.com&fp=chrome#vless-tls-ws-4
|
||||
```
|
||||
|
||||
7.
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@sub.example.com:443?type=ws&path=%2Fdir%2Fpath&host=sub.example.com&security=tls#configname
|
||||
```
|
||||
|
||||
## No security
|
||||
```
|
||||
vless://8100b6eb-3fd1-4e73-8ccf-b4ac961232d6@example.com:443?type=tcp&security=none#vless-tls-no-encrypt
|
||||
# XHTTP
|
||||
trojan://VEetltxLtw@127.0.0.1:59072?type=xhttp&path=%2Fxhttppath&host=google.com&mode=auto&security=none#trojan-xhttp
|
||||
```
|
||||
@@ -164,7 +164,8 @@ sing_box() {
|
||||
if [ "$(echo -e "$sing_box_version\n$required_version" | sort -V | head -n 1)" != "$required_version" ]; then
|
||||
msg "sing-box version $sing_box_version is older than required $required_version"
|
||||
msg "Removing old version..."
|
||||
opkg remove sing-box
|
||||
service podkop stop
|
||||
opkg remove sing-box --force-depends
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
function createAdditionalSection(mainSection, network) {
|
||||
let o = mainSection.tab('additional', _('Additional Settings'));
|
||||
|
||||
o = mainSection.taboption('additional', form.Flag, 'yacd', _('Yacd enable'), _('<a href="http://openwrt.lan:9090/ui" target="_blank">openwrt.lan:9090/ui</a>'));
|
||||
o = mainSection.taboption('additional', form.Flag, 'yacd', _('Yacd enable'), '<a href="http://openwrt.lan:9090/ui" target="_blank">openwrt.lan:9090/ui</a>');
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o.ucisection = 'main';
|
||||
|
||||
o = mainSection.taboption('additional', form.Flag, 'exclude_ntp', _('Exclude NTP'), _('For issues with open connections sing-box'));
|
||||
o = mainSection.taboption('additional', form.Flag, 'exclude_ntp', _('Exclude NTP'), _('Allows you to exclude NTP protocol traffic from the tunnel'));
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o.ucisection = 'main';
|
||||
@@ -60,38 +60,27 @@ function createAdditionalSection(mainSection, network) {
|
||||
return true;
|
||||
};
|
||||
|
||||
o = mainSection.taboption('additional', form.Flag, 'split_dns_enabled', _('Split DNS'), _('DNS for the list via proxy'));
|
||||
o.default = '1';
|
||||
o = mainSection.taboption('additional', form.Value, 'bootstrap_dns_server', _('Bootstrap DNS server'), _('The DNS server used to look up the IP address of an upstream DNS server'));
|
||||
o.value('77.88.8.8', '77.88.8.8 (Yandex DNS)');
|
||||
o.value('77.88.8.1', '77.88.8.1 (Yandex DNS)');
|
||||
o.value('1.1.1.1', '1.1.1.1 (Cloudflare DNS)');
|
||||
o.value('1.0.0.1', '1.0.0.1 (Cloudflare DNS)');
|
||||
o.value('8.8.8.8', '8.8.8.8 (Google DNS)');
|
||||
o.value('8.8.4.4', '8.8.4.4 (Google DNS)');
|
||||
o.value('9.9.9.9', '9.9.9.9 (Quad9 DNS)');
|
||||
o.value('9.9.9.11', '9.9.9.11 (Quad9 DNS)');
|
||||
o.default = '77.88.8.8';
|
||||
o.rmempty = false;
|
||||
o.ucisection = 'main';
|
||||
|
||||
o = mainSection.taboption('additional', form.ListValue, 'split_dns_type', _('Split DNS Protocol Type'), _('Select DNS protocol for split'));
|
||||
o.value('doh', _('DNS over HTTPS (DoH)'));
|
||||
o.value('dot', _('DNS over TLS (DoT)'));
|
||||
o.value('udp', _('UDP (Unprotected DNS)'));
|
||||
o.default = 'udp';
|
||||
o.rmempty = false;
|
||||
o.depends('split_dns_enabled', '1');
|
||||
o.ucisection = 'main';
|
||||
|
||||
o = mainSection.taboption('additional', form.Value, 'split_dns_server', _('Split DNS Server'), _('Select or enter DNS server address'));
|
||||
Object.entries(constants.DNS_SERVER_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
o.default = '1.1.1.1';
|
||||
o.rmempty = false;
|
||||
o.depends('split_dns_enabled', '1');
|
||||
o.ucisection = 'main';
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value) {
|
||||
return _('DNS server address cannot be empty');
|
||||
}
|
||||
|
||||
const ipRegex = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}(:[0-9]{1,5})?$/;
|
||||
const domainRegex = /^(?:https:\/\/)?([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,63}(:[0-9]{1,5})?(\/[^?#\s]*)?$/;
|
||||
|
||||
if (!ipRegex.test(value) && !domainRegex.test(value)) {
|
||||
return _('Invalid DNS server format. Examples: 8.8.8.8 or dns.example.com or dns.example.com/nicedns for DoH');
|
||||
if (!ipRegex.test(value)) {
|
||||
return _('Invalid DNS server format. Example: 8.8.8.8');
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -207,7 +196,6 @@ function createAdditionalSection(mainSection, network) {
|
||||
o.rmempty = false;
|
||||
o.ucisection = 'main';
|
||||
|
||||
// TODO(ampetelin): Can be moved to advanced settings in luci
|
||||
// Extra IPs and exclusions (main section)
|
||||
o = mainSection.taboption('basic', form.Flag, 'exclude_from_ip_enabled', _('IP for exclusion'), _('Specify local IP addresses that will never use the configured route'));
|
||||
o.default = '0';
|
||||
|
||||
@@ -37,7 +37,7 @@ function createConfigSection(section, map, network) {
|
||||
o.depends('mode', 'proxy');
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.TextValue, 'proxy_string', _('Proxy Configuration URL'), _(''));
|
||||
o = s.taboption('basic', form.TextValue, 'proxy_string', _('Proxy Configuration URL'), '');
|
||||
o.depends('proxy_config_type', 'url');
|
||||
o.rows = 5;
|
||||
o.rmempty = false;
|
||||
@@ -240,6 +240,44 @@ function createConfigSection(section, map, network) {
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'domain_resolver_enabled', _('Domain Resolver'), _('Enable built-in DNS resolver for domains handled by this section'));
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o.depends('mode', 'vpn');
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'domain_resolver_dns_type', _('DNS Protocol Type'), _('Select the DNS protocol type for the domain resolver'));
|
||||
o.value('doh', _('DNS over HTTPS (DoH)'));
|
||||
o.value('dot', _('DNS over TLS (DoT)'));
|
||||
o.value('udp', _('UDP (Unprotected DNS)'));
|
||||
o.default = 'udp';
|
||||
o.rmempty = false;
|
||||
o.depends('domain_resolver_enabled', '1');
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.Value, 'domain_resolver_dns_server', _('DNS Server'), _('Select or enter DNS server address'));
|
||||
Object.entries(constants.DNS_SERVER_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
o.default = '8.8.8.8';
|
||||
o.rmempty = false;
|
||||
o.depends('domain_resolver_enabled', '1');
|
||||
o.ucisection = s.section;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value) {
|
||||
return _('DNS server address cannot be empty');
|
||||
}
|
||||
|
||||
const ipRegex = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}(:[0-9]{1,5})?$/;
|
||||
const domainRegex = /^(?:https:\/\/)?([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,63}(:[0-9]{1,5})?(\/[^?#\s]*)?$/;
|
||||
|
||||
if (!ipRegex.test(value) && !domainRegex.test(value)) {
|
||||
return _('Invalid DNS server format. Examples: 8.8.8.8 or dns.example.com or dns.example.com/nicedns for DoH');
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'community_lists_enabled', _('Community Lists'));
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
|
||||
@@ -62,12 +62,12 @@ const UPDATE_INTERVAL_OPTIONS = {
|
||||
};
|
||||
|
||||
const DNS_SERVER_OPTIONS = {
|
||||
'1.1.1.1': 'Cloudflare (1.1.1.1)',
|
||||
'8.8.8.8': 'Google (8.8.8.8)',
|
||||
'9.9.9.9': 'Quad9 (9.9.9.9)',
|
||||
'dns.adguard-dns.com': 'AdGuard Default (dns.adguard-dns.com)',
|
||||
'unfiltered.adguard-dns.com': 'AdGuard Unfiltered (unfiltered.adguard-dns.com)',
|
||||
'family.adguard-dns.com': 'AdGuard Family (family.adguard-dns.com)'
|
||||
'1.1.1.1': '1.1.1.1 (Cloudflare)',
|
||||
'8.8.8.8': '8.8.8.8 (Google)',
|
||||
'9.9.9.9': '9.9.9.9 (Quad9)',
|
||||
'dns.adguard-dns.com': 'dns.adguard-dns.com (AdGuard Default)',
|
||||
'unfiltered.adguard-dns.com': 'unfiltered.adguard-dns.com (AdGuard Unfiltered)',
|
||||
'family.adguard-dns.com': 'family.adguard-dns.com (AdGuard Family)'
|
||||
};
|
||||
|
||||
const DIAGNOSTICS_UPDATE_INTERVAL = 10000; // 10 seconds
|
||||
|
||||
@@ -37,7 +37,7 @@ return view.extend({
|
||||
</style>
|
||||
`);
|
||||
|
||||
const m = new form.Map('podkop', _(''), null, ['main', 'extra']);
|
||||
const m = new form.Map('podkop', '', null, ['main', 'extra']);
|
||||
|
||||
// Main Section
|
||||
const mainSection = m.section(form.TypedSection, 'main');
|
||||
|
||||
30
luci-app-podkop/msgmerge.sh
Normal file
30
luci-app-podkop/msgmerge.sh
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PODIR="po"
|
||||
POTFILE="$PODIR/templates/podkop.pot"
|
||||
WIDTH=120
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 <language_code> (e.g., ru, de, fr)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LANG="$1"
|
||||
POFILE="$PODIR/$LANG/podkop.po"
|
||||
|
||||
if [ ! -f "$POTFILE" ]; then
|
||||
echo "Template $POTFILE not found. Run xgettext first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "$POFILE" ]; then
|
||||
echo "Updating $POFILE"
|
||||
msgmerge --update --width="$WIDTH" --no-location "$POFILE" "$POTFILE"
|
||||
else
|
||||
echo "Creating new $POFILE using msginit"
|
||||
mkdir -p "$PODIR/$LANG"
|
||||
msginit --no-translator --no-location --locale="$LANG" --width="$WIDTH" --input="$POTFILE" --output-file="$POFILE"
|
||||
fi
|
||||
|
||||
echo "Translation file for $LANG updated."
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
25
luci-app-podkop/xgettext.sh
Normal file
25
luci-app-podkop/xgettext.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
SRC_DIR="htdocs/luci-static/resources/view/podkop"
|
||||
OUT_POT="po/templates/podkop.pot"
|
||||
ENCODING="UTF-8"
|
||||
WIDTH=120
|
||||
|
||||
mapfile -t FILES < <(find "$SRC_DIR" -type f -name "*.js")
|
||||
if [ ${#FILES[@]} -eq 0 ]; then
|
||||
echo "No JS files found in $SRC_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$OUT_POT")"
|
||||
|
||||
echo "Generating POT template from JS files in $SRC_DIR"
|
||||
xgettext --language=JavaScript \
|
||||
--keyword=_ \
|
||||
--from-code="$ENCODING" \
|
||||
--output="$OUT_POT" \
|
||||
--width="$WIDTH" \
|
||||
--package-name="PODKOP" \
|
||||
"${FILES[@]}"
|
||||
|
||||
echo "POT template generated: $OUT_POT"
|
||||
@@ -29,22 +29,65 @@ check_required_file "$PODKOP_LIB/logging.sh"
|
||||
|
||||
config_load "$PODKOP_CONFIG"
|
||||
|
||||
start_main() {
|
||||
log "Starting podkop"
|
||||
check_requirements() {
|
||||
log "Check Requirements"
|
||||
|
||||
# checking
|
||||
sing_box_version=$(sing-box version | head -n 1 | awk '{print $3}')
|
||||
required_version="1.12.0"
|
||||
local sing_box_version jq_version coreutils_base64_version
|
||||
sing_box_version="$(sing-box version | head -n1 | awk '{print $3}')"
|
||||
jq_version="$(jq --version | awk -F- '{print $2}')"
|
||||
coreutils_base64_version="$(base64 --version | head -n1 | awk '{print $4}')"
|
||||
|
||||
if [ "$(echo -e "$sing_box_version\n$required_version" | sort -V | head -n 1)" != "$required_version" ]; then
|
||||
log "The version of sing-box ($sing_box_version) is lower than the minimum version. Update sing-box: opkg update && opkg remove sing-box && opkg install sing-box" "critical"
|
||||
if [ -z "$sing_box_version" ]; then
|
||||
log "Package 'sing-box' is not installed." "error"
|
||||
exit 1
|
||||
else
|
||||
if ! is_min_package_version "$sing_box_version" "$SB_REQUIRED_VERSION"; then
|
||||
log "Package 'sing-box' version ($sing_box_version) is lower than the required minimum ($SB_REQUIRED_VERSION). Update sing-box: opkg update && opkg remove sing-box && opkg install sing-box" "error"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! service_exists "sing-box"; then
|
||||
log "Service 'sing-box' is missing. Please install the official package to ensure the service is available." "error"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$jq_version" ]; then
|
||||
log "Package 'jq' is not installed." "error"
|
||||
exit 1
|
||||
elif ! is_min_package_version "$jq_version" "$JQ_REQUIRED_VERSION"; then
|
||||
log "Package 'jq' version ($jq_version) is lower than the required minimum ($JQ_REQUIRED_VERSION)." "error"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$coreutils_base64_version" ]; then
|
||||
log "Package 'coreutils-base64' is not installed." "error"
|
||||
exit 1
|
||||
elif ! is_min_package_version "$coreutils_base64_version" "$COREUTILS_BASE64_REQUIRED_VERSION"; then
|
||||
log "Package 'coreutils-base64' version ($coreutils_base64_version) is lower than the required minimum ($COREUTILS_BASE64_REQUIRED_VERSION). This may cause issues when decoding base64 streams with missing padding, as automatic padding support is not available in older versions." "warn"
|
||||
fi
|
||||
|
||||
if grep -qE 'doh_backup_noresolv|doh_backup_server|doh_server' /etc/config/dhcp; then
|
||||
log "Detected https-dns-proxy in dhcp config. Edit /etc/config/dhcp" "warn"
|
||||
fi
|
||||
|
||||
local proxy_string interface outbound_json urltest_proxy_links dont_touch_dhcp
|
||||
config_get proxy_string "main" "proxy_string"
|
||||
config_get interface "main" "interface"
|
||||
config_get outbound_json "main" "outbound_json"
|
||||
config_get urltest_proxy_links "main" "urltest_proxy_links"
|
||||
|
||||
if [ -z "$proxy_string" ] && [ -z "$interface" ] && [ -z "$outbound_json" ] && [ -z "$urltest_proxy_links" ]; then
|
||||
log "Required options (proxy_string, interface, outbound_json, urltest_proxy_links) are missing in 'main' section. Aborted." "error"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
start_main() {
|
||||
log "Starting podkop"
|
||||
|
||||
check_requirements
|
||||
|
||||
migration
|
||||
|
||||
config_foreach process_validate_service
|
||||
@@ -66,7 +109,6 @@ start_main() {
|
||||
|
||||
# sing-box
|
||||
sing_box_init_config
|
||||
sing_box_config_check
|
||||
config_foreach add_cron_job
|
||||
/etc/init.d/sing-box start
|
||||
|
||||
@@ -83,17 +125,6 @@ start_main() {
|
||||
}
|
||||
|
||||
start() {
|
||||
local proxy_string interface outbound_json urltest_proxy_links dont_touch_dhcp
|
||||
config_get proxy_string "main" "proxy_string"
|
||||
config_get interface "main" "interface"
|
||||
config_get outbound_json "main" "outbound_json"
|
||||
config_get urltest_proxy_links "main" "urltest_proxy_links"
|
||||
|
||||
if [ -z "$proxy_string" ] && [ -z "$interface" ] && [ -z "$outbound_json" ] && [ -z "$urltest_proxy_links" ]; then
|
||||
log "Required options (proxy_string, interface, outbound_json, urltest_proxy_links) are missing in 'main' section. Aborted." "fatal"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
start_main
|
||||
config_get_bool dont_touch_dhcp "main" "dont_touch_dhcp" 0
|
||||
if [ "$dont_touch_dhcp" -eq 0 ]; then
|
||||
@@ -239,23 +270,23 @@ migration() {
|
||||
}
|
||||
|
||||
validate_service() {
|
||||
local domain="$1"
|
||||
local service="$1"
|
||||
|
||||
for valid_service in $VALID_SERVICES; do
|
||||
if [ "$domain" = "$valid_service" ]; then
|
||||
for community_service in $COMMUNITY_SERVICES; do
|
||||
if [ "$service" = "$community_service" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
log "Invalid service in domain_list: $domain. Exiting. Check config and LuCI cache"
|
||||
log "Invalid service in community lists: $service. Check config and LuCI cache. Aborted." "fatal"
|
||||
exit 1
|
||||
}
|
||||
|
||||
process_validate_service() {
|
||||
local domain_list_enabled
|
||||
config_get_bool domain_list_enabled "$section" "domain_list_enabled" 0
|
||||
if [ "$domain_list_enabled" -eq 1 ]; then
|
||||
config_list_foreach "$section" domain_list validate_service
|
||||
local community_lists_enabled
|
||||
config_get_bool community_lists_enabled "$section" "community_lists_enabled" 0
|
||||
if [ "$community_lists_enabled" -eq 1 ]; then
|
||||
config_list_foreach "$section" "community_lists" validate_service
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -401,11 +432,12 @@ dnsmasq_restore() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
local cachesize noresolv backup_servers
|
||||
local cachesize noresolv backup_servers resolvfile
|
||||
log "Restoring cachesize" "debug"
|
||||
cachesize="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_cachesize")"
|
||||
if [ -z "$cachesize" ]; then
|
||||
uci_remove "dhcp" "@dnsmasq[0]" "cachesize"
|
||||
uci_set "dhcp" "@dnsmasq[0]" "cachesize" 150
|
||||
else
|
||||
uci_set "dhcp" "@dnsmasq[0]" "cachesize" "$cachesize"
|
||||
uci_remove "dhcp" "@dnsmasq[0]" "podkop_cachesize"
|
||||
@@ -415,6 +447,7 @@ dnsmasq_restore() {
|
||||
noresolv="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_noresolv")"
|
||||
if [ -z "$noresolv" ]; then
|
||||
uci_remove "dhcp" "@dnsmasq[0]" "noresolv"
|
||||
uci_set "dhcp" "@dnsmasq[0]" "noresolv" 0
|
||||
else
|
||||
uci_set "dhcp" "@dnsmasq[0]" "noresolv" "$noresolv"
|
||||
uci_remove "dhcp" "@dnsmasq[0]" "podkop_noresolv"
|
||||
@@ -422,12 +455,18 @@ dnsmasq_restore() {
|
||||
|
||||
log "Restoring DNS servers" "debug"
|
||||
uci_remove "dhcp" "@dnsmasq[0]" "server"
|
||||
resolvfile="/tmp/resolv.conf.d/resolv.conf.auto"
|
||||
backup_servers="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_server")"
|
||||
if [ -n "$backup_servers" ]; then
|
||||
for server in $backup_servers; do
|
||||
uci_add_list "dhcp" "@dnsmasq[0]" "server" "$server"
|
||||
done
|
||||
uci_remove "dhcp" "@dnsmasq[0]" "podkop_server"
|
||||
elif file_exists "$resolvfile"; then
|
||||
log "Backup DNS servers not found, using default resolvfile" "debug"
|
||||
uci_set "dhcp" "@dnsmasq[0]" "resolvfile" "$resolvfile"
|
||||
else
|
||||
log "Backup DNS servers and default resolvfile not found, possible resolving issues" "warn"
|
||||
fi
|
||||
|
||||
uci_commit "dhcp"
|
||||
@@ -537,16 +576,6 @@ list_update() {
|
||||
fi
|
||||
}
|
||||
|
||||
find_working_resolver() {
|
||||
for resolver in $DNS_RESOLVERS; do
|
||||
if nslookup -timeout=2 $FAKEIP_TEST_DOMAIN $resolver > /dev/null 2>&1; then
|
||||
echo "$resolver"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# sing-box funcs
|
||||
|
||||
sing_box_uci() {
|
||||
@@ -670,7 +699,7 @@ configure_outbound_handler() {
|
||||
else
|
||||
outbound_tags="$outbound_tags,$outbound_tag"
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
urltest_tag="$(get_outbound_tag_by_section "$section-urltest")"
|
||||
@@ -688,15 +717,32 @@ configure_outbound_handler() {
|
||||
;;
|
||||
vpn)
|
||||
log "Configuring outbound in VPN connection mode for the $section section"
|
||||
local interface_name
|
||||
local interface_name domain_resolver_enabled domain_resolver_dns_type domain_resolver_dns_server \
|
||||
outbound_tag domain_resolver_tag dns_domain_resolver
|
||||
|
||||
config_get interface_name "$section" "interface"
|
||||
config_get domain_resolver_enabled "$section" "domain_resolver_enabled"
|
||||
config_get domain_resolver_dns_type "$section" "domain_resolver_dns_type"
|
||||
config_get domain_resolver_dns_server "$section" "domain_resolver_dns_server"
|
||||
|
||||
if [ -z "$interface_name" ]; then
|
||||
log "VPN interface is not set. Aborted." "fatal"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
config=$(sing_box_cf_add_interface_outbound "$config" "$section" "$interface_name")
|
||||
local outbound_tag
|
||||
outbound_tag="$(get_outbound_tag_by_section "$section")"
|
||||
|
||||
if [ "$domain_resolver_enabled" -eq 1 ]; then
|
||||
if ! is_ipv4 "$domain_resolver_dns_server"; then
|
||||
dns_domain_resolver=$SB_BOOTSTRAP_SERVER_TAG
|
||||
fi
|
||||
domain_resolver_tag="$(get_domain_resolver_tag "$section")"
|
||||
config=$(sing_box_cf_add_dns_server "$config" "$domain_resolver_dns_type" "$domain_resolver_tag" \
|
||||
"$domain_resolver_dns_server" "$dns_domain_resolver" "$outbound_tag")
|
||||
fi
|
||||
|
||||
config=$(sing_box_cm_add_interface_outbound "$config" "$outbound_tag" "$interface_name" "$domain_resolver_tag")
|
||||
;;
|
||||
block)
|
||||
log "Connection mode 'block' detected for the $section section – no outbound will be created (handled via reject route rules)"
|
||||
@@ -710,53 +756,21 @@ configure_outbound_handler() {
|
||||
|
||||
sing_box_configure_dns() {
|
||||
log "Configure the DNS section of a sing-box JSON configuration"
|
||||
local split_dns_enabled final_dns_server
|
||||
config_get_bool split_dns_enabled "main" "split_dns_enabled" 0
|
||||
if [ "$split_dns_enabled" -eq 1 ]; then
|
||||
final_dns_server="$SB_SPLIT_DNS_SERVER_TAG"
|
||||
else
|
||||
final_dns_server="$SB_DNS_SERVER_TAG"
|
||||
fi
|
||||
config=$(sing_box_cm_configure_dns "$config" "$final_dns_server" "ipv4_only" true)
|
||||
config=$(sing_box_cm_configure_dns "$config" "$SB_DNS_SERVER_TAG" "ipv4_only" true)
|
||||
|
||||
local dns_type dns_server split_dns_type split_dns_server dns_server_address split_dns_server_address
|
||||
log "Adding DNS Servers" "debug"
|
||||
local dns_type dns_server bootstrap_dns_server dns_domain_resolver
|
||||
config_get dns_type "main" "dns_type" "doh"
|
||||
config_get dns_server "main" "dns_server" "1.1.1.1"
|
||||
config_get split_dns_type "main" "split_dns_type" "udp"
|
||||
config_get split_dns_server "main" "split_dns_server" "1.1.1.1"
|
||||
dns_server_address=$(url_get_host "$dns_server")
|
||||
split_dns_server_address=$(url_get_host "$split_dns_server")
|
||||
config_get bootstrap_dns_server "main" "bootstrap_dns_server" "77.88.8.8"
|
||||
|
||||
local need_dns_domain_resolver=0
|
||||
if ! is_ipv4 "$dns_server_address" || ! is_ipv4 "$split_dns_server_address"; then
|
||||
need_dns_domain_resolver=1
|
||||
fi
|
||||
|
||||
log "Adding DNS Servers"
|
||||
config=$(sing_box_cm_add_fakeip_dns_server "$config" "$SB_FAKEIP_DNS_SERVER_TAG" "$SB_FAKEIP_INET4_RANGE")
|
||||
|
||||
local dns_domain_resolver
|
||||
if [ "$need_dns_domain_resolver" -eq 1 ]; then
|
||||
log "One of the DNS server addresses is a domain. Searching for a working DNS server..."
|
||||
dns_domain_resolver=$(find_working_resolver)
|
||||
if [ -z "$dns_domain_resolver" ]; then
|
||||
log "Working DNS server not found, using default DNS server"
|
||||
dns_domain_resolver="1.1.1.1"
|
||||
else
|
||||
log "Working DNS server has been found: $dns_domain_resolver"
|
||||
fi
|
||||
config=$(sing_box_cm_add_udp_dns_server "$config" "$SB_DNS_DOMAIN_RESOLVER_TAG" "$dns_domain_resolver" 53)
|
||||
dns_domain_resolver="$SB_DNS_DOMAIN_RESOLVER_TAG"
|
||||
if ! is_ipv4 "$dns_server"; then
|
||||
dns_domain_resolver=$SB_BOOTSTRAP_SERVER_TAG
|
||||
fi
|
||||
|
||||
config=$(sing_box_cm_add_udp_dns_server "$config" "$SB_BOOTSTRAP_SERVER_TAG" "$bootstrap_dns_server" 53)
|
||||
config=$(sing_box_cf_add_dns_server "$config" "$dns_type" "$SB_DNS_SERVER_TAG" "$dns_server" "$dns_domain_resolver")
|
||||
|
||||
if [ "$split_dns_enabled" -eq 1 ]; then
|
||||
config=$(
|
||||
sing_box_cf_add_dns_server "$config" "$split_dns_type" "$SB_SPLIT_DNS_SERVER_TAG" "$split_dns_server" \
|
||||
"$dns_domain_resolver" "$SB_MAIN_OUTBOUND_TAG"
|
||||
)
|
||||
fi
|
||||
config=$(sing_box_cm_add_fakeip_dns_server "$config" "$SB_FAKEIP_DNS_SERVER_TAG" "$SB_FAKEIP_INET4_RANGE")
|
||||
|
||||
log "Adding DNS Rules"
|
||||
local rewrite_ttl service_domains
|
||||
@@ -768,11 +782,6 @@ sing_box_configure_dns() {
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "rewrite_ttl" "$rewrite_ttl")
|
||||
service_domains=$(comma_string_to_json_array "$FAKEIP_TEST_DOMAIN,$CHECK_PROXY_IP_DOMAIN")
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "domain" "$service_domains")
|
||||
if [ "$split_dns_enabled" -eq 1 ]; then
|
||||
config=$(sing_box_cm_add_dns_route_rule "$config" "$SB_DNS_SERVER_TAG" "$SB_INVERT_FAKEIP_DNS_RULE_TAG")
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_INVERT_FAKEIP_DNS_RULE_TAG" "invert" true)
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_INVERT_FAKEIP_DNS_RULE_TAG" "domain" "$service_domains")
|
||||
fi
|
||||
}
|
||||
|
||||
sing_box_configure_route() {
|
||||
@@ -951,7 +960,9 @@ prepare_common_ruleset() {
|
||||
config=$(sing_box_cm_add_local_ruleset "$config" "$ruleset_tag" "source" "$ruleset_filepath")
|
||||
config=$(sing_box_cm_patch_route_rule "$config" "$route_rule_tag" "rule_set" "$ruleset_tag")
|
||||
case "$type" in
|
||||
domains) _add_ruleset_to_dns_rules "$ruleset_tag" "$route_rule_tag" ;;
|
||||
domains)
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "rule_set" "$ruleset_tag")
|
||||
;;
|
||||
subnets) ;;
|
||||
*) log "Unsupported remote rule set type: $type" "warn" ;;
|
||||
esac
|
||||
@@ -971,8 +982,8 @@ configure_community_list_handler() {
|
||||
config_get update_interval "main" "update_interval" "1d"
|
||||
|
||||
config=$(sing_box_cm_add_remote_ruleset "$config" "$ruleset_tag" "$format" "$url" "$detour" "$update_interval")
|
||||
_add_ruleset_to_dns_rules "$ruleset_tag"
|
||||
config=$(sing_box_cm_patch_route_rule "$config" "$route_rule_tag" "rule_set" "$ruleset_tag")
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "rule_set" "$ruleset_tag")
|
||||
}
|
||||
|
||||
configure_user_domain_or_subnets_list() {
|
||||
@@ -1031,7 +1042,7 @@ configure_local_domain_or_subnet_lists() {
|
||||
domains)
|
||||
config_list_foreach "$section" "local_domain_lists" import_local_domain_or_subnet_list "$type" \
|
||||
"$section" "$ruleset_filepath"
|
||||
_add_ruleset_to_dns_rules "$ruleset_tag" "$route_rule_tag"
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "rule_set" "$ruleset_tag")
|
||||
;;
|
||||
subnets)
|
||||
config_list_foreach "$section" "local_subnet_lists" import_local_domain_or_subnet_list "$type" \
|
||||
@@ -1091,7 +1102,9 @@ configure_remote_domain_or_subnet_list_handler() {
|
||||
config=$(sing_box_cm_add_remote_ruleset "$config" "$ruleset_tag" "$format" "$url" "$detour" "$update_interval")
|
||||
config=$(sing_box_cm_patch_route_rule "$config" "$route_rule_tag" "rule_set" "$ruleset_tag")
|
||||
case "$type" in
|
||||
domains) _add_ruleset_to_dns_rules "$ruleset_tag" "$route_rule_tag" ;;
|
||||
domains)
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "rule_set" "$ruleset_tag")
|
||||
;;
|
||||
subnets) ;;
|
||||
*) log "Unsupported remote rule set type: $type" "warn" ;;
|
||||
esac
|
||||
@@ -1102,17 +1115,6 @@ configure_remote_domain_or_subnet_list_handler() {
|
||||
esac
|
||||
}
|
||||
|
||||
_add_ruleset_to_dns_rules() {
|
||||
local ruleset_tag="$1"
|
||||
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "rule_set" "$ruleset_tag")
|
||||
local split_dns_enabled final_dns_server
|
||||
config_get_bool split_dns_enabled "main" "split_dns_enabled" 0
|
||||
if [ "$split_dns_enabled" -eq 1 ]; then
|
||||
config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_INVERT_FAKEIP_DNS_RULE_TAG" "rule_set" "$ruleset_tag")
|
||||
fi
|
||||
}
|
||||
|
||||
sing_box_configure_experimental() {
|
||||
log "Configure the experimental section of a sing-box JSON configuration"
|
||||
|
||||
@@ -1167,6 +1169,8 @@ sing_box_save_config() {
|
||||
log "Save sing-box temporary config to $temp_file_path" "debug"
|
||||
sing_box_cm_save_config_to_file "$config" "$temp_file_path"
|
||||
|
||||
sing_box_config_check "$temp_file_path"
|
||||
|
||||
current_config_hash=$(md5sum "$sing_box_config_path" 2> /dev/null | awk '{print $1}')
|
||||
temp_config_hash=$(md5sum "$temp_file_path" | awk '{print $1}')
|
||||
log "Current sing-box config hash: $current_config_hash" "debug"
|
||||
@@ -1181,10 +1185,10 @@ sing_box_save_config() {
|
||||
}
|
||||
|
||||
sing_box_config_check() {
|
||||
local sing_box_config_path
|
||||
config_get sing_box_config_path "main" "config_path"
|
||||
if ! sing-box -c "$sing_box_config_path" check > /dev/null 2>&1; then
|
||||
log "Sing-box configuration is invalid" "fatal"
|
||||
local config_path="$1"
|
||||
|
||||
if ! sing-box -c "$config_path" check > /dev/null 2>&1; then
|
||||
log "Sing-box configuration $config_path is invalid" "fatal"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
@@ -1752,15 +1756,14 @@ show_sing_box_config() {
|
||||
}
|
||||
|
||||
show_config() {
|
||||
if [ ! -f /etc/config/podkop ]; then
|
||||
if [ ! -f "$PODKOP_CONFIG" ]; then
|
||||
nolog "Configuration file not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
tmp_config=$(mktemp)
|
||||
|
||||
cat /etc/config/podkop | sed \
|
||||
-e 's/\(option proxy_string\).*/\1 '\''MASKED'\''/g' \
|
||||
sed -e 's/\(option proxy_string\).*/\1 '\''MASKED'\''/g' \
|
||||
-e 's/\(option outbound_json\).*/\1 '\''MASKED'\''/g' \
|
||||
-e 's/\(option second_proxy_string\).*/\1 '\''MASKED'\''/g' \
|
||||
-e 's/\(option second_outbound_json\).*/\1 '\''MASKED'\''/g' \
|
||||
@@ -1769,8 +1772,9 @@ show_config() {
|
||||
-e 's/\(pbk=[^&]*\)/pbk=MASKED/g' \
|
||||
-e 's/\(sid=[^&]*\)/sid=MASKED/g' \
|
||||
-e 's/\(option dns_server '\''[^'\'']*\.dns\.nextdns\.io'\''\)/option dns_server '\''MASKED.dns.nextdns.io'\''/g' \
|
||||
-e "s|\(option dns_server 'dns\.nextdns\.io\)/[^']*|\1/MASKED|"
|
||||
> "$tmp_config"
|
||||
-e "s|\(option dns_server 'dns\.nextdns\.io\)/[^']*|\1/MASKED|" \
|
||||
-e 's/\(list urltest_proxy_links\).*/\1 '\''MASKED'\''/g' \
|
||||
"$PODKOP_CONFIG" > "$tmp_config"
|
||||
|
||||
cat "$tmp_config"
|
||||
rm -f "$tmp_config"
|
||||
@@ -1949,6 +1953,16 @@ print_global() {
|
||||
echo "$message"
|
||||
}
|
||||
|
||||
find_working_resolver() {
|
||||
for resolver in $DNS_RESOLVERS; do
|
||||
if nslookup -timeout=2 "$FAKEIP_TEST_DOMAIN" "$resolver" > /dev/null 2>&1; then
|
||||
echo "$resolver"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
global_check() {
|
||||
print_global "📡 Global check run!"
|
||||
print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
@@ -9,6 +9,8 @@ FAKEIP_TEST_DOMAIN="fakeip.podkop.fyi"
|
||||
TMP_SING_BOX_FOLDER="/tmp/sing-box"
|
||||
TMP_RULESET_FOLDER="$TMP_SING_BOX_FOLDER/rulesets"
|
||||
CLOUDFLARE_OCTETS="8.47 162.159 188.114" # Endpoints https://github.com/ampetelin/warp-endpoint-checker
|
||||
JQ_REQUIRED_VERSION="1.7.1"
|
||||
COREUTILS_BASE64_REQUIRED_VERSION="9.7"
|
||||
|
||||
## nft
|
||||
NFT_TABLE_NAME="PodkopTable"
|
||||
@@ -18,14 +20,14 @@ NFT_DISCORD_SET_NAME="podkop_discord_subnets"
|
||||
NFT_INTERFACE_SET_NAME="interfaces"
|
||||
|
||||
## sing-box
|
||||
SB_REQUIRED_VERSION="1.12.0"
|
||||
# Log
|
||||
SB_DEFAULT_LOG_LEVEL="warn"
|
||||
# DNS
|
||||
SB_DNS_SERVER_TAG="dns-server"
|
||||
SB_SPLIT_DNS_SERVER_TAG="split-dns-server"
|
||||
SB_FAKEIP_DNS_SERVER_TAG="fakeip-server"
|
||||
SB_FAKEIP_INET4_RANGE="198.18.0.0/15"
|
||||
SB_DNS_DOMAIN_RESOLVER_TAG="dns-domain-resolver"
|
||||
SB_BOOTSTRAP_SERVER_TAG="bootstrap-dns-server"
|
||||
SB_FAKEIP_DNS_RULE_TAG="fakeip-dns-rule-tag"
|
||||
SB_INVERT_FAKEIP_DNS_RULE_TAG="invert-fakeip-dns-rule-tag"
|
||||
# Inbounds
|
||||
@@ -63,4 +65,4 @@ SUBNETS_HETZNER="${GITHUB_RAW_URL}/Subnets/IPv4/hetzner.lst"
|
||||
SUBNETS_OVH="${GITHUB_RAW_URL}/Subnets/IPv4/ovh.lst"
|
||||
SUBNETS_DIGITALOCEAN="${GITHUB_RAW_URL}/Subnets/IPv4/digitalocean.lst"
|
||||
SUBNETS_CLOUDFRONT="${GITHUB_RAW_URL}/Subnets/IPv4/cloudfront.lst"
|
||||
VALID_SERVICES="russia_inside russia_outside ukraine_inside geoblock block porn news anime youtube discord meta twitter hdrezka tiktok telegram cloudflare google_ai google_play hetzner ovh hodca digitalocean cloudfront"
|
||||
COMMUNITY_SERVICES="russia_inside russia_outside ukraine_inside geoblock block porn news anime youtube hdrezka tiktok google_ai google_play hodca discord meta twitter cloudflare cloudfront digitalocean hetzner ovh telegram"
|
||||
@@ -40,6 +40,25 @@ is_base64() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Checks if the given string looks like a Shadowsocks userinfo
|
||||
is_shadowsocks_userinfo_format() {
|
||||
local str="$1"
|
||||
local regex='^[^:]+:[^:]+(:[^:]+)?$'
|
||||
|
||||
[[ "$str" =~ $regex ]]
|
||||
}
|
||||
|
||||
# Compares the current package version with the required minimum
|
||||
is_min_package_version() {
|
||||
local current="$1"
|
||||
local required="$2"
|
||||
|
||||
local lowest
|
||||
lowest="$(printf '%s\n' "$current" "$required" | sort -V | head -n1)"
|
||||
|
||||
[ "$lowest" = "$required" ]
|
||||
}
|
||||
|
||||
# Checks if the given file exists
|
||||
file_exists() {
|
||||
local filepath="$1"
|
||||
@@ -51,6 +70,17 @@ file_exists() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Checks if a service script exists in /etc/init.d
|
||||
service_exists() {
|
||||
local service="$1"
|
||||
|
||||
if [ -x "/etc/init.d/$service" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns the inbound tag name by appending the postfix to the given section
|
||||
get_inbound_tag_by_section() {
|
||||
local section="$1"
|
||||
@@ -67,6 +97,14 @@ get_outbound_tag_by_section() {
|
||||
echo "$section-$postfix"
|
||||
}
|
||||
|
||||
# Constructs and returns a domain resolver tag by appending a fixed postfix to the given section
|
||||
get_domain_resolver_tag() {
|
||||
local section="$1"
|
||||
local postfix="domain-resolver"
|
||||
|
||||
echo "$section-$postfix"
|
||||
}
|
||||
|
||||
# Constructs and returns a ruleset tag using section, name, optional type, and a fixed postfix
|
||||
get_ruleset_tag() {
|
||||
local section="$1"
|
||||
@@ -176,6 +214,13 @@ url_get_file_extension() {
|
||||
esac
|
||||
}
|
||||
|
||||
# Remove url fragment (everything after the first '#')
|
||||
url_strip_fragment() {
|
||||
local url="$1"
|
||||
|
||||
echo "${url%%#*}"
|
||||
}
|
||||
|
||||
# Decodes and returns a base64-encoded string
|
||||
base64_decode() {
|
||||
local str="$1"
|
||||
@@ -299,33 +344,11 @@ parse_domain_or_subnet_string_to_commas_string() {
|
||||
local string="$1"
|
||||
local type="$2"
|
||||
|
||||
local result
|
||||
for item in $string; do
|
||||
case "$type" in
|
||||
domains)
|
||||
if ! is_domain_suffix "$item"; then
|
||||
log "'$item' is not a valid domain" "debug"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
subnets)
|
||||
if ! is_ipv4_ip_or_ipv4_cidr "$item"; then
|
||||
log "'$item' is not IPv4 or IPv4 CIDR" "debug"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "Unknown type: $type" "error"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
tmpfile=$(mktemp)
|
||||
printf "%s\n" "$string" | sed 's/\/\/.*//' | tr ', ' '\n' | grep -v '^$' > "$tmpfile"
|
||||
|
||||
if [ -z "$result" ]; then
|
||||
result="$item"
|
||||
else
|
||||
result="$result,$item"
|
||||
fi
|
||||
done
|
||||
result="$(parse_domain_or_subnet_file_to_comma_string "$tmpfile" "$type")"
|
||||
rm -f "$tmpfile"
|
||||
|
||||
echo "$result"
|
||||
}
|
||||
@@ -345,6 +368,8 @@ parse_domain_or_subnet_file_to_comma_string() {
|
||||
|
||||
local result
|
||||
while IFS= read -r line; do
|
||||
line=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
|
||||
[ -z "$line" ] && continue
|
||||
|
||||
case "$type" in
|
||||
|
||||
@@ -62,6 +62,7 @@ sing_box_cf_add_proxy_outbound() {
|
||||
local udp_over_tcp="$4"
|
||||
|
||||
url=$(url_decode "$url")
|
||||
url=$(url_strip_fragment "$url")
|
||||
|
||||
local scheme="${url%%://*}"
|
||||
case "$scheme" in
|
||||
@@ -75,64 +76,19 @@ sing_box_cf_add_proxy_outbound() {
|
||||
packet_encoding=$(url_get_query_param "$url" "packetEncoding")
|
||||
|
||||
config=$(sing_box_cm_add_vless_outbound "$config" "$tag" "$host" "$port" "$uuid" "$flow" "" "$packet_encoding")
|
||||
|
||||
local transport
|
||||
transport=$(url_get_query_param "$url" "type")
|
||||
case "$transport" in
|
||||
tcp | raw) ;;
|
||||
ws)
|
||||
local ws_path ws_host ws_early_data
|
||||
ws_path=$(url_get_query_param "$url" "path")
|
||||
ws_host=$(url_get_query_param "$url" "host")
|
||||
ws_early_data=$(url_get_query_param "$url" "ed")
|
||||
|
||||
config=$(sing_box_cm_set_vless_ws_transport "$config" "$tag" "$ws_path" "$ws_host" "$ws_early_data")
|
||||
;;
|
||||
grpc)
|
||||
# TODO(ampetelin): Add handling of optional gRPC parameters; example links are needed.
|
||||
config=$(sing_box_cm_set_vless_grpc_transport "$config" "$tag")
|
||||
;;
|
||||
*)
|
||||
log "Unknown transport '$transport' detected." "error"
|
||||
;;
|
||||
esac
|
||||
|
||||
local security
|
||||
security=$(url_get_query_param "$url" "security")
|
||||
case "$security" in
|
||||
tls | reality)
|
||||
local sni insecure alpn fingerprint public_key short_id
|
||||
sni=$(url_get_query_param "$url" "sni")
|
||||
insecure=$(url_get_query_param "$url" "allowInsecure")
|
||||
alpn=$(comma_string_to_json_array "$(url_get_query_param "$url" "alpn")")
|
||||
fingerprint=$(url_get_query_param "$url" "fp")
|
||||
public_key=$(url_get_query_param "$url" "pbk")
|
||||
short_id=$(url_get_query_param "$url" "sid")
|
||||
|
||||
config=$(
|
||||
sing_box_cm_set_vless_tls \
|
||||
"$config" \
|
||||
"$tag" \
|
||||
"$sni" \
|
||||
"$([ "$insecure" == "1" ] && echo true)" \
|
||||
"$([ "$alpn" == "[]" ] && echo null || echo "$alpn")" \
|
||||
"$fingerprint" \
|
||||
"$public_key" \
|
||||
"$short_id"
|
||||
)
|
||||
;;
|
||||
none) ;;
|
||||
*)
|
||||
log "Unknown security '$security' detected." "error"
|
||||
;;
|
||||
esac
|
||||
config=$(_add_outbound_security "$config" "$tag" "$url")
|
||||
config=$(_add_outbound_transport "$config" "$tag" "$url")
|
||||
;;
|
||||
ss)
|
||||
local userinfo tag host port method password udp_over_tcp
|
||||
|
||||
userinfo=$(url_get_userinfo "$url")
|
||||
if is_base64 "$userinfo"; then
|
||||
if ! is_shadowsocks_userinfo_format "$userinfo"; then
|
||||
userinfo=$(base64_decode "$userinfo")
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Cannot decode shadowsocks userinfo or it does not match the expected format. Aborted." "fatal"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
tag=$(get_outbound_tag_by_section "$section")
|
||||
@@ -153,6 +109,17 @@ sing_box_cf_add_proxy_outbound() {
|
||||
"$([ "$udp_over_tcp" == "1" ] && echo 2)" # if udp_over_tcp is enabled, enable version 2
|
||||
)
|
||||
;;
|
||||
trojan)
|
||||
local tag host port password
|
||||
tag=$(get_outbound_tag_by_section "$section")
|
||||
host=$(url_get_host "$url")
|
||||
port=$(url_get_port "$url")
|
||||
password=$(url_get_userinfo "$url")
|
||||
|
||||
config=$(sing_box_cm_add_trojan_outbound "$config" "$tag" "$host" "$port" "$password")
|
||||
config=$(_add_outbound_security "$config" "$tag" "$url")
|
||||
config=$(_add_outbound_transport "$config" "$tag" "$url")
|
||||
;;
|
||||
*)
|
||||
log "Unsupported proxy $scheme type"
|
||||
exit 1
|
||||
@@ -162,6 +129,75 @@ sing_box_cf_add_proxy_outbound() {
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
_add_outbound_security() {
|
||||
local config="$1"
|
||||
local outbound_tag="$2"
|
||||
local url="$3"
|
||||
|
||||
local security
|
||||
security=$(url_get_query_param "$url" "security")
|
||||
case "$security" in
|
||||
tls | reality)
|
||||
local sni insecure alpn fingerprint public_key short_id
|
||||
sni=$(url_get_query_param "$url" "sni")
|
||||
insecure=$(url_get_query_param "$url" "allowInsecure")
|
||||
alpn=$(comma_string_to_json_array "$(url_get_query_param "$url" "alpn")")
|
||||
fingerprint=$(url_get_query_param "$url" "fp")
|
||||
public_key=$(url_get_query_param "$url" "pbk")
|
||||
short_id=$(url_get_query_param "$url" "sid")
|
||||
|
||||
config=$(
|
||||
sing_box_cm_set_tls_for_outbound \
|
||||
"$config" \
|
||||
"$outbound_tag" \
|
||||
"$sni" \
|
||||
"$([ "$insecure" == "1" ] && echo true)" \
|
||||
"$([ "$alpn" == "[]" ] && echo null || echo "$alpn")" \
|
||||
"$fingerprint" \
|
||||
"$public_key" \
|
||||
"$short_id"
|
||||
)
|
||||
;;
|
||||
none) ;;
|
||||
*)
|
||||
log "Unknown security '$security' detected." "error"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
_add_outbound_transport() {
|
||||
local config="$1"
|
||||
local outbound_tag="$2"
|
||||
local url="$3"
|
||||
|
||||
local transport
|
||||
transport=$(url_get_query_param "$url" "type")
|
||||
case "$transport" in
|
||||
tcp | raw) ;;
|
||||
ws)
|
||||
local ws_path ws_host ws_early_data
|
||||
ws_path=$(url_get_query_param "$url" "path")
|
||||
ws_host=$(url_get_query_param "$url" "host")
|
||||
ws_early_data=$(url_get_query_param "$url" "ed")
|
||||
|
||||
config=$(
|
||||
sing_box_cm_set_ws_transport_for_outbound "$config" "$outbound_tag" "$ws_path" "$ws_host" "$ws_early_data"
|
||||
)
|
||||
;;
|
||||
grpc)
|
||||
# TODO(ampetelin): Add handling of optional gRPC parameters; example links are needed.
|
||||
config=$(sing_box_cm_set_grpc_transport_for_outbound "$config" "$outbound_tag")
|
||||
;;
|
||||
*)
|
||||
log "Unknown transport '$transport' detected." "error"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
sing_box_cf_add_json_outbound() {
|
||||
local config="$1"
|
||||
local section="$2"
|
||||
|
||||
@@ -622,7 +622,47 @@ sing_box_cm_add_vless_outbound() {
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Set gRPC transport settings for a VLESS outbound in a sing-box JSON configuration.
|
||||
# Add a Trojan outbound to the outbounds section of a sing-box JSON configuration.
|
||||
# Arguments:
|
||||
# config: string, JSON configuration
|
||||
# tag: string, identifier for the outbound
|
||||
# server_address: string, IP address or hostname of the Trojan server
|
||||
# server_port: number, port of the Trojan server
|
||||
# password: string, password for authentication
|
||||
# network: string, optional network type (e.g., "tcp")
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_add_trojan_outbound "$CONFIG" "trojan-out" "example.com" 443 "supersecretpassword" "tcp")
|
||||
#######################################
|
||||
sing_box_cm_add_trojan_outbound() {
|
||||
local config="$1"
|
||||
local tag="$2"
|
||||
local server_address="$3"
|
||||
local server_port="$4"
|
||||
local password="$5"
|
||||
local network="$6"
|
||||
|
||||
echo "$config" | jq \
|
||||
--arg tag "$tag" \
|
||||
--arg server_address "$server_address" \
|
||||
--arg server_port "$server_port" \
|
||||
--arg password "$password" \
|
||||
--arg network "$network" \
|
||||
'.outbounds += [(
|
||||
{
|
||||
type: "trojan",
|
||||
tag: $tag,
|
||||
server: $server_address,
|
||||
server_port: ($server_port | tonumber),
|
||||
password: $password
|
||||
}
|
||||
+ (if $network != "" then {network: $network} else {} end)
|
||||
)]'
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Set gRPC transport settings for an outbound in a sing-box JSON configuration.
|
||||
# Arguments:
|
||||
# config: JSON configuration (string)
|
||||
# tag: string, identifier of the outbound to modify
|
||||
@@ -633,9 +673,9 @@ sing_box_cm_add_vless_outbound() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_set_vless_grpc_transport "$CONFIG" "vless-tls-grpc-out")
|
||||
# CONFIG=$(sing_box_cm_set_grpc_transport_for_outbound "$CONFIG" "vless-tls-grpc-out")
|
||||
#######################################
|
||||
sing_box_cm_set_vless_grpc_transport() {
|
||||
sing_box_cm_set_grpc_transport_for_outbound() {
|
||||
local config="$1"
|
||||
local tag="$2"
|
||||
local service_name="$3"
|
||||
@@ -667,7 +707,7 @@ sing_box_cm_set_vless_grpc_transport() {
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Set WebSocket transport settings for a VLESS outbound in a sing-box JSON configuration.
|
||||
# Set WebSocket transport settings for an outbound in a sing-box JSON configuration.
|
||||
# Arguments:
|
||||
# config: JSON configuration (string)
|
||||
# tag: string, identifier of the outbound to modify
|
||||
@@ -678,9 +718,9 @@ sing_box_cm_set_vless_grpc_transport() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_set_vless_ws_transport "$CONFIG" "vless-tls-ws-out" "/path" "example.com")
|
||||
# CONFIG=$(sing_box_cm_set_ws_transport_for_outbound "$CONFIG" "vless-tls-ws-out" "/path" "example.com")
|
||||
#######################################
|
||||
sing_box_cm_set_vless_ws_transport() {
|
||||
sing_box_cm_set_ws_transport_for_outbound() {
|
||||
local config="$1"
|
||||
local tag="$2"
|
||||
local path="$3"
|
||||
@@ -717,7 +757,7 @@ sing_box_cm_set_vless_ws_transport() {
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Set TLS settings for a VLESS outbound in a sing-box JSON configuration.
|
||||
# Set TLS settings for an outbound in a sing-box JSON configuration.
|
||||
# Arguments:
|
||||
# config: JSON configuration (string)
|
||||
# tag: string, identifier of the outbound to modify
|
||||
@@ -731,11 +771,11 @@ sing_box_cm_set_vless_ws_transport() {
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(
|
||||
# sing_box_cm_set_vless_tls "$CONFIG" "vless-reality-out" "example.com" false null "chrome" \
|
||||
# sing_box_cm_set_tls_for_outbound "$CONFIG" "vless-reality-out" "example.com" false null "chrome" \
|
||||
# "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0" "0123456789abcdef"
|
||||
# )
|
||||
#######################################
|
||||
sing_box_cm_set_vless_tls() {
|
||||
sing_box_cm_set_tls_for_outbound() {
|
||||
local config="$1"
|
||||
local tag="$2"
|
||||
local server_name="$3"
|
||||
@@ -788,6 +828,7 @@ sing_box_cm_set_vless_tls() {
|
||||
# config: JSON configuration (string)
|
||||
# tag: string, identifier for the outbound
|
||||
# interface: string, network interface to bind the outbound
|
||||
# domain_resolver: string, tag of the domain resolver to be used for this outbound (optional)
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
@@ -797,15 +838,20 @@ sing_box_cm_add_interface_outbound() {
|
||||
local config="$1"
|
||||
local tag="$2"
|
||||
local interface="$3"
|
||||
local domain_resolver="$4"
|
||||
|
||||
echo "$config" | jq \
|
||||
--arg tag "$tag" \
|
||||
--arg interface "$interface" \
|
||||
'.outbounds += [{
|
||||
type: "direct",
|
||||
tag: $tag,
|
||||
bind_interface: $interface
|
||||
}]'
|
||||
--arg domain_resolver "$domain_resolver" \
|
||||
'.outbounds += [
|
||||
{
|
||||
type: "direct",
|
||||
tag: $tag,
|
||||
bind_interface: $interface
|
||||
}
|
||||
+ (if $domain_resolver != "" then {domain_resolver: $domain_resolver} else {} end)
|
||||
]'
|
||||
}
|
||||
|
||||
#######################################
|
||||
|
||||
Reference in New Issue
Block a user