Skip to content

Instantly share code, notes, and snippets.

@sepiabrown
Last active December 22, 2024 15:09
Show Gist options
  • Save sepiabrown/0dbca7da5610055991ad04bbeb461fed to your computer and use it in GitHub Desktop.
Save sepiabrown/0dbca7da5610055991ad04bbeb461fed to your computer and use it in GitHub Desktop.
{ lib, config, options, pkgs, ... }:
with lib;
let cfg = config.services.chrome-remote-desktop;
in {
options.services.chrome-remote-desktop = {
enable = mkEnableOption "Chrome Remote Desktop";
user = mkOption {
type = types.str;
description = ''
A user which the service will run as.
'';
example = "alice";
};
};
config = mkIf cfg.enable {
environment = {
etc = {
"chromium/native-messaging-hosts/com.google.chrome.remote_assistance.json".source = "${pkgs.chrome-remote-desktop}/etc/opt/chrome/native-messaging-hosts/com.google.chrome.remote_assistance.json";
"chromium/native-messaging-hosts/com.google.chrome.remote_desktop.json".source = "${pkgs.chrome-remote-desktop}/etc/opt/chrome/native-messaging-hosts/com.google.chrome.remote_desktop.json";
};
systemPackages = [ pkgs.chrome-remote-desktop ];
};
security = {
wrappers.crd-user-session.source = "${pkgs.chrome-remote-desktop}/opt/google/chrome-remote-desktop/user-session";
pam.services.chrome-remote-desktop.text = ''
auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
session required pam_unix.so
'';
};
users.groups.chrome-remote-desktop = {};
users.users.${cfg.user}.extraGroups = [ "chrome-remote-desktop" ];
systemd.packages = [
pkgs.chrome-remote-desktop
];
# Reference : ${pkgs.chrome-remote-desktop}/lib/systemd/system/[email protected]
systemd.services."chrome-remote-desktop@sepiabrown" = {
enable = true;
description = "Chrome Remote Desktop instance for ${cfg.user}";
after = [ "network.target" ];
serviceConfig = {
Type = "simple";
User = cfg.user;
Environment = "XDG_SESSION_CLASS=user XDG_SESSION_TYPE=x11";
PAMName = "chrome-remote-desktop";
TTYPath = "/dev/chrome-remote-desktop";
ExecStart = "${pkgs.chrome-remote-desktop}/opt/google/chrome-remote-desktop/chrome-remote-desktop --start --new-session";
ExecReload = "${pkgs.chrome-remote-desktop}/opt/google/chrome-remote-desktop/chrome-remote-desktop --reload";
ExecStop = "${pkgs.chrome-remote-desktop}/opt/google/chrome-remote-desktop/chrome-remote-desktop --stop";
StandardOutput = "journal";
StandardError = "inherit";
RestartForceExitStatus = "41";
};
wantedBy = [ "multi-user.target" ];
};
};
}
{ config, pkgs, ... }:
{
imports =
[
./chrome-remote-desktop.nix
];
environment.systemPackages = with pkgs; [
chromium
];
# List services that you want to enable:
services = {
chrome-remote-desktop = {
enable = true;
user = "sepiabrown";
};
};
nixpkgs.overlays = [
(self: super: {
chrome-remote-desktop = super.callPackage ./default.nix {};
})
];
}
{ stdenv, pkgs, lib, config, fetchurl, fetchgit, dpkg, python3, glibc, glib, pam, nss
, nspr, expat, gnome3, xorg, fontconfig, dbus_daemon, alsaLib, shadow, mesa, libdrm, libxkbcommon, wayland}:
stdenv.mkDerivation rec {
name = "chrome-remote-desktop";
src = fetchurl {
sha256 = "sha256-CNE3kvAj7Jp4cB5x2D/YUA1H9Ri397C6rxQBRmstz1c="; # This hash needs frequent updates
url = "https://dl.google.com/linux/direct/chrome-remote-desktop_current_amd64.deb";
};
buildInputs = [ pkgs.makeWrapper ];
dontBuild = true;
dontConfigure = true;
unpackPhase = ''
${dpkg}/bin/dpkg -x $src $out
'';
installPhase = ''
mkdir $out/bin
makeWrapper $out/opt/google/chrome-remote-desktop/chrome-remote-desktop $out/bin/chrome-remote-desktop
'';
replacePrefix = "/opt/google/chrome-remote-desktop";
replaceTarget = "/run/current-system/sw/bin/./././";
patchPhase = ''
sed \
-e '/^.*sudo_command =/ s/"gksudo .*"/"pkexec"/' \
-e '/^.*command =/ s/s -- sh -c/s sh -c/' \
-i $out/opt/google/chrome-remote-desktop/chrome-remote-desktop
substituteInPlace $out/etc/opt/chrome/native-messaging-hosts/com.google.chrome.remote_desktop.json --replace $replacePrefix/native-messaging-host $out/$replacePrefix/native-messaging-host
substituteInPlace $out/etc/opt/chrome/native-messaging-hosts/com.google.chrome.remote_assistance.json --replace $replacePrefix/remote-assistance-host $out/$replacePrefix/remote-assistance-host
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace "USER_SESSION_PATH = " "USER_SESSION_PATH = \"/run/wrappers/bin/crd-user-session\" #"
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace /usr/bin/python3 ${python3.withPackages (ps: with ps; [ psutil ])}/bin/python3
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace '"Xvfb"' '"${xorg.xorgserver}/bin/Xvfb"'
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace '"Xorg"' '"${xorg.xorgserver}/bin/Xorg"'
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace '"xrandr"' '"${xorg.xrandr}/bin/xrandr"'
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace /usr/lib/xorg/modules ${xorg.xorgserver}/lib/xorg/modules
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace xdpyinfo ${xorg.xdpyinfo}/bin/xdpyinfo
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace /usr/bin/sudo /run/wrappers/bin/sudo
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace /usr/bin/pkexec /run/wrappers/bin/pkexec
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace /usr/bin/gpasswd ${shadow}/bin/gpasswd
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace /usr/bin/groupadd ${shadow}/bin/groupadd
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace "FIRST_X_DISPLAY_NUMBER = 20" "FIRST_X_DISPLAY_NUMBER = 0"
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace "while os.path.exists(X_LOCK_FILE_TEMPLATE % display):" "# while os.path.exists(X_LOCK_FILE_TEMPLATE % display):"
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace "display += 1" "# display += 1"
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace "self._launch_x_server(x_args)" "display = self.get_unused_display_number()"
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace "if not self._launch_pre_session():" "self.child_env[\"DISPLAY\"] = \":%d\" % display"
substituteInPlace $out/$replacePrefix/chrome-remote-desktop --replace "self.launch_x_session()" "# self.launch_x_session()"
'';
preFixup = let
libPath = lib.makeLibraryPath [
glib
pam
nss
nspr
expat
gnome3.gtk
gnome3.dconf
xorg.libXext
xorg.libX11
xorg.libXcomposite
xorg.libXrender
xorg.libXrandr
xorg.libXcursor
xorg.libXdamage
xorg.libXfixes
xorg.libXi
xorg.libXtst
xorg.libxcb
fontconfig
xorg.libXScrnSaver
dbus_daemon.lib
alsaLib
mesa # added!
libdrm # added!
libxkbcommon # added!
wayland # added!
];
in ''
for i in $out/$replacePrefix/{chrome-remote-desktop-host,start-host,native-messaging-host,remote-assistance-host,user-session}; do
sed -i "s|$replacePrefix|$replaceTarget|g" $i
patchelf --set-rpath "${libPath}" $i
patchelf --set-interpreter ${glibc}/lib/ld-linux-x86-64.so.2 $i
done
'';
}
@OmerFarukOruc
Copy link

i want to access my nixos machine (gui) remotely and looking for better and efficient ways to accomplish this. Is accessing via chrome rd good way to do that?

@sepiabrown
Copy link
Author

sepiabrown commented Jan 20, 2024

I have not used other remote desktop services except chrome-remote-desktop so I have no reference for comparison.

But I felt that chrome-remote-desktop itself worked pretty well and satisfied what I needed. Once I got the nix packaging to work, accessing my nixos machine (gui) remotely was easy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment