Rancid and JunOS

 24.09.2013 -  Louis Kowolowski -  ~6 Minutes

Rancid is a collection of perl bits which are able to login to various network devices and extract their configurations.

It then uses version control and checks in the current (just extracted) configuration into version control for tracking purposes. With the proper interface to your version control, you can easily see when changes are made. Due to the nature of how Rancid works (pull model) it can’t know who made the changes, but at least you’ll be able to see what changed, and when it happened.

Using Rancid to backup a JunOS device

Configuration management is important. Having the visibility on your network to know not only if something changed, but exactly what changed, and when it changed can keep you from spending hours debugging something. Rancid can be configured (cron) to check your devices every 5min for changes, and then log those changes using version control. Once your configs are stored in version control, you have the visibility to know what changed, and when it changed.

Configuring JunOS

We need to create a user for rancid to login as, and a class to define which privileges to grant our user.

	set system login class RANCID permissions access
	set system login class RANCID permissions admin
	set system login class RANCID permissions firewall
	set system login class RANCID permissions flow-tap
	set system login class RANCID permissions interface
	set system login class RANCID permissions network
	set system login class RANCID permissions routing
	set system login class RANCID permissions secret
	set system login class RANCID permissions security
	set system login class RANCID permissions snmp
	set system login class RANCID permissions storage
	set system login class RANCID permissions system
	set system login class RANCID permissions trace
	set system login class RANCID permissions view
	set system login class RANCID permissions view-configuration
	set system login user rancid full-name RANCID
	set system login user rancid uid 2001
	set system login user rancid class RANCID
	set system login user rancid authentication ssh-ecdsa "ssh_key_text_here"

Installing rancid

rancid is pretty straight forward to install. You can do either of the following:

pkg install rancid

or

cd /usr/ports/networking/rancid && sudo make install clean

After installing rancid, you may need to create the rancid user. You can do that with:

sudo pw useradd rancid
sudo passwd rancid

Configuring rancid

Rancid offers the ability to store device passwords in its config file. I know that in many ways, the network world is behind, but this is a bad idea. An attacker could simply compromise your rancid box and have passwords for the entire network. Fortunately, Juniper devices don’t require passwords. They can take advantage of ssh public keys. This means you can generate a key-pair and copy the public key to the network device. No more password required. We’ve already restricted the rancid user in JUNOS so they can’t do any damage (no write access), so we’ve minimized the damage as much as we can.

If your version of JunOS doesn’t support ecdsa   , just use rsa for now (and upgrade so you can take advantage of shiny new crypto).

There are a handful of config files to edit/create. Defaults are in /usr/local/share/rancid. A .cloginrc file needs to exist in ~rancid. It should be set with permissions of 600 (rancid will complain and refuse to run if you don’t do this). The relevant bits look like this:

# Only use SSH
add password    *       1
add user        *       rancid
add method      *       ssh
add identity    *       /var/rancid/.ssh/id_ecdsa

Password is not used, but rancid whines with out it, so just make something up and assign it.

The rancid config file is in /usr/local/etc/rancid/. Stripping out all the comments in rancid.conf, it looks like this (after I’ve modified it):

TERM=network;export TERM
LC_COLLATE="POSIX"; export LC_COLLATE
umask 027
TMPDIR=/tmp; export TMPDIR
BASEDIR=/var/rancid; export BASEDIR
PATH=/usr/local/libexec/rancid:/usr/bin:/usr/local/bin:/usr/sbin:/bin:/usr/bin; export PATH
CVSROOT=/svn/rancid; export CVSROOT
LOGDIR=$BASEDIR/logs; export LOGDIR
RCSSYS=svn; export RCSSYS
FILTER_PWDS=YES; export FILTER_PWDS
NOCOMMSTR=YES; export NOCOMMSTR
LIST_OF_GROUPS="rancid"
MAILDOMAIN="@dom.tld"; export MAILDOMAIN

Create the directory /var/rancid. Set ownership to rancid. Create the directory /svn/rancid. Set ownership to rancid. You should now be able to (as user rancid), run rancid-run, and then rancid-cvs. It should create some directories in /var/rancid: logs, rancid, and it should populate /svn/rancid with a new repo. You should be able to edit /var/rancid/rancid/router.db and add a line like this:

# <device_name>;<device_type>;<state>[;comments]
switch1.cmhome:junos:up

Re-run rancid-run and you should see a new file show up in /var/rancid/rancid/configs/192.168.0.1 which contains the config of your juniper device. The first 20 lines of mine look like this:

#RANCID-CONTENT-TYPE: juniper
#
# switch1.cmhome> show chassis clocks 
# switch1.cmhome> show chassis environment 
# Class Item                           Status
# Power FPC 0 Power Supply 0           OK        
# Temp  FPC 0 GEPHY1                   OK        
#       FPC 0 GEPHY2                   OK        
#       FPC 0 GEPHY3                   OK        
#       FPC 0 GEPHY4                   OK        
# 
# switch1.cmhome> show chassis firmware 
# Part                     Type       Version
# FPC 0                    uboot      U-Boot 1.1.6 (Jun 29 2011 - 11:08:23)   1.0.0
#                          loader     FreeBSD/arm U-Boot loader 1.1              
# 
# switch1.cmhome> show chassis fpc detail 
# Slot 0 information:
#   State                               Online    
#   Total CPU DRAM                  512 MB

If you want to store things as ‘set’ commands, as opposed to a heirarchy, edit /usr/local/etc/rancid/rancid.types.base

juniper;command;junos::ShowConfiguration;show configuration

Add ‘| display set’ on the end so it looks like this:

juniper;command;junos::ShowConfiguration;show configuration | display set

With all this working, you can now cron an entry for rancid-run. It should look something like this (/etc/crontab):

# RANCID
# clean up after rancid. don't need more than 30 days worth of log files cluttering things up
1	*	*	*	*	/usr/bin/find /var/rancid/logs/ -type f -cmin +120 -delete

# do a rancid-run every */30min
*/30      *       *       *       *       /usr/local/bin/rancid-run > /dev/null

Installing and configuring websvn

I chose a web frontend called websvn. Its written in PHP which sucks, but I’m only using it internally. For the web server, I used nginx. I built php with fpm support and configured nginx to talk to the php-fpm process as shown below. Enabling php-fpm in /etc/rc.conf:

Here is the nginx snippit for websvn and php-fpm:

	location /websvn {
		alias /usr/local/www/websvn;
		index index.php;
	}
	location ~ \.php {
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		set $path /usr/local/www/nginx;
		if ($request_uri ~* /websvn) {
			set $path /usr/local/www;
		}
		fastcgi_param SCRIPT_FILENAME $path$fastcgi_script_name;
		fastcgi_pass backend;
		include fastcgi_params;
	}
	upstream backend {
		server 127.0.0.1:9000;
	}

Edit the /usr/local/www/websvn/includes/config.php and define where your SVN repo is (I used /svn/rancid). Start up your services (php-fpm, nginx), and point your browser at http://yourserver/websvn   . You should see the websvn interface, a config directory with your juniper device config named 192.168.0.1, and your router.db file.


Footnotes and References