diff --git a/backend/mpc-system/scripts/tproxy.sh b/backend/mpc-system/scripts/tproxy.sh new file mode 100644 index 00000000..30dec13f --- /dev/null +++ b/backend/mpc-system/scripts/tproxy.sh @@ -0,0 +1,344 @@ +#!/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() { + if ! pgrep -x "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 -x "clash" > /dev/null 2>&1; then + echo -e " Status: ${GREEN}Running${NC}" + echo " PID: $(pgrep -x clash)" + 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