openwrt l2tp支持设置本地静态ip地址

发布时间 2023-11-17 17:04:10作者: thammer

设备使用4G网络,设备间需要通讯,又是短连接,必须要是静态ip,所以选择使用l2tp。然后LNS端通过/etc/ppp/chap-secrets为每个帐号绑定一个ip,每个设备使用一个帐号,LNS这端设备默认的隧道保活时间为60s。这时设备端(LAC)正常拨号时获取到的ip为LNS端绑定的,但是如果插拔一下网线,或者断电重启,即保活周期内未明确告知LNS端隧道断开,会导致LAC端拿到的IP不是LNS上绑定的那个,因此会导致设备间的短连接通讯会失败。

网络工程师告知可以通过在LAC端设置静态ip,来解决这个问题,并且在LNS端也不用麻烦的配置一堆的帐号和ip的绑定关系。分析l2tp网络建立的过程知道,隧道通了后会使用ppp来做接下来的工作,而ppp使用IPCP协议来协商网络参数,包括ip地址的分配,dns的分配等。既然是pppd在干活,那么肯定有参数设置,man pppd之,OPTIONS节第一个选项便是:

OPTIONS
       <local_IP_address>:<remote_IP_address>
              Set the local and/or remote interface IP addresses.  Either one may be omitted.  The IP addresses can be specified with a host  name  or  in  decimal  dot  notation  (e.g.
              150.234.56.78).   The default local address is the (first) IP address of the system (unless the noipdefault option is given).  The remote address will be obtained from the
              peer if not specified in any option.  Thus, in simple cases, this option is not required.  If a local and/or remote IP address is specified with this option, pppd will not
              accept a different value from the peer in the IPCP negotiation, unless the ipcp-accept-local and/or ipcp-accept-remote options are given, respectively.

      <本地ip地址>:<远程ip地址>
              设置本地/远程接口IP地址。这两个地址均可省略。IP地址可以指定为一个域名或者点分十进制格式(x.x.x.x)。默认的本地地址是系统网络接口的原本IP地址(即建立隧道的那个网络接口)(除非指定了noipdefault选项)。如果参      
              数里面远程ip地址未指定,则远程地址将从对端获取。因此,简单来说,此选项不是必须的(因为前面提到了local和remote都有默认值)。如果本地/远程IP地址通过此选项指定了,需要对应的设置`ipcp-accept-local`或者 
              `ipcp-accept-remote`选项,否则pppd将不会接受和对端IPCP协商的值。

按照这里的介绍,在/etc/ppp/options.xl2tpd里面配置即可,也可以通过/lib/netifd/proto/l2tp.sh脚本里面使用xl2tpd-config传参的方式实现。大致按照如下方式改动即可

+       local usestaticip localip
+       json_get_vars usestaticip  localip
+       [ "$usestaticip" = "1" ] && {
+               localaddr="${localip:+local ip=$localip}"
+       }
 
-       xl2tpd-control add l2tp-${interface} pppoptfile=${optfile} lns=${server} || {
+       xl2tpd-control add l2tp-${interface} pppoptfile=${optfile} lns=${server} ${localaddr} || {