Open getreu opened 7 months ago
I'm attempting building from source. @keliramu I may have questions for you from time to time, but most of the help will need to come from other nix package maintainers.
I managed to write a nix package to compile from source, the nix package can be contributed to this project and built locally using src = ./.
and $ nix-build -E 'with import <nixpkgs> {}; callPackage ./default.nix {}'
default.nix
in the project code or (something like) nordvpn.nix
in your os config:
{ pkgs, lib, gcc, autoPatchelfHook, ... }:
let
patchedPkgs = pkgs.appendOverlays [
(final: prev: {
# Nordvpn uses a patched openvpn in order to perform xor obfuscation
# See https://github.com/NordSecurity/nordvpn-linux/blob/e614303aaaf1a64fde5bb1b4de1a7863b22428c4/ci/openvpn/check_dependencies.sh
openvpn = prev.openvpn.overrideAttrs (old: {
patches = (old.patches or [ ]) ++ [
(prev.fetchpatch {
url =
"https://github.com/Tunnelblick/Tunnelblick/raw/master/third_party/sources/openvpn/openvpn-${old.version}/patches/02-tunnelblick-openvpn_xorpatch-a.diff";
hash = "sha256-b9NiWETc0g2a7FNwrLaNrWx7gfCql7VTbewFu3QluFk=";
})
(prev.fetchpatch {
url =
"https://github.com/Tunnelblick/Tunnelblick/raw/master/third_party/sources/openvpn/openvpn-${old.version}/patches/03-tunnelblick-openvpn_xorpatch-b.diff";
hash = "sha256-X/SshB/8ItLFBx6TPhjBwyA97ra0iM2KgsGqGIy2s9I=";
})
(prev.fetchpatch {
url =
"https://github.com/Tunnelblick/Tunnelblick/raw/master/third_party/sources/openvpn/openvpn-${old.version}/patches/04-tunnelblick-openvpn_xorpatch-c.diff";
hash = "sha256-fw0CxJGIFEydIVRVouTlD1n275eQcbejUdhrU1JAx7g=";
})
(prev.fetchpatch {
url =
"https://github.com/Tunnelblick/Tunnelblick/raw/master/third_party/sources/openvpn/openvpn-${old.version}/patches/05-tunnelblick-openvpn_xorpatch-d.diff";
hash = "sha256-NLRtoRVz+4hQcElyz4elCAv9l1vp4Yb3/VJef+L/FZo=";
})
(prev.fetchpatch {
url =
"https://github.com/Tunnelblick/Tunnelblick/raw/master/third_party/sources/openvpn/openvpn-${old.version}/patches/06-tunnelblick-openvpn_xorpatch-e.diff";
hash = "sha256-mybdjCIT9b6ukbGWYvbr74fKtcncCtTvS5xSVf92T6Y=";
})
];
});
})
];
nordvpn = pkgs.buildGoModule rec {
pname = "nordvpn";
version = "3.19.0";
#src = ./.;
src = pkgs.fetchFromGitHub {
owner = "NordSecurity";
repo = "nordvpn-linux";
rev = "e614303aaaf1a64fde5bb1b4de1a7863b22428c4";
sha256 = "sha256-uIzG9QIVwax0Cop2VuDzy033efEBudFnGNj7osT/x2g";
};
nativeBuildInputs = with pkgs; [ pkg-config gcc ];
buildInputs = with pkgs; [ libxml2 gcc ];
vendorHash = "sha256-h5G5J/Sw0277pDzVXT6b3BX0KUbtyN8ujITfYp5PmgE";
ldflags = [
"-X main.Version=${version}"
"-X main.Environment=dev"
"-X main.Salt=development"
"-X main.Hash=${src.rev}"
];
buildPhase = ''
runHook preBuild
echo "Building nordvpn CLI..."
export LDFLAGS="${builtins.concatStringsSep " " ldflags}"
go build -ldflags "$LDFLAGS" -o bin/nordvpn ./cmd/cli
echo "Building nordvpn user..."
go build -ldflags "$LDFLAGS" -o bin/norduserd ./cmd/norduser
# Fix missing include in a library preventing compilation
chmod +w vendor/github.com/jbowtie/gokogiri/xpath/
sed -i '6i#include <stdlib.h>' vendor/github.com/jbowtie/gokogiri/xpath/expression.go
echo "Building nordvpn daemon..."
go build -ldflags "$LDFLAGS" -o bin/nordvpnd ./cmd/daemon
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/lib/nordvpn/
mv bin/norduserd $out/lib/nordvpn/
ln -s ${patchedPkgs.openvpn}/bin/openvpn $out/lib/nordvpn/openvpn
ln -s ${pkgs.wireguard-tools}/bin/wg $out/lib/nordvpn/wg
# Nordvpn needs icons for the system tray and notifications
mkdir -p $out/share/icons/hicolor/scalable/apps
cp assets/icon.svg $out/share/icons/hicolor/scalable/apps/nordvpn.svg # Does not follow naming convention
nordvpn_asset_prefix="nordvpn-" # hardcoded image prefix
for file in assets/*; do
cp "$file" "$out/share/icons/hicolor/scalable/apps/''\${nordvpn_asset_prefix}$(basename "$file")"
done
mkdir -p $out/bin
cp bin/* $out/bin
runHook postInstall
'';
meta = with pkgs.lib; {
description = "NordVPN CLI and daemon application for Linux";
homepage = "https://github.com/nordsecurity/nordvpn-linux";
mainProgram = "nordvpn";
license = licenses.gpl3;
platforms = platforms.linux;
};
};
in pkgs.buildFHSEnv {
name = "nordvpnd";
targetPkgs = with pkgs;
pkgs: [
nordvpn
sysctl
iptables
iproute2
procps
cacert
libxml2
libidn2
zlib
wireguard-tools
patchedPkgs.openvpn
e2fsprogs # for chattr
];
extraInstallCommands = ''
mkdir -p $out/bin/
printf "#!${pkgs.bash}/bin/bash\n${nordvpn}/bin/nordvpn \"\$@\"" > $out/bin/nordvpn
chmod +x $out/bin/nordvpn
'';
runScript = ''
${nordvpn}/bin/nordvpnd
'';
}
The daemon can then be activated using this in your os config:
systemd = {
services.nordvpn = {
description = "NordVPN daemon.";
serviceConfig = {
ExecStart = "${pkgs.nordvpn}/bin/nordvpnd";
ExecStartPre = ''
${pkgs.bash}/bin/bash -c '\
mkdir -m 700 -p /var/lib/nordvpn; \
if [ -z "$(ls -A /var/lib/nordvpn)" ]; then \
cp -r ${pkgs.nordvpn}/var/lib/nordvpn/* /var/lib/nordvpn; \
fi'
'';
NonBlocking = true;
KillMode = "process";
Restart = "on-failure";
RestartSec = 5;
RuntimeDirectory = "nordvpn";
RuntimeDirectoryMode = "0750";
Group = "nordvpn";
};
wantedBy = [ "multi-user.target" ];
#after = [ "network-online.target" ];
#wants = [ "network-online.target" ];
};
};
If you are having issues importing the package I found it easiest just appending this to the os config:
nixpkgs.config.packageOverrides = pkgs: {
nordvpn = pkgs.callPackage ./path-to-your-nordvpn.nix { inherit lib; };
};
It's probably not the best solution, but it's easy and works :shrug:
That's beautiful. How would you feel about adding it to nixos/nixpkgs (with plenty of support)? It's about 95% of the way there.
That would be great! Unfortunately I am not at all well versed in the PR process to get it into nixpkgs (this is my first package). Feel free to copy the code to make a PR though, just make sure to co-author me :+1:
Perhaps @LuisChDev might be interested. I used your package before this :heart:
@Blatzar I tested your solution. The package compiles, but I can not start the service:
building the system configuration...
stopping the following units: nordvpn.service
activating the configuration...
setting up /etc...
reloading user units for getreu...
restarting sysinit-reactivation.target
starting the following units: nordvpn.service
warning: the following units failed: nordvpn.service
● nordvpn.service - NordVPN daemon.
Loaded: loaded (/etc/systemd/system/nordvpn.service; enabled; preset: enabled)
Active: activating (auto-restart) (Result: exit-code) since Sun 2024-11-17 09:00:51 EET; 143ms ago
Process: 420641 ExecStartPre=/nix/store/syl4snn859kpqvn9qh91kr7n9i4dws04-bash-5.2p32/bin/bash -c mkdir -m 700 -p /var/lib/nordvpn; if [ -z "$(ls -A /var/lib/nordvpn)" ]; then cp -r /nix/store/30h9kdmxcamma5b83507mbwyhvcd35aw-nordvpnd/var/lib/nordvpn/* /var/lib/nordvpn; fi (code=exited, status=0/SUCCESS)
Process: 420646 ExecStart=/nix/store/30h9kdmxcamma5b83507mbwyhvcd35aw-nordvpnd/bin/nordvpnd (code=exited, status=1/FAILURE)
Main PID: 420646 (code=exited, status=1/FAILURE)
IP: 0B in, 0B out
CPU: 83ms
warning: error(s) occurred while switching to the new configuration
$ sudo /nix/store/30h9kdmxcamma5b83507mbwyhvcd35aw-nordvpnd/bin/nordvpnd
2024/11/17 09:01:49 [Info] Daemon has started
2024/11/17 09:01:49 cipher: message authentication failed
2024/11/17 09:01:49 cipher: message authentication failed
Any ideas?
@getreu Your issue is likely due to the changed salt. See https://github.com/NordSecurity/nordvpn-linux/blob/main/BUILD.md?plain=1#L65-L68
I do not know what salt the debian package is compiled with, so you need to remove your old /var/lib/nordvpn
and let it regenerate. This also means your need to login and set all your settings again.
Please support NixOS. It is an one time effort, then it becomes an effortless sure-fire success.
Some exploratory work: NordVPN · Issue #101864