Replacing telnet/rlogin/rsh with SSH
See also Part I
By Seán Boran (sean at boran.com)
www.boran.com/security/sp/ssh-part2.html
This article is the second in a two part series on SSH, the Secure SHell. The focus here is on the OpenSSH implementation. OpenSSH has developed quickly since it's inception in 1999 and has an expert team of developers behind it.
Recent changes:
See also the change history section |
It is now a solid alternative to the commercial SSH1 and SSH2. The availability of OpenSSH, the loosening of the U.S. export controls in 2000 and the expiry of the RSA patent allows OS vendors to finally ship SSH on all UNIX-like Operating Systems and put telnet/rlogin/rsh/rcp to rest.
Refer to Part I for a general presentation of
SSH and several other implementations.
Italian readers: please note that this
article has also been translated into Italian [9].
Secure Shell (SSH) is a secure replacement for Telnet, rlogin, rcp, rsh and provides secured TCP tunnels. It is described in detail in Part I.
Where does OpenSSH originate?
Why OpenSSH?
Where can I get OpenSSH?
Why should I use OpenSSH?
Difficulties:
Previously, compiling was tricky with OpenSSH, new versions are much easier. There are lots of ways to compile OpenSSH, here we following Sun's guidelines Building and Deploying OpenSSH for the Solaris Operating Environment (which is a bit old at this stage) compiling with gcc.
Note: SSH is now bundled with Solaris 9. It is an older version of OpenSSH adapted by Sun. Some features such as HostbasedAuthentication are not implemented. The latest version of the SSH patch 113273 (sparc) should be installed to ensure known security issues are updated.
Note:
Our first package listed here was v2.9p2 See also Upgrade notes. |
Have a quick read of Sun's document , which we use this as a basis. There are however, some errors:
SSH is compiled below in a similar way to Sun and also installed in /opt/OBSDssh. There are some differences though:
The following package compiled on Solaris 2.6
worked on 2.6, 7, 8 on both UltraSPARC and SuperSPARCs. If
compiled on Solaris 8 UltraSPARC however, it would only work on Solaris 8 UltraSPARC.
The precompiled Solaris package created below can be
downloaded [10].
Step 0:
set umask. If you use a restrictive umask like 077 or 027, this will cause problems when running "make install", often creating files and directories not accessible to others. Therefore it is suggested to allow group and world to read any files generated. In addition make sure ccs in in the path and LD_LIBARY_PATH doesn't cause any lib issues.
umask 022
export PATH=${PATH}:/usr/ccs/bin
unset LD_LIBRARY_PATH
cd zlib-1.1.4
make clean && ./configure && make
[now su to root]
make install
To check if it's already installed:
showrev -p | grep 112438
ls -l /dev/random
PRNGD:
There is no pseudo-random device patch for Solaris
versions prior to Solaris8, so a prng needs to be installed.
To Build and install prngd; first download from www.aet.tu-cottbus. de/personen/jaenicke/postfix_tls/prngd.html [This site was experiencing some problems when last tried on 11.Mar.02]
To compile SSH with PRNGD:
|
Patch are downloadable from ftp://sunsolve.sun.com/pub/patches/
- Solaris 8 SPARC: 112438-01
- Solaris 8 Intel 112439-01
Important: Reboot after installing the patch, to create the device
/dev/random.
cd openssl-0.9.7a
make clean
./Configure solaris-sparcv7-gcc
make
[now su to root]
make install
cd tcp_wrappers_7.6
make REAL_DAEMON_DIR=/usr/sbin sunos5 CC=gcc
[Note: We don't need to actually install the
tcpd binaries for SSH compilation]
cd openssh-3.7.1p2
Consider hiding the actual SSH version for key systems exposed to hostile
networks:
vi version.h
./configure --prefix=/opt/OBSDssh --with-pam --without-rsh \
--sysconfdir=/etc/ssh --with-pid-dir=/var/run --disable-suid-ssh \
--with-tcp-wrappers=../tcp_wrappers_7.6 --without-rand-helper --with-ssl-dir=/usr/local/ssl
make
a) Copy Jass scripts
cd
OpenSSH_tools
b) Tune package settings:
cd openssh-3.7.1p2
vi makeOpenSSHPackage.ksh
Adapt the script to your taste, e.g.
see makeOpenSSHPackage.ksh which
includes the following changes:
- installSSHSUID=no [yes - if you'll need host-based trusts]
- change configDir=/etc to configDir=/etc/ssh
- change "primes" to "moduli" in the line: "for file in moduli ssh_prng_cmds; do"
- change to install man pages in /usr/local instead of /opt
- install tcp wrapper man pages
cp sshd_config.out sshd_config.out.orig
[adapt the
default config to your taste, e.g. see our sshd_config.out]
vi sshd_config.out
c) Make the package
cp sshd_config.out makeOpenSSHPackage.ksh openssh.server openssh-3.7.1p2/
cd openssh-3.7.1p2
./makeOpenSSHPackage.ksh
d) Examine the package description:
pkginfo -l -d OBSDssh.pkg
f) Rename the package to include architecture & version (This format is also suitable
for Jass+Jumpstart installations):
mv OBSDssh.pkg ../OBSDssh-3.7.1p2-`uname -p`-`uname -m`-`uname -r`.pkg
pkgadd -d OBSDssh-3.7.1p2-sparc-sun4u-5.8.pkg OBSDssh
groupadd sshd; useradd -g sshd sshd
## Run a maximum of SSH as user "sshd"
## Reduce privileges for most openssh features.
UsePrivilegeSeparation yes
sh /etc/init.d/openssh.server start
upgrade_checklist_371p2.txt v3.7.1p1 => 3.7.1p2
upgrade_checklist_371.txt v3.4 => 3.7.1p1
upgrade_checklist_34.txt v3.1 => v3.4
upgrade_checklist_31.txt v3.0.2p2 => v3.1
upgrade_checklist_3.txt v2.9 to v3.0.2
OpenSSH can provide authentication with SecurID tokens, thanks to a patch from Theo Schlossnagle (www.omniti.com/~jesus/projects ) . I've been using this for several years o Solaris, this sections describes the Solaris build. This patch integrates SecurID authentication services directly into the OpenSSH daemon, allowing users to use SecurID tokens directly as their passwords.
A
new how-to page has appeared that is worth reading: http://www.joerg.cc/cgi-bin/wiki.pl?MySecurID-page
RSA libraries for linux can be downloaded from ftp://ftp.rsasecurity.com/pub/agents/linux.tar
To compile: extract SSH as usual, download Theo's patch into the OpenSSH directory, then:
Apply patch (using GNU patch tool):
/usr/local/bin/patch <
openssh-3.7.1p2+SecurID_v1.3.1.patchRead
README.SecurID
before continuing.Copy SecurID library to SSH dir:
cp /usr/ace/examples/sdiclient.a .
Consider hiding the actual SSH version for key systems exposed to hostile networks:
vi version.h
Compile (see the Solaris section above for an explanation of the options used), note that an ACE v4 server is used:
./configure --prefix=/opt/OBSDssh_sdi --with-pam --without-rsh --sysconfdir=/etc/ssh --with-pid-dir=/var/run --disable-suid-ssh --with-tcp-wrappers=../tcp_wrappers_7.6 --without-rand-helper --with-cflags=-I/usr/ace/examples --with-securid-old --with-ssl-dir=/usr/local/ssl
Then
make
and build a package, as indicated in the Solaris section for example. Note that the package name should be changed in makeOpenSSHPackage.ksh (I use OBSDssh-sdi).
./makeOpenSSHPackage.ksh
mv OBSDssh.pkg ../OBSDssh-sdi-3.7.1p2-`uname -p`-`uname -m`-`uname -r`.pkg
Comments:
A Binary Solaris 8 package for sun4u, OBSDssh-sdi.pkg can be downloaded [10].
NOTE: This (old) section is redundant as more newer versions of Linux include OpenSSH
already, but it may be of interest to those who wish to install their own SSH.
We install OpenSSH below in /usr/{bin,sbin,man}, with configuration files in /etc/ssh,
since that is what is used in the binary rpms for RH6.1.
rpm -erase ssh-1.2.27-41
zcat openssl-0.9.3.tar.gz | tar xf -; cd openssl-0.9.3;
./config;
make && make install;
zcat openssh-1_2_2_tar.gz |tar xf -; cd openssh-1.2.2;
./configure --prefix=/usr --sysconfdir=/etc/ssh -without-pam --with-tcp-wrappers
make && make install;
ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N ''
/usr/sbin/sshd
zcat openssl-0.9.3.tar.gz | tar xf - ; cd openssl-0.9.3;
./config;
make && make install;
zcat openssh-1_2_2_tar.gz |tar xf -; cd openssh-1.2.2;
./configure --prefix=/usr --sysconfdir=/etc/ssh -without-pam --with-tcp-wrappers
ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N ''
/usr/sbin/sshd
Red Hat 6.1 on Intel i386:
Download and install packages:
rpm -i openssl-0_9_4-3_i386.rpm
rpm -i openssh-1.2.2-1.i386.rpm
rpm -i openssh-server-1.2.2-1.i386.rpm
rpm -i openssh-clients-1.2.2-1.i386.rpmStart the daemon:
/usr/sbin/sshd
Problems:
OpenBSD 2.6 is bundled with OpenSSH v1.2 and works fine, except for a few issues:
That being said it worked well is a mixed environment of SSH1 Solaris Systems and NT Systems with Mindterm SSH.
A comprehensive UNIX-like environment, including a port of OpenSSH can be installed by installing Cygwin. The client and server work well and secure copy (scp) also works on client and server side, as did testes with VNC tunnelling.
ssh-host-config -y
ssh-user-config
/usr/sbin/sshd -d -d -d
First install the service:
instsrv.exe OpenSSHD f:\utils\srvany.exe
Then run OpenSSHD.reg file to setup registry entries.
Make sure the system use owns ssh config files:
chown system /etc/ssh*
Then start SSHD:
net start OpenSSHD
Mark Bradshaw has produced an interesting package for OpenSSH on Windows,
based on cygwin.
http://www.networksimplicity.com/openssh
Documentation look promising indeed, I've not yet tested it though. A colleague who has tested it says: "Easy to install, works perfectly as a win service, scp works fine, ssh tunnelling also (stable), rsa/dsa authentication works fine too!".
OpenSSH supports both the v1 and v2 protocol, this make things quite complex as there dedicated option for each and similar ways of doing the same things.
Let's say we want to login from host A to B, as root, without a password prompt. This is called a trust and is useful for automated operations, and for saving time when hopping from one machine to another. It is a feature that needs to be used with care, if security weaknesses are not to be opened up. Here we give an overview and some concrete examples on how to set it up.
SSH has two kinds of trust, one based on host keys - "host based", the other on user keys - "RSA or publickey".
Why host based and not RSA/public key trusts?
- The server depends on the client protecting it's private key and passphrase properly.
- The normal server login, and account management/aging mechanisms may be bypassed.
- IP based access control was not possible with RSA keys in v1.
- Users have more freedom to setup trusts if RSA is allowed (this is good or bad depending on the server scenario)
Why RSA/publickey trusts?
- RSA/publickey is convenient for usage with ssh-agent on workstations to avoid multiple logins.
- Configuration is simpler and less error prone (Host based trusts can use /etc/shosts.equiv, hosts.equiv, .rhosts and .shosts. RSA/DSA/publickey just uses .ssh/authorized_keys and .ssh/authorized_keys2 for v2.x)- Newer SSH versions allow controls to be placed on public key logins, via 'options' in authorized_keys:
- The source IP/name can be restricted:
from="176.17.17.*"
from="server1"
- Port forwarding can be disabled, or ports controlled:
no-port-forwarding
no-X11-forwarding
no-agent-forwarding
permitopen="10.1.1.3:80"
- Interactive shells can be disabled:
no-pty
- A specific command can be executed, any other commands passed are ignored. Typically
Note to the OpenSSH crew: It would have been nice to specify a list of allowed commands, for situations where several automated tools use the same trust. used for backups.
command="df -k"
And assume we want to use host trust, rather than RSA/publickey trust. The following was tested from OpenSSH v3.02p1 to v3 and v1.2.27. The v1 method also works between older SSH1 servers.
In the examples below, absolute path names are not given, your SSH config may be in /etc, /etc/ssh, /opt/openssh/etc, /usr/local/etc ..... I recommend using /etc/ssh where possible..
With v1 protocol:
On host B
- Add the Host Publickey of A in ssh_known_hosts (permissions 644, owner root). A's public key can be found in ssh_host_key.pub on host A. When you copy the line from ssh_host_rsa_key.pub, add the name of hostA and a space before it, as you paste to the known hosts file.
- Add "serverA root" to /root/.shosts to allow login as user root. (permissions 600, owner root)
- Add an entry for A to /etc/hosts
- Possibly restrict login accounts in sshd_config: "AllowUsers"
- In sshd_config (permissions 644, owner root), set:
IgnoreRhosts no
PasswordAuthentication yes
RhostsAuthentication no
RhostsRSAAuthentication yesOn host A:
- The sshd client binary must be suid root, to enable it to read the host A's private key.
- To ensure that the ssh client selects the correct protocols, add to ssh_config:
Host serverB
RhostsAuthentication no
RhostsRSAAuthentication yes
RSAAuthentication no
PasswordAuthentication yes
Protocol 1
LogLevel DEBUG
#UsePrivilegedPort yes- If serverB has SSHv1 (e.g. v1.2.27), then you will also need to add "UsePrivilegedPort yes" to ssh_config
With v2 protocol:
On host B
- Add the Host Publickey of A in ssh_known_hosts (permissions 644, owner root). A's public key can be found in ssh_host_rsa_key.pub on host A. When you copy the line from ssh_host_rsa_key.pub, add the name of hostA and a space before it, as you paste to the ssh_known_hosts file.
- Add "serverA root" to /root/.shosts to allow login as user root. (permissions 600, owner root)
- Add an entry for A to /etc/hosts
- Possibly restrict login accounts in sshd_config: "AllowUsers"
- In sshd_config (permissions 644, owner root), set:
IgnoreRhosts no
PasswordAuthentication yes
RhostsAuthentication no
RhostsRSAAuthentication no
RSAAuthentication no
HostbasedAuthentication yesOn host A:
- The sshd client binary must be suid root, to enable it to read the host A's private key.
- To ensure that the ssh client selects the correct protocols, add to ssh_config:Host serverB
RhostsAuthentication no
RhostsRSAAuthentication no
HostbasedAuthentication yes
RSAAuthentication no
PasswordAuthentication yes
Protocol 2
PreferredAuthentications hostbased,password
# Only during initial debugging:
LogLevel DEBUG
And assume we want to use a RSA/publickey trust from hostA to hostB, using protocol v2 only. The following was tested with OpenSSH v3.02p1 on both sides.
On host A
- Log in as the appropriate user and generate a v2 rsa key (~.ssh/id_rsa and ~.ssh/id_rsa.pub), and set a passphrase.
ssh-keygen -t rsa
- In ssh_config (or .ssh/config), set:
Host hostB
Protocol 2
PubkeyAuthentication yes
PreferredAuthentications publickey,keyboard-interactive,password
On host B
- Possibly add an entry for hostA to /etc/hosts- In sshd_config (or .ssh/config), set:
PubkeyAuthentication yes
- in ~/.ssh/authorized_keys add the contents of hostA:~.ssh/id_rsa.pub, for example:
ssh-rsa AAAAB3NzaC1yc2EAAAASOMEBIGLONGKEYOROTHERmdklQM= root@server1
- Possibly restrict the trust, e.g.
from="10.1.2.3",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAASOMEBIGLONGKEYOROTHERmdklQM= root@server1
Now the previous section allows us to setup an Publickey session between the two hosts. If we want to have an automated login, without passphrase prompting, then we have two options:
SSH provides an optional daemon ssh-agent, which can be used to store keys during a login session, only asking for passphrases once and passing keys as need to SSH when loggings into other hosts. For example, if we setup the trust from hostA to hostB in the previous section, as we do "ssh hostB" on hostA, we'll be prompted for the passphrase, which is then used to decrypt the private keys and authenticate. Assuming we logon on frequently to hostB, we can start ssh-agent, add a key to it and then logon as often as desired without having to enter a passphrase:
Start SSH agent:
[root@hostA]#ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-QaSI4226/agent.4226; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4227; export SSH_AGENT_PID;
echo Agent pid 4227;Set the environment variables as given by the output of the ssh-agent:
[root@hostA]#SSH_AUTH_SOCK=/tmp/ssh-QaSI4226/agent.4226; export SSH_AUTH_SOCK;
[root@hostA]#SSH_AGENT_PID=4227; export SSH_AGENT_PID;
[root@hostA]#echo Agent pid 4227;
Agent pid 4227Add the key to the agent:
[root@hostA]#ssh-add ~/.ssh/id_rsa
Enter passphrase for /root/.ssh/id_rsa: XXXXXX
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)Now logon as often as you like to hostB, without the need to re-enter the passphrase each time
[root@hostA]#ssh hostB
A quicker version of the above would be:
ssh-agent > .ssh-env
. .ssh-env
ssh-add ~/.ssh/id_rsa
Notes
Don't forget to kill the ssh-agent when logging out:
pkill ssh-agent
The above examples work fine for interactive sessions, but what about daemons that run on the system, or jobs that run from cron, that need to be able to access trusts, for example a root trust?
For this case,
- a system startup script is written that: starts ssh-agent when the system boots and emails the administrator with the ssh-agent environment and reminds him to do an ssh-add.
- The administrator loads the ssh-agent environment and does an ssh-add as root.
- Each daemon that needs to use the trust, loads the ssh-agent environment before using ssh.
- For each cron job, load the ssh-agent environment, then run the job.
Advantages: This type of trust has quite a high security, since even if the SSH private key is somehow stolen, the passphrase still needs to be cracked, before the be can be misused.
Disadvantage: If the system is rebooted, the administrator must do an "ssh-add", before trusts will function.
A concrete example of how this works:
Copy /etc/init.d/ssh-agent to /etc/init.d and setup links to make it auto-start:
ln -s /etc/init.d/ssh-agent /etc/rc3.d/S99ssh-agent
ln -s /etc/init.d/ssh-agent /etc/rc2.d/K99ssh-agentThen edit this file and change the patches near the top if needed.
Start the daemon:
/etc/init.d/ssh-agent startYou (root) should get a reminder via email saying ssh-add needs to be run, so we run it as follows:
. /tmp/ssh-agent.info
ssh-add ~/.ssh/id_rsaNow lets say we have a cron entry that uses an ssh trust to host B:
0 * * * * /bin/do/something
We now change it to load the ssh-agent environment and then run:
0 * * * * . /tmp/ssh-agent.info; /bin/do/something
Or if we need to login interactively via the trust we would:
. /tmp/ssh-agent.info
sshhostB
Given the current speed of development, the interest & expertise shown by the developers and the easing of U.S. export restrictions, OpenSSH is definitely the one to use.
Consider getting your organisation to contribute cash or people to help in the testing, development, packaging or documentation of excellent open source projects like OpenSSH. |
Like all community efforts though, the success of OpenSSH depends active users and active developers. The more help the existing team get, the better.
[0] Getting OpenSSH:
See www.OpenSSH.com for the original BSD version and www.openssh.com/unix.html for Linux/UNIX ports.
Other sites for source tarballs: thermo.stat.ncsu.edu/pub/openssh/files/
www.openssl.org/source
Note that the domain openssh.org does NOT belong to OpenSSH and should not be used.
[2] Schneier and Kelsey's Yarrow - A secure pseudo random number generator: www.counterpane.com/yarrow.html
[3] SSH Communications and DataFellows.
[4] OSSH ftp.pdc.kth.se/pub/krypto/ossh
[5] openssh-unix-dev Discussion list
www.progressive-comp.com/Lists/?l=openssh-unix-dev&r=1&w=2
[7] /dev/random for Solaris
[9] This article has been translated into Italian:
Tutto su SSH - Parte II/II, Sostituire telnet/rlogin/rsh con SSH
http://www.ziobudda.net/Recensioni/ssh-part2.php
[10] A copy of the precompiled Solaris packages, migration notes and config examples described above can be downloaded for SPARC and x86. See www.boran.com/security/sp/ssh or the mirror sean.boran.com/security/sp/ssh.
[11] Other links:
28.Feb'00 First Publication
01.Mar'00 G.Cope & putty tests. C.Mason & 3DES key lengths. Update:
Installation under Linux
8.May'00 Update: add notes on v1.2.3 which support Protocol V2.0.
16.Jun'00 Note on Security bug in versions prior to v2.1.1.
24.Jul'00 Fix for using scp when openssh installed in /opt/openssh on
Solaris.
19.Sep'00 Feedback from Erek Adams: add link to Solaris /dev/random module.
24.Oct'00 Links to Italian translation.
1.Feb'01 Update links
31.May'01 Update. Add section OpenSSH
on NT/Win2000
08.Aug'01 Compiling latest 2.9p2 on Solaris according to Sun's
Guidelines.
24.Sep.01 Add links to precompiled Solaris pkg.
27.Sep.01 Adapt for openssh-2.9.9p2, create x86 &sparc packages [10]
17.Oct.01 Add section host-based trusts. Improve
references.
13.Dec.01 Add Keychain, update host-based trusts for v1
server.
23.Jan'02 Adapt Solaris for
openssh-3.0.2p1, New trusts section.
14.Feb'02 Add Publickey
trusts with ssh-agent/ssh-add
11.Mar'02 Update
Solaris packages & instructions for OpenSSH v3.1: openssl-0.9.6b->v0.9.6c,
zlib-1.1.3->zlib-1.1.4, remove ssh client suid. Add upgrade
notes.
27.Mar'02 Add OpenSSH for NT
from Network Simplicity
27.Jun.02: Solaris
packages & instructions for OpenSSH v3.4
22.Sep.02: SecurID
31.Jan.03 Improve
Solaris /dev/random notes [7].
20.Oct.03 Several tweaks on Solaris section.
Seán Boran is an IT security consultant based in Switzerland and the author of the online IT Security Cookbook.
Copyright 2002, Seán Boran, Last Update: 21 octobre, 2003 |