我正在使用网络命名空间,以便我可以捕获单个进程的网络流量。命名空间通过 veth 对通过“主机”连接,并通过 NAT 进行网络连接。到目前为止,这适用于 IP 流量和命名的 Unix 域套接字。
当程序需要与 D-Bus 会话总线通信时,就会出现问题。D-Bus 守护进程侦听此环境变量指定的抽象套接字:
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-jIB6oAy5ea,guid=04506c9a7f54e75c0b617a6c54e9b63a
Run Code Online (Sandbox Code Playgroud)
看来抽象 Unix 域套接字命名空间在命名空间中是不同的。有没有办法从网络命名空间访问这个 D-Bus 会话?
我正在运行 Linux。
我在 mount 命名空间中有一个进程。我在这个过程中做了一个mount -t tmpfs tmpfs /mountpoint.
如果进程退出并且该挂载命名空间中没有更多进程,会发生什么情况?文件系统会自动卸载吗?挂载命名空间会被破坏吗?如果命名空间和挂载仍然处于活动状态,我该如何访问它?
如果网络命名空间没有更多进程,tun/tap/macvtap 接口会发生什么?
网络命名空间(7)的 Linux 手册页说:
网络命名空间提供与网络相关的系统资源的隔离:[...]、/sys/class/net 目录、[...]。
但是,简单地切换到不同的网络命名空间似乎不会改变/sys/class/net(有关如何重现,请参见下文)的内容。我只是误以为setns()进入网络命名空间已经足够了吗?是否总是需要重新挂载/sys才能正确/sys/class/net匹配当前加入的网络命名空间?还是我在这里错过了其他东西?
拿一个*ubuntu系统,找到rtkit-daemon的PID,进入daemon的网络命名空间,显示它的网络接口,然后检查/sys/class/net:
$ PID=`sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2`
$ sudo nsenter -t $PID -n
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ls /sys/class/net
docker0 enp3s0 lo lxcbr0 ...
Run Code Online (Sandbox Code Playgroud)
请注意,虽然ip link show …
是否有一个(简单的)命令可以创建一个 veth 接口对并将每个接口分配给不同的网络命名空间?
例如,假设我有两个命名空间:mynamespace-1和mynamespace-2. 是否有一个(简单的)命令可以通过一个接口的每个端点都被命名的 veth 对来连接这两个命名空间eth0?
目前我要做的是创建 veth 对,将每个接口移动到相应的命名空间,然后从该命名空间内重命名接口。我想知道这三个命令是否可以压缩成一个命令。
对于上下文,以下是我当前如何连接一对命名空间并测试连接的示例:
# Create two network namespaces
sudo ip netns add 'mynamespace-1'
sudo ip netns add 'mynamespace-2'
# Create a veth virtual-interface pair
sudo ip link add 'myns-1-eth0' type veth peer name 'myns-2-eth0'
# Assign the interfaces to the namespaces
sudo ip link set 'myns-1-eth0' netns 'mynamespace-1'
sudo ip link set 'myns-2-eth0' netns 'mynamespace-2'
# Change the names of the interfaces (I prefer to use …Run Code Online (Sandbox Code Playgroud) tl;dr Linux 有命名空间,特别是network namespaces. 似乎-n在运行时通过标志创建的命名空间在使用时systemd-nspwawn没有显示ip netns list(既不在主机中,也没有在假定创建的命名空间中)。它要么systemd-nspawn或ip netns不实际使用Linux的命名空间处理(这是我认为是这样的:https://lwn.net/Articles/531114/#series_index)?
长话短说:
我使用以下命令从我的 Arch Linux 中运行 Arch Linux 的“轻量级容器”:
systemd-nspawn -nbUD /mntpointArchLinuxSysFs
Run Code Online (Sandbox Code Playgroud)
数据/mntpointArchLinuxSysFs已被引导,并且“运行/启动”良好。man systemd-nspawn告诉我-noptions-flag 意味着:
-n,--network-veth
veth在主机和容器之间创建一个虚拟以太网链接(“ ”)。以太网链路的主机端将作为以容器名称(如 指定--machine=)命名的网络接口可用 ,前缀为“ve-”。以太网链路的容器端将命名为“host0”。该--network-veth选项意味着--private-network.
反过来,隐含--private-network的解释如下
--private-networkRun Code Online (Sandbox Code Playgroud)Disconnect networking of the container from the host. This makes all network interfaces unavailable in the container, …
假设我使用ip-link(8)创建一个接口 ,test-macvlan并为其分配地址10.11.12.13:
# ip link add link eno1 name test-macvlan type macvlan
# ip address add 10.11.12.13 dev test-macvlan
# ip address show test-macvlan
10: test-macvlan@eno1: <BROADCAST,MULTICAST> mtu 1500 ...
link/ether d2:f7:32:3f:c9:4a brd ff:ff:ff:ff:ff:ff
inet 10.11.12.13/32 scope global test-macvlan
Run Code Online (Sandbox Code Playgroud)
然后,我使用ip-netns(8)创建网络命名空间,test-netns并使用ip-link(8)将接口分配test-macvlan给新命名空间:
# ip netns add test-netns
# ip link set test-macvlan netns test-netns
# ip netns exec test-netns ip address show test-macvlan
10: test-macvlan@if2: <BROADCAST,MULTICAST> mtu 1500 …Run Code Online (Sandbox Code Playgroud) 我需要能够限制用户应用程序始终在特定的网络命名空间中运行。假设我之前已将网络配置设置为:
ip tuntap add name tap0 mode tap
ip link add veth0 type veth peer name veth1
ip netns add appns
ip link set dev tap0 netns appns
ip link set dev veth0 netns appns
ip netns exec appns ip addr add 10.0.0.254/24 dev tap0
ip netns exec appns ip link set dev tap0 up
ip netns exec appns ip addr add 10.20.30.1/24 dev veth0
ip netns exec appns iptables -t nat -A POSTROUTING -o veth0 -j SNAT --to 10.20.30.1 …Run Code Online (Sandbox Code Playgroud) 我有以下使用 linux 命名空间的网络拓扑:
.--------.veth0 .--------.veth2 .--------.
| ns_snd |------------| ns_mid |------------| ns_rcv |
'--------' veth1'--------' veth3'--------'
Run Code Online (Sandbox Code Playgroud)
veth0: 10.0.0.1/30
veth1: 10.0.0.2/30
veth2: 10.0.0.5/30
veth3: 10.0.0.6/30
veth0 属于 ns_snd,
veth[1,2] 属于 ns_mid,
veth3 属于 ns_rcv
命令是:
S1="veth0"
S2M1="veth1"
M2R1="veth2"
R1="veth3"
NS_SND="ns_snd"
NS_RCV="ns_rcv"
NS_MID="ns_mid"
#Remove existing namespace
sudo ip netns del $NS_SND
sudo ip netns del $NS_RCV
sudo ip netns del $NS_MID
#Remove existing veth pairs
sudo ip link del $S1
sudo ip link del $R1
sudo ip link del $S2M1
sudo ip …Run Code Online (Sandbox Code Playgroud) 我能够设置一个网络命名空间并启动一个在命名空间内侦听 127.0.0.1 的服务器:
# ip netns add vpn
# ip netns exec vpn ip link set dev lo up
# ip netns exec vpn nc -l -s 127.0.0.1 -p 80 &
# ip netns exec vpn netstat -tlpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN 5598/nc
Run Code Online (Sandbox Code Playgroud)
之后,我可以连接到命名空间内的服务器:
# ip netns exec vpn nc 127.0.0.1 80 -zv
localhost [127.0.0.1] 80 (http) open
Run Code Online (Sandbox Code Playgroud)
但是我无法连接到命名空间之外的服务器:
# nc 127.0.0.1 80 …Run Code Online (Sandbox Code Playgroud) 我有一个在网络命名空间中运行的应用程序。这效果很好。
我想在不同的命名空间中多次运行该应用程序。为了方便起见,我想将应用程序的工作目录绑定到命名空间内的 /tmp/nsX 之类的目录。
如果我只是mount --bind /tmp/nsX /var/lib/my-app在命名空间中执行此操作,那么当我退出命名空间时,挂载就会消失。
通过进入/退出命名空间,我的意思是ip netns exec bash
我正在看unshare,nsenter但我不知道该怎么做。
我想要:
如果我需要使用其他一些命名空间类型,那也没有问题。
namespace ×5
iproute ×3
linux ×3
networking ×3
d-bus ×1
iptables ×1
routing ×1
unix-sockets ×1
unshare ×1