Installing and configuring Rancid on CentOS 8

Posted: January 16, 2020 in Linux

RANCID – Really Awesome New Cisco config Differ monitors a router’s (or more generally a device’s) configuration, including software and hardware (cards, serial numbers, etc) and uses CVS (Concurrent Version System), Subversion or Git to maintain history of changes.

Rancid:

  • login to each device in the router table (router.db)
  • runs various commands to get the information that will be saved,
  • cook the output; re-format, remove oscillating or incrementing data,
  • email any differences (sample) from the previous collection to a mail list
  • commit those changes to the revision control system

Installing required components

dnf update -y
dnf install -y epel-release 
dns install -y python2 vim wget git mlocate 
dnf install dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm 
dnf module reset php 
dnf module enable php:remi-7.4 
dnf install php php-opcache php-gd php-curl php-mysqlnd 
systemctl enable --now php-fpm 
rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm 
yum install -y wget ftp telnet mariadb-server mariadb perl tcl expect gcc cvs httpd autoconf php-common php-gd php-pear php-pecl-memcache php-mysql php-xml mod_ssl tar sendmail postfix  
pip2 install mysql-connector-python MySQL-Python 

If, during installing MySQL-Python you face following error:

Building wheels for collected packages: MySQL-python
Running setup.py bdist_wheel for MySQL-python ... error
Complete output from command /usr/bin/python -u -c "import setuptools, tokenize;file='/tmp/pip-build-3oXEzH/MySQL-python/setup.py';exec(compile(getattr( tokenize, 'open', open)(file).read().replace('\r\n', '\n'), file, 'exec'))" bdist_wheel -d /tmp/tmpXv05tnpip-wheel- --python-tag cp27:
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-2.7
copying mysql_exceptions.py -> build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/MySQLdb
copying MySQLdb/init.py -> build/lib.linux-x86_64-2.7/MySQLdb
copying MySQLdb/converters.py -> build/lib.linux-x86_64-2.7/MySQLdb
copying MySQLdb/connections.py -> build/lib.linux-x86_64-2.7/MySQLdb
copying MySQLdb/cursors.py -> build/lib.linux-x86_64-2.7/MySQLdb
copying MySQLdb/release.py -> build/lib.linux-x86_64-2.7/MySQLdb
copying MySQLdb/times.py -> build/lib.linux-x86_64-2.7/MySQLdb
creating build/lib.linux-x86_64-2.7/MySQLdb/constants
copying MySQLdb/constants/init.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
copying MySQLdb/constants/CR.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
copying MySQLdb/constants/FIELD_TYPE.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
copying MySQLdb/constants/ER.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
copying MySQLdb/constants/FLAG.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
copying MySQLdb/constants/REFRESH.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
copying MySQLdb/constants/CLIENT.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
running build_ext
building 'mysql' extension
creating build/temp.linux-x86_64-2.7
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Dversion_info=(1,2,5,'final',1) -D__version=1.2.5 -I/usr/include/mysql -I/usr/include/ python2.7 -c _mysql.c -o build/temp.linux-x86_64-2.7/_mysql.o
In file included from _mysql.c:44:0:
/usr/include/mysql/my_config.h:3:2: warning: #warning This file should not be included by clients, include only <mysql.h> [-Wcpp]
#warning This file should not be included by clients, include only <mysql.h>
^
In file included from _mysql.c:46:0:
/usr/include/mysql/mysql.h:440:3: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
MYSQL_CLIENT_PLUGIN_HEADER
^
/usr/include/mysql/mysql.h:585:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
my_bool STDCALL mysql_embedded();
^
_mysql.c: In function ‘_mysql_ConnectionObject_ping’:
_mysql.c:2005:41: error: ‘MYSQL {aka struct st_mysql}’ has no member named ‘reconnect’
if ( reconnect != -1 ) self->connection.reconnect = reconnect;
^
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

Failed building wheel for MySQL-python
Running setup.py clean for MySQL-python
Failed to build MySQL-python

Edit  /usr/include/mysql/mysql.h. Add a line with unsigned int reconnect; after the line unsigned int warning_count;

Installing Rancid

groupadd netadm 
useradd -g netadm -c "Networking Backups" -d /home/rancid rancid 
mkdir /home/rancid/tar 
cd /home/rancid/tar/ 
wget ftp://ftp.shrubbery.net/pub/rancid/rancid-3.9.tar.gz 
tar -xzvf rancid-3.9.tar.gz 
cd rancid-3.9 
./configure --prefix=/usr/local/rancid 
make && make install

