利用iptables實現埠對映(支援動態域名)

项希盛發表於2024-10-19

將下列程式碼儲存到/bin/ddns_portmap.sh

#!/bin/bash

# 檢查引數
if [ "$#" -ne 2 ]; then
    echo "Usage: $0 <domain> <local_port1:remote_port1,local_port2:remote_port2,...>"
    exit 1
fi

# 從引數獲取動態域名和埠對映
domain=$1
port_mappings=$2

# 獲取當前解析的IP地址
new_ip=$(getent ahosts $domain | awk '{print $1}' | head -n 1)

# 如果無法解析域名,退出
if [ -z "$new_ip" ]; then
    echo "Failed to resolve domain: $domain"
    exit 1
fi

# 迴圈處理每個埠對映
IFS=',' read -ra mappings <<< "$port_mappings"
for mapping in "${mappings[@]}"; do
    local_port=$(echo $mapping | cut -d ':' -f 1)
    remote_port=$(echo $mapping | cut -d ':' -f 2)

    # 獲取當前iptables中配置的目標IP和埠
    current_mapping=$(iptables -t nat -L PREROUTING -n --line-numbers | grep "dpt:$local_port" | awk '{print $9}')

    # 提取當前的目標IP和目標埠
    current_ip=$(echo $current_mapping | cut -d ':' -f 2)
    current_port=$(echo $current_mapping | cut -d ':' -f 3)

    # 如果新IP或遠端埠和現有的不一致,則更新iptables規則
    if [ "$new_ip" != "$current_ip" ] || [ "$remote_port" != "$current_port" ]; then
        # 刪除舊規則
        if [ -n "$current_ip" ]; then
            iptables -t nat -D PREROUTING -p tcp --dport $local_port -j DNAT --to-destination $current_ip:$current_port
            iptables -t nat -D POSTROUTING -p tcp -d $current_ip --dport $current_port -j MASQUERADE
        fi

        # 新增新規則
        iptables -t nat -A PREROUTING -p tcp --dport $local_port -j DNAT --to-destination $new_ip:$remote_port
        iptables -t nat -A POSTROUTING -p tcp -d $new_ip --dport $remote_port -j MASQUERADE

        echo "Updated iptables rules for $domain: $local_port -> $new_ip:$remote_port"
    else
        echo "No change in IP address or remote port for $domain on port $local_port."
    fi
done

crontab -e
貼入下列程式碼即可完成埠對映

* * * * * /bin/ddns_portmap.sh 39.172.91.235 201:201
* * * * * /bin/ddns_portmap.sh dx11.fm20.cn 1110:1110,1112:1112,1161:1161

相關文章