# Internet Technologies/SSH

SSH is a secure replacement for Telnet and rsh. All communications between the client and server are encrypted. To access an SSH client (usually OpenSSH) in most Unix OSs, type ssh user@host.com in a terminal window. If you don't specify the username, the user that entered the command ($USER) will be used. In Windows, you will need to download a 3rd-party utility such as PuTTY or Cygwin. Find more information in the ssh(1) man page. On other Operating Systems (smart phones for example), you will have to use a webbased client. There are several SSH apps for Android, including ConnectBot, Dropbear, ServerAssistant, and the Telnet / SSH Simple Client.

## Uses

SSH is actually so much more than just a way to access a remote shell securely. It can be used for lots of other ways to transfer information securely.

### Using SSH

The secure shell client is conveniently called ssh. It is typically used to access a remote host. A typical usage of ssh is
    ssh user@host
This means that the client intends to login as user on host machine. On successful authentication, an SSH session is established between the client and the host.
Rsync and SFTP are the two recommended ways to transfer files, since there are unfixable flaws with SCP.

### Using SFTP

SFTP has nothing to do with FTP. SFTP merely works like FTP, meaning you use it as you would FTP. Using SFTP requires only the SSH server. The FTP server is irrelevant to SFTP. Files are transferred as binary by default.
    sftp user@host

### Using Rsync

"rsync" is not part of the SSH suite but is nearly ubqiquitous. It uses SSH to secure connections when transferring to or from a remote system.
    rsync file user@host:/path/
or
    rsync user@host:/path/file .
One of the best parts of "rsync" is that it only transfers any changes, if an earlier version the file is on the destination. That saves on time and bandwidth. There are a lot of useful options for "rsync" including the -a option which combines recursive copying with preserved times, attributes, owner, and group, among others.

### Using SCP

The SSH suite still includes a neat utility "scp", which stands for secure copy, which has a great way to copy files between machines. In recent version it is a wrapper for SFTP but it works almost exactly like the default unix cp command. scp also allows you to copy a file from a remote host to a remote host. An example of scp:
scp user@host.com:~/files/ . which means copy files from files/ directory in user's home directory on the host.com machine (it will copy ALL files from the files/ directory) to the CWD (current working directory).
Another great use is to use it to encrypt the transport of any data from one machine to another. As an extreme example, you can use SSH to remotely move a disk from one machine to another (akin to ghost, but securely). This may not be the best use of SSH, or the fastest way to transfer data from one machine to another over a network, but it shows you how powerful SSH can be.
scp, aka Secure Copy, works just like rcp.
* Copy to a remote host - You must use the colon. REMOTE_PATH is not necessary and all REMOTE_PATHs are relative to the user's home directory.
    scp FILE_PATH user@host:REMOTE_PATH
* Copy from a remote host ,
    scp user@host:REMOTE_PATH LOCAL_PATH
Note : If your filename contains spaces then, use scp like this:-
* file name is /media/sda6/Tutorials/Linux Unix/linux_book.pdf then destination directory is home/narendra/data
** $scp user@host:"/media/sda6/Tutorials/Linux\\ Unix/linux_book.pdf" /home/narendra/data
* file name is /home/narendra/linux_book.pdf then destination directory is /media/Tutorials/Linux Unix/
** $ scp /home/narendra/linux_book.pdf user@host:"/media/Tutorials/Linux\\ Unix/"
Note : If you want to copy the whole directory then use
* scp -r user@host:"<syntaxhighlight_dirname>" <destination_dirname>

### Creating SSH Keys

Although SSH can be used with passwords, doing so is not recommended, and many servers will not allow password logins. Instead, use a key - this is more secure, and more convenient.
To create an SSH key ,
Most modern Unix systems include the OpenSSH client. To generate a key, run:
This will store your private key in $HOME/.ssh/id_rsa, and your public key in $HOME/.ssh/id_rsa.pub. You can use different filenames, but these are the default filenames, so it's easiest to not change them.

#### Permissions

