NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
16.43k stars 12.93k forks source link

[package request]: NordVPN #101864

Open dmedinag opened 3 years ago

dmedinag commented 3 years ago

Project description NordVPN's native app is the only way to access some of their VPN features. They provide .deb and .rpm packages, which are compatible with various Debian-based and RHEL-based systems, however I don't know enough about nix/nixpkgs to know whether we can use these in NixOS.

Metadata

jakubdaniel commented 3 years ago

I have no idea what I am doing but following a blog post over at reflexivereflection.com and the nixos wiki about deb packages in nixos lead me to nordvpn.nix and builder.sh

nix-env -f nordvpn.nix nordvpn
sudo nordvpnd # this complains about public keys
nordvpn # prints help, anything else does not work due to nordvpnd not running
SrTobi commented 3 years ago

I was able to run the nordvpn service by running it in a bubblewrap environment... This makes nordvpnd find the stuff it expects under /var/lib/nordvpn/... unfortunately the service wants to write into /var/lib/nordvpn/data/settings.dat and because that is mounted as read only it fails

2020/11/08 19:03:39 [Error] open /var/lib/nordvpn/data/settings.dat: read-only file system
2020/11/08 19:03:39 [Error] open /var/lib/nordvpn/data/settings.dat: no such file or directory

Here is the code. nordvpn is here just the definition from @jakubdaniel

pkgs.buildFHSUserEnvBubblewrap {
  name = "nordvpnd";
  targetPkgs = pkgs: [ nordvpn ];
  runScript = "${nordvpn}/usr/sbin/nordvpnd";
}

Maybe anyone else has a tip how to circumvent this issue?

michzappa commented 3 years ago

I have been playing around with this for the last day and it seems to be a very interesting thing to try and package for nix. The .deb only adds a GPG key and the location of the nordvpn repository to your apt package manager, so you can then download and update the package through apt normally. This means that one cannot use the same style of packaging as we see in other .deb packages like opera, skype, or teams.

michzappa commented 3 years ago

Currently trying to see if there is a compiled binary somewhere on their repository and try packaging that directly, but probably will run into an issue of needing the GPG key.

thornycrackers commented 3 years ago

Disclaimer: I've only recently started using nix. I've been working on this a little bit and I think I've narrowed down exactly where the issue lies. First I've updated the nordvpn version to the latest because it will complain if it isn't the latest. Here is my first file nordvpnd.nix that combines all the stuff from this thread so far:

{ pkgs ? import <nixpkgs> {} }:

with pkgs;
let
  nordvpn = stdenv.mkDerivation {
      name = "nordvpn";

      src = fetchurl {
        url = "https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn_3.8.8_amd64.deb";
        sha256 = "0v6r3wwnsk5pdjr188nip3pjgn1jrn5pc5ajpcfy6had6b3v4dwm";
      };

      nativeBuildInputs = [ dpkg ];

      phases = [ "unpackPhase" "installPhase" "fixupPhase" "distPhase" ];

      unpackPhase = "dpkg -x $src unpacked";

      installPhase = ''
        mkdir -p $out/usr
        cp -r unpacked/* $out/
        patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/usr/bin/nordvpn
        patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/usr/sbin/nordvpnd
      '';

      dontPatchShebangs = true;
      dontStrip = true;
      dontPatchELF = true;
      dontAutoPatchelf = true;

  };
in pkgs.buildFHSUserEnvBubblewrap {
  name = "nordvpnd";
  targetPkgs = pkgs: [ nordvpn ];
  runScript = "${nordvpn}/usr/sbin/nordvpnd";
}

So if you take that file and place it somewhere and execute nix-build nordvpnd.nix as root and then run ./result/bin/nordvpnd you should see the error first:

Error on listening to UNIX domain socket: listen unix /run/nordvpn/nordvpnd.sock: bind: no such file or directory`

It looks like they've updated the located of the socket so you will have to mkdir /run/nordvpn and rerun again to get:

open /var/lib/nordvpn/data/settings.dat: read-only file system

If you run it mutliple times you might also run into:

Error on listening to UNIX domain socket: listen unix /run/nordvpn/nordvpnd.sock: bind: address already in use

in which case you can you can just remove /run/nordvpn/nordvpnd.sock and run it again. Ok, now that we have everything set up here is where this becomes an issue. When you unpack nordvpn with dpkg -x $src unpacked you can see that it contains 3 folders etc, usr, and var. Now if you look at the pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix for the buildFHSUserEnvBubblewrap command you will notice this script in the bwrapCmd:

for i in ${env}/*; do
  path="/''${i##*/}"
  if [[ $path == '/etc' ]]; then
    continue
  fi
  echo $i $path
  ro_mounts+=(--ro-bind "$i" "$path")
  blacklist+=("$path")
