Accessing Linux Systems using SSH
This article show examples of advanced techniques of SSH to access other Linux systems.
If you are new to Linux and use SSH in only the most obvious ways (to get a terminal into a remote system), this document is meant to share some of the more powerful ways SSH can be used. This document assumes you are accessing a Linux system from a Linux system. With some adjustments (installation of an X11 system) these will also work on a Mac. Windows will require a Unix-like environment, such as Cygwin, but your results may vary.
Application/port forwarding
Most servers will allow SSH forwarding, but not by default. If you want to run a graphical application on a remote server and display it locally, you can do this by including either the -X or -Y options. The -X option provides an insecure forward, and the -Y a "secure" forward of the X protocol. To ensure the remote system supports it, you can log in with either of these options and run: `echo $DISPLAY` to see if you have a forwarded graphical display. If you get no return, the remote system does not support X11 forwarding.
The -X or -Y options only allow one application to be forwarded to your terminal, not the entire desktop. To forward the desktop, you will need VNC, NoMachine, TeamViewer, or a similar program.
Access to remote systems is always easier if you are using keys. On your local system, create a key:
ssh-keygen -t ed25519
Note: default is to create an RSA 1024-bit key, but -t overrides that. If you need to use an RSA key, make it larger than 1024 bits:
ssh-keygen -t rsa -b 4096
Copy your key to another system
To copy the key to a remote system (you need password access as the user on the remote system):
ssh-copy-id -i ~/.ssh/id_ed25519 <netid>@remote.system.com
Once copied, you will be prompted to perform a test login.
System jumping
If you need to access systems on the private network, you can do so, but will need access to a system with a public IP. Let's say you have an account on example.rice.edu which has a public IP, but you need to access a system on the 10.0.0.0/8 (private) network. Let's say foo.rice.edu has an address of 10.8.0.21. To get to this system, you can either ssh into example then ssh into foo, or you can use example as a proxy. (Note: ensure your key is first copied to the example.) In your ~/.ssh/config file on your local system put:
Host rice
Hostname example.rice.edu
User <your netid on example>
Host foo.rice.edu
ProxyCommand ssh -q rice nc -q0 10.8.0.21 22
With this saved, you can now run:
ssh-copy-id -i ~/.ssh/id_ed25519 foo.rice.edu
and login directly to foo. This will allow you to ssh directly to foo without using a VPN.
On more recent versions of openssh, you can -J in place of the ProxyCommand:
ssh -J user@jump.host user@destination.host
Connecting to a port on another host:
Now, let's say we have another private system, bar.rice.edu, that is on the private network that runs PostgreSQL. However, we can only access Postgres from foo, not from an example. Ensure you have a host entry for the bar in your /etc/hosts file:
10.8.0.25 bar.rice.edu bar
Postgres runs on port 5432 by default. To connect to port 5432 on the bar, we need to come through foo. We want to use port 1234 on our localhost to connect. So we run the following command:
ssh -L 1234:bar.rice.edu:5432 <netid>@foo.rice.edu
The above will log us into foo.rice.edu and create an ssh tunnel from our localhost to bar.rice.edu on port 5432. Open another terminal, and we should be able to connect:
psql -p 1234 localhost <tablename>
The local postgres client will connect through localhost on port 1234 and connect to bar.rice.edu on port 5432.
This can be used for any protocol: ssh -L 8888:something.rice.edu:443 <netid>@example.rice.edu will allow you to open your web browser and point it to https://localhost:8888/ and connect to something.rice.edu on port 443.
However, you would have to do this for every site you wanted to connect to. It also has the shortcoming that any site that uses absolute vice relative redirects, or redirects to a different site for authentication, etc., won't work.
Using SSH as a socks proxy:
ssh -D 8765 <netid>@foo.rice.edu
open another terminal and enter:
google-chrome --proxy-server="socks5://127.0.0.1:8765"
We had to start Google Chrome from the command line because, on Linux, google chrome does not have an HTTP proxy setting.
Now all your Google Chrome connections will go through foo.rice.edu and you can access any private site that foo.rice.edu can get to. Remember, you'll need host entries for any private sites.
QC-NESB