I will on this page give some information on how I set up a CVS server to be used on my local LAN. The server is placed behind the firewall and is not supposed to be accessible outside of my own LAN. Due to this I can relax the security bit a little
My main objective of this server is to store my coding, mostly C and Perl programs, but also to use it when making home pages.
The following explains how I set up the server on a RedHat 7.3 system. It is not intended for a newcomers, as I do not go into detail on several things. I might add this information later on.
To be able to set up a server you need the following packages:
The xinetd-package is not needed if you do not intend to access the CVS repository over your LAN, i.e. if you set up the repository on your local machine.
/home/cvsroot but you may chose whatever directory
you like.
/sbin/nologin,
/dev/null, or /bin/false will do.
cvs -d /home/cvsroot
init This will initialize your repository by creating the
CVSROOT directory and the files therein.
chown -R
cvs. /home/cvsroot
/etc/services/
cvspserver 2401/tcp # CVS client/server operations cvspserver 2401/udp # CVS client/server operations(I am not sure if the UDP-line really is necessary.) You then have to make sure that your xinetd server knows how to deal with incoming connections to port 2401. I.e. put the following code into
/etc/xinetd.d/cvspserver
service cvspserver
{
disable = no
socket_type = stream
protocol = tcp
wait = no
user = cvs
server = /usr/bin/cvs
server_args = -f --allow-root=/home/cvsroot pserver
# Only bind on interfaces on the local LAN, and only allow local connects
bind = 192.168.0.5 127.0.0.1
only_from = 192.168.0.0 127.0.0.1
}
Restart the xinetd server by typing
/etc/rc.d/init.d/xinetd reload
/home/cvsroot/CVSROOT/passwd
This file contains a list of users, their passwords, and an
optional mapped user name. It looks like this:
anonymous::cvs lars:xhfdncuej:cvs(no, the password is not a real one :-) Both anonymous and lars are here mapped to the local user cvs. I wrote a quick and dirty (?) program to calculate the password, here it goes
/*
* This program was written to get passwords to put in a cvs password
* file. Simply use "./crypt clear_text_password" to get the crypt'ed
* equivalent of the clear_text_password. The returned value should be
* put in the cvs password file.
*
* Compile with:
*
* gcc -O2 -Wall -o crypt -lcrypt crypt.c
*
*
* Written March 3, 2003 by Lars E. Pettersson
*
*/
#include <unistd.h>
#include <stdio.h>
char *version = "Version: March 6, 2003";
int main(int argc, char *argv[]) {
char *salt = "xY";
if (argc == 2) {
printf("%s => %s\n", argv[1], crypt(argv[1], salt));
return 0;
}
printf("\n%s\n\nThis program was written to get passwords to put in a cv
s password\nfile. The program returns the password after running the crypt()\nfu
nction on the argument given. The returned value should be put into\nthe cvs pas
sword file.\n\nUsage: %s [clear_text_password]\n\n", version, argv[0]);
return -1;
}
/home/cvsroot/CVSROOT/readers file. It is now time
to access the repository. In an arbitrary directory write
cvs -d :pserver:lars@server:/home/cvsroot co
CVSROOT (where server is the host-name of the server.)
After you have given the password the files in
/home/cvsroot/CVSROOT will be copied to the
directory CVSROOT in your directory. Go down into this directory
and create a file named reader with the following content
anonymousNow issue the command
cvs add reader to put
the file in queue to be added to the repository. And then
cvs commit reader to add it to the repository. An
editor will be opened and you are then supposed to write a short
comment, something like reader added to repository
would suffice.
-d
:pserver:lars@server:/home/cvsroot all the time. To get
rid of this we can put this into the environment variable
CVSROOT. I choose to add a file to the
/etc/profile.d/ directory named cvs.sh
The file on the server machine contains
export EDITOR=/usr/bin/emacs export CVSROOT=/home/cvsrootand on the clients
export EDITOR=/usr/bin/emacs export CVSROOT=:pserver:$USER@server:/home/cvsrootThe file should be executable. This could of course be overridden by the local users own profile-files.
/home/cvsroot/CVSROOT/cvswrappers file. Go down to
the CVSROOT directory you fetched earlier. Edit the
cvswrappers to contain something like this
# This file affects handling of files based on their names. # # The -t/-f options allow one to treat directories of files # as a single file, or to transform a file in other ways on # its way in and out of CVS. # # The -m option specifies whether CVS attempts to merge files. # # The -k option specifies keyword expansion (e.g. -kb for binary). # # Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) # # wildcard [option value][option value]... # # where option is one of # -f from cvs filter value: path to filter # -t to cvs filter value: path to filter # -m update methodology value: MERGE or COPY # -k expansion mode value: b, o, kkv, &c # # and value is a single-quote delimited value. # For example: #*.gif -k 'b' # # NOTE: This file is case sensative!!! # *.[aA][vV][iI] -k 'b' *.[bB][mM][pP] -k 'b' *.[bB][zZ]2 -k 'b' *.[dD][oO][cC] -k 'b' *.[eE][xX][eE] -k 'b' *.[eE][pP][sS] -k 'b' *.[gG][iI][fF] -k 'b' *.[gG][zZ] -k 'b' *.[hH][qQ][xX] -k 'b' *.[jJ][aA][rR] -k 'b' *.[jJ][pP][eE][gG] -k 'b' *.[jJ][pP][gG] -k 'b' *.[mM][oO][vV] -k 'b' *.[mM][pP][gG] -k 'b' *.o -k 'b' *.[pP][dD][fF] -k 'b' *.[pP][nN][gG] -k 'b' *.[pP][pP][tT] -k 'b' *.[pP][sS] -k 'b' *.[sS][iI][tT] -k 'b' *.[sS][oO] -k 'b' *.[sS][wS][fF] -k 'b' *.[tT][aA][rR] -k 'b' *.[tT][gG][zZ] -k 'b' *.[tT][iI][fF] -k 'b' *.[tT][iI][fF][fF] -k 'b' *.[xX][bB][mM] -k 'b' *.[xX][lL][sS] -k 'b' *.Z -k 'b' *.[zZ][iI][pP] -k 'b'As you see the cvswrappers file is case sensitive, so you must take care of all permutations of case.
A very good introduction is the manual that comes with the source, written by Per Cederqvist et. el. Print it out (182 pages, ouch!) and read it, you will learn a lot, so it is time well spent.
We can connect to our repository using a SSH tunnel. This can be
done by issuing the command ssh -L 2401:localhost:2401 -N -f
-g -q -x lars@server.some.org on the client machine. We can
now access the repository by using cvs -d
:pserver:lars@localhost:/home/cvsroot login and cvs
-d :pserver:lars@localhost:/home/cvsroot co module on the
client. We may also set the CVSROOT environment variable to
:pserver:lars@localhost:/home/cvsroot if this is the
preferred repository.
Another, perhaps simpler, way, is the following. Set the
environment variable CVS_RSH to ssh. You may now access the
repository by issuing the command cvs -d
:ext:lars@localhost:/home/cvsroot co module
I have no idea on which of these two are the best, but the latter setup seems simpler. In both versions you need an account on the machine running the cvs server. In the first version the user and group will be determined by how we set up xinetd, in the second version the user and group will be that of the user logging in on the machine. This might be good to know if you have an automatic update of a home page etc. from loginfo.
If you want to make a more secure installation of CVS a chroot variant might be a good choice. Information about this can be found at many places, some that I found interesting where
If the web server and the cvs repository is on the same computer,
one can easily set up cvs to automatically update the web server.
To do this checkout the CVSROOT repository, and edit the
loginfo file. Add the line (all in one line)
^homepage (date; cat; (sleep 2; cd /var/www/html/homepage; cvs -q update -d) &) >> /home/cvsroot/CVSROOT/updatelog 2>&1
where homepage is the name of the cvs repository, and
/var/www/html/homepage is the directory to put the
home page in on the web server. Each time you make a
commit command the web page will be updated and a
logging message will be appended to the updatelog
file.