diff --git a/files/ua2f.init b/files/ua2f.init index 70b473c..7a2931a 100755 --- a/files/ua2f.init +++ b/files/ua2f.init @@ -1,83 +1,110 @@ #!/bin/sh /etc/rc.common # Copyright (C) 2020 Zxilly # Copyright (C) 2021 Tianling Shen -# Copyright (C) 2022 wulishui + +USE_PROCD=1 START=99 -USE_PROCD=1 -EXTRA_COMMANDS="handle_firewall" -flush_ipts() { - iptables -w -t mangle -D POSTROUTING -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>/dev/null - iptables -w -t mangle -D POSTROUTING -p tcp -m conntrack --ctdir REPLY 2>/dev/null - iptables -w -t mangle -F ua2f 2>/dev/null - iptables -w -t mangle -X ua2f 2>/dev/null - ipset flush nohttp 2>/dev/null - ipset destroy nohttp 2>/dev/null -} +NAME="ua2f" +PROG="/usr/bin/$NAME" +IPT_M="iptables -t mangle" -handle_firewall() { - flush_ipts - handle_fw=$(uci -q get ua2f.firewall.handle_fw) ; [ "$handle_fw" == 1 ] || return - handle_tls=$(uci -q get ua2f.firewall.handle_tls) - handle_intranet=$(uci -q get ua2f.firewall.handle_intranet) - handle_mmtls=$(uci -q get ua2f.firewall.handle_mmtls) +FW_DIR="/var/etc" +FW_CONF="$FW_DIR/ua2f.include" - iptables -w -t mangle -N ua2f 2>/dev/null - iptables -w -t mangle -A ua2f -d 10.0.0.0/8 -j RETURN - iptables -w -t mangle -A ua2f -d 172.16.0.0/12 -j RETURN - iptables -w -t mangle -A ua2f -d 192.168.0.0/16 -j RETURN - iptables -w -t mangle -A ua2f -d 0.0.0.0/8 -j RETURN - iptables -w -t mangle -A ua2f -d 127.0.0.0/8 -j RETURN - iptables -w -t mangle -A ua2f -d 169.254.0.0/16 -j RETURN - iptables -w -t mangle -A ua2f -d 224.0.0.0/4 -j RETURN - iptables -w -t mangle -A ua2f -d 240.0.0.0/4 -j RETURN # 不处理流向保留地址的包 - iptables -w -t mangle -A ua2f -p tcp --dport 22 -j RETURN # 不处理 SSH - [ "$handle_tls" == 1 ] || iptables -w -t mangle -A ua2f -p tcp --dport 443 -j RETURN # 不处理 HTTPS - iptables -w -t mangle -A ua2f -p tcp --dport 80 -j CONNMARK --set-mark 44 - iptables -w -t mangle -A ua2f -m connmark --mark 43 -j RETURN # 不处理标记为非 http 的流 (实验性) - [ "$handle_mmtls" == 1 ] || iptables -w -t mangle -A ua2f -p tcp --dport 80 -m string --string "/mmtls/" --algo bm -j RETURN # 不处理微信的mmtls +if type extra_command >"/dev/null" 2>&1; then + extra_command "setup_firewall" +else + EXTRA_COMMANDS="setup_firewall" +fi + +setup_firewall() { + config_load "$NAME" + + local handle_fw + config_get_bool handle_fw "firewall" "handle_fw" "0" + [ "$handle_fw" -eq "1" ] || return 1 + + local handle_tls handle_intranet handle_mmtls + config_get_bool handle_tls "firewall" "handle_tls" "0" + config_get_bool handle_intranet "firewall" "handle_intranet" "0" + config_get_bool handle_mmtls "firewall" "handle_mmtls" "0" ipset create nohttp hash:ip,port hashsize 16384 timeout 300 - iptables -w -t mangle -A ua2f -m set --match-set nohttp dst,dst -j RETURN + $IPT_M -N ua2f + $IPT_M -A ua2f -d 10.0.0.0/8 -j RETURN + $IPT_M -A ua2f -d 172.16.0.0/12 -j RETURN + $IPT_M -A ua2f -d 192.168.0.0/16 -j RETURN + $IPT_M -A ua2f -d 0.0.0.0/8 -j RETURN + $IPT_M -A ua2f -d 127.0.0.0/8 -j RETURN + $IPT_M -A ua2f -d 169.254.0.0/16 -j RETURN + $IPT_M -A ua2f -d 224.0.0.0/4 -j RETURN + $IPT_M -A ua2f -d 240.0.0.0/4 -j RETURN # 不处理流向保留地址的包 + $IPT_M -A ua2f -p tcp --dport 22 -j RETURN # 不处理 SSH + [ "$handle_tls" -eq "1" ] || $IPT_M -A ua2f -p tcp --dport 443 -j RETURN # 不处理 HTTPS + $IPT_M -A ua2f -p tcp --dport 80 -j CONNMARK --set-mark 44 + $IPT_M -A ua2f -m connmark --mark 43 -j RETURN # 不处理标记为非 http 的流 (实验性) + $IPT_M -A ua2f -m set --match-set nohttp dst,dst -j RETURN + [ "$handle_mmtls" -eq "1" ] || $IPT_M -A ua2f -p tcp --dport 80 -m string --string "/mmtls/" --algo bm -j RETURN # 不处理微信的mmtls + $IPT_M -A ua2f -j NFQUEUE --queue-num 10010 + $IPT_M -A FORWARD -p tcp -m conntrack --ctdir ORIGINAL -j ua2f - iptables -w -t mangle -A ua2f -j NFQUEUE --queue-num 10010 - iptables -w -t mangle -A POSTROUTING -p tcp -m conntrack --ctdir ORIGINAL -j ua2f - [ "$handle_intranet" == 1 ] && { + [ "$handle_intranet" -eq "1" ] && { local wan="$(route -n | grep UG | awk '{print $2}')" + if [[ "$wan" =~ ^"10." ]]; then - iptables -w -t mangle -D ua2f 1 - elif echo "$wan" | egrep -q "^172\.((1[6-9])|(2[0-9])|(3[0-1]))\."; then - iptables -w -t mangle -D ua2f 2 + $IPT_M -D ua2f 1 + elif echo "$wan" | grep -Eq "^172\.((1[6-9])|(2[0-9])|(3[0-1]))\."; then + $IPT_M -D ua2f 2 elif [[ "$wan" =~ ^"192.168" ]]; then - iptables -w -t mangle -D ua2f 3 + $IPT_M -D ua2f 3 fi } } start_service() { - enabled=$(uci -q get ua2f.enabled.enabled) - if [ "$enabled" == 1 ]; then - handle_firewall + config_load "$NAME" - procd_open_instance ua2f - procd_set_param command /usr/bin/ua2f + local enabled + config_get_bool enabled "enabled" "enabled" "0" + [ "$enabled" -eq "1" ] || exit 1 + + procd_open_instance "$NAME" + procd_set_param command "$PROG" + + local handle_fw + config_get_bool handle_fw "firewall" "handle_fw" "0" + [ "$handle_fw" -eq "1" ] && { + setup_firewall + mkdir -p "$FW_DIR" + echo -e "/etc/init.d/$NAME setup_firewall" > "$FW_CONF" + } + + procd_set_param stdout 1 + procd_set_param stderr 1 procd_set_param respawn - procd_close_instance - fi -} -service_triggers() { - procd_add_reload_trigger ua2f + procd_close_instance } stop_service() { - flush_ipts + ( + $IPT_M -D FORWARD -p tcp -m conntrack --ctdir ORIGINAL -j ua2f + $IPT_M -D FORWARD -p tcp -m conntrack --ctdir REPLY + $IPT_M -F ua2f + $IPT_M -X ua2f + ipset flush nohttp + ipset destroy nohttp + echo > "$FW_CONF" + ) 2>"/dev/null" } reload_service() { stop - sleep 2 start } +service_triggers() { + procd_add_reload_trigger "$NAME" +} diff --git a/files/ua2f.uci b/files/ua2f.uci index dd95a37..6aedec8 100644 --- a/files/ua2f.uci +++ b/files/ua2f.uci @@ -4,7 +4,7 @@ uci -q batch <<-EOF >/dev/null delete firewall.ua2f set firewall.ua2f=include set firewall.ua2f.type=script - set firewall.ua2f.path=/etc/ua2f.include + set firewall.ua2f.path=/var/etc/ua2f.include set firewall.ua2f.reload=1 commit firewall -EOF \ No newline at end of file +EOF