Configuring Rancid

Copy over the ‘cloginrc.sample into path /home/rancid/.cloginrc’ file. Then set the ownership and and permissions on the rancid files and directories.

cp cloginrc.sample /home/rancid/.cloginrc 
chmod 0640 /home/rancid/.cloginrc 
chown -R rancid:netadm /home/rancid/.cloginrc 
chown -R rancid:netadm /usr/local/rancid/ 
chmod 775 /usr/local/rancid/ 

Create folders “Routers Switches Firewalls”,you will see when you first log into the ViewVC web front end.

vim /usr/local/rancid/etc/rancid.conf 
Uncomment and add your groups, i.e. 
LIST_OF_GROUPS="Routers Switches Firewalls" 

Apply changes:

su - rancid 
/usr/local/rancid/bin/rancid-cvs
exit

Anytime when /usr/local/rancid/etc/rancid.conf is edited, above command needs to be executed.

Installing ViewVC

ViewVC is a browser interface for CVS and Subversion version control repositories. It generates templatized HTML to present navigable directory, revision, and change log listings. It can display specific versions of files as well as diffs between those versions.

cd /home/rancid/tar/ 
wget http://www.viewvc.org/downloads/viewvc-1.1.27.tar.gz 
tar -xzvf viewvc-1.1.27.tar.gz 
cd viewvc-1.1.27 
./viewvc-install 

Configuring ViewVC

vim /usr/local/viewvc-1.1.27/viewvc.conf 
#Uncomment and change the values, (as shown bellow)# 
root_parents = /usr/local/rancid/var/CVS : cvs 
rcs_dir = /usr/local/bin 
use_rcsparse = 1 

Enable ViewVC to work with Apache httpd, we need to copy over some CGI, and set some permissions.

