cvsd - chroot wrapper to run `cvs pserver' more securely. cvsd was originally written by Chris Black , http://cblack.mokey.com/. That was until release 0.6. cvsd versions up till 0.8b3 were maintained by Philippe Kehl , http://guv.ethz.ch/~flip/cvsd/, http://www.oinkzwurgl.org/software/cvsd/. after that Arthur de Jong took up the work and did a complete rewrite, http://ch.tudelft.nl/~arthur/cvsd. Copyright (C) 1999 Chris Black. Copyright (C) 2000 Philippe Kehl. Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Arthur de Jong. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA INTRODUCTION ============ cvsd is a wrapper program for cvs in pserver mode. it will run 'cvs pserver' under a special uid/gid in a chroot jail. cvsd is run as a daemon and is controlled through a configuration file. It is relatively easy to configure and provides tools for easy setting up a chroot jail. This server can be useful if you want to run a public cvs pserver. You should however be aware of the security limitations of running a cvs pserver. If you want any kind of authentication you should really consider using secure shell as a secure authentication mechanism and transport. Passwords used in cvs pserver are transmitted in plaintext. This wrapper adds a layer of security to the cvs server. cvs is a very powerful tool and is capable of running scripts and other things. Running cvs in a chroot jail it is possible to limit the amount of "damage" cvs can do if it is exploited. It is generally a good idea to run cvsd without any write permissions to any directory on the system. Features of cvsd include: * running in chroot jail * configuring chroot jail * running under a non-root uid * set a nice value * limit resource usage * limit number of connections * relatively easy to set up INSTALLING CVSD =============== In short: % ./configure % make % make install You can add '--sysconfdir=/etc', '--prefix', '--enable-warnings' and/or '--enable-debug' options to configure to tune installation. Debugging is only recommended for finding bugs. cvsd is developed on a Debian GNU/Linux system and should work fine on most GNU/Linux systems. The code is supposed to be portable but is not regularly tested on other platforms. cvsd is known to work on Solaris, FreeBSD, OpenBSD and others. tcp wrappers ------------ cvsd currently has experimental support for tcp wrappers. Use './configure --with-libwrap' to enable support. Most versions of the tcp wrapper libraries have issues with systems supporting IPv6, see the FAQ. Using this option will have a slight performance hit on the number of connections that can be handled per minute. For each incoming connection the tcp wrapper reads the configuration files and does a name lookup. This is done inside the main loop before the child is forked.. Also note that you have to edit the hosts.allow and hosts.deny files INSIDE the chroot jail since the tcp wrapper libraries reread these files for every connection. CONFIGURING CVSD ================ cvsd is controlled through a configuration file in /etc/cvsd/cvsd.conf (or maybe /usr/local/etc/cvsd/cvsd.conf depending where you set --prefix to with configure). The default configuration file is fully commented and has a manual page (cvsd.conf(5)) which documents use of the configuration file. very quick setup guide ---------------------- The is just a series of commands to set up cvsd in a typical read-only setup. If you don't understand these steps or are looking for commands that work on your system you should look below for further details. # addgroup --system cvsd (or groupadd) # adduser --system --ingroup cvsd --home /var/lib/cvsd \ --shell /bin/false --gecos 'cvs pserver daemon' cvsd # cvsd-buildroot /var/lib/cvsd # cvs -d /var/lib/cvsd/myrepos init # cvsd-passwd /var/lib/cvsd/myrepos +anonymous # touch /var/lib/cvsd/myrepos/CVSROOT/writers edit /var/lib/cvsd/myrepos/CVSROOT/config add "SystemAuth=no" add "PamAuth=no" (on systems that have this option) add "LockDir=/tmp/myrepos" # mkdir /var/lib/cvsd/tmp/myrepos # chown cvsd:cvsd /var/lib/cvsd/tmp/myrepos edit /etc/cvsd/cvsd.conf set "RootJail /var/lib/cvsd" set "Repos /myrepos" You should now be able to continue with the section "checking the configuration" below. setting up the user and group ----------------------------- You should setup a user and group under which cvsd is run. Adding users to the system is different on most platforms but this should work for most systems: # addgroup cvsd # adduser --system --ingroup cvsd --home /var/lib/cvsd \ --shell /bin/false --gecos 'cvs pserver daemon' cvsd or maybe (or some other variation depending on your system): # groupadd cvsd # useradd -r -M -d /var/lib/cvsd -s /bin/false \ -c "cvs pserver daemon" -g cvsd cvsd (replace /var/lib/cvsd with the place where your chrooted file system is located) setting up a chroot jail ------------------------ You can populate a chrooted file system with cvsd-buildroot. You should rerun this script if your cvs binary changes or the libraries that it depends upon. The place where you create the chroot file system should be specified in the configuration file as the 'RootJail'. It is possible (but not advisable) to run cvsd without a chrooted file system. If you plan to run stuff like the scripts from the contrib/ subdirectory in cvs, then you have to have all necessary binaries, libraries etc. etc. in the chrooted file system. You can just put the needed binaries in the 'bin' directory of the chroot jail and 'cvsd-buildroot' will install the needed libraries. Please note that this may require manual reconfiguring. Some systems may require extra libraries to be present in the chrooted file system than can not be automatically detected (using ldd). See the FAQ for details. disabling inetd pserver ----------------------- If inetd is configured to start cvs /etc/inetd.conf should contain a line like this: cvspserver stream tcp nowait root /usr/bin/cvs --allow-root /home/cvs You should remove or comment out this line or tell cvsd to listen on a different port (use Listen option in cvsd.conf). If you change inetd.conf you should tell inetd to reload it's configuration by: # kill -s HUP setting up a repository ----------------------- If you have configured the chroot jail and the user and group id bits you can start adding repositories to the chroot jail. There are a couple of ways you could do that. The first is creating an empty repository with something like: # cvs -d /var/lib/cvsd/myrepos init (where /var/lib/cvsd is the location of the chroot jail and myrepos is the name of the new repository) Another way is copying an already existing repository to the chroot jail. It is also possible to do something smart with a tool like 'rsync'. Put this in a cronjob for extra effect. Symbolic linking a repository to the chroot jail is not possible since symlinks will be evaluated within the chroot jail. Hardlinking directories should be avoided (hardlinking in general in my opinion). With Linux 2.4 (and probably other systems) it is possible to remount an existing directory within another directory. You can use mount: # mount --bind /home/user/develrepos /var/lib/cvsd/userrepos or add something like this to /etc/fstab: /home/user/develrepos /var/lib/cvsd/userrepos none bind 0 0 (don't forget to create the /var/lib/cvsd/userrepos directory) After you have created or copied a repository into the chroot jail you should add it to the cvsd.conf configuration file so cvs can access it. Use the 'Repos' option for this and remember to specify it relative to the chroot jail. So if your repository is /var/lib/cvsd/myrepos you should add 'Repos /myrepos' to the configuration file. The last step for making your repository accessible is to add a passwd file to the 'CVSROOT' directory of the repository. The cvsd-passwd tool will do this for you. cvsd-passwd /var/lib/cvsd/myrepos anonymous This will add user 'anonymous' to the list of users that can access the repository. You will be prompted for a password which can optionally be blank. Note that the cvsd user needs to have the correct permissions to the repository. The cvsd user probably should have read access to the repository but probably no write permission. You can add all users in the repository passwd file to a file named 'readers' in the 'CVSROOT' directory or create an empty 'writers' file. Without any of these files all users have write access! If you set up your repository so that the cvsd user only has read access to the files and directories in the repository (through unix file permissions) you need to take some extra provisions since cvs creates lockfiles when checking out files from the repository. The best way to do this is to create a directory for the cvsd user to write the lockfiles to (e.g. /var/lib/cvsd/tmp/myrepos) and add "LockDir=/tmp/myrepos" to the /var/lib/cvsd/myrepos/CVSROOT/config file. Be sure to create the directory and make it writable for the cvsd user. If your cvsd user has write access to the repository this should be no problem. It is also a good idea to put "SystemAuth=no" and maybe "PamAuth=no" in your CVSROOT/config file. This way password lookups will only be done to CVSROOT/config and not to /etc/passwd inside the chroot jail (that passwd file shouldn't contain any passwords) or PAM. See the "Password authentication server" section in the cvs texinfo document for more information about running a pserver and setting up repositories. CHECKING THE CONFIGURATION ========================== If you have started cvsd with the provided init script: # /etc/init.d/cvsd start (or /usr/local/etc/init.d/cvsd start) and configured a repository (say myrepos) you should be able to access the server with something like: % cvs -d :pserver:anonymous@localhost:/myrepos login % cvs -d :pserver:anonymous@localhost:/myrepos checkout . For troubleshooting information see the FAQ on debugging. REPORTING BUGS ============== If you find any bugs or missing features please send email to arthur@ch.tudelft.nl Please include as much information as needed (platform, output of configure if compilation fails, output of the failure, etc). Most of the configuration information can be provided by running cvsd-buginfo. Patches are more than welcome.