#!/bin/sh -eux
# Indrani PI, The Unlicense
# 1. 不正な目的に使わないでね!
# 2. 大いなる力には大いなる責任が伴うからね!
# 3. 他者へ配慮を忘れずに責任を持って使ってね!
# 1. Don't use it for malicious purposes!
# 2. With great power comes great responsibility!
# 3. Use it responsibly and be considerate of others!
RAW_UID='raw'
PATH='/bin:/sbin'
PI='1'; LAN='172.16.0.0/12'
type iptables tor || exit 1
[ "$(id -u)" != "0" ] && echo 'exec root' && exit 2
sysctl -w net.ipv6.conf.default.disable_ipv6=1 -w net.ipv6.conf.all.disable_ipv6=1 || exit 3
if ! id "$RAW_UID"; then echo "sudo useradd -m $RAW_UID; sudo passwd $RAW_UID; sudo usermod -aG audio,video $RAW_UID"; exit 4; fi
if id tor; then TOR_UID='tor'; elif id toranon; then TOR_UID='toranon'; elif id debian-tor; then TOR_UID='debian-tor'; else echo "TOR_UID is not found."; exit 5; fi
RESERVED_IP='255.255.255.255/32 240.0.0.0/4 233.252.0.0/24 224.0.0.0/4 203.0.113.0/24 198.51.100.0/24 198.18.0.0/15 192.168.0.0/16 192.88.99.0/24 192.0.2.0/24 192.0.0.0/24 172.16.0.0/12 169.254.0.0/16 127.0.0.0/8 100.64.0.0/10 10.0.0.0/8 0.0.0.0/8'
_stop() {
iptables -t nat -F
iptables -F
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
[ "$PI" = "1" ] && iptables -A INPUT -s "$LAN" -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -j DROP
iptables -P INPUT DROP
iptables -A FORWARD -j DROP
iptables -P FORWARD DROP
iptables -A OUTPUT -j ACCEPT
iptables -P OUTPUT DROP
return 0
}
_start() {
iptables -t nat -F
iptables -t nat -A OUTPUT -m string --hex-string '|2112a442|' --algo bm -j RETURN
iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-port 9053
iptables -t nat -A OUTPUT -p tcp -d 10.192.0.0/10 --syn -j REDIRECT --to-port 9040
iptables -t nat -A OUTPUT -m owner --uid-owner "$TOR_UID" -j RETURN
iptables -t nat -A OUTPUT -m owner --uid-owner "$RAW_UID" -j RETURN
iptables -t nat -A OUTPUT -o lo -j RETURN
# shellcheck disable=SC2116
for reserved_ip in $(echo "$RESERVED_IP"); do
iptables -t nat -A OUTPUT -d "$reserved_ip" -j RETURN
done
iptables -t nat -A OUTPUT -p tcp --syn -j REDIRECT --to-port 9040
iptables -F
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
[ "$PI" = "1" ] && iptables -A INPUT -s "$LAN" -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -j DROP
iptables -P INPUT DROP
iptables -A FORWARD -j DROP
iptables -P FORWARD DROP
iptables -A OUTPUT -m string --hex-string '|2112a442|' --algo bm -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p udp -d 127.0.0.1 --dport 9053 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -d 127.0.0.1 --dport 9040 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -d 127.0.0.1 --dport 9050 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 --syn -m owner --uid-owner "$TOR_UID" -m state --state NEW -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner "$RAW_UID" -m state --state NEW -j ACCEPT
[ "$PI" = "1" ] && iptables -A OUTPUT -d "$LAN" -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1 -o lo -j ACCEPT
# shellcheck disable=SC2116
for reserved_ip in $(echo "$RESERVED_IP"); do
iptables -A OUTPUT -d "$reserved_ip" -j DROP
done
iptables -A OUTPUT -j DROP
iptables -P OUTPUT DROP
return 0
}
_config() {
sv_status="$1"
{
echo "FascistFirewall 1"
echo "FirewallPorts 443"
echo
echo "User $TOR_UID"
echo "DataDirectory /var/lib/tor"
echo
echo "DNSPort 9053"
echo "TransPort 9040"
echo "SocksPort 9050"
echo "AutomapHostsOnResolve 1"
echo "AutomapHostsSuffixes .onion"
echo "VirtualAddrNetworkIPv4 10.192.0.0/10"
} > /etc/tor/torrc
/etc/init.d/tor "$sv_status"
return 0
}
_status() {
sleep 3
cat /etc/tor/torrc
iptables -t nat -nvL; iptables -nvL
ss -autnp | grep -e 'ESTAB' -e 'LISTEN' | awk '{print $1,$2,$7,$5,$6}' | sort -r
return 0
}
_unsafe() {
UNSAFE_APP="$1"
UNSAFE_ENV="$2"
xhost +
su "$RAW_UID" -c "env $UNSAFE_ENV $UNSAFE_APP"
return 0
}
case "${1:-help}" in
p|stop|-p|--stop)
_stop
_config 'stop'
_status
;;
t|start|-t|--start)
_start
_config 'restart'
_status
;;
c|change|-c|--change)
_config 'restart'
_status
;;
u|unsafe|-u|--unsafe)
_unsafe "${2:-firefox}" "${3:-GTK_IM_MODULE=fcitx5 QT_IM_MODULE=fcitx5 XMODIFIERS=@im=fcitx5}"
;;
*)
echo ' p, stop, -p, --stop Stop the Tor'
echo ' t, start, -t, --start Start the Tor'
echo ' c, change, -c, --change Change the Cfg'
echo ' u, unsafe, -u, --unsafe Unsafe the App'
;;
esac
exit 0