Sunday, February 21, 2010

Playing MIDI files in Ubuntu

Back in the winter of 2005 when I was using Debian (back them Etch was the "testing" version) I spent several frustrated days trying to get Linux to play MIDI files. The best I could come up with was running TiMidiTy from the command line and specifying the "dumb" interface. It was very clumsy because I kept forgetting the command line arguments and would have to look them up whenever I wanted to play a song, and eventually I just decided that playing MIDI files was something that I would have to boot into my Windows partition to be able to do with a reasonable amount of ease.

Fast forward to about half an hour ago. I joined our local Church's choir last fall and wanted to listen to some MIDI files to help me learn my parts. A quick Google search revealed the packages I needed, so I went to the command line and issued the following:

    sudo apt-get install timidity timidity-interfaces-extra freepats

And within a few minutes I was listening to my MIDI files through Totem movie player, with which Ubuntu had automatically associated the MIDI file type. After my last experience I couldn't believe how easy it was!

So I want to send a big shout out to all the devs working on Ubuntu, Gnome, TiMidiTy, PulseAudio, etc. for getting this right. The need for playing MIDI files is definitely something of a niche need, since not too many people listen to them, so it would have been easy to overlook it but instead they did a great job of making it work. This is yet another example of how far Linux has come over the years. The Internet is peppered with stories about how various tasks were recently very difficult to do on Linux and are dead simple now, and I am happy to add mine to the pile. Great work, guys!

Sunday, February 7, 2010

XRDP, the best remote access software under Linux

My desktop PC is in my basement office, which is a nice place but somewhat inconvenient.  I really wanted a way to access it remotely from my laptop but had trouble finding a remote-access application that was fast enough.

Both my laptop and desktop are wireless, so there are 2 wireless "hops" between my machines and when logged into my desktop from my laptop each command (i.e. a click or keystroke) has 4 wireless hops to go through before my screen displays the result.  So speed is key. 

Remote access servers that didn't work out

I tried pretty much every remote access server I could find.  I was already familiar with VNC, and that was a perfectly viable option but my desktop has dual monitors, so there was a pretty big difference in screen resolutions and one of VNC's real weaknesses IMHO is that the client is forced to use the screen resolution of the server.  I didn't want to be scrolling around a lot so I axed that idea. 

Next I tried SSH with X forwarding enabled (using the -Y option).  That was nice and simple since all of the software and keys were already in place, but it was too slow, even with the -C option (which enables compression, effectively speeding up the rate of transfer).  FreeNX is a similar solution, and although it was somewhat faster some of the time, it didn't provide a consistently high level of performance so I had to reject both solutions.


Gnome also offers the option of logging into another machine via XDMCP.  When booting my laptop, I would stop at the login screen, hit Options, then "Remote Login via XDMCP".  In addition to stopping me from running any applications or doing anything else on my laptop while logged into my desktop remotely, this proved to be too slow also, so I canned the idea.


I was about to give up when I discovered xrdp.


XRDP

XRDP is a service that I installed on my desktop to enable it to accept RDP connections from my laptop.  Ubuntu already comes with an RDP client, tsclient, installed by default, and I've used Windows XP's Remote Desktop a lot at work so I know how well it works.  XRDP is in the Ubuntu repositories so I installed it on my desktop and now I can log into it from my laptop using the same program I use to log into my computer at work, and the speed more than adequate.  It is really great to be able to program, run virtual machines, and do many other resource-intensive operations from my laptop.

