PF_MAIN="/etc/pf.conf" PF_ANCHOR_DIR=/etc/pf.anchors PF_ANCHOR_ZAPRET="$PF_ANCHOR_DIR/zapret" PF_ANCHOR_ZAPRET_V4="$PF_ANCHOR_DIR/zapret-v4" PF_ANCHOR_ZAPRET_V6="$PF_ANCHOR_DIR/zapret-v6" std_ports pf_anchor_root_reload() { echo reloading PF root anchor pfctl -qf "$PF_MAIN" } pf_anchor_root() { local patch [ -f "$PF_MAIN" ] && { grep -q '^rdr-anchor "zapret"$' "$PF_MAIN" || { echo patching rdr-anchor in $PF_MAIN patch=1 sed -i '' -e '/^rdr-anchor "com\.apple\/\*"$/i \ rdr-anchor "zapret" ' $PF_MAIN } grep -q '^anchor "zapret"$' "$PF_MAIN" || { echo patching anchor in $PF_MAIN patch=1 sed -i '' -e '/^anchor "com\.apple\/\*"$/i \ anchor "zapret" ' $PF_MAIN } grep -q "^set limit table-entries" "$PF_MAIN" || { echo patching table-entries limit patch=1 sed -i '' -e '/^scrub-anchor "com\.apple\/\*"$/i \ set limit table-entries 5000000 ' $PF_MAIN } grep -q '^anchor "zapret"$' "$PF_MAIN" && grep -q '^rdr-anchor "zapret"$' "$PF_MAIN" && grep -q '^set limit table-entries' "$PF_MAIN" && { if [ -n "$patch" ]; then echo successfully patched $PF_MAIN pf_anchor_root_reload else echo successfully checked zapret anchors in $PF_MAIN fi return 0 } } echo ---------------------------------- echo Automatic $PF_MAIN patching failed. You must apply root anchors manually in your PF config. echo rdr-anchor \"zapret\" echo anchor \"zapret\" echo ---------------------------------- return 1 } pf_anchor_root_del() { sed -i '' -e '/^anchor "zapret"$/d' -e '/^rdr-anchor "zapret"$/d' -e '/^set limit table-entries/d' "$PF_MAIN" } pf_anchor_zapret() { [ "$DISABLE_IPV4" = "1" ] || { if [ -f "$ZIPLIST_EXCLUDE" ]; then echo "table persist file \"$ZIPLIST_EXCLUDE\"" else echo "table persist" fi } [ "$DISABLE_IPV6" = "1" ] || { if [ -f "$ZIPLIST_EXCLUDE6" ]; then echo "table persist file \"$ZIPLIST_EXCLUDE6\"" else echo "table persist" fi } [ "$DISABLE_IPV4" = "1" ] || echo "rdr-anchor \"/zapret-v4\" inet to !" [ "$DISABLE_IPV6" = "1" ] || echo "rdr-anchor \"/zapret-v6\" inet6 to !" [ "$DISABLE_IPV4" = "1" ] || echo "anchor \"/zapret-v4\" inet to !" [ "$DISABLE_IPV6" = "1" ] || echo "anchor \"/zapret-v6\" inet6 to !" } pf_anchor_zapret_tables() { # $1 - variable to receive applied table names # $2/$3 $4/$5 ... table_name/table_file local tblv=$1 local _tbl shift [ "$MODE_FILTER" = "ipset" ] && { while [ -n "$1" ] && [ -n "$2" ] ; do [ -f "$2" ] && { echo "table <$1> file \"$2\"" _tbl="$_tbl<$1> " } shift shift done } [ -n "$_tbl" ] || _tbl="any" eval $tblv="\"\$_tbl\"" } pf_nat_reorder_rules() { # this is dirty hack to move rdr above route-to and remove route-to dups sort -rfu } pf_anchor_port_target() { if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then echo "{$HTTP_PORTS_IPT,$HTTPS_PORTS_IPT}" elif [ "$MODE_HTTPS" = "1" ]; then echo "{$HTTPS_PORTS_IPT}" elif [ "$MODE_HTTP" = "1" ]; then echo "{$HTTP_PORTS_IPT}" fi } pf_anchor_zapret_v4_tpws() { # $1 - tpws listen port # $2 - rdr ports. defaults are used if empty local rule port if [ -n "$2" ]; then port="{$2}" else port=$(pf_anchor_port_target) fi for lan in $IFACE_LAN; do for t in $tbl; do echo "rdr on $lan inet proto tcp from any to $t port $port -> 127.0.0.1 port $1" done done echo "rdr on lo0 inet proto tcp from !127.0.0.0/8 to any port $port -> 127.0.0.1 port $1" for t in $tbl; do rule="route-to (lo0 127.0.0.1) inet proto tcp from !127.0.0.0/8 to $t port $port user { >root }" if [ -n "$IFACE_WAN" ] ; then for wan in $IFACE_WAN; do echo "pass out on $wan $rule" done else echo "pass out $rule" fi done } pf_anchor_zapret_v4() { local tbl port [ "$DISABLE_IPV4" = "1" ] || { case "${MODE_OVERRIDE:-$MODE}" in tpws) [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST" pf_anchor_zapret_v4_tpws $TPPORT ;; custom) pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST" custom_runner zapret_custom_firewall_v4 | pf_nat_reorder_rules ;; esac } } pf_anchor_zapret_v6_tpws() { # $1 - tpws listen port # $2 - rdr ports. defaults are used if empty local rule LL_LAN port if [ -n "$2" ]; then port="{$2}" else port=$(pf_anchor_port_target) fi # LAN link local is only for router for lan in $IFACE_LAN; do LL_LAN=$(get_ipv6_linklocal $lan) [ -n "$LL_LAN" ] && { for t in $tbl; do echo "rdr on $lan inet6 proto tcp from any to $t port $port -> $LL_LAN port $1" done } done echo "rdr on lo0 inet6 proto tcp from !::1 to any port $port -> fe80::1 port $1" for t in $tbl; do rule="route-to (lo0 fe80::1) inet6 proto tcp from !::1 to $t port $port user { >root }" if [ -n "${IFACE_WAN6:-$IFACE_WAN}" ] ; then for wan in ${IFACE_WAN6:-$IFACE_WAN}; do echo "pass out on $wan $rule" done else echo "pass out $rule" fi done } pf_anchor_zapret_v6() { local tbl port [ "$DISABLE_IPV6" = "1" ] || { case "${MODE_OVERRIDE:-$MODE}" in tpws) [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6" pf_anchor_zapret_v6_tpws $TPPORT ;; custom) pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6" custom_runner zapret_custom_firewall_v6 | pf_nat_reorder_rules ;; esac } } pf_anchors_create() { wait_lan_ll pf_anchor_zapret >"$PF_ANCHOR_ZAPRET" pf_anchor_zapret_v4 >"$PF_ANCHOR_ZAPRET_V4" pf_anchor_zapret_v6 >"$PF_ANCHOR_ZAPRET_V6" } pf_anchors_del() { rm -f "$PF_ANCHOR_ZAPRET" "$PF_ANCHOR_ZAPRET_V4" "$PF_ANCHOR_ZAPRET_V6" } pf_anchors_load() { echo loading zapret anchor from "$PF_ANCHOR_ZAPRET" pfctl -qa zapret -f "$PF_ANCHOR_ZAPRET" || { echo error loading zapret anchor return 1 } if [ "$DISABLE_IPV4" = "1" ]; then echo clearing zapret-v4 anchor pfctl -qa zapret-v4 -F all 2>/dev/null else echo loading zapret-v4 anchor from "$PF_ANCHOR_ZAPRET_V4" pfctl -qa zapret-v4 -f "$PF_ANCHOR_ZAPRET_V4" || { echo error loading zapret-v4 anchor return 1 } fi if [ "$DISABLE_IPV6" = "1" ]; then echo clearing zapret-v6 anchor pfctl -qa zapret-v6 -F all 2>/dev/null else echo loading zapret-v6 anchor from "$PF_ANCHOR_ZAPRET_V6" pfctl -qa zapret-v6 -f "$PF_ANCHOR_ZAPRET_V6" || { echo error loading zapret-v6 anchor return 1 } fi echo successfully loaded PF anchors return 0 } pf_anchors_clear() { echo clearing zapret anchors pfctl -qa zapret-v4 -F all 2>/dev/null pfctl -qa zapret-v6 -F all 2>/dev/null pfctl -qa zapret -F all 2>/dev/null } pf_enable() { echo enabling PF pfctl -qe } pf_table_reload() { echo reloading zapret tables [ "$DISABLE_IPV4" = "1" ] || pfctl -qTl -a zapret-v4 -f "$PF_ANCHOR_ZAPRET_V4" [ "$DISABLE_IPV6" = "1" ] || pfctl -qTl -a zapret-v6 -f "$PF_ANCHOR_ZAPRET_V6" pfctl -qTl -a zapret -f "$PF_ANCHOR_ZAPRET" }