#!/bin/bash # bunker.sh # # Echoes of Hackers (association déclarée) · Platon-Y (pctamalou) # https://pctamalou.fr — Licence GPL-3+ # # Lab éducatif / hygiène défensive uniquement. Pas un VPN, pas Tor Browser, # pas une garantie d'anonymat. Utilisez uniquement sur VOS machines, dans # le respect du droit et des politiques de votre réseau. # # Usage (exemples) : # sudo ./bunker.sh # EXTRA_TCP_PORTS="80,443,8080,8443" sudo -E ./bunker.sh # STRICT_EGRESS=0 sudo -E ./bunker.sh # OUTPUT ACCEPT (lab plus souple) # ALLOW_SSH=1 sudo -E ./bunker.sh # SSH entrant limité # USE_TOR=1 sudo -E ./bunker.sh # ports Tor + démarrage tor.service # FAKE_HOST=laptop-lab SPOOF_MAC=1 sudo -E ./bunker.sh # # Variables d'environnement (défauts publics / sûrs) : # USE_TOR=0 SPOOF_MAC=0 FAKE_HOST= ALLOW_SSH=0 STRICT_EGRESS=1 # EXTRA_TCP_PORTS=80,443,8080,8443,2443 DROP_MDNS=1 # # Checklist : https://pctamalou.fr/tutoriels/doc/bunker-checklist.md # Section Spéciale : https://pctamalou.fr/special/bunker.html if [ "${EUID:-$(id -u)}" -ne 0 ]; then echo "root requis : sudo $0" exit 1 fi # --- réglages (overridables via env) --- USE_TOR="${USE_TOR:-0}" SPOOF_MAC="${SPOOF_MAC:-0}" FAKE_HOST="${FAKE_HOST:-}" ALLOW_SSH="${ALLOW_SSH:-0}" STRICT_EGRESS="${STRICT_EGRESS:-1}" EXTRA_TCP_PORTS="${EXTRA_TCP_PORTS:-80,443,8080,8443}" DROP_MDNS="${DROP_MDNS:-1}" IFACE="$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}')" IFACE="${IFACE:-}" if [ -z "$IFACE" ]; then IFACE="$(ip -4 route show default 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}')" fi IFACE="${IFACE:-eth0}" LAN_NET="$(ip -4 route show dev "$IFACE" proto kernel scope link 2>/dev/null | awk '{print $1; exit}')" echo "bunker: iface=$IFACE lan=${LAN_NET:-?} ssh=$ALLOW_SSH tor=$USE_TOR mac=$SPOOF_MAC strict=$STRICT_EGRESS ports=$EXTRA_TCP_PORTS host=${FAKE_HOST:-(inchangé)}" # --- 1) identité locale (optionnel) --- if [ -n "$FAKE_HOST" ]; then hostnamectl set-hostname "$FAKE_HOST" 2>/dev/null || hostname "$FAKE_HOST" if grep -qE '^127\.0\.1\.1' /etc/hosts; then sed -i "s/^127\\.0\\.1\\.1.*/127.0.1.1\\t$FAKE_HOST/" /etc/hosts else echo -e "127.0.1.1\t$FAKE_HOST" >> /etc/hosts fi fi if [ "$SPOOF_MAC" = "1" ] && [ -d "/sys/class/net/$IFACE" ]; then ip link set "$IFACE" down 2>/dev/null || true NEWMAC="$(printf '02:%02x:%02x:%02x:%02x:%02x' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))" ip link set "$IFACE" address "$NEWMAC" 2>/dev/null || true ip link set "$IFACE" up 2>/dev/null || true echo "mac=$NEWMAC" fi # --- 2) kernel discret --- sysctl -w net.ipv4.ip_forward=0 >/dev/null 2>&1 || true sysctl -w net.ipv4.conf.all.rp_filter=1 >/dev/null 2>&1 || true sysctl -w net.ipv4.conf.default.rp_filter=1 >/dev/null 2>&1 || true sysctl -w net.ipv4.icmp_echo_ignore_all=1 >/dev/null 2>&1 || true sysctl -w net.ipv4.conf.all.accept_redirects=0 >/dev/null 2>&1 || true sysctl -w net.ipv4.conf.default.accept_redirects=0 >/dev/null 2>&1 || true sysctl -w net.ipv4.conf.all.send_redirects=0 >/dev/null 2>&1 || true sysctl -w net.ipv4.conf.all.accept_source_route=0 >/dev/null 2>&1 || true sysctl -w net.ipv6.conf.all.accept_redirects=0 >/dev/null 2>&1 || true sysctl -w net.ipv4.tcp_timestamps=0 >/dev/null 2>&1 || true sysctl -w net.ipv4.tcp_syncookies=1 >/dev/null 2>&1 || true # --- 3) firewall --- systemctl stop firewalld 2>/dev/null || true systemctl disable firewalld 2>/dev/null || true iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables -t raw -F iptables -t raw -X iptables -P INPUT DROP iptables -P FORWARD DROP if [ "$STRICT_EGRESS" = "1" ]; then iptables -P OUTPUT DROP else iptables -P OUTPUT ACCEPT fi # loopback iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # invalides iptables -A INPUT -m conntrack --ctstate INVALID -j DROP iptables -A OUTPUT -m conntrack --ctstate INVALID -j DROP # réponses à VOS sessions iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # anti-spoof RFC1918 : laissez votre LAN_NET (DHCP / réponses locales) # sans casser le client DHCP if [ -n "${LAN_NET:-}" ]; then # 10/8 et 172.16/12 hors loopback iptables -A INPUT -s 10.0.0.0/8 ! -i lo ! -s "$LAN_NET" -j DROP iptables -A INPUT -s 172.16.0.0/12 ! -i lo ! -s "$LAN_NET" -j DROP iptables -A INPUT -s 192.168.0.0/16 ! -s "$LAN_NET" -j DROP else iptables -A INPUT -s 10.0.0.0/8 ! -i lo -j DROP iptables -A INPUT -s 172.16.0.0/12 ! -i lo -j DROP iptables -A INPUT -s 192.168.0.0/16 ! -i lo -j DROP fi iptables -A INPUT -s 127.0.0.0/8 ! -i lo -j DROP # anti-scan silencieux iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT iptables -A INPUT -p tcp --syn -j DROP # DHCP client iptables -A OUTPUT -o "$IFACE" -p udp --dport 67:68 -j ACCEPT iptables -A INPUT -i "$IFACE" -p udp --sport 67 --dport 68 -j ACCEPT # DNS / NTP sortants iptables -A OUTPUT -o "$IFACE" -p udp --dport 53 -j ACCEPT iptables -A OUTPUT -o "$IFACE" -p tcp --dport 53 -j ACCEPT iptables -A OUTPUT -o "$IFACE" -p udp --dport 123 -j ACCEPT # egress TCP multiport (configurable) iptables -A OUTPUT -o "$IFACE" -p tcp -m multiport --dports "$EXTRA_TCP_PORTS" -j ACCEPT iptables -A OUTPUT -o "$IFACE" -p tcp --dport 853 -j ACCEPT # Tor optionnel (socks local + ports relais courants) if [ "$USE_TOR" = "1" ]; then iptables -A OUTPUT -o lo -p tcp --dport 9050 -j ACCEPT iptables -A OUTPUT -o "$IFACE" -p tcp --dport 9001 -j ACCEPT iptables -A OUTPUT -o "$IFACE" -p tcp --dport 9030 -j ACCEPT fi # SSH entrant : OFF par défaut if [ "$ALLOW_SSH" = "1" ]; then iptables -A INPUT -i "$IFACE" -p tcp --dport 22 -m conntrack --ctstate NEW -m limit --limit 5/min --limit-burst 10 -j ACCEPT fi # fuites locales (mDNS / SSDP / NetBIOS / SMB) if [ "$DROP_MDNS" = "1" ]; then iptables -A OUTPUT -p udp --dport 5353 -j DROP iptables -A OUTPUT -p udp --dport 1900 -j DROP iptables -A OUTPUT -p udp --dport 137:139 -j DROP iptables -A OUTPUT -p tcp --dport 139 -j DROP iptables -A OUTPUT -p tcp --dport 445 -j DROP iptables -A INPUT -p udp --dport 5353 -j DROP iptables -A INPUT -p udp --dport 1900 -j DROP fi # ICMP entrant muet iptables -A INPUT -p icmp -j DROP # log iptables -N BUNKER_LOG 2>/dev/null || true iptables -F BUNKER_LOG iptables -A BUNKER_LOG -m limit --limit 2/min -j LOG --log-prefix "BUNKER_DROP: " --log-level 4 iptables -A BUNKER_LOG -j DROP iptables -A INPUT -j BUNKER_LOG # sortie : hors liste → DROP si STRICT_EGRESS if [ "$STRICT_EGRESS" = "1" ]; then iptables -A OUTPUT -j DROP fi # --- 4) Tor optionnel --- if [ "$USE_TOR" = "1" ]; then systemctl start tor.service 2>/dev/null || true fi echo "OK bunker appliqué." echo "Vérifs : iptables -L -n -v ; hostname ; ip link show $IFACE | grep ether" echo "Rouvrir SSH : ALLOW_SSH=1 sudo -E $0" echo "Tor : USE_TOR=1 sudo -E $0" echo "Checklist : https://pctamalou.fr/tutoriels/doc/bunker-checklist.md"