Accessing Linux Systems using SSH

This article show examples of advanced SSH techniques 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, or WSL (from powershell, run WSL --install to gain access to a Linux subsystem).

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.  However, forwarding graphics is slow and network intensive.  I recommend, especially for a browser, just using the remote system as a proxy.
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, Remote Desktop, Anydesk or a similar program. Again, great if you have a lot of bandwidth, not so great otherwise.
Access to remote systems is always easier if you are using ssh keys. On your local system, create a key: 
 ssh-keygen -t ed25519
Note: default is to create an RSA 1024-bit key (on more recent clients, this is now 2048 bit, but see below, the recommended minimum size is 3072), but -t overrides that. If you need to use an RSA key, make it larger than 1024 bits: 
ssh-keygen -t rsa -b 4096 (note: key sizes should be one of 2048, 3072, or 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 jump through example to use foo as a proxy. (Note: ensure your key is first copied to example.rice.edu.) In your ~/.ssh/config file on your local system put:
---- begin ~/.ssh/config file ---
Host rice
Hostname example.rice.edu
User <your netid on example>
Host foo.rice.edu
ProxyCommand ssh rice -X -W %h:%p 10.8.0.21 22
User <your netid on foo>
----- end ~/.ssh/config file -----
With this saved, you can now run: 

ssh foo.rice.edu

(note: you may want to run `ssh-copy-id -i ~/.ssh/id_ed25519 foo.rice.edu` on your first connection) 
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 use -J on the command line in place of using a ProxyCommand in your .ssh/config file:
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.rice.edu, not from example.rice.edu.  Ensure you have a host entry for bar.rice.edu in your /etc/hosts file on foo.rice.edu:
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 via foo.
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 not in DNS (Rice DNS is split tunnel, so resolves private sites on Rice).  



Keywords:
Linux, SSH, access, ssh-keygen, ssh-copy-id, socks proxy, proxy-server, 
Doc ID:
99794
Owned by:
David B. in Rice U
Created:
2020-03-31
Updated:
2025-08-07
Sites:
Rice University