How to Limit SSH Access

Created by Pete Nesbitt
October 27, 2003

This document is intended to be a guide for creating a secure method to access 
system from a specific remote host. The intent is to allow access without 
opening the system up to everyone everywhere.

The idea is to set the host up to allow access from a specific remote system. 
This can be used, for example, to acess your home system from work.

We will use IPtables to control the source of the ssh request, this is typically 
on the edge of your network but could run on the host itself. Then we use 
TCPwrappers as a second level check. If you think this sounds a bit redundent, 
your right! Then we restict which accounts can access ssh by implimenting PAM 
access rules. Finally we make a few changes to the default sshd configuration to 
force a key based authentication, which links to the remote host for the key and 
the specified user who has the pass phrase for the key.

The Details:
Note: You may want to do the key generation (last step) early so you can easily 
scp it without restrictions in place, although this set up would allow a 
seamless 'reverse scp' anyway.

-IPtables Firewall:
Although there are many ways to set up firewall rules, the best approach is 
'everything is denied except that which is explicitly allowed'. This method errs 
on the side of caution as there are always typoes and other little issues to fix.
If you need help seting up IPTables you may want to start at the projects home:

The basic firewall rules for ssh should resemble:

  Prerouting Chain:
     $IPTABLES -A PREROUTING -t nat -p tcp -i $EXT_IF \
        --dport 22 -j DNAT --to-destination $SSH_TARGET 

  Forward Chain:
     $IPTABLES -A FORWARD -i $EXT_IF -p tcp --dport 22 -j SSH_CHAIN

  SSH Chain: (note "" is the remote ssh clients host or network)
     $IPTABLES -A SSH_CHAIN -p tcp -m state --state NEW -i $EXT_IF \
        --dport 22 -j LOG --log-prefix "NetF SSH Login: "
     $IPTABLES -A SSH_CHAIN -p tcp -i $EXT_IF -s \
         -d $MY_WORKSTATION --dport 22 -j ACCEPT

-TCPwrappers Acceess Control:
Set your hosts.allow and hosts.deny as follows (add other services as required).
Note, do not allow ssh inbound from the firewall/gateway ip (.1) as this 
should never be the case.

   ALL: 192.168.0. EXCEPT
   sshd: 123.123.123. EXCEPT UNKNOWN # (ssh clients host or network)
     # note "UNKNOWN" forces reverse DNS lookup and may help prevent spoofing.


-PAM access control:
Here we use PAM to restrict access to sshd to a specific target user. By seting 
this to a cryptic user id helps prevent id & password guessing. Once authenticated 
the user can su to her regular id.

edit /etc/pam.d/sshd (it's always best to make a copy of the original first)
 add the line:
 account  required  /lib/security/ accessfile=/etc/security/access.conf_ssh

touch /etc/security/access.conf_ssh
  (or copy /etc/security/access.conf to include comments)

edit /etc/security/access.conf_ssh adding the following:
    +:ALL:192.168.0. .localdomain

(note that although we allow access for all users on the local lan, the next 
section would require that keys are in place on those systems.)

-SSHD Restrictions:
make the following changes to /etc/ssh/sshd.conf to disllow root user access and 
to disallow password or athentication, forcing key based. (You will see similar 
lines that are commented out which display the defaults.)

PermitRootLogin no
PasswordAuthentication no
PAMAuthenticationViaKbdInt no

Note: you will need to reload/restart the sshd daemon for changes to take place.
      You can use "service sshd reload", "/etc./init.d/sshd reload" or 
      "killall -HUP sshd" depending on your system or personal preference.

-Generate Authentication Keys:
As the user you want to log in as, but on the remote system (same user), run the 
'ssh-keygen -t dsa' and enter a decent pass-phrase when requested.

This will leave 2 keys in the users .ssh directory named something like 'id_dsa' 
and ''. Transfer the '' file (via scp, sftp, floppy etc but 
NOT ftp!) to the sshd host. If the users .ssh dir has a file named "authorized_keys" 
then append the key to that file, otherwise, create the file and copy the key into it.

You know have a ssh daemon that only allow access from a specific user on a specific 
remote network via key based authentication combined with a pass-phrase. The only 
real downside is that you need to create keys for any local systems that require 
ssh access to this host.