Defindit Docs and Howto Home

This page last modified: Aug 05 2011
title:SSH public key authentication including scp, sftp, sshfs and X11 forwarding
description:Configuring ssh to use your public key, scp notes as well as SELinux context problem diagnosis and fixes, sshfs and fuse, and how to configure X11 forwarding in order to run Firefox and Emacs in graphical mode.

Table of contents
Shortcuts and .ssh/config
X11 graphical appications
Introduction to ssh keys
How to determine which SSH version you have
SSH public key setup and configuration
Detailed ssh key explanations
Using the -l limit option with scp
How to sshfs, using ssh to mount a remote file system aka fuse
How to create shortcuts in .ssh/config
Host identification warning
Public key not accepted due to SELinux context
Permission denied (publickey,keyboard-interactive) due to config

Shortcuts and .ssh/config

If you have a file named "config" in the .ssh directory in your home
directory, then that file will be used for aliases and other ssh
options. I like have short name for each server (host) that I
routinely login to. It is also useful to include a username if the
destination user name is different. You'll also want to use a key pair
(see below) so you don't have to type your password every time.

From what I can tell, the information for each host begins with a
"Host" line. I separate stanzas with at least one blank line. Lines
beginning with # are comments.

See notes below about the X11 configurations settings.

I set EscapeChar to none because I am prone to use all my escape
characters for something, and I don't want any conflicts. I have never
used the escape anyway. If a session hangs, I kill it and start

These options apply to OpenSSH. The commercial version may differ.

