├── README.md └── install.sh /README.md: -------------------------------------------------------------------------------- 1 | - [Русский](#ru) 2 | - [English](#en) 3 | 4 | # RU 5 | 6 | Shell скрипт для настройки sing-box на использование TProxy и FakeIP на роутере с OpenWrt. 7 | 8 | Текущая версия скрипта настраивает sing-box версии `1.11.x`. 9 | 10 | ## Установка 11 | 12 | ```bash 13 | sh <(wget -O - https://github.com/vernette/singbox-tproxy-fakeip/raw/master/install.sh) 14 | ``` 15 | 16 | > [!WARNING] 17 | > Скрипт заменит файл `/etc/sing-box/config.json` **только** в том случае, если он не содержит настроек для `FakeIP` (то есть если вы запустите скрипт снова, то он пропустит замену конфига), поэтому сделайте резервную копию вашего конфига перед запуском скрипта 18 | 19 | ## После установки 20 | 21 | После окончания работы скрипта, вам нужно изменить конфиг sing-box (изменить секцию `outbounds` на свои нужды) и перезапустить сервис sing-box: 22 | 23 | ```bash 24 | nano /etc/sing-box/config.json # или vim /etc/sing-box/config.json 25 | service sing-box restart 26 | ``` 27 | 28 | И всё готово! 29 | 30 | **Обязательно** прочитать [как всё это работает](https://gist.github.com/vernette/67466961ed5882b3ff21222d1b964929) 31 | 32 | # EN 33 | 34 | Shell script to configure sing-box to use TProxy and FakeIP on OpenWrt router. 35 | 36 | The current version of the script configures sing-box version `1.11.x`. 37 | 38 | ## Installation 39 | 40 | ```bash 41 | sh <(wget -O - https://github.com/vernette/singbox-tproxy-fakeip/raw/master/install.sh) 42 | ``` 43 | 44 | > [!WARNING] 45 | > This script will replace `/etc/sing-box/config.json` file **only** if it doesn't contain `FakeIP` settings (basically, if you will run script again it will skip config replacement), so make sure to backup your config file before running this script 46 | 47 | ## Post-Install 48 | 49 | After script finishes, you need to make changes to the sing-box config file (change `outbounds` section to your needs) and restart sing-box service: 50 | 51 | ```bash 52 | nano /etc/sing-box/config.json # or vim /etc/sing-box/config.json 53 | service sing-box restart 54 | ``` 55 | 56 | And now you are ready to go! 57 | 58 | **Must read** [on how everything works](https://gist.github.com/vernette/67466961ed5882b3ff21222d1b964929) 59 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | NEED_UPDATE=1 4 | DEPENDENCIES="sing-box kmod-nft-tproxy nano" 5 | 6 | get_timestamp() { 7 | format="$1" 8 | date +"$format" 9 | } 10 | 11 | log_message() { 12 | log_level="$1" 13 | message="$2" 14 | timestamp=$(get_timestamp "%d.%m.%Y %H:%M:%S") 15 | echo "[$timestamp] [$log_level]: $message" 16 | } 17 | 18 | is_installed() { 19 | opkg list-installed | grep -qo "$1" 20 | } 21 | 22 | check_updates() { 23 | if [ "$NEED_UPDATE" -eq "1" ]; then 24 | log_message "INFO" "Updating package list" 25 | opkg update >/dev/null 26 | NEED_UPDATE=0 27 | fi 28 | } 29 | 30 | install_dependencies() { 31 | for package in $DEPENDENCIES; do 32 | if ! is_installed "$package"; then 33 | check_updates 34 | log_message "INFO" "Installing $package" 35 | opkg install "$package" >/dev/null 36 | fi 37 | done 38 | } 39 | 40 | configure_sing_box_service() { 41 | sing_box_enabled=$(uci -q get sing-box.main.enabled) 42 | sing_box_user=$(uci -q get sing-box.main.user) 43 | 44 | if [ "$sing_box_enabled" -eq "0" ]; then 45 | log_message "INFO" "Enabling sing-box service" 46 | uci -q set sing-box.main.enabled=1 47 | uci commit sing-box 48 | fi 49 | 50 | if [ "$sing_box_user" != "root" ]; then 51 | log_message "INFO" "Setting sing-box user to root" 52 | uci -q set sing-box.main.user=root 53 | uci commit sing-box 54 | fi 55 | } 56 | 57 | configure_dhcp() { 58 | is_noresolv_enabled=$(uci -q get dhcp.@dnsmasq[0].noresolv || echo "0") 59 | is_filter_aaaa_enabled=$(uci -q get dhcp.@dnsmasq[0].filter_aaaa || echo "0") 60 | dhcp_server=$(uci -q get dhcp.@dnsmasq[0].server || echo "") 61 | dhcp_server_ip="127.0.0.1#5353" 62 | 63 | if [ "$is_noresolv_enabled" -ne "1" ]; then 64 | log_message "INFO" "Enabling noresolv option in DHCP config" 65 | uci -q set dhcp.@dnsmasq[0].noresolv=1 66 | uci commit dhcp 67 | fi 68 | 69 | if [ "$is_filter_aaaa_enabled" -ne "1" ]; then 70 | log_message "INFO" "Enabling filter_aaaa option in DHCP config" 71 | uci -q set dhcp.@dnsmasq[0].filter_aaaa=1 72 | uci commit dhcp 73 | fi 74 | 75 | if [ "$dhcp_server" != "$dhcp_server_ip" ]; then 76 | log_message "INFO" "Setting DHCP server to $dhcp_server_ip" 77 | uci -q delete dhcp.@dnsmasq[0].server 78 | uci -q add_list dhcp.@dnsmasq[0].server="$dhcp_server_ip" 79 | uci commit dhcp 80 | fi 81 | } 82 | 83 | configure_network() { 84 | if [ -z "$(uci -q get network.@rule[0])" ]; then 85 | log_message "INFO" "Creating marking rule" 86 | uci batch <"$config_path" 113 | define TPROXY_MARK = 0x1 114 | define TPROXY_L4PROTO = { tcp, udp } 115 | define TPROXY_PORT = 4444 116 | define FAKEIP = { 198.18.0.0/15 } 117 | 118 | chain tproxy_prerouting { 119 | type filter hook prerouting priority mangle; policy accept; 120 | meta nfproto ipv6 return 121 | ip daddr != $FAKEIP return 122 | meta l4proto $TPROXY_L4PROTO tproxy to :$TPROXY_PORT meta mark set $TPROXY_MARK accept 123 | } 124 | 125 | chain tproxy_output { 126 | type route hook output priority mangle; policy accept; 127 | meta nfproto ipv6 return 128 | ip daddr != $FAKEIP return 129 | meta l4proto $TPROXY_L4PROTO meta mark set $TPROXY_MARK 130 | } 131 | EOF 132 | fi 133 | } 134 | 135 | restart_service() { 136 | service="$1" 137 | log_message "INFO" "Restarting $service service" 138 | service "$service" restart 139 | } 140 | 141 | configure_sing_box() { 142 | config_path="/etc/sing-box/config.json" 143 | if ! grep -q "fakeip" "$config_path"; then 144 | log_message "INFO" "Configuring sing-box" 145 | cat <<'EOF' >"$config_path" 146 | { 147 | "log": { 148 | "level": "info" 149 | }, 150 | "experimental": { 151 | "cache_file": { 152 | "enabled": true, 153 | "store_fakeip": true, 154 | "path": "/etc/sing-box/cache.db" 155 | } 156 | }, 157 | "dns": { 158 | "strategy": "ipv4_only", 159 | "fakeip": { 160 | "enabled": true, 161 | "inet4_range": "198.18.0.0/15" 162 | }, 163 | "servers": [ 164 | { 165 | "tag": "cloudflare-doh-server", 166 | "address": "https://1.1.1.1/dns-query", 167 | "detour": "direct-out" 168 | }, 169 | { 170 | "tag": "fakeip-server", 171 | "address": "fakeip" 172 | } 173 | ], 174 | "rules": [ 175 | { 176 | "domain_suffix": ["ifconfig.me"], 177 | "server": "fakeip-server" 178 | } 179 | ] 180 | }, 181 | "inbounds": [ 182 | { 183 | "tag": "tproxy-in", 184 | "type": "tproxy", 185 | "listen": "::", 186 | "listen_port": 4444, 187 | "tcp_fast_open": true, 188 | "udp_fragment": true 189 | }, 190 | { 191 | "tag": "dns-in", 192 | "type": "direct", 193 | "listen": "127.0.0.1", 194 | "listen_port": 5353 195 | } 196 | ], 197 | "outbounds": [ 198 | { 199 | "tag": "direct-out", 200 | "type": "direct" 201 | }, 202 | { 203 | "tag": "vless-out", 204 | "type": "vless", 205 | "server": "$SERVER", 206 | "server_port": 443, 207 | "uuid": "$UUID", 208 | "flow": "$FLOW", 209 | "tls": { 210 | "enabled": true, 211 | "server_name": "$FAKE_SERVER", 212 | "utls": { 213 | "enabled": true, 214 | "fingerprint": "$FINGERPRINT" 215 | }, 216 | "reality": { 217 | "enabled": true, 218 | "public_key": "$PUBLIC_KEY", 219 | "short_id": "$SHORT_ID" 220 | } 221 | } 222 | } 223 | ], 224 | "route": { 225 | "rules": [ 226 | { 227 | "inbound": ["tproxy-in", "dns-in"], 228 | "action": "sniff" 229 | }, 230 | { 231 | "protocol": "dns", 232 | "action": "hijack-dns" 233 | }, 234 | { 235 | "inbound": ["tproxy-in"], 236 | "domain_suffix": ["ifconfig.me"], 237 | "outbound": "vless-out" 238 | } 239 | ], 240 | "auto_detect_interface": true 241 | } 242 | } 243 | EOF 244 | fi 245 | } 246 | 247 | print_post_install_message() { 248 | printf "\nInstallation completed successfully.\n\n!!! Now you need to make changes to sing-box config (nano /etc/sing-box/config.json) and restart sing-box service with this command: service sing-box restart !!!\n\n" 249 | } 250 | 251 | main() { 252 | install_dependencies 253 | configure_sing_box_service 254 | configure_dhcp 255 | configure_network 256 | configure_nftables 257 | configure_sing_box 258 | restart_service "network" 259 | restart_service "dnsmasq" 260 | restart_service "firewall" 261 | print_post_install_message 262 | } 263 | 264 | main 265 | --------------------------------------------------------------------------------