done

Where env is the bubble wrapped filesystem. Essentially this means that any folder that is created by the package, in our case we create a /var/. will be marked as readonly and therefore can't be written to. So unfortunately seems like and edge case that isn't handled with BubbleWrap so I don't think that's going to work. If we can't bubble wrap though it is possible to just manually move the files that are required onto our "host" system. Consider the following file which is essentially the above one without the bubblewrap (I called this one nordvpn.nix)

{ pkgs ? import <nixpkgs> {} }:

with pkgs;
stdenv.mkDerivation {
    name = "nordvpn";

    src = fetchurl {
      url = "https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn_3.8.8_amd64.deb";
      sha256 = "0v6r3wwnsk5pdjr188nip3pjgn1jrn5pc5ajpcfy6had6b3v4dwm";
    };

    nativeBuildInputs = [ dpkg ];

    phases = [ "unpackPhase" "installPhase" "fixupPhase" "distPhase" ];

    unpackPhase = "dpkg -x $src unpacked";

    installPhase = ''
      mkdir -p $out/usr
      cp -r unpacked/* $out/
      patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/usr/bin/nordvpn
      patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/usr/sbin/nordvpnd
    '';

}

After that you can run nix-build nordvpn.nix and you will again get your result folder that has all the required files. You can execute ./result/usr/sbin/nordvpnd to get the daemon running and then if you get complaints such as:

retrieving public key from vault: error reading file: open /var/lib/nordvpn/data//rsa-key-1.pub: no such file or directory

You can just copy the file manually like so:

cp result/var/lib/nordvpn/data/rsa-key-1.pub /var/lib/nordvpn/data/

and then re-run the ./result/usr/sbin/nordvpnd command. Or just copy the entire result/var/lib/nordvpn over. I've got nordvpnd running but I've still not been able to get is to connect, although it does allow me to login to my account. If I run ./result/usr/sbin/nordvpnd in one terminal and try to connect with ./result/usr/bin/nordvpn connect in another one the daemon will print out all of the commands but in the client window it says it fails. This part is starting to get beyond me so I'll probably give up here. I've spent quite a bit of time tinkering and hopefully this will help someone else who's trying to take a full stab at this problem better understand the issue.

domust commented 3 years ago

I'm still new to NixOS, so I don't know how to go about implementing this.. I think I understand what needs to be done:

  1. Debian package has to be downloaded.
  2. It's contents need to be extracted into the output directory.
  3. ELF needs to be patched to not rely on FHS.
  4. SystemD files need to be included from the original package.
  5. Sandboxing the app is not going to work, because it needs read/write access to some parts of the system, which are global, for example, firewall.
  6. When installed, user needs to be added to nordvpn group to be able to invoke nordvpn commands, due to socket permissions. Same as docker requires docker group.
  7. Metadata has to be added to mark this as a non free package.

I'm still not sure how to test this derivation locally.. What I've done so far is sudo nix-env -i -f default.nix, but it does not place binaries in the path. SystemD files are also not detected.. Therefore I'm unable to see if this actually works before submitting code changes.

I was not able to run the daemon like described in the comments above:

./result/usr/sbin/nordvpnd

2020/12/31 20:14:17 [Info] Daemon has started
2020/12/31 20:14:17 Error on listening to UNIX domain socket: listen unix /run/nordvpn/nordvpnd.sock: bind: no such file or directory

and

./result/usr/bin/nordvpn status

Whoops! /run/nordvpn/nordvpnd.sock not found

which basically means that systemd does not create socket..

I've tried linking service and socket files manually, but it seems that I'm unable to do so..

sudo systemctl link result/usr/lib/systemd/system/*
Failed to link unit: File /etc/systemd/system/nordvpnd.service: Read-only file system

Here is how my current derivation looks like.

cat default.nix

{ pkgs ? import <nixpkgs> {} }:

with pkgs;

stdenv.mkDerivation {
    name = "nordvpn";

    src = fetchurl {
        url = "https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn_3.8.9_amd64.deb";
        sha256 = "7af59ef35c0f9c6bda3ad8cab1d962b340a7a030725e857413b28f9458c950b7";
    };

    nativeBuildInputs = [ dpkg ];

    phases = [ "unpackPhase" "installPhase" "fixupPhase" "distPhase" ];

    unpackPhase = "dpkg -x $src unpacked";

    installPhase = ''
        mkdir -p $out/usr
        cp -r unpacked/* $out/
        patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/usr/bin/nordvpn
        patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/usr/sbin/nordvpnd
    '';

    dontPatchShebangs = true;
    dontStrip = true;
    dontPatchELF = true;
    dontAutoPatchelf = true;
}
domust commented 3 years ago

Today I've tried following Nixpkgs documentation: https://nixos.org/manual/nixpkgs/stable/#submitting-changes-making-patches

My fork of Nixpkgs: https://github.com/domust/nixpkgs/commit/b92e6875c33b6ff9d217c8cb23be33a0efddad70

I've added the following lines to my /etc/nixos/configuration.nix:

  nixpkgs.config.allowUnfree = true;
  environment.systemPackages = with pkgs; [
    nordvpn
  ];

and executed the following command:

sudo nixos-rebuild switch -I /home/-/devel/nixpkgs
building Nix...
building the system configuration...
error: undefined variable 'nordvpn' at /etc/nixos/configuration.nix:52:5
(use '--show-trace' to show detailed location information)

Am I missing something? I don't understand the reason behind this error, because I've added the package here: https://github.com/domust/nixpkgs/commit/b92e6875c33b6ff9d217c8cb23be33a0efddad70#diff-ab5748dc9567516fefba8344056b51ec1866adeace380f46e58a7af3d619ea22R15498

domust commented 3 years ago

I think I have made significant progress today. I needed to define service module, which handles systemd services. My code so far: https://github.com/domust/nixpkgs/commit/1ccd3e1928e89bb313dfbf75eea49c7b1c7c26c0

This article helped tremendously: https://nixos.wiki/wiki/NixOS:extend_NixOS Also, a lot of reading of nixpkgs, for example, how docker accomplishes virtualization.docker.enable = true; type of installation. Currently I'm testing my changes, because I'm still not sure if it works.

chuahou commented 3 years ago

I managed to make some progress using your (@domust) fork as an overlay with some additional modifications:

The first two are due to Nix in general (as well as your service) assuming that bin/ and sbin/ belong in $out rather than $out/usr.

With these modifications, the CLI tool and service run, but the next obstacle to solve would be nordvpnd looking for the files in /var/lib/nordvpn, which fails as they are located in /nix/store/${hash}-nordvpn-3.8.9/var/lib/nordvpn instead—I'll check back in if I make progress on that front.

aanderse commented 3 years ago

@domust you can replace both the systemd service and socket declaration with systemd.packages = [ pkgs.nordvpn ]; because the package already ships these files :+1: Just make sure you patch any incorrect absolute paths in the nordvpn derivation.

domust commented 3 years ago

I have made changes according to @chuahou and @aanderse comments. The resulting code is here: https://github.com/domust/nixpkgs/commit/4a0edd7145826d5fdeea6aa60c63c1368b6e03c4

But unlike @chuahou, I'm still unable to run the app and verify my changes. I'm testing them using build-vm command. VM configuration is in a file named vmtest.nix with the following contents:

{config, pkgs, ...}:

{
  # You need to configure a root filesytem
  fileSystems."/".label = "vmdisk";

  # The test vm name is based on the hostname, so it's nice to set one
  networking.hostName = "vmhost";

  # Add nordvpn group
  users.groups.nordvpn = {};

  # Add a test user who can sudo to the root account for debugging
  users.extraUsers.vm = {
    password = "vm";
    shell = "${pkgs.bash}/bin/bash";
    group = "wheel";
    extraGroups = [ "nordvpn" ];
  };
  security.sudo = {
    enable = true;
    wheelNeedsPassword = false;
  };

  nixpkgs.config.allowUnfree = true;
  # Enable your new service!
  services.nordvpn.enable = true;
}

I'm building vm with the following command while at the root of nixpkgs repository:

NIXOS_CONFIG=`pwd`/vmtest.nix nixos-rebuild -I nixpkgs=`pwd` -I nixos=`pwd`/nixos/ build-vm

When I run a resulting vm with ./result/bin/run-vmhost-vm and login into vm user, I cannot find nordvpn in path. systemctl status nordvpnd reports service not found.

chuahou commented 3 years ago

@domust I'm not overly familiar with the correct way in NixOS yet, but I believe you need to also have environment.systemPackages = [ pkgs.nordvpn ]; to have the package in your path, as systemd.packages will only handle the systemd units. If you do that you should be able to run nordvpn.

Also, the systemd units are nordvpn.service and nordvpn.socket (without the d), which is why systemctl status nordvpnd would report "not found". Edit: The units indeed do have the d, so I'm not sure why it reports "service not found". I misremembered it as not having the d as the previous manually written units were named systemd.(services|sockets).nordvpn.

Lastly, I should probably clarify that I managed to get the service and CLI tool to run (start and produce output), but not to run correctly, as they still produce errors I unfortunately haven't been able to try fixing yet.

domust commented 3 years ago

@chuahou I was under impression that writing service like this allows to have one line install just like in the docker example above, especially when the software is designed to be run as a service and stand alone package is not that useful on its own.

I've also added environment.systemPackages = [ pkgs.nordvpn ]; to vmtest.nix. This time new vm does not even boot. Bootlogs show that both dhcpcd.service and nscd.service failed to start and ~the system just keeps trying to start them and never exits the boot loop~ it eventually booted but it does not accept the password found in vmtest.nix :confused: .

chuahou commented 3 years ago

@domust If I'm not wrong that will install the systemd units and the software the units run (i.e. nordvpnd), but nordvpn is the CLI tool for the user to call, so for that to be added to the path in the user environment you would need environment.systemPackages.

For example, for blueman these lines show adding the user executables, the DBus configuration and the systemd units respectively.

domust commented 3 years ago

It seems that I've hit this issue: https://github.com/NixOS/nixpkgs/issues/97305 That's why I'm having problems booting the vm and the password seems not to work.

Deleting the qcow2 image solves the problem. After booting new vm and logging in I've found nordvpn in PATH, but the systemctl status nordvpnd reported that service is dead. Thanks again @chuahou

domust commented 3 years ago

I think I know why service is dead: nordvpnd.service has hardcoded ExecStart=/usr/sbin/nordvpnd.

@chuahou Would it be possible to change the value of ExecStart to nix store path during fixupPhase or is there some other way to solve this problem? I've tried referring to the derivation's store path from within the derivation:

{ fetchurl, dpkg, patchelf, stdenv
}:

let drv = stdenv.mkDerivation rec {
  pname = "nordvpn";
  version = "3.8.10";

  src = fetchurl {
    url = "https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/${pname}_${version}_amd64.deb";
    sha256 = "e27ba637dffc766b99161805f525b87716c8d36186d09abea61f6094af87a9fe";
  };

  nativeBuildInputs = [
    dpkg
    patchelf
  ];

  phases = [ "unpackPhase" "installPhase" "fixupPhase" ];

  unpackPhase = "dpkg -x $src unpacked";

  installPhase = ''
      mkdir -p $out
      cp -r unpacked/* $out/
      mv $out/usr/* $out
      rmdir $out/usr
  '';

  fixupPhase = ''
      patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/bin/nordvpn
      patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/sbin/nordvpnd
      patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/var/lib/nordvpn/openvpn

      sed '/ExecStart/c\ExecStart=${drv}/sbin/nordvpnd' -i $out/lib/systemd/system/nordvpnd.service
  '';

  meta = with stdenv.lib; {
    homepage = "https://nordvpn.com";
    description = "Client for NordVPN";
    changelog = "https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/${pname}_${version}_amd64.changelog";
    license = licenses.unfree;
    platforms = [ "x86_64-linux" ];
   };
}; in drv

but got this error: error: infinite recursion encountered, at undefined position

I could probably avoid this problem by moving this to service derivation, but I'm not sure if it has anything like fixupPhase to allow partial modification of service file instead of having to redefine it completely like I've done previously.

jtojnar commented 3 years ago

Right, that is because in order to evaluate drv variable you need to evaluate drv inside the string. Instead of interpolating drv Nix variable, just use $out environment variable. Or interpolate placeholder "out" Nix expression.

domust commented 3 years ago

@jtojnar's solution worked. I was able to run the service, but new problems appeared:

  1. Service is not started by default, I've probably missed something in the service configuration.
  2. The daemon tries to access files at /var/lib/nordvpn/data/, but those are at $out/var/lib/nordvpn/data/ and I was thinking if I could do something like patchelf again.
thornycrackers commented 3 years ago

I was able to get the code at the end of my last post working by disabling the built in firewall:

networking.firewall.enable = false;

and then adding iptables to my packages. I can only connect with nordlynx I wasn't able to figure out the issue with openvpn.

domust commented 3 years ago

@thornycrackers if I understand correctly, patching ELF is error prone and due to new path being longer than original, patching would require binary padding. On the other hand, using mount namespaces with FHS is easier(which is what bubblewrap can do). What I don't understand about bubblewrap is how you've managed to connect, because their README clearly states that:

Bubblewrap could be viewed as setuid implementation of a subset of user namespaces. Emphasis on subset - specifically relevant to the above CVE, bubblewrap does not allow control over iptables.

Iptables should not work at all. :confused:

thornycrackers commented 3 years ago

The bash script that does the bind mounting won't work in it's current implementation for nordvpn. You can see my post for an explanation. Nordvpn needs write access for /var/lib/nordvpn/data/settings.dat. To give it write access you'd need to use a bind mount to the host system, which won't work because the nordvpn has a var in it's unpackaged directory. I have the following solution to just get nordvpn working, it is ugly but at least I can use the VPN. I ran the following commands as root:

  1. create nordvpn.nix
    
    { pkgs ? import <nixpkgs> {} }:

with pkgs; stdenv.mkDerivation { name = "nordvpn";

src = fetchurl {
  url = "https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn_3.8.8_amd64.deb";
  sha256 = "0v6r3wwnsk5pdjr188nip3pjgn1jrn5pc5ajpcfy6had6b3v4dwm";
};

nativeBuildInputs = [ dpkg ];

phases = [ "unpackPhase" "installPhase" "fixupPhase" "distPhase" ];

unpackPhase = "dpkg -x $src unpacked";

installPhase = ''
  mkdir -p $out/usr
  cp -r unpacked/* $out/
  patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/usr/bin/nordvpn
  patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/usr/sbin/nordvpnd
'';

}


2. Make sure `networking.firewall.enable = false;` but you have `iptables` installed. Something with the generated rules messes with nordvpn and I don't know how to figure out exactly what the issue is but I had to do this or when I tried to connect it would just kill my internet connection.
3. `nix-build nordvpn` to build the package. For readers unfamiliar this will create the `result` directory with the files.
4. `cp -r result/var/lib/nordvpn /var/lib/nordvpn` I just manually copy these files to my host system. 
5. in terminal 1 run `./result/usr/sbin/nordvpnd` to start the daemon. This command might complain about `listen unix /run/nordvpn/nordvpnd.sock:` in which case you just need to `mkdir /run/nordvpn`
6. In terminal 2 run `./result/usr/bin/nordvpn login` to get access to your account.
7. In terminal 2 run `./result/usr/bin/nordvpn set technology nordlynx` to set the technology to nordlynx. I've tried adding the patchelf command on the `/var/lib/nordvpn/openvpn` file but it didn't change the outcome for me. I couldn't get the service to ever start with openvpn only nordlynx.
8. In terminal 2 run `./result/usr/bin/nordvpn connect`

This will get you a Frankenstein version of Nordvpn working, it's ugly but I haven't seen any other way to get NordLynx working on NixOS. 
domust commented 3 years ago

@thornycrackers I think I know how to get around problem number 4. https://www.freedesktop.org/software/systemd/man/systemd.exec.html#WorkingDirectory= I have found this in gitea's derivation: https://github.com/NixOS/nixpkgs/blob/release-19.03/nixos/modules/services/misc/gitea.nix#L407

In short, we need a way to manage mutable application data, which for most Linux applications is stored in /var/lib. I think working directory works for gitea, because they are using relative paths. In our case, paths are absolute, so https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RootDirectory= might make more sense.

milahu commented 3 years ago

all the mainstream VPN providers expect their users to install CLOSED SOURCE software which is 100% ridiculous, given that openVPN and wireguard are open source protocols and the only good reason for closed source is spyware and backdoors

all that the client must do is login and download keys for crypto (two http requests) which can be implemented in like 100 lines of bash code

i recommend https://www.privateinternetaccess.com/ as VPN provider

they offer multiple open source clients https://github.com/pia-foss/manual-connections https://github.com/pia-foss/manual-connections#3rd-party-repositories https://github.com/pia-foss/desktop https://github.com/pia-foss/android

to get wireguard working, see https://github.com/NixOS/nixpkgs/pull/110197

juliosueiras commented 2 years ago

so here

juliosueiras commented 2 years ago

will make a draft PR in a bit

SrTobi commented 2 years ago

Today I found out, that NordVPN actually supports OpenVpn. It's not as great as the software in terms of automatically selecting a country or a good server for you, but I don't have to install any additional software which is great. See this page: https://nordvpn.com/de/ovpn/

Be aware that ipv6 is not supported and thus may leak if you connect via ipv6. I tried to disable ipv6 with networking.enableIPv6 = false, but that lead to all kinds of strange network problems :disappointed:

bernardoaraujor commented 2 years ago

Today I found out, that NordVPN actually supports OpenVpn. It's not as great as the software in terms of automatically selecting a country or a good server for you, but I don't have to install any additional software which is great. See this page: https://nordvpn.com/de/ovpn/

Be aware that ipv6 is not supported and thus may leak if you connect via ipv6. I tried to disable ipv6 with networking.enableIPv6 = false, but that lead to all kinds of strange network problems disappointed

@SrTobi could you expand on your comment? when you say ipv6 is not supported and thus may leak, what do you mean, specifically?

I'm asking because I just migrated into a fresh nixOS setup, and I need to mix a nordvpn and wireguard (ipv6) tunnels. I'm calculating the best approach for nordvpn, since it seems there's not yet any canonical solution to the problem

SrTobi commented 2 years ago

@bernardoaraujor as far as I understand it, NordVPN (as most VPN provider) does not offer vpn support for ipv6. This would mean that when your computer determines to use ipv6 for a certain connection (like a tcp connection for a http request/response), this connection would not go through your VPN but just directly. It can chose to use ipv6 in situations where your computer, your isp, the dns server, and the targeted server all support ipv6. You can check your ipv6 status here for example: https://test-ipv6.com/.

Because this would not be great for your anonymity, the NordVPN software "goes the extra mile" and blocks ipv6 (I think directly in the network interface) when the vpn is active. In that way they ensure that your whole traffic goes over ipv4 and thus over the vpn. you can read about their leak protection here.

But if you are just using the normal openvpn software with a specific nordvpn server, no one is blocking your ipv6 interface and thus some connections might chose to bypass the VPN.

To avoid this, I am disabling ipv6 in my wlan connection at the moment, but I think networking.enableIPv6 = false is the better solution. I haven't tested it again, but I think the problems I reported previously might have been unrelated to this option (I think it was a driver problem).

Hope that helped

bernardoaraujor commented 2 years ago

@SrTobi yea quite helpful thanks 🙏

svalaskevicius commented 1 year ago

regarding firewall:

the UDP (source) port 51820 needs to be enabled - not sure yet how to configure it in the nixpkgs for the package though

-A PREROUTING -j nixos-fw-rpfilter
-A nixos-fw-rpfilter -m rpfilter --validmark -j RETURN
-A nixos-fw-rpfilter -p udp -m udp --sport 67 --dport 68 -j RETURN
-A nixos-fw-rpfilter -s 0.0.0.0/32 -d 255.255.255.255/32 -p udp -m udp --sport 68 --dport 67 -j RETURN

-A nixos-fw-rpfilter -p udp -m udp --sport 51820 -j RETURN

-A nixos-fw-rpfilter -j DROP

Note: this rule may still be unstable as I hadn't tested it for a long time

ohxxm commented 1 year ago

Any update on this? Would love to see this packaged.

svalaskevicius commented 1 year ago

@Spaxly I am using the work done by the ppl in the above comments: https://github.com/svalaskevicius/nixpkgs/blob/master/pkgs/tools/networking/nordvpn/default.nix (possibly updated version)

afaik, the few steps missing are:

  1. set up /var/lib/nordvpn dir with data from the package
  2. auto create /var/run/nordvpn
  3. maybe add nordvpn user group (I think I noticed a warning about it) or otherwise permission the created socket (I just chmod it every time)
  4. set up the firewall with the -A nixos-fw-rpfilter -p udp -m udp --sport 51820 -j RETURN rule

Unfortunately, I don't think I have enough time currently to figure out how to do all that in the nixpkg - help would be appreciated! :)

ohxxm commented 1 year ago

Oh alright, thanks!

clefru commented 6 months ago

OT but working alternative to packaging the non-free app:

nix-shell -p wgnord
mkdir -p /var/lib/wgnord
curl https://raw.githubusercontent.com/phirecc/wgnord/master/template.conf > /var/lib/wgnord/template.conf
wgnord l $YOUR_CREDS_SEE_GITHUB_REPO_HOW_TO_GET_IT
wgnord c germany

wgnord writes a wg-quick target to /etc/wireguard, which can be added to

networking.wg-quick.interfaces.wgnord = "/etc/wireguard/wgnord.conf"

See the GitHub repo for more information: https://github.com/phirecc/wgnord

sarahec commented 1 month ago

Nord released the client in source form (GPL3) at the start of the year. I'm having partial success getting it to build (Go compiler errors), but chipping away at it. That would get us a native build.