346 lines
11 KiB
Bash
346 lines
11 KiB
Bash
#!/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
|