1SLIRP4NETNS(1)                   User Commands                  SLIRP4NETNS(1)
2
3
4

NAME

6       slirp4netns - User-mode networking for unprivileged network namespaces
7
8
9

SYNOPSIS

11       slirp4netns [OPTION]... PID|PATH [TAPNAME]
12
13
14

DESCRIPTION

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              • DHCP begin:        10.0.2.15   (network address + 15)
36
37              • DHCP end:          10.0.2.30   (network address + 30)
38
39              • IPv6 CIDR:         fd00::/64
40
41              • IPv6 Gateway/Host: fd00::2
42
43              • IPv6 DNS:          fd00::3
44
45
46
47

OPTIONS

49       -c,  --configure  bring  up  the  TAP  interface.  IP  will  be  set to
50       10.0.2.100 (network address + 100) by default. IPv6 will be  set  to  a
51       random  address.   Starting with v0.4.0, the loopback interface (lo) is
52       brought up as well.
53
54
55       -e, --exit-fd=FD specify the FD for terminating slirp4netns.  When  the
56       FD  is specified, slirp4netns exits when a poll(2) event happens on the
57       FD.
58
59
60       -r, --ready-fd=FD specify the FD to write to  when  the  initialization
61       steps  are  finished.  When the FD is specified, slirp4netns writes "1"
62       to the FD and close the FD.  Prior to v0.4.0, the FD was written  after
63       the  network configuration (-c) but before the API socket configuration
64       (-a).
65
66
67       -m, --mtu=MTU (since v0.2.0) specify MTU (max=65521).
68
69
70       -6, --enable-ipv6 (since v0.2.0, EXPERIMENTAL) enable IPv6
71
72
73       -a, --api-socket (since v0.3.0) API socket path
74
75
76       --cidr (since v0.3.0) specify CIDR, e.g. 10.0.2.0/24
77
78
79       --disable-host-loopback   (since   v0.3.0)   prohibit   connecting   to
80       127.0.0.1:* on the host namespace
81
82
83       --netns-type=TYPE   (since   v0.4.0)  specify  network  namespace  type
84       ([path|pid], default=pid)
85
86
87       --userns-path=PATH (since v0.4.0) specify user namespace path
88
89
90       --enable-sandbox (since v0.4.0) enter the user namespace and  create  a
91       new mount namespace where only /etc and /run are mounted from the host.
92
93
94       Requires  /etc/resolv.conf  not  to be a symlink to a file outside /etc
95       and /run.
96
97
98       When running as the root, the process does not enter the user namespace
99       but all the capabilities except CAP_NET_BIND_SERVICE are dropped.
100
101
102       --enable-seccomp  (since  v0.4.0,  EXPERIMENTAL)  enable  seccomp(2) to
103       limit syscalls.  Typically used in conjunction with --enable-sandbox.
104
105
106       --outbound-addr=IPv4 (since v1.1.0, EXPERIMENTAL) specify outbound ipv4
107       address slirp should bind to
108
109
110       --outbound-addr=INTERFACE (since v1.1.0, EXPERIMENTAL) specify outbound
111       interface slirp should bind to (ipv4 traffic only)
112
113
114       --outbound-addr=IPv6 (since v1.1.0, EXPERIMENTAL) specify outbound ipv6
115       address slirp should bind to
116
117
118       --outbound-addr6=INTERFACE  (since  v1.1.0,  EXPERIMENTAL) specify out‐
119       bound interface slirp should bind to (ipv6 traffic only)
120
121
122       --disable-dns (since v1.1.0) disable built-in DNS (10.0.2.3 by default)
123
124
125       --macaddress (since v1.1.9) specify MAC address of  the  TAP  interface
126       (only valid with -c)
127
128
129       --target-type=TYPE    (since    v1.2.0)   specify   the   target   type
130       ([netns|bess], default=netns).
131
132
133       The bess mode (since v1.2.0, EXPERIMENTAL) is expected to be used  with
134       User  Mode  Linux.   The bess mode conflicts with --configure, --netns-
135       type, and --userns-path.
136
137
138       -h, --help (since v0.2.0) show help and exit
139
140
141       -v, --version (since v0.2.0) show version and exit
142
143
144

