#!/bin/sh # For systemd : # install : /usr/lib/lsb/install_initd zapret # remove : /usr/lib/lsb/remove_initd zapret ### BEGIN INIT INFO # Provides: zapret # Required-Start: $local_fs $network # Required-Stop: $local_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 ### END INIT INFO ZAPRET_BASE=/opt/zapret # SHOULD EDIT config . "$ZAPRET_BASE/config" NAME=zapret DESC=anti-zapret PIDDIR=/var/run IPSET_CR=$ZAPRET_BASE/ipset/create_ipset.sh QNUM=200 NFQWS=$ZAPRET_BASE/nfq/nfqws NFQWS_OPT_BASE="--qnum=$QNUM" TPPORT_HTTP=1188 TPPORT_HTTPS=1189 TPWS=$ZAPRET_BASE/tpws/tpws TPWS_USER=tpws TPWS_HOSTLIST=$ZAPRET_BASE/ipset/zapret-hosts.txt TPWS_OPT_BASE="--user=$TPWS_USER --bind-addr=127.0.0.1" TPWS_OPT_BASE_HTTP="--port=$TPPORT_HTTP $TPWS_OPT_BASE" TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS $TPWS_OPT_BASE" # exit script on any error set -e exists() { which $1 >/dev/null 2>/dev/null } fw_tpws_add() { # $1 - iptable filter # $2 - tpws port echo "Adding iptables rule for tpws : $1" [ -n "$SLAVE_ETH" ] && { iptables -t nat -C PREROUTING -i $SLAVE_ETH -p tcp $1 -j DNAT --to 127.0.0.1:$2 2>/dev/null || iptables -t nat -I PREROUTING -i $SLAVE_ETH -p tcp $1 -j DNAT --to 127.0.0.1:$2 } iptables -t nat -C OUTPUT -m owner ! --uid-owner $TPWS_USER -p tcp $1 -j DNAT --to 127.0.0.1:$2 2>/dev/null || iptables -t nat -I OUTPUT -m owner ! --uid-owner $TPWS_USER -p tcp $1 -j DNAT --to 127.0.0.1:$2 } fw_tpws_del() { # $1 - iptable filter # $2 - tpws port echo "Deleting iptables rule for tpws : $1" [ -n "$SLAVE_ETH" ] && { iptables -t nat -C PREROUTING -i $SLAVE_ETH -p tcp $1 -j DNAT --to 127.0.0.1:$2 2>/dev/null && iptables -t nat -D PREROUTING -i $SLAVE_ETH -p tcp $1 -j DNAT --to 127.0.0.1:$2 } iptables -t nat -C OUTPUT -m owner ! --uid-owner $TPWS_USER -p tcp $1 -j DNAT --to 127.0.0.1:$2 2>/dev/null && iptables -t nat -D OUTPUT -m owner ! --uid-owner $TPWS_USER -p tcp $1 -j DNAT --to 127.0.0.1:$2 true } fw_nfqws_add_pre() { # $1 - iptable filter echo "Adding iptables rule for nfqws prerouting : $1" iptables -t raw -C PREROUTING -p tcp --tcp-flags SYN,ACK SYN,ACK $1 -j NFQUEUE --queue-num $QNUM --queue-bypass 2>/dev/null || iptables -t raw -I PREROUTING -p tcp --tcp-flags SYN,ACK SYN,ACK $1 -j NFQUEUE --queue-num $QNUM --queue-bypass } fw_nfqws_del_pre() { # $1 - iptable filter echo "Deleting iptables rule for nfqws prerouting : $1" iptables -t raw -C PREROUTING -p tcp --tcp-flags SYN,ACK SYN,ACK $1 -j NFQUEUE --queue-num $QNUM --queue-bypass 2>/dev/null && iptables -t raw -D PREROUTING -p tcp --tcp-flags SYN,ACK SYN,ACK $1 -j NFQUEUE --queue-num $QNUM --queue-bypass true } fw_nfqws_add_post() { # $1 - iptable filter echo "Adding iptables rule for nfqws postrouting : $1" iptables -t mangle -C POSTROUTING -p tcp $1 -j NFQUEUE --queue-num $QNUM --queue-bypass 2>/dev/null || iptables -t mangle -I POSTROUTING -p tcp $1 -j NFQUEUE --queue-num $QNUM --queue-bypass } fw_nfqws_del_post() { # $1 - iptable filter echo "Deleting iptables rule for nfqws postrouting : $1" iptables -t mangle -C POSTROUTING -p tcp $1 -j NFQUEUE --queue-num $QNUM --queue-bypass 2>/dev/null && iptables -t mangle -D POSTROUTING -p tcp $1 -j NFQUEUE --queue-num $QNUM --queue-bypass true } JOBCT=1 run_daemon() { # $1 - daemon number : 1,2,3,... # $2 - daemon # $3 - daemon args # use $PIDDIR/$DAEMONBASE$1.pid as pidfile local DAEMONBASE=$(basename $2) local PIDFILE=$PIDDIR/$DAEMONBASE$1.pid echo "Starting daemon $1: $2 $3" if exists start-stop-daemon ; then start-stop-daemon --start --quiet --pidfile "$PIDFILE" --background --make-pidfile \ --exec "$2" -- $3 elif exists daemonize ; then daemonize -p "$PIDFILE" "$2" $3 else nohup "$2" $3 >/dev/null 2>/dev/null & PID=$(jobs -p %$JOBCT) if [ -n "$PID" ]; then echo $PID >$PIDFILE let JOBCT=$JOBCT+1 else echo could not start daemon $1 : $2 $3 fi fi } stop_daemon() { # $1 - daemon number : 1,2,3,... # $2 - daemon # use $PIDDIR/$DAEMONBASE$1.pid as pidfile local DAEMONBASE=$(basename $2) local PIDFILE=$PIDDIR/$DAEMONBASE$1.pid echo "Stopping daemon $1: $2" if exists start-stop-daemon ; then start-stop-daemon --oknodo --stop --quiet --pidfile "$PIDFILE" \ --exec "$2" else if [ -f "$PIDFILE" ]; then read PID <"$PIDFILE" kill $PID rm -f "$PIDFILE" else echo no pidfile : $PIDFILE false fi fi } prepare_tpws() { # $TPWS_USER is required to prevent redirection of the traffic originating from TPWS itself # otherwise infinite loop will occur # also its good idea not to run tpws as root id -u $TPWS_USER >/dev/null 2>/dev/null || useradd --no-create-home --system --shell /bin/false $TPWS_USER # otherwise linux kernel will treat 127.0.0.1 as "martian" ip and refuse routing to it # NOTE : kernels <3.6 do not have this feature. consider upgrading or change DNAT to REDIRECT and do not bind to 127.0.0.1 for iface in /proc/sys/net/ipv4/conf/*; do sysctl -qw net.ipv4.conf.$(basename $iface).route_localnet=1; done } create_ipset() { echo "Creating ipset" "$IPSET_CR" } case "$1" in start) case "${MODE}" in tpws_hostlist) prepare_tpws fw_tpws_add "--dport 80" $TPPORT_HTTP run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP --hostlist=$TPWS_HOSTLIST" ;; tpws_ipset) create_ipset prepare_tpws fw_tpws_add "--dport 80 -m set --match-set zapret dst" $TPPORT_HTTP run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP" ;; tpws_ipset_https) create_ipset prepare_tpws fw_tpws_add "--dport 80 -m set --match-set zapret dst" $TPPORT_HTTP fw_tpws_add "--dport 443 -m set --match-set zapret dst" $TPPORT_HTTPS run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP" run_daemon 2 $TPWS "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS" ;; tpws_all) prepare_tpws fw_tpws_add "--dport 80" $TPPORT_HTTP run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP" ;; tpws_all_https) prepare_tpws fw_tpws_add "--dport 80" $TPPORT_HTTP fw_tpws_add "--dport 443" $TPPORT_HTTPS run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP" run_daemon 2 $TPWS "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS" ;; nfqws_ipset) create_ipset fw_nfqws_add_pre "--sport 80 -m set --match-set zapret src" fw_nfqws_add_post "--dport 80 -m set --match-set zapret dst" run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT" ;; nfqws_ipset_https) create_ipset fw_nfqws_add_pre "-m multiport --sports 80,443 -m set --match-set zapret src" fw_nfqws_add_post "--dport 80 -m set --match-set zapret dst" run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT" ;; nfqws_all) fw_nfqws_add_pre "--sport 80" fw_nfqws_add_post "--dport 80" run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT" ;; nfqws_all_https) fw_nfqws_add_pre "-m multiport --sports 80,443" fw_nfqws_add_post "--dport 80" run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT" ;; ipset) create_ipset ;; custom) # PLACEHOLDER echo !!! NEED ATTENTION !!! echo Configure iptables for required actions echo Start daemon\(s\) echo Study how other sections work run_daemon 1 /bin/sleep 20 ;; esac ;; stop) case "${MODE}" in tpws_hostlist|tpws_all) fw_tpws_del "--dport 80" $TPPORT_HTTP stop_daemon 1 $TPWS ;; tpws_ipset) fw_tpws_del "--dport 80 -m set --match-set zapret dst" $TPPORT_HTTP stop_daemon 1 $TPWS ;; tpws_ipset_https) fw_tpws_del "--dport 80 -m set --match-set zapret dst" $TPPORT_HTTP fw_tpws_del "--dport 443 -m set --match-set zapret dst" $TPPORT_HTTPS stop_daemon 1 $TPWS stop_daemon 2 $TPWS ;; tpws_all_https) fw_tpws_del "--dport 80" $TPPORT_HTTP fw_tpws_del "--dport 443" $TPPORT_HTTPS stop_daemon 1 $TPWS stop_daemon 2 $TPWS ;; nfqws_ipset) fw_nfqws_del_pre "--sport 80 -m set --match-set zapret src" fw_nfqws_del_post "--dport 80 -m set --match-set zapret dst" stop_daemon 1 $NFQWS ;; nfqws_ipset_https) fw_nfqws_del_pre "-m multiport --sports 80,443 -m set --match-set zapret src" fw_nfqws_del_post "--dport 80 -m set --match-set zapret dst" stop_daemon 1 $NFQWS ;; nfqws_all) fw_nfqws_del_pre "--sport 80" fw_nfqws_del_post "--dport 80" stop_daemon 1 $NFQWS ;; nfqws_all_https) fw_nfqws_del_pre "-m multiport --sports 80,443" fw_nfqws_del_post "--dport 80" stop_daemon 1 $NFQWS ;; custom) # PLACEHOLDER echo !!! NEED ATTENTION !!! echo Clear firewall rules here. Remove iptables changes made previously. echo Stop daemon\(s\) previously started. echo Study how other sections work. ;; esac ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop}" >&2 exit 1 ;; esac exit 0