1SLIRP4NETNS(1) User Commands SLIRP4NETNS(1)
2
3
4
6 slirp4netns - User-mode networking for unprivileged network namespaces
7
8
9
11 slirp4netns [OPTION]... PID|PATH TAPNAME
12
13
14
16 slirp4netns provides user-mode networking ("slirp") for network name‐
17 spaces.
18
19
20 Unlike veth(4), slirp4netns does not require the root privileges on the
21 host.
22
23
24 Default configuration:
25
26
27 • MTU: 1500
28
29 • CIDR: 10.0.2.0/24
30
31 • Gateway/Host: 10.0.2.2 (network address + 2)
32
33 • DNS: 10.0.2.3 (network address + 3)
34
35 • IPv6 CIDR: fd00::/64
36
37 • IPv6 Gateway/Host: fd00::2
38
39 • IPv6 DNS: fd00::3
40
41
42
43
45 -c, --configure bring up the TAP interface. IP will be set to
46 10.0.2.100 (network address + 100) by default. IPv6 will be set to a
47 random address. Starting with v0.4.0, the loopback interface (lo) is
48 brought up as well.
49
50
51 -e, --exit-fd=FD specify the FD for terminating slirp4netns. When the
52 FD is specified, slirp4netns exits when a poll(2) event happens on the
53 FD.
54
55
56 -r, --ready-fd=FD specify the FD to write to when the initialization
57 steps are finished. When the FD is specified, slirp4netns writes "1"
58 to the FD and close the FD. Prior to v0.4.0, the FD was written after
59 the network configuration (-c) but before the API socket configuration
60 (-a).
61
62
63 -m, --mtu=MTU (since v0.2.0) specify MTU (max=65521).
64
65
66 -6, --enable-ipv6 (since v0.2.0, EXPERIMENTAL) enable IPv6
67
68
69 -a, --api-socket (since v0.3.0) API socket path
70
71
72 --cidr (since v0.3.0) specify CIDR, e.g. 10.0.2.0/24
73
74
75 --disable-host-loopback (since v0.3.0) prohibit connecting to
76 127.0.0.1:* on the host namespace
77
78
79 --netns-type=TYPE (since v0.4.0) specify network namespace type
80 ([path|pid], default=pid)
81
82
83 --userns-path=PATH (since v0.4.0) specify user namespace path
84
85
86 --enable-sandbox (since v0.4.0) enter the user namespace and create a
87 new mount namespace where only /etc and /run are mounted from the host.
88
89
90 Requires /etc/resolv.conf not to be a symlink to a file outside /etc
91 and /run.
92
93
94 When running as the root, the process does not enter the user namespace
95 but all the capabilities except CAP_NET_BIND_SERVICE are dropped.
96
97
98 --enable-seccomp (since v0.4.0, EXPERIMENTAL) enable seccomp(2) to
99 limit syscalls. Typically used in conjunction with --enable-sandbox.
100
101
102 --outbound-addr=IPv4 (since v1.1.0, EXPERIMENTAL) specify outbound ipv4
103 address slirp should bind to
104
105
106 --outbound-addr=INTERFACE (since v1.1.0, EXPERIMENTAL) specify outbound
107 interface slirp should bind to (ipv4 traffic only)
108
109
110 --outbound-addr=IPv6 (since v1.1.0, EXPERIMENTAL) specify outbound ipv6
111 address slirp should bind to
112
113
114 --outbound-addr6=INTERFACE (since v1.1.0, EXPERIMENTAL) specify out‐
115 bound interface slirp should bind to (ipv6 traffic only)
116
117
118 --disable-dns (since v1.1.0) disable built-in DNS (10.0.2.3 by default)
119
120
121 -h, --help (since v0.2.0) show help and exit
122
123
124 -v, --version (since v0.2.0) show version and exit
125
126
127
129 Terminal 1: Create user/network/mount namespaces
130
131
132 (host)$ unshare --user --map-root-user --net --mount
133 (namespace)$ echo $$ > /tmp/pid
134
135
136
137 In this documentation, we use (host)$ as the prompt of the host shell,
138 (namespace)$ as the prompt of the shell running in the namespaces.
139
140
141 If unshare fails, try the following commands (known to be needed on De‐
142 bian, Arch, and old CentOS 7.X):
143
144
145 (host)$ sudo sh -c 'echo "user.max_user_namespaces=28633" >> /etc/sysctl.d/userns.conf'
146 (host)$ if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then sudo sh -c 'echo "kernel.unprivileged_userns_clone=1" >> /etc/sysctl.d/userns.conf'; fi
147 (host)$ sudo sysctl --system
148
149
150
151 Terminal 2: Start slirp4netns
152
153
154 (host)$ slirp4netns --configure --mtu=65520 $(cat /tmp/pid) tap0
155 starting slirp, MTU=65520
156
157
158
159 Terminal 1: Make sure tap0 is configured and connected to the Internet
160
161
162 (namespace)$ ip a
163 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
164 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
165 3: tap0: <BROADCAST,UP,LOWER_UP> mtu 65520 qdisc fq_codel state UNKNOWN group default qlen 1000
166 link/ether c2:28:0c:0e:29:06 brd ff:ff:ff:ff:ff:ff
167 inet 10.0.2.100/24 brd 10.0.2.255 scope global tap0
168 valid_lft forever preferred_lft forever
169 inet6 fe80::c028:cff:fe0e:2906/64 scope link
170 valid_lft forever preferred_lft forever
171 (namespace)$ echo "nameserver 10.0.2.3" > /tmp/resolv.conf
172 (namespace)$ mount --bind /tmp/resolv.conf /etc/resolv.conf
173 (namespace)$ curl https://example.com
174
175
176
177 Bind-mounting /etc/resolv.conf is only needed when /etc/resolv.conf on
178 the host refers to loopback addresses (127.0.0.X, typically dnsmasq(8)
179 or systemd-resolved.service(8)) that cannot be accessed from the name‐
180 space.
181
182
183 If your /etc/resolv.conf on the host is managed by networkmanager(8) or
184 systemd-resolved.service(8), you might need to mount a new filesystem
185 on /etc instead, so as to prevent the new /etc/resolv.conf from being
186 unmounted unexpectedly when /etc/resolv.conf on the host is regener‐
187 ated.
188
189
190 (namespace)$ mkdir /tmp/a /tmp/b
191 (namespace)$ mount --rbind /etc /tmp/a
192 (namespace)$ mount --rbind /tmp/b /etc
193 (namespace)$ mkdir /etc/.ro
194 (namespace)$ mount --move /tmp/a /etc/.ro
195 (namespace)$ cd /etc
196 (namespace)$ for f in .ro/*; do ln -s $f $(basename $f); done
197 (namespace)$ rm resolv.conf
198 (namespace)$ echo "nameserver 10.0.2.3" > resolv.conf
199 (namespace)$ curl https://example.com
200
201
202
203 These steps can be simplified with rootlesskit --copy-up=/etc if root‐
204 lesskit is installed:
205
206
207 (host)$ rootlesskit --net=slirp4netns --copy-up=/etc bash
208 (namespace)$ cat /etc/resolv.conf
209 nameserver 10.0.2.3
210
211
212
213
215 To route ping packets, you may need to set up net.ipv4.ping_group_range
216 properly as the root.
217
218
219 e.g.
220
221
222 (host)$ sudo sh -c 'echo "net.ipv4.ping_group_range=0 2147483647" > /etc/sysctl.d/ping_group_range.conf'
223 (host)$ sudo sysctl --system
224
225
226
227
229 By default, ports listening on INADDR_LOOPBACK (127.0.0.1) on the host
230 are accessible from the child namespace via the gateway (default:
231 10.0.2.2). --disable-host-loopback can be used to prohibit connecting
232 to INADDR_LOOPBACK on the host.
233
234
235 However, a host loopback address might be still accessible via the
236 built-in DNS (default: 10.0.2.3) if /etc/resolv.conf on the host refers
237 to a loopback address. You may want to set up iptables for limiting
238 access to the built-in DNS in such a case.
239
240
241 (host)$ nsenter -t $(cat /tmp/pid) -U -n
242 (namespace)$ iptables -A OUTPUT -d 10.0.2.3 -p udp --dport 53 -j ACCEPT
243 (namespace)$ iptables -A OUTPUT -d 10.0.2.3 -j DROP
244
245
246
247
249 slirp4netns can provide QMP-like API server over an UNIX socket file:
250
251
252 (host)$ slirp4netns --api-socket /tmp/slirp4netns.sock ...
253
254
255
256 add_hostfwd: Expose a port (IPv4 only)
257
258
259 (namespace)$ json='{"execute": "add_hostfwd", "arguments": {"proto": "tcp", "host_addr": "0.0.0.0", "host_port": 8080, "guest_addr": "10.0.2.100", "guest_port": 80}}'
260 (namespace)$ echo -n $json | nc -U /tmp/slirp4netns.sock
261 {"return": {"id": 42}}
262
263
264
265 If host_addr is not specified, then it defaults to "0.0.0.0".
266
267
268 If guest_addr is not specified, then it will be set to the default ad‐
269 dress that corresponds to --configure.
270
271
272 list_hostfwd: List exposed ports
273
274
275 (namespace)$ json='{"execute": "list_hostfwd"}'
276 (namespace)$ echo -n $json | nc -U /tmp/slirp4netns.sock
277 {"return": {"entries": [{"id": 42, "proto": "tcp", "host_addr": "0.0.0.0", "host_port": 8080, "guest_addr": "10.0.2.100", "guest_port": 80}]}}
278
279
280
281 remove_hostfwd: Remove an exposed port
282
283
284 (namespace)$ json='{"execute": "remove_hostfwd", "arguments": {"id": 42}}'
285 (namespace)$ echo -n $json | nc -U /tmp/slirp4netns.sock
286 {"return": {}}
287
288
289
290 Remarks:
291
292
293 • Client needs to shutdown(2) the socket with SHUT_WR after
294 sending every request. i.e. No support for keep-alive and
295 timeout.
296
297 • slirp4netns "stops the world" during processing API requests.
298
299 • A request must be less than 4096 bytes.
300
301 • JSON responses may contain error instead of return.
302
303
304
305
307 A user can define a network namespace path as opposed to the default
308 process ID:
309
310
311 (host)$ slirp4netns --netns-type=path ... /path/to/netns tap0
312
313
314
315 Currently, the netns-type=TYPE argument supports path or pid args with
316 the default being pid.
317
318
319 Additionally, a --userns-path=PATH argument can be included to override
320 any user namespace path defaults
321
322
323 (host)$ slirp4netns --netns-type=path --userns-path=/path/to/userns /path/to/netns tap0
324
325
326
327
329 A user can defined preferred outbound ipv4 and ipv6 address in multi IP
330 scenarios.
331
332
333 (host)$ slirp4netns --outbound-addr=10.2.2.10 --outbound-addr6=fe80::10 ...
334
335
336
337 Optionally you can use interface names instead of ip addresses.
338
339
340 (host)$ slirp4netns --outbound-addr=eth0 --outbound-addr6=eth0 ...
341
342
343
344
346 The easiest way to allow inter-namespace communication is to nest net‐
347 work namespaces inside the slirp4netns's network namespace.
348
349
350 (host)$ nsenter -t $(cat /tmp/pid) -U -n -m
351 (namespace)$ mount -t tmpfs none /run
352 (namespace)$ ip netns add foo
353 (namespace)$ ip netns add bar
354 (namespace)$ ip link add veth-foo type veth peer name veth-bar
355 (namespace)$ ip link set veth-foo netns foo
356 (namespace)$ ip link set veth-bar netns bar
357 (namespace)$ ip netns exec foo ip link set veth-foo name eth0
358 (namespace)$ ip netns exec bar ip link set veth-bar name eth0
359 (namespace)$ ip netns exec foo ip link set lo up
360 (namespace)$ ip netns exec bar ip link set lo up
361 (namespace)$ ip netns exec foo ip link set eth0 up
362 (namespace)$ ip netns exec bar ip link set eth0 up
363 (namespace)$ ip netns exec foo ip addr add 192.168.42.100/24 dev eth0
364 (namespace)$ ip netns exec bar ip addr add 192.168.42.101/24 dev eth0
365 (namespace)$ ip netns exec bar ping 192.168.42.100
366
367
368
369 However, this method does not work when you want to allow communication
370 across multiple slirp4netns instances. To allow communication across
371 multiple slirp4netns instances, you need to combine another network
372 stack such as vde_plug(1) with slirp4netns.
373
374
375 (host)$ vde_plug --daemon switch:///tmp/switch null://
376 (host)$ nsenter -t $(cat /tmp/pid-instance0) -U -n
377 (namespace-instance0)$ vde_plug --daemon vde:///tmp/switch tap://vde
378 (namespace-instance0)$ ip link set vde up
379 (namespace-instance0)$ ip addr add 192.168.42.100/24 dev vde
380 (namespace-instance0)$ exit
381 (host)$ nsenter -t $(cat /tmp/pid-instance1) -U -n
382 (namespace-instance1)$ vde_plug --daemon vde:///tmp/switch tap://vde
383 (namespace-instance1)$ ip link set vde up
384 (namespace-instance1)$ ip addr add 192.168.42.101/24 dev vde
385 (namespace-instance1)$ ping 192.168.42.100
386
387
388
389
391 VXLAN is known to work. See Usernetes project for the example of
392 multi-node rootless Kubernetes cluster with VXLAN:
393 https://github.com/rootless-containers/usernetes
394
395
396
398 Kernel 4.20 bumped up the default value of /proc/sys/net/ipv4/tcp_rmem
399 from 87380 to 131072. This is known to slow down slirp4netns port for‐
400 warding: https://github.com/rootless-containers/slirp4netns/issues/128.
401
402
403 As a workaround, you can adjust the value of
404 /proc/sys/net/ipv4/tcp_rmem inside the namespace. No real root privi‐
405 lege is needed to modify the file since kernel 4.15.
406
407
408 (host)$ nsenter -t $(cat /tmp/pid) -U -n -m
409 (namespace)$ c=$(cat /proc/sys/net/ipv4/tcp_rmem); echo $c | sed -e s/131072/87380/g > /proc/sys/net/ipv4/tcp_rmem
410
411
412
413
415 network_namespaces(7), user_namespaces(7), veth(4)
416
417
418
420 The slirp4netns command is available from https://github.com/root‐
421 less-containers/slirp4netns under GNU GENERAL PUBLIC LICENSE Version 2
422 (or later).
423
424
425
426Rootless Containers November 2020 SLIRP4NETNS(1)