website/content/blog/2021-01-17-running-emacs-with-wsl2-xrdp.md
2023-10-19 01:04:39 +02:00

211 lines
6.5 KiB
Markdown

+++
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)
``` shell
$ 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:
``` shell
#!/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** :
``` shell
#!/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.
``` shell
$ 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.
``` shell
#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...)
``` shell
$ sudo pacman -S xfce4
```
and then start it form **\~/.xinitrc**
``` shell
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:<username> /pass:<password>
>_ 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 \"&
\'\<path-of-script\>`\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.