├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── dnat-uninstall.sh ├── dnat.sh ├── iptables.sh ├── iptables4ddns.sh ├── natcfg.sh ├── rmPreNatRule.sh ├── setCroniptablesDDNS-debian.sh └── setCroniptablesDDNS.sh /.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 | ## 上游项目地址 2 | https://github.com/arloor/iptablesUtils 3 | 4 | ## 修改内容 5 | 6 | 1、通过 ip.sb 获取公网IPV4地址,方便NAT GCE AWS 阿里云等内网ip机型获取公网IP 7 | 8 | 2、修改 dnat.sh 下载逻辑,变更dnat.sh的下载地址,避免github raw dns污染导致异常 9 | 10 | 3、添加 gitlab 镜像仓库 11 | 12 | ## 用法 13 | 14 | ```shell 15 | wget -qO natcfg.sh https://gitlab.com/wulabing/iptablesUtils/raw/master/natcfg.sh && bash natcfg.sh 16 | ``` 17 | 18 | 其他内容请参考上游项目 19 | -------------------------------------------------------------------------------- /dnat-uninstall.sh: -------------------------------------------------------------------------------- 1 | if [ $USER != "root" ];then 2 | echo -e "${red}请使用root用户执行本脚本!! ${black}" 3 | exit 1 4 | fi 5 | 6 | #要删除的转发端口 7 | localport=$1 8 | if [ "$localport" = "" ];then 9 | echo -n "要删除的ddns转发的本地端口:" ;read localport 10 | fi 11 | 12 | # 判断端口是否为数字 13 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && valid=true 14 | if [ "$valid" = "" ];then 15 | echo -e "本地端口请输入数字!!" 16 | exit 1; 17 | fi 18 | 19 | service dnat$localport stop 20 | systemctl disable dnat$localport 21 | rm -f /lib/systemd/system/dnat$localport.service 22 | rm -f /etc/dnat/$localport.conf 23 | 24 | arr1=(`iptables -L PREROUTING -n -t nat --line-number |grep DNAT|grep "dpt:$localport "|sort -r|awk '{print $1,$3,$9}'|tr " " ":"|tr "\n" " "`) 25 | for cell in ${arr1[@]} # cell= 1:tcp:to:8.8.8.8:543 26 | do 27 | arr2=(`echo $cell|tr ":" " "`) #arr2=(1 tcp to 8.8.8.8 543) 28 | index=${arr2[0]} 29 | proto=${arr2[1]} 30 | targetIP=${arr2[3]} 31 | targetPort=${arr2[4]} 32 | echo 清除本机$localport端口到$targetIP:$targetPort的${proto}PREROUTING转发规则$index 33 | iptables -t nat -D PREROUTING $index 34 | echo 清除对应的POSTROUTING规则 35 | toRmIndexs=(`iptables -L POSTROUTING -n -t nat --line-number|grep $targetIP|grep $targetPort|grep $proto|awk '{print $1}'|sort -r|tr "\n" " "`) 36 | for cell1 in ${toRmIndexs[@]} 37 | do 38 | iptables -t nat -D POSTROUTING $cell1 39 | done 40 | done -------------------------------------------------------------------------------- /dnat.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | [[ "$EUID" -ne '0' ]] && echo "Error:This script must be run as root!" && exit 1; 3 | 4 | 5 | 6 | base=/etc/dnat 7 | mkdir $base 2>/dev/null 8 | conf=$base/conf 9 | firstAfterBoot=1 10 | 11 | 12 | #### 13 | echo "正在安装依赖...." 14 | yum install -y bind-utils &> /dev/null 15 | apt install -y dnsutils &> /dev/null 16 | echo "Completed:依赖安装完毕" 17 | echo "" 18 | #### 19 | turnOnNat(){ 20 | # 开启端口转发 21 | echo "1.端口转发开启 【成功】" 22 | sed -n '/^net.ipv4.ip_forward=1/'p /etc/sysctl.conf | grep -q "net.ipv4.ip_forward=1" 23 | if [ $? -ne 0 ]; then 24 | echo -e "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && sysctl -p 25 | fi 26 | 27 | #开放FORWARD链 28 | echo "2.开放iptbales中的FORWARD链 【成功】" 29 | 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 30 | for cell in ${arr1[@]} 31 | do 32 | arr2=(`echo $cell|tr ":" " "`) #arr2=16 REJECT 0.0.0.0/0 33 | index=${arr2[0]} 34 | echo 删除禁止FOWARD的规则——$index 35 | iptables -D FORWARD $index 36 | done 37 | iptables --policy FORWARD ACCEPT 38 | } 39 | turnOnNat 40 | 41 | 42 | 43 | testVars(){ 44 | local localport=$1 45 | local remotehost=$2 46 | local remoteport=$3 47 | # 判断端口是否为数字 48 | local valid= 49 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]||{ 50 | # echo -e "${red}本地端口和目标端口请输入数字!!${black}"; 51 | return 1; 52 | } 53 | 54 | # 检查输入的不是IP 55 | if [ "$(echo $remotehost |grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}')" != "" ];then 56 | local isip=true 57 | local remote=$remotehost 58 | 59 | # echo -e "${red}警告:你输入的目标地址是一个ip!${black}" 60 | return 2; 61 | fi 62 | } 63 | 64 | dnat(){ 65 | [ "$#" = "3" ]&&echo $1 $2 $3 66 | local localport=$1 67 | local remote=$2 68 | local remoteport=$3 69 | #删除旧的中转规则 70 | arr1=(`iptables -L PREROUTING -n -t nat --line-number |grep DNAT|grep "dpt:$localport "|sort -r|awk '{print $1,$3,$9}'|tr " " ":"|tr "\n" " "`) 71 | for cell in ${arr1[@]} # cell= 1:tcp:to:8.8.8.8:543 72 | do 73 | arr2=(`echo $cell|tr ":" " "`) #arr2=(1 tcp to 8.8.8.8 543) 74 | index=${arr2[0]} 75 | proto=${arr2[1]} 76 | targetIP=${arr2[3]} 77 | targetPort=${arr2[4]} 78 | # echo 清除本机$localport端口到$targetIP:$targetPort的${proto}的PREROUTING转发规则[$index] 79 | iptables -t nat -D PREROUTING $index 80 | # echo ==清除对应的POSTROUTING规则 81 | toRmIndexs=(`iptables -L POSTROUTING -n -t nat --line-number|grep SNAT|grep $targetIP|grep dpt:$targetPort|grep $proto|awk '{print $1}'|sort -r|tr "\n" " "`) 82 | for cell1 in ${toRmIndexs[@]} 83 | do 84 | iptables -t nat -D POSTROUTING $cell1 85 | done 86 | done 87 | 88 | ## 建立新的中转规则 89 | iptables -t nat -A PREROUTING -p tcp --dport $localport -j DNAT --to-destination $remote:$remoteport 90 | iptables -t nat -A PREROUTING -p udp --dport $localport -j DNAT --to-destination $remote:$remoteport 91 | iptables -t nat -A POSTROUTING -p tcp -d $remote --dport $remoteport -j SNAT --to-source $localIP 92 | iptables -t nat -A POSTROUTING -p udp -d $remote --dport $remoteport -j SNAT --to-source $localIP 93 | } 94 | 95 | dnatIfNeed(){ 96 | [ "$#" = "3" ]&&{ 97 | local needNat=0 98 | local remote=$(host -t a $2|grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"|head -1) 99 | if [ "$remote" = "" ];then 100 | echo Warn:解析失败 101 | return 1; 102 | fi 103 | }||{ 104 | echo "Error: host命令缺失或传递的参数数量有误" 105 | return 1; 106 | } 107 | 108 | if [[ -f "$base/${1}IP" ]];then 109 | local last=`cat $base/${1}IP` 110 | [ "$last" != "$remote" ]&&needNat=1&&echo IP变化 进行nat 111 | else 112 | # echo 不存在强制nat 113 | needNat=1 114 | fi 115 | 116 | if [ "$firstAfterBoot" = "1" ];then 117 | echo 第一次运行,强制刷新nat 118 | needNat=1 119 | fi 120 | 121 | echo $remote >$base/${1}IP 122 | [ "$needNat" = "1" ]&& dnat $1 $remote $3 123 | } 124 | 125 | while true ; 126 | do 127 | ## 获取本机地址 128 | 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}$)') 129 | if [ "${localIP}" = "" ]; then 130 | localIP=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1|head -n 1 ) 131 | fi 132 | echo "3.本机网卡IP——$localIP" 133 | arr1=(`cat $conf`) 134 | for cell in ${arr1[@]} 135 | do 136 | arr2=(`echo $cell|tr ":" " "|tr ">" " "`) #arr2=16 REJECT 0.0.0.0/0 137 | # 过滤非法的行 138 | [ "${arr2[2]}" != "" -a "${arr2[3]}" = "" ]&& testVars ${arr2[0]} ${arr2[1]} ${arr2[2]}&&{ 139 | echo "转发规则${arr2[0]}>${arr2[1]}:${arr2[2]}" 140 | dnatIfNeed ${arr2[0]} ${arr2[1]} ${arr2[2]} 141 | } 142 | done 143 | echo "###########################################################" 144 | iptables -L PREROUTING -n -t nat --line-number 145 | iptables -L POSTROUTING -n -t nat --line-number 146 | echo "###########################################################" 147 | firstAfterBoot=0 148 | sleep 60 149 | done 150 | -------------------------------------------------------------------------------- /iptables.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # wget https://raw.githubusercontent.com/arloor/iptablesUtils/master/iptables.sh;bash iptables.sh;rm -f iptables.sh; 4 | 5 | red="\033[31m" 6 | black="\033[0m" 7 | 8 | if [ $USER = "root" ];then 9 | echo "本脚本用途:" 10 | echo "设置本机tcp和udp端口转发" 11 | echo "原始iptables仅支持ip地址,该脚本增加域名支持(要求域名指向的主机ip不变)" 12 | echo -e "若要支持ddns,请使用 ${red}dnat-install.sh${black}" 13 | echo 14 | else 15 | echo -e "${red}请使用root用户执行本脚本!! ${black}" 16 | exit 1 17 | fi 18 | 19 | #中转目标host,自行修改 20 | remotehost= 21 | #中转端口,自行修改 22 | remoteport= 23 | localport= 24 | if [ "$localport" = "" ];then 25 | echo -n "local port:" ;read localport 26 | fi 27 | 28 | if [ "$remoteport" = "" ];then 29 | echo -n "remote port:" ;read remoteport 30 | fi 31 | if [ "$remotehost" = "" ];then 32 | echo -n "target domain/ip:" ;read remotehost 33 | fi 34 | 35 | # 判断端口是否为数字 36 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]&& valid=true 37 | if [ "$valid" = "" ];then 38 | echo -e "${red}本地端口和目标端口请输入数字!!${black}" 39 | exit 1; 40 | fi 41 | 42 | if [ "$(echo $remotehost |grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}')" != "" ];then 43 | isip=true 44 | remote=$remotehost 45 | else 46 | echo "正在安装host命令....." 47 | yum install -y wget bind-utils &> /dev/null #为centos系列安装依赖 48 | apt install -y wget dnsutils &> /dev/null #为debain系列安装依赖 49 | echo "Done" 50 | remote=$(host -t a $remotehost|grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"|head -1) 51 | fi 52 | if [ "$remote" = "" ];then 53 | echo -e "${red}无法解析remotehost,请填写正确的remotehost!${black}" 54 | exit 1 55 | fi 56 | 57 | 58 | 59 | 60 | # 开启端口转发 61 | sed -n '/^net.ipv4.ip_forward=1/'p /etc/sysctl.conf | grep -q "net.ipv4.ip_forward=1" 62 | if [ $? -ne 0 ]; then 63 | echo -e "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && sysctl -p 64 | fi 65 | 66 | #开放FORWARD链 67 | 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 68 | for cell in ${arr1[@]} 69 | do 70 | arr2=(`echo $cell|tr ":" " "`) #arr2=16 REJECT 0.0.0.0/0 71 | index=${arr2[0]} 72 | echo 删除禁止FOWARD的规则——$index 73 | iptables -D FORWARD $index 74 | done 75 | iptables --policy FORWARD ACCEPT 76 | 77 | ## 获取本机地址 78 | local=$(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}$)') 79 | if [ "x${local}" = "x" ]; then 80 | local=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 ) 81 | fi 82 | echo target-ip: $remote 83 | echo local-ip: $local 84 | 85 | ##如果有旧的,冲突的规则则删除 86 | arr1=(`iptables -L PREROUTING -n -t nat --line-number |grep DNAT|grep "dpt:$localport "|sort -r|awk '{print $1,$3,$9}'|tr " " ":"|tr "\n" " "`) 87 | for cell in ${arr1[@]} # cell= 1:tcp:to:8.8.8.8:543 88 | do 89 | arr2=(`echo $cell|tr ":" " "`) #arr2=(1 tcp to 8.8.8.8 543) 90 | index=${arr2[0]} 91 | proto=${arr2[1]} 92 | targetIP=${arr2[3]} 93 | targetPort=${arr2[4]} 94 | echo 清除本机$localport端口到$targetIP:$targetPort的${proto}PREROUTING转发规则$index 95 | iptables -t nat -D PREROUTING $index 96 | echo 清除对应的POSTROUTING规则 97 | toRmIndexs=(`iptables -L POSTROUTING -n -t nat --line-number|grep $targetIP|grep $targetPort|grep $proto|awk '{print $1}'|sort -r|tr "\n" " "`) 98 | for cell1 in ${toRmIndexs[@]} 99 | do 100 | iptables -t nat -D POSTROUTING $cell1 101 | done 102 | done 103 | #设置新的中转规则 104 | iptables -t nat -A PREROUTING -p tcp --dport $localport -j DNAT --to-destination $remote:$remoteport 105 | iptables -t nat -A PREROUTING -p udp --dport $localport -j DNAT --to-destination $remote:$remoteport 106 | iptables -t nat -A POSTROUTING -p tcp -d $remote --dport $remoteport -j SNAT --to-source $local 107 | iptables -t nat -A POSTROUTING -p udp -d $remote --dport $remoteport -j SNAT --to-source $local 108 | echo 端口转发成功 109 | echo "###########################################################" 110 | echo -e "当前NAT表如下:(仅供专业人士debug用)" 111 | iptables -L PREROUTING -n -t nat 112 | iptables -L POSTROUTING -n -t nat 113 | echo "###########################################################" 114 | 115 | -------------------------------------------------------------------------------- /iptables4ddns.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # rm -f iptables4ddns.sh;wget https://raw.githubusercontent.com/arloor/iptablesUtils/master/iptables4ddns.sh;bash iptables4ddns.sh $localport $remoteport $remotehost [ $remoteIpTempfile——暂存ddns的目标ip,用于定时任务判断时候需要更新iptables转发 ]; 3 | 4 | 5 | 6 | localport=$1 #中转端口,自行修改 7 | remoteport=$2 #中转端口,自行修改 8 | remotehost=$3 #中转目标host,自行修改 9 | tempFile=$4 10 | if [ "$4" = "" ];then 11 | tempFile=remoteip 12 | fi 13 | 14 | 15 | 16 | red="\033[31m" 17 | black="\033[0m" 18 | 19 | if [ $USER != "root" ];then 20 | echo -e "${red}请使用root用户执行本脚本!! ${black}" 21 | exit 1 22 | fi 23 | 24 | if [ "$remotehost" = "" ];then 25 | echo -e "${red}Usage: bash iptables4ddns.sh localport remoteport remotehost [ remoteIpTempflie ]; ${black}" 26 | exit 1 27 | fi 28 | 29 | 30 | echo "" 31 | echo 时间:$(date) 32 | 33 | # 开启端口转发 34 | sed -n '/^net.ipv4.ip_forward=1/'p /etc/sysctl.conf | grep -q "net.ipv4.ip_forward=1" 35 | if [ $? -ne 0 ]; then 36 | echo -e "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && sysctl -p 37 | fi 38 | 39 | if [ "$(echo $remotehost |grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}')" != "" ];then 40 | isip=true 41 | remote=$remotehost 42 | 43 | echo -e "${red}警告:你输入的目标地址是一个ip!${black}" 44 | echo -e "${red}该脚本的目标是,使用iptables中转到动态ip的vps${black}" 45 | echo -e "${red}所以remotehost参数应该是动态ip的vps的ddns域名${black}" 46 | exit 1 47 | else 48 | remote=$(host -t a $remotehost|grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"|head -1) 49 | if [ "$remote" = "" ];then 50 | echo -e "${red}无法解析remotehost,请填写正确的remotehost!${black}" 51 | exit 1 52 | fi 53 | fi 54 | 55 | #开放FORWARD链 56 | 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 57 | for cell in ${arr1[@]} 58 | do 59 | arr2=(`echo $cell|tr ":" " "`) #arr2=16 REJECT 0.0.0.0/0 60 | index=${arr2[0]} 61 | echo 删除禁止FOWARD的规则——$index 62 | iptables -D FORWARD $index 63 | done 64 | iptables --policy FORWARD ACCEPT 65 | 66 | lastremote=$(cat /root/$tempFile 2> /dev/null) 67 | if [ "$lastremote" = "$remote" ]; then 68 | echo 地址解析未变化,退出 69 | exit 1 70 | fi 71 | 72 | echo last-remote-ip: $lastremote 73 | echo new-remote-ip: $remote 74 | echo $remote > /root/$tempFile 75 | 76 | 77 | ## 获取本机地址 78 | local=$(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}$)') 79 | if [ "${local}" = "" ]; then 80 | local=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 ) 81 | fi 82 | echo local-ip: $local 83 | echo 重新设置iptables转发 84 | 85 | #删除旧的中转规则 86 | arr1=(`iptables -L PREROUTING -n -t nat --line-number |grep DNAT|grep "dpt:$localport "|sort -r|awk '{print $1,$3,$9}'|tr " " ":"|tr "\n" " "`) 87 | for cell in ${arr1[@]} # cell= 1:tcp:to:8.8.8.8:543 88 | do 89 | arr2=(`echo $cell|tr ":" " "`) #arr2=(1 tcp to 8.8.8.8 543) 90 | index=${arr2[0]} 91 | proto=${arr2[1]} 92 | targetIP=${arr2[3]} 93 | targetPort=${arr2[4]} 94 | echo 清除本机$localport端口到$targetIP:$targetPort的${proto}PREROUTING转发规则$index 95 | iptables -t nat -D PREROUTING $index 96 | echo 清除对应的POSTROUTING规则 97 | toRmIndexs=(`iptables -L POSTROUTING -n -t nat --line-number|grep $targetIP|grep $targetPort|grep $proto|awk '{print $1}'|sort -r|tr "\n" " "`) 98 | for cell1 in ${toRmIndexs[@]} 99 | do 100 | iptables -t nat -D POSTROUTING $cell1 101 | done 102 | done 103 | 104 | 105 | ## 建立新的中转规则 106 | iptables -t nat -A PREROUTING -p tcp --dport $localport -j DNAT --to-destination $remote:$remoteport 107 | iptables -t nat -A PREROUTING -p udp --dport $localport -j DNAT --to-destination $remote:$remoteport 108 | iptables -t nat -A POSTROUTING -p tcp -d $remote --dport $remoteport -j SNAT --to-source $local 109 | iptables -t nat -A POSTROUTING -p udp -d $remote --dport $remoteport -j SNAT --to-source $local 110 | 111 | -------------------------------------------------------------------------------- /natcfg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | red="\033[31m" 3 | black="\033[0m" 4 | 5 | base=/etc/dnat 6 | mkdir $base 2>/dev/null 7 | conf=$base/conf 8 | touch $conf 9 | 10 | # wget -qO natcfg.sh https://raw.githubusercontent.com/arloor/iptablesUtils/master/natcfg.sh && bash natcfg.sh 11 | echo -e "${red}用途${black}: 便捷的设置iptables端口转发" 12 | echo -e "${red}注意1${black}: 到域名的转发规则在添加后需要等待2分钟才会生效,且在机器重启后仍然有效" 13 | echo -e "${red}注意2${black}: 到IP的转发规则在重启后会失效,这是iptables的特性" 14 | echo 15 | # github raw dns污染,修改dnat的获取地址 16 | setupService(){ 17 | if [[ ! -f /usr/local/bin/dnat.sh ]];then 18 | wget -qO /usr/local/bin/dnat.sh https://gitlab.com/wulabing/iptablesUtils/raw/master/dnat.sh ||{ 19 | echo "脚本不存在,请通过github提交issue通知作者" 20 | exit 1 21 | } 22 | fi 23 | 24 | cat > /lib/systemd/system/dnat.service <<\EOF 25 | [Unit] 26 | Description=动态设置iptables转发规则 27 | After=network-online.target 28 | Wants=network-online.target 29 | 30 | [Service] 31 | WorkingDirectory=/root/ 32 | EnvironmentFile= 33 | ExecStart=/bin/bash /usr/local/bin/dnat.sh 34 | Restart=always 35 | RestartSec=30 36 | 37 | [Install] 38 | WantedBy=multi-user.target 39 | EOF 40 | 41 | systemctl daemon-reload 42 | systemctl enable dnat > /dev/null 2>&1 43 | service dnat stop > /dev/null 2>&1 44 | service dnat start > /dev/null 2>&1 45 | } 46 | 47 | 48 | ## 获取本机地址 49 | # 修改 ipv4 公网获取 50 | localIP=$(curl -s -4 ip.sb) >/dev/null 2>&1 51 | echo "本机公网IP:${localIP}" 52 | if [ "${localIP}" = "" ]; then 53 | localIP=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1|head -n 1 ) 54 | fi 55 | 56 | rmIptablesNat(){ 57 | #删除旧的中转规则 58 | local arr1=(`iptables -L PREROUTING -n -t nat --line-number |grep DNAT|grep "dpt:$1 "|sort -r|awk '{print $1,$3,$9}'|tr " " ":"|tr "\n" " "`) 59 | for cell in ${arr1[@]} # cell= 1:tcp:to:8.8.8.8:543 60 | do 61 | local arr2=(`echo $cell|tr ":" " "`) #arr2=(1 tcp to 8.8.8.8 543) 62 | local index=${arr2[0]} 63 | local proto=${arr2[1]} 64 | local targetIP=${arr2[3]} 65 | local targetPort=${arr2[4]} 66 | # echo 清除本机$localport端口到$targetIP:$targetPort的${proto}的PREROUTING转发规则[$index] 67 | iptables -t nat -D PREROUTING $index 68 | # echo ==清除对应的POSTROUTING规则 69 | local toRmIndexs=(`iptables -L POSTROUTING -n -t nat --line-number|grep SNAT|grep $targetIP|grep dpt:$targetPort|grep $proto|awk '{print $1}'|sort -r|tr "\n" " "`) 70 | for cell1 in ${toRmIndexs[@]} 71 | do 72 | iptables -t nat -D POSTROUTING $cell1 73 | done 74 | done 75 | } 76 | 77 | addDnat(){ 78 | local localport= 79 | local remoteport= 80 | local remotehost= 81 | local valid= 82 | echo -n "本地端口号:" ;read localport 83 | echo -n "远程端口号:" ;read remoteport 84 | # echo $localport $remoteport 85 | # 判断端口是否为数字 86 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]||{ 87 | echo -e "${red}本地端口和目标端口请输入数字!!${black}" 88 | return 1; 89 | } 90 | 91 | echo -n "目标域名:" ;read remotehost 92 | # 检查输入的不是IP 93 | if [ "$remotehost" = "" -o "$(echo $remotehost |grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}')" != "" ];then 94 | isip=true 95 | remote=$remotehost 96 | echo -e "${red}请输入一个ddns域名${black}" 97 | return 1 98 | fi 99 | 100 | setupService 101 | echo "成功添加转发规则 $localport>$remotehost:$remoteport 大约两分钟后规则会生效" 102 | 103 | sed -i "s/^$localport.*/$localport>$remotehost:$remoteport/g" $conf 104 | [ "$(cat $conf|grep "$localport>$remotehost:$remoteport")" = "" ]&&{ 105 | cat >> $conf <$remotehost:$remoteport 107 | LINE 108 | } 109 | } 110 | 111 | rmDnat(){ 112 | local localport= 113 | echo -n "本地端口号:" ;read localport 114 | sed -i "/^$localport>.*/d" $conf 115 | 116 | rmIptablesNat $localport 117 | #删除临时文件 118 | rm -f $base/${1}IP 119 | } 120 | 121 | testVars(){ 122 | local localport=$1 123 | local remotehost=$2 124 | local remoteport=$3 125 | # 判断端口是否为数字 126 | local valid= 127 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]||{ 128 | # echo -e "${red}本地端口和目标端口请输入数字!!${black}"; 129 | return 1; 130 | } 131 | 132 | # 检查输入的不是IP 133 | if [ "$(echo $remotehost |grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}')" != "" ];then 134 | local isip=true 135 | local remote=$remotehost 136 | 137 | # echo -e "${red}警告:你输入的目标地址是一个ip!${black}" 138 | return 2; 139 | fi 140 | } 141 | 142 | lsDnat(){ 143 | arr1=(`cat $conf`) 144 | for cell in ${arr1[@]} 145 | do 146 | arr2=(`echo $cell|tr ":" " "|tr ">" " "`) #arr2=16 REJECT 0.0.0.0/0 147 | # 过滤非法的行 148 | [ "${arr2[2]}" != "" -a "${arr2[3]}" = "" ]&& testVars ${arr2[0]} ${arr2[1]} ${arr2[2]}&&{ 149 | echo "转发规则: ${arr2[0]}>${arr2[1]}:${arr2[2]}" 150 | } 151 | done 152 | } 153 | 154 | addSnat(){ 155 | local localport= 156 | local remoteport= 157 | local remotehost= 158 | echo -n "本地端口号:" ;read localport 159 | echo -n "远程端口号:" ;read remoteport 160 | # echo $localport $remoteport 161 | # 判断端口是否为数字 162 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]||{ 163 | echo -e "${red}本地端口和目标端口请输入数字!!${black}" 164 | return 1; 165 | } 166 | 167 | echo -n "目标IP:" ;read remotehost 168 | # 检查输入的不是IP 169 | if [ "$remotehost" = "" -o "$(echo $remotehost |grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}')" != "" ];then 170 | rmIptablesNat $localport 171 | 172 | ## 建立新的中转规则 173 | iptables -t nat -A PREROUTING -p tcp --dport $localport -j DNAT --to-destination $remotehost:$remoteport 174 | iptables -t nat -A PREROUTING -p udp --dport $localport -j DNAT --to-destination $remotehost:$remoteport 175 | iptables -t nat -A POSTROUTING -p tcp -d $remotehost --dport $remoteport -j SNAT --to-source $localIP 176 | iptables -t nat -A POSTROUTING -p udp -d $remotehost --dport $remoteport -j SNAT --to-source $localIP 177 | else 178 | echo 请输入一个IP 179 | return 1 180 | fi 181 | } 182 | 183 | rmSnat(){ 184 | local localport= 185 | echo -n "本地端口号:" ;read localport 186 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] &&rmIptablesNat $localport 187 | } 188 | 189 | 190 | 191 | echo -e "${red}你要做什么呢(请输入数字)?Ctrl+C 退出本脚本${black}" 192 | select todo in 增加到域名的转发 删除到域名的转发 增加到IP的转发 删除到IP的转发 列出所有到域名的转发 查看iptables转发规则 193 | do 194 | case $todo in 195 | 增加到域名的转发) 196 | addDnat 197 | break 198 | ;; 199 | 删除到域名的转发) 200 | rmDnat 201 | break 202 | ;; 203 | 增加到IP的转发) 204 | addSnat 205 | break 206 | ;; 207 | 删除到IP的转发) 208 | rmSnat 209 | break 210 | ;; 211 | 列出所有到域名的转发) 212 | lsDnat 213 | ;; 214 | 查看iptables转发规则) 215 | echo "###########################################################" 216 | iptables -L PREROUTING -n -t nat --line-number 217 | iptables -L POSTROUTING -n -t nat --line-number 218 | echo "###########################################################" 219 | ;; 220 | *) 221 | echo "如果要退出,请按Ctrl+C" 222 | ;; 223 | esac 224 | done 225 | -------------------------------------------------------------------------------- /rmPreNatRule.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # 删除本机上指定端口的转发规则,会删除对应的PREROUTING和POSTROUTING规则 4 | # bash rmPreNatRule.sh $localPort 5 | 6 | red="\033[31m" 7 | black="\033[0m" 8 | 9 | #要删除的转发端口 10 | localport=$1 11 | if [ "$localport" = "" ];then 12 | echo -n "要删除转发的本地端口:" ;read localport 13 | fi 14 | 15 | if [ $USER = "root" ];then 16 | echo "本脚本用途:" 17 | echo "删除本机上指定端口的转发规则,会删除对应的PREROUTING和POSTROUTING规则" 18 | echo 19 | else 20 | echo -e "${red}请使用root用户执行本脚本!! ${black}" 21 | exit 1 22 | fi 23 | 24 | 25 | 26 | arr1=(`iptables -L PREROUTING -n -t nat --line-number |grep DNAT|grep "dpt:$localport "|sort -r|awk '{print $1,$3,$9}'|tr " " ":"|tr "\n" " "`) 27 | for cell in ${arr1[@]} # cell= 1:tcp:to:8.8.8.8:543 28 | do 29 | arr2=(`echo $cell|tr ":" " "`) #arr2=(1 tcp to 8.8.8.8 543) 30 | index=${arr2[0]} 31 | proto=${arr2[1]} 32 | targetIP=${arr2[3]} 33 | targetPort=${arr2[4]} 34 | echo 清除本机$localport端口到$targetIP:$targetPort的${proto}PREROUTING转发规则$index 35 | iptables -t nat -D PREROUTING $index 36 | echo 清除对应的POSTROUTING规则 37 | toRmIndexs=(`iptables -L POSTROUTING -n -t nat --line-number|grep $targetIP|grep $targetPort|grep $proto|awk '{print $1}'|sort -r|tr "\n" " "`) 38 | for cell1 in ${toRmIndexs[@]} 39 | do 40 | iptables -t nat -D POSTROUTING $cell1 41 | done 42 | done -------------------------------------------------------------------------------- /setCroniptablesDDNS-debian.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # wget https://raw.githubusercontent.com/arloor/iptablesUtils/master/setCroniptablesDDNS.sh;bash setCroniptablesDDNS.sh 4 | 5 | red="\033[31m" 6 | black="\033[0m" 7 | 8 | if [ $USER = "root" ];then 9 | echo "本脚本用途:" 10 | echo "适用于 Debian / Ubuntu;设置 iptables 定时任务,以转发流量到 DDNS 的 VPS 上" 11 | echo 12 | else 13 | echo -e "${red}请使用 root 用户执行本脚本!! ${black}" 14 | exit 1 15 | fi 16 | 17 | cd 18 | 19 | echo "正在安装依赖...." 20 | apt install -y wget dnsutils &> /dev/null 21 | cd /usr/local 22 | rm -f /usr/local/iptables4ddns.sh 23 | wget https://raw.githubusercontent.com/arloor/iptablesUtils/master/iptables4ddns.sh &> /dev/null 24 | chmod +x /usr/local/iptables4ddns.sh 25 | echo "Done!" 26 | echo "" 27 | 28 | 29 | echo -n "本地端口号:" ;read localport 30 | echo -n "远程端口号:" ;read remoteport 31 | echo -n "目标DDNS:" ;read targetDDNS 32 | 33 | # 判断端口是否为数字 34 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]&& valid=true 35 | 36 | if [ "$valid" = "" ];then 37 | echo -e "${red}本地端口和目标端口请输入数字!!${black}" 38 | exit 1; 39 | fi 40 | 41 | IPrecordfile=${localport}[${targetDDNS}:${remoteport}] 42 | # 开机强制刷新一次 43 | chmod +x /etc/rc.local 44 | echo "rm -f /root/$IPrecordfile" >> /etc/rc.local 45 | # 替换下面的localport remoteport targetDDNS 46 | echo "/bin/bash /usr/local/iptables4ddns.sh $localport $remoteport $targetDDNS $IPrecordfile &>> /root/iptables${localport}.log" >> /etc/rc.local 47 | chmod +x /etc/rc.local 48 | # 定时任务,每分钟检查一下 49 | echo "* * * * * root /usr/local/iptables4ddns.sh $localport $remoteport $targetDDNS $IPrecordfile &>> /root/iptables${localport}.log" >> /etc/crontab 50 | cd 51 | rm -f /root/$IPrecordfile 52 | bash /usr/local/iptables4ddns.sh $localport $remoteport $targetDDNS $IPrecordfile &>> /root/iptables${localport}.log 53 | echo "done!" 54 | echo "现在每分钟都会检查ddns的ip是否改变,并自动更新" 55 | -------------------------------------------------------------------------------- /setCroniptablesDDNS.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # wget https://raw.githubusercontent.com/arloor/iptablesUtils/master/setCroniptablesDDNS.sh;bash setCroniptablesDDNS.sh 4 | 5 | red="\033[31m" 6 | black="\033[0m" 7 | 8 | if [ $USER = "root" ];then 9 | echo "本脚本用途:" 10 | echo "适用于centos7;设置iptables定时任务,以转发流量到ddns的vps上" 11 | echo 12 | else 13 | echo -e "${red}请使用root用户执行本脚本!! ${black}" 14 | exit 1 15 | fi 16 | 17 | cd 18 | 19 | echo "正在安装依赖...." 20 | yum install -y wget bind-utils &> /dev/null 21 | cd /usr/local 22 | rm -f /usr/local/iptables4ddns.sh 23 | wget https://raw.githubusercontent.com/arloor/iptablesUtils/master/iptables4ddns.sh &> /dev/null 24 | chmod +x /usr/local/iptables4ddns.sh 25 | echo "Done!" 26 | echo "" 27 | 28 | 29 | echo -n "本地端口号:" ;read localport 30 | echo -n "远程端口号:" ;read remoteport 31 | echo -n "目标DDNS:" ;read targetDDNS 32 | 33 | # 判断端口是否为数字 34 | echo "$localport"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] && echo $remoteport |[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ]&& valid=true 35 | 36 | if [ "$valid" = "" ];then 37 | echo -e "${red}本地端口和目标端口请输入数字!!${black}" 38 | exit 1; 39 | fi 40 | 41 | IPrecordfile=${localport}[${targetDDNS}:${remoteport}] 42 | # 开机强制刷新一次 43 | chmod +x /etc/rc.d/rc.local 44 | echo "rm -f /root/$IPrecordfile" >> /etc/rc.d/rc.local 45 | # 替换下面的localport remoteport targetDDNS 46 | echo "/bin/bash /usr/local/iptables4ddns.sh $localport $remoteport $targetDDNS $IPrecordfile &>> /root/iptables${localport}.log" >> /etc/rc.d/rc.local 47 | chmod +x /etc/rc.d/rc.local 48 | # 定时任务,每分钟检查一下 49 | echo "* * * * * root /usr/local/iptables4ddns.sh $localport $remoteport $targetDDNS $IPrecordfile &>> /root/iptables${localport}.log" >> /etc/crontab 50 | cd 51 | rm -f /root/$IPrecordfile 52 | bash /usr/local/iptables4ddns.sh $localport $remoteport $targetDDNS $IPrecordfile &>> /root/iptables${localport}.log 53 | echo "done!" 54 | echo "现在每分钟都会检查ddns的ip是否改变,并自动更新" 55 | --------------------------------------------------------------------------------