1# This module implements a terminal service based on ‘x11vnc’. It
2# listens on port 5900 for VNC connections. It then presents a login
3# screen to the user. If the user successfully authenticates, x11vnc
4# checks to see if a X server is already running for that user. If
5# not, a X server (Xvfb) is started for that user. The Xvfb instances
6# persist across VNC sessions.
7
8{ config, lib, pkgs, ... }:
9
10with lib;
11
12let
13
14 # Wrap Xvfb to set some flags/variables.
15 xvfbWrapper = pkgs.writeScriptBin "Xvfb"
16 ''
17 #! ${pkgs.stdenv.shell}
18 export XKB_BINDIR=${pkgs.xorg.xkbcomp}/bin
19 export XORG_DRI_DRIVER_PATH=${pkgs.mesa}/lib/dri
20 exec ${pkgs.xorg.xorgserver}/bin/Xvfb "$@" -xkbdir ${pkgs.xkeyboard_config}/etc/X11/xkb
21 '';
22
23in
24
25{
26
27 config = {
28
29 services.xserver.enable = true;
30 services.xserver.videoDrivers = [];
31
32 # Enable KDM. Any display manager will do as long as it supports XDMCP.
33 services.xserver.displayManager.kdm.enable = true;
34 services.xserver.displayManager.kdm.enableXDMCP = true;
35 services.xserver.displayManager.kdm.extraConfig =
36 ''
37 [General]
38 # We're headless, so don't bother starting an X server.
39 StaticServers=
40
41 [Xdmcp]
42 Xaccess=${pkgs.writeText "Xaccess" "localhost"}
43 '';
44
45 systemd.sockets.terminal-server =
46 { description = "Terminal Server Socket";
47 wantedBy = [ "sockets.target" ];
48 before = [ "multi-user.target" ];
49 socketConfig.Accept = true;
50 socketConfig.ListenStream = 5900;
51 };
52
53 systemd.services."terminal-server@" =
54 { description = "Terminal Server";
55
56 path =
57 [ xvfbWrapper pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth
58 pkgs.nettools pkgs.shadow pkgs.procps pkgs.utillinux pkgs.bash
59 ];
60
61 environment.FD_GEOM = "1024x786x24";
62 environment.FD_XDMCP_IF = "127.0.0.1";
63 #environment.FIND_DISPLAY_OUTPUT = "/tmp/foo"; # to debug the "find display" script
64
65 serviceConfig =
66 { StandardInput = "socket";
67 StandardOutput = "socket";
68 StandardError = "journal";
69 ExecStart = "@${pkgs.x11vnc}/bin/x11vnc x11vnc -inetd -display WAIT:1024x786:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp -unixpw -ssl SAVE";
70 # Don't kill the X server when the user quits the VNC
71 # connection. FIXME: the X server should run in a
72 # separate systemd session.
73 KillMode = "process";
74 };
75 };
76
77 };
78
79}