at 21.11-pre 5.2 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.xrdp; 7 confDir = pkgs.runCommand "xrdp.conf" { preferLocalBuild = true; } '' 8 mkdir $out 9 10 cp ${cfg.package}/etc/xrdp/{km-*,xrdp,sesman,xrdp_keyboard}.ini $out 11 12 cat > $out/startwm.sh <<EOF 13 #!/bin/sh 14 . /etc/profile 15 ${cfg.defaultWindowManager} 16 EOF 17 chmod +x $out/startwm.sh 18 19 substituteInPlace $out/xrdp.ini \ 20 --replace "#rsakeys_ini=" "rsakeys_ini=/run/xrdp/rsakeys.ini" \ 21 --replace "certificate=" "certificate=${cfg.sslCert}" \ 22 --replace "key_file=" "key_file=${cfg.sslKey}" \ 23 --replace LogFile=xrdp.log LogFile=/dev/null \ 24 --replace EnableSyslog=true EnableSyslog=false 25 26 substituteInPlace $out/sesman.ini \ 27 --replace LogFile=xrdp-sesman.log LogFile=/dev/null \ 28 --replace EnableSyslog=1 EnableSyslog=0 29 30 # Ensure that clipboard works for non-ASCII characters 31 sed -i -e '/.*SessionVariables.*/ a\ 32 LANG=${config.i18n.defaultLocale}\ 33 LOCALE_ARCHIVE=${config.i18n.glibcLocales}/lib/locale/locale-archive 34 ' $out/sesman.ini 35 ''; 36in 37{ 38 39 ###### interface 40 41 options = { 42 43 services.xrdp = { 44 45 enable = mkEnableOption "xrdp, the Remote Desktop Protocol server"; 46 47 package = mkOption { 48 type = types.package; 49 default = pkgs.xrdp; 50 defaultText = "pkgs.xrdp"; 51 description = '' 52 The package to use for the xrdp daemon's binary. 53 ''; 54 }; 55 56 port = mkOption { 57 type = types.int; 58 default = 3389; 59 description = '' 60 Specifies on which port the xrdp daemon listens. 61 ''; 62 }; 63 64 sslKey = mkOption { 65 type = types.str; 66 default = "/etc/xrdp/key.pem"; 67 example = "/path/to/your/key.pem"; 68 description = '' 69 ssl private key path 70 A self-signed certificate will be generated if file not exists. 71 ''; 72 }; 73 74 sslCert = mkOption { 75 type = types.str; 76 default = "/etc/xrdp/cert.pem"; 77 example = "/path/to/your/cert.pem"; 78 description = '' 79 ssl certificate path 80 A self-signed certificate will be generated if file not exists. 81 ''; 82 }; 83 84 defaultWindowManager = mkOption { 85 type = types.str; 86 default = "xterm"; 87 example = "xfce4-session"; 88 description = '' 89 The script to run when user log in, usually a window manager, e.g. "icewm", "xfce4-session" 90 This is per-user overridable, if file ~/startwm.sh exists it will be used instead. 91 ''; 92 }; 93 94 }; 95 }; 96 97 98 ###### implementation 99 100 config = mkIf cfg.enable { 101 102 # xrdp can run X11 program even if "services.xserver.enable = false" 103 xdg = { 104 autostart.enable = true; 105 menus.enable = true; 106 mime.enable = true; 107 icons.enable = true; 108 }; 109 110 fonts.enableDefaultFonts = mkDefault true; 111 112 systemd = { 113 services.xrdp = { 114 wantedBy = [ "multi-user.target" ]; 115 after = [ "network.target" ]; 116 description = "xrdp daemon"; 117 requires = [ "xrdp-sesman.service" ]; 118 preStart = '' 119 # prepare directory for unix sockets (the sockets will be owned by loggedinuser:xrdp) 120 mkdir -p /tmp/.xrdp || true 121 chown xrdp:xrdp /tmp/.xrdp 122 chmod 3777 /tmp/.xrdp 123 124 # generate a self-signed certificate 125 if [ ! -s ${cfg.sslCert} -o ! -s ${cfg.sslKey} ]; then 126 mkdir -p $(dirname ${cfg.sslCert}) || true 127 mkdir -p $(dirname ${cfg.sslKey}) || true 128 ${pkgs.openssl.bin}/bin/openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 365 \ 129 -subj /C=US/ST=CA/L=Sunnyvale/O=xrdp/CN=www.xrdp.org \ 130 -config ${cfg.package}/share/xrdp/openssl.conf \ 131 -keyout ${cfg.sslKey} -out ${cfg.sslCert} 132 chown root:xrdp ${cfg.sslKey} ${cfg.sslCert} 133 chmod 440 ${cfg.sslKey} ${cfg.sslCert} 134 fi 135 if [ ! -s /run/xrdp/rsakeys.ini ]; then 136 mkdir -p /run/xrdp 137 ${cfg.package}/bin/xrdp-keygen xrdp /run/xrdp/rsakeys.ini 138 fi 139 ''; 140 serviceConfig = { 141 User = "xrdp"; 142 Group = "xrdp"; 143 PermissionsStartOnly = true; 144 ExecStart = "${cfg.package}/bin/xrdp --nodaemon --port ${toString cfg.port} --config ${confDir}/xrdp.ini"; 145 }; 146 }; 147 148 services.xrdp-sesman = { 149 wantedBy = [ "multi-user.target" ]; 150 after = [ "network.target" ]; 151 description = "xrdp session manager"; 152 restartIfChanged = false; # do not restart on "nixos-rebuild switch". like "display-manager", it can have many interactive programs as children 153 serviceConfig = { 154 ExecStart = "${cfg.package}/bin/xrdp-sesman --nodaemon --config ${confDir}/sesman.ini"; 155 ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID"; 156 }; 157 }; 158 159 }; 160 161 users.users.xrdp = { 162 description = "xrdp daemon user"; 163 isSystemUser = true; 164 group = "xrdp"; 165 }; 166 users.groups.xrdp = {}; 167 168 security.pam.services.xrdp-sesman = { allowNullPassword = true; startSession = true; }; 169 }; 170 171}