layout: post
title:  Different uses of ssh
category: Projects
description: Different uses of ssh
---

# Different Uses of `ssh`

I typically use ssh for logging into a remote machine and executing command on that machine. As it turns out, it is possible to do much more than that. In this document, we shall look at some of the cool features that come with `ssh` for free. It is something that I hadn't ever used it. But nevertheless are very useful and practical commands on their own.

We shall look at three things specifically.

 - Run a remote command without logging into a system
 - Generate a local keychain
     -  And login to a remote shell without a password
 - Create `ssh` tunnel that allows you to *tunnel* commands and results through

Used in combination they can result in very nifty process flows. So lets start ...

## 1. Run a remote command locally

For this, you dont need anything fancy.  Let us say that your local username is `local` and your local machine is `LOCAL`. Typically, you would refer to this as `local@LCOAL`. Your command prompt will look like some variant of this:

```bash
╭─local@LCOAL /Users/local  
╰─$ 
```

What you see above is a fish-shell. A bash shell will look similar

Suppose furthermore, you wish to log into a remote shell with username `a` and hostname `A`. What would you do? Something like the following:

```bash
╭─local@LCOAL /Users/local  
╰─$ ssh a@A
password:
[ a@A ]    ~
$
```

So far so good. However, we want to do something trivial. Like check the status of a log file that is being generated by a program running overnight. It turns out that if you specify a command *immediately after* the `ssh` command, you will not be logged in, the command will just be executed in the remote machine. Something like this ...

```bash
╭─local@LCOAL /Users/local  
╰─$ ssh a@A ls -l
password:
total 1659812
drwxr-xr-x  3 a a         54 Jul  5 09:42 data
drwxr-xr-x 11 a a       4096 Jun 13 11:27 docs
drwxr-xr-x 17 a a       4096 Jun 14 15:42 programs
-rw-r--r--  1 a a       5451 Aug 18  2016 temp.txt
```

pretty awesome! Now you see the pesky problem. Every time you run a remote command, you need to enter a password. Not a cool thing if you are running remote commands all the time (and sometimes when you are running commands through a script). Lets deal with that next. 

## 2. Create a keychain for remote logins

If you use a mac, you will love this tiny application called Keychain Access. It collects all your passwords from all your applications into one neat program. Forgot your password to one of the sites that you visit? Just use Keychain Access to find out. 

![keychain](img/kch.png) 

Would it not be nice to have such a service for your `ssh`? I am glad you asked! For doing this, you would use what is called an authentication token. I like to think in terms of pictures. So I'll draw a picture for you. Suppose you have \\(N\\) machines you want to log into: [ `a@A`, `b@B`, ... `n@N`]. Remember that in each machine, you are logging in a different user, and thus you possibly have \\(N\\) different passwords.

You create 2 files within your `~/.ssh/` folder:

 - `~/.ssh/id_rsa.pub`, and 
 - `~/.ssh/id_rsa`

You can do that by the following command: `ssh-keygen -t rsa`, like so: (**remember to leave the passphrase blank**)

```bash
╭─local@LCOAL /Users/local  
╰─$ ssh a@A ls -l
local@LOCAL:~> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/local/.ssh/id_rsa): 
Created directory '/home/local/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/local/.ssh/id_rsa.
Your public key has been saved in /home/local/.ssh/id_rsa.pub.
The key fingerprint is:
3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 local@LOCAL
```

Now, you will need to transfer the *public file*  `~/.ssh/id_rsa.pub` to the other computers that you want to log into. Specifically, you want to paste the contents of this file at the end of the following document in remote computer: `a@A:~/.ssh/authorized_keys`. It will look like this:

![local to remote](img/locRem.png)

Of course there are different ways of passing this file to your remote server. You can e-mail the text. You can copy-paste it. However, remember the first section where you could just run remote commands locally? Well using that:

```bash
╭─local@LCOAL /Users/local  
╰─$ cat ~/.ssh/id_rsa.pub | ssh a@A 'cat >> .ssh/authorized_keys'
password: 
```

Congratulations! Now you have added your public key to the remote machine. Go ahead and do the same for all the other machines. Now try running a remote command:

```bash
╭─local@LCOAL /Users/local  
╰─$ ssh a@A tail temp.txt
 trial of sl  dose reduction
 unhelpful.
 Unknown Reason DCd on hosp discharge
 VPA level 103
 wanted generic
 want reg. release
 wean off--lack of efficacy
 weight gain and worsening of psoriasis.
 We will be changing it to Cymbalta.
 will be comparing to Metadate CD
╭─local@LCOAL /Users/local  
╰─$ 
```

No more passwords! Nice. 

## Generate an ssh tunnel

`ssh` relies in port 22. Would it not be nice if you could run other remote commands that use other ports in the same secure way? Say for example, you access a Postgres instance on a GUI-less server. However, you wish to use your favorite GUI for exploring your database. Postgres provides its services typically on port 5432. You can open up a secure `ssh` tunnel on that port: 

```bash
╭─local@LCOAL /Users/local  
╰─$ ssh -L 5432:localhost:5432 a@A
```

Now fire up your favorite Postgres GUI, and use localhost for your host, and you are good to go! You want to run an iPython Notebook on a server and access it through a local machine? No problem. Forward port 8888. 

## Conclusion

`ssh` in Trump's words is *euuuuuge*!. Check out the man page. If you don't like reading manuals, check out the following video. https://vimeo.com/54505525 for all the cool thing that it can do.

## Credits

1. http://www.linuxproblem.org/art_9.html
