我尝试了netstat
和lsof
,但似乎无法看到与我的 LXC 客人的连接。
有没有办法实现这一目标...全部马上来客人吗?
本质上,让我感到困惑的是,只要我以超级用户身份运行,我就可以看到来宾的进程。我还可以看到veth
为每个访客动态创建的界面。为什么我看不到原本可见的进程上的连接?
答案1
内核指示 等上的连接状态/proc/net/tcp
,/proc/net/udp
但由于命名空间将网络堆栈分开,如果应用程序在容器(不同的用户空间)内运行并连接到网络,主机/proc/net/tcp
将不会显示其连接,
conntrack
可用于显示整机连接但这不适用于某些接口,例如wireguard...
ip -all netns exec command
可用于在所有用户空间内运行命令但这仅限于使用ip
命令创建的用户空间。
从在容器上运行的应用程序的角度来看,其网络堆栈状态在该位置的主机上仍然可见,/proc/$pid/net/tcp
因此作为等待在 c 中编写适当工具的解决方法,我编写了一个小 bash 脚本,该脚本循环/proc/$pid/net/tcp[udp]
并连接所有状态能够列出整机连接。
该脚本首先连接所有内容/proc/$pid/net/tcp
或/proc/$pid/net/udp
对它们进行排序,删除重复项,将值转换为可读文本并打印它们(脚本需要find
, grep
, xargs
, awk
, strtonum
,sort
和uniq
)
对于TCP
find /proc/ 2>/dev/null | grep tcp | grep -v task | grep -v sys/net | xargs grep -v rem_address 2>/dev/null | awk '{x=strtonum("0x"substr($3,index($3,":")-2,2)); y=strtonum("0x"substr($4,index($4,":")-2,2)); for (i=5; i>0; i-=2) x = x"."strtonum("0x"substr($3,i,2)); for (i=5; i>0; i-=2) y = y"."strtonum("0x"substr($4,i,2))}{printf ("%s\t:%s\t ----> \t %s\t:%s\t%s\n",x,strtonum("0x"substr($3,index($3,":")+1,4)),y,strtonum("0x"substr($4,index($4,":")+1,4)),$1)}' | sort | uniq --check-chars=25
对于UDP
find /proc/ 2>/dev/null | grep udp | grep -v task | grep -v sys/net | xargs grep -v rem_address 2>/dev/null | awk '{x=strtonum("0x"substr($3,index($3,":")-2,2)); y=strtonum("0x"substr($4,index($4,":")-2,2)); for (i=5; i>0; i-=2) x = x"."strtonum("0x"substr($3,i,2)); for (i=5; i>0; i-=2) y = y"."strtonum("0x"substr($4,i,2))}{printf ("%s\t:%s\t ----> \t %s\t:%s\t%s\n",x,strtonum("0x"substr($3,index($3,":")+1,4)),y,strtonum("0x"substr($4,index($4,":")+1,4)),$1)}' | sort | uniq --check-chars=25
输出如下:(注意pid并不准确,仅用于识别容器)
127.0.0.1 :80 ----> 0.0.0.0 :0 /proc/10176/net/tcp:
192.168.0.2 :33882 ----> 192.30.253.125 :443 /proc/10176/net/tcp
192.168.0.2 :34020 ----> 192.30.253.125 :443 /proc/10176/net/tcp:
192.168.0.2 :34162 ----> 192.30.253.125 :443 /proc/10176/net/tcp:
192.168.0.2 :36242 ----> 192.30.253.124 :443 /proc/10176/net/tcp:
192.168.0.2 :37324 ----> 192.30.253.124 :443 /proc/10176/net/tcp:
192.168.0.2 :40122 ----> 216.239.38.21 :80 /proc/10176/net/tcp:
192.168.0.2 :40124 ----> 216.239.38.21 :80 /proc/10176/net/tcp:
我还发现了一个很棒的工具,可以使用一些非常有用的命令来管理命名空间nsutils
答案2
我认为https://stackoverflow.com/a/40352004/1951468应该回答你。
所以基本上,唯一的方法是围绕容器和 进行循环nsenter
。
答案3
我想你可以使用sudo conntrack -L
conntrack 是一个针对系统管理员的用户空间命令行程序。它使他们能够查看和管理内核内连接跟踪状态表。
如果未安装,所需的软件包是conntrack-tools
(在 Fedora 等上)或conntrack
(在 Debian、Ubuntu 等上)。
答案4
到目前为止,我很幸运通过从容器运行 netstat 来获得容器连接:
sudo docker exec -it <containerIdOrName> netstat
显然,容器需要安装它。