{"id":42,"date":"2013-09-10T22:41:07","date_gmt":"2013-09-10T20:41:07","guid":{"rendered":"http:\/\/www.opencloudblog.com\/?p=42"},"modified":"2021-01-17T12:24:26","modified_gmt":"2021-01-17T11:24:26","slug":"linux-network-namespaces","status":"publish","type":"post","link":"https:\/\/www.opencloudblog.com\/?p=42","title":{"rendered":"Linux Network Namespaces"},"content":{"rendered":"<h1>Introduction<\/h1>\n<p>In the professional networking world it is quite common to use\u00a0<i>Virtual Routing and Forwarding\u00a0<\/i><strong>VRFs\u00a0<\/strong>for a long time. Cisco, Alcatel-Lucent, Juniper and others are supporting this technology. In the L2 switching world, the concept of\u00a0<strong>VLAN<\/strong>s has been used since the 90&#8217;s of the last century. One physical switch supports more than one broadcast domain. Most switches are supporting up to 4k Vlans.<\/p>\n<p>This idea has been adopted to the L3 world. Many network devices are supporting now VRFs. This means, that more than one virtual router (Layer 3 forwarding instance) can be run on one physical device.<\/p>\n<p>In the Linux world, the VRFs of the professional networking world got the name &#8222;network namespace&#8220;. In Linux, there are other namespaces available (like mount namespace&#8230;). The acticle at\u00a0<a href=\"http:\/\/lwn.net\/Articles\/531114\/\">http:\/\/lwn.net\/Articles\/531114\/<\/a>\u00a0 has more details.<\/p>\n<p>Each network namespace has it&#8217;s own routing table, it&#8217;s own iptables setup providing nat and filtering. Linux network namespaces offer in addition the capability to run processes within the network namespace.<\/p>\n<p>But why should someone use this feature. Think about a firewall running on a Linux system. You should assign all service interfaces of the firewall to a network namespace. After this, the default network namespace and the firewall network namespace are running with different routing tables. An applications like SSH is only reachable in the default namespace but not in the firewall namespace. And you may use the same IP addresses in each namespace without any interferance &#8211; but be careful on the L2 layer!<\/p>\n<p>The following sections show the basic usage. A more complex example using also linux bridges or the openvswitch is available in this\u00a0<a title=\"Linux Switching \u2013 Interconnecting Namespaces\" href=\"http:\/\/www.opencloudblog.com\/?p=66\">article<\/a>\u00a0on this site.<\/p>\n<h1>Basic network namespace commands<\/h1>\n<p>The tool to handle network namespaces is the command\u00a0<strong>ip<\/strong>. Some users may know this tool as the replacement for the deprecated tools ifconfig, route, netstat&#8230;. You\u00a0<strong>must be root<\/strong>\u00a0for all operations which change the configuration of the network stack.<\/p>\n<p>Mapping of the commands between the ip and the depricated tools:<\/p>\n<pre class=\"lang:sh decode:true\">ifconfig                                            --&gt; ip addr or just ip a\nifconfig &lt;interface&gt; up\/down                        --&gt; ip link set dev &lt;interface&gt; up\/down\nifconfig &lt;interface&gt; &lt;ip&gt; netmask &lt;netmask&gt;         --&gt; ip addr add &lt;ip&gt;\/&lt;masklen&gt; dev &lt;interface&gt;\nnetstat -rn                                         --&gt; ip route or just ip r\nroute add -net &lt;net&gt; netmask &lt;netmask&gt; gw &lt;gateway&gt; --&gt; ip r add &lt;net&gt;\/&lt;netmasklen&gt; via &lt;gateway&gt;<\/pre>\n<h1>Check your Linux for namespace support<\/h1>\n<p>Before trying to play with network namespaces check it your Linux system supports network namespaces. Ubuntu 12.04 and higher versions have the feature on board.<\/p>\n<h2>Creating a network namespace<\/h2>\n<pre class=\"lang:sh decode:true\"># add a new namespace\nip netnas add &lt;network namespace name&gt;\n#Example:\nip netns add nstest<\/pre>\n<h2>Listing all existing network namespaces in the system<\/h2>\n<pre class=\"lang:sh decode:true\"># list all namespaces\nip netns list\n#will show the namespace from above\n\nnstest<\/pre>\n<h1>Deleting a network namespace<\/h1>\n<p>A network namespace can be deleted using the command<\/p>\n<pre class=\"lang:sh decode:true\">ip netns delete &lt;network namespace name&gt;<\/pre>\n<h1>Executing a command in a network namespace<\/h1>\n<p>The command ip offers the &#8222;black magic&#8220; to execute commands in the network namespace. The following is used:<\/p>\n<pre class=\"lang:sh decode:true\"># execute a command in a namespace\nip netns exec &lt;network namespace name&gt; &lt;command&gt;\n#Example using the namespace from above:\nip netns exec nstest ip addr<\/pre>\n<p>shows all ip interfaces and addresses in the namespace<\/p>\n<pre class=\"lang:sh decode:true\">1: lo: &lt;LOOPBACK&gt; mtu 65536 qdisc noop state DOWN mode DEFAULT \n    link\/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00<\/pre>\n<p>A &#8222;dirty&#8220; trick is to not start each command with the prefix ip netns exec&#8230;. Start a shell in the network namespace using<\/p>\n<pre class=\"lang:sh decode:true\">ip netns exec &lt;network namespace name&gt; bash<\/pre>\n<p>But do not forget, that you are now &#8222;trapped&#8220; in the network namespace. Just type\u00a0<strong>exit<\/strong>\u00a0to leave.<\/p>\n<h1>Exploring the network namespace<\/h1>\n<p>After creating the namespace with the command above, the first task is to bring up the loopback interface of the new namespace. You may have noticed from the output above, that the loopback interface is\u00a0<strong>DOWN<\/strong>\u00a0after creating the network namespace. If you forget this, strange things may happen. It&#8217;s not a good idea to leave the loopback interface down.<\/p>\n<pre class=\"lang:sh decode:true\"># set the link of lo in the namespace to up\nip netns exec nstest ip link set dev lo up\n# list all interfaces and the state in the namespace \nip netns exec nstest ip link<\/pre>\n<p>and the loopback interface is now UP. Now it&#8217;s time to connect the network namespace to the outside world.<\/p>\n<h1>\u00a0Adding interfaces to a network namespace<\/h1>\n<p>It is not possible to assign physical interfaces of your Linux box to a network namespace. It&#8217;s only possible to attach virtual interfaces. So we have to create a virtual interface. The tool is &#8211; again &#8211;\u00a0<strong>ip<\/strong>. The command<\/p>\n<pre class=\"lang:sh decode:true\">ip link add veth-a type veth peer name veth-b<\/pre>\n<p>creates two virtual interfaces veth-a and veth-b, which are connected using &#8222;a virtual cable&#8220;. The command ip link shows both interfaces in the default namespace.<\/p>\n<pre class=\"lang:sh decode:true\">ip link\nveth-b: &lt;BROADCAST,MULTICAST&gt; mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000\n link\/ether 72:01:ad:c5:67:84 brd ff:ff:ff:ff:ff:ff\nveth-a: &lt;BROADCAST,MULTICAST&gt; mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000\n link\/ether 8e:8b:bd:b1:88:e5 brd ff:ff:ff:ff:ff:ff<\/pre>\n<p>We can now take one end of this construct and attach it to the created namespace nstest using the command<\/p>\n<pre class=\"lang:sh decode:true\">ip link set veth-b netns nstest<\/pre>\n<p>Now ip l in the default namespace does not show this interface any more. It shows up now in the network namespace nstest, Verify this using the command<\/p>\n<pre class=\"lang:sh decode:true\"># list all interfaces in the namespace nstest\nip netns exec nstest ip link\n\nlo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT \n link\/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\nveth-b: &lt;BROADCAST,MULTICAST&gt; mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000\n link\/ether 72:01:ad:c5:67:84 brd ff:ff:ff:ff:ff:ff<\/pre>\n<p>Now we have two interfaces in the network namespace nstest.<\/p>\n<h1>Assign ip addresses to the veth interfaces<\/h1>\n<p>Now it&#8217;s time to assign ip addresses to the veth interfaces and bring the interfaces up<\/p>\n<pre class=\"lang:sh decode:true\"># default namespace\nip addr add 10.0.0.1\/24 dev veth-a\nip link set dev veth-a up\n#\n# namespace nstest\nip netns exec nstest ip addr add 10.0.0.2\/24 dev veth-b\nip netns exec nstest ip link set dev veth-b up<\/pre>\n<p>Verify, that the interfaces are up (use<strong>\u00a0ip link<\/strong>), have ip addresses assigned (use\u00a0<strong>ip addr<\/strong>) and a route is existing (use\u00a0<strong>ip route<\/strong>).<\/p>\n<p>Now you can ping from the default namespace interface veth-a \u00a0to the nstest namespace interface veth-b:<\/p>\n<pre class=\"lang:sh decode:true\">ping 10.0.0.2\nPING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.\n64 bytes from 10.0.0.2: icmp_req=1 ttl=64 time=0.054 ms\n64 bytes from 10.0.0.2: icmp_req=2 ttl=64 time=0.034 ms\n64 bytes from 10.0.0.2: icmp_req=3 ttl=64 time=0.039 ms\n64 bytes from 10.0.0.2: icmp_req=4 ttl=64 time=0.036 ms<\/pre>\n<p>And from the nstest namespace interface veth-b to the default namespace interface veth-a:<\/p>\n<pre class=\"lang:sh decode:true\">ip netns exec nstest ping 10.0.0.1\nPING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.\n64 bytes from 10.0.0.1: icmp_req=1 ttl=64 time=0.064 ms\n64 bytes from 10.0.0.1: icmp_req=2 ttl=64 time=0.036 ms\n64 bytes from 10.0.0.1: icmp_req=3 ttl=64 time=0.039 ms<\/pre>\n<p>Try to reach another interface in the default namespace when pinging from the network namespace.<\/p>\n<h1>Which software is using network namespaces?<\/h1>\n<p>Network namespaces are used by many container and virtualization techniques. LXC is one of the virtualization container techniques. Openstack neutron is also using the Linux network namespaces.<\/p>\n<p>Virtual inferfaces and network namespaces are very useful, when a virtual switch, e.g. Openvswitch, is installed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In the professional networking world it is quite common to use\u00a0Virtual Routing and Forwarding\u00a0VRFs\u00a0for a long time. Cisco, Alcatel-Lucent, Juniper and others are supporting this technology. In the L2 switching world, the concept of\u00a0VLANs has been used since the 90&#8217;s of the last century. One physical switch supports more than one broadcast domain. Most [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/posts\/42"}],"collection":[{"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=42"}],"version-history":[{"count":12,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/posts\/42\/revisions"}],"predecessor-version":[{"id":934,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/posts\/42\/revisions\/934"}],"wp:attachment":[{"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=42"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=42"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}