SSH

From CSE330 Wiki
Revision as of 19:29, 2 May 2014 by Shane (talk | contribs) (AWS has upgraded from Precise to Trusty)
Jump to navigationJump to search

Secure SHell, or SSH, is the leading interface for connecting as an administrator from your local computer to something on the cloud. You will be using exclusively SSH to execute commands and upload files to your cloud instance. If you use a Git hosting service like BitBucket or Github, you will need SSH in order to save your changes there as well.

SSH access requires that the sshd daemon is running on the remote machine. By default, SSH is preinstalled on your EC2 instance. If you are not using an EC2 instance, simply install ssh from yum or apt on the remote machine.

SSH Keys

SSH can work using password-based authentication, but it is more common nowadays, and also more secure, to use public and private keys, also known as a key pair.

Here's how it works. You have a private copy of your key, called your private key. Servers to which you want to connect have an analog to your private key called your public key. When you attempt to connect to a server using your private key, the server checks to see if any of its public keys "fits" your private key, and if it finds a match, it lets you in.

You can think of the private key as the "key" and the public key as the "lock".

SSH Configuration

This section discusses how to set up your computer and your remote instance for SSH. You need to do this only once.

Creating an SSH Key Pair

You should create your own SSH Key Pair. You will keep the private key on your own computer, and you will upload the public key to all places to which you need to connect.

To generate a key pair, open Terminal or Cygwin, which you will need to install if on a personal Windows computer, and run the following command:

# Run on Local Machine in Terminal or Cygwin
$ ssh-keygen

Important: Don't name the file unless you are using a CEC machine. If you are using a CEC machine, name the file /cygdrive/h/.ssh/id_rsa

For the purposes of this course, you do not need to enter a passphrase, although you would probably want one in real life.

Your keys should have been created in ~/.ssh. Check to make sure they exist using the ls command:

$ ls ~/.ssh
id_rsa  id_rsa.pub

id_rsa is your private key, and id_rsa.pub is the corresponding public key. Let's look at the public signature of your key pair:

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAA3Bblahblahblahblah yourname@somedomain

We will need this later. Let's now add our key to the ssh-agent.

SSH Agent: OS X

Run the following command to add your key to the SSH agent in Mac OS X.

# Non-Cygwin
$ ssh-add

SSH Agent: Cygwin

In order to make the SSH agent run when you start Cygwin, you need to run a couple more commands (these will add a line to your .bashrc file, which runs automatically on startup):

# Cygwin only
$ echo "eval \`ssh-agent -s\`; ssh-add" >> ~/.bashrc
$ source ~/.bashrc # reload the Bash shell

If you get this scary-looking error after you run the second command…

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

…then you need to do the following to fix the permissions:

# Cygwin only
$ chgrp Users /path/to/id_rsa
$ chmod 600 /path/to/id_rsa

Amazon EC2 SSH Configuration

When you first created your EC2 instance, you downloaded a *.pem file. This is the private key for the default user (ubuntu on Ubuntu or ec2-user on AMI). We need use this key to connect to your instance using the default user, at which point we will create a new custom user. We will give that new user the public key that you created in the previous step. You will then be able to log into your custom user using your personal key pair, so you won't need the default user again (although you should keep the *.pem file around just in case).

Logging In as the Default User

To connect to the default user on your Amazon EC2 instance, run this command in Terminal or Cygwin:

# Run on Local Machine
$ ssh -i /path/to/default-privatekey.pem ubuntu@ec2-xx-xx-xx-xx.compute-1.amazonaws.com # or ec2-user@... for AMI

Important: As soon as you are able to successfully log in, commands you type into your prompt will be executed on the remote instance, not your local machine.

If you get this scary-looking warning:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

…then you need to correctly set the permissions on your *.pem file. You should know how to do this from the Linux guide, but in case you didn't catch that detail, run:

# Run on Local Machine

# Cygwin Only:
$ chgrp Users /path/to/default-privatekey.pem

# Terminal and Cygwin:
$ chmod 600 /path/to/default-privatekey.pem

Food for Thought: Why you wouldn't want other people viewing your private key file?

Creating a New User with SSH Permissions

First, you need to create your new user with sudo and SSH permissions. Again, the instructions for this are in the Linux guide, but to keep everything in one place, the commands are:

# Run these on your instance, not on your local machine!

