UPNP device not found!

(您搜索到这个,自然是遇到了类似的问题,自然是知道upnp是什么,所以我不介绍它了)

我使用的环境是:
        windows10 + openwrt-19.07 + miniupnpd-2.2.1

前言:
        我一开始使用的是miniupnpd-2.1.2019,使用这个版本时,是可以成功内网穿透的,换成2.2.1版本后,失效了,搜索过很多,基本都是降miniupnpd的版本,因为某些原因,我又必须得使用2.2.1,所以,研究了一下,有点点小收获,分享给同样陷入迷茫的你。


1. 抓包发现,只有电脑的M-Search数据包,没有路由器发出来的"notify"组播包
        解决方案:
 mcpd配置中添加:

igmp-mcast-snoop-exceptions 224.0.255.135/255.255.255.255 239.255.255.250/255.255.255.255

igmp-snooping-interfaces br-lan

可以"ps | grep mcpd" 或者查看"/etc/init.d/mcpd"文件,看看mcpd的配置文件是谁

如果添加后还是不起作用,可以看看
 ipv4 多播转发功能是否在所有网络接口上启用
查看方式:

 sysctl net.ipv4 | grep mc_forwarding

理论上,"net.ipv4.conf.all.mc_forwarding"和“net.ipv4.conf.br-lan.mc_forwarding”是要打开的
 

2. 调用/etc/miniupnpd/iptscript.sh 失败
​https://miniupnp.tuxfamily.org/files/
win10用上面的网站,下载下面的upnpc,解压并把它加入电脑的环境变量中

win + r ,cmd下输入下面的指令

 upnpc-shared.exe -l          #查看已经添加的端口映射
 upnpc-shared.exe -a 192.168.1.200 1234 5678 TCP     #添加规则(通过wan口的5678端口可以访问lan口1.200 ip的1234端口)

        -a: 添加  (-D是删除)
        192.168.1.200 : pc的ip
        1234 : pc的内部端口
        5678 : 外部端口


这里有个小注意:
1. 使用 upnpc-shared.exe这种方式,最好断开pc的其他网线
2. 使用 upnpc-shared.exe这种方式,需要设置任意外网ip
    uci set upnpd.config.external_ip='任意一个外网的ip'
    uci commit
    然后重启miniupnpd


为什么需要外网ip,可以查看下面的网站的说明(反正我是看它加所以我加的)
​https://forum.openwrt.org/t/miniupnpd-problem-getexternalipaddress-error-unable-to-add-forward-rule/61008

打开miniupnpd的调试(加 ‘-d’ )可以看到,port是被允许的,但是iptscript.sh这个脚本调用失败

解决方案:
         iptscript.sh这个脚本来自于“opensync”的core里面,也可以自己编辑一个,大致的内容是用于实现iptables规则的

                 win10 执行这个:  upnpc-shared.exe -a 192.168.1.200 1234 5678 TCP 
                与之对应要在 iptscript.sh下实现:

iptables -t nat  -A MINIUPNPD -p tcp -m tcp --dport 5678 -j DNAT --to-destination 192.168.1.200:1234

iptables -t nat  -A MINIUPNPD-POSTROUTING -s 192.168.1.200/32 -p tcp -m tcp --sport 1234 -j MASQUERADE --to-ports 5678


3. 实现了 iptscript.sh脚本后,你会发现,手动执行上面的两条iptables规则,是可以映射了,但,miniupnpd实现不了
win 10 执行  
upnpc-shared.exe -a 192.168.1.200 1234 5678 TCP
miniupnpd的log里面有如下内容:

 我在iptscript.sh里面加入“id”命令,确定它是root权限执行
miniupnpd调用iptscript.sh也很简单

int iptscript_exec_a(const char * const argv[])
{
    int status;

    pid_t cpid = fork();

    if (cpid != 0)  
    {
        if (waitpid(cpid, &status, 0) != cpid || !WIFEXITED(status))
        {
            return -1;
        }

        return WEXITSTATUS(status);
    }

    execvp(IPTSCRIPT_PATH, (char * const *)argv);

    syslog(LOG_ERR, "Error executing: %s %s", IPTSCRIPT_PATH, argv[1]);

    return 0;
};

fork创建子进程后,通过execvp去替换子进程,miniupnpd是root权限运行,调用iptscript.sh脚本应该也是root权限,事实上我加入“id”命令也确认iptscript.sh脚本是root权限,甚至我在“iptscript.sh”脚本里加了20秒延迟,ps查看iptscript.sh的运行状态也能看到是root权限。
咋会这样?

遍历了下代码,可以看到有个capability机制在降权
把这部分内容屏蔽或者在
capng_updatev里加入适量的权限,就可以解决了


4. 来到这一步,使用win 10的upnpc,是可以内网穿透了
        但,“网络邻居”里面的upnp设备,应该有个“常规”->“设置”的页面可以添加端口的
        目前卡在这里,它没有这个页面,后来人如果有能力,可以试着去解决这个问题



最后附上:
win7/10 是不support  IGDv2的,去网页里把它关闭掉IGDv2,勾选下面的框让它运行IGDv1



其次,你也可以试着关闭Makefile里面的"--iptscript"
因为我这边是要运行opensync,需要用到“--iptscript”
开了它以至于才有上面的一系列的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值