not logged in | [Login]

Using git to administer FreeRADIUS server configurations

As well as being an excellent SCM (Source control management) tool, git is also very useful for tracking changes to configuration files, and even for performing remote administration of servers.

The basics

For basic configuration management one only has to:

cd <config_dir>/raddb
git init
git add .
git commit --message 'Initial commit of FreeRADIUS configuration'

Then every time a change is made:

git commit -a --message 'Added support for xyz'

To see a list of changes:

git log

To know who to blame:

git blame

And if it's all gone horribly wrong:

git log # To find the last known good commit id
git revert <commit id>

There are many many tutorials available if you want to learn more generic git administration, this one is extra pretty:

Remote administration

The basic functionality of git is useful on its own, but one of the features that really makes git shine among the SCMs is its support for commit hooks. Hooks don't require anything special to function (like gitosis or the git-daemon), they work just as well over straight SSH.

They can be as simple or complex as you want to make them, but the server source contains a particularly compelling example.


To install it convert your raddb folder to a git repository (as show above)

Copy the post-receive hook script to the .git/hooks dir:

cd <config_dir>/raddb/.git/hooks
chmod +x post-receive

Edit parameters at the top of the file to work with with your system (defaults are for Ubuntu 10.04 LTS)

Tweak the git configuration to allow commits to the currently checked out branch:

cd <config_dir>/raddb
git config receive.denyCurrentBranch ignore

Clone the servers remote repository to your local machine:

mkdir <respositories>
cd <repositories>
git clone ssh://<user>@<server>/<config_dir>/raddb

Make your local modifications:

echo "foouser    Cleartext-Password := 'foopass'" >> users
git add users
git commit --message 'Add foouser'
git push

And if all goes well you should see something like:

Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 367 bytes, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: HEAD is now at f4419ec Commit stuff
remote: Checking new configuration... ok
remote: Restarting server... ok
remote: Updated tag 'stable' (was ae98fa8)
To ssh://<user>@<server>/usr/local/etc/raddb
  ae98fa8..f4419ec  master -> master

What just happened?

First the commit was transferred to the remote server and merged with the commits already there, then our post-receive hook was executed. The post receive hook updated the working copy to the repository HEAD (throwing away any local changes, be careful).

radiusd -C was called to check the new config was valid, it appeared to be valid so the server was restarted to load in the new config parameters, restart seemed to go ok so the stable tag was updated to point to the new commit (tags are user assigned aliases for particular commits).

The stable tag

The stable tag actually provides two functions here. If radiusd -C passed the config, but the server failed to restart correctly, the hook script uses it to roll back the config automatically to a known good version and start the server. If the server started ok, but unfortunately so have the angry emails; to rapidly revert the server back to a known good configuration git revert stable.

With multiple servers

Extending the idea further you can add multiple cluster servers as remotes and push the new configuration out to each of them (or write a simple script to do that for you):

git remote rename master server0
git remote add server1 ssh://<user>@<server>/usr/local/etc/raddb
git remote add server2 ssh://<user>@<server>/usr/local/etc/raddb

for remote in `git remote`; do
    git push $remote master

See Also