nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 autoPatchelfHook,
3 buildFHSEnv,
4 dpkg,
5 fetchurl,
6 inotify-tools,
7 lib,
8 stdenvNoCC,
9 sysctl,
10 writeScript,
11}:
12
13let
14 pname = "expressvpn";
15 clientVersion = "3.52.0";
16 clientBuild = "2";
17 version = lib.strings.concatStringsSep "." [
18 clientVersion
19 clientBuild
20 ];
21
22 expressvpnBase = stdenvNoCC.mkDerivation {
23 inherit pname version;
24
25 src = fetchurl {
26 url = "https://www.expressvpn.works/clients/linux/expressvpn_${version}-1_amd64.deb";
27 hash = "sha256-cDZ9R+MA3FXEto518bH4/c1X4W9XxgTvXns7zisylew=";
28 };
29
30 nativeBuildInputs = [
31 dpkg
32 autoPatchelfHook
33 ];
34
35 dontConfigure = true;
36 dontBuild = true;
37
38 unpackPhase = ''
39 runHook preUnpack
40 dpkg --fsys-tarfile $src | tar --extract
41 runHook postUnpack
42 '';
43
44 installPhase = ''
45 runHook preInstall
46 mv usr/ $out/
47 runHook postInstall
48 '';
49 };
50
51 expressvpndFHS = buildFHSEnv {
52 inherit version;
53 pname = "expressvpnd";
54
55 # When connected, it directly creates/deletes resolv.conf to change the DNS entries.
56 # Since it's running in an FHS environment, it has no effect on actual resolv.conf.
57 # Hence, place a watcher that updates host resolv.conf when FHS resolv.conf changes.
58
59 # Mount the host's resolv.conf to the container's /etc/resolv.conf
60 runScript = writeScript "${pname}-wrapper" ''
61 mkdir -p /host/etc
62 [ -e /host/etc/resolv.conf ] || touch /host/etc/resolv.conf
63 mount --bind /etc/resolv.conf /host/etc/resolv.conf
64 mount -o remount,rw /host/etc/resolv.conf
65 trap "umount /host/etc/resolv.conf" EXIT
66
67 while inotifywait /etc 2>/dev/null;
68 do
69 cp /etc/resolv.conf /host/etc/resolv.conf;
70 done &
71 expressvpnd --client-version ${clientVersion} --client-build ${clientBuild}
72 '';
73
74 # expressvpnd binary has hard-coded the path /sbin/sysctl hence below workaround.
75 extraBuildCommands = ''
76 mkdir -p sbin
77 chmod +w sbin
78 ln -s ${sysctl}/bin/sysctl sbin/sysctl
79 '';
80
81 # The expressvpnd binary also uses hard-coded paths to the other binaries and files
82 # it ships with, hence the FHS environment.
83
84 targetPkgs =
85 pkgs: with pkgs; [
86 expressvpnBase
87 inotify-tools
88 iproute2
89 ];
90 };
91in
92stdenvNoCC.mkDerivation {
93 inherit pname version;
94
95 dontUnpack = true;
96 dontConfigure = true;
97 dontBuild = true;
98
99 installPhase = ''
100 runHook preInstall
101 mkdir -p $out/bin $out/share
102 ln -s ${expressvpnBase}/bin/expressvpn $out/bin
103 ln -s ${expressvpndFHS}/bin/expressvpnd $out/bin
104 ln -s ${expressvpnBase}/share/{bash-completion,doc,man} $out/share/
105 runHook postInstall
106 '';
107
108 meta = {
109 description = "CLI client for ExpressVPN";
110 homepage = "https://www.expressvpn.com";
111 license = lib.licenses.unfree;
112 platforms = [ "x86_64-linux" ];
113 maintainers = with lib.maintainers; [ yureien ];
114 };
115}