# Don't forget to customize `My Full Name` and `<username here>`:
$ sudo useradd -r -m -c "My Full Name" <username here>
$ sudo passwd <username here>

# Ubuntu only:
$ sudo chsh -s /bin/bash <username here>

# You need to add your username to the sudoers list.  Refer to the Linux guide for details.
#  Ubuntu: Look around line 19.
#  Amazon AMI: Look around line 99.
$ sudo visudo 

# Ubuntu only: add your user to the SSH whitelist:
$ echo "AllowUsers <username here> ubuntu" | sudo tee -a /etc/ssh/sshd_config

# Restart the SSH server:
$ sudo service ssh restart || sudo service sshd restart

Okay, cool: we have created our custom username on our remote instance. Now, we need to enable this account to accept our SSH key when authenticating. To do this, we need to add our public key to a file named authorized_keys, which is stored in your remote username's SSH configuration directory.

To create the directory and edit the file, run on your instance:

# Switch to our own user to ensure that permissions are set correctly:
$ su <username here>

# Change the working directory to our user's home directory:
$ cd

# Make the nonexistent SSH configuration directory and set its permissions:
$ mkdir .ssh
$ chmod 700 .ssh

# Create the `authorized_keys` file and set the permissions
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys

# Edit the `authorized_keys` file
$ nano .ssh/authorized_keys

For more detail on editing files on the command line, see the Linux guide.

Inside of the `authorized_keys` file, paste in your public key. Your public key is the content of `~/.ssh/id_rsa.pub` on your local machine (it starts with "ssh-rsa"). There are a few ways to get it onto your clipboard:

  1. OS X Only: Open a new Terminal and run:
    cat ~/.ssh/id_rsa.pub | pbcopy
    
    This immediately copies the contents of your public key to your clipboard.
  2. Windows Only: Navigate to id_rsa.pub manually, open it in your favorite text editor (like Notepad++), select all, and copy. The location of id_rsa.pub might be: C:\cygwin\home\username\.ssh\id_rsa.pub
  3. *NIX Only: Open a new Terminal and copy the output of the following command:
    cat ~/.ssh/id_rsa.pub
    
    Note that this won't work as advertised in Cygwin because Cygwin adds extra line breaks when you try to copy out of it.

When finished, save and close `authorized_keys`.

Food for Thought: How would you enable your remote user to authenticate over SSH using the same default key instead of the one you created using ssh-keygen?

Logging In as your New User

Let's test whether we can log into our instance using our own username and our own key pair. Open up a new Terminal or Cygwin and run:

$ ssh <username here>@ec2-xx-xx-xx-xx.compute-1.amazonaws.com

This is how you will be SSHing into your instances for the remainder of the semester.

Troubleshooting

Almost everyone receives the following error at some point in their career: Permission denied (publickey).

Here are some possible causes for the error.

The Authorized Keys File

Make sure that your remote authorized_keys file contains exactly your public signature from id_rsa.pub.

Pasting into Vi

If you used vi to edit your file and you forgot to enter "insert" mode before pasting in your key, it is possible that you lost the first "s" in "ssh-rsa".

Check the contents of authorized_keys via cat ~/.ssh/authorized_keys on your server. If the output starts with "sh-rsa" instead of "ssh-rsa", edit the authorized_keys file and add the second s.

Unintentional Line Breaks

If you got your key via a cat ~/.ssh/id_rsa.pub and then copied it from the terminal, it's possible that you unintentionally introduced line breaks. Ensure that the key is represented by only one line of text.

Permissions

They need to be correct on both the client side and on the server side.

  • Local .ssh = 700
  • Local id_rsa = 600
  • Remote .ssh = 700
  • Remote authorized_keys = 600

If you are in Cygwin and the permissions don't seem to change, you might need to add the troubled file to a usergroup, like this:

$ chgrp Users .ssh/id_rsa

The SSH Agent

You need to be sending the correct key along with your SSH Agent. Run the following command, and you should see some output:

$ ssh-add -l
2048 ab:cd:ef:ab:cd:ef:ab:cd:ef:ab:cd:ef:ab:cd:ef:ab:cd /path/to/.ssh/id_rsa (RSA)

If you don't see any output, or if the output does not contain your id_rsa, then you need to run:

$ ssh-add /path/to/.ssh/id_rsa

More SSH Server Configurations

Up to this point, we have been using all of the default SSH configurations. Like most things in Linux, SSH can be customized.

