Setting up Cygwin/X
In this article we will set-up Cygwin with an X11 server so you can use X11
forwarding to run remote graphical applications on Windows. To allow a
passwordless log-in, we will use public-key authentication. Even though this is
technically out of scope of this document, I will summarize the necessary steps
to make this a comprehensive guide.
Quick summary
We will need the following Cygwin packages:
- xinit — Everything you need for a local X11 server.
- openssh — The SSH package to connect to remote machines.
- keychain — A tool to simplify handling public key authentication.
- nano or vim — A text editor to work on config files. Note that
vim behaves extremely different on Windows/Cygwin than on common unix
systems. So if you don’t fully grok vim, stick to nano. If you create
a proper .vimrc, it will return back to “normal” though.
Once the packages are set up, we will put passwordless authentication in place,
check X11 forwarding and finally make some changes to the system config files
(notably: ~/.startxwinrc and ~/.XWinrc).
Installing Cygwin
Go to the Cygwin download page and grab the installer (setup-x86.exe or
setup-x86_64.exe). Run it.
The installer is pretty self-explanatory. When asked to select a mirror, try to
pick one closest to your location. The country-code in the URL should give you
a hint. It can make a huge difference in download times.
When you arrive at the package selection, mark the packages mentiones above for
installation. Use the search box to find them. Once clicking next, the
installer will ask if it should install the required dependencies. Accept and
continue.
Public Key Authentication
I won’t go much into detail about this topic. If you already have a
private/public key pair, you can skip this step, but you should take note of
the location of your private key!
If you need a new pair, we’ll create them here using the defaults. The defaults
will create the files ~/.ssh/id_rsa and ~.ssh/id_rsa.pub. If you want
to change the defaults (f.ex.: if you want a DSA key, or change the filename),
you should look it up in the man-pages of ssh-keygen.
Creating a key pair
Run the following command:
It will ask you for a target filename and passphrase. Obviously, if you care
about security, you should give it a strong passphrase. It is possible to
leave it empty, but this means that anyone who gets hold of your private key
will be able to log-in without password to any server where you deploy your
public key! You have been warned!
The above command will create the following files:
- ~/.ssh/id_rsa
- Your private key. Take good care of this one. Keep it safe. You can always
derive the public key from this one as well. - ~/.ssh/id_rsa.pub
- Your public key. This is the key we will deploy on the remote machine(s).
“Deploying” the public key
The remote server maintains a list of which keys are allowed to log-in to a
specific user-account. This file is located under
remote-machine:~usernam/.ssh/authorized_keys. It’s a plain-text file and
can be modified manually, but we’ll use the tools made available by OpenSSH.
To add your public key to the list, run the command:
This will by default use ~/.ssh/id_rsa.pub. If you changed the filename,
you should consult the man-page of ssh-copy-id.
To verify if logging in with yout key works, run the following command:
It should now ask for the passphrase of the key. Not the password of the
server. If this works, we can now move on the set up ssh-agent using
keychain to load the key into memory.
keychain
To allow a real passwordless login, your key must be loaded into memory using a
tool called ssh-agent. This has it's security implications, but for most
day-to-day work, it will be "secure enough". In it's base form, you usually run
ssh-agent as parent process to the processes you would like to have access
to your keys. This is sometime cumbersome. keychain simplifies this.
To load your keys run:
To set-up keychain to run automatically, add the following line to your
~/.bashrc:
This will initialise each bash session with the proper environment variables to
make publickey authentication work. To test this, re-start your xterm right
now, and try to access your remote machine. It should work without password now.
Note that keychain only asks your passphrase on first execution. After
that, it will automatically detect the proper running agent and "connect" to
it.
X11 forwarding
You should now be able to connect to your remote host without a password
prompt. We can now test X11 forwarding. First, make sure Cygwin/X is running.
You can see that it's running by the black "X" symbol in the system tray.
To test forwarding, run xterm. If it's not yet running, you can launch it
by right clicking the system tray icon.
Inside xterm, run:
This will run xcalc on the remote machine. xcalc should be available on
each machine with X11 installed. If this does not work, go back and see if you
did not skip over something.
If it asks for a password, make sure you have keychain running and that you
have it set up in your ~/.bashrc.
If a window with a calculator pops up on your screen, you're in business. But
we will automate a few things. In general, you probably want to always forward
X11 to that host (the -X flag). You can configure this in your
~/.ssh/config file. Here's an example:
ForwardX11 yes
ForwardAgent yes
Compression yes
CompressionLevel 9
This will use the mentioned settings for each SSH connection made to
myremote-host. See man ssh_config for more details.
Forwarding the agent means that you will be able to make passwordless
connections to other hosts from within that connection.
This will also set up strong compression on the channel, which can be
beneficial for X11 connections. X11 is by default uncompressed. You should
experiment with the compression level to find something that works best for
you. The value depends on connection speed and CPU power of both host and
client. A higher value means that more CPU is required on both machines, but
there will be less data transmitted over the channel. This can have a
dramatic impact over slow connections!
Configuring Cygwin
Next we will touch the aforementioned config files ~/.startxwinrc and
~/.XWinrc.
~/.startxwinrc
This file contains startup commands for the X11 server. These commands will be
run right after the X11 server is running. Think of is as a file akin to
autorun.bat.
You will have noticed by now, that Cygwin/X always starts an xterm instance
on startup. This is because, if no ~/.startxwinrc is present, it will run
the system file, which contains this command. If you want to suppress this
simply put an empty file in place:
However there is a problem with public key management. By default,
keychain will use a GUI tool to ask the passphrase if it's not running in
an interactive console. That tool is selected using the SSH_ASKPASS
environment variable. Unfortunately, I have not yet found a satisfactory
solution for Windows.
This means, I recommend running keychain in an interactive console first
before doing anything else. The change we made to ~/.bashrc above will do
this, as long as you run an interactive console! Thus, having an xterm pop
up once the X11 server is up and running is convenient.
If you have a multi-monitor set-up, you may also notice, that xterm pops up
on the very upper left corner of your leftmost screen (coordinates: 0, 0). This
may be annoying, but can be specified using the -geometry argument to
xterm. A sample ~/.startxwinrc might therefore look like:
This will create a window which is 200 characters wide and 70 characters high
on coordinates (1970, 50). If your left screen is 1920 pixels wide, this will
place it on your second screen.
We'll leave xterm in the ~/.startxwinrc file as a poor-man's
replacement for a better SSH_ASKPASS tool.
~/.XWinrc
This file contains the configuration for the context-menu which is available
from the system tray.
The system-tray menu is a very convenient way to launch applications on
Cygwin/X. Even remote.
Note that your X11 instance does not have the necessary environment variable
set up to access the SSH-agent. So each remote connection must be prefixed with
a call to keychain!
Let's add a menu option for xcalc:
menu apps {
xterm exec "xterm"
"xcalc on myremote-host" exec "eval `keychain --eval id_rsa` && ssh myremote-host xcalc"
[... snip ...]
}
[... snip ...]
The remote-xcalc line will add a new menu option in the "Applications"
menu, running the remote xcalc. The ssh command does not contain the
-X flag because we added the ForwardX11 directive to ~/.ssh_config.
It would be redundant.
The X11 context menu contains an entry "Reload .XWinrc" entry. Press this now,
and the above entry should appear.
Selecting the "xcalc on myremote-host" should run the xcalc window.
Running remote applications in this manner will open a separate SSH connection
for each application. This can be avoided using SSH connection sharing, or by
simply executing an application launcher (f.ex.: xfce4-panel) on the
remote, and running your application from there.
Troubleshooting
If you run into trouble, stop the X11 server (via the system tray), and launch
a normal Cygwin shell. Inside that shell run:
Running Cygwin/X like this, will show messages on your console which might help
identifying issues you might have.
For example, the issu mentioned below about keyboard layouts should trigger a
message similar to this:
In my experience, running the server like this will cause issues with X11
forwarding though, and running applications via the context menu won't work,
but running it manually via the default xterm should still work.
Known issues
- Keyboard layout
- Cygwin/X tries to use the most appropriate layout for your X11 session based
on the layout selected in the Regional settings in Windows. If it does not
find the appropriate layout, it willk revert to en_US! For example, if
setting up Windows with everything set to Luxembourg it will use a
keyboard layout German/Luxembourg. This is unknown to Cygwin and it will
revert to en_US. However, that layout is the exact same as French/Swiss
which is known to Cygwin and it will work as expected. Something to keep in
mind! - Passphrase for private key is not asked
- See the notes on SSH_ASKPASS above in the "Configuring Cygwin" section.
Comparison to PuTTY/Xming
In the past I always used PuTTY with Xming for the same task. But after using
Cygwin/X I am not going back. The fonts are much clearer on Cygwin/X than on
Xming, and multi-monitor support is much better. As an additional side-effect,
you will have Cygwin on your Windows machine, which might come in handy.
The downside is that public key authentication with PuTTY and pageant
(which is the PuTTY equivalent to keychain) is much better integrated in
the Windows world. A good deal of applications in Windows are capable of using
pageant, including WinSCP, TortoiseGit, TortoiseSVN and more.
Unfortunately PuTTY uses a different format for SSH keys, but they can be
converted using putty-keygen. In the end it's hard to avoid having both
PuTTY and Cygwin/X on your machine if you want to use application which only
support pageant or plink.