#!/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
Edit Report
Pub: 02 Apr 2025 11:39 UTC
Edit: 15 Apr 2025 00:52 UTC
Views: 30
Auto Theme: Dark