├── README.md └── multi-ip-routing-conf.sh /README.md: -------------------------------------------------------------------------------- 1 | ### Multi IP Routing Conf Script 2 | 3 | #### 功能简介 4 | 这个Bash脚本是一个交互式工具,用于在Debian系统上管理iptables/ip6tables的出站NAT规则(SNAT)。它允许用户通过指定目标CIDR地址和公网IP来控制网络流量出站,实现精细化的出口IP管理。脚本会自动读取系统配置的公网IPv4和IPv6地址,并支持规则的持久化(通过自动安装iptables-persistent)。 5 | 6 | 主要功能包括: 7 | - **列出公网IP**:自动检测并显示系统所有公网IPv4和IPv6地址。 8 | - **查看规则**:浏览当前IPv4和IPv6的POSTROUTING链NAT规则,包括编号和详情。 9 | - **添加规则**:交互式输入目标CIDR、公网IP和规则名称(作为注释),添加SNAT规则。 10 | - **删除规则**:根据IP类型(v4/v6)和规则编号删除指定规则。 11 | - **编辑规则**:选择现有规则,修改CIDR、公网IP或规则名称,并重新应用。 12 | - **规则持久化**:所有操作后自动保存规则,确保重启后生效。 13 | 14 | 脚本运行需要root权限(sudo),并在交互菜单中操作,支持IPv4和IPv6混合使用。该脚本由 AI 创建,已经在酷雪云多 V6 环境下测试通过。 15 | 16 | #### 使用场景 17 | 这个脚本适用于需要多IP出口控制的网络环境,帮助解决流量路由、IP隔离或优化的问题。例如: 18 | - **多IP服务器管理**:在云VPS或专用服务器上,有多个公网IP时,你可以指定某些目标网络(如特定网站或子网)的流量从特定IP出站,避免单一IP过载或被封禁。例如,为访问海外服务的流量分配专用出口IP。 19 | - **网络安全与隔离**:在企业或个人防火墙设置中,为敏感目标CIDR(如内部子网或外部API)强制使用特定公网IP,实现流量隔离或合规要求。 20 | - **开发/测试环境**:开发者在Debian容器或VM中测试网络路由时,快速添加/编辑规则来模拟不同出口场景,而无需手动编辑iptables命令。 21 | - **负载均衡或冗余**:在有备用公网IP的系统中,针对高流量目标CIDR切换出口IP,提高可用性和性能。 22 | 23 | 通过这个脚本,用户可以避免复杂的命令行操作,快速配置和管理出站规则,适合网络管理员、DevOps工程师或Linux爱好者。 24 | 25 | #### 脚本的使用方法 26 | 该脚本托管在GitHub上,线上链接为:https://github.com/yt1988/Multi-IP-Routing-Conf/raw/refs/heads/main/multi-ip-routing-conf.sh 27 | 28 | 在Debian系统中,您可以采用一键运行的方式快速部署和使用脚本。以下是推荐步骤: 29 | 30 | 1. **一键下载并运行(推荐,但请确保信任来源)**: 31 | 使用curl直接下载并管道执行脚本: 32 | ``` 33 | curl -sSL https://github.com/yt1988/Multi-IP-Routing-Conf/raw/refs/heads/main/multi-ip-routing-conf.sh | sudo bash 34 | ``` 35 | 这将自动下载脚本、检查并安装iptables-persistent(如果缺失),然后进入交互菜单。脚本需要root权限,因此使用sudo。 36 | 37 | 2. **手动下载并运行**: 38 | - 下载脚本: 39 | ``` 40 | wget https://github.com/yt1988/Multi-IP-Routing-Conf/raw/refs/heads/main/multi-ip-routing-conf.sh -O multi-ip-routing-conf.sh 41 | ``` 42 | - 赋予执行权限: 43 | ``` 44 | chmod +x multi-ip-routing-conf.sh 45 | ``` 46 | - 以root权限运行: 47 | ``` 48 | sudo ./multi-ip-routing-conf.sh 49 | ``` 50 | 51 | 运行后,脚本会显示主菜单,您可以通过数字选项(如1-6)进行操作。确保系统为Debian或兼容的衍生版(如Ubuntu),并已启用IPv4/IPv6转发(如果需要)。 52 | -------------------------------------------------------------------------------- /multi-ip-routing-conf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script manages outbound rules for specific destination CIDRs using SNAT on Debian systems. 4 | # It supports IPv4 and IPv6 public IPs. 5 | # Requires iptables and ip6tables. Will automatically install iptables-persistent if not present. 6 | # Run as root: sudo ./script.sh 7 | 8 | # Check and install iptables-persistent if not installed 9 | if ! command -v netfilter-persistent &> /dev/null; then 10 | echo "安装 iptables-persistent 以确保规则持久化..." 11 | apt update 12 | apt install -y iptables-persistent 13 | if [ $? -ne 0 ]; then 14 | echo "错误:无法安装 iptables-persistent。请手动安装。" 15 | exit 1 16 | fi 17 | fi 18 | 19 | # Function to get all public IPv4 addresses 20 | get_public_ipv4() { 21 | ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -vE '^127\.|^10\.|^172\.(1[6-9]|2[0-9]|3[0-1])\.|^192\.168\.' | sort -u 22 | } 23 | 24 | # Function to get all public IPv6 addresses (global unicast, excluding link-local and ULA) 25 | get_public_ipv6() { 26 | ip -6 addr show | grep -oP '(?<=inet6\s)[0-9a-f:]+' | grep -E '^2' | grep -vE '^fe80|^fc' | sort -u 27 | } 28 | 29 | # Function to list all public IPs 30 | list_public_ips() { 31 | echo "公网 IPv4 地址:" 32 | get_public_ipv4 33 | echo "" 34 | echo "公网 IPv6 地址:" 35 | get_public_ipv6 36 | } 37 | 38 | # Function to view current outbound rules 39 | view_rules() { 40 | echo "IPv4 NAT POSTROUTING 规则:" 41 | iptables -t nat -L POSTROUTING -n -v --line-numbers 42 | echo "" 43 | echo "IPv6 NAT POSTROUTING 规则:" 44 | ip6tables -t nat -L POSTROUTING -n -v --line-numbers 45 | } 46 | 47 | # Function to add a rule 48 | add_rule() { 49 | # List public IPs for selection 50 | echo "可用的公网 IP:" 51 | list_public_ips 52 | echo "" 53 | 54 | # Ask for the public IP to use for outbound 55 | read -p "请输入用于出站的公网 IP(v4 或 v6): " public_ip 56 | 57 | # Detect if IPv4 or IPv6 58 | if [[ $public_ip =~ \. ]]; then 59 | ip_type="v4" 60 | cmd="iptables" 61 | elif [[ $public_ip =~ : ]]; then 62 | ip_type="v6" 63 | cmd="ip6tables" 64 | else 65 | echo "无效的 IP 格式。" 66 | return 67 | fi 68 | 69 | # Ask for the destination CIDR 70 | read -p "请输入目标 CIDR(例如,192.168.1.0/24 或 2001:db8::/64): " cidr 71 | 72 | # Validate CIDR matches IP type 73 | if [[ $ip_type == "v4" && $cidr =~ : ]] || [[ $ip_type == "v6" && $cidr =~ \. ]]; then 74 | echo "CIDR 类型与公网 IP 类型不匹配。" 75 | return 76 | fi 77 | 78 | # Ask for the rule name 79 | read -p "请输入规则名称: " rule_name 80 | 81 | # Add the SNAT rule for destination with comment 82 | $cmd -t nat -A POSTROUTING -d "$cidr" -m comment --comment "$rule_name" -j SNAT --to-source "$public_ip" 83 | echo "规则已添加。" 84 | 85 | # Save rules for persistence 86 | netfilter-persistent save 87 | } 88 | 89 | # Function to delete a rule 90 | delete_rule() { 91 | # View rules first 92 | view_rules 93 | echo "" 94 | 95 | # Ask for IP type 96 | read -p "请输入 'v4' 表示 IPv4 或 'v6' 表示 IPv6: " ip_type 97 | if [[ $ip_type == "v4" ]]; then 98 | cmd="iptables" 99 | elif [[ $ip_type == "v6" ]]; then 100 | cmd="ip6tables" 101 | else 102 | echo "无效的选择。" 103 | return 104 | fi 105 | 106 | # Ask for the rule number to delete 107 | read -p "请输入要删除的规则编号: " rule_num 108 | 109 | # Delete the rule 110 | $cmd -t nat -D POSTROUTING "$rule_num" 111 | echo "规则已删除。" 112 | 113 | # Save rules 114 | netfilter-persistent save 115 | } 116 | 117 | # Function to edit a rule 118 | edit_rule() { 119 | # View rules first 120 | view_rules 121 | echo "" 122 | 123 | # Ask for IP type 124 | read -p "请输入 'v4' 表示 IPv4 或 'v6' 表示 IPv6: " ip_type 125 | if [[ $ip_type == "v4" ]]; then 126 | cmd="iptables" 127 | elif [[ $ip_type == "v6" ]]; then 128 | cmd="ip6tables" 129 | else 130 | echo "无效的选择。" 131 | return 132 | fi 133 | 134 | # Ask for the rule number to edit 135 | read -p "请输入要编辑的规则编号: " rule_num 136 | 137 | # Get the current rule line using -S (show in save format) 138 | rule_line=$($cmd -t nat -S POSTROUTING | sed -n "${rule_num}p") 139 | 140 | if [ -z "$rule_line" ]; then 141 | echo "规则不存在。" 142 | return 143 | fi 144 | 145 | # Parse the current values 146 | # Assuming format: -A POSTROUTING -d CIDR -m comment --comment "NAME" -j SNAT --to-source IP 147 | current_cidr=$(echo "$rule_line" | grep -oP '(?<=-d )\S+') 148 | current_public_ip=$(echo "$rule_line" | grep -oP '(?<=--to-source )\S+') 149 | current_rule_name=$(echo "$rule_line" | grep -oP '(?<=--comment ")([^"]+)(?=")') 150 | 151 | # Prompt for new values, default to current 152 | read -p "当前目标 CIDR: $current_cidr,新值(回车保持不变): " new_cidr 153 | new_cidr=${new_cidr:-$current_cidr} 154 | 155 | read -p "当前公网 IP: $current_public_ip,新值(回车保持不变): " new_public_ip 156 | new_public_ip=${new_public_ip:-$current_public_ip} 157 | 158 | read -p "当前规则名称: $current_rule_name,新值(回车保持不变): " new_rule_name 159 | new_rule_name=${new_rule_name:-$current_rule_name} 160 | 161 | # Validate new CIDR matches IP type 162 | if [[ $ip_type == "v4" && $new_cidr =~ : ]] || [[ $ip_type == "v6" && $new_cidr =~ \. ]]; then 163 | echo "新 CIDR 类型与公网 IP 类型不匹配。" 164 | return 165 | fi 166 | 167 | # Delete the old rule 168 | $cmd -t nat -D POSTROUTING "$rule_num" 169 | 170 | # Add the new rule 171 | $cmd -t nat -A POSTROUTING -d "$new_cidr" -m comment --comment "$new_rule_name" -j SNAT --to-source "$new_public_ip" 172 | echo "规则已编辑。" 173 | 174 | # Save rules 175 | netfilter-persistent save 176 | } 177 | 178 | # Main menu 179 | while true; do 180 | echo "" 181 | echo "出站规则管理器" 182 | echo "1. 列出公网 IP" 183 | echo "2. 查看规则" 184 | echo "3. 添加规则" 185 | echo "4. 删除规则" 186 | echo "5. 编辑规则" 187 | echo "6. 退出" 188 | read -p "选择一个选项: " choice 189 | 190 | case $choice in 191 | 1) list_public_ips ;; 192 | 2) view_rules ;; 193 | 3) add_rule ;; 194 | 4) delete_rule ;; 195 | 5) edit_rule ;; 196 | 6) exit 0 ;; 197 | *) echo "无效的选项。" ;; 198 | esac 199 | done --------------------------------------------------------------------------------