parent
63433537ce
commit
dad760061e
@ -0,0 +1,150 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.services.xrdp; |
||||
confDir = pkgs.runCommand "xrdp.conf" { } '' |
||||
mkdir $out |
||||
|
||||
cp ${cfg.package}/etc/xrdp/{km-*,xrdp,sesman,xrdp_keyboard}.ini $out |
||||
|
||||
${cfg.package}/bin/xrdp-keygen xrdp $out/rsakeys.ini |
||||
|
||||
cat > $out/startwm.sh <<EOF |
||||
#!/bin/sh |
||||
. /etc/profile |
||||
${cfg.defaultWindowManager} |
||||
EOF |
||||
chmod +x $out/startwm.sh |
||||
|
||||
substituteInPlace $out/xrdp.ini \ |
||||
--replace "certificate=" "certificate=${cfg.sslCert}" \ |
||||
--replace "key_file=" "key_file=${cfg.sslKey}" \ |
||||
--replace LogFile=xrdp.log LogFile=/dev/null \ |
||||
--replace EnableSyslog=true EnableSyslog=false |
||||
|
||||
substituteInPlace $out/sesman.ini \ |
||||
--replace LogFile=xrdp-sesman.log LogFile=/dev/null \ |
||||
--replace EnableSyslog=1 EnableSyslog=0 |
||||
''; |
||||
in |
||||
{ |
||||
|
||||
###### interface |
||||
|
||||
options = { |
||||
|
||||
services.xrdp = { |
||||
|
||||
enable = mkEnableOption "Whether xrdp should be run on startup."; |
||||
|
||||
package = mkOption { |
||||
type = types.package; |
||||
default = pkgs.xrdp; |
||||
defaultText = "pkgs.xrdp"; |
||||
description = '' |
||||
The package to use for the xrdp daemon's binary. |
||||
''; |
||||
}; |
||||
|
||||
port = mkOption { |
||||
type = types.int; |
||||
default = 3389; |
||||
description = '' |
||||
Specifies on which port the xrdp daemon listens. |
||||
''; |
||||
}; |
||||
|
||||
sslKey = mkOption { |
||||
type = types.str; |
||||
default = "/etc/xrdp/key.pem"; |
||||
example = "/path/to/your/key.pem"; |
||||
description = '' |
||||
ssl private key path |
||||
A self-signed certificate will be generated if file not exists. |
||||
''; |
||||
}; |
||||
|
||||
sslCert = mkOption { |
||||
type = types.str; |
||||
default = "/etc/xrdp/cert.pem"; |
||||
example = "/path/to/your/cert.pem"; |
||||
description = '' |
||||
ssl certificate path |
||||
A self-signed certificate will be generated if file not exists. |
||||
''; |
||||
}; |
||||
|
||||
defaultWindowManager = mkOption { |
||||
type = types.str; |
||||
default = "xterm"; |
||||
example = "xfce4-session"; |
||||
description = '' |
||||
The script to run when user log in, usually a window manager, e.g. "icewm", "xfce4-session" |
||||
This is per-user overridable, if file ~/startwm.sh exists it will be used instead. |
||||
''; |
||||
}; |
||||
|
||||
}; |
||||
}; |
||||
|
||||
|
||||
###### implementation |
||||
|
||||
config = mkIf cfg.enable { |
||||
|
||||
systemd = { |
||||
services.xrdp = { |
||||
wantedBy = [ "multi-user.target" ]; |
||||
after = [ "network.target" ]; |
||||
description = "xrdp daemon"; |
||||
requires = [ "xrdp-sesman.service" ]; |
||||
preStart = '' |
||||
# prepare directory for unix sockets (the sockets will be owned by loggedinuser:xrdp) |
||||
mkdir -p /tmp/.xrdp || true |
||||
chown xrdp:xrdp /tmp/.xrdp |
||||
chmod 3777 /tmp/.xrdp |
||||
|
||||
# generate a self-signed certificate |
||||
if [ ! -s ${cfg.sslCert} -o ! -s ${cfg.sslKey} ]; then |
||||
mkdir -p $(dirname ${cfg.sslCert}) || true |
||||
mkdir -p $(dirname ${cfg.sslKey}) || true |
||||
${pkgs.openssl.bin}/bin/openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 365 \ |
||||
-subj /C=US/ST=CA/L=Sunnyvale/O=xrdp/CN=www.xrdp.org \ |
||||
-config ${cfg.package}/share/xrdp/openssl.conf \ |
||||
-keyout ${cfg.sslKey} -out ${cfg.sslCert} |
||||
chown root:xrdp ${cfg.sslKey} ${cfg.sslCert} |
||||
chmod 440 ${cfg.sslKey} ${cfg.sslCert} |
||||
fi |
||||
''; |
||||
serviceConfig = { |
||||
User = "xrdp"; |
||||
Group = "xrdp"; |
||||
PermissionsStartOnly = true; |
||||
ExecStart = "${cfg.package}/bin/xrdp --nodaemon --port ${toString cfg.port} --config ${confDir}/xrdp.ini"; |
||||
}; |
||||
}; |
||||
|
||||
services.xrdp-sesman = { |
||||
wantedBy = [ "multi-user.target" ]; |
||||
after = [ "network.target" ]; |
||||
description = "xrdp session manager"; |
||||
serviceConfig = { |
||||
ExecStart = "${cfg.package}/bin/xrdp-sesman --nodaemon --config ${confDir}/sesman.ini"; |
||||
}; |
||||
}; |
||||
|
||||
}; |
||||
|
||||
users.users.xrdp = { |
||||
description = "xrdp daemon user"; |
||||
isSystemUser = true; |
||||
group = "xrdp"; |
||||
}; |
||||
users.groups.xrdp = {}; |
||||
|
||||
security.pam.services.xrdp-sesman = { allowNullPassword = true; startSession = true; }; |
||||
}; |
||||
|
||||
} |
@ -0,0 +1,45 @@ |
||||
import ./make-test.nix ({ pkgs, ...} : { |
||||
name = "xrdp"; |
||||
meta = with pkgs.stdenv.lib.maintainers; { |
||||
maintainers = [ volth ]; |
||||
}; |
||||
|
||||
nodes = { |
||||
server = { lib, pkgs, ... }: { |
||||
imports = [ ./common/user-account.nix ]; |
||||
services.xrdp.enable = true; |
||||
services.xrdp.defaultWindowManager = "${pkgs.xterm}/bin/xterm"; |
||||
networking.firewall.allowedTCPPorts = [ 3389 ]; |
||||
}; |
||||
|
||||
client = { lib, pkgs, ... }: { |
||||
imports = [ ./common/x11.nix ./common/user-account.nix ]; |
||||
services.xserver.displayManager.auto.user = "alice"; |
||||
environment.systemPackages = [ pkgs.freerdp ]; |
||||
services.xrdp.enable = true; |
||||
services.xrdp.defaultWindowManager = "${pkgs.icewm}/bin/icewm"; |
||||
}; |
||||
}; |
||||
|
||||
testScript = { nodes, ... }: '' |
||||
startAll; |
||||
|
||||
$client->waitForX; |
||||
$client->waitForFile("/home/alice/.Xauthority"); |
||||
$client->succeed("xauth merge ~alice/.Xauthority"); |
||||
|
||||
$client->sleep(5); |
||||
|
||||
$client->execute("xterm &"); |
||||
$client->sleep(1); |
||||
$client->sendChars("xfreerdp /cert-tofu /w:640 /h:480 /v:127.0.0.1 /u:alice /p:foobar\n"); |
||||
$client->sleep(5); |
||||
$client->screenshot("localrdp"); |
||||
|
||||
$client->execute("xterm &"); |
||||
$client->sleep(1); |
||||
$client->sendChars("xfreerdp /cert-tofu /w:640 /h:480 /v:server /u:alice /p:foobar\n"); |
||||
$client->sleep(5); |
||||
$client->screenshot("remoterdp"); |
||||
''; |
||||
}) |
@ -0,0 +1,111 @@ |
||||
{ stdenv, fetchFromGitHub, fetchpatch, pkgconfig, which, perl, autoconf, automake, libtool, openssl, systemd, pam, fuse, libjpeg, libopus, nasm, xorg }: |
||||
|
||||
let |
||||
xorgxrdp = stdenv.mkDerivation rec { |
||||
name = "xorgxrdp-${version}"; |
||||
version = "0.2.0"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "neutrinolabs"; |
||||
repo = "xorgxrdp"; |
||||
rev = "v${version}"; |
||||
sha256 = "125mv7lm2ns1gdgz6zf647d3pay8if8506rclb3312wwa5qfd2hn"; |
||||
}; |
||||
|
||||
nativeBuildInputs = [ pkgconfig autoconf automake which libtool nasm ]; |
||||
|
||||
buildInputs = [ xorg.xorgserver ]; |
||||
|
||||
postPatch = '' |
||||
# patch from Debian, allows to run xrdp daemon under unprivileged user |
||||
substituteInPlace module/rdpClientCon.c \ |
||||
--replace 'g_sck_listen(dev->listen_sck);' 'g_sck_listen(dev->listen_sck); g_chmod_hex(dev->uds_data, 0x0660);' |
||||
|
||||
substituteInPlace configure.ac \ |
||||
--replace 'moduledir=`pkg-config xorg-server --variable=moduledir`' "moduledir=$out/lib/xorg/modules" \ |
||||
--replace 'sysconfdir="/etc"' "sysconfdir=$out/etc" |
||||
''; |
||||
|
||||
preConfigure = "./bootstrap"; |
||||
|
||||
configureFlags = [ "XRDP_CFLAGS=-I${xrdp.src}/common" ]; |
||||
|
||||
enableParallelBuilding = true; |
||||
}; |
||||
|
||||
xrdp = stdenv.mkDerivation rec { |
||||
version = "0.9.1"; |
||||
rev = "0920933"; # Fixes https://github.com/neutrinolabs/xrdp/issues/609; not a patch on top of the official repo because "xorgxrdp.configureFlags" above includes "xrdp.src" which must be fixed already |
||||
name = "xrdp-${version}.${rev}"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "volth"; |
||||
repo = "xrdp"; |
||||
rev = rev; |
||||
fetchSubmodules = true; |
||||
sha256 = "0a000h82728vp0abvjk2m03nqqiw2lky7kqk41b70cyd3bp0vdnz"; |
||||
}; |
||||
|
||||
nativeBuildInputs = [ pkgconfig autoconf automake which libtool nasm ]; |
||||
|
||||
buildInputs = [ openssl systemd pam fuse libjpeg libopus xorg.libX11 xorg.libXfixes xorg.libXrandr ]; |
||||
|
||||
postPatch = '' |
||||
substituteInPlace sesman/xauth.c --replace "xauth -q" "${xorg.xauth}/bin/xauth -q" |
||||
substituteInPlace common/file_loc.h --replace /etc/xrdp $out/etc/xrdp --replace /usr/local $out |
||||
substituteInPlace instfiles/xrdp.sh --replace /etc/xrdp $out/etc/xrdp --replace /usr/local $out |
||||
''; |
||||
|
||||
preConfigure = '' |
||||
(cd librfxcodec && ./bootstrap && ./configure --prefix=$out --enable-static --disable-shared) |
||||
./bootstrap |
||||
''; |
||||
dontDisableStatic = true; |
||||
configureFlags = [ "--with-systemdsystemunitdir=./do-not-install" "--enable-ipv6" "--enable-jpeg" "--enable-fuse" "--enable-rfxcodec" "--enable-opus" ]; |
||||
|
||||
installFlags = [ "DESTDIR=$(out)" "prefix=" ]; |
||||
|
||||
postInstall = '' |
||||
# remove generated keys as non-determenistic |
||||
rm $out/etc/xrdp/{rsakeys.ini,key.pem,cert.pem} |
||||
|
||||
cp $src/keygen/openssl.conf $out/share/xrdp/openssl.conf |
||||
|
||||
substituteInPlace $out/etc/xrdp/sesman.ini --replace /etc/xrdp/pulse $out/etc/xrdp/pulse |
||||
|
||||
# remove all session types except Xorg (they are not supported by this setup) |
||||
${perl}/bin/perl -i -ne 'print unless /\[(X11rdp|Xvnc|console|vnc-any|sesman-any|rdp-any|neutrinordp-any)\]/ .. /^$/' $out/etc/xrdp/xrdp.ini |
||||
|
||||
# remove all session types and then add Xorg |
||||
${perl}/bin/perl -i -ne 'print unless /\[(X11rdp|Xvnc|Xorg)\]/ .. /^$/' $out/etc/xrdp/sesman.ini |
||||
|
||||
cat >> $out/etc/xrdp/sesman.ini <<EOF |
||||
|
||||
[Xorg] |
||||
param=${xorg.xorgserver}/bin/Xorg |
||||
param=-modulepath |
||||
param=${xorgxrdp}/lib/xorg/modules,${xorg.xorgserver}/lib/xorg/modules |
||||
; the following two lines are needless after https://github.com/NixOS/nixpkgs/pull/21653 |
||||
param=-xkbdir |
||||
param=${xorg.xkeyboardconfig}/share/X11/xkb |
||||
param=-config |
||||
param=${xorgxrdp}/etc/X11/xrdp/xorg.conf |
||||
param=-noreset |
||||
param=-nolisten |
||||
param=tcp |
||||
param=-logfile |
||||
param=.xorgxrdp.%s.log |
||||
EOF |
||||
''; |
||||
|
||||
enableParallelBuilding = true; |
||||
|
||||
meta = with stdenv.lib; { |
||||
description = "An open source RDP server"; |
||||
homepage = https://github.com/neutrinolabs/xrdp; |
||||
license = licenses.asl20; |
||||
maintainers = [ maintainers.volth ]; |
||||
platforms = platforms.linux; |
||||
}; |
||||
}; |
||||
in xrdp |
Loading…
Reference in new issue