Purpose of this howto
Setup a chrooted SSHD environment.
This is very useful when the goal is to set up limitations to the users that access the system through the network
or when u realize that network daemons are inherently insecure to exploits and the best u can do,
in that case, is to reduce the consequences of a exploitation.
This can be useful to do some CVS tracking, source code/packages builds,
or to run a secure backup client–server solution among others examples.
NTPD, Apache (HTTPD) and BIND daemons are very examples of network daemons that runs a chroot cage.
In my example, I want to build a sshd/sftp-server to act as a secure ftp server
without the possibility of allowing logins to the users..
To accomplish that I will use a shell called scponly (http://sublimation.org/scponly/).
In my system, scponly is located in it’s default pkgsrc place: /usr/pkg/bin/scponly.
My box is a NetBSD 2.0.2, but this howto can be easy applicable to FreeBSD cor OpenBSD with some small modifications.
*) Creating the chroot jail
First of all, we create a directory structure.
The permissions have to be right to only allow copying files to the user home folder and to tmp.
# mkdir -p /opt/chroot/sshd
# cd /opt/chroot/sshd
# mkdir -p bin dev etc home lib libexec sbin tmp var
# mkdir -p var/run var/chroot/sshd
# ln -s . usr
# chmod 555 home
# chmod 1777 tmp
# mkdir –p pkg/etc/ssh
As u can see `ln -s . usr`, make usr subdirectory becomes a symblink to chroot's top directory.
This will avoid binary distinction.
In “pkg/etc/ssh” is the place where the sshd config file and keys are going to be copied.
*) Copying the needed stuff to the chrooted directory structure
# cd /opt/chroot/sshd
# cp /bin/ksh /usr/bin/passwd /bin/date /bin/ls /bin/pwd /usr/bin/groups bin
# cp /usr/pkg/bin/scponly bin
# cp /etc/localtime etc/localtime
# cp /sbin/nologin /usr/sbin/pwd_mkdb /usr/pkg/sbin/sshd sbin
# cp /etc/master.passwd /etc/group /etc/passwd.conf etc
# cp /usr/libexec/ld.elf_so /usr/libexec/ld.so /usr/pkg/libexec/sftp-server libexec
# cp -rf /etc/ssh pkg/etc
The ksh (my root default shell), date and passwd binaries are needed to set up the environment
and those can be deleted later.
The localtime timezone file is needed to keep the same time zone as the “box”.
In /etc/ssh is where my ssh stuff is and it is usually located in /usr/pkg/etc/ssh.
Next we create the needed device files
# cd /opt/chroot/sshd/dev
# /dev/MAKEDEV std pty0 tty random
We need some share libraries as well.
If u use static linked binaries then u should not need those or at least some of them.
Using ldd and awk is quite easy to get all of them inside the chrooted environment.
# cd /opt/chroot/sshd/
# cp `ldd bin/* sbin/* | awk '{print $3}'` lib
*) Setting up the user(s)
In my example, I set up only one user and the same procedure can be used to set up all users u need.
First, we modify the group file inside the chroot.
Be aware of the slashes now!
# cd /opt/chroot/sshd/etc
# vi group
My group file is as follows:
wheel:*:0:tonyex
sshd:*:16:
staff:*:20:scpuser
nobody:*:39:
I added a user called scpuser to the group staff and removed everything that was useless.
This user has write access only to the following folders inside the chroot: tmp and home/scpuser.
The next step is edit the master.passwd file (inside the chroot).
# cd /opt/chroot/sshd/etc
# vi master.passwd
My master.passwd file become this short.
sshd:*:16:16:& pseudo-user:/var/chroot/sshd:/sbin/nologin
nobody:*:32767:39:Unprivileged user:/nonexistent:/sbin/nologin
scpuser:*:2003:100:test:/home/scpuser:/bin/scponly
Everytime we modify the master.passwd file, we need to recreate the db files. We can use these commands:
# cd /opt/chroot/sshd/
# sbin/pwd_mkdb -d /opt/chroot/sshd etc/master.passwd
# sbin/pwd_mkdb -d /opt/chroot/sshd -p etc/master.passwd
The scpuser is configured. Now we create his home folder.
# cd /opt/chroot/sshd/home
# mkdir –p scpuser
# chown 2003:sshd scpuser
We use numeric IDs to setup permissions, as user/group names may not exist in our "real" system.
I use “PubkeyAuthentication” in my setup so see Appendix A , if u are interested in this matter.
A password base configuration is discussed as well in the following topic.
*) Setting up the initial passwords
Before we can continue, we have to make sure that the chroot environment has everything we need,
so we try to change the user password inside the chroot.
In my real live box, this step is not needed as I use a very different configuration of the sshd daemon.
See Appendix A.
# cd /opt/chroot/sshd/
# passwd scpuser
Changing local password for scpuser.
New password: *********
Retype new password: *********
# exit
At this time u can delete the not needed binaries :
# cd /opt/chroot/sshd
# rm bin/passwd
# rm bin/ksh
# rm bin/date
Note: If any users has to be added afterwards, then "passwd" and "ksh" has to be temporary copied back
to the chroot environment to accomplish the set up tasks for the new users.
*) Setting up the SSHD server
We need to make sure the chrooted ssh daemon does not conflict with any other SSHD server in the same machine,
so we will set it up. The first step is to generate some new keys (or copy the ones you already have):
# cd /opt/chroot/sshd/pkg/etc/ssh/
# /usr/pkg/bin/ssh-keygen -t rsa1 -b 1024 -f ssh_host_key -N ''
# /usr/pkg/bin/ssh-keygen -t dsa -f ssh_host_dsa_key -N ''
# /usr/pkg/bin/ssh-keygen -t rsa -f ssh_host_rsa_key -N ''
To start the chrooted sshd server, if u have another sshd server already running in the same machine,
u have to choose another port than the 22 ( the default port of the ssh daemon).
To accomplish that edit the sshd_config and edit the following line:
“Port 22” and change the 22 to anything else up to 65535:
*) Starting the sshd server
At this point everything is ready to start the ssh daemon and it is done with the following command:
# chroot /opt/chroot/sshd /sbin/sshd
Add this line to your startup scripts if you want it to be started at system bootup.
*) Set up syslogd to log from the chrooted sshd server
It is very important to know how our chrooted sshd server is doing inside the chroot.
To syslog to the /var/log/authlog ( the default log file for the sshd server)
we configure the syslogd_flags in the /etc/defaults/rc.conf file.
# vi /etc/defaults/rc.conf
And add/modify this line:
syslogd=YES syslogd_flags="-p /var/run/log -p /opt/chroot/sshd/var/run/log -s" # -s "secure" unix domain only
And then restart the syslogd daemon a la rc.d way.
# /etc/rc.d/syslogd restart
*) Client configuration
The client configuration part is up to U.
I use the scp command that comes with the openssh suite.
A good free scp client for Windows is WinSCP (http://winscp.net).
*) The folder/file structure
This is how my chrooted folder/file structure looks like.
Remember that the soft-linked pkg/etc acts like usr/pkg/etc.
The dev folder is omitted, so don't panic if you don't see it.
bin
bin/scponly
bin/groups
bin/pwd
bin/ls
etc
etc/passwd.conf
etc/group
etc/master.passwd
etc/spwd.db
etc/passwd
etc/pwd.db
etc/localtime
home
home/scpuser
home/scpuser/.ssh
home/scpuser/.ssh/authorized_keys
lib
lib/libcrypt.so.0
lib/libutil.so.7
lib/libskey.so.1
lib/libcrypto.so.0.9.7
lib/libc.so.12
lib/libwrap.so.0
lib/libtermcap.so.0
lib/libedit.so.2
lib/libroken.so.12
lib/libcom_err.so.4
lib/libasn1.so.6
lib/libcrypto.so.2
lib/libkrb5.so.19
lib/libz.so.0
libexec
libexec/ld.so
libexec/ld.elf_so
libexec/sftp-server
sbin
sbin/sshd
sbin/nologin
sbin/pwd_mkdb
tmp
var
var/run
var/run/sshd.pid
var/run/log
var/run/utmpx
var/chroot
var/chroot/sshd
pkg
pkg/etc
pkg/etc/ssh
pkg/etc/ssh/moduli
pkg/etc/ssh/ssh_known_hosts
pkg/etc/ssh/ssh_config
pkg/etc/ssh/sshd_config
pkg/etc/ssh/ssh_host_key.pub
pkg/etc/ssh/ssh_host_dsa_key
pkg/etc/ssh/ssh_host_dsa_key.pub
pkg/etc/ssh/ssh_host_rsa_key
pkg/etc/ssh/ssh_host_rsa_key.pub
pkg/etc/ssh/ssh_host_key
*) Apendix A
In my “real life” setup, there is not need for passwords.
My sshd server is configured to use only private/public keys and this enhance the security to a higher level.
More reading about this can be found here: http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config
Now back to this howto
After we configured the scpuser home folder with the following commmands
# cd /opt/chroot/sshd/home
# mkdir –p scpuser
# chown 2003:sshd scpuser
We generate a key pair and copy there a public key to the needed place.
For more information about key generation see this page: http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-keygen
Some of the line of interest of my sshd_config are:
….
LogLevel DEBUG
……
LoginGraceTime 600
PermitRootLogin no
…..
AuthorizedKeysFile .ssh/authorized_keys
……
PasswordAuthentication no
….
So basically we have to match the line “AuthorizedKeysFile .ssh/authorized_keys”.
This can be done by copying the public key to .ssh/authorized_keys and setting up the permissions.
# cd /opt/chroot/sshd/home/scpuser
# mkdir .ssh
# chown 2003:16 .ssh
# cd .ssh
# cp ‘location of the public key’ authorized_keys
# chown 2003:16 authorized_keys; chmod 400 authorized_keys
And the user scpuser can login into the chrooted sshd server with his/her private key
(often secured with a password as well) instead of just a password.
Sugestions? mail them to tonyex@yahoo.com