Skip to content

nixos/nordvpn: make more secure and robust - #547437

Merged
romildo merged 2 commits into
NixOS:masterfrom
different-error:nordvpn-security-tightening
Oct 18, 2026
Merged

romildo merged 2 commits into
NixOS:masterfrom
different-error:nordvpn-security-tightening

Conversation

@different-error

@different-error different-error commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor
  • add systemd sandboxing to nordvpnd; sandboxing shrinks the blast radius of a compromised nordvpnd process
  • add more comprehensive nixos tests to verify service prerequisites and capability bounds: loaded kernel modules, capabilities, socket permissions, tun device access

Assisted-by: Claude Code (Sonnet 5)

(edit note: I initially patched nordvpn-linux's source directly; I decided to move that change upstream instead)


Spin up a VM for manual verification:

{
  pkgs,
  lib,
  ...
}:

{
  imports = [
    ./hardware-configuration.nix
  ];

  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;
  networking.firewall.enable = true;
  networking.firewall.checkReversePath = "loose";

  services.xserver.enable = true;
  services.displayManager.gdm.enable = true;
  services.desktopManager.plasma6.enable = true;

  services.timesyncd.enable = lib.mkForce true;
  services.timesyncd.servers = [
    "time.google.com"
    "pool.ntp.org"
  ];

  services.nordvpn = {
    enable = true;
  };

  virtualisation.vmVariant = {
    virtualisation = {
      memorySize = 8192;
      cores = 3;
    };
  };
  users.groups.alice = { };
  users.users.alice = {
    isNormalUser = true;
    password = "alice";
    group = "alice";
    extraGroups = [
      "wheel"
      "nordvpn"
    ];
    shell = pkgs.bash;
    home = "/home/alice";
    createHome = true;
    packages = with pkgs; [
      dunst
      firefox
      libnotify
      nftables
      socat
      tmux
      tree
      vim
    ];
  };
  system.stateVersion = "24.11"; # Did you read the comment?
}
nixos-rebuild build-vm \
  -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/refs/pull/547437/head.tar.gz \
  -I nixos-config=/path/to/configuration.nix

Note: since this package/service hasn't made it to stable yet, I've not updated the release notes.

Things done

@h7x4

h7x4 commented Jul 30, 2026

Copy link
Copy Markdown
Member

Could you read through the Automation/AI policy and state whether the contribution adheres to it?

@nixpkgs-ci nixpkgs-ci Bot added 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Jul 30, 2026
@different-error
different-error force-pushed the nordvpn-security-tightening branch from 69baa5d to 070174d Compare July 31, 2026 05:36
@nixpkgs-ci nixpkgs-ci Bot added the llm-assisted Contributions that include code generation with LLMs label Jul 31, 2026
@different-error
different-error force-pushed the nordvpn-security-tightening branch 6 times, most recently from 9cd50f7 to 7f8316a Compare July 31, 2026 14:26
@different-error different-error changed the title nixos/nordvpn: make more secure and portable nixos/nordvpn: harden nordvpnd sandboxing and relax socket permissions Aug 1, 2026
@different-error
different-error force-pushed the nordvpn-security-tightening branch from 7f8316a to e887ec9 Compare August 1, 2026 05:57
@different-error
different-error marked this pull request as ready for review August 1, 2026 05:59
@nixpkgs-ci nixpkgs-ci Bot added the 9.needs: reviewer This PR currently has no reviewers requested and needs attention. label Aug 1, 2026
@different-error
different-error marked this pull request as draft August 1, 2026 12:24
@different-error
different-error force-pushed the nordvpn-security-tightening branch from e887ec9 to 8179b6e Compare August 1, 2026 12:30
@different-error different-error changed the title nixos/nordvpn: harden nordvpnd sandboxing and relax socket permissions nixos/nordvpn: harden nordvpnd sandboxing Aug 1, 2026
@different-error different-error changed the title nixos/nordvpn: harden nordvpnd sandboxing nixos/nordvpn: make more secure and robust Aug 1, 2026
@different-error
different-error marked this pull request as ready for review August 1, 2026 12:46
@different-error
different-error force-pushed the nordvpn-security-tightening branch from 8179b6e to 4ccb9b3 Compare August 2, 2026 07:13
@different-error different-error mentioned this pull request Aug 2, 2026
6 of 13 tasks
@different-error
different-error force-pushed the nordvpn-security-tightening branch 2 times, most recently from 390f526 to f98575c Compare August 11, 2026 06:46
@different-error

Copy link
Copy Markdown
Contributor Author

@ruffsl @andersonjoseph

Hello again. I could use your qa testing of the changes in this pr as well to facilitate review. Ty.

@andersonjoseph

Copy link
Copy Markdown

Built a VM from this PR and verified the sandboxing lands and doesn't break anything:

  • All the new directives are active on nordvpnd (ProtectSystem=strict, RestrictAddressFamilies, RestrictNamespaces, ProtectControlGroups, DeviceAllow=/dev/net/tun, NoNewPrivileges, ReadWritePaths=/tmp, WorkingDirectory=/var/lib/nordvpn).
  • Capabilities locked to exactly CAP_NET_ADMIN (CapEff/CapBnd/CapPrm/CapAmb/CapInh all 0x1000).
  • tun + wireguard kernel modules auto-loaded.
  • norduserd starts as a user service via default.target (no graphical session needed).
  • A real nordvpn connect establishes a tunnel under the sandbox*(connected through a NordVPN server, got an exit IP) and disconnect works. no sandbox violations during the connection.

Looks good from my side

@romildo

romildo commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Built a VM from this PR and verified the sandboxing lands and doesn't break anything:

* All the new directives are active on `nordvpnd` (`ProtectSystem=strict`, `RestrictAddressFamilies`, `RestrictNamespaces`, `ProtectControlGroups`, `DeviceAllow=/dev/net/tun`, `NoNewPrivileges`, `ReadWritePaths=/tmp`, `WorkingDirectory=/var/lib/nordvpn`).

* Capabilities locked to exactly `CAP_NET_ADMIN` (`CapEff`/`CapBnd`/`CapPrm`/`CapAmb`/`CapInh` all `0x1000`).

* `tun` + `wireguard` kernel modules auto-loaded.

* `norduserd` starts as a user service via `default.target` (no graphical session needed).

* A real `nordvpn connect` establishes a tunnel under the sandbox*(connected through a NordVPN server, got an exit IP) and `disconnect` works. no sandbox violations during the connection.

Looks good from my side

Is this an approval for merging?

@BerriJ BerriJ Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove line 16 now since networking.firewall.checkReversePath now defaults to loose (see #550306) . This also means that the comment below (L20) can also be removed.

@different-error different-error Sep 8, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, very cool. Thank you for pointing this out. I intend to include the following changes in the next pr (for meshnet):

Additionally, others may only want to update the unstable commit for nordvpn package and therefore might miss the new firewall change, making the proposed documentation changes premature.

I therefore think it more appropriate to move the proposed documentation changes to the next pr (which would include meshnet).

Edit: oops, I confused my local setup with unstable. Sounds good.

@nixpkgs-ci nixpkgs-ci Bot removed the 9.needs: reviewer This PR currently has no reviewers requested and needs attention. label Sep 6, 2026
@different-error
different-error force-pushed the nordvpn-security-tightening branch 2 times, most recently from e186511 to b004542 Compare September 8, 2026 15:41
@different-error

Copy link
Copy Markdown
Contributor Author

Is this an approval for merging?

@romildo yes; GITHUB actions seems to not work on this PR atm. The URL to this PR responds with a 404. I don't quite understand yet why this has happened.

@different-error
different-error force-pushed the nordvpn-security-tightening branch from b004542 to fbb5e13 Compare September 9, 2026 05:40
@nixpkgs-ci nixpkgs-ci Bot added the 12.first-time contribution This PR is the author's first one; please be gentle! label Oct 17, 2026
@different-error
different-error force-pushed the nordvpn-security-tightening branch from fbb5e13 to 7d39ca0 Compare October 17, 2026 16:33

@nixpkgs-ci nixpkgs-ci Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing to the documentation.

Follow the documentation style guide, especially:

  • Show, don’t tell. Start with a minimal working example. Explain after the code.
  • Avoid meta-commentary. Don’t write "This section explains how to…".
  • Use present tense, imperative mood, and active voice. For example: "Run the command," not "The user should run the following command."
  • Avoid vague references like "this" when the referent is unclear. Write "This command creates a folder," not "This will create a folder."
  • Be direct. Avoid "should", "might", "typically", and "usually".
  • Cut filler words like "simply", "just", "easily", and "basically". Use "to" instead of "in order to".

For larger changes, such as adding or removing whole sections, ask the NixOS documentation team for review.

@different-error
different-error force-pushed the nordvpn-security-tightening branch from 7d39ca0 to 581e26f Compare October 17, 2026 16:45
- shrink blast radius of a compromised nordvpnd
- ensure prerequisite kernel modules have loaded
- fix norduserd systemd user service to restart on rebuilds
- run go test recursively
- update documentation; firewall.checkReversePath defaults to "loose"

Assisted-by: Claude Code (Claude Sonnet 5)
@different-error
different-error force-pushed the nordvpn-security-tightening branch from 581e26f to c1fd43f Compare October 17, 2026 16:59
@different-error

Copy link
Copy Markdown
Contributor Author

@romildo I had a temporary disputed account suspension. I've rebased on top of latest master and added myself back as maintainer. Verified that cli and gui work for both protocols. Thank you for your patience and perhaps we can move forward with this?

@novalkun fyi

@nixpkgs-ci
nixpkgs-ci Bot requested a review from novalkun October 17, 2026 17:05
@nixpkgs-ci nixpkgs-ci Bot added the 8.has: maintainer-list (update) This PR changes `maintainers/maintainer-list.nix` label Oct 17, 2026
@novalkun

Copy link
Copy Markdown
Contributor

This exact change has also been independently verified on my end via #568291 (build + VM test + live hardware, same sandboxing/test changes). Good to see you back — will close #568291 in favor of this one to avoid duplicate diffs.

@novalkun novalkun left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. thanks

@nixpkgs-ci nixpkgs-ci Bot added 12.approvals: 1 This PR was reviewed and approved by one person. 12.approved-by: package-maintainer This PR was reviewed and approved by a maintainer listed in any of the changed packages. labels Oct 17, 2026
@romildo
romildo added this pull request to the merge queue Oct 18, 2026
Merged via the queue into NixOS:master with commit a2ed8f5 Oct 18, 2026
31 checks passed
novalkun added a commit to novalkun/nixpkgs that referenced this pull request Oct 19, 2026
Adds meshnet (libtelio) and fileshare (libdrop) support, both fully
open-source/GPLv3 and gated behind upstream's own telio/drop/cdnrc Go
build tags (moose/quench stay out of scope, proprietary-only).

- nordvpnd gains a --hosts-readonly flag backed by a NoopHostsSetter
  (daemon/dns/hosts.go), so /etc/hosts is never written to. Peer hostnames
  do not resolve as a result; connect by meshnet IP instead.
- builds and installs cmd/fileshare as nordfileshare; its and
  norduserd's unix sockets are chowned to the nordvpn group so
  processes running as a different user than nordvpnd (which runs
  unprivileged) can reach them.
- only start the norduserd user service for members of the configured
  group, since other users cannot assign their socket to that group.
- adds CAP_NET_RAW (libtelio needs it for ping) and nordlynx to
  networking.firewall.trustedInterfaces.
- sets the RemotePath ldflag to upstream's documented default
  (.env.sample: /apps/linux/config). Without it, remote-config
  downloads that gate meshnet/libtelio resolve to the wrong CDN path.
- run daemon/dns tests, including the read-only hosts setter, except
  nameserver discovery, which needs a gateway absent from the sandbox.
- expand nixosTests.nordvpn to check trusted interfaces, socket modes
  and groups, the expected fileshare exit code while meshnet is disabled,
  and skipped services for non-members across all user/group combinations.
- document meshnet support and its hostname limitation in the release notes.

Rebased onto master's merged nixos/nordvpn: make more secure and robust
(NixOS#547437): reconciled the refactored nixosTests.nordvpn
UserGroupTestCase, the broader checkPhase daemon test coverage, and the
full systemd sandboxing directive set with this branch's meshnet-specific
additions on top.

Based on independent work by different-error, who could not push this
directly due to a disputed account suspension. Credited via Co-authored-by.

Co-authored-by: different-error <[email protected]>
Assisted-by: Claude Code (Sonnet 5, claude-sonnet-5)
Assisted-by: OpenCode (GPT-6.1 Sol, openai/gpt-6.1-sol)
@novalkun novalkun mentioned this pull request Oct 19, 2026
6 of 13 tasks
novalkun added a commit to novalkun/nixpkgs that referenced this pull request Oct 20, 2026
Adds meshnet (libtelio) and fileshare (libdrop) support, both fully
open-source/GPLv3 and gated behind upstream's own telio/drop/cdnrc Go
build tags (moose/quench stay out of scope, proprietary-only).

- nordvpnd gains a --hosts-readonly flag backed by a NoopHostsSetter
  (daemon/dns/hosts.go), so /etc/hosts is never written to. Peer hostnames
  can be mapped declaratively via networking.hosts instead (documented).
- builds and installs cmd/fileshare as nordfileshare; its and
  norduserd's unix sockets are chowned to the nordvpn group so
  processes running as a different user than nordvpnd (which runs
  unprivileged) can reach them.
- only start the norduserd user service for members of the configured
  group, since other users cannot assign their socket to that group.
- adds CAP_NET_RAW (libtelio needs it for ping) and nordlynx to
  networking.firewall.trustedInterfaces.
- sets the RemotePath ldflag to upstream's documented default
  (.env.sample: /apps/linux/config). Without it, remote-config
  downloads that gate meshnet/libtelio resolve to the wrong CDN path.
- run daemon/dns tests, including the read-only hosts setter, except
  nameserver discovery, which needs a gateway absent from the sandbox.
- expand nixosTests.nordvpn to check trusted interfaces, socket modes
  and groups, the expected fileshare exit code while meshnet is disabled,
  and skipped services for non-members across all user/group combinations.
- document meshnet support and its hostname limitation in the release notes.

Rebased onto master's merged nixos/nordvpn: make more secure and robust
(NixOS#547437): reconciled the refactored nixosTests.nordvpn
UserGroupTestCase, the broader checkPhase daemon test coverage, and the
full systemd sandboxing directive set with this branch's meshnet-specific
additions on top.

Based on independent work by different-error, who could not push this
directly due to a disputed account suspension. Credited via Co-authored-by.

Co-authored-by: different-error <[email protected]>
Assisted-by: Claude Code (Sonnet 5, claude-sonnet-5)
Assisted-by: OpenCode (GPT-6.1 Sol, openai/gpt-6.1-sol)
Assisted-by: Claude Code (Opus 5.5, claude-opus-5-5)
novalkun added a commit to novalkun/nixpkgs that referenced this pull request Oct 20, 2026
Adds meshnet (libtelio) and fileshare (libdrop) support, both fully
open-source/GPLv3 and gated behind upstream's own telio/drop/cdnrc Go
build tags (moose/quench stay out of scope, proprietary-only).

- nordvpnd gains a --hosts-readonly flag backed by a NoopHostsSetter
  (daemon/dns/hosts.go), so /etc/hosts is never written to. Peer hostnames
  can be mapped declaratively via networking.hosts instead (documented).
- builds and installs cmd/fileshare as nordfileshare; its and
  norduserd's unix sockets are chowned to the nordvpn group so
  processes running as a different user than nordvpnd (which runs
  unprivileged) can reach them.
- only start the norduserd user service for members of the configured
  group, since other users cannot assign their socket to that group.
- adds CAP_NET_RAW (libtelio needs it for ping) and nordlynx to
  networking.firewall.trustedInterfaces.
- sets the RemotePath ldflag to upstream's documented default
  (.env.sample: /apps/linux/config). Without it, remote-config
  downloads that gate meshnet/libtelio resolve to the wrong CDN path.
- run daemon/dns tests, including the read-only hosts setter, except
  nameserver discovery, which needs a gateway absent from the sandbox.
- expand nixosTests.nordvpn to check trusted interfaces, socket modes
  and groups, the expected fileshare exit code while meshnet is disabled,
  and skipped services for non-members across all user/group combinations.
- document meshnet support and its hostname limitation in the release notes.

Rebased onto master's merged nixos/nordvpn: make more secure and robust
(NixOS#547437): reconciled the refactored nixosTests.nordvpn
UserGroupTestCase, the broader checkPhase daemon test coverage, and the
full systemd sandboxing directive set with this branch's meshnet-specific
additions on top.

Based on independent work by different-error, who could not push this
directly due to a disputed account suspension. Credited via Co-authored-by.

Co-authored-by: different-error <[email protected]>
Assisted-by: Claude Code (Sonnet 5, claude-sonnet-5)
Assisted-by: OpenCode (GPT-6.1 Sol, openai/gpt-6.1-sol)
Assisted-by: Claude Code (Opus 5.5, claude-opus-5-5)
@different-error
different-error deleted the nordvpn-security-tightening branch October 21, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: maintainer-list (update) This PR changes `maintainers/maintainer-list.nix` 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 12.approvals: 1 This PR was reviewed and approved by one person. 12.approved-by: package-maintainer This PR was reviewed and approved by a maintainer listed in any of the changed packages. 12.first-time contribution This PR is the author's first one; please be gentle! llm-assisted Contributions that include code generation with LLMs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants