--- title: 'SSH Quick Start Guide' description: 'The fastest way to get all the SSH essentials out of the way' pubDate: 'December 26 2023' heroImage: '/blog-placeholder-3.jpg' --- # SSH SSH is the standard way to control a computer remotely. It lets us login and use the system, despite not being right in front of it. In fact, many people can log into the same computer and use it at the same time, though only at most 1 user can use it directly. It's absolutely essential to know for any software developer and CS researcher. It's also just really cool! ![silly akemi](/akemi_silly_transparent.png) For this course, we will be using the university's lab machines for all assignments and lab demos. They all run Ubuntu 20.04. It's important you compile and test your code on these machines. We will not accept situations where the code runs perfectly on your computer, virtual machine, or really anything else that's not a lab computer. TAs will be able to help you a lot better if you're using the lab machines SSH will allow you to connect to the lab machine and transfer files between the lab machines and your computer ### Setup You'll need a recent-ish version of OpenSSH installed on your computer. On linux/mac you can use `ssh -V` to check your version. If that command fails, or your version is below 8, please install openssh for your system Macs may want to use [brew](https://formulae.brew.sh/formula/openssh), while linux systems should use their package manager ### University Lab Machines To ssh into a computer, we'll need its IP address. Just like with websites, we don't actually need to remember the number, we'll instead use the domain name. Our 34 lab machines numbered 01-34 are all at the domain `cs.ualberta.ca`. Here's a complete list: ``` ug01.cs.ualberta.ca ug02.cs.ualberta.ca ug03.cs.ualberta.ca ug04.cs.ualberta.ca ug05.cs.ualberta.ca ug06.cs.ualberta.ca ug07.cs.ualberta.ca ug08.cs.ualberta.ca ug09.cs.ualberta.ca ug10.cs.ualberta.ca ug11.cs.ualberta.ca ug12.cs.ualberta.ca ug13.cs.ualberta.ca ug14.cs.ualberta.ca ug15.cs.ualberta.ca ug16.cs.ualberta.ca ug17.cs.ualberta.ca ug18.cs.ualberta.ca ug19.cs.ualberta.ca ug20.cs.ualberta.ca ug21.cs.ualberta.ca ug22.cs.ualberta.ca ug23.cs.ualberta.ca ug24.cs.ualberta.ca ug25.cs.ualberta.ca ug26.cs.ualberta.ca ug27.cs.ualberta.ca ug28.cs.ualberta.ca ug29.cs.ualberta.ca ug30.cs.ualberta.ca ug31.cs.ualberta.ca ug32.cs.ualberta.ca ug33.cs.ualberta.ca ug34.cs.ualberta.ca ``` We also have other computers, though these ones are typically set aside for CMPUT201. Usually most people use ug01-ug04, so those computers often get overloaded and laggy. It's in your best interest to use the mid-to-higher numbered ones IST usually reboots these computers about once per month early morning on Wednesday. If you're experiencing issues around that time, it might just be since they're updating the software, so wait an hour before trying to connect again. As a backup, there's `ohaton.cs.ualberta.ca`, which is a much slower computer, though very rarely has any downtime Your files are stored on a separate network-attached storage device, so no matter which computer you login to, all your files will be there ### Connection Demo Let's see how Alice logs into the 33rd lab machine. Her email is `alice@ualberta.ca` so to login to the 33rd lab machine, she'll use the address `alice@ug33.cs.ualberta.ca` Here's what Alice sees when she attempts to connect: ``` $ ssh alice@ug33.cs.ualberta.ca The authenticity of host 'ug33.cs.ualberta.ca (129.128.29.63)' can't be established. ED25519 key fingerprint is SHA256:o3LbTXb16zGX3rGy9Xl1qF9eigRMYLWlsXTG6ACt3L8. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes alice@ug33.cs.ualberta.ca's password: ``` Here's what Alice typed, assuming her password is `password123` ``` ssh alice@ug33.cs.ualberta.ca yes password123 ``` Replace the CCID and password with your own. Make sure you type `yes` when it asks if you want to continue connecting. If everything goes well, you'll be connected to the lab machine. If you want to make sure, type `hostname` and hit enter. It should print `ug33`, or a different number if you logged into one of the other machines. Type `exit` to get back to your own computer # SCP Once we can connect to the lab machine, we may want to transfer files to and from the lab machines. SSH has a tool called `scp`, which stands for **s**sh**c**o**p**y. The syntax is very similar the to `cp` command you should be familiar with from the linux tutorial. As a refresher, if Alice has a file `a.txt` and she wants to duplicate it to a file called `b.txt`, she can use ```bash cp a.txt b.txt ``` Notice how the command is always in the order `cp `. `scp` is almost identical, except it adds the ability to specify which machine we want to copy from/to. By default, it's our own computer, so it'd be identically valid to duplicate `a.txt` using ```bash scp a.txt b.txt ``` This is again a shorthand for typing out a relative path to each file, so Alice could also use ```bash scp ./a.txt ./b.txt ``` Now let's say Alice wants to make a copy of `a.txt` called `b.txt` in the directory `/dev/shm`. All she needs to change in the command above is the path to `b.txt` ```bash scp ./a.txt /dev/shm/b.txt ``` Everything Alice has done so far is possible with `cp` as well. Now what if she instead wants to copy `a.txt` from her laptop to a file called `b.txt` in the directory `/dev/shm` on the lab machine. She'll need to prefix the path of `b.txt` in the command above with the login address of the machine. For example, if Alice chooses to use `ug33`, she'll type: ```bash scp ./a.txt alice@ug33.cs.ualberta.ca:/dev/shm/b.txt ``` Notice Alice put a colon following the login address she typed to SSH into the machine. At this point, SSH will prompt Alice for her password. Once she types that in, her `a.txt` will be copied over the network Alice can also copy files from the lab computer to her own laptop. Below, she copies the `b.txt` file from `/dev/shm` on the lab machine, to her own home directory ```bash scp alice@ug33.cs.ualberta.ca:/dev/shm/b.txt ~/c.txt ``` It's often useful to copy entire directories over to the lab machines instead of just a single file. For this, Alice will add the `-r` flag, which stands for recursive, to her command. Below she copies her entire `Lab1` directory to her `~/Documents` directory on the lab machine. Note that the `~` expands to the home directory's path, which is usually where you'll want to put your files ```bash scp -r Lab1 alice@ug33.cs.ualberta.ca:~/Documents ``` Now Alice has a directory called `~/Documents/Lab1` on her lab machine. **Use caution with scp!** Just like `cp` it will overwrite files irrecoverably without warning. Make sure your destination is right before copying, otherwise you will **erase files**. Making frequent git commits and pushes is the best way to avoid having to start over on a lab or assignment # Advanced SSH We've already covered everything SSH can do, though it may be apparent that having to type `alice@ug33.cs.ualberta.ca` and password every time we use `ssh` or `scp` takes a while. We also don't have a clear way to tell Github we're logging in over SSH Both these problems can be solved using a combination of SSH aliases and keys. This part is not esentail for the course, though it's important in industry and will save you a **LOT** of time this semester ## SSH Aliases It's quite annoying having to type in the long `alice@ug33.cs.ualberta.ca` every time. Instead, SSH provides and aliasing system, where we can using something else First create the file and directory `~/.ssh/config`. On unix (linux or macos), this looks like ```bash mkdir ~/.ssh touch ~/.ssh/config ``` Now use a text editor to write the following into `~/.ssh/config`. Replace `alice` with your own CCID and feel free to use a number other than `33` for the lab machine ```sshconfig Host lab Hostname ug33.cs.ualberta.ca User alice ``` Now Alice will be able to type this alias anywhere she previously used `alice@ug33.cs.ualberta.ca`! From the previous examples, she could now use ```bash ssh lab scp ./a.txt lab:/dev/shm/b.txt scp lab:/dev/shm/b.txt ~/c.txt scp -r Lab1 lab:~/Documents ``` ## SSH keys SSH aliases shorten what we have to type, though currently we're still typing our password every single time. Not only is this considered incredibly insecure, it's also such a waste of time. In real-world usage of SSH, it's usually advised to disable passwords entirely and only rely on cryptographic SSH keys to login IST deals with the security for us, though we can still take advantage of keys to skip the password step entirely. And remember, this is ironically considered **more secure** than using password-based logins! ### Making a key pair Generating an SSH key is a bit daunting for the first time, so I'll explain every step. All you need to do is copy/paste every line into a terminal ```bash ssh-keygen -t ed25519 -f ~/.ssh/ualberta_cs_labs -N '' ``` You should see a long message saying something about a fingerprint and printing an art piece at the end. If instead it says something about an error, please ask one of the TAs for assistance The line above created a private and public cryptographic key pair. As the name suggests, the public key is the one you can give out and the private key is the one you should never share with anyone. If someone else obtains your private key, they'll be able to login everywhere that key can access (your lab machine files and github if you finish this tutorial) Keys are nothing more than files. In fact you can go ahead and open them in your text editor. The keys are at ``` ~/.ssh/ualberta_cs_labs ~/.ssh/ualberta_cs_labs.pub ``` Where the `.pub` is the much shorter public key and the one without `.pub` is the private key. My public key looks like: ``` ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHYJVpQTIGoNSqxK7Gp9m3O4qYLR9x7+jbkcjqTBl63W akemi@Akemis-Waybook ``` While the private key will look similar to: ``` -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACB2CVaUEyBqDUqsSuxqfZtzuKmC0fce/o25HI6kwZet1gAAAKBBpTVkQaU1 ZAAAAAtzc2gtZWQyNTUxOQAAACB2CVaUEyBqDUqsSuxqfZtzuKmC0fce/o25HI6kwZet1g AAAEDBEgSLMzFVcf490TC+Cz5cbeVzWwkhGXCX7LZAqy3G5XYJVpQTIGoNSqxK7Gp9m3O4 qYLR9x7+jbkcjqTBl63WAAAAFmVsYWluYUBFbGFpbmFzLUZlbWJvb2sBAgMEBQYH -----END OPENSSH PRIVATE KEY----- ``` **Never show this private key to anyone!** I generated a spare one above as an example and would never actually share my private key ### Enabling login through the key Alice will now need to let her lab machine know this key is safe to use for authentication. She'll use the following command: ```bash ssh-copy-id -i ~/.ssh/ualberta_cs_labs.pub alice@ug33.cs.ualberta.ca ``` Alternatively, if she already setup the `lab` alias from before, she can use ```bash ssh-copy-id -i ~/.ssh/ualberta_cs_labs.pub lab ``` Either way, she'll be prompted to enter her password one last time Now, she'll once again open `~/.ssh/config` in her favorite text editor and make it look like below. The last two lines are new: ```sshconfig Host lab User alice Hostname ug33.cs.ualberta.ca IdentityFile ~/.ssh/ualberta_cs_labs IdentitiesOnly=yes ``` ### Testing if it works If all went well, now when you use the `lab` alias, you'll automatically be logged in, without any password! Try the following commands: ```bash ssh lab touch a.txt && scp ./a.txt lab:/dev/shm/b.txt ``` If you're still being prompted for a password, retry all the steps from the beginning then ask a TA for help if the issue persists ### Logging into Github Github also supports SSH keys! As before, the advantage is being able to `git push` and `git fetch` without needing to type in a password. ```bash ssh-keygen -t ed25519 -f ~/.ssh/github_main -N '' ``` Alternatively, if you'd like some extra security, you can put a password on the SSH key itself. This'll mean that even if your key gets stolen, it'll still take attackers a while to crack through the password, assuming your password is sufficiently long. The convenience-security trade off here is up to you. Simply use the command below and type in the password you want: ```bash ssh-keygen -t ed25519 -f ~/.ssh/github_main ``` Now login to [Github](https://github.com/login) in your browser. Go into [Settings -> SSH and GPG keys](https://github.com/settings/keys). Click "New SSH Key" in the top right. Give it whichever title you feel is memorable, like "laptop github key" and set key type to be "Authentication Key" Now we'll actually need to open up our public key file and paste it in the text field on Github. Use a text editor to open `~/.ssh/github_main.pub`. Some examples include: ```bash # Manually copy with your mouse cat ~/.ssh/github_main.pub # The following copy directly to your clipboard! Just paste on Github cat ~/.ssh/github_main.pub | pbcopy # On MacOS cat ~/.ssh/github_main.pub | xclip -selection clipboard # On X11-powered Linux cat ~/.ssh/github_main.pub | wl-copy # On Wayland-powered Linux ``` Hit "Add SSH Key". Now we'll need to add a clever alias to our SSH config which will make `git` automatically use this key for Github. Run the following command ```bash cat <> ~/.ssh/config Host github.com Hostname github.com IdentityFile ~/.ssh/github_main SSH ``` Now we can test if everything works with the following command. It should greet you with your Github username if everything worked well ``` ssh -T git@github.com ``` If the above doesn't work, try ``` ssh -i ~/.ssh/github_main -T git@github.com ``` If only the second one works, you'll want to open `~/.ssh/config` in a text editor and make sure it looks like the example below. Otherwise you likely didn't copy/paste the right key on Github The final `~/.ssh/config` file should look like this: ```sshconfig Host lab User alice Hostname ug33.cs.ualberta.ca IdentityFile ~/.ssh/ualberta_cs_labs IdentitiesOnly=yes Host github.com Hostname github.com IdentityFile ~/.ssh/github_main ``` ### Github Over SSH Even when you pass the SSH tests from above, `git push` will likely still be prompting you for a password. In all likelyhood, you're still using HTTPS instead of SSH to connect to Github. Luckily, this part is easy to fix First, navigate to your git directory. Now run the following command ```bash git remote -v ``` This should print something similar to the below. Your Github username and project name will be different of course ``` origin https://github.com/aizuko/noway.moe.git (fetch) origin https://github.com/aizuko/noway.moe.git (push) ``` This means we're currently using the HTTP protocol to communicate with Github. It's the same protocol we use for browsing websites. However we want to use the SSH protocol. What we'll need to change boils down to: 1. From `https:` at the front to `ssh:` 2. Prepend `git@` in front of `github.com` 3. Append `:22` right after `github.com` For the example above, we'd run the following to change it ```bash git remote set-url origin ssh://git@github.com:22/aizuko/noway.moe.git ``` Now when we run `git remote -v` we should see ``` github ssh://git@github.com:22/aizuko/noway.moe.git (fetch) github ssh://git@github.com:22/aizuko/noway.moe.git (push) ``` Try doing a `git fetch` and `git push` now. It should just automatically use the SSH key we previously setup in the `~/.ssh/config` You will need to do this `git remote set-url` for every old repository manually. Next time you're using `git clone` though, clone using the SSH url directly. For example: ```bash git clone 'ssh://git@github.com:22/aizuko/noway.moe.git ``` This will even let you clone private repositories, since it's using your SSH key to authenticate you, no need for passwords and usernames!