blockcheck: macos support

This commit is contained in:
bol-van 2024-03-11 20:49:11 +03:00
parent aae2b6f2f8
commit 353d34a425

View File

@ -41,6 +41,8 @@ DNSCHECK_DIGS=/tmp/digs.txt
unset PF_STATUS
PF_RULES_SAVE=/tmp/pf-zapret-save.conf
CURL=curl
killwait()
{
# $1 - signal (-9, -2, ...)
@ -76,16 +78,24 @@ pf_save()
{
PF_STATUS=0
pf_is_enabled && PF_STATUS=1
pfctl -sr >"$PF_RULES_SAVE"
[ "$UNAME" = "OpenBSD" ] && pfctl -sr >"$PF_RULES_SAVE"
}
pf_restore()
{
[ -n "$PF_STATUS" ] || return
case "$UNAME" in
OpenBSD)
if [ -f "$PF_RULES_SAVE" ]; then
pfctl -qf "$PF_RULES_SAVE"
else
echo | pfctl -qf -
fi
;;
Darwin)
# it's not possible to save all rules in the right order. hard to reorder. if not ordered pf will refuse to load conf.
pfctl -qf /etc/pf.conf
;;
esac
if [ "$PF_STATUS" = 1 ]; then
pfctl -qe
else
@ -98,15 +108,39 @@ pf_clean()
}
opf_dvtws_anchor()
{
# $1 - port
local family=inet
[ "$IPV" = 6 ] && family=inet6
echo "set reassemble no"
echo "pass in quick proto tcp from port {80,443} flags SA/SA divert-packet port $IPFW_DIVERT_PORT no state"
echo "pass in quick proto tcp from port {80,443} no state"
echo "pass out quick proto tcp to port {80,443} divert-packet port $IPFW_DIVERT_PORT no state"
echo "pass in quick $family proto tcp from port $1 flags SA/SA divert-packet port $IPFW_DIVERT_PORT no state"
echo "pass in quick $family proto tcp from port $1 no state"
echo "pass out quick $family proto tcp to port $1 divert-packet port $IPFW_DIVERT_PORT no state"
echo "pass"
}
opf_prepare_dvtws()
{
opf_dvtws_anchor | pfctl -qf -
# $1 - port
opf_dvtws_anchor $1 | pfctl -qf -
pfctl -qe
}
mpf_tpws_anchor()
{
# $1 - port
case "$IPV" in
4)
echo "rdr pass on $LO_IFACE inet proto tcp from \!127.0.0.0/8 to any port $1 -> $LOCALHOST port $TPPORT"
echo "pass out route-to ($LO_IFACE $LOCALHOST) inet proto tcp from any to any port $1 user { >root }"
;;
6)
echo "rdr pass on $LO_IFACE inet6 proto tcp from \!::1 to any port $1 -> $LOCALHOST port $TPPORT"
echo "pass out route-to ($LO_IFACE $LOCALHOST) inet6 proto tcp from any to any port $1 user { >root }"
;;
esac
}
mpf_prepare_tpws()
{
# $1 - port
mpf_tpws_anchor $1 | pfctl -qf -
pfctl -qe
}
@ -176,6 +210,7 @@ check_system()
Linux)
PKTWS="$NFQWS"
PKTWSD=nfqws
LO_IFACE=lo
linux_fwtype
[ "$FWTYPE" = iptables -o "$FWTYPE" = nftables ] || {
echo firewall type $FWTYPE not supported in $UNAME
@ -186,12 +221,24 @@ check_system()
PKTWS="$DVTWS"
PKTWSD=dvtws
FWTYPE=ipfw
LO_IFACE=lo0
[ -f /etc/platform ] && read SUBSYS </etc/platform
;;
OpenBSD)
PKTWS="$DVTWS"
PKTWSD=dvtws
FWTYPE=opf
LO_IFACE=lo0
;;
Darwin)
PKTWS="$DVTWS"
PKTWSD=dvtws
FWTYPE=mpf
# will not redirect traffic for root
CURL="sudo -u nobody curl"
# /dev/pf requires root. hardcoded in kernel
TPWS_UID=0
LO_IFACE=lo0
;;
*)
echo $UNAME not supported
@ -220,7 +267,7 @@ check_prerequisites()
{
echo \* checking prerequisites
[ -x "$PKTWS" ] && [ -x "$TPWS" ] && [ -x "$MDIG" ] || {
[ "$UNAME" = Darwin -o -x "$PKTWS" ] && [ -x "$TPWS" ] && [ -x "$MDIG" ] || {
echo $PKTWS or $TPWS or $MDIG is not available. run \"$ZAPRET_BASE/install_bin.sh\" or make -C \"$ZAPRET_BASE\"
exitp 6
}
@ -255,7 +302,7 @@ check_prerequisites()
exitp 6
}
;;
OpenBSD)
OpenBSD|Darwin)
progs="$progs pfctl"
pf_is_avail || {
echo pf is not available
@ -265,7 +312,9 @@ check_prerequisites()
# even with route-to trick DIOCNATLOOK fails, thus making tpws unusable
# this trick works fine on MacOS but doesn't work on FreeBSD and OpenBSD
# socks version is also not a solution because I can't control ip version of the resolved domain
SKIP_TPWS=1
[ "$UNAME" = "OpenBSD" ] && SKIP_TPWS=1
# no divert sockets in MacOS
[ "$UNAME" = "Darwin" ] && SKIP_PKTWS=1
pf_save
;;
esac
@ -361,7 +410,7 @@ curl_test_http()
# $1 - ip version : 4/6
# $2 - domain name
local code loc
curl -${1}SsD "$HDRTEMP" --max-time $CURL_MAX_TIME $CURL_OPT "http://$2" -o /dev/null 2>&1 || {
$CURL -${1}SsD "$HDRTEMP" --max-time $CURL_MAX_TIME $CURL_OPT "http://$2" -o /dev/null 2>&1 || {
code=$?
rm -f "$HDRTEMP"
return $code
@ -390,7 +439,7 @@ curl_test_https_tls12()
# $2 - domain name
# do not use tls 1.3 to make sure server certificate is not encrypted
curl -${1}ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.2 $TLSMAX12 "https://$2" -o /dev/null 2>&1
$CURL -${1}ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.2 $TLSMAX12 "https://$2" -o /dev/null 2>&1
}
curl_test_https_tls13()
{
@ -398,7 +447,7 @@ curl_test_https_tls13()
# $2 - domain name
# force TLS1.3 mode
curl -${1}ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.3 $TLSMAX13 "https://$2" -o /dev/null 2>&1
$CURL -${1}ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.3 $TLSMAX13 "https://$2" -o /dev/null 2>&1
}
pktws_ipt_prepare()
@ -447,7 +496,7 @@ pktws_ipt_prepare()
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from any $1 to me proto ip${IPV} tcpflags syn,ack in
;;
opf)
opf_prepare_dvtws
opf_prepare_dvtws $1
;;
esac
}
@ -496,6 +545,9 @@ tpws_ipt_prepare()
ipfw)
IPFW_ADD fwd $LOCALHOST,$TPPORT tcp from me to any $1 proto ip${IPV} not uid $TPWS_UID
;;
mpf)
mpf_prepare_tpws $1
;;
esac
}
tpws_ipt_unprepare()
@ -511,6 +563,9 @@ tpws_ipt_unprepare()
ipfw)
IPFW_DEL
;;
mpf)
pf_restore
;;
esac
}
pktws_start()
@ -529,7 +584,7 @@ pktws_start()
}
tpws_start()
{
"$TPWS" --uid $TPWS_UID:$TPWS_GID --bind-addr=$LOCALHOST --port=$TPPORT "$@" >/dev/null &
"$TPWS" --uid $TPWS_UID:$TPWS_GID --bind-addr=$LOCALHOST%$LO_IFACE --port=$TPPORT "$@" >/dev/null &
PID=$!
# give some time to initialize
minsleep
@ -839,6 +894,7 @@ check_domain()
echo
[ "$SKIP_PKTWS" = 1 ] || {
echo preparing $PKTWSD redirection
pktws_ipt_prepare $2
@ -847,6 +903,7 @@ check_domain()
echo clearing $PKTWSD redirection
pktws_ipt_unprepare $2
}
}
check_domain_http()
{
# $1 - domain
@ -867,6 +924,7 @@ configure_ip_version()
{
if [ "$IPV" = 6 ]; then
LOCALHOST=::1
[ "$UNAME" = Darwin ] && LOCALHOST=fe80::1
LOCALHOST_IPT=[${LOCALHOST}]
IPVV=6
else