summary refs log tree commit diff
path: root/nixos/modules/services/x11/terminal-server.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/x11/terminal-server.nix')
-rw-r--r--nixos/modules/services/x11/terminal-server.nix66
1 files changed, 66 insertions, 0 deletions
diff --git a/nixos/modules/services/x11/terminal-server.nix b/nixos/modules/services/x11/terminal-server.nix
new file mode 100644
index 00000000000..ab05639aeca
--- /dev/null
+++ b/nixos/modules/services/x11/terminal-server.nix
@@ -0,0 +1,66 @@
+# This module implements a terminal service based on ‘x11vnc’.  It
+# listens on port 5900 for VNC connections.  It then presents a login
+# screen to the user.  If the user successfully authenticates, x11vnc
+# checks to see if a X server is already running for that user.  If
+# not, a X server (Xvfb) is started for that user.  The Xvfb instances
+# persist across VNC sessions.
+
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  # Wrap Xvfb to set some flags/variables.
+  xvfbWrapper = pkgs.writeScriptBin "Xvfb"
+    ''
+      #! ${pkgs.stdenv.shell}
+      export XKB_BINDIR=${pkgs.xorg.xkbcomp}/bin
+      export XORG_DRI_DRIVER_PATH=${pkgs.mesa}/lib/dri
+      exec ${pkgs.xorg.xorgserver}/bin/Xvfb "$@" -xkbdir "${pkgs.xkeyboard_config}/etc/X11/xkb"
+    '';
+
+  # ‘xinetd’ is insanely braindamaged in that it sends stderr to
+  # stdout.  Thus requires just about any xinetd program to be
+  # wrapped to redirect its stderr.  Sigh.
+  x11vncWrapper = pkgs.writeScriptBin "x11vnc-wrapper"
+    ''
+      #! ${pkgs.stdenv.shell}
+      export PATH=${makeSearchPath "bin" [ xvfbWrapper pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth pkgs.nettools pkgs.shadow pkgs.procps pkgs.utillinux pkgs.bash ]}:$PATH
+      export FD_GEOM=1024x786x24
+      exec ${pkgs.x11vnc}/bin/x11vnc -inetd -display WAIT:1024x786:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp -unixpw -ssl SAVE 2> /var/log/x11vnc.log
+    '';
+
+in 
+
+{
+
+  config = {
+  
+    services.xserver.enable = true;
+
+    # Enable KDM.  Any display manager will do as long as it supports XDMCP.
+    services.xserver.displayManager.kdm.enable = true;
+    services.xserver.displayManager.kdm.enableXDMCP = true;
+    services.xserver.displayManager.kdm.extraConfig =
+      ''
+        [General]
+        # We're headless, so don't bother starting an X server.
+        StaticServers=
+
+        [Xdmcp]
+        Xaccess=${pkgs.writeText "Xaccess" "localhost"}
+      '';
+
+    services.xinetd.enable = true;
+    services.xinetd.services = singleton
+      { name = "x11vnc";
+        port = 5900;
+        unlisted = true;
+        user = "root";
+        server = "${x11vncWrapper}/bin/x11vnc-wrapper";
+      };
+
+  };
+
+}