http://www.unixtools.org/cvs/server-how-to.html 020311



CVS Server Setup and Info


These instructions and sample code allow you to quickly and easily set up a fairly secure CVS server that allows both anonymous read-only access and read-write access for a group of developers. I put together this code and these instructions because I wasn't satisfied with the standard way of setting up a server. It just had too many flaws, particularly if you (root) don't trust the person who's repository you're setting up.

These instructions are designed to set up a "remote only" repository. The owner user should be able to use it locally, but it's recommended that all users access it through the pserver method. They also assume a tightly-knit group of developers, all of which the owner trusts. I have some changes that can be made to this list of instructions if you want to have slightly less trust of the developers, but this is intended to be easy to set up and reasonably secure.

These instructions are based on installing on a Redhat 5.2 x86 linux system. They should be relatively easy to adapt to any other architecture.

At this time, the example below will only work for a single installation of this facility per machine. With some small changes, that can be reduced to a single installation per IP. With some work, it should be possible to eliminate that requirement, but it won't be immediately straightforward. (It would involve intercepting the "repository path" sent by the client and handling the request accordingly. If anyone is interested in this, send me a note.)

As a note, I'd really like to see this sort of functionality integrated into the CVS package in some fashion, as the current server doesn't really appear suited to run on general use machines w/ untrusted users.

Before you can get started, you need to decide who the owner user will be. This is the user that will own the repository and the chroot area. This example assumes that the owner userid is 'cvsowner', and that it's home directory is '/users/cvsowner' who's UID is 6000 and GID is 1000.


Steps performed as the owner user

  1. Create the following directory structure:
    /users/cvsowner/cvs-server-root/cvsroot-projectname
    /users/cvsowner/cvs-server-root/etc
    /users/cvsowner/cvs-server-root/bin
    /users/cvsowner/cvs-server-root/lib
    /users/cvsowner/cvs-server-root/tmp
    /users/cvsowner/cvs-server-root/dev
    
  2. From this point on, BASE refers to "/users/cvsowner/cvs-server-root".
  3. The "cvsroot-projectname" directory will be the CVS repository for a particular project/group of developers. Create it with cvs init.
  4. Compile a copy of cvs (I did mine static.) copy a few more files into lib later on, most likely libcrypt.so.)
  5. Copy the cvs binary into the 'BASE/bin' directory.
  6. Create 'BASE/dev/null' by issuing 'mknod BASE/dev/null c 1 3' (You'll likely have to have root do this for you.)
  7. Copy the 'ld-linux.so.2', 'libc.so.6', 'libcrypt.so.1' and 'libnss_files.so.1' libraries to the 'BASE/lib' directory.
  8. Create a minimal password file in 'BASE/etc'. OWNERUID and OWNERGID are the UID and GID of the 'cvsowner' account. The password for the cvs account is 'cvs'.
    cvsowner:*:6000:1000:::
    cvs:hlAmN0pdL98yo:6000:1000:::
    
  9. Add any other users you want to that passwd file. (Put the actual crypt string instead of '*' obviously'. Give them all the same UID and GID as the owner userid.
  10. Create your repository (you can have as many as you want.)
  11. Create the file 'writers' in the CVSROOT subdirectory of the repository. It's probably a good idea to use the usual checkout and commit to create this, but it will work either way. List in this file the userids that you want to have write access to this particular repository. NOTE - any user that has write access to a repository can potentially destroy it, so you should have some degree of trust established.
  12. If you did any of the above as root, make sure the permissions of all the files and directories under BASE are mode 600 or mode 700. (If you wish, you can make them 644 or 755, but it's better to close it down.)
  13. At this point, the rest of the process needs to be done by root.

Steps performed as 'root'

  1. Compile this program, and install it in a secure location. By secure I mean somewhere that a non-root user won't be able to write to it. This example assumes you install it as "/usr/sbin/run-cvs".
  2. That example is a very minimal program assuming you are only going to be running this one installation. It will need to be more complex for more complicated installations. You'll need to add an 'allow-root' line for each repository you create.
  3. Add this line to your inetd.conf file:
    2401 stream tcp nowait root /usr/sbin/run-cvs run-cvs
    
  4. You are now set to go.