Giter Site home page Giter Site logo

systemd-named-netns's Introduction

systemd-named-netns

This project enables you to:

  • Create and delete named netns on the fly like systemd services
  • Start named netns on boot
  • Quickly set up bridging or NAT from netns to host
  • Use named netns in systemd services
    • Enables them to connect to the internet too
    • And you can manually switch to its netns (since they are named)

Installation

Dependencies:

  • Recent version of systemd (newer is better; tested down to v232)
  • iproute2
  • iptables (only if you use default NAT config)
  • /usr/bin/env

For installation, run make install with root privilege.

You ran run make uninstall to remove the systemd units, but the configs located in /etc/default will not be removed.

Quickstart

systemctl start netns-nat@helloworld
chnetns helloworld ip address

Note: Network interface names are derived from the netns name, so do not create netns names longer than 12 characters.

NS Types

It creates a new netns. Use this if you want to customize everything by hand. All other types depend on this.

It creates a new netns with NATed network access (like VMNet8). Use this if you want to get things quickly up and running without any network hassles.

Note:

  • The default configuration will only work for the first netns-nat instance. You need to change the IP addresses if you want 2 or more netns-nat instances running at the same time.
  • This will setup packet forwarding on your Linux kernel, making your host a router (this might cause security problems if set incorrectly)
  • If you want automatic iptables accept rules, set NAT_ACCEPT_TRAFFIC=1

It creates a new netns with a pseudo wire to the host (like VMNet1). Use this if you want to communicate with the program inside the netns but don't want them to have internet access, or if you want to assign routable IPs to a netns.

It bridges the new netns to a Linux bridge. You need to set up the bridge first: see wiki if you are not sure what to do.

MACVLAN Bridge ([email protected])

Alternative to NSType bridge. A MACVLAN Bridge allows you to create multiple interfaces with different Layer 2 (that is, Ethernet MAC) addresses on top of a single NIC. MACVLAN is a bridge without an explicit bridge device.

For netns-mvbr, ${MACVLAN_BRIDGE} will be the bridge device (usually your physical NIC device).

Note that any MACVLAN devices in other netns's will be able to communicate each other and the outside world but NOT the bridge device. If you want to enable communication with the root netns, you can add a MACVLAN device in the root netns and use that instead of the MACVLAN bridge device.

Resources

References

systemd-named-netns's People

Contributors

admirito avatar belphemur avatar darkkowalski avatar f3flight avatar jamesits avatar orzfly avatar smarre avatar st31ny avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

systemd-named-netns's Issues

Uninstaller bug - unit name escaped

systemctl stop netns@*.service || true
systemctl disable netns@*.service || true
Invalid unit name "netns@*.service" was escaped as "netns@\x2a.service" (maybe you should use systemd-escape?)
systemctl disable netns-tunnel@*.service || true
Invalid unit name "netns-tunnel@*.service" was escaped as "netns-tunnel@\x2a.service" (maybe you should use systemd-escape?)
Failed to disable unit: Unit file netns-tunnel@\x2a.service does not exist.
systemctl disable netns-bridge@*.service || true
Invalid unit name "netns-bridge@*.service" was escaped as "netns-bridge@\x2a.service" (maybe you should use systemd-escape?)
systemctl disable netns-nat@*.service || true
Invalid unit name "netns-nat@*.service" was escaped as "netns-nat@\x2a.service" (maybe you should use systemd-escape?)
rm -f //usr/lib/systemd/system/[email protected]
rm -f //usr/lib/systemd/system/[email protected]
rm -f //usr/lib/systemd/system/[email protected]
rm -f //usr/lib/systemd/system/[email protected]
rm -f /usr/bin/chnetns
rm -f /usr/sbin/netnsinit

Change NIC prefix

In my master branch https://github.com/steinymity/systemd-named-netns I changed the NIC prefix from ve- to vn- because ve- is already used by systemd-nspawn (i.e., to avoid collisions). Particularily, there is a default .network file (on my system in /lib/systemd/network/80-container-ve.network) that matches on all ve-* interfaces and automatically assigns IPs (if systemd-networkd is active).

Before pushing this backwards-incompatible change I wanted to ask about your opinions on this. Ideally, the prefix would be configurable, however, systemd doesn't allow to use variables in lines other than Exec*.

Tag version/releases to make packaging easier

Currently there are no tags/releases, I was looking at adding this to Debian/Ubuntu, but the absence of any tagging makes this much harder. Could some scheme be agreed to about when something is tagged, and with what version?

netns raw on specific interface, via configuration