For the purposes of CSE 330, the additional configurations in this short section are optional; this serves only as a reference.

Disabling Root Access

It is almost always a good idea to disable root access over ssh. This could be done by editing /etc/ssh/sshd_config and setting

PermitRootLogin no

You will need to restart the SSH server for changes to take effect:

$ sudo service ssh restart # Debian version
$ sudo service sshd restart # RHEL version

Enabling Password-Based Authentication

Up to this point, we have been using key pairs for SSH. A public/private key pair is generally considered to be more secure, but it requires that you always have access to your private key file when you want to log into your remote machine.

By default, EC2 instances allow only public/private key pair authentication. You can enable password-based authentication by setting the PaswordAuthentication option in /etc/ssh/sshd_config to yes:

PasswordAuthentication yes

There may be a line with this option that you can un-comment. For me, it is line 25. You will need to restart the server for changes to take effect.

If possible, however, you should restrict yourself to using private and public keys.

Using SSH

Once you have completed the #SSH Configuration section above, all you need to do in order to SSH into your instance is to open a terminal and run:

$ ssh <username here>@ec2-xx-xx-xx-xx.compute-1.amazonaws.com

PuTTY

This short section about PuTTY serves only as a reference.

If you have Cygwin available, you should use it to SSH into your instance. However, if you are using a different computer, you might not have Cygwin at your fingertips. In this case, a lighter-weight SSH client called PuTTY is available for Windows.

You can download PuTTY from: http://www.chiark.greenend.org.uk/~sgtatham/putty/

Amazon provides a great tutorial on how to connect to a virtual machine from Windows.

PuTTY is fairly simple and straight forward with one caveat: Amazon's *.pem files are SSH private key files, and they need to be converted to PuTTY's own .ppk format. To do this, use the puttygen.exe utility available from the same page as PuTTY. Select "Import" under the conversions menu, load the amazon *.pem key file, and press the "Save Private Key" button.

Copy and paste works similarly to the X Window System in Unix. You use the left mouse button to select text in the PuTTY window. The act of selection automatically copies the text to the clipboard: there is no need to press Ctrl-Ins or Ctrl-C or anything else. In fact, pressing Ctrl-C will send a Ctrl-C character to the other end of your connection (just like it does the rest of the time), which may have unpleasant effects. The only thing you need to do, to copy text to the clipboard, is to select it.

To paste the clipboard contents into a PuTTY window, by default you click the right mouse button. If you have a three-button mouse and are used to X applications, you can configure pasting to be done by the middle button instead, but this is not the default because most Windows users don't have a middle button at all.

Here is a good PuTTY tutorial that you might find useful to get started: http://kb.mediatemple.net/questions/1595/Using+SSH+in+Putty+%28Windows%29

SSHFS and SFTP

In addition to just SSH, your SSH server also supports SSHFS, which enables you to mount your remote instance as a disk on your local computer, and SFTP, which is a file transfer protocol that enables you to upload files directly to your instance.

SSHFS

SSHFS is a filesystem client which allows secure mounting of remote file systems. While there are other ways to mount remote file systems, SSHFS has the advantage of being able to mount a file system located on any host that has an SSH daemon running without any host side installation or configuration. This means that you can easily access and edit your files using all of your local applications including IDEs.

As you may have inferred from the name, the underlying implementation utilizes SSH File Transfer Protocol in combination with FUSE, a package now included in the kernel that allows unprivileged users to easily create their own file systems in userspace (see the wikipedia entry for more information [1]).

To mount a share using password based authentication, the command is:

$ sshfs user@domain:/path/to/remote/directory /path/to/local/mountpoint

For example, to mount the directory /home/joe/myfiles in the user joe's home directory for a machine with the domain schmoesfiles.org using SSHFS you would enter the command

$ sshfs joe@www.schmoesfiles.org:myfiles

Note that if you are using public key authentication, the command to mount the remote filesystem may need to be slightly different:

$ sshfs -o IdentityFile=/path/to/private/key user@domain:/path/to/remote/directory /path/to/local/mountpoint

To unmount the filesystem, you can use the following command:

$ fusermount -u /path/to/local/mountpoint

SFTP

Any server running an SSH server is also compatible with SFTP or Secure File Transfer Protocol. (Compare to FTP, or File Transfer Protocol.) SFTP is a convenient way to edit files on your computer and then upload them to your server in just a few clicks.