heiher/natmap

是否可以增加个先行脚本参数呢 例如-e 带的脚本

Closed this issue · 12 comments

是否可以增加个先行脚本参数呢 例如-e 带的脚本
只是这个先行脚本 需要在程序功能执行前 先执行这个脚本 并且程序将-s -b等参数附加给脚本调用
想到这个是因为tplink路由下程序运行起来后 tp无法进行端口映射和upnp了 所以想穿出去 必须先在路由上做端口映射 或者 upnp
路由upnp
upnpc -i -e "natmap" -a 192.168.1.100 8080 8080 TCP 0

可以通过环境变量传递

可以接受环境变量传递

需要的是先执行脚本,后运行natmap,这样tplink路由才能正常使用
实在不行就只能先计划任务执行脚本 再运行natmap了

`#!/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`

``

我以为你是想传递数据给成功后执行的notify script。
如果是要在启动时执行,那可以考虑脚本执行后再由脚本运行 natmap?

我以为你是想传递数据给成功后执行的notify script。 如果是要在启动时执行,那可以考虑脚本执行后再由脚本运行 natmap?

这个方法可以,但还是得先给脚本指定参数再运行natmap,如果能直接给natmap指定参数去调用脚本就省事了

我以为你是想传递数据给成功后执行的notify script。 如果是要在启动时执行,那可以考虑脚本执行后再由脚本运行 natmap?

我的考虑是,脚本模板被natmap调用,
无论natmap参数如何变动,把natmap参数给脚本预处理完成再运行natmap
如果是脚本调用natmap,那么脚本模板就得写natmap运行命令,
如果我把脚本重复的功能拆分成一个个的脚本模板,让模板可以相互组合调用,那么模板里的natmap启动命令就是个大问题,因为主脚本模板调用其他模板时不知道natmap是否在运行中,是否正常启动了

我以为你是想传递数据给成功后执行的notify script。 如果是要在启动时执行,那可以考虑脚本执行后再由脚本运行 natmap?

这个参数推荐有,因为有这个参数可以省去写模板时调用natmap和监测natmap运行的麻烦,
主脚本引用其他脚本也不需要担心natmap重复运行的情况,
因为计划任务发现natmap程序在运行这个端口就不会再启动,如果预处理时间长导致多次启动脚本,这种就比较麻烦了,因为多启动的脚本会重复启动natmap

我也比较倾向于针对特定需求定制natmap的启动器(脚本),关于多个模板脚本之间的关联以及natmap的是否启动,在启动器中都可以维护状态标识来判断的。

我也比较倾向于针对特定需求定制natmap的启动器(脚本),关于多个模板脚本之间的关联以及natmap的是否启动,在启动器中都可以维护状态标识来判断的。

我目前判断启动是根natmap的-b参数来判断的
如果无法获取到natmap进程里存在这个端口的任务就无法确定natmap是否正常启动了
所以我在想,是否可以增加先行脚本,来确保natmap的启动以及避免重复启动
因为upnp虽然是个很即时的功能,但如果同时存在2个相同进程 upnp可能会被清理掉,
因为upnp必须保持实时清理端口的状态,保持这个状态是因为很多路由厂商限制了upnp映射的数量,运行脚本首先做的就是清理upnp缓存,缓存是根据upnp任务备注来识别的,
华为路由限制upnp数量是32 如果出现多个相同upnp任务,就会导致upnp最终被清理,如果存在环境文件修改可能会导致文件配置崩溃

我也比较倾向于针对特定需求定制natmap的启动器(脚本),关于多个模板脚本之间的关联以及natmap的是否启动,在启动器中都可以维护状态标识来判断的。

最主要的,虽然-b端口可以作为识别,但是在主机出现随机端口程序时,可能会导致natmap无法正常启动,因为端口冲突,这种时候需要终结natmap换端口再启动,而我也是这么做的,为了避免端口冲突,我都是用随机端口来启动natmap,正常启动后 -e的脚本做最后的操作,比如打开upnp 修改transmission端口

直到碰到tplink路由器,我才头疼,因为想用tplink就得先执行脚本开放upnp 再运行natmap
而脚本运行时长是不确定的,所以在脚本超时时,获取不到natmap就会再启动一遍,甚至换参数再启动,而为了避免端口冲突无法正常启动,在15秒后如果natmap没有获取到外网信息,就会强制换端口重启,而超时的前置脚本就可能成为残留任务,目前我是获取所有脚本进程以及根据-b来判断是否残留的,然后kill残留的脚本

我也比较倾向于针对特定需求定制natmap的启动器(脚本),关于多个模板脚本之间的关联以及natmap的是否启动,在启动器中都可以维护状态标识来判断的。

因为脚本具有重复性,所以我把必要的参数全都写到配置文件中,脚本做成通用模板的形式,在启动前,启动脚本会根据备注名称修改配置文件的upnp端口 然后再启动natmap
natmap启动后 -e脚本会获取到-b端口 然后脚本去配置文件读取这个端口的配置信息,加载完信息后开始打开路由upnp 修改对应的transmission端口。以及更新域名信息啥的

我也比较倾向于针对特定需求定制natmap的启动器(脚本),关于多个模板脚本之间的关联以及natmap的是否启动,在启动器中都可以维护状态标识来判断的。

我已经决定好,修改我配置文件 和 脚本模板的全部结构
循环检测的结构也修改了, 这样就可以提前打开upnp了