TCP 在 Debian 上监听任意 IPv6 块

TCP 在 Debian 上监听任意 IPv6 块

我有一个 /64 的 IPv6 地址块,我想能够启动一个 TCP 服务器来监听其中任何一个地址。目前我可以绑定到任何静态 IP 地址,但不能绑定到其他地址。如果我尝试绑定到非静态路由的地址(顺便说一句,我不确定我使用的术语是否正确),我会收到一条错误消息“绑定:无法分配请求的地址”。

以下是 ifconfig 的内容:

eth0      Link encap:Ethernet  HWaddr 56:00:00:60:af:c6
          inet addr:104.238.191.172  Bcast:104.238.191.255  Mask:255.255.254.0
          inet6 addr: fe80::5400:ff:fe60:afc6/64 Scope:Link
          inet6 addr: 2001:19f0:6801:187:5400:ff:fe60:afc6/64 Scope:Global
          inet6 addr: 2001:19f0:6801:187:ea1e:eb99:13ae:d49a/128 Scope:Global
          UP BROADCAST RUNNING ALLMULTI MULTICAST  MTU:1500  Metric:1
          RX packets:1526389 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1622562 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:280302410 (267.3 MiB)  TX bytes:266740313 (254.3 MiB)

如果我尝试绑定到例如 2001:19f0:6801:187:a:b:c:d,它会失败并显示“绑定:无法分配请求的地址”。但如果我这样做ip -6 addr add dev eth0 2001:19f0:6801:187:a:b:c:d,那么我就可以启动侦听该 IP 地址的服务器。

如何配置 Linux,以便可以监听任何 2001:19f0:6801:187::/64 地址?也就是说,我想绑定到某个特定的 IP 地址,而不必先绑定到该 IP 地址ip addr add

或者我应该ip addr add在绑定之前给我的服务器一个地址,然后也许ip addr del在我完成的时候?

附录:如果我的问题不清楚,我已经走得足够远了,整个前缀都被路由到我的服务器,这样它就可以响应带有该前缀的任何地址的 ping。如果我在“[::]:80”上启动 TCP 监听,它将响应对任何 IP 地址的请求。我想要的是能够监听特定的 IP 地址,以便只有发送到该 IP 地址的请求才会到达服务器。与之相关的其他 ServerFault 问题询问如何让服务器响应对任何 IP 地址的请求。我已经走到这一步了。我希望能够绑定到任意地址,但只能绑定到一个特定的地址。问题是,如果特定地址没有静态分配给接口,Linux 甚至不允许我在特定地址上启动服务器,我想解决这个问题。

更具体地说,我现在可以在我的 VPS 的所有接口上运行 TCP 回显服务器:

ncat -l 2000 --keep-open --exec "/bin/cat"

然后从我的笔记本电脑,我可以使用任何随机 IPv6 地址连接到它:

telnet 2001:19f0:6801:187:: 2000
telnet 2001:19f0:6801:187:abc:def:: 2000
telnet 2001:19f0:6801:187:abc:def:123:0 2000

这一切都有效。如果我在静态分配的地址上启动服务器,它也会有效:

ncat -l 2001:19f0:6801:187:5400:ff:fe60:afc6 2000 --keep-open --exec "/bin/cat"

现在我只能连接到那个特定的 IP 地址。到目前为止一切顺利。

现在我希望能够在某个随机地址上启动服务器:

ncat -l 2001:19f0:6801:187:abc:123:: 2000 --keep-open --exec "/bin/cat"

但是我收到一个错误:“Ncat:绑定到 2001:19f0:6801:187:abc:123:::2000:无法分配请求的地址。退出。”但是如果我ip -6 addr add dev eth0 2001:19f0:6801:187:abc:123::/64,那么前面的 ncat 命令有效,并且服务器启动并且仅响应到 2001:19f0:6801:187:abc:123::的连接。

那么我可以配置 Linux 让我在我的块中的任意地址上启动服务器,而无需先将其添加为静态地址吗?

(实际上,我的问题非常类似于https://stackoverflow.com/questions/40198619/can-docker-automatically-add-ip-addresses-to-the-host-upon-running-container,尽管他们谈论的是 IPv4。答案是静态添加所有地址。)

答案1

您要求的功能似乎不存在ncat,因此您可能必须下载源代码并自行添加。

我验证该功能是否存在的方法如下(在 Ubuntu 16.04 上进行,因为它最接近我可以立即访问的 Debian 系统)。首先,我尝试输入命令来查看它是否安装在我的系统上:

$ ncat
The program 'ncat' is currently not installed. You can install it by typing:
sudo apt install nmap

因此它尚未安装,但在包中可用nmap。因此我继续下载源代码:

$ apt-get source nmap

然后我查看该源代码中是否在任何地方使用了IP_FREEBIND或:IP_TRANSPARENT

$ find nmap-7.01 -type f -print0 | xargs -0 grep -l 'IP_FREEBIND\|IP_TRANSPARENT'

看起来情况并非如此。所以下一个问题是我们应该在源代码的哪个位置添加它。

$ grep bind nmap-7.01/ncat/*c
nmap-7.01/ncat/ncat_connect.c:    /* TODO just two bytes for now, need to read more for bind */
nmap-7.01/ncat/ncat_main.c:            bye("-l and -s are incompatible.  Specify the address and port to bind to like you would a host to connect to.");
nmap-7.01/ncat/ncat_main.c:        /* Try to bind to IPv6 first; on AIX a bound IPv4 socket blocks an IPv6
nmap-7.01/ncat/util.c:        /* Tell it to not try and bind to IPV4 */
nmap-7.01/ncat/util.c:            die("Unable to set IPV6 socket to bind only to IPV6");
nmap-7.01/ncat/util.c:    if (bind(sock, &srcaddr_u->sockaddr, sa_len) < 0) {
nmap-7.01/ncat/util.c:            bye("bind to %s: %s.", srcaddr_u->un.sun_path,
nmap-7.01/ncat/util.c:            bye("bind to %s:%hu: %s.", inet_socktop(srcaddr_u),
nmap-7.01/ncat/util.c:        if (bind(sock, &srcaddr.sockaddr, sa_len) < 0) {
nmap-7.01/ncat/util.c:            bye("bind to %s:%hu: %s.", inet_socktop(&srcaddr),

bind函数从内部的两个地方调用,在其中一个位置(或两个位置)util.c设置应该可以满足您的需要。IP_FREEBIND

相关内容