]> ruderich.org/simon Gitweb - linux-network-namespace-labs/linux-network-namespace-labs.git/blob - README.adoc
1ec8238fd7c831d05e830c55f0c73d00054e2489
[linux-network-namespace-labs/linux-network-namespace-labs.git] / README.adoc
1 = README
2
3 linux-network-namespace-labs is a small program to create networking lab
4 setups based on Linux network namespaces in a simple manner. It provides a
5 quick way to setup labs using a text file describing the architecture
6 (networks, nodes, links, commands). This is much simpler than running each
7 node in a separate virtual machine or manually allocating the IP addresses for
8 each node. It is licensed under GPLv3+.
9
10
11 == Requirements
12
13 === Build
14
15 - Go, no external dependencies
16
17 === Run
18
19 - Linux compiled with `CONFIG_NET_NS` (available on most modern systems)
20 - iproute2 (`ip`)
21
22
23 == Build
24
25     $ go build
26
27 Then copy the binary `linux-network-namespace-labs` to somewhere in your
28 `$PATH`.
29
30
31 == Usage
32
33 The following configuration from `examples/readme/` setups a lab with three
34 nodes (routers) and configures static routes.
35
36 ----
37 # Network range for loopback addresses of the nodes
38 net loops 192.0.2.0/24 3fff::/20
39 # Network range for interfaces between nodes
40 net addrs 198.51.100.0/24 2001:db8::/32
41
42 # Setup three nodes (routers) and assign IPv4 and IPv6 loopback addresses
43 node r1 loops
44 node r2 loops
45 node r3 loops
46
47 # Links between routers: /31 or /127 is used for each interface
48 link r1 r2 addrs
49 link r2 r3 addrs
50
51 # Commands to run on each node; $1 is the node name (= name of network
52 # namespace). Here it's used to setup static routes but can also be used to
53 # start routing daemons like bird.
54 cmd ./setup.sh $1
55 ----
56
57 Then setup the lab by running (as root):
58
59     # cd examples/readme
60     # linux-network-namespace-labs up lab.conf
61     [...]
62
63 Now you can enter the network namespace of each router and test a simple
64 traceroute:
65
66     # ip netns exec r1 sh
67     # ip -br a
68     lo               UNKNOWN        127.0.0.1/8 ::1/128
69     lo2              UNKNOWN        192.0.2.0/32 3fff::/128 fe80::438:67ff:fe0a:4e58/64
70     r2@if287         UP             198.51.100.0/31 2001:db8::/127 fe80::a896:cdff:fe58:5c23/64
71     # traceroute 192.0.2.2
72     traceroute to 192.0.2.2 (192.0.2.2), 30 hops max, 60 byte packets
73      1  r2 (198.51.100.1)  0.937 ms  0.818 ms  0.768 ms
74      2  r3-loop (192.0.2.2)  0.722 ms  0.650 ms  0.603 ms
75
76 Use `exit` to leave the network namespace.
77
78 `/etc/hosts` of each node (via `/etc/netns/<ns>/hosts`) is automatically
79 filled with all known addresses so you can use hostnames as well:
80
81     # ping -c1 r3-loop
82     PING r3-loop(r3-loop (3fff::2)) 56 data bytes
83     64 bytes from r3-loop (3fff::2): icmp_seq=1 ttl=63 time=0.266 ms
84     --- r3-loop ping statistics ---
85     1 packets transmitted, 1 received, 0% packet loss, time 0ms
86     rtt min/avg/max/mdev = 0.266/0.266/0.266/0.000 ms
87
88 When you change the configuration you can simply rerun "up" and it will remove
89 the lab (and killing all processes inside it) before starting it up again:
90
91     # linux-network-namespace-labs up lab.conf
92     [...]
93
94 When you're done you can remove the lab with:
95
96     # linux-network-namespace-labs down lab.conf
97     [...]
98
99 To get an overview of the network you can create a
100 https://en.wikipedia.org/wiki/DOT_(graph_description_language)[DOT] file:
101
102     $ linux-network-namespace-labs dot lab.conf lab.dot
103     $ dot -Tpng lab.dot > lab.png
104
105 image::examples/readme/lab.png[DOT style diagram of network nodes and links]
106
107
108 == Examples
109
110 Have a look at `examples/` for some examples which also include running
111 https://bird.network.cz/[Bird] on each node and spawning a Podman container
112 inside the created nodes running https://frrouting.org/[FRR].
113
114
115 == Syntax of configuration file
116
117 One option per line, empty lines are permitted as well as comments at the
118 beginning of the line with `#`.
119
120 The config files is parsed from top to bottom and the options "net", "node",
121 "link" must be given in this order. "cmd" can be put anywhere (but is only
122 executed at the end).
123
124 === Option "net"
125
126     "net" <name> <prefix>...
127
128 "net" creates a new prefix which is used to allocate addresses for loopback
129 and link interfaces. Multiple IPv4 and IPv6 prefixes can be specified. When
130 the network is used one address of each prefix is assigned to the interface.
131 "net"s used for loopback interfaces must be separate from "net"s used for link
132 interfaces.
133
134 === Option "node"
135
136     "node" <name> [<loopback-net-name>...]
137
138 "node" creates a new node (router) and (if specified) assigns loopback
139 addresses from the given networks. The loopback addresses are assigned to a
140 new interface "lo2".
141
142 === Option "link"
143
144     "link" <node> <node> <net-name> ["l3"]
145
146 "link" creates links between nodes. The IP addresses are taken from the given
147 network name. /31 is used for IPv4- and /127 for IPv6-prefixes. The MAC
148 address is not static and allocated by the kernel. The link is named after the
149 node "on the other side". Multiple links can be created between two nodes. In
150 this case "_2", "_3", etc. is appended to the interface name. By default veth
151 interfaces are used, adding "l3" changes this to netkit which provide a
152 layer-3 connection without needing ARP (requires kernel 6.7, iproute2 6.8).
153
154 === Option "cmd"
155
156     "cmd" <string-passed-to-sh-c>
157
158 "cmd" runs the given command (by passing it as is to `sh -c`) on each node.
159 The first argument is the name of the node (which is also the name of the
160 network namespace). This can be used to run setup commands or routing daemons
161 on the nodes.
162
163 If "cmd" is not flexible enough you can simply use `ip netns exec` to manually
164 run commands on specific nodes.
165
166
167 == Authors
168
169 Written by Simon Ruderich <simon@ruderich.org>.
170
171 Please report bugs, feature requests and patches via email.
172
173
174 == License
175
176 This program is licensed under GPL version 3 or later.
177
178 Copyright (C) 2024  Simon Ruderich
179
180 This program is free software: you can redistribute it and/or modify
181 it under the terms of the GNU General Public License as published by
182 the Free Software Foundation, either version 3 of the License, or
183 (at your option) any later version.
184
185 This program is distributed in the hope that it will be useful,
186 but WITHOUT ANY WARRANTY; without even the implied warranty of
187 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
188 GNU General Public License for more details.
189
190 You should have received a copy of the GNU General Public License
191 along with this program.  If not, see <https://www.gnu.org/licenses/>.