diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index 5219c1329e36..958000687810 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -71,6 +71,13 @@ services.persistent-evdev. + + + expressvpn, + the CLI client for ExpressVPN. Available as + services.expressvpn. + +
diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index 0f04eff7c045..1a14885ed8c3 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -31,6 +31,8 @@ In addition to numerous new and upgraded packages, this release has the followin Available as [services.infnoise](options.html#opt-services.infnoise.enable). - [persistent-evdev](https://github.com/aiberia/persistent-evdev), a daemon to add virtual proxy devices that mirror a physical input device but persist even if the underlying hardware is hot-plugged. Available as [services.persistent-evdev](#opt-services.persistent-evdev.enable). +- [expressvpn](https://www.expressvpn.com), the CLI client for ExpressVPN. Available as [services.expressvpn](#opt-services.expressvpn.enable). + ## Backward Incompatibilities {#sec-release-22.11-incompatibilities} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 495be43ec561..2bb9d2879689 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -771,6 +771,7 @@ ./services/networking/ergo.nix ./services/networking/ergochat.nix ./services/networking/eternal-terminal.nix + ./services/networking/expressvpn.nix ./services/networking/fakeroute.nix ./services/networking/ferm.nix ./services/networking/fireqos.nix diff --git a/nixos/modules/services/networking/expressvpn.nix b/nixos/modules/services/networking/expressvpn.nix new file mode 100644 index 000000000000..d8ae6528a4d4 --- /dev/null +++ b/nixos/modules/services/networking/expressvpn.nix @@ -0,0 +1,29 @@ +{ config, lib, pkgs, ... }: + +with lib; +{ + options.services.expressvpn.enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable the ExpressVPN daemon. + ''; + }; + + config = mkIf config.services.expressvpn.enable { + boot.kernelModules = [ "tun" ]; + + systemd.services.expressvpn = { + description = "ExpressVPN Daemon"; + serviceConfig = { + ExecStart = "${pkgs.expressvpn}/bin/expressvpnd"; + Restart = "on-failure"; + RestartSec = 5; + }; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "network-online.target" ]; + }; + }; + + meta.maintainers = with maintainers; [ yureien ]; +} diff --git a/pkgs/applications/networking/expressvpn/default.nix b/pkgs/applications/networking/expressvpn/default.nix new file mode 100644 index 000000000000..0bc0fd34fe5a --- /dev/null +++ b/pkgs/applications/networking/expressvpn/default.nix @@ -0,0 +1,98 @@ +{ autoPatchelfHook +, buildFHSUserEnv +, dpkg +, fetchurl +, inotify-tools +, lib +, stdenvNoCC +, sysctl +, writeScript +}: + +let + pname = "expressvpn"; + clientVersion = "3.25.0"; + clientBuild = "13"; + version = lib.strings.concatStringsSep "." [ clientVersion clientBuild ]; + + expressvpnBase = stdenvNoCC.mkDerivation { + inherit pname version; + + src = fetchurl { + url = "https://www.expressvpn.works/clients/linux/expressvpn_${version}-1_amd64.deb"; + hash = "sha256-lyDjG346FrgT7SZbsWET+Hexl9Un6mzMukfO2PwlInA="; + }; + + nativeBuildInputs = [ dpkg autoPatchelfHook ]; + + dontConfigure = true; + dontBuild = true; + + unpackPhase = '' + runHook preUnpack + dpkg --fsys-tarfile $src | tar --extract + runHook postUnpack + ''; + + installPhase = '' + runHook preInstall + mv usr/ $out/ + runHook postInstall + ''; + }; + + expressvpndFHS = buildFHSUserEnv { + name = "expressvpnd"; + + # When connected, it directly creates/deletes resolv.conf to change the DNS entries. + # Since it's running in an FHS environment, it has no effect on actual resolv.conf. + # Hence, place a watcher that updates host resolv.conf when FHS resolv.conf changes. + runScript = writeScript "${pname}-wrapper" '' + cp /host/etc/resolv.conf /etc/resolv.conf; + while inotifywait /etc 2>/dev/null; + do + cp /etc/resolv.conf /host/etc/resolv.conf; + done & + expressvpnd --client-version ${clientVersion} --client-build ${clientBuild} + ''; + + # expressvpnd binary has hard-coded the path /sbin/sysctl hence below workaround. + extraBuildCommands = '' + chmod +w sbin + ln -s ${sysctl}/bin/sysctl sbin/sysctl + ''; + + # The expressvpnd binary also uses hard-coded paths to the other binaries and files + # it ships with, hence the FHS environment. + + targetPkgs = pkgs: with pkgs; [ + expressvpnBase + inotify-tools + iproute2 + ]; + }; +in +stdenvNoCC.mkDerivation { + inherit pname version; + + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin $out/share + ln -s ${expressvpnBase}/bin/expressvpn $out/bin + ln -s ${expressvpndFHS}/bin/expressvpnd $out/bin + ln -s ${expressvpnBase}/share/{bash-completion,doc,man} $out/share/ + runHook postInstall + ''; + + meta = with lib; { + description = "CLI client for ExpressVPN"; + homepage = "https://www.expressvpn.com"; + license = licenses.unfree; + platforms = [ "x86_64-linux" ]; + maintainers = with maintainers; [ yureien ]; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 753d5f6a0a44..c08320fd339e 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -392,6 +392,8 @@ with pkgs; evans = callPackage ../development/tools/evans { }; + expressvpn = callPackage ../applications/networking/expressvpn { }; + firefly-desktop = callPackage ../applications/misc/firefly-desktop { }; frugal = callPackage ../development/tools/frugal { };