With the config file in place, and your public key properly installed
on the destination server (, then you can login
simply with:

ssh zeus

No password will be required.

The config file:

# see man ssh_config

Host zeus
User mst3k
EscapeChar none
ForwardX11 yes
ForwardX11Trusted yes

X11 graphical appications

If you are running X-windows then you can run graphical applications
just like they were on your desktop. Aside from minor style
differences, the applications look and act like they are running on
your computer, however, they are running on the server. This does
require a fairly fast network connection.

Use the ForwardX11 config as below. Linux-to-Linux normally does not
need the ForwardX11Trusted. However, I have found that Mac-to-Linux
requires it. (Probably because the Mac is configured not to trust
other X11 servers.)

If you run an X11 graphical application on the server, the window will
appear on your X11 desktop, although the application is running on the
server. Use "&" at the end of the command to run the application in
the background, allowing you to continue to use your terminal. I
typically run several terminal sessions, but I try to keep all my
background X11 applications in one of the terminals. If you try to
close a sessions with background jobs, you may get a warning.

To view any background tasks, use the shell's "jobs" command. Here is
a sample of what I see when I enter the command "jobs" with two
background jobs:

> jobs
[1]-  Running                 emacs &
[2]+  Running                 firefox &

Here are three example commands that will run graphical applications
(assuming that these applications are installed on your server):

firefox &

emacs &

google-chrome &

It is also possible to start the entire desktop, either KDE or Gnome. 

startkde &

gnome-session &

My initial trials with this were not good. I was running IceWM locally
on a Macintosh and when Gnome started, the keyboard started sending
the wrong characters. I'll try again without a local desktop, just
plain XQuartz.

Introduction to ssh keys

Ssh keys are generally used to login securely with the need to enter a
password. The "key pair" consists of a private key and a public
key. The public key is installed on other computers. You keep the
private key local on your computer, and you must make sure that your
private key cannot be read by anyone else, including other users on
your computer. Login via public key is more secure than a password
because no one can look over your shoulder and see you type your
password, and if your computer is infected with a trojan malware
keyboard password sniffers, there's nothing to sniff. Ssh establishes
an encrypted session before exchanging keys or passwords, so network
packet sniffing will not reveal passwords or keys.

I'm pretty sure that anything that seems to require copying private
keys is wrong. I have never needed to copy a private key.  Instead of
copying a private key, generate a new key pair with the other user or
other machine.

The private key allows access from anyone, which is why private keys
must also always be readable only by their creator. (users read only).

Use this method to have a secure login without using a password.  The
machines are host1 and host2.  Use this method to login to host2
without using a password.  Assume you have accounts on both machines,
and you able to ssh login to either machine using a password.  Assume
you are already logged in to host1.  Assume your userid is mst3k.

In order to avoid confusion, rename the public key that is copied to
host2. Confusion would arise in the situation where multiple accounts
and/or multiple users were logging in to host2.

How to determine which SSH version you have

Use the command:
ssh -V

The two types of output are shown below.

Commercial version from SSH Communications Security Corp. In this case
"non-commercial" most likely means commercial software on a
non-commercial licence to the university.

[mst3k@hostx mst3k]$ ssh -V
ssh: SSH Secure Shell 3.1.0 (non-commercial version) on i686-pc-linux-gnu
[mst3k@hostx mst3k]$

OpenSSH, Open source version:

[mst3k@host1 ~]$ ssh -V
OpenSSH_4.2p1, OpenSSL 0.9.7f 22 Mar 2005
[mst3k@host1 ~]$

SSH public key setup and configuration

# All steps when going from an OpenSSH machine to an OpenSSH machine
# This has been tested. When running ssh-keygen you will be prompted
# for a file name and a  passphrase. Simply hit the return key to accept the
# default file name, and enter no passphrase.

cd .ssh
ssh-keygen -t dsa
scp host2:/home/mst3k/.ssh/
ssh host2:
cd .ssh
cat >> authorized_keys

# The last three steps above can be replaced by one command:

ssh host2 'cd .ssh; cat >> authorized_keys'

# Those tick marks around the command are single quotes, and that quoted
# command is sent to host2 to be run as a shell command on host2. I
# don't know if double quotes "" will work. Do not use backticks ``
# which will not work because backticks evaluate the enclosed text in
# the current shell.

# All steps when going from an OpenSSH machine to a commercial SSH
# machine.  scp may require a -1 switch to force scp1 compatibility
# mode.  Note! The commercial SSH directory is .ssh2 (with a 2).
# These steps have been tested when host1 was Fedora Core 4, and host2
# was SunOS 5.8.

cd .ssh
ssh-keygen -t dsa
ssh-keygen -e -f >
scp host2:/home/mst3k/.ssh2/
ssh host2:
cd .ssh2
echo "key" >> authorization

# All steps when going from an commercial SSH machine to a OpenSSH machine.
# This has not been tested. 
cd .ssh2
ssh-keygen -t dsa
scp host2:/home/mst3k/.ssh/
# The following line may be necessary on host1 (the commercial SSH host)
echo "IdKey id_dsa_1024_a" >> identification
ssh host2:
cd .ssh
ssh-keygen -i -f >
cat >> authorized_keys

# All steps when going from an commercial SSH to a commercial SSH machine.
# This has worked, but was not tested thoroughly.
cd .ssh2
ssh-keygen -t dsa
scp host2:/home/mst3k/.ssh2/
# The following line may be necessary on host1 (the commercial SSH host)
echo "IdKey id_dsa_1024_a" >> identification
ssh host2:
cd .ssh2
echo "key" >> authorization

Detailed ssh key explanations

#Create a OpenSSH DSA key pair. This might be the same for commercial SSH.
# man ssh-keygen should answer questions.
ssh-keygen -t dsa

#Copy the DSA public key from host1 to host2
scp host2:/home/mst3k/.ssh/

# A variant of scp where your userid on host2 is explicit.
scp mst3k@host2:/home/mst3k/.ssh/

# login, and cd to the ssh directory
ssh host2
cd .ssh

# DSA keys seem to want to be in authorized_keys, not authorized_keys2 (see RSA below)
cat >> authorized_keys

#Create an OpenSSH RSA key pair:
ssh-keygen -t rsa

#Copy the public key from host1 to another host2
scp host2:/home/mst3k/.ssh/

# login and cd to the ssh directory
ssh host2:
cd .ssh

# Note: it appears that RSA keys go into authorized_keys2
cat >> authorized_keys2

# Debuging. To get access to verbose information, use ssh -vvv.
# If you get the message:
# userauth_pubkey_agent: no more key
# This may mean that $HOME or $HOME/.ssh is group/other writable.
# The following chmod fixed this problem:
cd ~/
chmod go-rw .
chmod go+x .

# On an OpenSSH host, convert an OpenSSH key to the SECSH format.
# Use this when you need to move an OpenSSH key to a commercial SSH machine.
# In the following example, we assume that host1 is OpenSSH,
# and host2 is commercial SSH.
ssh-keygen -e -f >

# On an OpenSSH host, convert a public key from a commercial SSH client.
# Use this when you have a public key generates on a commercial SSH machine.
# In this case, we assume that host1 was commercial SSH, and we are 
# logged in to host2. 
cd ~/.ssh
ssh-keygen -i -f >

# Concatenate the key to the end of the authorized_keys file.
cat >> authorized_keys

# Logged in to commercial SSH machine host2 where is
# an SECSH formatted public key. 
# Add a single line to the "authorization" file using the echo command.
# Apparently, commercial SSH uses the key file name, in the authorization file
# instead of the whole key.
cd ~/.ssh2
echo "key" >> authorization

#SSH Corp, non-OpenSSH
# Contents of the file ./ssh2/authorization

# Contents of the file ./ssh2/
Subject: mst3k
Comment: "1024-bit dsa,, Thu Aug 22 \
2002 11:12:23 -0400"

Using the -l limit option with scp

The scp -l limit option uses Kbit/s which is kilobits per second (8
bits per byte). To convert to KB per second use Google
calculator. Enter a query like the following into

20 KBps in kbps

For example, you have a 70 kilobyte per second DSL, and you want to
move a large file, but you don't want to overload the DSL. You decide
that 20 KB per second is fine. The answer (from Google) is 160 kbps
(note lower case kb for kilobit versus uppercase KB for kilobyte).

Somewhere I got the idea (seems accurate) that to convert kbps to
actualy KB per second one multiplies by 0.088

760 kbps * 0.088 = 67 KB/s

This must be actual throughput number since 760 kbps is actually 95
KBps (according to Google; I haven't done the conversion myself since
I'm lazy). My DSL provider says I have a 760 kbps line, but max
throughput is right about 67 KB/s.

In any case, -l 160 with scp settles down (after 15 seconds or so) to
20 KB/s.

scp -l 160 big.tar

How to sshfs, using ssh to mount a remote file system aka fuse

Many thanks to Ryan for telling me about this nifty way to connect to
remote machines via ssh.

I've tried this mounting a server that is on a DSL line, and then
editing files with emacs. Works great. There were minimal (1 second or
less) delays when saving files.

- You will have to install the fuse-sshfs.i386 package (Fedora) if it
doesn't already exist on your sytem.

- Add yourself to the fuse group. Logout and login again or su -l to a new shell so
that the shell has your new group membership.

- Create an empty directory to use as a mount point.

(As far as I know you can use any directory as a mount point, but it
seems odd to mount a file system to a directory that has files in
it. If you try to use sshfs on a non-empty directory, you'll get a
message like this:

fuse: mountpoint is not empty
fuse: if you are sure this is safe, use the 'nonempty' mount option

I suggest that you use an empty directory as the mount point, however,
I've had no problems when mounting to a directory with files.

This error:
fuse: failed to open /dev/fuse: Permission denied

means that either you aren't in group fuse, or your shell doesn't know
it yet. See output from the groups command below. You may have to
logout/exit your X session in order to get the shell to refresh your
new group memberships.

In the example below I'm "mst3k" on host "zeus". In my home directory
I make a new directory "readme_files".  I'm mounting
"/home/remote/public_html/readme_files" on "./readme_files". (The full
path of ./readme_files is /home/mst3k/readme_files.)

Example session transcript:

[zeus ~]$ groups
mst3k fuse
[zeus ~]$ pwd
[zeus ~]$ mkdir readme_files
[zeus ~]$ sshfs ./readme_files's password:
[zeus ~]$ ls readme_files/
3c905.html                     find_tricks.html                   perl_setuidperl.html
3c905.txt                      find_tricks.txt                    perl_setuidperl.txt
actiontec_ethernet_modem.html  firefox.html                       perl_sql_example.html
actiontec_ethernet_modem.txt   firefox.txt                        perl_sql_example.tar
adduser.html                   fsck_check_logical_volumes.html    perl_sql_example.txt
adduser.txt                    fsck_check_logical_volumes.txt     perl_syntax_errors.html
analog_web_logs.html           gconfd_firefox_evolution.html      perl_syntax_errors.txt
analog_web_logs.txt            gconfd_firefox_evolution.txt       pg_dump.html
apache_13_error.html           gconfd_http_launch_howto.html      pg_dump.txt

To unmount a fuse filesystem:

fusermount -u mountpoint

Using the example above:
fusermount -u readme_files

The filesystem will be unmounted even if there are files open in emacs
because emacs (apparently) doesn't keep an i/o stream open to the
file. In my (brief) test, when "less" was reading a file from the
mounted filesystem, fusermount -u gave the expected message:

umount: /home/mst3k/readme_files: device is busy
umount: /home/mst3k/readme_files: device is busy

As with sshfs, you must be in group "fuse" to run fusermount.

The fuse home page is:

The basic syntax is:

$ sshfs [user@]host:[/path/to/folder] /local/mountpoint [-o mount_options,SSHOPT=value,...]

If you leave out the username, it uses the default, just like ssh. If
you leave out the directory, it defaults to your home directory (or
more specifically, whichever directory you would start out in if you
ssh'ed to that server). You can include ssh options in the mount
options, and these will be passed to the underlying ssh
process. Someone recommends "BatchMode=yes" but I have no idea why.

An alternate way to show the same command format for etc/fstab is:

sshfs#USERNAME@REMOTE_HOST:REMOTE_PATH MOUNT_POINT fuse SSHFS_OPTIONS 0 0 /mnt/guest fuse uid=1003,gid=100,umask=0,allow_other 0 0

I'm not sure why #guest since I always just use a space after the ssh command.

It is possible to set these up from fstab to mount at boot time (or
rather, at such time as the network becomes available).

Here are some working sshfs commands.

Run this as root to mount mst3k from to the current machine.

sshfs /home/mst3k -o nonempty -o follow_symlinks -o allow_other -o default_permissions -o workaround=rename

-o nonempty # allow mounting to nonempty directories as mount pointes
-o follow_symlinks # probably not necessary, but I have symlinks so I added this
-o allow_other # necessary so that apache can serve web pages
-o default_permissions # related to other users reading your files
-o workaround=rename # necessary for CVS to work. 

The -o workaround=rename option fixes this problem:

cannot rename file CVS/Entries.Backup to CVS/Entries: Operation not permitted

I found a note about the rename problem in a FUSE support page:

Run the command below as mst3k to mount home directory from to the local file system:

sshfs /home/mst3k -o nonempty

Here is a handy fuse FAQ:

As of May 2008 using Fedora 8, I have an unresolved error. Creating symlinks give an i/o error, but the symlink is created and works. The resulting symlink cannot be distinguished from a real file. Here is a session transcript:

[mst3k@zeus CGKB]$ ls -l ~/public_html/omssaweb/
-rw-r--r-- 1 mst3k users 36592 2008-04-25 16:47 /home/mst3k/public_html/omssaweb/
[mst3k@zeus CGKB]$ ln -s /home/mst3k/public_html/omssaweb/ ./
ln: creating symbolic link `./': Input/output error
[mst3k@zeus CGKB]$ ls -l ./
-rw-r--r-- 1 mst3k users 36592 2008-04-25 16:47 ./
[mst3k@zeus CGKB]$

Also, I don't know if you use ftp often, but there's also curlftpfs,
which allows you to mount an ftp server folder as a filesystem in much
the same way.

Here's the website for curlftpfs:

How to create shortcuts in .ssh/config

I often have to login to machines with long names like If the command is in my bash history I
can use control-R to search backwards which is fast, but the ever
clever Ryan suggested another, more comprehensive solution.

Create a file ~/.ssh/config and add lines Host, HostName, and
User. This is also great when you are logging in to a machine where
your userid is different.

# sassafras unix shortcut
Host sas
User msterry

Host identification warning

This means you need to delete the entry or entries in you
.ssh/known_hosts file for the machine you are connecting too. This
occurs after re-installing the operating system. It could also mean
that someone is attempting a man-in-the-middle attack on your ssh
connection. You can verify host identity by logging in to the remote
host via some other method, and getting that host's RSA finger print.

From the ssh man page, we learn how to get a hosts RSA
fingerprint. The RSA keys are private, and therefore only readable by

[root@zeus ~]# ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key
2048 e9:14:81:58:0b:b8:91:09:4d:f1:07:a7:1f:eb:ac:25 /etc/ssh/
[root@zeus ~]#

This might also be useful:
ssh-keygen -R ip-address

Here is a typical warning:

Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
Please contact your system administrator.
Add correct host key in /home/mst3k/.ssh/known_hosts to get rid of this message.
Offending key in /home/mst3k/.ssh/known_hosts:1
RSA host key for has changed and you have requested strict checking.
Host key verification failed.

Public key not accepted due to SELinux context

In May of 2008 with Fedora 8 I found that SELinux file contexts will
prevent the use of public key authentication until the context is
restored. For this example we have two machines "zeus" and
"hera". Machine (server) hera is running SELinux, but is otherwise
essentially identical to zeus. (Both zeus and hera are running up to
date Fedora 8.) The public key on zeus has been generated as above,
and copied to .ssh/authorized_keys on hera as usual (I used scp and
authenticated with my password). File and directory permissions were
all correct (700 for .ssh, 600 for all the files).

This is the output from hera when the public key is not accepted:

[zeus .ssh]$ ssh -v hera
debug1: Next authentication method: publickey
debug1: Trying private key: /home/mst3k/.ssh/identity
debug1: Trying private key: /home/mst3k/.ssh/id_rsa
debug1: Offering public key: /home/mst3k/.ssh/id_dsa
debug1: Authentications that can continue:
debug1: Next authentication method: password

Note that after the public key was offered, the server did not accept
the key.

When the public key authentication works properly you'll see these lines:

debug1: Server accepts key: pkalg ssh-dss blen 434
debug1: read PEM private key done: type DSA
debug1: Authentication succeeded (publickey).

The problem is on hera. To diagnose the problem you must login to hera
as a normal user (since we have root ssh logins disabled for security
reasons), and then "su -l root". You must be running both
setroubleshootd and auditd. If you are running setroubleshootd and not
running auditd, then you'll find lines like this in your

2008-05-06 13:09:29,057 [avc.WARNING] could not open any audit sockets (/var/run/audispd_events, /var/run/audit_events), retry in 60 seconds

Those "could not open any audit sockets" messages means that auditd is
not running. Confirm by running "/etc/init.d/auditd status".

Start auditd by running "/etc/init.d/auditd start" and remember to enable it
at boot with "chkconfig auditd on".

When both setroubleshootd and auditd are running, again attempt to ssh
from zeus to hera and /var/log/messages says:

May  6 13:11:47 zeus setroubleshoot: SELinux is preventing sshd (sshd_t) "getattr" to /home/mst3k/.ssh/authorized_keys2 (home_root_t). For complete SELinux messages. run sealert -l 85cae04a-0185-4921-8a68-e82dfbe0e955
May  6 13:11:47 zeus setroubleshoot: SELinux is preventing sshd (sshd_t) "getattr" to /home/mst3k/.ssh/authorized_keys (home_root_t). For complete SELinux messages. run sealert -l 3a90536d-63b9-4f2c-94da-513da0d5793f

Now we see that there is some problem with
/home/mst3k/.ssh/authorized_keys and
/home/mst3k/.ssh/authorized_keys2. This would explain why the
authentication didn't work. To see a diagnosis of the problem, run the
recommended command sealert. You may run this command as root or mst3k
(the normal user), however, only root can view /var/log/messages.

sealert -l 3a90536d-63b9-4f2c-94da-513da0d5793f

The output is long, but this is the important part:

Sometimes labeling problems can cause SELinux denials. You could try to restore
the default system file context for /home/mst3k/.ssh/authorized_keys,

restorecon -v '/home/mst3k/.ssh/authorized_keys'

To solve my problem, I ran /sbin/restorecon as mst3k, *not* as
root. Note that /sbin is not in the default path for non-root users,
thus you must type the entire path.

[mst3k@hera .ssh]$ /sbin/restorecon -v '/home/mst3k/.ssh/authorized_keys'
/sbin/restorecon reset /home/mst3k/.ssh/authorized_keys context system_u:object_r:home_root_t:s0->system_u:object_r:user_home_ssh_t:s0
[mst3k@hera .ssh]$

Problem solved. Login via ssh was successful using public key

From this I conclude that users must be somehow aware of SELinux
context (whatever "context" means) when creating files that will be
used by the system and/or system daemons such as sshd. I su'd to root
in order to read /var/log/messages and solve the problem. However, you
may be able to

sealert -l *

in order to read alerts as a non-root user.

Permission denied (publickey,keyboard-interactive) due to config

If you have a .ssh/config file on the originating computer and use a
setting to force the use of publickey, but don't have a public key,
login will fail. You don't be prompted for a password. You will get this message:

Permission denied (publickey,keyboard-interactive)

The key diagnostic is that login will fail from one computer, but not
from another.

This line is the feature in the config that causes this interesting

PreferredAuthentications password,publickey

This can happen when you have a config file working on one computer,
and copy the config file to a second computer, but forget to set up
public keys.

Being prompted for a password could be "password" or could be
"keyboard-interactive". Using just one or the other could cause the
failure, and you won't be prompted for a password.