Subversion + WebAuthLog
— print (last updated: Jun 18, 2009) print

Select font size:
Personalize this online document by providing values relevant to you.
  1. Replace the generic LOGIN by the actual login:
       
  2. Replace the generic MACHINE name by its actual name:
       

Installation and configuration

Install the necessary packages:
$ sudo apt-get install subversion websvn enscript
The websvn package is a great tool for viewing the revisions of a subversion project; its installation causes the package configurator to run. Take all the defaults (just hit Enter), telling it to not configure it now. We'll configure it by hand.

Create the general subversion repository directory:
$ mkdir ~/svn
The key files are in the /etc/websvn package. The suggested Apache configuration needed to run websvn is within the directory.
$ sudo cp /etc/websvn/apache.conf /etc/apache2/conf.d/websvn.conf
Edit /etc/apache2/conf.d/websvn.conf. Make this the content of the Directory element be:
<Directory /usr/share/websvn>
  DirectoryIndex index.php
  Options FollowSymLinks
  Order deny,allow
  Allow from 127.0.0.1
</Directory>
Reload Apache.

Next, we have to do several edits on the main WebSVN config file:
/etc/websvn/config.php
Start an editor for this file, and:
  1. Find the line:
    // $config->parentPath('Path/to/parent (e.g. c:\\svn)');
    
    Just below that line, create this one (uncommented):
    $config->parentPath('/home/LOGIN/svn');
    
  2. Go to the end of the this file and fix a bug! The last 6 lines look like this:
    ?>
    <?php
    if ( file_exists("/etc/websvn/svn_deb_conf.inc") ) {
      include("/etc/websvn/svn_deb_conf.inc");
    }
    ?>
    
    Remove the 3 Php "tag" lines you see, getting:
    if ( file_exists("/etc/websvn/svn_deb_conf.inc") ) {
      include("/etc/websvn/svn_deb_conf.inc");
    }
    
  3. Lastly, at the bottom of the file add these lines:
    $config->useEnscript();
    $extEnscript[".cgi"]   = "perl";
    $extEnscript[".pl"]    = "perl";
    $extEnscript[".pm"]    = "perl";
    $extEnscript[".html"]  = "html";
    
Save the changes and exit.

Initial subversion project

Create and initialize the first subversion repository for the web project called authlog.
$ svnadmin create ~/svn/authlog
Then, take a look at the WebSVN website:
http://localhost/websvn/
You should see authlog hyperlink listed as the only subversion repository. Click on this link and you should see revision 0 (Rev 0) revealed.

Revision 0 (empty)

The initial software revision is empty, but we want to "check it out" from subversion so that we obtain the configuration information needed to maintain later revisions.
$ cd ~/public_html
$ svn co file:///home/LOGIN/svn/authlog
Checked out revision 0.
Note the "///" syntax common to using the "file" protocol to specify a URL. The "Checked out revision 0" feedback confirms what we see in WebSVN. The "co" is a shortened substitution for "checkout". Then,
$ cd authlog
$ ls -a
The ".svn/" directory is the important subversion configuration directory.

Revision 1 (starters)

Open the folder ~/public_html/authlog as a Perl project in Eclipse (named authlog). Like others we have done, this project consists of:

index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>auth.log viewer</title> <script type="text/javascript" src="/javascript/jquery.js"></script> <script type="text/javascript" src="index.js"></script> </head> <body> <h3>/var/log/auth.log viewer</h3> <button id="view">View</button> Direction: <select id="dir"> <option value="R">Reverse</option> <option value="F">Forward</option> </select> <hr /> <div id="display"></div> </body> </html>

index.js
$(document).ready( function() { $("#view").click( function() { $.get( "getlog.cgi", { dir: $("#dir").val() }, function(data) { $("#display").html(data) } ) }) })

getlog.cgi
#!/usr/bin/perl use strict; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); print header; my $dir = param("dir"); print "direction=$dir"; my @loglines = split "\n", qx(cat /var/log/auth.log); @loglines = reverse @loglines if ($dir eq "R"); my @showlines = @loglines; print "<pre>"; foreach (@showlines) { print "$_\n"; } print "</pre>";
Make the CGI file executable and then test the URL:
http://localhost/~LOGIN/authlog
Once you have it working, commit it to revision 1:
$ svn add *
$ svn commit -m "initial files"
Refresh the WebSVN website. You should see revision 1 revealed with the files added.

Test the web application

The CGI script reads the lines from the log file /var/log/auth.log and prints them out, forward or reverse, and numbered. The web application can read this file because: Verify these facts:
$ ll /var/log/auth.log         (observe permissions)
$ groups                       (the groups I belong to, observe adm)
Create a new log entry by attempting an invalid ssh login to the local system:
$ ssh foo@localhost
foo@localhost's password: whatever
Permission denied, please try again.
foo@localhost's password: Ctrl-C
Immediately click the View button in the web application to reveal the log lines generated by the failed login.
   1: ... sshd[13272]: Failed password for invalid user foo ...
   2: ... sshd[13272]: pam_unix(sshd:auth): authentication failure; ...
   3: ... sshd[13272]: pam_unix(sshd:auth): check pass; user unknown
   4: ... sshd[13272]: Failed none for invalid user foo from ::1 ...

Revision 2

We're not interested so much in every line in this log file and so what we want to do is to add some filtering capabilities via a regular expression so that only special lines of interest are revealed.

Here are the new versions of the files with changes indicated:

