├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── dnat-uninstall.sh ├── natcfg.sh └── wechat_shoukuan.jpg /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: http://cdn.arloor.com/wechat_shoukuan.jpg 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | 3 | *IP -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 利用iptables设置端口转发的shell脚本 2 | 3 | ## 项目作用 4 | 5 | 1. 便捷地设置iptables流量转发规则 6 | 2. 当域名解析的地址发生变化时,自动更新流量转发规则,不需要手动变更(适用于ddns域名) 7 | 8 | ## 用法 9 | 10 | **国内机器使用** 11 | 12 | > 通过Github Proxy加速下载 13 | 14 | ```shell 15 | bash <(curl -fsSL https://us.arloor.dev/https://raw.githubusercontent.com/arloor/iptablesUtils/master/natcfg.sh) 16 | ``` 17 | 18 | **国外机器使用** 19 | 20 | ``` 21 | bash <(curl -fsSL https://raw.githubusercontent.com/arloor/iptablesUtils/master/natcfg.sh) 22 | ``` 23 | 24 | ### 输出如下: 25 | 26 | ``` 27 | ############################################################# 28 | # Usage: setup iptables nat rules for domian/ip # 29 | # Website: http://www.arloor.com/ # 30 | # Author: ARLOOR # 31 | # Github: https://github.com/arloor/iptablesUtils # 32 | ############################################################# 33 | 34 | 你要做什么呢(请输入数字)?Ctrl+C 退出本脚本 35 | 1) 增加转发规则 3) 列出所有转发规则 36 | 2) 删除转发规则 4) 查看当前iptables配置 37 | #? 38 | ``` 39 | 40 | 此时按照需要,输入1-4中的任意数字,然后按照提示即可。`Ctrl+C` 退出本脚本 41 | 42 | ## 卸载 43 | 44 | **国内机器使用** 45 | 46 | > 通过Github Proxy加速下载 47 | 48 | ```shell 49 | bash <(curl -SsLf https://us.arloor.dev/https://raw.githubusercontent.com/arloor/iptablesUtils/master/dnat-uninstall.sh) 50 | ``` 51 | 52 | **国外机器使用** 53 | 54 | ```shell 55 | bash <(curl -SsLf https://raw.githubusercontent.com/arloor/iptablesUtils/master/dnat-uninstall.sh) 56 | ``` 57 | 58 | ## 查看日志 59 | 60 | ```shell 61 | journalctl -exu dnat 62 | ``` 63 | 64 | ## 配置文件备份和导入导出 65 | 66 | 配置文件在 67 | 68 | ```shell 69 | /etc/dnat/conf 70 | ``` 71 | 72 | ## trojan转发 73 | 74 | 总是有人说,不能转发trojan,这么说的人大部分是证书配置不对。最简单的解决方案是:客户端选择不验证证书。复杂一点是自己把证书和中转机的域名搭配好。 75 | 76 | 小白记住一句话就好:客户端不验证证书。 77 | 78 | ----------------------------------------------------------------------------- 79 | 80 | ## 推荐新项目——使用nftables实现nat转发 81 | 82 | iptables的后继者nftables已经在debain和centos最新的操作系统中作为生产工具提供,nftables提供了很多新的特性,解决了iptables很多痛点。 83 | 84 | 因此创建了一个新的项目[/arloor/nftables-nat-rust](https://github.com/arloor/nftables-nat-rust)。该项目使用nftables作为nat转发实现,相比本项目具有如下优点: 85 | 86 | 1. 支持端口段转发 87 | 2. 转发规则使用配置文件,可以进行备份以及导入 88 | 3. 更加现代 89 | 90 | 所以**强烈推荐**使用[/arloor/nftables-nat-rust](https://github.com/arloor/nftables-nat-rust)。不用担心,本项目依然可以正常稳定使用。 91 | 92 | PS: 新旧两个项目并不兼容,切换到新项目时,请先卸载此项目 93 | 94 | -------------------------------------------------------------------------------- /dnat-uninstall.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | base=/etc/dnat 4 | systemctl disable --now dnat 5 | rm -rf $base 6 | iptables -t nat -F PREROUTING 7 | iptables -t nat -F POSTROUTING 8 | -------------------------------------------------------------------------------- /natcfg.sh: -------------------------------------------------------------------------------- 1 | red="\033[31m" 2 | black="\033[0m" 3 | 4 | base=/etc/dnat 5 | mkdir $base 2>/dev/null 6 | conf=$base/conf 7 | touch $conf 8 | 9 | # wget wget --no-check-certificate -qO natcfg.sh http://blog.arloor.com/sh/iptablesUtils/natcfg.sh && bash natcfg.sh 10 | 11 | clear 12 | echo "#############################################################" 13 | echo "# Usage: setup iptables nat rules for domian/ip #" 14 | echo "# Website: http://www.arloor.com/ #" 15 | echo "# Author: ARLOOR #" 16 | echo "# Github: https://github.com/arloor/iptablesUtils #" 17 | echo "#############################################################" 18 | echo 19 | 20 | 21 | setupService(){ 22 | cat > /usr/local/bin/dnat.sh <<"AAAA" 23 | #! /bin/bash 24 | [[ "$EUID" -ne '0' ]] && echo "Error:This script must be run as root!" && exit 1; 25 | 26 | 27 | 28 | base=/etc/dnat 29 | mkdir $base 2>/dev/null 30 | conf=$base/conf 31 | firstAfterBoot=1 32 | lastConfig="/iptables_nat.sh" 33 | lastConfigTmp="/iptables_nat.sh_tmp" 34 | 35 | 36 | #### 37 | echo "正在安装依赖...." 38 | yum install -y bind-utils &> /dev/null 39 | apt install -y dnsutils &> /dev/null 40 | echo "Completed:依赖安装完毕" 41 | echo "" 42 | #### 43 | turnOnNat(){ 44 | # 开启端口转发 45 | echo "1. 端口转发开启 【成功】" 46 | sed -n '/^net.ipv4.ip_forward=1/'p /etc/sysctl.conf | grep -q "net.ipv4.ip_forward=1" 47 | if [ $? -ne 0 ]; then 48 | echo -e "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && sysctl -p 49 | fi 50 | 51 | #开放FORWARD链 52 | echo "2. 开放iptbales中的FORWARD链 【成功】" 53 | arr1=(`iptables -L FORWARD -n --line-number |grep "REJECT"|grep "0.0.0.0/0"|sort -r|awk '{print $1,$2,$5}'|tr " " ":"|tr "\n" " "`) #16:REJECT:0.0.0.0/0 15:REJECT:0.0.0.0/0 54 | for cell in ${arr1[@]} 55 | do 56 | arr2=(`echo $cell|tr ":" " "`) #arr2=16 REJECT 0.0.0.0/0 57 | index=${arr2[0]} 58 | echo 删除禁止FOWARD的规则$index 59 | iptables -D FORWARD $index 60 | done 61 | iptables --policy FORWARD ACCEPT 62 | } 63 | turnOnNat 64 | 65 | 66 | 67 | testVars(){ 68 | local localport=$1 69 | local remotehost=$2 70 | local remoteport=$3 71 | # 判断端口是否为数字 72 | local valid= 73 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]||{ 74 | echo -e "${red}本地端口和目标端口请输入数字!!${black}"; 75 | return 1; 76 | } 77 | } 78 | 79 | dnat(){ 80 | [ "$#" = "3" ]&&{ 81 | local localport=$1 82 | local remote=$2 83 | local remoteport=$3 84 | 85 | cat >> $lastConfigTmp <$base/${1}IP 113 | dnat $1 $remote $3 114 | } 115 | 116 | 117 | echo "3. 开始监听域名解析变化" 118 | echo "" 119 | while true ; 120 | do 121 | ## 获取本机地址 122 | localIP=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 | grep -Ev '(^127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.1[6-9]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.2[0-9]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.3[0-1]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^192\.168\.[0-9]{1,3}\.[0-9]{1,3}$)') 123 | if [ "${localIP}" = "" ]; then 124 | localIP=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1|head -n 1 ) 125 | fi 126 | echo "本机网卡IP [$localIP]" 127 | cat > $lastConfigTmp <" " "`) #arr2=16 REJECT 0.0.0.0/0 135 | # 过滤非法的行 136 | [ "${arr2[2]}" != "" -a "${arr2[3]}" = "" ]&& testVars ${arr2[0]} ${arr2[1]} ${arr2[2]}&&{ 137 | echo "转发规则: ${arr2[0]} => ${arr2[1]}:${arr2[2]}" 138 | dnatIfNeed ${arr2[0]} ${arr2[1]} ${arr2[2]} 139 | } 140 | done 141 | 142 | lastConfigTmpStr=`cat $lastConfigTmp` 143 | lastConfigStr=`cat $lastConfig` 144 | if [ "$firstAfterBoot" = "1" -o "$lastConfigTmpStr" != "$lastConfigStr" ];then 145 | echo '更新iptables规则[DOING]' 146 | source $lastConfigTmp 147 | cat $lastConfigTmp > $lastConfig 148 | echo '更新iptables规则[DONE],新规则如下:' 149 | echo "###########################################################" 150 | iptables -L PREROUTING -n -t nat --line-number 151 | iptables -L POSTROUTING -n -t nat --line-number 152 | echo "###########################################################" 153 | else 154 | echo "iptables规则未变更" 155 | fi 156 | 157 | firstAfterBoot=0 158 | echo '' > $lastConfigTmp 159 | sleep 60 160 | echo '' 161 | echo '' 162 | echo '' 163 | done 164 | AAAA 165 | echo 166 | 167 | 168 | cat > /lib/systemd/system/dnat.service <<\EOF 169 | [Unit] 170 | Description=动态设置iptables转发规则 171 | After=network-online.target 172 | Wants=network-online.target 173 | 174 | [Service] 175 | WorkingDirectory=/root/ 176 | EnvironmentFile= 177 | ExecStart=/bin/bash /usr/local/bin/dnat.sh 178 | Restart=always 179 | RestartSec=30 180 | 181 | [Install] 182 | WantedBy=multi-user.target 183 | EOF 184 | 185 | systemctl daemon-reload 186 | systemctl enable dnat > /dev/null 2>&1 187 | service dnat stop > /dev/null 2>&1 188 | service dnat start > /dev/null 2>&1 189 | } 190 | 191 | 192 | ## 获取本机地址 193 | localIP=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 | grep -Ev '(^127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.1[6-9]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.2[0-9]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.3[0-1]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^192\.168\.[0-9]{1,3}\.[0-9]{1,3}$)') 194 | if [ "${localIP}" = "" ]; then 195 | localIP=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1|head -n 1 ) 196 | fi 197 | 198 | 199 | addDnat(){ 200 | local localport= 201 | local remoteport= 202 | local remotehost= 203 | local valid= 204 | echo -n "本地端口号:" ;read localport 205 | echo -n "远程端口号:" ;read remoteport 206 | # echo $localport $remoteport 207 | # 判断端口是否为数字 208 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]||{ 209 | echo -e "${red}本地端口和目标端口请输入数字!!${black}" 210 | return 1; 211 | } 212 | 213 | echo -n "目标域名/IP:" ;read remotehost 214 | # # 检查输入的不是IP 215 | # if [ "$remotehost" = "" -o "$(echo $remotehost |grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}')" != "" ];then 216 | # isip=true 217 | # remote=$remotehost 218 | # echo -e "${red}请输入一个ddns域名${black}" 219 | # return 1 220 | # fi 221 | 222 | sed -i "s/^$localport.*/$localport>$remotehost:$remoteport/g" $conf 223 | [ "$(cat $conf|grep "$localport>$remotehost:$remoteport")" = "" ]&&{ 224 | cat >> $conf <$remotehost:$remoteport 226 | LINE 227 | } 228 | echo "成功添加转发规则 $localport>$remotehost:$remoteport" 229 | setupService 230 | } 231 | 232 | rmDnat(){ 233 | local localport= 234 | echo -n "本地端口号:" ;read localport 235 | sed -i "/^$localport>.*/d" $conf 236 | echo "done!" 237 | } 238 | 239 | testVars(){ 240 | local localport=$1 241 | local remotehost=$2 242 | local remoteport=$3 243 | # 判断端口是否为数字 244 | local valid= 245 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]||{ 246 | # echo -e "${red}本地端口和目标端口请输入数字!!${black}"; 247 | return 1; 248 | } 249 | 250 | # # 检查输入的不是IP 251 | # if [ "$(echo $remotehost |grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}')" != "" ];then 252 | # local isip=true 253 | # local remote=$remotehost 254 | 255 | # # echo -e "${red}警告:你输入的目标地址是一个ip!${black}" 256 | # return 2; 257 | # fi 258 | } 259 | 260 | lsDnat(){ 261 | arr1=(`cat $conf`) 262 | for cell in ${arr1[@]} 263 | do 264 | arr2=(`echo $cell|tr ":" " "|tr ">" " "`) #arr2=16 REJECT 0.0.0.0/0 265 | # 过滤非法的行 266 | [ "${arr2[2]}" != "" -a "${arr2[3]}" = "" ]&& testVars ${arr2[0]} ${arr2[1]} ${arr2[2]}&&{ 267 | echo "转发规则: ${arr2[0]}>${arr2[1]}:${arr2[2]}" 268 | } 269 | done 270 | } 271 | 272 | 273 | 274 | 275 | echo -e "${red}你要做什么呢(请输入数字)?Ctrl+C 退出本脚本${black}" 276 | select todo in 增加转发规则 删除转发规则 列出所有转发规则 查看当前iptables配置 277 | do 278 | case $todo in 279 | 增加转发规则) 280 | addDnat 281 | #break 282 | ;; 283 | 删除转发规则) 284 | rmDnat 285 | #break 286 | ;; 287 | # 增加到IP的转发) 288 | # addSnat 289 | # #break 290 | # ;; 291 | # 删除到IP的转发) 292 | # rmSnat 293 | # #break 294 | # ;; 295 | 列出所有转发规则) 296 | lsDnat 297 | ;; 298 | 查看当前iptables配置) 299 | echo "###########################################################" 300 | iptables -L PREROUTING -n -t nat --line-number 301 | iptables -L POSTROUTING -n -t nat --line-number 302 | echo "###########################################################" 303 | ;; 304 | *) 305 | echo "如果要退出,请按Ctrl+C" 306 | ;; 307 | esac 308 | done 309 | -------------------------------------------------------------------------------- /wechat_shoukuan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arloor/iptablesUtils/99d248158f7507c899501fd7821e4f9bb9f85c74/wechat_shoukuan.jpg --------------------------------------------------------------------------------