# Run systemd service in network namespace

**URL:** https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179
**Category:** Help
**Created:** [June 14, 2019, 3:59pm UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179 "2019-06-14T15:59:46Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![mth](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/dc4da7/32.png) [@mth](https://discourse.nixos.org/u/mth)
#### Post date: [June 14, 2019, 3:59pm UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179/1 "2019-06-14T15:59:46Z")

</div>

I could prepend `ip netns exec xx` where applicable (e.g. `serviceConfig.ExecStart`). But `ip netns` requires root privileges. What can I do if `serviceConfig.User` isn’t `"root"`?

---

<div class="post-metadata">

### Author: ![azazel75](https://discourse.nixos.org/user_avatar/discourse.nixos.org/azazel75/32/177_2.png) [@azazel75](https://discourse.nixos.org/u/azazel75)
#### Post date: [June 14, 2019, 9:49pm UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179/2 "2019-06-14T21:49:29Z")

</div>

maybe using `JoinNamespaceOf` (see `man systemd.unit`) on another unit that is running as root ?

---

<div class="post-metadata">

### Author: ![mth](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/dc4da7/32.png) [@mth](https://discourse.nixos.org/u/mth)
#### Post date: [June 15, 2019, 2:17pm UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179/3 "2019-06-15T14:17:47Z")

</div>

@azazel75 thanks a lot! got it working:

```auto
{ config, pkgs, lib, ... }: {
  systemd.services."netns@" = {
    description = "%I network namespace";
    before = ["network.target"];
    serviceConfig = {
      Type = "oneshot";
      RemainAfterExit = true;
      PrivateNetwork = true;
      ExecStart = (pkgs.writeScript "netns-up" ''
        #! ${pkgs.bash}/bin/bash
        ${pkgs.iproute}/bin/ip netns add $1
        ${pkgs.utillinux}/bin/umount /var/run/netns/$1
        ${pkgs.utillinux}/bin/mount --bind /proc/self/ns/net /var/run/netns/$1
      '') + " %I";
      ExecStop = "${pkgs.iproute}/bin/ip netns del %I";
    };
  };
}

```

Any `systemd.services.<name>` can join with:

```auto
bindsTo = ["netns@wg.service"];
after = ["netns@wg.service"];
unitConfig.JoinsNamespaceOf = "netns@wg.service";
serviceConfig.PrivateNetwork = true;

```

stolen from [Access mounted (ip netns ...) network namespaces. · Issue #2741 · systemd/systemd · GitHub](https://github.com/systemd/systemd/issues/2741#issuecomment-336736214)

---

<div class="post-metadata">

### Author: ![mth](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/dc4da7/32.png) [@mth](https://discourse.nixos.org/u/mth)
#### Post date: [June 15, 2019, 2:26pm UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179/4 "2019-06-15T14:26:24Z")

</div>

I might write a blog post soon about using this to sandbox services in a network namespace with wireguard, since I have a working setup.

---

<div class="post-metadata">

### Author: ![mth](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/dc4da7/32.png) [@mth](https://discourse.nixos.org/u/mth)
#### Post date: [August 28, 2019, 12:20pm UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179/5 "2019-08-28T12:20:35Z")

</div>

ok, here we go:

> **[WireGuard network namespace on NixOS](https://mth.st/blog/nixos-wireguard-netns/)**
>
> We configure a network namespace (as described in the
> WireGuard
> documentation)
> 
> containing solely a WireGuard interface whereto systemd services can b…

---

<div class="post-metadata">

### Author: ![arianvp](https://discourse.nixos.org/user_avatar/discourse.nixos.org/arianvp/32/602_2.png) [@arianvp](https://discourse.nixos.org/u/arianvp)
#### Post date: [August 28, 2019, 3:45pm UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179/6 "2019-08-28T15:45:01Z")

</div>

For your interest, in NixOS 19.09 you’ll be able to directly specify the `netns` for a service to Join

> <https://github.com/systemd/systemd/blob/4b259b3c63eeefe4cd52fa3b169b1ca4b19f13e9/NEWS#L525-L527>

So this could simplify your code a bit

```auto
# netns@.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=${pkgs.iproute}/bin/ip netns add %I
ExecStop=${pkgs.iproute}/bin/ip netns del %I

# myservice.service
[Unit]
BindsTo=netns@wg.service
After=netns@wg.service
NetworkNamespacePath=/var/run/netns/wg
[Service]
ExecStart=myservice

```

---

<div class="post-metadata">

### Author: ![cladmi](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/c/ac8455/32.png) [@cladmi](https://discourse.nixos.org/u/cladmi)
#### Post date: [December 24, 2019, 2:39pm UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179/7 "2019-12-24T14:39:28Z")

</div>

> [@arianvp](#):
>
> `
> # myservice.service
> `
> 
> `[Unit]
> BindsTo=netns@wg.service
> After=netns@wg.service
> NetworkNamespacePath=/var/run/netns/wg
> [Service]
> ExecStart=myservice
> `

This one must be changed to move `NetworkNamespacePath` into the `[Serice]` section as when it is in `[Unit]` you get an `Unknown key name ‘NetworkNamespacePath’ in section ‘Unit’, ignoring` warning in the log.

With the modification it works like a charm thank you for documenting it.

---

<div class="post-metadata">

### Author: ![nh2](https://discourse.nixos.org/user_avatar/discourse.nixos.org/nh2/32/631_2.png) [@nh2](https://discourse.nixos.org/u/nh2)
#### Post date: [September 6, 2022, 2:41am UTC](https://discourse.nixos.org/t/run-systemd-service-in-network-namespace/3179/8 "2022-09-06T02:41:56Z")

</div>

> [@azazel75](#):
>
> `JoinNamespaceOf`

Correcting a typo: This should be `JoinsNamespaceOf`, with an `s`.

This mistake made it into [examples/mautrix.nix · ff782189f05f48f28a8292b0e3c9bb579ebe93e5 · Coffee Tables / nix-matrix-appservices · GitLab](https://gitlab.com/coffeetables/nix-matrix-appservices/-/blob/ff782189f05f48f28a8292b0e3c9bb579ebe93e5/examples/mautrix.nix#L30)
