Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[shares] notification scripts #12

Open
heiher opened this issue Dec 26, 2022 · 13 comments
Open

[shares] notification scripts #12

heiher opened this issue Dec 26, 2022 · 13 comments
Labels
documentation Improvements or additions to documentation

Comments

@heiher
Copy link
Owner

heiher commented Dec 26, 2022

Welcome to share the notification scripts.
欢迎分享通知脚本。

@heiher heiher added the documentation Improvements or additions to documentation label Dec 26, 2022
@heiher
Copy link
Owner Author

heiher commented Dec 26, 2022

Cloudflare DDNS IP4P(IPv4 and port encoding in AAAA record):

#!/bin/sh

ZONE=''
RECORD=''
EMAIL=''
AUTH=''
DOMAIN=''

IP4P=${3}

while true; do
    curl -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE}/dns_records/${RECORD}" \
        -H "X-Auth-Email: ${EMAIL}" \
        -H "Authorization: Bearer ${AUTH}" \
        -H "Content-Type:application/json" \
        --data "{\"type\":\"AAAA\",\"name\":\"${DOMAIN}\",\"content\":\"${IP4P}\",\"ttl\":60,\"proxied\":false}" > /dev/null 2> /dev/null
    if [ $? -eq 0 ]; then
        break
    fi
done

Applications supports IP4P:

@heiher
Copy link
Owner Author

heiher commented Dec 26, 2022

Natter/NATMap 打洞后自动更新 qBittorrent/Transmission 监听端口和 OpenWrt 防火墙规则并推送到 Telegram:

https://gist.github.com/veltlion/b59d73654f0ae36725f5a571602729cb

据说让BT/PT客户端的侦听端口与打洞后的公网端口保持一致可以有效提高peer间的连通性,从而提升上传速度。
See also: https://www.v2ex.com/t/902093#reply29

@ysc3839
Copy link
Collaborator

ysc3839 commented Dec 27, 2022

ns1.com scripts for update A (IPv4 address) and SRV (port) record. Requires OpenWrt's jshn (/usr/share/libubox/jshn.sh), used to format JSON string.
https://gist.github.com/ysc3839/2c629d69f5fc3541a3f1900a23681f0c

Docs about SRV record:
https://www.cloudflare.com/learning/dns/dns-records/dns-srv-record/
https://en.wikipedia.org/wiki/SRV_record

@heiher heiher pinned this issue Dec 28, 2022
@OpportunityLiu
Copy link

OpportunityLiu commented Jun 27, 2023

据说让BT/PT客户端的侦听端口与打洞后的公网端口保持一致可以有效提高peer间的连通性,从而提升上传速度。
See also: https://www.v2ex.com/t/902093#reply29

image

qBittorrent 的实现应该没啥问题,是不是受 IPV4、V6 监听端口不一致的影响

好像是 tracker 实现的问题,有些 tracker 只能绑定一个端口
arvidn/libtorrent#5746 (comment)

@OpenGG
Copy link

OpenGG commented Sep 8, 2023

dynv6 DDNS IP4P(IPv4 and port encoding in AAAA record):

#!/bin/sh

ZONE=''
TOKEN=''

IP4P=${3}

while true; do
    curl \
      "https://dynv6.com/api/update?hostname=${ZONE}&token=${TOKEN}&ipv6=${IP4P}&ipv6prefix=${IP4P}" \
      > /dev/null 2> /dev/null
    if [ $? -eq 0 ]; then
        break
    fi
done

@Wikeolf
Copy link

Wikeolf commented Oct 2, 2023

Fix someting wrong with my openwrt router from https://github.com/heiher/natmap/wiki/web /usr/bin/wdns

What's more, when you are using HTTP protocol, please create a Configuration Rules (zone-->Rules --> Configuration Rules) to switch SSL option to off for specific subdomain, or turn to use HTTPS

#!/bin/sh

ZONE='ZONE_ID'
RECORD='DNS_RECORD_ID'
RULE='ORIGIN_RULE_ID'
EMAIL='Cloudflare_EMAIL'
AUTH='Global_API_Key' 
#or you can use API Tokens but change "X-Auth-Key: ${AUTH}" to "Authorization: Bearer ${AUTH}"
DOMAIN='DEST_DOMAIN'

ADDR=${1}
PORT=${2}

# DNS
while true; do
    curl -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE}/dns_records/${RECORD}" \
        -H "X-Auth-Email: ${EMAIL}" \
        -H "X-Auth-Key: ${AUTH}" \
        -H "Content-Type:application/json" \
        --data "{\"type\":\"A\",\"name\":\"${DOMAIN}\",\"content\":\"${ADDR}\",\"ttl\":60,\"proxied\":true}" >> /tmp/wdns.log 2>&1
    if [ $? -eq 0 ]; then
        break
    fi
done

# Origin rule
while true; do
    curl -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE}/rulesets/${RULE}" \
        -H "X-Auth-Email: ${EMAIL}" \
        -H "X-Auth-Key: ${AUTH}" \
        -H "Content-Type:application/json" \
        --data "{\"rules\":[{\"expression\":\"(http.host eq \\\"${DOMAIN}\\\")\",\"description\":\"natmap\",\"action\":\"route\",\"action_parameters\":{\"origin\":{\"port\":${PORT}}}}]}" >> /tmp/wdns.log 2>&1
    if [ $? -eq 0 ]; then
        break
    fi
done

@cwbsw
Copy link

cwbsw commented Apr 26, 2024

自动配置OpenWrt防火墙,将IPv4流量DNAT到内网地址(端口与公网映射端口一致),并且允许同一端口的IPv6流量。

#!/bin/sh

dest_ip="192.168.1.123"
dest_ip6="::1111:2222:3333:4444/::ffff:ffff:ffff:ffff"

. /usr/share/libubox/jshn.sh

json_init
json_add_string name natmap
json_add_object data
json_add_array firewall

for file in /var/run/natmap/*.json; do
	public_port=$(jsonfilter -i $file -e '@.port')
	bind_port=$(jsonfilter -i $file -e '@.inner_port')

	json_add_object
	json_add_string type redirect
	json_add_string target DNAT
	json_add_string proto tcp
	json_add_string src wan
	json_add_string dest lan
	json_add_string src_dport $bind_port
	json_add_string dest_ip $dest_ip
	json_add_string dest_port $public_port
	json_add_boolean reflection false
	json_close_object

	json_add_object
	json_add_string type rule
	json_add_string target ACCEPT
	json_add_string proto tcp
	json_add_string src wan
	json_add_string dest lan
	json_add_string dest_ip $dest_ip6
	json_add_string dest_port $public_port
	json_close_object
done

json_close_array
json_close_object

ubus call service set "$(json_dump)"

#Now fw4 can't reload correctly, so reload-sets first
/sbin/fw4 reload-sets && /sbin/fw4 reload

@ysc3839
Copy link
Collaborator

ysc3839 commented Apr 26, 2024

@cwbsw 看上去使用这种方案可以让防火墙配置跟随 natmap 服务?重启系统是不是可以自动清除?有相关文档吗?

@cwbsw
Copy link

cwbsw commented Apr 27, 2024

@ysc3839 这个不会写入配置文件,停掉natmap,重新加载防火墙就没了。在natmap的启动脚本加上停止时重新加载防火墙的命令可自动化。
https://openwrt.org/docs/guide-developer/ubus/service
https://github.com/openwrt/firewall4/blob/698a53354fd280aae097efe08803c0c9a10c14c2/root/usr/share/ucode/fw4.uc#L573

@ysc3839
Copy link
Collaborator

ysc3839 commented Apr 28, 2024

@cwbsw 去确认了一下代码,使用 service.set 时是会覆盖掉已有的 triggersvalidate,似乎必须先获取所有数据,更新,再设置。
https://github.com/openwrt/procd/blob/946552a7b598a0b88db6101e864679554ec4f221/service/service.c#L123-L141
既然要先获取原有设置,我觉得不如把 firewall 数据放到 instance 下的 data,甚至 natmap 返回的端口信息都可以放在 data 中,这样的话 luci 就可以直接获取到对应数据,不需要额外读取文件。
不过这里的 data 字段设计似乎是在服务启动时设置的,运行时修改可能违反了原有设计用途,有空我先提一个 PR 询问一下吧。
CC @heiher

@ysc3839
Copy link
Collaborator

ysc3839 commented Apr 28, 2024

@dmserver
Copy link

多层路由 UPNP 映射端口, 当运行natmap设备 及上级路由全dhcp随机IP 时 这个很实用。
支持 爱快 京东 磊科 腾达 OpenWrt 路由混插,无论怎么串接都可以。
不支持 h3c 360 等 因为这些路由采用的随机UUID ipc,而upnp还无法跨路由发现,所以不支持。
理论支持 TP-Link ,因为想支持TP-Link,就得提前运行脚本去打开 混插在里面的TP-Link路由的UPNP端口,
否则一旦natmap运行起来,TP-Link将无法进行端口映射 upnp dmz,这属于TP-Link的设计缺陷,测试了手中全部TP-Link都这样
如果natmap 可以增加个先行脚本参数 例如-e 带的脚本 去执行准备任务,那么脚本可以支持TP-Link

#65
下面是脚本

`#!/bin/bash
###################################################################脚本测试模式数据
#捆绑物理网卡
eth="eth0"
#路由层数 有几层路由就填几,当前主机上面只有一台路由就填1,可以使用ssh命令traceroute -n -m 10 223.5.5.5检查经过几个家用路由器(运营商的不算,具体看情况)
wan_upnp=4
#打开外网端口 这个是natmap -b的端口
wan_upnp_port=9090
#打开内网端口 这个是natmap -b的端口
lan_upnp_port=2022
#路由upnp xml 文件名 各家路由可能不一样 尽量搜集就是了
upnp_xml="igd.xml rootDesc.xml UPnP/IGD.xml"
#upnp 备注名
upnp_port_name="STUN-TEXT"
#旁路由跃迁 旁路由跃迁模式(yes/no),开启后,若发现路由网关信息内出现旁路由,将直接由主路映射至下级设备,流量不经转旁路,正常情况不会出现旁路信息
side_route="no"
#测试协议
protocol="tcp"
########################################################################################################下方固定函数及内容
times=$(date +"%F %T")
upnp_text_info=$times" upnp测试"
if ! type upnpc > /dev/null 2>&1; then
echo 'upnpc 未安装,开始安装';
apt-get install -y miniupnpc
else
cd /
fi

if ! type traceroute > /dev/null 2>&1; then
echo 'traceroute 未安装,开始安装';
apt-get install -y traceroute
else
cd /
fi

if ! type fping > /dev/null 2>&1; then
echo 'fping 未安装,开始安装';
apt-get install -y fping
else
cd /
fi

lan_ip=$(ip address show $eth | head -n4 | grep inet | awk '{print$2}' | cut -d/ -f1-1)
break_id=0
for ((;;))
do
if [ -n "$eth" ]; then
wan_gw_info=$(traceroute -n -m $wan_upnp -i $eth 223.5.5.5 | awk '{print$2}' | grep ".")
else
wan_gw_info=$(traceroute -n -m $wan_upnp 223.5.5.5 | awk '{print$2}' | grep ".")
fi
if [ -n "$wan_gw_info" ] || [ $break_id -eq 5 ]; then
break
fi
((break_id++));
done
if [ ! -n "$wan_gw_info" ];then
exit 0
fi
#######################################################################操作函数
get_gw_upnp (){
gw_ip=$1
gx_xml=$2
break_id=1
upnp_xmls=(${gx_xml// / })
for ((upp=1;upp<3;upp++))
do
upnp_port=$(nmap -F -max_rtt_timeout 1 -sT $gw_ip | grep open)
if [ -n "$upnp_port" ] ; then
break
fi
done
upnp_port_info=$(echo $upnp_port | awk '{split($0, a, "open upnp"); print a[1]}' | rev | cut -d' ' -f2 | rev | cut -d/ -f1-1)
if [[ -z $upnp_port_info ]] || [[ "$upnp_port_info" = "p" ]] || [[ "$upnp_port_info" = *"p" ]]; then
upnp_port_info="80 1900 5000"
fi
for upnp_xmlname in ${upnp_xmls[@]}; do
for upnp_porti in ${upnp_port_info[@]}; do
upnpxml_cs="http://"$gw_ip":"$upnp_porti"/"$upnp_xmlname
upnp_xml_info=$(curl -L -k --connect-timeout 1 -m 1 -s "$upnpxml_cs")
if [[ "$upnp_xml_info" = "xml" ]];then
upnpxml_url=$upnpxml_cs
break
fi
done
if [ ! -z $upnpxml_url ];then
echo $upnpxml_url
return 1
fi
done
break_id=1
for ((;;))
do
upnpxml_cs=$(upnpc -i -P | grep "$gw_ip" | grep "desc" | cut -d: -f2-4)
if [ -n "$upnpxml_cs" ]; then
echo $upnpxml_cs
return 1
fi
upnpxml_cs=$(upnpc -P | grep "$gw_ip" | grep "desc" | cut -d: -f2-4)
if [ -n "$upnpxml_cs" ]; then
echo $upnpxml_cs
return 1
fi
if [ $break_id -eq 5 ];then
echo $upnpxml_cs
return 1
fi
((break_id++));
done
}
get_upnp_exip (){
upnpxml=$1
break_id=0
upnp_eth=$2
if [ -n "$upnp_eth" ]; then
upnpeth=" -m "$upnp_eth
else
upnpeth=" "
fi
for ((;;))
do
upnpexip=$(upnpc $upnpeth -u $upnpxml -S | grep ExternalIPAddress | awk '{print $3}')
if [ -n "$upnpexip" ];then
echo $upnpexip
return 1
fi
upnpexip=$(upnpc $upnpeth -i -u $upnpxml -S | grep ExternalIPAddress | awk '{print $3}')
if [ -n "$upnpexip" ];then
echo $upnpexip
return 1
fi
upnpexip=$(upnpc $upnpeth -u $upnpxml -s | grep ExternalIPAddress | awk '{print $3}')
if [ -n "$upnpexip" ];then
echo $upnpexip
return 1
fi
upnpexip=$(upnpc $upnpeth -i -u $upnpxml -s | grep ExternalIPAddress | awk '{print $3}')
if [ -n "$upnpexip" ];then
echo $upnpexip
return 1
fi
if [ $break_id -eq 5 ];then
break
fi
((break_id++));
done
}

get_ip (){
gw_ip=$1
gw_port=$2
protocolas=$3
protocolac=$(echo $protocolas | tr a-z A-Z)
upnp_text_infos=$4
ip_scan=$(echo $gw_ip | cut -d. -f1-3)
ip_a_info=$(fping -a -g -q $ip_scan.0/24)
ip_a_array=(${ip_a_info// / })
for ip_add in ${ip_a_array[@]}; do
if [[ ${protocolac} = "TCP" ]]
then
ip_upnp_port=$(nc -z $ip_add $gw_port -w 2 && echo "open" || echo "close")
ip_upnp_ports_a=$(curl -L -k --connect-timeout 1 -m 2 -s "http://$ip_add:$gw_port")
ip_upnp_ports_b=$(curl -L -k --connect-timeout 1 -m 2 -s "https://$ip_add:$gw_port")
else
ip_upnp_port=$(nc -z $ip_add $gw_port -w 2 -u && echo "open" || echo "close")
fi
if [[ "$ip_upnp_port" = "open" ]] && [[ "$gw_ip" != "$ip_add" ]];then
echo $ip_add
return 1
fi
done
}
upnp_nat_v2 (){
lan_ip_add=$1
route_upnp_xml=$2
lan_ip_port=$3
wan_ip_port=$4
upnp_protocol=$5
upnp_base=$6
upnp_eth=$7
upnp_pa=$upnp_base""$wan_ip_port""$lan_ip_port""$(echo $upnp_protocol | tr a-z A-Z)
upnp_pb=$upnp_base"
"$wan_ip_port""$lan_ip_port""$upnp_protocol
if [ -n "$upnp_eth" ]; then
upnpeth=" -m "$upnp_eth
else
upnpeth=" "
fi
upnp_array=$(upnpc -u $route_upnp_xml $upnpeth -L | grep "$upnp_base" | awk '{print $3""$2}'| sed 's/-.*./ /g' | awk '{print $1""$1""$2}')
for upnp_tp in ${upnp_array[@]}; do
upnpc -u $route_upnp_xml $upnpeth -N $(echo $upnp_tp | sed 's/_/ /g') > /dev/null
done
upnpc -u $route_upnp_xml $upnpeth -N $wan_ip_port $wan_ip_port $upnp_protocol >/dev/null
add_upnp_log=$(upnpc -u $route_upnp_xml $upnpeth -e "$upnp_base" -n $lan_ip_add $lan_ip_port $wan_ip_port $upnp_protocol 0)
add_upnp_log_a=$(echo $add_upnp_log | grep "duration" | grep "InternalIP:Port")
if [ -n "$add_upnp_log_a" ];then
return 1
fi
upnp_arrayp=$(upnpc -u $route_upnp_xml $upnpeth -L | grep "$upnp_base" | awk '{print $4""$3""$2}'| sed "s/->..://g" | sed "s/'//g")
for upnp_tpp in ${upnp_arrayp[@]}; do
if [[ ${upnp_tpp} = ${upnp_pa} ]] || [[ ${upnp_tpp} = ${upnp_pb} ]]
then
return 1
else
cd /
fi
done
return 0
}
upnp_nat_v2i (){
lan_ip_add=$1
route_upnp_xml=$2
lan_ip_port=$3
wan_ip_port=$4
upnp_protocol=$5
upnp_base=$6
upnp_eth=$7
upnp_pa=$upnp_base"
"$wan_ip_port""$lan_ip_port""$(echo $upnp_protocol | tr a-z A-Z)
upnp_pb=$upnp_base""$wan_ip_port""$lan_ip_port""$upnp_protocol
if [ -n "$upnp_eth" ]; then
upnpeth=" -m "$upnp_eth
else
upnpeth=" "
fi
upnp_array=$(upnpc -i -u $route_upnp_xml $upnpeth -L | grep "$upnp_base" | awk '{print $3"
"$2}'| sed 's/-.
./ /g' | awk '{print $1""$1""$2}')
for upnp_tp in ${upnp_array[@]}; do
upnpc -i -u $route_upnp_xml $upnpeth -N $(echo $upnp_tp | sed 's/_/ /g') > /dev/null
done
upnpc -i -u $route_upnp_xml $upnpeth -N $wan_ip_port $wan_ip_port $upnp_protocol >/dev/null
add_upnp_log=$(upnpc -i -u $route_upnp_xml $upnpeth -e "$upnp_base" -n $lan_ip_add $lan_ip_port $wan_ip_port $upnp_protocol 0)
add_upnp_log_a=$(echo $add_upnp_log | grep "duration" | grep "InternalIP:Port")
if [ -n "$add_upnp_log_a" ];then
return 1
fi
upnp_arrayp=$(upnpc -i -u $route_upnp_xml $upnpeth -L | grep "$upnp_base" | awk '{print $4"
"$3""$2}'| sed "s/->.*.://g" | sed "s/'//g")
for upnp_tpp in ${upnp_arrayp[@]}; do
if [[ ${upnp_tpp} = ${upnp_pa} ]] || [[ ${upnp_tpp} = ${upnp_pb} ]]
then
return 1
else
cd /
fi
done
return 0
}
upnp_nat_v1 (){
lan_ip_add=$1
route_upnp_xml=$2
lan_ip_port=$3
wan_ip_port=$4
upnp_protocol=$5
upnp_base=$6
upnp_eth=$7
upnp_pa=$upnp_base""$wan_ip_port""$lan_ip_port""$(echo $upnp_protocol | tr a-z A-Z)
upnp_pb=$upnp_base"
"$wan_ip_port""$lan_ip_port""$upnp_protocol
if [ -n "$upnp_eth" ]; then
upnpeth=" -m "$upnp_eth
else
upnpeth=" "
fi
upnp_array=$(upnpc -u $route_upnp_xml $upnpeth -l | grep "$upnp_base" | awk '{print $3""$2}'| sed 's/-.*.//g')
for upnp_tp in ${upnp_array[@]}; do
upnpc -u $route_upnp_xml $upnpeth -d $(echo $upnp_tp | sed 's/_/ /g') > /dev/null
done
upnpc -u $route_upnp_xml $upnpeth -d $wan_ip_port $upnp_protocol >/dev/null
add_upnp_log=$(upnpc -u $route_upnp_xml $upnpeth -e "$upnp_base" -a $lan_ip_add $lan_ip_port $wan_ip_port $upnp_protocol 0)
add_upnp_log_a=$(echo $add_upnp_log | grep "duration" | grep "InternalIP:Port")
if [ -n "$add_upnp_log_a" ];then
return 1
fi
upnp_arrayp=$(upnpc -u $route_upnp_xml $upnpeth -l | grep "$upnp_base" | awk '{print $4"
"$3""$2}'| sed "s/->.*.://g" | sed "s/'//g")
for upnp_tpp in ${upnp_arrayp[@]}; do
if [[ ${upnp_tpp} = ${upnp_pa} ]] || [[ ${upnp_tpp} = ${upnp_pb} ]]
then
return 1
else
cd /
fi
done
return 0
}
upnp_nat_v1i (){
lan_ip_add=$1
route_upnp_xml=$2
lan_ip_port=$3
wan_ip_port=$4
upnp_protocol=$5
upnp_base=$6
upnp_eth=$7
upnp_pa=$upnp_base""$wan_ip_port""$lan_ip_port""$(echo $upnp_protocol | tr a-z A-Z)
upnp_pb=$upnp_base"
"$wan_ip_port""$lan_ip_port""$upnp_protocol
if [ -n "$upnp_eth" ]; then
upnpeth=" -m "$upnp_eth
else
upnpeth=" "
fi
upnp_array=$(upnpc -i -u $route_upnp_xml $upnpeth -l | grep "$upnp_base" | awk '{print $3""$2}'| sed 's/-.*.//g')
for upnp_tp in ${upnp_array[@]}; do
upnpc -i -u $route_upnp_xml $upnpeth -d $(echo $upnp_tp | sed 's/_/ /g') > /dev/null
done
upnpc -i -u $route_upnp_xml $upnpeth -d $wan_ip_port $upnp_protocol >/dev/null
add_upnp_log=$(upnpc -i -u $route_upnp_xml $upnpeth -e "$upnp_base" -a $lan_ip_add $lan_ip_port $wan_ip_port $upnp_protocol 0)
add_upnp_log_a=$(echo $add_upnp_log | grep "duration" | grep "InternalIP:Port")
if [ -n "$add_upnp_log_a" ];then
return 1
fi
upnp_arrayp=$(upnpc -i -u $route_upnp_xml $upnpeth -l | grep "$upnp_base" | awk '{print $4"
"$3""$2}'| sed "s/->.*.://g" | sed "s/'//g")
for upnp_tpp in ${upnp_arrayp[@]}; do
if [[ ${upnp_tpp} = ${upnp_pa} ]] || [[ ${upnp_tpp} = ${upnp_pb} ]]
then
return 1
else
cd /
fi
done
return 0
}
#######################################################################开始处理数据
fb=$(expr $wan_upnp - 1)
echo
upnp_exip_up=""
upnp_exip_down=""
wan_gw_array=(${wan_gw_info// / })
for ((i=0;i<$wan_upnp;i++))
do
wan_gw_ip=${wan_gw_array[$i]}
gw_upnp_xml=$(get_gw_upnp $wan_gw_ip "$upnp_xml")
echo $(date +"%F %T")"获取网关xml:"$gw_upnp_xml
upnp_exip_down=$(get_upnp_exip "$gw_upnp_xml" $eth)
echo $(date +"%F %T")"获取网关出口IP:"$upnp_exip_down

	if [ ! -n "$gw_upnp_xml" ];then
	    echo "网关"$wan_gw_ip"未找到UPNP服务"
	    exit 0
	fi
    if [[ $i -eq 0 ]]
        then
            #本机IP OR 内网下lan IP
			upnp_exip_up=$lan_ip
        else
			#映射的内网端口
			lan_upnp_port=$wan_upnp_port
			#本机IP OR 内网下lan IP(上一轮的出口IP)
			upnp_exip_up=$upnp_exip_down_d
			if [ ! -n "$upnp_exip_up" ]; then
				#上一轮未获取到出口IP作为LAN IP,将通过服务信息检索出服务IP
				upnp_exip_up=$(get_ip $wan_gw_ip $wan_upnp_port $protocol "$upnp_text_info")
			fi
    fi
	#差值 将本轮出口IP 作为下一网关 内网下lan
	upnp_exip_down_d=$upnp_exip_down
	
	#旁路由判定-基于IP段是否相同的方式判定 因为正常路由wan和lan不能处于相同网段
	gw_wan_domain_a=$(echo ${wan_gw_array[$i]} | cut -d. -f1-3)
	gw_wan_domain_b=$(echo ${wan_gw_array[$i + 1]} | cut -d. -f1-3)
	if [[ "$gw_wan_domain_a" = "$gw_wan_domain_b" ]] && [[ "$side_route" = "yes" ]];then
		echo "疑似遇到旁路由模式,停止本网关映射,进行映射跃迁,不经过旁路映射"
		if [[ $i -eq 0 ]]
			then
				#差值 将本轮 LAN IP 作为下一网关 内网下lan
				upnp_exip_down_d=$lan_ip
			else
				#差值 将本轮 LAN IP 作为下一网关 内网下lan
				upnp_exip_down_d=$upnp_exip_up
		fi
		continue
	fi
	break_id=1
	for ((;;))
		do
			upnp_nat_v2 $upnp_exip_up "$gw_upnp_xml" $lan_upnp_port $wan_upnp_port $protocol "$upnp_port_name" $eth
			if [ $? -eq 1 ];then
				upnp_state="V2映射成功"
				break
			fi
			upnp_nat_v2i $upnp_exip_up "$gw_upnp_xml" $lan_upnp_port $wan_upnp_port $protocol "$upnp_port_name" $eth
			if [ $? -eq 1 ];then
				upnp_state="V2i映射成功"
				break
			fi
			upnp_nat_v1 $upnp_exip_up "$gw_upnp_xml" $lan_upnp_port $wan_upnp_port $protocol "$upnp_port_name" $eth
			if [ $? -eq 1 ];then
				upnp_state="V1映射成功"
				break
			fi
			upnp_nat_v1i $upnp_exip_up "$gw_upnp_xml" $lan_upnp_port $wan_upnp_port $protocol "$upnp_port_name" $eth
			if [ $? -eq 1 ];then
				upnp_state="V1i映射成功"
				break
			fi
			if [ $break_id -eq 1 ];then
				upnp_state="映射失败"
				break
			fi
			((break_id++));
		done
    if [[ "$cspding" != "route" ]]
        then
            echo ""
            echo $upnp_exip_up "$gw_upnp_xml" $lan_upnp_port $wan_upnp_port $protocol "$upnp_port_name" $eth
            echo "路由层 "$i" "$upnp_state"--------"$upnp_exip_up "-->>" $wan_gw_ip "upnpXML" $gw_upnp_xml "ExitIP "$upnp_exip_down
        else
            echo $upnp_exip_up "$gw_upnp_xml" $lan_upnp_port $wan_upnp_port $protocol "$upnp_port_name" $eth
            echo "路由层 "$i" "$upnp_state"--------"$upnp_exip_up "-->>" $wan_gw_ip "upnpXML" $gw_upnp_xml "ExitIP "$upnp_exip_down
    fi
    echo ""
    echo ""
done`

@lhongcai
Copy link

lhongcai commented Sep 10, 2024

如果是多个端口映射,配置起来就非常繁琐容易出错
PixPin_2024-09-11_02-36-08
同时想在同一个端口号配置多少个ddns脚本
所以我花费了三四天的时间构思和编写了这个一键脚本
一键安装配置natmap插件脚本

为了方便使用我弄了个在线安装命令:
curl -L w.1hc.us.kg/natmap_install.sh|sh

脚本只适合于padavan或者openwrt
PixPin_2024-09-11_02-49-05

脚本使用方法:
在线安装
第一步:登录SSH终端,输入 curl http://w.1hc.us.kg/natmap/natmap_install.sh | sh

第二步:Openwrt的编辑_/etc/rc.local_
padavan的编辑_/etc/storage/started_script.sh_

第三步:输入 sh /etc/storage/natmap.sh
或者 sh /etc/natmap.sh

openwrt的

停止运行:sh /etc/natmap.sh 0
sh /etc/natmap.sh stop

重启运行:sh /etc/natmap.sh

卸载:sh /etc/natmap.sh uninstall

padavan的

停止运行:sh /etc/storage/natmap.sh 0
sh /etc/storage/natmap.sh stop

重启运行:sh /etc/storage/natmap.sh

卸载:sh /etc/storage/natmap.sh uninstall

目前预编辑几个natmap专用ddns脚本

cf_txt.sh <子域名> <域名> <电子邮箱>
域名以TXT记录
https://dash.cloudflare.com/login

cf_ip4p.sh <子域名> <域名> <电子邮箱>
域名以ip4p形式AAAA记录
https://dash.cloudflare.com/login

dedyn_ip4p.sh <子域名> <域名>
子域名以ip4p形式AAAA记录
https://desec.io/

dedyn_txt.sh <子域名> <域名>
子域名以TXT记录
https://desec.io/

dynv6_ip4p.sh <子域名> <域名>
子域名以ip4p形式AAAA记录
https://dynv6.com/

dynv6_aaaa.sh <域名>
主域名以ip4p形式AAAA记录
https://dynv6.com/

dynv6_txt.sh <子域名> <域名>
子域名以TXT记录
https://dynv6.com/

freedomain_ip4p.sh <子域名> <域名>
子域名以ip4p形式AAAA记录
https://freedomain.one/users/login/

freedomain_txt.sh <子域名> <域名>
域名以TXT记录
https://freedomain.one/users/login/

UrlShort_wr.sh <后缀> <服务器> <密码>
直接在浏览器中重定向。
现成的网站
https://1hc.us.kg/
https://Lhc.us.kg/
相关的项目
https://github.com/lmq8267/CloudflareWorker-KV-UrlShort
https://github.com/lmq8267/short-url
https://github.com/lmq8267/short-url-go

UrlShort_ssh.sh <后缀> <服务器> <密码>
以文本形式在浏览器显示SSH信息

UrlShort_html.sh <后缀> <服务器> <密码>
在浏览器显示ip和端口号

gg_wr.sh <后缀> <电子邮箱> <密码> <link_id>
直接在浏览器中重定向
https://gg.gg/login

shorten_wr.sh <后缀> <服务器> <密码>
直接在浏览器中重定向
相关的项目
https://github.com/lmq8267/Url-Shorten-Worker
——natmap_install.sh脚本内容——

#!/bin/sh

# 脚本制作人:liao*****
# 适用平台:pandavan和OpenWrt

log_ () {
#echo -e "\033[35m`date +%F' '%X ` \033[0m" "\033[32m ${loge} \033[0m"
echo -e "\033[36;1m【$(TZ=UTC-8 date -R +%Y年%m月%d月\ %X)】 : \033[0m\033[32;1m$1 \033[0m"
logger  "$1"
}

log_2 () {
local loge=$1
#echo -e "\033[35m`date +%F' '%X ` \033[0m" "\033[31m ${loge} \033[0m"
echo -e "\033[36;1m【$(TZ=UTC-8 date -R +%Y年%m月%d月\ %X)】 : \033[0m\033[31;1m$1 \033[0m"
logger  "${loge}"
}

if [ -f "/etc/storage/started_script.sh" ] ; then # 判断系统是否为padavan
boot_up="/etc/storage/started_script.sh"
natmap_sh="/etc/storage/natmap.sh"
n_ddns="/etc/storage/n_ddns"
#cp "${natmap}" /etc/storage/natmap
#iptable_sh="/etc/storage/post_iptables_script.sh"
#boot_up="/tmp/log/info.txt"
#natmap_sh="/tmp/natmap.sh"
else # 其他的系统
boot_up="/etc/rc.local"
natmap_sh="/etc/natmap.sh"
n_ddns="/etc/n_ddns"
#cp "${natmap}" /etc/natmap
#boot_up="/tmp/natmap_info.txt"
#natmap_sh="/tmp/log/natmap.sh"
#boot_up="/tmp/log/info.txt"
fi



log_ "开始下载启动natmap.sh脚本文件"
script="natmap.sh"
urls="
http://w.1hc.us.kg/natmap/${script}
http://lhc.us.kg:19213/natmap/${script}
http://liaoh.web3v.vip/natmap/${script}
"
# 尝试下载并检查每个URL
for url in ${urls}
do
    log_ "尝试下载: $url"
    
    # 使用curl下载文件
    if curl --connect-timeout 3 -#Lko "/tmp/${script}" "$url" ; then
        log_ "下载成功: $url"
         [ -x "/tmp/${script}" ] || chmod +x "/tmp/${script}"
        # 检查文件的第一行是否包含 #! 字符串
        if head -n 1 /tmp/${script} | grep -q '^#!'; then
         [ -x "/tmp/${script}" ] || chmod +x "/tmp/${script}"
            log_ "文件检查通过,是shell脚本"
            cp "/tmp/${script}" "${natmap_sh}"
            break  # 成功下载并验证后退出循环
        else
            log_2 "文件不是shell脚本,尝试下一个地址"
        fi
    else
        log_2 "下载失败: $url,尝试下一个地址"
    fi
done
log_ "启动natmap.sh脚本文件下载完毕"





log_ "开始下载natmap专用ddns脚本文件"
natmap_ddns_script="
cf_txt.sh
cf_ip4p.sh
dedyn_ip4p.sh
dedyn_txt.sh
dynv6_ip4p.sh
dynv6_aaaa.sh
dynv6_txt.sh
freedomain_ip4p.sh
freedomain_txt.sh
UrlShort_wr.sh
UrlShort_ssh.sh
UrlShort_html.sh
gg_wr.sh
shorten_wr.sh
"

for k in $natmap_ddns_script

do
[ ! -d "${n_ddns}" ] && mkdir "${n_ddns}"

ddns_script="${n_ddns}/$k"

[ -f "$ddns_script" ] || {

url_1="
http://w.1hc.us.kg/natmap/natmap_ddns_script/$k
http://lhc.us.kg:19213/natmap/natmap_ddns_script/$k
http://liaoh.web3v.vip/natmap_ddns_script/$k
http://${webd_t}/natmap_ddns_script/$k
"

for j in ${url_1}
do
curl -o "$ddns_script" -#Lks $j &>/dev/unll
if [ -f "$ddns_script" ] ; then
if head -n 1 "$ddns_script" | grep -q '\#!' ; then
	log_ "$j下载成功!"
	log_ " "
	break
else
	log_2 "$j文件错误!"
	[ -f "$ddns_script" ] && rm -f "$ddns_script" && log_ "$j删除成功!"
	log_ "即将尝试使用下一个网址进行下载 ······"
	log_ " "
fi
else
	[ -f "$ddns_script" ] && rm -f "$ddns_script" && log_ "$j删除成功!"
	log_2 "$j下载错误!"
	log_ "即将尝试使用下一个网址进行下载 ······"
	log_ " "
fi
done


}
 [ -x "$ddns_script" ] || chmod +x "$ddns_script"
 

done
log_ "natmap专用ddns脚本文件下载完毕"

log_ "请到${n_ddns}目录中查看natmap专用ddns脚本文件"


 [ -z "`cat $boot_up | grep -o 'natmap.sh'`" ] && {
sed -i '2i\sleep 55 && sh '"${natmap_sh}"' &' ${boot_up} # 插在开机启动脚本第二行中
} 

if [ -z "`cat $boot_up | grep -o 'natmap端口映射配置'`" ] ; then

cat <<EOF10>> "$boot_up"  # 加到开机启动脚本后

:<<'!mn'
natmap端口映射配置

像这样的格式,一条映射可以配置多个ddns脚本,同时要去掉“#”号!
已下载的natmap专用ddns脚本文件:
${n_ddns}/cf_txt.sh 			域名以TXT记录
${n_ddns}/cf_ip4p.sh 			域名以ip4p形式AAAA记录
${n_ddns}/dedyn_ip4p.sh 		子域名以ip4p形式AAAA记录
${n_ddns}/dedyn_txt.sh 		子域名以TXT记录
${n_ddns}/dynv6_ip4p.sh		子域名以ip4p形式AAAA记录
${n_ddns}/dynv6_aaaa.sh		主域名以ip4p形式AAAA记录
${n_ddns}/dynv6_txt.sh 		子域名以TXT记录
${n_ddns}/freedomain_ip4p.sh 		子域名以ip4p形式AAAA记录
${n_ddns}/freedomain_txt.sh 		域名以TXT记录
${n_ddns}/UrlShort_wr.sh 		直接在浏览器中重定向
${n_ddns}/UrlShort_ssh.sh 		以文本形式在浏览器显示SSH信息
${n_ddns}/UrlShort_html.sh 		在浏览器显示ip和端口号
${n_ddns}/gg_wr.sh 		直接在浏览器中重定向
${n_ddns}/shorten_wr.sh 		直接在浏览器中重定向
#udp/tcp 端口号 [(内网ip) (服务端口)]
#-/+ 脚本路径 后缀/子域名 域名 密码/token

例如:
#udp 20086 127.0.0.1 10086 # N2N服务 udp端口
#- ${n_ddns}/dynv6_txt.sh 	<子域名> 	<域名> 		<token>

#udp 49872 127.0.0.1 29872 # vnts服务端udp端口
#- ${n_ddns}/dynv6_txt.sh 	<子域名> 	<域名> 		<token>
#- ${n_ddns}/dedyn_txt.sh	 <子域名> 	<域名> 		<token>

#udp 41820 127.0.0.1 51820 # wireguard服务
#- ${n_ddns}/dynv6_ip4p.sh 	<子域名> 	<域名> 		<token>

#tcp 49872 127.0.0.1 29872 # vnts服务端tcp端口
#+ ${n_ddns}/cf_txt.sh 	<子域名> 	<域名> 	<token>	 <电子邮箱>	 <key>
#+ ${n_ddns}/UrlShort_html.sh 	<后缀> 		<域名> 		<密码>
#+ ${n_ddns}/dynv6_txt.sh 	<子域名> 	<域名> 		<token>
#+ ${n_ddns}/dedyn_txt.sh	 <子域名> 	<域名> 		<token>

#tcp 49870 127.0.0.1 29870 # vnts服务端web页面
#+ ${n_ddns}/UrlShort_wr.sh 	<后缀> 		<域名> 		<密码>

#tcp 400180 192.168.1.10 80 # 其他web页面
#+ ${n_ddns}/UrlShort_wr.sh 	<后缀> 		<域名> 		<密码>

#tcp 40080 <内网ip> 80 # 路由器主页,不要用127.0.0.1
#+ ${n_ddns}/UrlShort_wr.sh 	<后缀> 		<域名> 		<密码>
#+ ${n_ddns}/UrlShort_wr.sh 	<后缀> 		<域名> 		<密码>

#tcp 40022 127.0.0.1 22 # SSH 用户@ip -p 端口 信息
#+ ${n_ddns}/UrlShort_ssh.sh 	<后缀> 		<域名> 		<密码>

!mn
EOF10
log_ "配置完毕"

fi

log_ "请到本地启动配置文件(${boot_up})中编辑你自己的"
log_ "编辑完成后,记得保存!"
log_ "最后运行下sh ${natmap_sh} 脚本即可"

——natmap.sh脚本内容——

#!/bin/sh

# 脚本制作人:liao******
# 适用平台:pandavan和OpenWrt

log_ (){
local loge=$1
echo -e "\033[36;1m【$(TZ=UTC-8 date -R +%Y年%m月%d月\ %X)】 : \033[0m\033[35;1m${loge} \033[0m"
logger  "${loge}"
}


( [ "$1" = "0" ] || [ "$1" = "stop" ] ) && {
	sh  "/tmp/log/kill_natmap.log"
	log_ "已停止运行"
	exit 0
}



if [ -f "/etc/storage/started_script.sh" ] ; then # 判断系统是否为padavan
boot_up="/etc/storage/started_script.sh"
natmap_sh="/etc/storage/natmap.sh"
n_ddns="/etc/storage/n_ddns"
etc_natmap="/etc/storage/natmap"
#iptable_sh="/etc/storage/post_iptables_script.sh"
#boot_up="/tmp/log/info.txt"
#natmap_sh="/tmp/natmap.sh"
else # 其他的系统
boot_up="/etc/rc.local"
natmap_sh="/etc/natmap.sh"
n_ddns="/etc/n_ddns"
etc_natmap="/etc/natmap"
#cp "${natmap}" /etc/natmap
#boot_up="/tmp/natmap_info.txt"
#natmap_sh="/tmp/log/natmap.sh"
#boot_up="/tmp/log/info.txt"
fi

find_ (){ # 查找natmap运行文件

if [ -f "/tmp/natmap" ] ; then  
	natmap="/tmp/natmap"
elif [ -f "/etc/storage/natmap" ] ; then
	natmap="/etc/storage/natmap"
elif [ -f "/etc/storage/bin/natmap" ] ; then
	natmap="/etc/storage/bin/natmap"
elif [ -f "/etc/natmap" ] ; then
	natmap="/etc/natmap"
elif [ -f "/usr/bin/natmap" ] ; then
	natmap="/usr/bin/natmap"
elif [ -f "/jffs/natmap" ] ; then
	natmap="/jffs/natmap"
else
	natmap=""
	
	echo "系统不存在natmap插件"
fi

[ -f "${natmap}" ] && [ ! -x "${natmap}" ] && chmod +x "${natmap}" 

}

if ( [ "$1" = "install" ] || [ "$1" = "安装" ] ) ; then


log_ "开始下载启动natmap.sh脚本文件"
script="natmap.sh"
urls="
http://w.lhc.us.kg/natmap/${script}
http://s4.serv00.com:19213/natmap/${script}
http://liaoh.web3v.vip/natmap/${script}
"
# 尝试下载并检查每个URL
for url in ${urls}
do
    log_ "尝试下载: $url"
    
    # 使用curl下载文件
    if curl --connect-timeout 3 -#Lko "/tmp/${script}" "$url" ; then
        log_ "下载成功: $url"
         [ -x "/tmp/${script}" ] || chmod +x "/tmp/${script}"
        # 检查文件的第一行是否包含 #! 字符串
        if head -n 1 /tmp/${script} | grep -q '^#!'; then
         [ -x "/tmp/${script}" ] || chmod +x "/tmp/${script}"
            log_ "文件检查通过,是shell脚本"
            cp "/tmp/${script}" "${natmap_sh}"
            break  # 成功下载并验证后退出循环
        else
            log_ "文件不是shell脚本,尝试下一个地址"
        fi
    else
        log_ "下载失败: $url,尝试下一个地址"
    fi
done
log_ "启动natmap.sh脚本文件下载完毕"

log_ "开始下载natmap专用ddns脚本文件"

shell_script="
cf_txt.sh
cf_ip4p.sh
dedyn_ip4p.sh
dedyn_txt.sh
dynv6_ip4p.sh
dynv6_aaaa.sh
dynv6_txt.sh
freedomain_ip4p.sh
freedomain_txt.sh
UrlShort_wr.sh
UrlShort_ssh.sh
UrlShort_html.sh
gg_wr.sh
shorten_wr.sh
"
dir="${n_ddns}"

url_1="
http://w.lhc.us.kg/natmap/natmap_ddns_script
http://s4.serv00.com:19213/natmap/natmap_ddns_script
http://liaoh.web3v.vip/natmap_ddns_script

"

for k in $shell_script
do
[ ! -d "${dir}" ] && mkdir "${dir}" # 判断是否存在这个目录,否则创建
	dir_script="${dir}/$k" # 路径
[ -f "${dir_script}" ] || {
for j in ${url_1}
do
curl -o "$dir_script" -#Lks "$j/$k" &>/dev/unll
if [ -f "$dir_script" ] ; then
if head -n 1 "$dir_script" | grep -q '\#!' ; then # 判断下载的文件是否为脚本
	log_ "从$j下载的$k脚本成功!"
	log_ " "
	break # 如果是,跳出内循环,进行下一个脚本下载
else
	
	log_ "从$j下载的$k文件不是shell脚本!"
	[ -f "$dir_script" ] && rm -f "$dir_script" && log_ "$k删除成功!"
	log_ "即将尝试使用下一个网址进行下载 ······"
	echo " "
fi
else
	[ -f "$dir_script" ] && rm -f "$dir_script" && log_ "$k删除成功!"
	log_ "$j下载地址错误,无法下载!"
	log_ "即将尝试使用下一个网址进行下载 ······"
	log_ " "
fi
done
}
 [ -x "$dir_script" ] || chmod +x "$dir_script" # 判断是否有运行权限,否则赋予运行权限!
done

log_ "natmap专用ddns脚本文件下载完毕"

log_ "请到${n_ddns}目录中查看natmap专用ddns脚本文件"


 [ -z "`cat $boot_up | grep -o 'natmap.sh'`" ] && {
sed -i '2i\sleep 55 && sh '"${natmap_sh}"' &' ${boot_up} # 插在开机启动脚本第二行中
} 

if [ -z "`cat $boot_up | grep -o 'natmap端口映射配置'`" ] ; then

cat <<EOF10>> "$boot_up"  # 加到开机启动脚本后

:<<'!mn'
natmap端口映射配置

像这样的格式,一条映射可以配置多个ddns脚本,同时要去掉“#”号!
已下载的natmap专用ddns脚本文件:

${n_ddns}/cf_txt.sh 			域名以TXT记录
${n_ddns}/cf_ip4p.sh 			域名以ip4p形式AAAA记录
${n_ddns}/dedyn_ip4p.sh 		子域名以ip4p形式AAAA记录
${n_ddns}/dedyn_txt.sh 		子域名以TXT记录
${n_ddns}/dynv6_ip4p.sh		子域名以ip4p形式AAAA记录
${n_ddns}/dynv6_aaaa.sh		主域名以ip4p形式AAAA记录
${n_ddns}/dynv6_txt.sh 		子域名以TXT记录
${n_ddns}/freedomain_ip4p.sh 		子域名以ip4p形式AAAA记录
${n_ddns}/freedomain_txt.sh 		域名以TXT记录
${n_ddns}/UrlShort_wr.sh 		直接在浏览器中重定向
${n_ddns}/UrlShort_ssh.sh 		以文本形式在浏览器显示SSH信息
${n_ddns}/UrlShort_html.sh 		在浏览器显示ip和端口号
${n_ddns}/gg_wr.sh 			直接在浏览器中重定向
${n_ddns}/shorten_wr.sh 		直接在浏览器中重定向
#udp/tcp 端口号 [(内网ip) (服务端口)]
#-/+ 脚本路径 后缀/子域名 域名 密码/token

例如:
#udp 20086 127.0.0.1 10086 # N2N服务 udp端口
#- ${n_ddns}/dynv6_txt.sh 	<子域名> 	<域名> 		<token>

#udp 49872 127.0.0.1 29872 # vnts服务端udp端口
#- ${n_ddns}/dynv6_txt.sh 	<子域名> 	<域名> 		<token>
#- ${n_ddns}/dedyn_txt.sh	 <子域名> 	<域名> 		<token>

#udp 41820 127.0.0.1 51820 # wireguard服务
#- ${n_ddns}/dynv6_ip4p.sh 	<子域名> 	<域名> 		<token>

#tcp 49872 127.0.0.1 29872 # vnts服务端tcp端口
#+ ${n_ddns}/cf_txt.sh 	<子域名> 	<域名> 	<token>	 <电子邮箱>	 <key>
#+ ${n_ddns}/UrlShort_html.sh 	<后缀> 		<域名> 		<密码>
#+ ${n_ddns}/dynv6_txt.sh 	<子域名> 	<域名> 		<token>
#+ ${n_ddns}/dedyn_txt.sh	 <子域名> 	<域名> 		<token>

#tcp 49870 127.0.0.1 29870 # vnts服务端web页面
#+ ${n_ddns}/UrlShort_wr.sh 	<后缀> 		<域名> 		<密码>

#tcp 400180 192.168.1.10 80 # 其他web页面
#+ ${n_ddns}/UrlShort_wr.sh 	<后缀> 		<域名> 		<密码>

#tcp 40080 <内网ip> 80 # 路由器主页,不要用127.0.0.1
#+ ${n_ddns}/UrlShort_wr.sh 	<后缀> 		<域名> 		<密码>
#+ ${n_ddns}/UrlShort_wr.sh 	<后缀> 		<域名> 		<密码>

#tcp 40022 127.0.0.1 22 # SSH 用户@ip -p 端口 信息
#+ ${n_ddns}/UrlShort_ssh.sh 	<后缀> 		<域名> 		<密码>

!mn
EOF10
log_ "配置完毕"

fi

log_ "请到本地启动配置文件(${boot_up})中编辑你自己的"
log_ "编辑完成后,记得保存!"
log_ "最后运行下sh ${natmap_sh} 脚本即可"

exit 0
fi

if [ "$1" = "uninstall" ] ; then # 卸载

	[ -f "/tmp/log/kill_natmap.log" ] && sh "/tmp/log/kill_natmap.log"
	log_ "已停止运行"
	
	[ -d "${n_ddns}" ] && rm -rf "${n_ddns}" && log_ "删除${n_ddns}成功" # 是否存在这个文件夹,然后再删除
	[ -d "/tmp/n_ddns" ] && rm -rf "/tmp/n_ddns" && log_ "删除/tmp/n_ddns成功" # 是否存在这个文件夹,然后再删除
	[ -f "/tmp/log/kill_natmap.log" ] && rm -rf "/tmp/log/kill_natmap.log" && log_ "删除/tmp/log/kill_natmap.log成功" # 是否存在这个文件,然后再删除
	[ -f "${natmap_sh}" ] && rm "${natmap_sh}" && log_ "删除${natmap_sh}成功" # 是否存在这个文件,然后再删除
	[ -f "${etc_natmap}" ] && rm "${etc_natmap}" && log_ "删除${etc_natmap}成功" # 是否存在这个文件,然后再删除
#	[ -f "/tmp/natmap" ] && rm "/tmp/natmap" && log_ "删除/tmp/natmap成功" #是否存在这个文件,然后再删除
	
	sed -i '/natmap.sh/d' "${boot_up}" && log_ "从开始启动文件中删除natmap.sh字样成功" # 从开始启动中删除natmap.sh字样
	
	sed -i '/:<<'\''!mn'\''/,/!mn/d' "${boot_up}" && log_ "从开始启动文件中删除natmap配置成功" # 从开始启动中删除natmap.sh字样
	
	exit 0
fi

cputype_ (){
cputype=$(uname -ms | tr ' ' '_' | tr '[A-Z]' '[a-z]')
[ -n "$(echo $cputype | grep -E "linux.*armv.*")" ] && cpucore="arm"
[ -n "$(echo $cputype | grep -E "linux.*armv.*"| grep ddwrt )" ] && cpucore="ddwrt-arm"
[ -n "$(echo $cputype | grep -E "linux.*armv7.*")" ] && [ -n "$(cat /proc/cpuinfo | grep vfp)" ] && [ ! -d /jffs/clash ] && cpucore="armv7"
[ -n "$(echo $cputype | grep -E "linux.*aarch64.*|linux.*armv8.*")" ] && cpucore="aarch64"
[ -n "$(echo $cputype | grep -E "linux.*86.*")" ] && cpucore="i386"
[ -n "$(echo $cputype | grep -E "linux.*86_64.*")" ] && cpucore="x86_64" 

if [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ] ; then
mipstype=$(echo -n I | hexdump -o 2>/dev/null | awk '{ print substr($2,6,1); exit}') ##通过判断大小端判断mips或mipsle
[ "$mipstype" = "0" ] && cpucore="mips" || cpucore="mipsel"
fi
##判断CPU框架

# [ -n "$(cat /proc/cpuinfo | grep -E 'fpu|vfp')" ] && musl_eabi_hf="musleabihf" || musl_eabi_hf="musleabi"
# [ -n "$(cat /proc/cpuinfo | grep -E 'fpu|vfp')" ] && echo "musleabihf" || echo "musleabi"

musl_eabi_hf="musleabi" # 强制下载软件浮点

}


[ -d "/tmp/log" ] || mkdir "/tmp/log"

download_ () {

webd_t_


natmap="/tmp/natmap"

curl="curl --connect-timeout 3 -#Lko "
https="
http://s4.serv00.com:19213/natmap/bin/
http://w.1hc.us.kg/natmap/bin/
http://liaoh.web3v.vip/natmap/
"

for_in_ () {
for k in $https
do

for i in $url
do
	${curl} ${natmap} "${k}${i}" # &>/dev/null
	
if	[ "$?" = 0 ] ; then
	[ -f "${natmap}" ] && log_ "下载成功!"
	[ -f "${natmap}" ] && [ ! -x "${natmap}" ] && chmod +x "${natmap}"
  if [ $(($(${natmap} -h | wc -l))) -gt 3 ] ; then
			log_ "但程序与系统不匹配!"
			rm "$natmap"
			log_ "正在删除!" 
			sleep 2 
			echo -e "\n\n"
			log_ "准备下一个地址下载..."
			else
			"${natmap}" -h >/dev/null
			[ "$?" = 255 ] && {
			log_ "程序与系统匹配!"
			cp "${natmap}" "${etc_natmap}"
			
			break 
			} || rm "$natmap"
			fi
		else
			rm -f "${natmap}"
  fi
done
[ -f "${natmap}" ] && break
done
log_ "$i与设备匹配"


}



case "${cpucore}" in 
	"mipsel") url="
natmap-linux-mips32elsf.jpg
natmap-linux-mipsel.jpg
	"
	
	;;
	"mips") url="
natmap-linux-mips32sf.jpg
natmap-linux-mips32.jpg
	"

	
	;;
	"x86_64") url="
natmap-linux-x86_64.jpg

	"
	;;
	"i386")  url="
natmap-linux-x86_32.jpg
  "
	;;
	"arm") url="
natmap-linux-arm32.jpg
	"

	;;
	"armv7") url="
natmap-linux-arm32.jpg
	"

	;;
	"aarch64") url="
natmap-linux-arm64.jpg
	"	
	;;
esac


for_in_

}




find_

[ "${natmap}" = "" ] && {

cputype_

download_
}




# 清理旧文件
[ -n "$(find /tmp/log/ -maxdepth 1 -type f -name 'udp_*' -print)" ] && rm /tmp/log/udp_* &>/dev/null

#find /tmp/log/:在 /tmp/log/ 目录中查找文件。
#-maxdepth 1:限制查找深度为1,即只在指定目录中查找,不进入子目录。
#-type f:只查找普通文件。
#-name 'udp_*':查找文件名符合模式 udp_* 的文件。
#-print -quit:找到第一个匹配的文件后打印文件名并立即退出,这样可以提高效率,避免不必要的额外搜索。

[ -n "$(find /tmp/log/ -maxdepth 1 -type f -name 'tcp_*' -print)" ] && rm /tmp/log/tcp_* &>/dev/null
[ -f "/tmp/log/commands.sh" ] && rm /tmp/log/commands.sh &>/dev/null
[ -f "/tmp/log/natmap.log" ] && rm /tmp/log/natmap.log  &>/dev/null

[ -f "/tmp/log/kill_natmap.log" ] && {
sh "/tmp/log/kill_natmap.log"
rm "/tmp/log/kill_natmap.log"
}

sleep 1 && log_ "2"
sleep 1 && log_ "1"
sleep 1 && log_ "正在读取配置信息 。。。"

# 定义natmap变量
#natmap="/tmp/natmap"  # 替换为实际的natmap命令路径
stun="stun.miwifi.com" # stun服务器
nohup="`which nohup`" 

# 读取并处理每一行
current_udp_file=""
while IFS= read -r line; do
    case "$line" in
        udp*)
            # 提取UDP信息
            port=$(echo "$line" | awk '{print $2}')
            ip=$(echo "$line" | awk '{print $3,$4}' | grep -v '\#' |awk '{print $1}')
            target_port=$(echo "$line" |  awk '{print $3,$4}' | grep -v '\#' |awk '{print $2}')
            current_udp_file="/tmp/log/udp_$port"
            # 构建并运行UDP命令
            if [ -n "$ip" ] && [ -n "$target_port" ]; then
            
                echo -e "${nohup} ${natmap} -u -s $stun -b $port -t $ip -p $target_port -e $current_udp_file >>/tmp/log/natmap.log &\nsleep 1" >> /tmp/log/commands.sh 

                echo -e "kill \`ps -w | grep \"\\-u -s $stun -b $port -t $ip -p $target_port\" | grep -v 'grep' |awk '{print \$1}'\`" >> /tmp/log/kill_natmap.log # 记录natmap进程
                
                
            echo -e '#!/bin/sh\n'  > "$current_udp_file"
            
            chmod +x "$current_udp_file"
            
            else
                echo -e "${nohup} ${natmap} -u -s $stun -b $port -e $current_udp_file >>/tmp/log/natmap.log  &\nsleep 1" >> /tmp/log/commands.sh
             # ${natmap} -u -s $stun -b $port -e $current_udp_file &
                echo -e "kill \`ps -w | grep \"\\-u -s $stun -b $port -e $current_udp_file\" | grep -v 'grep' |awk '{print \$1}'\`" >> /tmp/log/kill_natmap.log
            echo -e '#!/bin/sh\n' > "$current_udp_file"
            chmod +x "$current_udp_file" 
                
            fi
            iptables -I INPUT -p udp --dport $port -j ACCEPT # 放开端口
            ;;
        -*)
            # 提取命令和参数
            cmd=$(echo "$line" | awk '{print $2}')
            params=$(echo "$line" | awk '{print $3,$4,$5,$6,$7}')
            # 构建命令字符串
            cmd_str="sh $cmd \$1 \$2 \$3 $params"
            # 写入到文件
            echo -e "$cmd_str\nsleep 2" >> "$current_udp_file"
            
            chmod +x "$current_udp_file"
            ;;
    esac
done < "${boot_up}"


#################################
stun="turn.cloudflare.com" # stun服务器
current_tcp_file=""
while IFS= read -r line; do
    case "$line" in
        tcp*)
            # 提取TCP信息
            port=$(echo "$line" | awk '{print $2}')
            ip=$(echo "$line" | awk '{print $3,$4}' | grep -v '\#' |awk '{print $1}')
            target_port=$(echo "$line" | awk '{print $3,$4}' | grep -v '\#' |awk '{print $2}')
            current_tcp_file="/tmp/log/tcp_$port"
            # 构建并运行TCP命令
            if [ -n "$ip" ] && [ -n "$target_port" ]; then
                echo -e "${nohup} ${natmap} -s $stun -h baidu.com -b $port -t $ip -p $target_port -e $current_tcp_file >>/tmp/log/natmap.log & \nsleep 1" >> /tmp/log/commands.sh

                echo -e "kill \`ps -w | grep \"\\-s $stun -h baidu.com -b $port -t $ip -p $target_port\" | grep -v 'grep' |awk '{print \$1}'\`" >> /tmp/log/kill_natmap.log # 记录natmap进程
            echo -e '#!/bin/sh\n' > "$current_tcp_file"
            
            chmod +x "$current_tcp_file"
            
            else
                echo -e "${nohup} ${natmap} -s $stun -h baidu.com -b $port -e $current_tcp_file >>/tmp/log/natmap.log & \nsleep 1" >> /tmp/log/commands.sh

                echo -e "kill \`ps -w | grep \"\\-s $stun -h baidu.com -b $port -e $current_tcp_file\" | grep -v 'grep' |awk '{print \$1}'\`" >> /tmp/log/kill_natmap.log
            echo -e '#!/bin/sh\n' > "$current_tcp_file"
            chmod +x "$current_tcp_file" 
                
            fi
            iptables -I INPUT -p tcp --dport $port -j ACCEPT  # 放开端口
            ;;
        +*)
            # 提取命令和参数
            cmd=$(echo "$line" | awk '{print $2}')
            params=$(echo "$line" | awk '{print $3,$4,$5,$6,$7}')
            # 构建命令字符串
            cmd_str="sh $cmd \$1 \$2 \$3 $params"
            # 写入到文件
            echo -e "$cmd_str\nsleep 2" >> "$current_tcp_file"
            
            chmod +x "$current_tcp_file"
            ;;
    esac
done < "${boot_up}"

# 运行所有UDP命令
[ -f "/tmp/log/commands.sh" ] && sh -x /tmp/log/commands.sh
sleep 1 && log_ "5"
sleep 1 && log_ "4"
sleep 1 && log_ "3"
sleep 1 && log_ "2"
sleep 1 && log_ "1"

if [ -f "/tmp/log/natmap.log" ] ; then
sleep 1 && log_ "natmap进程启动成功"
sleep 1 && cat /tmp/log/natmap.log

else

log_ "无natmap配置信息,请检查下natmap配置"
exit 1
fi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

8 participants