使用ping获取指定URL的IP地址,使用iptables进行NAT转发,使用Cron进行定时检查IP是否发生改变,理论上其他系统也同样支持本文方式。
转载请注明出处,本文仅用于学习交流,不对之处,恳请指正 ,部分图片摘取网络,如有侵权请联系
1. 系统环境
- Debian 11
- iptables v1.8.7 (nf_tables)
2. 环境配置
本文使用的是iptables进行端口转发,你也可以使用ufw等工具,我在其他文章中也有大概提及使用UFW防火墙进行端口转发方式
-
Debian系统安装iptables iputils
sudo apt-get update && apt-get install iptables iputils-ping
-
CentOS7, OpenEuler安装iptables iputils
sudo yum install iptables iputils
-
CentOS8, OpenEuler安装iptables iputils
sudo dnf install iptables iputils
3. 脚本代码
请根据实际情况对一些代码进行调整
- local_port # 你要访问的本机端口号
- remote_url # 你要NAT的目标URL地址
- remote_port # 你要NAT的目标端口
至于为什么用英文注释,特殊处理罢了
-
编写脚本
nano /etc/cron.d/iptablesnat.sh
-
写入以下代码
#!/bin/bash current_time(){ echo `date -d "@$(( $(date +%s) ))" +%Y/%m/%d' '%H:%M:%S` } get_internal_ip() { # Check for 10.x.x.x IP address ip_addr=$(ip addr show | grep -oP "(?<=inet\s)10(\.\d+){3}") if [[ -n $ip_addr ]]; then echo "$ip_addr" return fi # Check for 172.x.x.x IP address if 10.x.x.x IP address is not found ip_addr=$(ip addr show | grep -oP "(?<=inet\s)172\.(1[6-9]|2[0-9]|3[0-1])(\.\d+){2}") if [[ -n $ip_addr ]]; then echo "$ip_addr" return fi # Check for 192.168.x.x IP address if 10.x.x.x and 172.x.x.x IP addresses are not found ip_addr=$(ip addr show | grep -oP "(?<=inet\s)192\.168(\.\d+){2}") if [[ -n $ip_addr ]]; then echo "$ip_addr" return fi } internal_ip=$(get_internal_ip) if [[ -n $internal_ip ]]; then echo "Internal IP Address: $internal_ip" else echo "No internal IP address found." exit 1 fi # Port number to use, it is recommended to use special ports like 443 or 3389 to avoid suspicion local_port=change_to_your_port # The remote URL address to forward to remote_url=change_to_your_url # The remote port to forward to, usually 443 remote_port=change_to_your_prot # Path to save the log file log_file="/var/log/iptablesnat.log" # Path to save the IP address obtained from the URL old_ip_file="/var/log/iptablesnat.oldip" echo "===================IPTABLES===================" >> $log_file if [ ! -f "$old_ip_file" ];then touch $old_ip_file echo "$(current_time) [I] Created IP file" >> $log_file fi realIP=$(ping $remote_url -c 1 -w 1 | sed '1{s/[^(]*(//;s/).*//;q}') echo "$(current_time) [I] Current IP: $realIP" >> $log_file oldIP=`cat $old_ip_file` echo "$(current_time) [I] Old IP: $oldIP" >> $log_file if [[ "$realIP" == "$oldIP" ]];then echo "$(current_time) [I] Current IP same as old IP, skipping..." >> $log_file else if [ -n "$oldIP" ]; then remote=$oldIP echo "$(current_time) [W] Delete the old iptables rules..." >> $log_file iptables -t nat -D PREROUTING -p tcp --dport $local_port -j DNAT --to-destination $remote:$remote_port iptables -t nat -D PREROUTING -p udp --dport $local_port -j DNAT --to-destination $remote:$remote_port iptables -t nat -D POSTROUTING -p tcp -d $remote --dport $remote_port -j SNAT --to-source $internal_ip iptables -t nat -D POSTROUTING -p udp -d $remote --dport $remote_port -j SNAT --to-source $internal_ip fi remote=$realIP echo "$(current_time) [W] Create the new iptables rules..." >> $log_file iptables -t nat -A PREROUTING -p tcp --dport $local_port -j DNAT --to-destination $remote:$remote_port iptables -t nat -A PREROUTING -p udp --dport $local_port -j DNAT --to-destination $remote:$remote_port iptables -t nat -A POSTROUTING -p tcp -d $remote --dport $remote_port -j SNAT --to-source $internal_ip iptables -t nat -A POSTROUTING -p udp -d $remote --dport $remote_port -j SNAT --to-source $internal_ip echo "=======================================" >> $log_file echo "$(iptables -t nat -L -n --line-numbers)" >> $log_file echo "=======================================" >> $log_file echo "$(current_time) [W] Save current IP to the log file" >> $log_file echo $remote > $old_ip_file echo "$(current_time) [I] Completed!" >> $log_file fi
4. 创建定时脚本
-
使用nano打开定时文件
nano /etc/crontab
-
最后加入以下代码
# Automatically obtain the IP that requires NAT from the URL @reboot root /etc/cron.d/iptablesnat.sh */15 * * * * root /etc/cron.d/iptablesnat.sh
5. 修改本地host或者路由器的DHCP
如果转发到的目标Url不是你自己的,且你又希望开启TLS加密,那么你可以修改本地的host,或者在你的路由器的DHCP拦截对应的URL到你的服务器IP,或者如果你有类似Adguard Home或者SmartDNS之类的服务,那么你也可以在其中进行拦截
文章评论