ssh
Introduction
SSH is probably the most used tool that most developers need.
SSH means secure shell. It's a cryptographic network protocol for operating network services.
It's used everywhere, here is a list of things it's capable of
- Remote control a computer with command line
- SSH tunnel to forward ports from remote server to
localhost
or vice versa- Gives user secure connection over unsecure network
- Forward UI with X11
- e.g. display a GUI linux app on Mac or Windows.
Search for ssh on this website, I have plenty of notes about SSH on all sorts of weird topics
TL;DR
ssh <username>@<server> # most basic
# or
ssh -l <username> <server> # -l for username
# then enter password to login
Key-Based Password-less Authentication
# on local computer
ssh-keygen # keep pressing enter
# id_rsa and id_rsa.pub are generated in ~/.ssh
# ssh-keygen -t ed25519 uses another algorithem, it's better
# id_ed25519 and id_ed25519.pub are generated instead
cat ~/.ssh/id_rsa.pub # to get the content of public key, copy it to clipboard
# ========================================================================
# Mac and Linux ships with ssh-copy-id
# ========================================================================
ssh-copy-id -i ~/.ssh/id_rsa <username>@<server>
# ========================================================================
# Or you can do it manually if you don't have ssh-copy-ip (e.g. on windows)
# ========================================================================
ssh <username>@<server> # login to server
mkdir ~/.ssh
echo <paste public key here> >> authorized_keys
# Ctrl + D to quit ssh session
ssh <username>@<server> # ssh again, no password required
Identity File
ssh <username>@<server> -i ~/.ssh/id_rsa
# or
ssh <username>@<server> -i ~/.ssh/id_ed25519
# or any custom identity file name
SSH Config
Mac or Linux: ~/.ssh/config
Windows: C:\Users\<username>\.ssh\config
Append the remote server config
Host custom_name
HostName <server domain or IP>
User my_username
IdentityFile ~/.ssh/id_ed25519
Then
ssh custom_name
to connect (no password required).
X11 Forward
ssh -X <username>@<server> # untrusted
ssh -Y <username>@<server> # trusted
SSH Tunnel
It's a tunnel for network traffic between 2 computers.
It's too complicated to explain without examples. See SSH Tunnel.
Remote Forward
ssh -R <remote port>:localhost:<localhost port> <REMOTE_USER>@<REMOTE_HOST>
Local Forward
ssh -L <remote port>:localhost:<localhost port> <REMOTE_USER>@<REMOTE_HOST>
Remote Connection
The most common use case of ssh
is remote connection. It allows you to remotely connect a computer using command line. The computer can have any operating system (Mac, Linux or Windows), as long as it has a openssh-server running.
Basic Usage
Mac, Linux and Windows (powershell) should all come with ssh client, no need to install.
ssh <username>@<host> # most basic connection to control a computer
# then enter password
The host can be a domain (e.g. server.huakun.tech), or an IP address (i.e. 192.168.1.10).
Passwordless Login
Login without password can be achieved with key-based authentication. Instead of using password, we use ssh key to login.
This method is also used for git cloning with ssh key. (git urls starts with [email protected]/...
).
Read more at ssh-keygen and GitHub SSH.
ssh-keygen -t ed25519 # then press enter multiple times until a key is created
# don't enter password if you want password-less auth
2 files are generated in ~/.ssh
folder. id_ed25519
and id_ed25519.pub
.
The one with .pub
extension is a public key.
The overall idea is, add the public key to remote server (which you want to authenticate to), then use private key to authenticate. This is called Asymmetric Encryption. I will talk about this in another note. (TODO).
The public key can be exposed, but the private key must be kept private. Whoever with your private key can access the resource you can access without password.
Now you want to transfer the public key to remote server.
cat ~/.ssh/id_ed25519.pub # then copy the content
ssh <username>@<host> # ssh into the server with password
cd $HOME # cd into home directory if you are not in it
mkdir .ssh # make .ssh directory (by default it's doesn't exist)
echo '<the public key>' >> authorized_keys # append your public key to a file
authorized_keys
is the key point. You can have multiple public key in this file (each on a new line). Each key represents a computer that can access the target.
If the remote server is a Windows machine and the remote user is an administrator, .ssh/authorized_keys
may not work. Instead, use C:\ProgramData\ssh\administrators_authorized_keys
.
See https://superuser.com/questions/1342411/setting-ssh-keys-on-windows-10-openssh-server
Use >>
to append to the file. Don't use >
which could accidentally overwrite an existing authorized_keys
file.
It's also fine to edit the file using editors like vim
or nano
.
Then log out of the server and try again, you should not need to enter password.
Note
ssh-copy-id
is a command for automating the public key uploading process.- Password Login can be completely disabled (use key auth only) for better security
sudo vi /etc/ssh/sshd_config
- Set
PasswordAuthentication no
https://www.ssh.com/academy/ssh/copy-id
Identity File
The ssh keys are also called identity files, which can be used to identify an authorized client. You can have multiple identity file (ssh keys) in ~/.ssh
, or any folder, with custom names.
Then during ssh, your ssh client could use the wrong ssh key. Use -i
to specify the identity file you want to use.
ssh -i ~/.ssh/custom_key <username>@<host>
Note that the identity file used should be the private key (not the one with .pub
).
ssh config file
It's possible to make things even simpler using a config file.
Example: ssh server_name
. Without username, ip address or identity file.
Edit ~/.ssh/config
with any editor. On windows, it's C:\Users\<username>\.ssh\config
.
Host any_name
HostName server.huakun.tech
User my_username
IdentityFile ~/.ssh/id_ed25519
This is a simple sample config.
Then you can ssh any_name
to ssh to the server, without needing to enter password or username or anything.
More Advanced Discussion
There are more options, like ProxyCommand
allows you to use socks 5 VPN proxy, for VPNs that are not running in Network layer or Data Link Layer (layer 3 and 2 in OSI model). This will be discussed in another note (TODO) where I will discuss networks and VPN in more details.
Basically, VPNs that operate in higher layers (e.g. Shadowsocks runs in layer 5, session layer) can only proxy traffic for higher-layer traffic like HTTP which runs in Application Layer (layer 7).
OpenVPN operates in Layer 3 (Network Layer) by default, and can be configured to operate on Layer 2 (Data Link Layer), and can automatically route ssh traffic.
SSH operates in layer 4 - 7 (transport to appliaction layer). VPNs in lower layers can proxy SSH traffic. [SSH Wikipedia]
Read more at Some basic networking concepts simplified (Search for 'layer').
Don't worry about the OSI and VPN related stuff for now, those are more advanced topics.
Read more at Linuxize: ssh config file.
SSH Tunnel
Port binding/forwarding between 2 computers.
See SSH Tunnel Notes.
SSH X11 Forward
Allows you Forward UI from remote to local computer.
See SSH X11 Forward.
Reference
- Ubuntu: Service OpenSSH
- My Video Talking about ssh and port forwarding with raspberry pi
- The videos talks about raspberry pi, but a pi is just like any regular computer. The process is exactly the same.
- Known Host Issue
- SSH with VSCode (fix permission)
- ssh-keygen
- GitHub SSH
- Linuxize: ssh config file
- GFW, a Technical Analysis (osi layer 5)
- Some basic networking concepts simplified (Search for 'layer')
- SSH Wikipedia
- The Art of SSH
- SSH Tunneling