As recently as a 2001, it was not uncommon to log in to a remote Unix system using telnet.
Telnet is just above netcat in protocol sophistication, which means that passwords were sent in the clear.
As wifi proliferated, telnet went from security nuissance to security disaster.
As an undergrad, I remember running ethereal (now wireshark) in the school commons area, snagging about a dozen root passwords in an hour.
SSH, which encrypts and authenticates connections, had been in development since 1995, but it seemed to become adopted nearly universally and almost overnight around 2002.
It is worth configuring SSH properly:
per-user configuration is in
system-wide client configuration is in
system-wide daemon configurtion is in
Key-based, passwordless authentication
Key-based passwordless authentication makes it less cumbersome for other programs and scripts to piggyback atop SSH, since you won't have to re-enter your password each time.
Key-based authentication exploits public-key cryptography to prove to the server that the client owns the secret private key without revealing the key.
[If you're curious about public-key cryptography, see my post on a short implementation of RSA.]
To set this up, first log in to the client machine.
Then create a private/public key pair with
$ ssh-keygen -t dsa
This will place the private key in
and the public key in
Guard the private key (set appropriate permissions) as if the private key were your password. In effect, it is.
Now, append the contents of
to the end of
on the remote machine.
$ cat .ssh/id_dsa.pub | ssh host 'cat >> ~/.ssh/authorized_keys'
(On Linux systems, you can use
the technique above is more portable.)
Do not copy your private key over.
Now, when you connect to that account, it won't require a password.
Executing remote commands
To run a command on a remote system without logging in, specify the command after the login information:
$ ssh host command
For example, to check remote disk space:
$ ssh host df
My favorite example for Linux is piping the microphone from one machine to the speakers of another:
$ dd if=/dev/dsp | ssh -C user@host dd of=/dev/dsp
Copying files with ssh
For copying data and files over SSH, there are a few options.
It's possible to copy with the command
If you're trying to copy the output of a process instead of a file, this is certainly
a reasonable route.
If you're going to use SSH like this, disable the escape sequences:
$ cat file | ssh -e none remote-host 'cat > file'
If these are going to be large files, you may want to use the
flag to enable compression.
For copying files, the program
scp works like
except it also accepts remote destinations.
$ scp .bash_profile firstname.lastname@example.org:~/.bash_profile
For an FTP-like interface for
copying files, use the program
Per-host SSH client configuration options
You can set per-host configuration options
~/.ssh/config by specifying
followed by host-specific options.
It is possible to set the private key and the user (among many other settings) on a per-host basis.
Here's an example config file:
Host my-server.com User admin IdentityFile ~/.ssh/admin.id_dsa BatchMode yes EscapeChar none Host mm User matt HostName might.net IdentityFile ~/.ssh/matt.id_dsa Host *.lab.ucaprica.edu User u8193
The first example enables batch mode, which means
it will never ask for a passphrase or password
for this host.
It also disables an escape sequence, which
avoids any hiccups when transmitting
ssh is to be invoked within scripts,
this is a good option.
The second example uses a
ssh mm is equivalent to
ssh -i ~/.ssh/matt.id_dsa email@example.com.
The third example sets the user to
u8193 for any
machine in the subdomain
See more options in
The options most frequently tweaked are:
Port: set this to the port on which you want sshd to run. Unless you have a compelling reason to move it, keep it on 22.
PermitRootLogin: set this to
noand then configure
sudoto add a little security; another good setting is
without-password, which will force the use of public key authentication for
PasswordAuthentication: set this to
noto disallow password authentication entirely and to require public key authentication.
The man page for
sshd_config summarizes the
remaining options well.
Local port forwarding
SSH allows secure port forwarding.
For example, suppose you want to connect from
but route traffic securely through server
A$ ssh C -L localport:B:remoteport
Then, to connect to
If you use add
anyone that can reach
may connect to
This is useful for evading firewalls.
For example, suppose your work banned reddit.com.
# ssh yourserver -L 80:reddit.com:80
And, set the address of
You will also need to disable any local web server running first.
Now, it will surreptitiously traffic to
reddit.com through your yourserver.
If you do this frequently, you might want to add a special host:
Host redditfw HostName yourserver LocalForward 80 reddit.com:80
Remote port forwarding
Alternatively, suppose you wanted to give remote machine
access to another machine,
passing securely through your local machine
C, you can run:
C$ ssh B -R remoteport:A:targetport
At this point, local users on
If you want to to allow nonlocal users to be able to connect
Once again, if you do this frequently,
set up a special host in
Host exportme HostName B RemoteForward remoteport A:targetport
Setting up a SOCKS proxy for Firefox
SSH can also set up a SOCKS proxy to evade a firewall.
It's remarkably simple:
$ ssh -D localport host
In Firefox, under Preferences > Advanced > Network, select "Settings."
Set your SOCKS5 proxy to
localhost port localport.
Test it out by googling "what is my ip."
Firefox will now forward your web traffic through host.
A word of caution: this will not forward your DNS requests.
about:config, you can also tell Firefox to forward
your DNS requests;
SSH as a filesystem: sshfs
On the Mac, use Fuse4x.
From MacPorts, install it all with:
$ sudo port install sshfs
And, once it's installed, run:
$ sshfs remote-host: local-mount-directory
SSH from windows
Sometimes, you need to get to your home machine from windows. In these cases, you want the PuTTY suite of tools.
SSH from iOS
Using SSH from iOS can be cumbersome, but the iSSH app is particularly well-suited to administrative tasks.
The iSSH app allows storing configurations, which enables per-machine private keys and remote commands to run upon connecting.
So, you can create a configuration that logs in to run a shell script.
I have three command-based configurations for might.net:
- a script to (re)start the web server;
- a script to (re)start the DNS server;
- a script to reboot the entire server.