什么是TAP/TUN设备的"目标地址"?

Jon*_*art 7 tun

TAP/TUN设备的"目标地址"的目的是什么?

Pytun可让您轻松设置tap/tun设备的参数:

tun = TapTunDevice(name='mytun')
tun.addr = '10.66.66.1'
tun.dstaddr = '10.66.66.2'
tun.netmask = '255.255.255.0'
tun.up()
Run Code Online (Sandbox Code Playgroud)

这样做会导致设备配置如下:

$ ifconfig mytun
mytun: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 10.66.66.1  netmask 255.255.255.0  destination 10.66.66.2
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
Run Code Online (Sandbox Code Playgroud)

我知道系统现在有一个IP 10.66.66.1的虚拟接口.并且可以推测,在这种情况下,TUN设备将"连接"到IP地址为10.66.66.2的(例如VPN网关)设备.

但具体是什么目的,内核是否知道这是一个"点对点"接口,以及目的地的IP地址?它是否会以某种方式影响路由,简单地配置路由表无法实现?


设置dstaddr属性会产生SIOCSIFDSTADDRioctl.

netdevice(7)手册页只是说:

  SIOCGIFDSTADDR, SIOCSIFDSTADDR
          Get or set the destination address of a point-to-point  device
          using  ifr_dstaddr.  For compatibility, only AF_INET addresses
          are accepted or returned.  Setting the destination address  is
          a privileged operation.
Run Code Online (Sandbox Code Playgroud)

ysd*_*sdx 8

我不关心这一切我想配置我的界面

您无需设置目标地址.如果要10.66.66.1/24在界面上进行配置,可以执行以下操作:

tun = TapTunDevice(name='mytun')
tun.addr = '10.66.66.1'
tun.netmask = '255.255.255.0'
tun.up()
Run Code Online (Sandbox Code Playgroud)

此接口仅连接两台主机,因此您实际上并不需要整体/24.你只能说10.66.66.1连接到10.66.66.2(10.66.66.1 peer 10.66.66.2):

tun = TapTunDevice(name='mytun')
tun.addr = '10.66.66.1'
tun.dstaddr = '10.66.66.2'
tun.netmask = '255.255.255.255'
tun.up()
Run Code Online (Sandbox Code Playgroud)

在此设置中,两个IP地址根本不需要在相同的范围内.

另外,您也可以使用/31,RFC3021:

tun = TapTunDevice(name='mytun')
tun.addr = '10.66.66.2'
tun.dstaddr = '10.66.66.3'
tun.netmask = '255.255.255.254'
tun.up()
Run Code Online (Sandbox Code Playgroud)

请注意,我必须如何更改IP地址才能使它们相同/31.

什么是POINTOPOINT设备?

POINTOPOINT意味着在此接口上此接口上没有第2层寻址(无MAC地址):

  • 没有ARP请求(IPv4);
  • 没有NDP请求(IPv6);
  • 邻居表对于这个接口是无用的(ip neighbour);
  • 在此接口的路由表条目中,该via指令被忽略;
  • 此接口上的数据包始终发送到相同(仅)的下一跳.

POINTOPOINT设备示例

  • PPP接口:PPP没有第2层地址,因为这种类型的接口将单个主机连接到另一个主机(因此称为"点对点协议")

  • TUN接口:它们是没有第2层的仅IP接口.

POINTOPOINT 意味着这是一个点对点接口(惊喜!),这意味着在接口的另一端只能连接一个对等体:你在这个接口上有一个邻居,你不需要使用ARP/NDP用于将IP地址映射到链路层地址(并且根本没有链路层地址).

相反,以太网设备不是点对点接口,因为可以通过此接口直接访问多个主机.当您向此类设备发送IP数据包时,网络堆栈必须为目标IP地址找到第2层标识符(使用ARP,NDP),并将消息发送到此链路层地址.

这样说,是您的路由表(在以太网中):

default via 192.0.2.1 dev eth0  proto static  metric 100
192.0.2.0/24 dev eth0 proto kernel  scope link  src 192.0.2.2 metric 100
Run Code Online (Sandbox Code Playgroud)

可以通过eth0接口直接连接多个主机.如果要将数据包发送到198.51.100.1,则选择此路由:

default via 192.0.2.1 dev eth0  proto static  metric 100
Run Code Online (Sandbox Code Playgroud)

这意味着在eth0设备上的所有邻居中,您必须将数据包发送到192.0.2.1.为此,您的网络堆栈必须使用ARP找到192.0.2.1的MAC地址.

PEERTOPEER设备上,总是只有一个邻居,所以你不需要做ARP,你只需要发送数据包.

TUN和PPP接口是POINTOPOINT设备.以太网,以太网TAP设备和Wifi接口不是POINTOPOINT.

什么是目的地(同行)地址?

通常接口的IP配置形式如下:192.0.2.1/24.这意味着此接口的IP地址是,192.0.2.1并且192.0.2.0/24子网中的所有IP 都可以通过此接口直接访问:这会添加路由规则192.0.2.0/24 dev tun0.

当本地IP地址和对等地址不属于同一IP子网时,Linux内核支持另一种配置:192.0.2.1 peer 198.51.100.1.这意味着此接口192.0.2.1的IP地址是,并且对等体的IP地址是198.51.100.1:这会添加路由规则198.51.100.1 dev tun0.可以使用更通用的形式:192.0.2.1 peer 198.51.100.1/24.

$ ip address show tun0
14: tun0:  mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 192.0.2.1 198.51.100.1/24 scope global tun0
       valid_lft forever preferred_lft forever

dstaddr参数(和SIOCSIFDSTADDR)可以被用来设置诸如目标地址.

如果您不想为两个对等体分配公共子网,这将非常有用.您不必使用具有点对点接口的特殊目标地址.您可以使用标准IP子网.或者你可以分配一个/ 31.使用目标地址/ peer配置,可以避免为此点对点链接分配子网.

对等/目标地址与POINTOPOINT设备之间的关系是什么?

这些都是独立的.您没有在POINTOPOINT界面上设置目标地址.您可以在a上设置目标地址POINTOPOINT,也可以在普通地址上设置.

但是,使用对等目标地址对于POINTOPOINT接口尤其有用.

  • @horseguy:在顶部添加了一个TLDR. (2认同)