XRDP has a few quirks that I decided I could live with, but it is worth mentioning them here:
  1. It depends upon the package "tightvncserver" being installed on the server (the machine you are logging into), although it isn't configured as a dependency in the package (this was the case as of the last time I set up XRDP, which was a while ago so hopefully they have fixed this).  Install tightvncserver before you attempt to install XRDP.
  2. You may install the XRDP package and have it work just fine until you reboot the server.  This is because XRDP sometimes has difficulty figuring out whether it is running or not, so when the server is rebooting and it tries to start XRDP, XRDP thinks it is already running even though it isn't and refuses to start.  You can fix that by running this:
         sudo sesman --kill
         sudo xrdp --kill
         sudo rm /var/run/xrdp/xrdp.pid
         sudo sesman
         sudo xrdp
  3. There is no way to log into the console session.  So if I was working at my desktop and had to get up for something, I can't resume what I was doing on my laptop.  Windows XP provides the "/console" command-line switch which allows you to take over the session that is currently displayed on the machine's screen, but there is no way to do that with XRDP.  There might be a way to do it within Gnome; I'm not sure at the moment.
  4. If you do anything in the remote session that makes a sound, the sound will be played on the server's speakers, not your client's speakers.  So the first thing I hear when logging into my desktop is the sound of the Ubuntu login music being played on my desktop speakers, down the stairs and two rooms away.  This is a very minor annoyance to me but it is worth mentioning.
So now I have exactly what I set out to get: an easy-to-use remote access method that is fast and reliable.  It is really great to be able to open tsclient (you will find it on the Internet menu, it is called "Terminal Server Client") and see my desktop.  I highly recommend it!

Saturday, February 6, 2010

Using passphrase-protected SSH keys in Cron

Just a few days ago I told you all about the glory that is SSH, and now I want to show you how to automate its use.

I'm sure you noticed while you were setting up your key that it asked you for a passphrase to protect the key.  If you opt not to set a passphrase, it will store your key in plain text, which means that if anyone gets access to your filesystem, they have access to your key.  They can copy it and use it on any computer to log into your server as you, so you are much better off protecting your key with a passphrase.  The key generator will use the passphrase to encrypt your key and give you protection from this threat.

Because the SSH key is encrypted, whenever you want to use it, it will ask you for your passphrase so that it can get access to the key.  This is exactly what you want to keep your key secure, but if you want to automate any of your SSH related tasks in Cron, you will be prompted for the passphrase every time SSH tries to establish a connection with your server.  One quick, easy way out of this situation is to simply keep your SSH key unencrypted and hope that no one who gets near your computer has malicious intentions, but there's a better way: ssh-agent.

Ssh-agent is a process that stores SSH keys in memory.  When you set up your SSH key with a passphrase, you may notice that Gnome gives you the option to "unlock this key automatically when I log in" (Ubuntu offers this option, YMMV); if you select that option, it will use Ssh-agent to store your SSH key in memory.

So at this point you have your SSH key encrypted on disk but unlocked in memory, so you can manually SSH into your server without entering the password for you account on the server or your passphrase for the SSH key, but you want Cron to have the same ability.  At this point, any SSH jobs in Cron will prompt you for your passphrase to unlock the SSH key.  I will show you how to fix that by making your unlocked SSH key (which is stored in memory by ssh-agent) accessible to Cron.

There are 2 steps involved in making your key available to your script running in the Cron environment: Saving the 2 SSH environment variables to disk and reading them into your environment within your Cron job.

Saving the SSH environment variables

Go into your crontab file by entering "crontab -e" at the command line.  Add the following on its own line:

     @reboot ssh-agent -s | grep -v echo > $HOME/.ssh-agent

The @reboot is a special token in cron that will cause the command to be run when you first log in.  The command will cause the SSH_AUTH_SOCK and SSH_AGENT_PID to be written to a file on disk.

Retrieving the SSH environment variables within a Cron job

Basically, in order to make the running instance of ssh-agent available to your cron job, the following line needs to be run:
      
     . ~/.ssh-agent

On my machine, I put it right into crontab just before the job I wanted to run, like this:

     # m h  dom mon dow   command
     30 * * * * . ~/.ssh-agent; unison default -ui text -batch

If you are running a script, you can alternatively put the command at the top of the script.

And that's all there is to it!  You should now be able to run an SSH command using an SSH key that is encrypted on disk but unencrypted in memory within a cron job. 

EDIT:  A few days after posting this, I discovered that it was actually not working for me at all.  The steps I just described probably would have worked just fine if I was trying to start my own ssh-agent process and manually add keys to it using ssh-add, but I was trying to do it using the ssh-agent process and key which seahorse sets up for me when I first log in, and this configuration required a slightly different solution.  See my follow-up post for details.
 

