TAP/TUN 设备的 "destination address" 是什么?
What is the "destination address" for a TAP/TUN device?
"destination address" 用于 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()
这样做会导致设备配置如下:
$ 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
我了解到系统现在有一个 IP 为 10.66.66.1 的虚拟接口。并且可以推测在这种情况下,TUN 设备将 "connected" 到 IP 地址为 10.66.66.2 的(例如 VPN 网关)设备。
但是具体的目的是什么,是为了让内核知道这是一个"point-to-point"接口,以及目的地的IP地址吗?它是否会以某种方式影响路由,而仅配置路由 table 无法实现?
设置 dstaddr
属性 会导致 SIOCSIFDSTADDR
ioctl。
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.
如果你添加一个接口
inet 10.66.66.1 netmask 255.255.255.0
无论您是否将其创建为点对点 - 新的路由条目都将添加到 10.66.66.1/24 的内核中,并带有新接口的目的地。
所以我不认为那里有区别。
我不关心这一切我想配置我的界面
您不需要设置目标地址。如果你想在接口上配置10.66.66.1/24
,你可以这样做:
tun = TapTunDevice(name='mytun')
tun.addr = '10.66.66.1'
tun.netmask = '255.255.255.0'
tun.up()
这个接口只连接两台主机,所以你实际上并不需要整个/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()
在此设置中,两个 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()
请注意,我必须如何更改 IP 地址才能使它们位于同一 /31
。
什么是 POINTOPOINT
设备?
POINTOPOINT
表示在这个接口上没有第2层寻址(没有MAC地址):
- 无 ARP 请求 (IPv4);
- 没有 NDP 请求 (IPv6);
- 邻居table对该接口无用(
ip neighbour
);
- 在此接口的路由 table 条目中,
via
指令被忽略;
- 此接口上的数据包始终发送到相同的(仅)下一跳。
POINTOPOINT
个设备的示例
PPP 接口:PPP 没有第 2 层地址,因为这种类型的接口将一台主机连接到另一台主机(因此得名“点对点协议”)
TUN 接口:它们是没有第 2 层的纯 IP 接口。
POINTOPOINT
表示这是一个点对点接口(惊喜!),这意味着接口的另一侧只能连接一个对等点:您在这个接口上有一个邻居接口,您不需要使用 ARP/NDP 将 IP 地址映射到 link 层地址(并且您根本没有 link 层地址)。
相比之下,以太网设备不是点对点接口,因为可以通过此接口直接访问多个主机。当您向此类设备发送 IP 数据包时,网络堆栈必须为预期的 IP 地址找到第 2 层标识符(使用 ARP、NDP)并将消息发送到此 link 层地址。
这么说,你的路由是table(在以太网中):
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
多台主机可以通过eth0接口直接连接到你。如果要发包到198.51.100.1,选择这条路由:
default via 192.0.2.1 dev eth0 proto static metric 100
这意味着在eth0
设备上的所有邻居中,您必须将数据包发送到192.0.2.1。为此,您的网络堆栈必须使用 ARP 找到 192.0.2.1 的 MAC 地址。
在POINTOPOINT
设备上,总是只有一个邻居,所以你不需要做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
。这意味着这个接口的IP地址是192.0.2.1
,对端的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 子网。或者您可以分配 a /31。使用目标地址/peer
配置,可以避免为这种点对点分配子网link.
peer/destination地址和POINTOPOINT
设备有什么关系?
这些是独立的。您没有在 POINTOPOINT
接口上设置目标地址。您可以在 POINTOPOINT
上设置目标地址,也可以在普通地址上设置。
但是,使用对等目标地址 especially/mostly 对于 POINTOPOINT
接口很有用。
"destination address" 用于 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()
这样做会导致设备配置如下:
$ 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
我了解到系统现在有一个 IP 为 10.66.66.1 的虚拟接口。并且可以推测在这种情况下,TUN 设备将 "connected" 到 IP 地址为 10.66.66.2 的(例如 VPN 网关)设备。
但是具体的目的是什么,是为了让内核知道这是一个"point-to-point"接口,以及目的地的IP地址吗?它是否会以某种方式影响路由,而仅配置路由 table 无法实现?
设置 dstaddr
属性 会导致 SIOCSIFDSTADDR
ioctl。
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.
如果你添加一个接口
inet 10.66.66.1 netmask 255.255.255.0
无论您是否将其创建为点对点 - 新的路由条目都将添加到 10.66.66.1/24 的内核中,并带有新接口的目的地。
所以我不认为那里有区别。
我不关心这一切我想配置我的界面
您不需要设置目标地址。如果你想在接口上配置10.66.66.1/24
,你可以这样做:
tun = TapTunDevice(name='mytun')
tun.addr = '10.66.66.1'
tun.netmask = '255.255.255.0'
tun.up()
这个接口只连接两台主机,所以你实际上并不需要整个/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()
在此设置中,两个 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()
请注意,我必须如何更改 IP 地址才能使它们位于同一 /31
。
什么是 POINTOPOINT
设备?
POINTOPOINT
表示在这个接口上没有第2层寻址(没有MAC地址):
- 无 ARP 请求 (IPv4);
- 没有 NDP 请求 (IPv6);
- 邻居table对该接口无用(
ip neighbour
); - 在此接口的路由 table 条目中,
via
指令被忽略; - 此接口上的数据包始终发送到相同的(仅)下一跳。
POINTOPOINT
个设备的示例
PPP 接口:PPP 没有第 2 层地址,因为这种类型的接口将一台主机连接到另一台主机(因此得名“点对点协议”)
TUN 接口:它们是没有第 2 层的纯 IP 接口。
POINTOPOINT
表示这是一个点对点接口(惊喜!),这意味着接口的另一侧只能连接一个对等点:您在这个接口上有一个邻居接口,您不需要使用 ARP/NDP 将 IP 地址映射到 link 层地址(并且您根本没有 link 层地址)。
相比之下,以太网设备不是点对点接口,因为可以通过此接口直接访问多个主机。当您向此类设备发送 IP 数据包时,网络堆栈必须为预期的 IP 地址找到第 2 层标识符(使用 ARP、NDP)并将消息发送到此 link 层地址。
这么说,你的路由是table(在以太网中):
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
多台主机可以通过eth0接口直接连接到你。如果要发包到198.51.100.1,选择这条路由:
default via 192.0.2.1 dev eth0 proto static metric 100
这意味着在eth0
设备上的所有邻居中,您必须将数据包发送到192.0.2.1。为此,您的网络堆栈必须使用 ARP 找到 192.0.2.1 的 MAC 地址。
在POINTOPOINT
设备上,总是只有一个邻居,所以你不需要做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
。这意味着这个接口的IP地址是192.0.2.1
,对端的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 子网。或者您可以分配 a /31。使用目标地址/peer
配置,可以避免为这种点对点分配子网link.
peer/destination地址和POINTOPOINT
设备有什么关系?
这些是独立的。您没有在 POINTOPOINT
接口上设置目标地址。您可以在 POINTOPOINT
上设置目标地址,也可以在普通地址上设置。
但是,使用对等目标地址 especially/mostly 对于 POINTOPOINT
接口很有用。