+++ title = "Running Emacs with wsl2-xrdp" [taxonomies] tags = [ "wsl", "emacs" ] categories = ["os", "apps" ] +++ # Why I have been using Emacs in WSL2 using an X server running in Windows and that works fine as long as long as the computer does not go to sleep. When the computer goes to sleep, the X connection is cut and the emacs process crashes. I like to just have my emacs session available so I can continue where I was last time and I like my computer to go to sleep when I not use it because Global Warming. - start emacs in WSL2 in GUI mode - can be reconnected after sleep - copy-paste works transparent # Plan - use **xrdp** as remote desktop is built into windows - configure xrdp to startup in WSL2 - run emacs in a remote desktop session # Installation ## Install xrdp [Arch wiki page for xrdp](https://wiki.archlinux.org/index.php/xrdp) ``` sh $ yay -S xrdp xorgxrdp-git ``` We do not have systemd in WSL2 so I started the daemons manually with a small script \*/usr/local/bin/start-xrdp: ``` sh #!/bin/bash sudo /usr/sbin/xrdp sudo /usr/sbin/xrdp-sesman ``` We can now start it with **start-xrdp** from the bash command line or using **wsl -u root /usr/local/bin/start-xrdp**. If not running as root (or recently authenticated sudo access) it will ask for your Linux password to allow running as **sudo**. Trying to connect lets me login but after a timeout is shows a dialog box telling me Xorg did not want to start. This is confirmed in the **/var/log/xrdp-sesman.log** file. The root cause is that I cannot read properly because if I could, I would have read to add *allowed\\~users~=anybody* to the **/etc/X11/Xwrapper.config** file to allow **Xorg** to be started by regular users like me instead of only **root**. Once that is there I get a nice black screen after login. Note: Each time WSL2 restarts it gets a random ip address. So I created a small script to dig out the actual ip address out of the output of **ip address** : ``` sh #!/bin/bash ip address show dev eth0 | grep "inet " | sed -e 's/.*inet \([^/]*\).*/\1/' ``` Which I gave the original name of **/usr/local/bin/ip-address** (do not forget to `chmod +x /usr/local/bin/ip-address` to make it executable) so I can easily call it from powershell with `wsl ip-address`. ## Installing DBUS replacement DBUS is the de-facto GNU/Linux desktop communication bus which glues all kind of GUI apps together. I do not know if it is directly used by Emacs or any of the extensions I use, however it reduces the amount of errors and warnings. ``` sh $ yay -S dbus-x11 ``` allows xfce and other programs to feel happy and display the desktop with an emacs window. Now just maximizing the window and the goal is reached. ## Automatic start of Emacs only In order to just start emacs maximized in a single remote desktop window we only need to start it as the only program in the XSession. This of course also means there is no chrome on the X-Window or the ability to lauch other programs outside of Emacs. This is exactly how I like it. ``` sh #file:~/.xinitrc emacs -mm ``` If you rather have a full desktop environment, see further. ## Installing Xfce4 (Optional) I\'d rather have something more lightweight as window manager, but I have experience with Xfce4 in Arch and I also like something which just works. I only intend to run emacs in the window however having something a bit more capable which works can help me debug the environment. (I have some font things to sort out too...) ``` sh $ sudo pacman -S xfce4 ``` and then start it form **\~/.xinitrc** ``` sh emacs & startxfce4 ``` If you have skipped the **DBUS** setup above, this hangs while the **\~/.xorgxrdp.log** file is filling up with errors complaining about missing connection to dbus. # Using this from Windows ## Starting from the command-line We can start remote desktop session using >_ mstsc /v:$(wsl ip-address) /h:2560 /w:1600 This works, however we get now a prompt to accept the certificate and we still need to login. We can make this smoother ## Accepting the certificate You can accept the certificate and let remote desktop add it to your certificate stores. This solves this interruption. However, this still happens each time the ip address changes. ## Automatic login Start **remote desktop** GUI using the search or from the start menu. Fill in the ip address returned by `wsl ip-address` and your username. Enable the flag to store your password. Login and save the configuration as e.g. **emacs.rdp**. We can now start emacs using >_ cmdkey /generic:$(wsl ip-address) /user: /pass: >_ mstsc /v:$(wsl ip-address) We can assemble this is a small script **wsl-emacs.ps1** somewhere on your path: ``` powershell wsl -u root /usr/local/bin/start-xrdp $address = $(wsl ip-address) $userName = "pti" $userPwd = "shht!Secret" cmdkey /generic:$address /user:$userName /pass:$userPwd mstsc /v:$address ``` Which allows us to start our **wsl-emacs** from powershell or as a startup application with a shortcut. It ensures the **xrdp** daemons are running (they are idempotent, so the script can be run multiple times), then the credentials are created so they can be picked up by remote desktop. To add a shortcut to the start menu: - Type Win-R and open \*%AppData%`\Microsoft`{=latex}`\Windows`{=latex}`\Start`{=latex} Menu`\Programs*`{=latex} - create a new shortcut - set as target \*powershell.exe \"& \'\`\wsl`{=latex}-emacs.ps1\' Note the weird **\"&** on the command-line. ## A note on security Since you can run any command from the windows command-line as root, the current logged in person has full access to anything in the WSL Linux machines. As such there is not a big hole added by adding your linux password somewhere securely in your account files such as the startup script. This does not mean you should not have secure passwords, as your linux box can expose its ports (not by default but just assume they are) and allow e.g. ssh access. Since I assume a lot of WSL2 hosts will be used fast and loose as a development box, there is a good chance that sooner or later a port is opened for reasons. So I would not worry too much your linux box password is exposed in the emacs startup script as long as it is hard enough and not used anywhere else. If you\'d like to get it from some secure vault on your PC or from your infrastructure, go for it. tldr; - use a strong password for your WSL box - do not reuse an existing password - secure your startup script so it is only readable by you.