The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

CVS сервер с шифорванием и в chroot окружении (англ.) (chroot cvs)

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: chroot, cvs,  (найти похожие документы)
From: Anton Berezin <> Date: Mon, 9 Dec 2003 14:31:37 +0000 (UTC) Subject: CVS сервер с шифорванием и в chroot окружении (англ.) Chrooted tunnelled read-write CVS server Note 20 April 2000 I have been working on a much-improved version of scvs program, called tcvs, which is in fact a full-fledged many-to-many cvs proxy. As soon as I finish writing tcvs (and I unfortunately do not have time for this project until July 2000), I will rewrite this HOWTO. I will also write another version of this document, tailored for some Linux distribution. Abstract This HOWTO describes the steps necessary to setup a very network-secure CVS server, allowing anonymous read-only repository access as well as read-write access for a relatively trusted group of developers. It is not necessary for these developers to have shell accounts on the server box. The setup described here uses the combination of two well-established techniques, namely running CVS pserver in a chroot jail, and only allowing access to the server from the localhost itself, through a SSH tunnel. ThisHOWTO was written with the assumption that the server will operate on FreeBSD. Acknowledgements ------------------ Vadim Belman <>, Dmitry Karasik <>, John Polstra <>, and Phil Regnauld <> read the draft version of this HOWTO and made useful suggestions and corrections, both factual and stylistic. Background ------------ CVS ( is the most popular version control system in the free software community, used by Netscape, *BSD, many Linux projects, and others. Initially, CVS was designed to provide version control for a group of developers working on a single machine. There was a CVS repository somewhere on the file system, and every developer working on a project had to have a read-write access to the repository files, including auxiliary files used by cvs program itself. With the advent of the Internet the need for accessing remote repositories arose. Currently, CVS has several methods of doing this: * :ext: and :server: methods. These ( access methods make use of a remote shell rsh or (:ext: method only) a replacement, such as the secure shell (SSH). The developer accessing the repository using this method must have a shell account on the machine where the repository is located. * :pserver: method. This ( access method allows a direct client connection to the server using password authentication. The inetd ( daemon on the server machine starts the command cvs pserver when it receives a TCP connection on a specific port (usually port 2401). All communication between the client and the server goes using the CVS ( protocol. This method does not require every developer to have an account on the server box, but no communication over the network is encrypted, including passwords which are sent as cleartext (well, almost). * :gserver: and :kserver: methods. These methods allow secure direct client connection. The :gserver: ( uses GSSAPI, the generic interface to network security systems such as Kerberos 5. The :kserver: ( methods uses the Kerberos version 4 network security system. The :pserver: method is quite convenient for implementing remotely accessible CVS repositories, but its major drawback is that it is very insecure. Two ways to increase the security of :pserver: are suggested: * Running CVS server in chrooted jail. One of the main problems with cvs pserver is the fact that the developer accessing the repository can in fact gain an access to any file on the server system. This situation gets worse if the developer has read-write access to the repository; in this case it is possible that he/she will have the ability to write any file owned be the user the pserver runs as. But anyway, even read access to your system can be bad enough! The standard solution for this type of services is to use an intermediate program that first carries out a chroot(2) ( UNIX syscall, then changes its own credentials to those of some unpriviledged user, and execs ( cvs pserver. A method implementing this technique to set up a CVS server is described here. ( * Using SSH tunnelling feature. The second major problem with the cvs pserver is that all data transferred during the CVS remote session is unencrypted. The :gserver: and :kserver: access methods do not have this problem, if setup properly. However, I do not consider them here --- this HOWTO is only concerned with :pserver: access method. Luckily, the popular secure replacement of rsh, ssh, ( has a feature called TCP port forwarding, also known as tunnelling. The idea is that ssh client allocates a socket listening to the specified port on the local machine, and any connection made to this local port (normally from localhost) is automatically forwarded to the remote side over an encrypted channel. If you have never used this feature but you are a user of ssh, chances are that you have used it anyway without knowing it --- ssh, in its most typical configuration, automatically forwards all X11 connections this way. The combination of these two techniques is the subject of this HOWTO. Rationale ----------- When I installed CVS repository for PRIMA project, I tried to find a kind of tutorial about how to set up a fairly secure CVS server allowing the remote access to the repository without giving away the accounts on the CVS box. The second requirement was to allow the developers from Windows NT machines to access the repository. Since I was not able to find such a tutorial, I decided to write it myself. So this HOWTO is in fact the by-product of that installation. Requirements for the server ----------------------------- This HOWTO assumes that the server will run FreeBSD version 3.3 or later. It does not mean, of course, that it is not possible to setup similarly configured server on a UNIX box running different operating system. It simply means that the exact steps below are for FreeBSD. The computer should: * be connected to the Internet; * have operational C compiler with standard libraries; * have sshd up and running; * have recent enough version of cvs installed (1.10 will suffice); * ideally be running or able to run a firewall software. Requirements for the client ----------------------------- Any UNIX or Windows NT machine with the Internet connection that has: * cvs installed; * ssh installed; * Perl ( 5 interpreter installed. Requirements for the administrator ------------------------------------ The administrator should: * have root privileges on the server machine; * have basic understanding of CVS workings; * be able to tweak hard-coded paths and host names in C and Perl code; * be able to compile and install C programs. The instructions below are fairly detailed to allow even very inexperienced sysadmin to setup the server. Server setup -------------- 1. Add cvs user and group. Since CVS server will not run as root, we need to create a special cvs user. I use UID 287, username cvs, and GID 287, groupname cvs. Of course you are free to use any UID you like, but remember that using existing real or system UIDs and GIDs is generally a bad idea. Needless to say that this operation must be performed as root. To add new robotic users I find it easier to use vipw(8) ( directly; in vipw editor, add the following line: cvs:*:287:287::0:0:CVS account:/usr/local/site/cvsroot:/sbin/nologin Of course, you might choose a different home directory for the cvs user. Also note, that ``password disabled'' star and /sbin/nologin shell are here temporarily. Subsequently, they will be replaced with ``no password'' void and a special ``sleeping beauty'' shell, written by Tim ( TimeWaster. Edit /etc/group file using your favorite text editor, and add the following line: cvs:*:287: 2. Create repository directory structure. + First, create cvs user home directory, if you have not created it already: mkdir -p /usr/local/site/cvsroot chown cvs.cvs /usr/local/site/cvsroot chmod 700 /usr/local/site/cvsroot If you would like to have less restricted permissions for the cvs user home directory, do so. The CVS server will be chroot'd right into cvs user home directory. It is trivial to modify the steps below if you would like to make a jail in a subdirectory of the home directory. + Next, create subdirectories necessary for the proper jail functioning: cd /usr/local/site/cvsroot mkdir bin dev etc tmp chown cvs.cvs bin dev etc tmp chmod 555 bin dev etc 3. Create CVS repository. For a project called projectname, create a repository in a usual ( way, as follows. cvs -d /usr/local/site/cvsroot/projectname init chown -R cvs.cvs projectname If you plan to serve several distinct repositories, repeat this step as necessary. 4. Create a null device in dev. cd dev mknod null c 2 2 chown 0.0 null chmod 666 null cd .. 5. Compile static version of cvs program. Ideally, you should have the complete sources of your FreeBSD system installed, since this makes this process so much easier. If it is not an option for you, do this step in some other way. Before proceeding, you will need to change just one line of CVS sources. The trouble is, that for some unknown reason, FreeBSD library function initgroups(3), ( which uses syscall setgroups(2) ( internally, likes to spit out error messages on stderr in case of trouble. CVS server uses initgroups(3) ( unconditionally, though it should better not do it in our setup. We will edit server.c file: cd /usr/src/contrib/cvs/src vi server.c - Find the line "initgroups (pw->pw_name, pw->pw_gid);" - and comment it out: /* initgroups (pw->pw_name, pw->pw_gid); */ - Save the file. - Now compile and install the cvs program: cd /usr/src/gnu/usr.bin/cvs make NOSHARED=yes cp /usr/obj/usr/src/gnu/usr.bin/cvs/cvs/cvs /usr/local/site/cvsroot/bin cd /usr/local/site/cvsroot chown cvs.cvs bin/cvs chmod 500 bin/cvs 6. Create fake passwd and group files. We need some passwd and group files in /usr/local/site/cvsroot/etc directory. cd etc vi master.passwd Note the absence of '/' above. Add the line cvs::287:287::0:0:CVS account:/:/bin/cvs The shell line can be anything, but it is better if nobody including cvs program itself can write to it. Save the file. vi group Add the line cvs:*:287: Save the file. Now run pwd_mkdb -d . master.passwd cd .. 7. Create passwd and writers files. The actual access control is done by CVS itself. In order to make use of this, we need to create passwd and writers files in the CVSROOT directory in every CVS repository we are serving. There are two ways of doing this for writers file, and I will show them both. Only the first method is working for passwd file due to possible security issues. + Manual creation. cd projectname/CVSROOT vi passwd If you are planning to provide anonymous read-only access to the projectname repository, add the following line: cvs::cvs For every non-anonymous developer add the line of the form: developerusername:encryptedpassword:cvs Where encryptedpassword is obtained from the cleartext password (which either yourself or a particular developer has chosen) with the standard system crypt(3) ( function. If you do not know how to obtain encrypted version of a password yourself, download this program (, and compile it: cd directory/with/ppw.c cc -o ppw ppw.c -lcrypt It is important that you compile and run this program on the very same machine on which CVS server will be installed. Launch this program as ./ppw md5 if your system passwords are MD5-based. If you have DES passwords, launch it as ./ppw des. If you have some other password system, you are on your own at this step. If you don't know what kind of passwords your local crypt(3) function supports, you might want to have a look at the /etc/master.passwd file. If the password field for user accounts starts with $1$, you have MD5-based passwords. If there is no $ sign at the beginning of the password field, you have DES passwords. Otherwise, you have something else. Save the passwd file. cd /usr/local/site/cvsroot/projectname/CVSROOT vi writers Add the line of the form developerusername for every developer who will have the write access to the projectname repository. Save the file. Do not forget to chown the passwd and writers files to cvs.cvs. + Checkout and commit. This method is better than the previous one because you save the history of changes made to writers. But you have to use manual creation method for passwd file anyway. As root, cd to some (preferably empty) directory and issue the following command: cvs -d /usr/local/site/cvsroot/projectname checkout . The current copy of the whole repository will be checked out. cd CVSROOT vi writers Add the lines to this file as described above and save the file. Issue the commands: cvs add writers cvs commit -m initial cd .. cvs -Q release -d CVSROOT rm -rf CVS Then go back to /usr/local/site/cvsroot/projectname/CVSROOT and change the owner of the files back to cvs. Note then you will not need to do it later, when the system will be fully operational --- you will simply use remote checkouts and commits instead of doing this locally as root. 8. Compile and install chroot wrapper. Download this program ( and modify it according to the instructions in the source code (this program is a modified for FreeBSD version of the wrapper suggested here). ( Compile it: cc -o run-cvs run-cvs.c Install it somewhere, make it executable, owned by root.wheel, and make sure nobody except root is able to modify the binary. I keep mine in /usr/local/site/sbin/. 9. Setup inetd. Here you will have to make an important choice. If you ever going to use ``remote'' access to repositories locally from the box where the server operates, you will need to choose a TCP port different from CVS default (2401). + Using default CVS port. Add the following line to /etc/inetd.conf file: cvspserver stream tcp nowait root /usr/local/site/sbin/run-cvs run-cvs and save the file. + Using different port. Choose the port value. I use 2410. Add the port description into /etc/services file: cvssshpserver 2410/tcp #CVS super-duper secure network server Then add the following line to /etc/inetd.conf file: cvssshpserver stream tcp nowait root /usr/local/site/sbin/run-cvs run-cvs In either case, restart the inetd daemon: kill -HUP `cat /var/run/` If for whatever reason you will have to restart inetd completely, make sure you have rather empty environment. In particular, having HOME variable set when you run inetd will hit you badly later. 10. Installing the ``sleeping beauty'' shell. Download this program ( (again, a slightly modified version of the original Tim ( TimeWaster's source). Compile it and install it somewhere. I use /usr/local/site/bin/: cc -o zzh zzh.c chown 0.0 zzh chmod 555 zzh mv zzh /usr/local/site/bin Now use vipw(8) again and change the original cvs user line to this: cvs::287:287::0:0:CVS account:/usr/local/site/cvsroot:/usr/local/site/bin/zzh The sleeping beauty shell's job is to control the SSH tunnel connection. It is there basically to prevent the nasty ``The following connections are still open'' message from SSH on the client side. 11. Preventing direct CVS server connections. The SSH tunnel will work well and good, but now we need a way to disable somehow normal CVS pserver operations. There are several ways to do it, and here I will describe two of them: + Using ipfw firewall. This method is just plain great if you are already using ipfw on the server machine. Just disable TCP connections to your run-cvs port (2401, or 2410 and 2401, see step 9) coming through external interfaces, like in this example: ipfw add 2000 deny log tcp from any to any 2401 via fxp0 ipfw add 2000 deny log tcp from any to any 2410 via fxp0 + Using TCP wrappers-enabled inetd. In recent versions of FreeBSD the inetd daemon has built-in TCP wrappers support. In even more recent versions (>= 3.3) everything is controlled by a single file, /etc/hosts.allow. Here is what you put at the beginning of this file: run-cvs : localhost : allow run-cvs : : allow run-cvs : ALL : deny Of course you have to put your real server DNS name (or IP address) there. You will have to restart inetd with -w switch in order to have TCP wrappers enabled. Also put inetd_flags="-w" into /etc/rc.conf. 12. Enabling sshd empty passwords. Since the cvs account has no password, you have to enable SSH connections with empty passwords. Put this line into your /usr/local/etc/sshd_config file: PermitEmptyPasswords yes and restart sshd: kill -HUP `cat /var/run/` 13. That's it! The server setup has been completed. Client setup -------------- UNIX client setup Download scvs Perl program ( and make modifications to it. All the tunable variables are at the top of the file, with comments. Again, this is the slightly modified version of the program developed by Tim ( TimeWaster. Do not forget to change the shebang line (#!/usr/bin/perl) if necessary. Install it somewhere in your system path. I use /usr/local/site/bin/: chown 0.0 scvs chmod 555 scvs mv scvs /usr/local/site/bin Now you a ready to go. To test the setup, run scvs -d login If everything is set correctly up, you will be presented with a prompt for developername CVS password. After entering the password, you continue to use scvs program as if it was a normal cvs command: you can checkout, update, commit files, and execute other CVS commands. Enjoy. Windows NT client setup The process is very similar to that required to setup UNIX client. There are some quirks, however; the proper setup of ssh client for Windows NT, so that connection forwarding is supported, can be non-trivial. At the very least, you should be using the most recent version of Cygwin ( Unix Compatibility toolkit. You will also have to edit scvs a bit more, since the paths will almost definitely be very different. Write me if you wish I present more detailed information here. Conclusion ------------ The method described allows to setup fairly secure CVS server. If you have any questions or suggestions, write E-mail to me using this address: Anton Berezin <>. References The Cyclic ( Software web site contains useful information about CVS, and many references to other CVS-related sources. Strangely, the online CVS manual is located elsewhere. ( The instructions on setting up chrooted ( CVS pserver (no ssh tunnelling) can be found on ( I also used Tim ( TimeWaster's page describing the setup ( of SSH tunnel for CVS pserver access (the page is a bit unclear at times, at least for my level of UNIX system administration). The FreeBSD ( project website was my source of online UNIX manual pages referenced in the text.

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий

Inferno Solutions
Hosting by

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру