From 51c323008a0f70422bea7e884ad981188ba786a7 Mon Sep 17 00:00:00 2001 From: asxalex Date: Fri, 27 Dec 2024 00:25:13 +0800 Subject: [PATCH] nat-simulator.sh is still on work, now, it simulates the fullcone(nat1), ip restricted cone(nat2) --- nat-simulator.sh | 216 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 nat-simulator.sh diff --git a/nat-simulator.sh b/nat-simulator.sh new file mode 100644 index 0000000..11bc905 --- /dev/null +++ b/nat-simulator.sh @@ -0,0 +1,216 @@ +#!/bin/bash + +## check for root + +NAT_TYPE= +UDP_PORT= +IP= +DELETE=0 + +OUTER_INTERFACE=eth0 + +OUTER_IP=`ifconfig ${OUTER_INTERFACE} | grep -e "\binet\b" | awk '{print $2}'` + +options=$(getopt -o t:p:i: --long type:,port:,ip:,delete -- "$@") +eval set -- "$options" + +while true; do + case "$1" in + -t|--type) + NAT_TYPE=$2 + shift 2 + ;; + -p|--port) + PORT=$2 + shift 2 + ;; + -i|--ip) + IP=$2 + shift 2 + ;; + --delete) + DELETE=1 + shift + ;; + --) + shift + break + ;; + *) + echo "invalid option: $1" + exit -1; + ;; + esac +done + +port=$PORT +ip=$IP + +is_number() { + re="^[1-9][0-9]*$" + if [[ $1 =~ $re ]]; then + return 0; + fi + return 1; +} + +is_valid_ip() { + re="^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" + if [[ $1 =~ $re ]]; then + return 0 + fi + return 1 +} + +if ! is_number $port; then + echo "invalid port: $port" + exit -1; +fi + +if ! is_valid_ip $ip; then + echo "invalid ip: $ip" + exit -1; +fi + +PUNCHNET_TCP_PORT=18083 +## iptables' tcp POSTROUTING chain name +POST_TCP=PUNCHNET-TCP +PRE_UDP=PUNCHNET-PRE-UDP + +IPSET_GROUP=allowed_ip_${ip} +add_ipset_group() { + ipset destroy ${IPSET_GROUP} + ipset create ${IPSET_GROUP} hash:ip hashsize 4096 +} + +add_ipset_group + +ensure_rule() { + table_name=$1 + chain_name=$2 + arguments=$3 + + ## create table + # iptables -t ${table_name} -N ${chain_name} > /dev/null 2>&1 + + ## add the rule + if ! iptables -t ${table_name} -C ${chain_name} ${arguments} > /dev/null 2>&1; then + echo "executing: iptables -t ${table_name} -A ${chain_name} ${arguments} > /dev/null 2>&1" + iptables -t ${table_name} -A ${chain_name} ${arguments} > /dev/null 2>&1 + fi +} + +clear_rule() { + table_name=$1 + chain_name=$2 + arguments=$3 + + iptables -t ${table_name} -D ${chain_name} ${arguments} > /dev/null 2>&1 +} + +drop_user_chian() { + table_name=$1 + chain_name=$2 + + iptables -t ${table_name} -F ${chain_name} + iptables -t ${table_name} -X ${chain_name} +} + + +ensure_tcp_connection() { + # create table anyhow + iptables -t nat -N ${POST_TCP} > /dev/null 2>&1 + + ensure_rule "nat" "${POST_TCP}" "-p tcp --dport ${PUNCHNET_TCP_PORT} -j MASQUERADE" + ensure_rule "nat" "${POST_TCP}" "-j RETURN" + ensure_rule "nat" "POSTROUTING" "-p tcp -s ${ip} -j ${POST_TCP}" +} + +fullcone() { + ensure_tcp_connection + + # POSTROUTING for udp ports + ensure_rule "nat" "POSTROUTING" "-o ${OUTER_INTERFACE} -p udp --sport ${port} -j SNAT --to-source ${OUTER_IP}:${port}" + + # prerouting for udp to the very host + ensure_rule "nat" "PREROUTING" "-p udp -i ${OUTER_INTERFACE} --dport ${port} -j DNAT --to-destination ${ip}:${port}" +} + +fullcone_clear() { + clear_rule "nat" "POSTROUTING" "-o ${OUTER_INTERFACE} -p udp --sport ${port} -j MASQUERADE" + clear_rule "nat" "PREROUTING" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -j DNAT --to-destination ${ip}" +} + +restricted_cone() { + fullcone + # ensure_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state ESTABLISHED,RELATED -j LOG --log-prefix \\\"accept INPUT: \\\"" + ensure_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state ESTABLISHED,RELATED -j SET --add-set ${IPSET_GROUP} src" + ensure_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state ESTABLISHED,RELATED -j ACCEPT" + # ensure_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state ESTABLISHED,RELATED -j ACCEPT" + # ensure_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state NEW -j LOG --log-prefix \"drop INPUT\"" + # ensure_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state NEW -m set ! --match-set allowed_ip src -j LOG" + ensure_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state NEW -m set ! --match-set ${IPSET_GROUP} src -j DROP" + ensure_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state NEW -m set --match-set ${IPSET_GROUP} src -j ACCEPT" +} + +restricted_cone_clear() { + fullcone_clear + clear_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state ESTABLISHED,RELATED -j ACCEPT" + clear_rule "filter" "FORWARD" "-i ${OUTER_INTERFACE} -p udp --dport ${port} -m state --state NEW -j DROP" +} + +port_restricted_cone() { + ensure_tcp_connection + ensure_rule "nat" "POSTROUTING" "-o ${OUTER_INTERFACE} -p udp --sport ${port} -j MASQUERADE" +} + +port_restricted_cone_clear() { + clear_rule "nat" "POSTROUTING" "-o ${OUTER_INTERFACE} -p udp --sport ${port} -j MASQUERADE" +} + +symmetric() { + ensure_rule "nat" "POSTROUTING" "-o ${OUTER_INTERFACE} -p udp --sport ${port} -j MASQUERADE --random" +} + +symmetric_clear() { + clear_rule "nat" "POSTROUTING" "-o ${OUTER_INTERFACE} -p udp --sport ${port} -j MASQUERADE --random" +} + +case $NAT_TYPE in + "nat1") + fullcone + echo "full cone" + ;; + "nat2") + restricted_cone + echo "restricted cone" + ;; + "nat3") + port_restricted_cone + echo "port restricted cone" + ;; + "nat4") + symmetric + echo "symmetric nat" + ;; + *) + echo "invalid nat type" + ;; +esac + +# iptables -t nat -C POSTROUTING -p tcp -j ${POST_TCP} > /dev/null 2>&1 +# +# +# iptables -t nat -F ${POST_TCP} > /dev/null 2&>1 +# iptables -t nat -N ${POST_TCP} +# iptables -t nat -A POSTROUTING -p tcp -j ${POST_TCP} +# iptables -t nat -A ${POST_TCP} -p tcp --dport ${PUNCHNET_TCP_PORT} +# iptables -t nat -A ${POST_TCP} -j RETURN +# +# iptables -t nat -D POSTROUTING -p udp -j ${POST_UDP} > /dev/null 2&>1 +# iptables -t nat -F ${POST_UDP} > /dev/null 2&>1 +# iptables -t nat -N ${POST_UDP} +# +# iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 18083 -j MASQUERADE +# iptables -t nat -A POSTROUTING -o eth0 -p udp --sport 7890 -j MASQUERADE +# iptables -t nat -A PREROUTING -i eth0 -p udp --dport 7890 -j DNAT --to-destination 172.17.0.2