See also:  http://sial.org/howto/openssh/publickey-auth/

Wednesday, February 3, 2010

SSH, the Secure Shizzle

SSH, the "secure shell" is the ultimate exception to the "security is inversely proportional to convenience" rule.  It is so easy to set up and once you have it running, secure authentication and communication are totally transparent.  It's almost irresponsible not to use it.

In its most basic form, SSH is a secure remote console program, a secure replacement for Telnet, however, it is very flexible and can handle such tasks as secure file copying between machines, proxying, and even tunneling.  Also, it's been around so long that it has become one of the de facto standards for secure authentication and communication on Linux.  Pretty much any network-enabled program worth its salt will feature support for it.

There are many fine tutorials on how to use SSH, my favorite is by the incomparable Chess Griffen on the Linux Reality podcast.  If you aren't already familiar with SSH, stop reading this post and listen to that episode of Linux Reality right away.  I'll wait.

As awesome as it is to be able to type "ssh myserver", enter the password, and start entering commands to be run on your server, there's a better way.  It's called SSH keys, and they will save you the trouble of typing in your password every time you want to connect to the server and they will give your server extra protection from being hacked.  It's easier and more secure, which almost never happens, so you know you have to do it.

Creating an SSH key

Simply hop into the command line and type "ssh-keygen".  It will ask you to give a filename and location for the new keys, and it will ask you to give it a passphrase.  When it is finished, go into your home directory's .ssh folder, and you will see two files: id_rsa and id_rsa.pub.  The id_rsa file is your private key; leave it where it is and don't let anyone have access to it.  Copy the id_rsa.pub file to your server.  On the server, go into your home directory's .ssh folder.  Create a file called authorized_keys if it doesn't already exist and copy the contents of your id_rsa.pub file into it (append the contents if the authorized_keys file already exists).  Now, go back to your client machine and SSH into your server.  It should let you in without asking for a password.

More SSH hardening measures

Let's face it, half the point of SSH is the security.  Setting up keys as I described will protect communications between your computers and ensure that you are actually contacting the server you think you are contacting with almost no effort on your part.  There are a few extra steps that should be taken to gain the highest level of security:
  1. Disallow protocol 1: On the server, open /etc/ssh/sshd_config as root.  Find the line that says "Protocol 1,2".  Delete the 1 and the comma, so it only says "Protocol 2".  Don't close sshd_config yet...
  2. Also in sshd_config, find the line that says "#PasswordAuthentication yes".  Remove the hash mark from the beginning of the line and change "yes" to "no".  Keep sshd_config open...
  3. Find the line that says "Port 22" and change the 22 to another number between 1024 and 65535.  
  4. Save that file and restart the ssh daemon (you can usually do this by running "sh /etc/init.d/sshd restart" as root)
  5. On your client, open /etc/ssh/ssh_config as root
  6. Find the line that says "Port 22" and change it to the same port number you set in step 3 above.
  7. Find the line that says "Protocol 1,2" and change it to "Protocol 2", as you did on the server in step 1 above.
  8. Find the line that says "Cipher aes128-cbc,3des-cbc,blowfish-cbc...".  Remove the hash mark at the beginning of the line if there is one, then remove all of the ciphers listed except aes256-cbc.  So that line should read, "Cipher aes256-cbc".
  9. Save that file
  10. Bookmark this blog post, because you will have to repeat steps 5-9 on all of your clients.
This may seem like a lot of work, but please keep in mind that SSH has been around for a very long time and there are a lot of automated ways to attack an SSH server that rely on the default settings, such as support for Protocol 1 and having the SSH daemon listen on port 22.  Changing these defaults takes only a few minutes but makes it exponentially harder for hackers to get in.  These steps are absolutely essential if you are considering exposing your SSH daemon to the public Internet.  

At this point, you are able communicate between machines with more ease and convenience than ever, and those communications are secured by military-grade authentication and encryption.  Security and convenience will never be this close, so take advantage!