Blog - Mutt and Bash on Ubuntu on Windows

Added on Wednesday, 2017-05-17 22:25 CEST in category Programming
For many, many years now I've been running my own email server, with Mutt as my email client, running in Screen on that same server. This setup gives me a lot of flexibility and programmability, but as efficient as it is, there had always been one big issue: attachments.

Attachments, be they HTML, PDF, audio/video, etc., just don't work well in a text-based UI. You can imagine my reaction when I came across this blog post on how to open these attachments locally, i.e., on my laptop. The general idea is as follows:
  • When logging in to my server over SSH, a RemoteForward tunnel is set up back to my laptop;
  • When I press 'x' in Mutt, it starts a script that copies the attachment over this connection, tells the laptop to open the file locally, and after a few seconds delete it.
This approach has been working great on my work laptop, which runs Linux, but I also wanted to get it working on my personal laptop, which runs Windows. In the meantime I'd gotten Bash on Ubuntu on Windows working properly, and after an evening of hacking I managed to get the whole shebang working there too.

Setting up sshd

In order for the connection from the server back to my laptop to work, I need to run sshd on my laptop.
  • For this I needed to install sshd:
    sudo apt-get install openssh-server; sudo ssh-keygen -A
  • Unfortunately, sshd isn't automatically started when opening bash, so I added
    service ssh --full-restart
    to /home/nieko/env/scripts/launch-screen.sh (see also my previous blogpost).
  • Next, I added the contents of my server's ~/.ssh/id_rsa.pub to my laptop's ~/.ssh/authorized_keys, and fixed its rights with
    chmod 600 ~/.ssh/authorized_keys
This should allow for incoming connections whenever I have Bash on Ubuntu on Windows running.

Setting up the RemoteForward tunnel

Whenever I connect to my server, I use RemoteForward to set up a tunnel back to my laptop, which I enabled in ~/.ssh/config on my laptop:
Host nieko.net
  RemoteForward 12345 127.0.0.1:22
  AddressFamily inet
  ForwardX11 yes
This tells SSH when connecting to nieko.net to also remotely (on my server) forward port 12345 on my server, back to 127.0.0.1:22 on my laptop, where sshd is listening.

Unfortunately IPv6 doesn't work yet in the Windows Subsystem for Linux, hence the rules above force an IPv4 connection. You can prefer IPv4 over IPv6 lookups globally by uncommenting the following line in /etc/gai.conf:
precedence ::ffff:0:0/96  100
Lastly, in order for forwarding to work, ssh needs an X11 "display", so when connecting over SSH, I run:
export DISPLAY=:0 ssh nieko.net
When opening this SSH connection, I now have remote port 12345 open (i.e., on the server), which I tested there as follows:
ssh -p 12345 127.0.0.1 ls
This output the files in my home directory on my laptop, success!

Copying and opening the attachment

With all that working the next step was to update Mutt's attachment upload script to call the right Windows-specific programs. You can download the full script here. A few highlights:
  • The script is invoked in Mutt by adding the following to ~/.muttrc, which makes use of mutt-attachment.mailcap:
    macro attach x ":set mailcap_path= ~/scripts/mutt-attachment.mailcap\n<view-mailcap>:reset mailcap_path\n"
  • "personal-laptop" (running Windows) and "work-laptop" (running Linux) are defined in ~/.ssh/config on my server as follows:
    # Connect back to laptop using SSH remote forwarding
    Host personal-laptop
        Hostname localhost
        Port 12345
    
    Host work-laptop
        Hostname localhost
        Port 54321
  • The "remote" directory /home/nieko/Incoming (on my laptop) is actually a symlink to /mnt/d/!incoming/, and is accessible to Windows; other bash directories are not.
  • Whereas Linux uses MIME types, Windows looks at file extensions. I therefore try to map the MIME type Mutt gave me to a file extension using /etc/mime.types.
  • Windows's command prompt supports the built-in command "start", which can be used to open a file by extension.
So now when I press 'x' on an attachment in Mutt on my server, it opens on my Windows laptop. So handy!