Because the security of your private key is so important, SSH will not work if file permissions are insecure. SSH will create files and directories with the appropriate permissions, but sometimes things will go wrong. To fix permission issues:

### Establish Trust

To log into a remote server using SSH keys, you'll need to put the public key on that server's list of authorized keys.
In other words, you need to append a copy of your local ~/.ssh/id_rsa.pub file to the end of the remote ~/.ssh/authorized_keys file.

#### Transfer Method A: ssh-copy-id

The easiest way to do that is using ssh-copy-id. This requires some alternate form of authentication, usually password (since you haven't got a key on the server you cannot use key authentication yet).
    ssh-copy-id -i ~/.ssh/KEY user@host.example.net

#### Transfer Method B: Step-by-step

The hard way to do that is to manually do each step that the above ssh-copy-id command does automatically for you:
* First create the remote ~/.ssh folder on the destination server, if it does not already exist:
    ssh user@host "mkdir ~/.ssh && chmod 700 ~/.ssh"
* Next upload your PUBLIC key only (not your private key).
    cd ~/.ssh
    sftp user@host.example.net:.ssh
    put KEY.pub
* Then append your PUBLIC key to the server's list of authorized keys:
    ssh user@host.example.net
    cat ~/.ssh/KEY.pub >> ~/.ssh/authorized_keys
    rm ~/.ssh/KEY.pub
Advanced *nix users could do all those steps in one line:
    cat ~/.ssh/id_rsa.pub | ssh user@host.example.net "cat >> ~/.ssh/authorized_keys"

### SSH Personal Configuration

You don't need to set up a ~/.ssh/config file, but it makes authentication easier. The important part is to specify your user name and your private key - if this is specified in the config file, you needn't provide it on the command line. Using HostName, you can shorten the ssh command to:

#### Example

You can now ssh into server1.example.com with just ssh Short_Name. The configuration options are chosen on a first-match basis, so put very specific rules torwards the beginning and more general rules towards the end.

### Using an SSH Agent

Most desktop environments provide SSH agents automatically these days. So if you wish to see the details, look for the environment variables $SSH_AUTH_SOCK and $SSH_AGENT_PID, though only the former is used for connecting to it and must be available in to any program which needs to connect to the agent.
Keys can be added to the agent easily manually,
    ssh-add ~/.ssh/KEY
Or they can be added automatically on first use by setting AddKeysToAgent to "yes" in the appropriate rule set in the client configuration file.
However, keep in mind that once you go over six keys in the agent, special considerations have to be taken to keep the agent from trying the wrong keys in the wrong order and preventing logging in. Specifically, IdentitiesOnly should be set to "yes" for each host, ideally using the client configuration file. See below.

## Public-key cryptography

The most significant difference between SSH and Telnet & "rsh" is in the realm of security. SSH uses RSA, EcDSA, or Ed25519 for public-key cryptography.
* The server or domain to which you are trying to connect generates a pair of keys (public and private) for a client.
* The public key is given to the client the first time it tries to connect. The corresponding private key is a secret and kept with the server.
* The client sends the packets of data by encrypting it through the public key and this data is decrypted by using the corresponding private key stored there.
Communication from the server to the client is also possible in the same way — the server encrypts using the client's public key and the client decrypts using it's private key.

## Setting up OpenSSH with public key cryptography

The following presumes physical access to the server or some out-of-band equivalent.
With your distro's package manager, install sshd (or openssh-server) on the server, and on the client install ssh (or openssh-client). It is likely that they're already installed since they're usually part of the distro's default installation for servers and workstations respectively. Be sure the following is in /etc/ssh/sshd_config on the server and uncommented there. That is to say, that there's no # in front of them:
* On the server,
** Open TCP port 22 on the server for incomming connections. This varies depending on your firewall. on-standard port.
** If the server is behind a router with DHCP:
*** Stop using DHCP and assign a static IP address to your server. See the Gentoo Handbook or Arch Linux Wiki for instructions if you do not know how.
*** Forward external TCP port 22 (or another port) on your router to port 22 on your server.
* Over on the client, create and test the a client key pair
** On the client command line, run ssh-keygen -f ~/.ssh/server.key ("rsa" is the default, it is not necessary to explicitly specify "rsa"). Consider annotating the key pair with a comment using the -C option.
** Copy the public key to removable media and transfer that media to the server and mount it. Copy the public key to the server, say to ~/.ssh/server.key there. Then append the key to the authorized_keys file, cat ~/.ssh/server.key >> ~/.ssh/authorized_keys
** Back over on the client, test that the new key works: ssh -i ~/.ssh/server.key serve.example.com
* (Re)start the sshd service.
* Log in again from the client using the key
Tip: If the username that you are logging in as on the server is the same as the one you're currently using on the client, you don't need to specify the user to log in as on the server.

## SSH as a Proxy

If you can make an SSH connection, you can (most likely) use that connection as a SOCKS5 proxy, without any extra setup on the remote computer. Traffic can then be tunneled securely through the SSH connection. If you are on a wireless connection, you can use this to effectively secure all your traffic from snooping. You can also use this to bypass IP restrictions, because you will appear to be connecting from the remote computer. Note that DNS traffic is not tunneled, unless specific provisions are made to do so.
Pick some big port number (bigger than 1024 so you can use it as non-root). Here I choose 1080, the standard SOCKS port. Use the -D option for dynamic port forwarding.
    ssh -D 1080 user@host
That's it. Now as long as the SSH connection is open, your application can use a SOCKS proxy on port 1080 on your own computer (localhost). For example, in Firefox on Linux:
* go to Edit -> Preferences -> Advanced -> Network -> Connection -> Settings...
* check "Manual proxy configuration"
* make sure "Use this proxy server for all protocols" is cleared
* clear "HTTP Proxy", "SSL Proxy", "FTP Proxy", and "Gopher Proxy" fields
* enter "127.0.0.1" for "SOCKS Host", and "1080" (or whatever port you chose) for Port.

## SSH from your webbrowser

You can also use ssh from a webbrowser with javascript support even when you don't have a secure shell client. In order to do this you have to install AnyTerm, AjaxTerm or WebShell on the system where the SSH server is running or use a third party service like WebSSH.

## SSH reverse tunneling

With reverse tunneling you can use a remote machine (for example on AWS) as an entry point to your local machine. Thus a request to that specific port on the remote machine IP will be forwarded to your local machine with a response returned. It is called reverse tunneling because this is not your local machine sending data to the remote one one that port, but instead from the remote to the local.
Use case: if your computer is behind NAT - without a public IP address (or not a local static IP address) - but you still want to make your local HTTP server or some database or other specific service be available to the public.
Another use case: if torrent seeding because with a public IP more computers will be able to fetch your legal data.
Such a command can setup a reverse tunnel where port 63368 on the remote machine is forwarded back through the SSH reverse tunnel to port 8000 on the originating machine, via SSH connecting on port 4160:
The format is:
ssh -R port-incoming:localhost:port-local -p port-for-for-connecting host.example.net
The remote machine's /etc/ssh/sshd_config can include the following:

## Further reading

* The Wikibook on OpenSSH
* https://man.openbsd.org/ssh, https://man.openbsd.org/ssh_config
* LPI Linux Certification/Secure Shell (SSH)
* Building a Beowulf Cluster/Installation, Configuration, and Administration/Shared directories and SSH
* "Mediawiki: Set Up SSH Keys in Gerrit" has a step-by-step tutorial on setting up SSH keys.
* ArchWiki: OpenSSH
* Gentoo Handbook: SSH
* SSH reverse tunneling: getting a static IP from a cloud
* "Github: Generating SSH Keys" has yet another step-by-step tutorial on setting up SSH keys.
* "How to Set Up SSH Keys on Ubuntu 20.04" has a similar step-by-step tutorial on setting up SSH keys.
* "Ubuntu: SSH/OpenSSH/Keys" has a similar step-by-step tutorial on setting up SSH keys.
* "Configuring Git over SSH to login once" describes how to use ssh-agent (on MacOS and Linux systems) to unlock a password-protected private key once per session, rather than every push or pull that uses the key.