#!/bin/bash # # Transparent Proxy Script for Gateway (192.168.1.100) # Routes traffic from LAN clients (192.168.1.111) through Clash proxy # # Usage: # ./tproxy.sh on # Enable transparent proxy # ./tproxy.sh off # Disable transparent proxy # ./tproxy.sh status # Check status # # Prerequisites: # - Clash running with allow-lan: true # - This machine is the gateway for 192.168.1.111 # set -e # ============================================ # Configuration # ============================================ # Clash proxy ports CLASH_HTTP_PORT="${CLASH_HTTP_PORT:-7890}" CLASH_SOCKS_PORT="${CLASH_SOCKS_PORT:-7891}" CLASH_REDIR_PORT="${CLASH_REDIR_PORT:-7892}" CLASH_TPROXY_PORT="${CLASH_TPROXY_PORT:-7893}" CLASH_DNS_PORT="${CLASH_DNS_PORT:-1053}" # Network configuration LAN_INTERFACE="${LAN_INTERFACE:-eth0}" LAN_SUBNET="${LAN_SUBNET:-192.168.1.0/24}" GATEWAY_IP="${GATEWAY_IP:-192.168.1.100}" # Clients to proxy (space-separated) PROXY_CLIENTS="${PROXY_CLIENTS:-192.168.1.111}" # Bypass destinations (don't proxy these) BYPASS_IPS="127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4" # iptables chain name CHAIN_NAME="CLASH_TPROXY" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # ============================================ # Check Prerequisites # ============================================ check_root() { if [ "$EUID" -ne 0 ]; then log_error "This script must be run as root" exit 1 fi } check_clash() { # Check for any clash process (clash, clash-linux-amd64, etc.) if ! pgrep -f "clash" > /dev/null 2>&1; then log_error "Clash is not running" log_info "Please start Clash first" exit 1 fi # Check if Clash is listening on redir port if ! ss -tlnp | grep -q ":$CLASH_REDIR_PORT"; then log_warn "Clash redir port ($CLASH_REDIR_PORT) not listening" log_info "Make sure your Clash config has:" echo " redir-port: $CLASH_REDIR_PORT" echo " allow-lan: true" fi } # ============================================ # Enable Transparent Proxy # ============================================ enable_tproxy() { check_root check_clash log_info "Enabling transparent proxy..." # Enable IP forwarding log_info "Enabling IP forwarding..." echo 1 > /proc/sys/net/ipv4/ip_forward sysctl -w net.ipv4.ip_forward=1 > /dev/null # Make IP forwarding persistent if ! grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf; then echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf fi # Create NAT chain for transparent proxy log_info "Creating iptables rules..." # Remove existing rules if any iptables -t nat -D PREROUTING -j $CHAIN_NAME 2>/dev/null || true iptables -t nat -F $CHAIN_NAME 2>/dev/null || true iptables -t nat -X $CHAIN_NAME 2>/dev/null || true # Create new chain iptables -t nat -N $CHAIN_NAME # Bypass local and private networks for ip in $BYPASS_IPS; do iptables -t nat -A $CHAIN_NAME -d $ip -j RETURN done # Bypass traffic to this gateway itself iptables -t nat -A $CHAIN_NAME -d $GATEWAY_IP -j RETURN # Only proxy traffic from specified clients for client in $PROXY_CLIENTS; do log_info "Adding proxy rule for client: $client" # Redirect HTTP/HTTPS traffic to Clash redir port iptables -t nat -A $CHAIN_NAME -s $client -p tcp --dport 80 -j REDIRECT --to-ports $CLASH_REDIR_PORT iptables -t nat -A $CHAIN_NAME -s $client -p tcp --dport 443 -j REDIRECT --to-ports $CLASH_REDIR_PORT # Redirect all other TCP traffic iptables -t nat -A $CHAIN_NAME -s $client -p tcp -j REDIRECT --to-ports $CLASH_REDIR_PORT done # Apply the chain to PREROUTING iptables -t nat -A PREROUTING -j $CHAIN_NAME # Setup DNS redirect (optional - redirect DNS to Clash DNS) if ss -ulnp | grep -q ":$CLASH_DNS_PORT"; then log_info "Setting up DNS redirect to Clash DNS..." for client in $PROXY_CLIENTS; do iptables -t nat -A PREROUTING -s $client -p udp --dport 53 -j REDIRECT --to-ports $CLASH_DNS_PORT done fi # Ensure MASQUERADE for forwarded traffic iptables -t nat -A POSTROUTING -s $LAN_SUBNET -o $LAN_INTERFACE -j MASQUERADE 2>/dev/null || true log_info "Transparent proxy enabled!" log_info "" log_info "Proxied clients: $PROXY_CLIENTS" log_info "Clash redir port: $CLASH_REDIR_PORT" log_info "" log_info "Test from client (192.168.1.111):" log_info " curl -I https://www.google.com" } # ============================================ # Disable Transparent Proxy # ============================================ disable_tproxy() { check_root log_info "Disabling transparent proxy..." # Remove DNS redirect rules for client in $PROXY_CLIENTS; do iptables -t nat -D PREROUTING -s $client -p udp --dport 53 -j REDIRECT --to-ports $CLASH_DNS_PORT 2>/dev/null || true done # Remove the chain from PREROUTING iptables -t nat -D PREROUTING -j $CHAIN_NAME 2>/dev/null || true # Flush and delete the chain iptables -t nat -F $CHAIN_NAME 2>/dev/null || true iptables -t nat -X $CHAIN_NAME 2>/dev/null || true log_info "Transparent proxy disabled!" log_info "" log_info "Clients will now access internet directly (through NAT only)" } # ============================================ # Check Status # ============================================ show_status() { echo "" echo "============================================" echo "Transparent Proxy Status" echo "============================================" echo "" # Check IP forwarding echo "IP Forwarding:" if [ "$(cat /proc/sys/net/ipv4/ip_forward)" = "1" ]; then echo -e " Status: ${GREEN}Enabled${NC}" else echo -e " Status: ${RED}Disabled${NC}" fi echo "" # Check Clash echo "Clash Process:" if pgrep -f "clash" > /dev/null 2>&1; then echo -e " Status: ${GREEN}Running${NC}" echo " PID: $(pgrep -f clash | head -1)" else echo -e " Status: ${RED}Not Running${NC}" fi echo "" # Check Clash ports echo "Clash Ports:" echo -n " HTTP ($CLASH_HTTP_PORT): " ss -tlnp | grep -q ":$CLASH_HTTP_PORT" && echo -e "${GREEN}Listening${NC}" || echo -e "${RED}Not Listening${NC}" echo -n " SOCKS ($CLASH_SOCKS_PORT): " ss -tlnp | grep -q ":$CLASH_SOCKS_PORT" && echo -e "${GREEN}Listening${NC}" || echo -e "${RED}Not Listening${NC}" echo -n " Redir ($CLASH_REDIR_PORT): " ss -tlnp | grep -q ":$CLASH_REDIR_PORT" && echo -e "${GREEN}Listening${NC}" || echo -e "${RED}Not Listening${NC}" echo -n " DNS ($CLASH_DNS_PORT): " ss -ulnp | grep -q ":$CLASH_DNS_PORT" && echo -e "${GREEN}Listening${NC}" || echo -e "${RED}Not Listening${NC}" echo "" # Check iptables rules echo "iptables Transparent Proxy Chain:" if iptables -t nat -L $CHAIN_NAME > /dev/null 2>&1; then echo -e " Status: ${GREEN}Active${NC}" echo " Rules:" iptables -t nat -L $CHAIN_NAME -n --line-numbers 2>/dev/null | head -20 else echo -e " Status: ${YELLOW}Not Active${NC}" fi echo "" # Check PREROUTING echo "PREROUTING Chain (first 10 rules):" iptables -t nat -L PREROUTING -n --line-numbers | head -12 echo "" } # ============================================ # Test Proxy from Client # ============================================ test_proxy() { echo "" echo "============================================" echo "Proxy Test Instructions" echo "============================================" echo "" echo "Run these commands on 192.168.1.111 to test:" echo "" echo "1. Test Google (requires proxy):" echo " curl -I --connect-timeout 5 https://www.google.com" echo "" echo "2. Test external IP:" echo " curl -s https://ipinfo.io/ip" echo "" echo "3. Test Docker Hub:" echo " curl -I --connect-timeout 5 https://registry-1.docker.io/v2/" echo "" echo "4. Test GitHub:" echo " curl -I --connect-timeout 5 https://github.com" echo "" } # ============================================ # Show Required Clash Configuration # ============================================ show_clash_config() { echo "" echo "============================================" echo "Required Clash Configuration" echo "============================================" echo "" echo "Add these settings to your Clash config.yaml:" echo "" cat << 'EOF' # Enable LAN access allow-lan: true bind-address: "*" # Proxy ports port: 7890 # HTTP proxy socks-port: 7891 # SOCKS5 proxy redir-port: 7892 # Transparent proxy (Linux only) tproxy-port: 7893 # TProxy port (optional) # DNS settings (optional but recommended) dns: enable: true listen: 0.0.0.0:1053 enhanced-mode: fake-ip fake-ip-range: 198.18.0.1/16 nameserver: - 223.5.5.5 - 119.29.29.29 fallback: - 8.8.8.8 - 1.1.1.1 EOF echo "" echo "After modifying, restart Clash:" echo " systemctl restart clash" echo " # or" echo " killall clash && clash -d /path/to/config &" echo "" } # ============================================ # Main # ============================================ case "${1:-}" in on|enable|start) enable_tproxy ;; off|disable|stop) disable_tproxy ;; status) show_status ;; test) test_proxy ;; config) show_clash_config ;; *) echo "Transparent Proxy Manager for Clash" echo "" echo "Usage: $0 {on|off|status|test|config}" echo "" echo "Commands:" echo " on - Enable transparent proxy for LAN clients" echo " off - Disable transparent proxy" echo " status - Show current status" echo " test - Show test commands for clients" echo " config - Show required Clash configuration" echo "" echo "Environment Variables:" echo " CLASH_REDIR_PORT - Clash redir port (default: 7892)" echo " CLASH_DNS_PORT - Clash DNS port (default: 1053)" echo " LAN_INTERFACE - LAN interface (default: eth0)" echo " PROXY_CLIENTS - Space-separated client IPs (default: 192.168.1.111)" echo "" echo "Example:" echo " sudo $0 on # Enable with defaults" echo " sudo PROXY_CLIENTS='192.168.1.111 192.168.1.112' $0 on # Multiple clients" echo " sudo $0 off # Disable" echo "" exit 1 ;; esac