cp /usr/local/viewvc-1.1.27/bin/cgi/*.cgi /var/www/cgi-bin/ 
chmod +x /var/www/cgi-bin/*.cgi 
chown apache:apache /var/www/cgi-bin/*.cgi 

MariaDB configuration

systemctl enable mariadb 
systemctl start mariadb 
mysql_secure_installation

We need to create a user in MariaDB SQL that ViewVC will use, to do this we need to log into SQL using the root password set up in previous step (mysql_secure_installation)

mysql -u root -p 
Enter your SQL root password 
CREATE USER 'VIEWVC'@'localhost' IDENTIFIED BY 'MyP4ssW0rd'; 
GRANT ALL PRIVILEGES ON *.* TO 'VIEWVC'@'localhost' WITH GRANT OPTION; 
FLUSH PRIVILEGES; 
quit 

Now we can setup database and get ViewVC to create its database.

cd /usr/local/viewvc-1.1.27/bin/ 
./make-database 

Create another user in MariaDB, that will be a ‘read-only’ user.

mysql -u root -p 
CREATE USER 'VIEWVCRO'@'localhost' IDENTIFIED BY 'MyP4ssW0rd'; 
GRANT SELECT ON ViewVC.* TO 'VIEWVCRO'@'localhost' WITH GRANT OPTION; 
FLUSH PRIVILEGES; 
quit 

Edit the ViewVC configuration so that it uses all the parameters you have setup.

vim /usr/local/viewvc-1.1.27/viewvc.conf

enabled = 1 
host = localhost 
port = 3306 
database_name = ViewVC 
user = VIEWVC 
passwd = MyP4ssW0rd 
readonly_user = VIEWVCRO 
readonly_passwd = MyP4ssW0rd

Rebuild the database

/usr/local/viewvc-1.1.27/bin/cvsdbadmin rebuild /usr/local/rancid/var/CVS/CVSROOT/

Apache configuration

Following configuration will:

  • enable SSL/https connection by self-signed certificate
  • will redirect http to https
  • will configure Active directory authentication
  • users must be members of specific AD group
dnf install mod_ldap
# create self-signed certificate
cd /etc/ssl/certs
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout rancid.key -out rancid.crt

Configure SSL Virtual host

vi /etc/httpd/conf.d/ssl.conf

SSLCertificateFile /etc/ssl/certs/rancid.crt 
SSLCertificateKeyFile /etc/ssl/certs/rancid.key 
<VirtualHost _default_:443> 
DocumentRoot "/var/www" 
ScriptAlias /cgi-bin/ "/var/www/cgi-bin" 
ScriptAlias /viewvc /var/www/cgi-bin/viewvc.cgi 
ScriptAlias /query /var/www/cgi-bin/query.cgi 
ServerName rancid.test.com:443 

<Directory "/var/www/cgi-bin"> 
    AllowOverride None 
    Options None 
    #Order allow,deny 
    #Allow from all 
    AuthType Basic 
    AuthName "login to continue" 
    AuthBasicProvider ldap 
    AuthLDAPBindAuthoritative off 
    AuthLDAPURL "ldap://test.com/dc=test,dc=com?sAMAccountName 
    AuthLDAPBindDN "test@test.com" 
    AuthLDAPBindPassword "somepassword" 
    #require valid-user
    AuthLDAPSubGroupAttribute member
    AuthLDAPSubGroupClass group
    Require ldap-group CN=Rancid,OU=Security,OU=Groups,OU=example,DC=test,DC=com  
</Directory> 

Create virtual host and configure http to https redirection

vi /etc/httpd/conf.d/viewvc.conf

<VirtualHost *:80> 
        ServerAlias * 
        DocumentRoot /var/www 
        ScriptAlias /cgi-bin/ "/var/www/cgi-bin" 
        ScriptAlias /viewvc /var/www/cgi-bin/viewvc.cgi 
        ScriptAlias /query /var/www/cgi-bin/query.cgi 
        RewriteEngine on 
        RewriteRule "^/?(.*)"  "https://%{HTTP_HOST}/$1" [R=301] 
</VirtualHost> 

systemctl enable httpd && systemctl start httpd

Type http://ip/viewvc, you should be automatically forwarded to https/ip/viewvc, credentials pop-up will ask for username/password and following page should be seen

Adding devices to Rancid

Rancid groups are represented by respective folders in /usr/local/rancid/var folder

In this example switch will be added

vi /usr/local/rancid/var/Switches/router.db

Fileformat: ip-or-hostname;vendor;up

In this case content would be

1.1.1.1;cisco,up

Adding credentials

vi /home/rancid/.cloginrc

add user {ip-or-hostname} {username}
add password {ip-or-hostname} {password}
add method {ip-or-hostname} {ssh or telnet}
add autoenable {ip-or-hostname} 1

Applying changes

su rancid
/usr/local/rancid/bin/rancid-run

Above command won’t give any output, in case of errors examine logs

cd /usrcd /usr/local/rancid/var/logs/
ls
cat {log-name}

# or interactively debugging

/usr/local/rancid/bin/clogin -c "sh run" IP/or host name

Configuring notifications

which sendmail
/sbin

Edit /usr/local/rancid/bin/control_rancid

SENDMAIL=${SENDMAIL:=/sbin/sendmail};

Rancid uses groups in following format:

rancid-"group_name" 
rancid-admin-"group_name"

The first group will receive a report after a configuration change, the second one when there is error messages.Vi need to create those aliases so postfix can use it for sending emails.

vi /etc/aliases

rancid-Switches:        email@test.com
rancid-admin-Switches:  email@test.com 

Apply aliases, start sendmail and postfix:

newaliases
systemctl enable postfix && systemctl start postfix
systemctl enable sendmail && systemctl start sendmail
Comments
  1. Tom says:

    Two thumbs up on your write up! Nice!
    I do have issues with a clean centos8 install. Initial Step #11 pip2 install mysql-connector-python MySQL-Python

    Seems I get a fatal error my_config.h: No such file or directory

    Been adding support files to no avail. Any suggestions?

    Installing collected packages: mysql-python
    Running setup.py install for mysql-python … error
    Complete output from command /usr/bin/python2 -u -c “import setuptools, tokenize;__file__=’/tmp/pip-build-RFQeZv/mysql-python/setup.py’;f=getattr(tokenize, ‘open’, open)(__file__);code=f.read().replace(‘\r\n’, ‘\n’);f.close();exec(compile(code, __file__, ‘exec’))” install –record /tmp/pip-5u0qdM-record/install-record.txt –single-version-externally-managed –compile:
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-2.7
    copying _mysql_exceptions.py -> build/lib.linux-x86_64-2.7
    creating build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/__init__.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/converters.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/connections.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/cursors.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/release.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/times.py -> build/lib.linux-x86_64-2.7/MySQLdb
    creating build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/__init__.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/CR.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/FIELD_TYPE.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/ER.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/FLAG.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/REFRESH.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/CLIENT.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    running build_ext
    building ‘_mysql’ extension
    creating build/temp.linux-x86_64-2.7
    gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -Dversion_info=(1,2,5,’final’,1) -D__version__=1.2.5 -I/usr/include/mysql -I/usr/include/python2.7 -c _mysql.c -o build/temp.linux-x86_64-2.7/_mysql.o -m64
    _mysql.c:44:10: fatal error: my_config.h: No such file or directory
    #include “my_config.h”
    ^~~~~~~~~~~~~
    compilation terminated.
    error: command ‘gcc’ failed with exit status 1

    —————————————-
    Command “/usr/bin/python2 -u -c “import setuptools, tokenize;__file__=’/tmp/pip-build-RFQeZv/mysql-python/setup.py’;f=getattr(tokenize, ‘open’, open)(__file__);code=f.read().replace(‘\r\n’, ‘\n’);f.close();exec(compile(code, __file__, ‘exec’))” install –record /tmp/pip-5u0qdM-record/install-record.txt –single-version-externally-managed –compile” failed with error code 1 in /tmp/pip-build-RFQeZv/mysql-python/

    ! END

    Like

  2. dragan979 says:

    do you have my_config.h ?

    find / -name my_config.h

    any output of above command ?

    it should be like this:

    /usr/include/mysql/my_config.h
    /usr/include/mysql/server/my_config.h

    Like

  3. Tim P says:

    any help with this?

    sudo pip2 install mysql-python
    WARNING: Running pip install with root privileges is generally not a good idea. Try `pip2 install –user` instead.
    Collecting mysql-python
    Using cached https://files.pythonhosted.org/packages/a5/e9/51b544da85a36a68debe7a7091f068d802fc515a3a202652828c73453cad/MySQL-python-1.2.5.zip
    Installing collected packages: mysql-python
    Running setup.py install for mysql-python … error
    Complete output from command /usr/bin/python2 -u -c “import setuptools, tokenize;__file__=’/tmp/pip-build-gUtolE/mysql-python/setup.py’;f=getattr(tokenize, ‘open’, open)(__file__);code=f.read().replace(‘\r\n’, ‘\n’);f.close();exec(compile(code, __file__, ‘exec’))” install –record /tmp/pip-T_qj3s-record/install-record.txt –single-version-externally-managed –compile:
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-2.7
    copying _mysql_exceptions.py -> build/lib.linux-x86_64-2.7
    creating build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/__init__.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/converters.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/connections.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/cursors.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/release.py -> build/lib.linux-x86_64-2.7/MySQLdb
    copying MySQLdb/times.py -> build/lib.linux-x86_64-2.7/MySQLdb
    creating build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/__init__.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/CR.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/FIELD_TYPE.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/ER.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/FLAG.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/REFRESH.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    copying MySQLdb/constants/CLIENT.py -> build/lib.linux-x86_64-2.7/MySQLdb/constants
    running build_ext
    building ‘_mysql’ extension
    creating build/temp.linux-x86_64-2.7
    gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -Dversion_info=(1,2,5,’final’,1) -D__version__=1.2.5 -I/usr/include/mysql -I/usr/include/python2.7 -c _mysql.c -o build/temp.linux-x86_64-2.7/_mysql.o -m64
    _mysql.c:29:10: fatal error: Python.h: No such file or directory
    #include “Python.h”
    ^~~~~~~~~~
    compilation terminated.
    error: command ‘gcc’ failed with exit status 1

    —————————————-
    Command “/usr/bin/python2 -u -c “import setuptools, tokenize;__file__=’/tmp/pip-build-gUtolE/mysql-python/setup.py’;f=getattr(tokenize, ‘open’, open)(__file__);code=f.read().replace(‘\r\n’, ‘\n’);f.close();exec(compile(code, __file__, ‘exec’))” install –record /tmp/pip-T_qj3s-record/install-record.txt –single-version-externally-managed –compile” failed with error code 1 in /tmp/pip-build-gUtolE/mysql-python/
    [tpolim001@netengsrv01 ~]$

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s