Is there a way (that I'm currently not able to figure out) to configure netns to simply bring in an external "eno2" ethernet device and run dhcp4 on it? Bonus to disable ipv6. All of my vlan and routing is done in hardware (switch layer 2+, router). I'm just trying to isolate certain systemctl services to a single network, which gets pretty complicated outside of netns.

Here's the script I have to run after running systemctl start netns@my_ns.service:

ip link set dev eno2 netns my_ns
chnetns my_ns sysctl net.ipv6.conf.eno2.disable_ipv6=1
ip -n my_ns link set eno2 up
ip -n my_ns link set lo up
ip netns exec my_ns dhclient eno2

Ideally this would be done as part of the service itself. I took a look inside netnsninit script but didn't see any kind of option for this. Maybe I'm just overlooking it!

netnsinit fails when no gateway is set

fails after [ ! -z "{$GATEWAY}" ] ... due to "set -e" and specifics of how it works. I'll create a pull request to fix. Basically if the last command in the function failed, even if this failure was ignored by "set -e", and function does not return anything, then upon leaving the function set -e will cause bash to quit.

#!/bin/bash -x
set -e
f() {
[ ! -z "$NOTSET"] && true
echo "you will see this"
[ ! -z "$NOTSET"] && true
}
f
echo "you will not see this"

/etc/default/netns breaks custom settings

Currently if you need only some of the options you run into an issue that default netns file defines everything and is always included, so you have to either undefine these variables orcomment /etc/default/netns each time after running install script.

Need to either specify in /etc/default/netns how to properly create custom config (i.e. have to "unset" all unneeded variables from default config) or rework sourcing.

Simplify configuration files

In my master branch https://github.com/steinymity/systemd-named-netns I refactored the common parts of [email protected] and [email protected] and created another service [email protected] that just creates a pair of connected interfaces.
To facilitate this refactoring, however, I had to remove the type-dependent config files. I.e., there are only /etc/default/netns and /etc/default/netns-%I. As netns-nat and netns-bridge conflict each other anyway, I don't think this is a major drawback.
However, this is of course backward-incompatible, so what do you think about merging the config files?

systemd service with JoinsNamespaceOf= does not use separate resolv.conf for that netns

$ ls -lah /proc/1/ns | grep -E '(mnt|net)'
lrwxrwxrwx 1 root root 0 Jul 28 12:24 mnt -> mnt:[4026531841]
lrwxrwxrwx 1 root root 0 Jul 27 22:07 net -> net:[4026531840]

I created a netns called warp use [email protected], and create /etc/netns/warp/resolv.conf, then:

$ ip netns exec warp ls -lah /proc/self/ns | grep -E '(mnt|net)'
lrwxrwxrwx 1 root root 0 Jul 28 12:30 mnt -> mnt:[4026532461]
lrwxrwxrwx 1 root root 0 Jul 28 12:30 net -> net:[4026532520]

Processes run by ip netns exec warp use separate netns and mount namespace, and it uses the separate resolv.conf

I also run a systemd service (warp-svc) with [email protected], however:

$ ls -lah /proc/$(pidof warp-svc)/ns | grep -E '(mnt|net)'
lrwxrwxrwx 1 root root 0 Jul 28 12:25 mnt -> mnt:[4026531841]
lrwxrwxrwx 1 root root 0 Jul 27 23:06 net -> net:[4026532520]

It only changes the netns, the mount namespace remains the same as pid 1, and therefore this process does not use the separate resolv.conf

systemd-networkd bridge wiki changes

On my system, I also needed a .netdev file for the bridge

[NetDev]
Name=br0
Kind=bridge

And I had to use restart instead of reload, to get systemd-networkd to pickup the new config, as reload wasn't an option.

[email protected]

...contains

Before=network.target network-online.target

but in case of DHCP option enabled the service always fails because of dhclient does not supposed to be operational unless both network targets are finished.

Connectivity to/from LAN in network namespace

I have a network namespace set up using netns-bridge, and it was previously working, but has stopped at some point, and I haven't been able to figure out what went wrong.

imntreal@server  /e/default  cat netns-vpn    2277ms  Tue 25 May 2021 09:13:19 PM EDT
# This is the default config for [email protected],
# [email protected] and [email protected].
# You can override config per netns by creating a file named
# netns-<your_netns_name>.

# Bridge name for [email protected]
BRIDGE=br0

# IP address of the interface outside
IPADDR_OUTSIDE=192.168.1.51/24


# If you need DHCP
# In order for this to function for netns-tunnel and
# netns-nat you need a local DHCP server, e.g., the
# one integrated in systemd-networkd. Netns bridge
# can use your LAN's DHCP.
#DHCPV4=1

# If you need static IP
IPADDR=192.168.1.51/24
GATEWAY=192.168.1.1/24
#GATEWAY=192.168.1.3/24

# If you need static MAC
#MACADDR=00:11:22:33:44:55

 imntreal@server  /e/default  ip a                      Tue 25 May 2021 09:13:22 PM EDT
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s25: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:25:90:d2:e8:7b brd ff:ff:ff:ff:ff:ff
3: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether 00:25:90:d2:e8:7a brd ff:ff:ff:ff:ff:ff
    altname enp4s0
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether ca:12:cc:82:54:ce brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.50/24 brd 192.168.1.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 2600:6c5a:557f:aa3b:c812:ccff:fe82:54ce/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 2591770sec preferred_lft 604570sec
    inet6 fe80::c812:ccff:fe82:54ce/64 scope link 
       valid_lft forever preferred_lft forever
7: cni-podman0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether c2:30:b4:07:c4:73 brd ff:ff:ff:ff:ff:ff
    inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0
       valid_lft forever preferred_lft forever
    inet6 fe80::c030:b4ff:fe07:c473/64 scope link 
       valid_lft forever preferred_lft forever
19: vn-vpn0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP group default qlen 1000
    link/ether fa:5c:2c:2c:be:0e brd ff:ff:ff:ff:ff:ff link-netns vpn
    inet 192.168.1.51/24 scope global vn-vpn0
       valid_lft forever preferred_lft forever
    inet6 fe80::f85c:2cff:fe2c:be0e/64 scope link 
       valid_lft forever preferred_lft forever

 imntreal@server  /e/default  sudo chnetns vpn ip a     Tue 25 May 2021 09:15:02 PM EDT
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none 
    inet 10.19.216.120/24 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fde6:7a:7d20:fd8::1076/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::726a:732e:48ba:9d1c/64 scope link stable-privacy 
       valid_lft forever preferred_lft forever
18: vn-vpn1@if19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 7a:21:3e:9e:64:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.51/24 scope global vn-vpn1
       valid_lft forever preferred_lft forever
    inet6 2600:6c5a:557f:aa3b:7821:3eff:fe9e:64bc/64 scope global dynamic mngtmpaddr 
       valid_lft 2591986sec preferred_lft 604786sec
    inet6 fe80::7821:3eff:fe9e:64bc/64 scope link 
       valid_lft forever preferred_lft forever

 imntreal@server  /e/default  sudo chnetns vpn iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DROP       all  --  anywhere             anywhere             ctstate INVALID
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  192.168.1.0/24       anywhere            
ACCEPT     tcp  --  anywhere             anywhere             tcp dpts:39081:39101
ACCEPT     udp  --  anywhere             anywhere             udp dpts:39081:39101
REJECT     tcp  --  anywhere             anywhere             reject-with tcp-reset
REJECT     udp  --  anywhere             anywhere             reject-with icmp-port-unreachable
REJECT     all  --  anywhere             anywhere             reject-with icmp-proto-unreachable

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             /* vpn */
ACCEPT     icmp --  anywhere             anywhere             /* icmp */
ACCEPT     all  --  anywhere             192.168.1.0/24       /* lan */
ACCEPT     udp  --  anywhere             anywhere             udp dpt:https /* openvpn */
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https /* openvpn tcp */
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:ssh /* ssh */
ACCEPT     udp  --  anywhere             anywhere             udp dpt:ntp /* ntp */
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain /* dns */
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain /* dns */
DROP       all  --  anywhere             anywhere

Any thoughts on what I'm doing wrong?

netns unit fails to start: umount: not mounted

ExecStart=/usr/bin/env umount /var/run/netns/physical (code=exited, status=32)
umount: /var/run/netns/physical: not mounted.

This used to work fine, it seems perhaps following delete & re-add it used to (still) be mounted but no longer is?

Best fix perhaps to check if it's mounted (mount -l) first and only conditionally unmount?

Name the network namespace in one step

The following lines from [email protected] can be replaced with the single command ip netns attach %I {pid} (using any pid in the service's network namespace) whenever it's safe to depend on iproute2 5.x.

Existing lines:

ExecStart=/usr/bin/flock --no-fork -- /var/run/netns.lock /usr/bin/env ip netns add %I
ExecStart=/usr/bin/env umount /var/run/netns/%I
ExecStart=/usr/bin/env mount --bind /proc/self/ns/net /var/run/netns/%I

Replacement:

ExecStart=/usr/bin/env sh -c '/usr/bin/env ip netns attach %I $$$$'

(Systemd parses $$ down to $, so $$$$ lets the shell process see $$.)

The ip netns attach command was committed in early 2019 (see https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/commit/?id=e3dbcb2a12ab1bda3de6f9f61f4dfca182ec8a4c), so there are still supported systems (e.g. RHEL/CentOS 7.x) that don't have it.

SELinux didn't like the netns bind mount on my system, but didn't complain about ip netns attach.

docker/containerd in netns

Did anyone try to run docker.service/containerd.service with systemd-named-nets in own namespace?

I tried and commands like docker pull works fine but docker run can't start any container.

I hope someone knows a fix.

netnsinit device name suffix

DEVNAME_INSIDE_TMP_SUFFIX="-${NSNAME}-tmp"

Below commands that uses DEVNAME_INSIDE_TMP_SUFFIX variable fails if resulting calculated interface name consists of more than 16 symbols:
ip link add ${DEVNAME_INSIDE}${DEVNAME_INSIDE_TMP_SUFFIX} netns ${NSNAME} link ${MACVLAN_BRIDGE} type macvlan mode bridge
ip -n ${NSNAME} link set dev ${DEVNAME_INSIDE}${DEVNAME_INSIDE_TMP_SUFFIX} name ${DEVNAME_INSIDE}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.