index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>auth.log viewer</title> <script type="text/javascript" src="/javascript/jquery.js"></script> <script type="text/javascript" src="index.js"></script> </head> <body> <h3>/var/log/auth.log viewer</h3> <button id="view">View</button> Direction: <select id="dir"> <option value="R">Reverse</option> <option value="F">Forward</option> </select> Filter: <input type="text" id="filter" size="30" /> <hr /> <div id="display"></div> </body> </html>

index.js
$(document).ready( function() { $("#view").click( function() { $.get( "getlog.cgi", { dir: $("#dir").val(), filter: $('#filter').val() }, function(data) { $("#display").html(data) } ) }) })

getlog.cgi
#!/usr/bin/perl use strict; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); print header; my $dir = param("dir"); my $filter = param("filter"); my $showFilter = $filter; $showFilter =~ s/ /&nbsp;/g; print "direction=$dir, filter=|$showFilter|"; my @loglines = split "\n", qx(cat /var/log/auth.log); @loglines = reverse @loglines if ($dir eq "R"); my @showlines; if ($filter) { foreach (@loglines) { push @showlines, $_ if /$filter/; } } else { @showlines = @loglines; } print "<pre>"; foreach (@showlines) { print "$_\n"; } print "</pre>";
Test the changes, and once satisfied, commit revision 2 (shell in authlog directory):
$ svn commit -m "add filtering"
Refresh the authlog project in the WebSVN site to see the effect. Click on the Compare Changes link on the right-hand side to see how this tool lists changes.

Back and forth between revisions

Subversion maintains all versions of this project. Let's say you want to go back to the previous step and test something else. Assuming you're in the authlog directory type:
$ svn up -r 1
$ svn info
Refresh the authlog web application to confirm that you've reverted your local copy to revision 1 (the subversion site is still 2). OK, now let's go to the latest revision.
$ svn update
Refresh the authlog web application to confirm that you're at the latest revision.

Discussion

Other svn command usages

You can download individual files of any revision, leaving others alone. For example:
$ svn up -r 1 getlog.cgi
When you add or remove a file from the project you must inform subversion. These are the relevant commands:
$ svn add NEW-FILE
$ svn delete OLD-FILE

Controlling web access

WebSVN gives easy access to a group who want to maintain to an open source (or other) project. If only you should see it (because it's a course requirement), or otherwise need to restrict the access, you have to create restrictions in Apache. The settings in the config file, /etc/apache2/conf.d/websvn.conf, grant access only to the local system:
Order deny,allow
Allow from 127.0.0.1
If you want external access, you need to protect it by using authentication. Follow the steps outlined in the Web Authentication + HTTPS document.

Real World Example

In a real world situation, subversion-based projects need to be made available for checkout in an anonymous sense to end users and developers throughout the internet. Furthermore, developers need to have the ability to commit changes through the internet as well.

For example, this content was extracted from a recent version of the developer's page used for the Ardour software (an open source digital audio workstation):

SVN/Bleeding Edge access

Ardour uses Subversion ("SVN") as its distributed development repository tool. Public read access is available to all, but only specific developers have write access.

Browsing the source code

You can use your web browser to read the source code directly from the repository.

Public read-only SVN access

Once you have subversion installed, you can checkout the source code to Ardour with this command:
svn co http://subversion.ardour.org/svn/ardour2/branches/2.0-ongoing
Note that this will fetch the branch corresponding to the current release in the 2.X series, rather then the bleeding-edge development version. If you are an active developer of Ardour, or a beta tester who can live with random crashes while testing out cool new functionality, you can get the development version using this command:
svn co http://subversion.ardour.org/svn/ardour2/branches/3.0

Developer (write) access to SVN

For developers that have been granted write access and have supplied a public SSH key, this command will checkout Ardour so that you can work on the software and commit your changes:
svn co svn+ssh://ardoursvn@ardour.org/ardour2/branches/3.0

Subversion via HTTP with WebDAV

Install the Apache WebDAV module. DAV means Distributed Authoring and Versioning; a system which allows reads/writes to an Apache Directory through a special protocol. Subversion clients (svn) know how use this protocol.

Several Apache modules need to be enabled for this to work. In Ubuntu:
$ sudo a2enmod dav dav_lock dav_fs
An Apache configuration file which uses the ~/svn/authlog project would look something like this:
<Location /svn/authlog>
  DAV svn
  SVNPath /home/LOGIN/svn/authlog
</Location>
Without other alterations, this would provide anonymous checkout capabilities with the http protocol using one of these statements:
$ svn co http://localhost/svn/authlog
$ svn co http://MACHINE.cs.wcupa.edu/svn/authlog
As in other situations, the access may be protected by authentication. If the project directory is made writeable by the Apache user like this:
$ sudo chgrp -R www-data ~/svn/authlog
$ sudo chmod -R g+w ~/svn/authlog
then developers would be able to make changes (import, commit, etc) using the http protocol. If we were to use this scheme, we definitely would want to employ some authentication mechanism.

Subversion via SSH

As we see in the Ardour project example, a developer who has been granted the right to commit changes uses the svn+ssh protocol. In order to use this, the you must be able to access the server via a cryptographic key. If you want to try this on your machine, simply
$ cd ~/.ssh
$ cat id_dsa.pub >> authorized_keys2
You must be able to ssh to yourself without password:
$ ssh localhost
With that in place, one would simply do:
$ svn co svn+ssh://LOGIN@localhost/home/LOGIN/svn/authlog
To have commit access your user needs to have write priviledges to the subversion repository (which is true in this simple case since you own the repository).


© Robert M. Kline