EXAMPLE

146       Terminal 1: Create user/network/mount namespaces
147
148
149              (host)$ unshare --user --map-root-user --net --mount
150              (namespace)$ echo $$ > /tmp/pid
151
152
153
154       In this documentation, we use (host)$ as the prompt of the host  shell,
155       (namespace)$ as the prompt of the shell running in the namespaces.
156
157
158       If unshare fails, try the following commands (known to be needed on De‐
159       bian, Arch, and old CentOS 7.X):
160
161
162              (host)$ sudo sh -c 'echo "user.max_user_namespaces=28633" >> /etc/sysctl.d/userns.conf'
163              (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
164              (host)$ sudo sysctl --system
165
166
167
168       Terminal 2: Start slirp4netns
169
170
171              (host)$ slirp4netns --configure --mtu=65520 $(cat /tmp/pid) tap0
172              starting slirp, MTU=65520
173
174
175
176       Terminal 1: Make sure tap0 is configured and connected to the Internet
177
178
179              (namespace)$ ip a
180              1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
181                  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
182              3: tap0: <BROADCAST,UP,LOWER_UP> mtu 65520 qdisc fq_codel state UNKNOWN group default qlen 1000
183                  link/ether c2:28:0c:0e:29:06 brd ff:ff:ff:ff:ff:ff
184                  inet 10.0.2.100/24 brd 10.0.2.255 scope global tap0
185                     valid_lft forever preferred_lft forever
186                  inet6 fe80::c028:cff:fe0e:2906/64 scope link
187                     valid_lft forever preferred_lft forever
188              (namespace)$ echo "nameserver 10.0.2.3" > /tmp/resolv.conf
189              (namespace)$ mount --bind /tmp/resolv.conf /etc/resolv.conf
190              (namespace)$ curl https://example.com
191
192
193
194       Bind-mounting /etc/resolv.conf is only needed when /etc/resolv.conf  on
195       the  host refers to loopback addresses (127.0.0.X, typically dnsmasq(8)
196       or systemd-resolved.service(8)) that cannot be accessed from the  name‐
197       space.
198
199
200       If your /etc/resolv.conf on the host is managed by networkmanager(8) or
201       systemd-resolved.service(8), you might need to mount a  new  filesystem
202       on  /etc  instead, so as to prevent the new /etc/resolv.conf from being
203       unmounted unexpectedly when /etc/resolv.conf on the  host  is  regener‐
204       ated.
205
206
207              (namespace)$ mkdir /tmp/a /tmp/b
208              (namespace)$ mount --rbind /etc /tmp/a
209              (namespace)$ mount --rbind /tmp/b /etc
210              (namespace)$ mkdir /etc/.ro
211              (namespace)$ mount --move /tmp/a /etc/.ro
212              (namespace)$ cd /etc
213              (namespace)$ for f in .ro/*; do ln -s $f $(basename $f); done
214              (namespace)$ rm resolv.conf
215              (namespace)$ echo "nameserver 10.0.2.3" > resolv.conf
216              (namespace)$ curl https://example.com
217
218
219
220       These  steps can be simplified with rootlesskit --copy-up=/etc if root‐
221       lesskit is installed:
222
223
224              (host)$ rootlesskit --net=slirp4netns --copy-up=/etc bash
225              (namespace)$ cat /etc/resolv.conf
226              nameserver 10.0.2.3
227
228
229
230

ROUTING PING PACKETS

232       To route ping packets, you may need to set up net.ipv4.ping_group_range
233       properly as the root.
234
235
236       e.g.
237
238
239              (host)$ sudo sh -c 'echo "net.ipv4.ping_group_range=0   2147483647" > /etc/sysctl.d/ping_group_range.conf'
240              (host)$ sudo sysctl --system
241
242
243
244

FILTERING CONNECTIONS

246       By  default, ports listening on INADDR_LOOPBACK (127.0.0.1) on the host
247       are accessible from the  child  namespace  via  the  gateway  (default:
248       10.0.2.2).   --disable-host-loopback can be used to prohibit connecting
249       to INADDR_LOOPBACK on the host.
250
251
252       However, a host loopback address might  be  still  accessible  via  the
253       built-in DNS (default: 10.0.2.3) if /etc/resolv.conf on the host refers
254       to a loopback address.  You may want to set up  iptables  for  limiting
255       access to the built-in DNS in such a case.
256
257
258              (host)$ nsenter -t $(cat /tmp/pid) -U --preserve-credentials -n
259              (namespace)$ iptables -A OUTPUT -d 10.0.2.3 -p udp --dport 53 -j ACCEPT
260              (namespace)$ iptables -A OUTPUT -d 10.0.2.3 -j DROP
261
262
263
264

API SOCKET

266       slirp4netns can provide QMP-like API server over an UNIX socket file:
267
268
269              (host)$ slirp4netns --api-socket /tmp/slirp4netns.sock ...
270
271
272
273       add_hostfwd: Expose a port (IPv4 only)
274
275
276              (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}}'
277              (namespace)$ echo -n $json | nc -U /tmp/slirp4netns.sock
278              {"return": {"id": 42}}
279
280
281
282       If host_addr is not specified, then it defaults to "0.0.0.0".
283
284
285       If  guest_addr is not specified, then it will be set to the default ad‐
286       dress that corresponds to --configure.
287
288
289       list_hostfwd: List exposed ports
290
291
292              (namespace)$ json='{"execute": "list_hostfwd"}'
293              (namespace)$ echo -n $json | nc -U /tmp/slirp4netns.sock
294              {"return": {"entries": [{"id": 42, "proto": "tcp", "host_addr": "0.0.0.0", "host_port": 8080, "guest_addr": "10.0.2.100", "guest_port": 80}]}}
295
296
297
298       remove_hostfwd: Remove an exposed port
299
300
301              (namespace)$ json='{"execute": "remove_hostfwd", "arguments": {"id": 42}}'
302              (namespace)$ echo -n $json | nc -U /tmp/slirp4netns.sock
303              {"return": {}}
304
305
306
307       Remarks:
308
309
310              • Client needs to shutdown(2)  the  socket  with  SHUT_WR  after
311                sending  every  request.   i.e.  No support for keep-alive and
312                timeout.
313
314              • slirp4netns "stops the world" during processing API requests.
315
316              • A request must be less than 4096 bytes.
317
318              • JSON responses may contain error instead of return.
319
320
321
322

DEFINED NAMESPACE PATHS

324       A user can define a network namespace path as opposed  to  the  default
325       process ID:
326
327
328              (host)$ slirp4netns --netns-type=path ... /path/to/netns tap0
329
330
331
332       Currently,  the netns-type=TYPE argument supports path or pid args with
333       the default being pid.
334
335
336       Additionally, a --userns-path=PATH argument can be included to override
337       any user namespace path defaults
338
339
340              (host)$ slirp4netns --netns-type=path --userns-path=/path/to/userns /path/to/netns tap0
341
342
343
344

OUTBOUND ADDRESSES

346       A user can defined preferred outbound ipv4 and ipv6 address in multi IP
347       scenarios.
348
349
350              (host)$ slirp4netns --outbound-addr=10.2.2.10 --outbound-addr6=fe80::10 ...
351
352
353
354       Optionally you can use interface names instead of ip addresses.
355
356
357              (host)$ slirp4netns --outbound-addr=eth0 --outbound-addr6=eth0 ...
358
359
360
361

INTER-NAMESPACE COMMUNICATION

363       The easiest way to allow inter-namespace communication is to nest  net‐
364       work namespaces inside the slirp4netns's network namespace.
365
366
367              (host)$ nsenter -t $(cat /tmp/pid) -U --preserve-credentials -n -m
368              (namespace)$ mount -t tmpfs none /run
369              (namespace)$ ip netns add foo
370              (namespace)$ ip netns add bar
371              (namespace)$ ip link add veth-foo type veth peer name veth-bar
372              (namespace)$ ip link set veth-foo netns foo
373              (namespace)$ ip link set veth-bar netns bar
374              (namespace)$ ip netns exec foo ip link set veth-foo name eth0
375              (namespace)$ ip netns exec bar ip link set veth-bar name eth0
376              (namespace)$ ip netns exec foo ip link set lo up
377              (namespace)$ ip netns exec bar ip link set lo up
378              (namespace)$ ip netns exec foo ip link set eth0 up
379              (namespace)$ ip netns exec bar ip link set eth0 up
380              (namespace)$ ip netns exec foo ip addr add 192.168.42.100/24 dev eth0
381              (namespace)$ ip netns exec bar ip addr add 192.168.42.101/24 dev eth0
382              (namespace)$ ip netns exec bar ping 192.168.42.100
383
384
385
386       However, this method does not work when you want to allow communication
387       across multiple slirp4netns instances.  To allow  communication  across
388       multiple  slirp4netns  instances,  you  need to combine another network
389       stack such as vde_plug(1) with slirp4netns.
390
391
392              (host)$ vde_plug --daemon switch:///tmp/switch null://
393              (host)$ nsenter -t $(cat /tmp/pid-instance0) -U --preserve-credentials -n
394              (namespace-instance0)$ vde_plug --daemon vde:///tmp/switch tap://vde
395              (namespace-instance0)$ ip link set vde up
396              (namespace-instance0)$ ip addr add 192.168.42.100/24 dev vde
397              (namespace-instance0)$ exit
398              (host)$ nsenter -t $(cat /tmp/pid-instance1) -U --preserve-credentials -n
399              (namespace-instance1)$ vde_plug --daemon vde:///tmp/switch tap://vde
400              (namespace-instance1)$ ip link set vde up
401              (namespace-instance1)$ ip addr add 192.168.42.101/24 dev vde
402              (namespace-instance1)$ ping 192.168.42.100
403
404
405
406

INTER-HOST COMMUNICATION

408       VXLAN is known to work.  See  Usernetes  project  for  the  example  of
409       multi-node      rootless     Kubernetes     cluster     with     VXLAN:
410       https://github.com/rootless-containers/usernetes
411
412
413

BESS MODE (FOR USER MODE LINUX)

415       slirp4netns (since v1.2.0) can be also used as a BESS-compatible server
416       to provide network connectivity to User Mode Linux.
417
418
419       Terminal 1: Start slirp4netns
420
421
422              (host)$ slirp4netns --target-type=bess /tmp/bess.sock
423
424
425
426       Terminal 2: Start User Mode Linux
427
428
429              (host)$ linux.uml vec0:transport=bess,dst=/tmp/bess.sock,depth=128,gro=1 root=/dev/root rootfstype=hostfs init=/bin/bash mem=2G
430              (UML)$ ip addr add 10.0.2.100/24 dev vec0
431              (UML)$ ip link set vec0 up
432              (UML)$ ip route add default via 10.0.2.2
433
434
435
436       Currently,  only  a single instance of User Mode Linux can be connected
437       to the slirp4netns BESS server.
438
439
440       See   also   User   Mode    Linux    documentation:    https://www.ker
441       nel.org/doc/html/latest/virt/uml/user_mode_linux_howto_v2.html#bess-
442       socket-transport
443
444
445

BUGS

447       Kernel 4.20 bumped up the default value of  /proc/sys/net/ipv4/tcp_rmem
448       from 87380 to 131072.  This is known to slow down slirp4netns port for‐
449       warding: https://github.com/rootless-containers/slirp4netns/issues/128.
450
451
452       As    a    workaround,    you    can    adjust     the     value     of
453       /proc/sys/net/ipv4/tcp_rmem  inside the namespace.  No real root privi‐
454       lege is needed to modify the file since kernel 4.15.
455
456
457              (host)$ nsenter -t $(cat /tmp/pid) -U --preserve-credentials -n -m
458              (namespace)$ c=$(cat /proc/sys/net/ipv4/tcp_rmem); echo $c | sed -e s/131072/87380/g > /proc/sys/net/ipv4/tcp_rmem
459
460
461
462

SEE ALSO

464       network_namespaces(7), user_namespaces(7), veth(4)
465
466
467

AVAILABILITY

469       The slirp4netns command is available from  https://github.com/rootless-
470       containers/slirp4netns  under  GNU GENERAL PUBLIC LICENSE Version 2 (or
471       later).
472
473
474
475Rootless Containers              January 2022                   SLIRP4NETNS(1)
Impressum