Easy system monitoring with Cacti under OpenBSD and nginx
Cacti is a great monitoring tool based on RRDTool and SNMP, I use this solution for more than 10 years, the project is very active, easy to manage and to maintain.
But... when you want to run it under OpenBSD with a chrooted httpd it can be very painfull to setup and it will make you want to break stuff.
So today we'll take the easy way !
Here, Cacti is just used by myself, so I need to restrict access to the service for more security, and to make sure that everything is running without privileges.
So... what do we need to make this wonderful project a reality ?
- An Operating System ("Do you have any others jokes like that ?" - "Plenty !"), we'll take OpenBSD, what else ?
- A chrooted http server, what about nginx ? seems perfect to me as it's chrooted by default on OpenBSD
- A snmp daemon, net-snmp is a great tool your can use to collect your datas
- RRDTool to generate your graphs
- PHP / MySQL, should I explain why ?
- Cacti
Install and configure what we need !
1. All the components we need :
# pkg_add nginx mariadb-server net-snmp php-snmp php-pdo_mysql php-gd php-gmp php-ldap rrdtool
# ln -s /usr/local/bin/php-7.0 /usr/local/bin/php
For PHP packages, I took the 7.x versions.
2. Setup net-snmp
We are using net-snmp in local, so we just bind it on the localhost, snmp v1 protocol will be enough.
# vi /etc/snmp/snmpd.conf
agentAddress udp:127.0.0.1:161
sysLocation Somewhere in a dark and creepy place
sysContact Lina Sovereign <[adresse masquée]>
# rcctl enable netsnmpd && rcctl start netsnmpd
netsnmpd(ok)
3. Setup MariaDB (MySQL)
# rcctl enable mysqld && mysql_install_db && rcctl mysqld start
mysqld(ok)
# mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none): [ENTER]
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.
Set root password? [Y/n] Y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n] Y
... Success!
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] Y
... Success!
By default, MariaDB comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n] Y
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n] Y
... Success!
Cleaning up...
All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!
Configuration tuning :
# mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
# vi /etc/my.cnf
[mysqld]
max_allowed_packet = 32M
tmp_table_size = 64M
innodb_doublewrite = OFF
innodb_additional_mem_pool_size = 80M
innodb_flush_log_at_timeout = 3
innodb_read_io_threads = 32
innodb_write_io_threads = 16
default_time_zone = Europe/Paris
# rcctl restart mysqld
mysqld(ok)
mysqld(ok)
4. Setup PHP
# rcctl enable php70_fpm
# cp /etc/php-7.0.sample/* /etc/php-7.0/
# rcctl start php70_fpm
php70_fpm(ok)
5. Cacti
We'll create a dedicated user to Cacti :
# adduser
Ok, let's go.
Don't worry about mistakes. There will be a chance later to correct any input.
Enter username []: cacti
Enter full name []: cacti user
Enter shell bash csh ksh nologin sh [bash]:
Uid [1001]:
Login group cacti [cacti]:
Login group is ``cacti''. Invite cacti into other groups: guest no
[no]:
Login class authpf bgpd daemon default pbuild staff unbound
[default]:
Enter password []:
Enter password again []:
Name: cacti
Password: ****
Fullname: cacti user
Uid: 1001
Gid: 1001 (cacti)
Groups: cacti
Login Class: default
HOME: /home/cacti
Shell: /usr/local/bin/bash
OK? (y/n) [y]: y
Added user ``cacti''
Copy files from /etc/skel to /home/cacti
Add another user? (y/n) [y]: n
Goodbye!
# su cacti
$ cd ~/
$ wget http://www.cacti.net/downloads/cacti-1.1.16.tar.gz
$ tar xvzf cacti-1.1.16.tar.gz
$ mv cacti-1.1.16 cacti
$ cd cacti
Time to create our SQL user/database :
$ mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 32
Server version: 10.0.30-MariaDB OpenBSD port: mariadb-server-10.0.30v1
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database cacti;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> CREATE USER 'cacti'@'localhost' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> grant create,delete,insert,select,update,alter ON cacti.* TO 'cacti'@'localhost';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> use mysql;
Database changed
MariaDB [mysql]> GRANT SELECT ON mysql.time_zone_name TO 'cacti'@'localhost';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> quit
Bye
Configure our database :
$ mysql -u cacti -p cacti < cacti.sql
Enter password:
Configure Cacti :
$ vi include/config.php
$database_type = 'mysql';
$database_default = 'cacti';
$database_hostname = 'localhost';
$database_username = 'cacti';
$database_password = 'password';
$database_port = '3306';
$database_ssl = false;
$url_path = '/';
Now we'll use the built-in PHP server to start our service.
$ /usr/local/bin/php-7.0 -S 127.0.0.1:9000
PHP 7.0.16 Development Server started at Fri Aug 4 09:21:53 2017
Listening on http://127.0.0.1:9000
Document root is /home/cacti/cacti
Press Ctrl-C to quit.
6. nginx
Our goal is to redirect http to https, use ssl, connect to our local php server running on localhost:9000 and restrict the access to our localnet, in my case : 192.168.1.0/24 & 2a01:cb06:3e0:eb00::/56.
# vi /etc/nginx/nginx.conf
server {
listen 80;
listen [::]:80;
server_name cacti.cagedmonster.net;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cacti.cagedmonster.net;
ssl_certificate /etc/letsencrypt/live/cagedmonster.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cagedmonster.net/privkey.pem;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:9000/;
allow 192.168.1.0/24;
allow 2a01:cb06:3e0:eb00::/56;
deny all;
}
}
# rcctl start nginx
nginx(ok)
7. Last step : Cacti interface and automation
Now you can check with your web browser if everything is fine. You should see something like this :
Follow the installation steps, you'll be able to configure your device here :
Finally, we configure our spooler to collect datas every 5 minutes with crontab and make sure our local PHP server runs at system startup :
$ crontab -e
@reboot cd ~/cacti/ && /usr/local/bin/php-7.0 -S 127.0.0.1:9000 > /dev/null 2>&1
*/5 * * * * /usr/local/bin/php-7.0 /home/cacti/cacti/poller.php > /dev/null 2>&1
Need help ?