Simple SSH Tutorial Outline

This is the outline for the talk I gave for the UMBC LUG on SSH. It probably won't be terribly helpful, as I wrote it for me, and I know all of this anyway, but it might be of some use to other people. I make no guarantees.


  1. Concepts

    1. Encryption

      Scrambles information so other people can't read it.

      1. Shared secrets

        Common case. There is a "password" (or similar) that both sides must know
        to encrypt/decrypt.

      2. Public keys

        There is a pair of keys. Things encrypted with one may only be decrypted
        with the other. Usually, one is kept secret while the other is publically
        distributed.

        1. Public key authentication

          If you have the public key, you can use it to check if the other end
          really has the private key (thus proving its authenticity).

        2. Fingerprints

          When you receive a public key, you may not know if it really belongs to
          the person you want to talk to. One method of verifying keys is via
          fingerprints. If you know the key's fingerprint ahead of time, you can
          check that agains the key you have. (Fingerprints are much shorter than
          actual keys and more practical to write down on sheets of paper.)

    2. Accessing machines remotely.

      1. Local access

        When you sit at a computer (and a command line), everything you type goes
        directly to the shell (which provides the "command line").

      2. telnet

        telnet goes across the network to simulate the same thing. Whatever you
        type is picked up, sent across the network, and sent to the shell on the
        remote machine.

        1. telnet is plaintext

          telnet sends everything literally across the network, so anyone watching
          the network will see exactly what you type, including things that you
          don't even see on the screen (like passwords).

      3. ssh

        ssh has the same basic concept as telnet--it takes what you type and sends
        it across the network to a shell on the remote computer.

        1. ssh is encrypted

          ssh, however, uses encryption to protect your information. People
          watching an ssh session on the network will see only gibberish.

    3. Versions of ssh

      There have been two major versions of the SSH protocol, as well as
      multiple implementations of it.

      1. The protocol

        Version 2 has a lot of nice features, including not being vulnerable
        to one particular security hole present in the first version of the
        protocol.

      2. Implementations

        There are three common implementations of ssh. OpenSSH, F-Secure SSH,
        and SSH.com SSH.

      3. UMBC

        UMBC uses SSH.com's SSH1, which only supports version 1 of the SSH
        protocol. (It does have compensation code to make the security hole
        harder to exploit.)

  2. Basic SSH

    1. Standard case

      Usually, ssh is used just as you would telnet. ssh to a host, type your
      password (correctly), and you're in.

      1. Example

        $ ssh somehost
        user@somehost's password: [not shown]
        somehost$


      2. Description

        Note that ssh does not ask for your username as telnet does. ssh assumes
        the username on the remote computer is the same as that on the local one.

    2. Host keys

      ssh uses public key encryption for the initial conversation with the
      host.

      1. Usefulness of PKI

        1. Encryption

          public keys are slow to use, so the ssh client sends a password encrypted
          with the server's public key.

        2. Authentication

          To prevent a man-in-the-middle attack, the client uses the host key to
          verify the host's authenticity.

          1. Man-in-the-middle attack

            Once the data is encrypted on the network, it can only be read by the
            intended recipient. However, someone may set up a computer that pretends
            to be the host that you want so you connect to that fake computer instead
            of the real one. The fake computer can then decrypt your data, look at
            it, encrypt it again, and send it on to the real host. Since your data is
            going all the way to the real computer (and back), you might never notice
            the intrusion.

            However, since the host's private key is kept secret, a man-in-the-middle
            can't fake it and is doomed to failure.

      2. Practical considerations

        When you ssh to a host you've never talked to before, it sends you its
        public key. This is possibly a security hole, since a fake host could get
        you to take its key instead at this point.

        1. Example

          $ ssh somehost
          The authenticity of host 'somehost (192.168.1.1)' can't be established.
          RSA key fingerprint is 90:9c:46:ab:03:1d:30:2c:5c:87:c5:c7:d9:13:5d:75.
          Are you sure you want to continue connecting (yes/no)? yes
          Warning: Permanently added 'somehost' (RSA) to the list of known hosts.
          user@somehost's password: [not shown]
          somehost$


        2. Explanation

          ssh is warning you that it doesn't really know about this host yet. It
          shows you the hostname and IP address, so you can be sure you're talking
          to the correct computer. It also shows the fingerprint of the server's
          public key. If you know what the fingerprint should be, you can check it
          and disallow it if it doesn't match.

        3. Reasonable paranoia

          Most of the time, it's pretty safe to just accept host keys. At least
          within a controlled environment such as UMBC, it's unlikely that someone
          could compromise the network enough to have their computer masquerading
          as, say, one of the gl machines. In other situations, it's up to you to
          decide whether to get key information from the server admin before
          connecting.

        4. Changed host key example

          $ ssh somehost
          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
          @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
          IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
          Someone could be eavesdropping on you right now (man-in-the-middle attack)!
          It is also possible that the RSA host key has just been changed.
          The fingerprint for the RSA key sent by the remote host is
          90:9c:46:ab:03:1d:30:2c:5c:87:c5:c7:d9:13:5d:75.
          Please contact your system administrator.
          Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
          Offending key in /home/user/.ssh/known_hosts:1
          Password authentication is disabled to avoid man-in-the-middle attacks.
          Agent forwarding is disabled to avoid man-in-the-middle attacks.
          X11 forwarding is disabled to avoid man-in-the-middle attacks.
          Permission denied (publickey,password,keyboard-interactive).
          $


    3. User names

      ssh assumes that your username on the remote computer is the same as it is
      locally.

      1. Different username

        $ ssh othername@somehost
        othername@somehost's password: [not shown]
        somehost$


      2. Explanation

        You can specify the username on the command line if it differs from the
        local username. You can also put it in a config file, which comes later.

    4. scp

      ssh also has a program for copying files across the network. It encrypts
      everything, of course, so neither your password nor the data is visible to
      prying eyes. (FTP, the other most common method for copying files, leaves
      both your password and the file visible)

      1. Example

        $ scp localfile somehost:public_html/
        user@somehost's password: [not shown]
        localfile            100% |*****************************|  2048 KB 00:03
        $ scp othername@somehost:public_html/index.html ~/public_html/
        othername@somehost's password: [not shown]
        index.html           100% |*****************************| 10198 KB 00:05
        $


      2. Explanation

        scp works just like cp. It copies files from one place to another. The
        only things it adds is the possibility of some of those places being on
        other computers. The syntax for a remote computer is to put
        'computername:' in front of the file name. (Note that relative paths are
        relative to your home directory.) Like ssh, you can put 'username@'
        before the hostname if your username is different there.

  3. Intermediate SSH

    1. Remote commands

      You don't have to connect to a shell on the remote computer. You can just
      tell ssh to run a command remotely and give you its output.

      1. Example

        $ hostname
        thishost
        $ ssh somehost hostname
        user@somehost's password: [not shown]
        somehost
        $


      2. Programs that use a terminal

        Some programs manipulate the terminal as they run. Usually these are
        interactive programs, like pine or emacs. Normally, ssh will run the
        remote command non-interactively and just spit its output back at you.
        For terminal-using programs, you must tell ssh to use a pseudoterminal
        with the -t option.

        1. Example

          $ ssh -t somehost pine
          user@somehost's password: [not shown]
          [pine opens; user reads mail; user exits]
          $


    2. X11 forwarding

      Graphical programs use the X Window protocol to display on your screen.
      With X, you can run a program on a remote computer have have it display
      locally. Normally, X runs unencrypted over the network. With ssh's -X
      option, you can tell it to use its encrypted connection for X programs.

      1. Example

        $ ssh -X -f somehost xclock
        user@somehost's password: [not shown]
        [xclock appears on screen]
        $


      2. Note on -f

        I also used the -f option here. -f puts ssh in the background after it
        asks for your password. The above command is the remote equivalent of
        'xclock&'.

    3. Config files

      The config file is ~/.ssh/config and can contain lots of stuff. (Note
      that only the local options file is important--ssh reads it before
      connecting to the remote host.)

      1. Host <foo>

        The file is broken up into chunks by Host directives. Everything after a
        Host line applies to that host. (Until the next Host line, of course.)
        The argument after 'Host' is the name that you'd type on the command
        line.

        1. Host *

          There is a special hostname, "*", which represents all hosts. You can use
          this hostname to set default values for settings. (Note that OpenSSH
          gives priority to things that are earlier in the file, so 'Host *' must
          appear last if you want more specific Host settings to override the
          generic ones. (Also note that SSH.com's SSH2 reverses this order;
          'Host * must come first there.))

      2. HostName <name>

        If HostName is specified, ssh will connect to that host instead of the one
        specified on the command line.

        1. Example

          -----
          Host moo
            HostName supercalifragilisticexpialidocious
          -----
          $ host moo
          moo does not exist
          $ host supercalifragilisticexpialidocious
          supercalifragilisticexpialidocious is 192.168.1.2
          $ ssh moo
          user@moo's password: [not shown]
          supercalifragilisticexpialidocious$


      3. User <username>

        When this is present, ssh uses the specified user. This is much easier
        than typing 'user@' on the command line all the time.

      4. Compression <yes or no>

        Setting 'Compression yes' turns on data compression, which helps with slow
        links.

      5. Lots of others

        There's a lot of stuff you can set in the config file. Check the man page
        or SSH book for other things.

  4. Advanced SSH

    1. RSA authentication

      ssh can use a number of methods to authenticate you to the remote host.
      Passwords are the default, since they're the most common. A more flexible
      approach is to use RSA keys.

      These work in much the same way that ssh uses the server's host key to
      verify the remote computer's identity.

      1. Versions

        The programs and file locations here will work in SSH.com's SSH1 and
        OpenSSH. They are different in SSH2.

      2. Advantages

        1. Can't be compromised remotely

          The server never sees your private key, so even if it's compromised the
          attacker can't steal your password for other hosts.

        2. Can use an agent to hold the key

          If you have a local ssh-agent with your key loaded, ssh will use it
          instead of asking you for a password every time. This is quite convenient
          while still pretty secure.

          (Agents will be covered next.)

        3. Can restrict keys to executing specific commands

          If you add 'command="<program>" ' to the beginning of the key's line in
          ~/.ssh/authorized_keys, anyone authenticating with that key will have
          <program> automatically run. They will not get a shell or any other
          program.

          Check the man page or SSH book for more info.

      3. Creating a key

        Use ssh-keygen. I recommend the '-t rsa' option, which creates an RSA key
        for use with version 2 of the SSH protocol. (You can use '-t rsa1' for a
        version 1 key and '-t dsa' for a DSA key, which may not be supported
        everywhere.)

        Note that with SSH1 there is no -t option, because there's only one type
        of key.

        1. Running ssh-keygen

          $ ssh-keygen -t rsa
          Generating public/private rsa key pair.
          Enter file in which to save the key (/home/user/.ssh/id_rsa): [press enter for default]
          Enter passphrase (empty for no passphrase): [not shown]
          Enter same passphrase again: [not shown]
          Your identification has been saved in /home/user/.ssh/id_rsa.
          Your public key has been saved in /home/user/.ssh/id_rsa.pub.
          The key fingerprint is:
          44:c8:07:c9:f8:f4:f5:9b:05:d1:0f:d1:05:f0:5d:bf user@localhost
          $


      4. Allowing login via that key

        On the remote host, add the line in /home/user/.ssh/id_rsa.pub to
        ~/.ssh/authorized_keys.

        1. Quick approach

          $ scp ~/.ssh/id_rsa.pub somehost:.
          user@somehost's password: [not shown]
          id_rsa.pub           100% |*****************************|   225 00:00
          $ ssh somehost
          user@somehost's password: [not shown]
          somehost$ cat id_rsa.pub >> ~/.ssh/authorized_keys
          somehost$ rm id_rsa.pub
          somehost$ exit
          $ ssh somehost
          Enter passphrase for key '/home/user/.ssh/id_rsa': [not shown]
          somehost$


      5. Done

        You can now log in to the remote host using your RSA key.

    2. ssh-agent

      An ssh-agent is a program that keeps a copy of your key in memory for ssh
      programs to use. (Normally, you have to type the passphrase for the key
      every time its needed.) It makes ssh as easy as this:

      $ ssh somehost
      somehost$


      1. Security concerns

        The agent is pretty good about security. It never even divulges your
        key--ssh programs hand data to it and it does the needed work with the key
        itself. However, there are some possible problems.

        1. Unattended use of the agent

          If you walk away from your computer, someone can sit down at it and ssh
          places as you. Solution: remove the key from the agent when you're going
          to be gone from your computer. (And/or just lock the screen.)

        2. Tricking the agent

          If someone else on the computer can act as you (root can do this), they
          can give data to the agent and have it processed as if you asked.
          Solution: don't run an agent on a computer where you don't trust the
          admin.

        3. Stealing the key

          Someone with access to the computer's memory (usually, this is only root)
          can search through the agent's data and get an unencrypted copy of the
          key. Solution: again, don't run an agent on a computer where you don't
          trust the admin.

      2. Starting the agent

        The procedure for running the agent differes slightly depending on whether
        you're running a Bourne Shell derivative such as bash, ksh, or zsh (this
        is probably the case) or a C-Shell derivative such as csh or tcsh (this is
        less likely).

        1. Bourne Shell

          $ eval `ssh-agent -s`
          $


        2. C-Shell

          > eval `ssh-agent -c`
          >


      3. Adding and removing keys

        Key management with an agent is done via the ssh-add program.

        1. Adding keys

          $ ssh-add ~/.ssh/id_rsa
          Enter passphrase for /home/user/.ssh/id_rsa: [not shown]
          Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)
          $


        2. Listing

          $ ssh-add -l
          1024 75:a4:2c:9b:b1:58:8f:9c:96:d8:99:77:fc:01:0d:8a /home/user/.ssh/id_rsa (RSA)
          $


        3. Removing keys

          $ ssh-add -d ~/.ssh/id_rsa
          Identity removed: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa.pub)
          $


      4. Using the agent

        Once the keys are loaded, the agent is used automatically.

        $ ssh somehost
        somehost$


      5. Note on multiple shells

        The agent's setup is only designed to work with a single shell. All you
        really need to do to have multiple shells (e.g. multiple xterms, etc.) use
        the same agent is to copy the value of the environment variable
        $SSH_AUTH_SOCK from one to the other.

        $ echo $SSH_AUTH_SOCK
        /tmp/ssh-XXLN11Tv/agent.953
        [In another shell on the came computer:]
        $ export SSH_AUTH_SOCK=/tmp/ssh-XXLN11Tv/agent.953
        $


        (Note that in C-Shell derivatives, the command is
        'setenv SSH_AUTH_SOCK ').

        1. keychain

          I use a program called 'keychain' to manage multiple shells with the same
          ssh agent. You can install it and read the documentation for more info,
          but basically, all you need to do is run 'keychain ~/.ssh/id_rsa' in your
          of your shell's startup files, and it will check for an existing agent,
          connect to it if it exists, and create a new one (loading the supplied
          key) if it doesn't.

      6. Exiting the agent

        From the shell where you started it, run 'eval `ssh-agent -k`' and the
        running agent will be shut down. If you copied $SSH_AUTH_SOCK to other
        shells, those variables will have to be unset by hand.

    3. Port forwarding

      The ssh program can also be told to listen on arbitrary ports eith on the
      local or remote computer, forward any data through the encrypted
      connection, and send it to some other destination from the other end.

      1. More concrete example

        1. Scenario

          I have a web proxy on a remote computer. I want my local browser to use
          an encrypted connection to that computer to use the proxy.
          So, ssh will listen for connections locally, forward the data across the
          encrypted connection and send it to the proxy on the remote computer. My
          web browser will be told to use a port on the local browser as its proxy.

        2. Numbers

          The remote computer is somehost. The local computer is localhost. The
          proxy is listening on port 5865 on the remote host. I'll have ssh use
          port 5001 on the local host.

        3. Commands

          $ ssh -L 5001:somehost:5865 somehost
          user@somehost's password: [not shown]
          somehost$


        4. Explanation

          The -L option tells ssh to listen on the local host and forward to the
          remote host. (Use the -R option for the reverse situation.)
          The first number is the port to listen on at the local computer. In this
          case, it's 5001.

          The second value is the computer to which the data should go after it
          comes out of the encrypted connection. (Since this example has the data
          going to the same computer as the connection goes to, I could have used
          the special name 'localhost', but avoided that, as it would confuse
          things.) Yes, the computer specified can be any computer on the network.
          The last number is the port that the data will be sent to on the
          destination computer. In this example, that port is 5865, where the web
          proxy is listening.

          I would then set my browser to use 'localhost:5001' as its HTTP proxy.
          The tunnel remains open for as long as you're conencted via ssh.

      2. Listening non-locally

        Normally, OpenSSH will only accept connection from the computer on which
        it's listening. If you want other computers on the network to use the
        encrypted tunnel, you must also use the -g option to ssh.

      3. Tunnel without a terminal

        OpenSSH has a -N option that can be used to just create an encrypted
        tunnel without opening a shell on the remote computer. The tunnel remains
        open until the client ssh is killed.


Phil! Gold