====== Setting up a Munin server and nodes ======
===== Munin master setup =====
In this example, we are going to set up a munin server in its own [[LXC]] container instance. This container will run unprivileged under an ordinary user. We are using Devuan because regular Debian with systemd will not run in an unprivileged container AFAIK.
==== Creating a container ====
- ''lxc-create -t download -n munin'' \\ ''(devuan, beowulf, arm64)''
- ''lxc-attach munin passwd''
==== Basic container setup ====
- ''lxc-attach munin''
- ''apt update''
- ''apt autoremove''
- ''apt clean''
- ''dpkg-reconfigure tzdata''
==== Installing munin ====
- ''apt install munin''
- Change these lines in ''/etc/munin/munin.conf'': graph_strategy cgi
html_strategy cgi
htmldir /var/www/munin
- Add some nodes if you have any already: [Node1]
address 1.2.3.4
use_node_name yes
- ''mkdir /var/www/munin''
- ''chown munin:munin /var/www/munin''
- ''service munin restart''
==== Setting up a web server ====
- ''apt install apache2 libapache2-mod-fcgid libcgi-fast-perl''
- ''vim /etc/apache2/sites-available/munin.conf''
ServerName munin.example.org
ServerAlias munin
ServerAdmin info@example.org
DocumentRoot /var/www
Alias /munin/static/ /etc/munin/static/
AuthType Basic
AuthName "Members Only"
AuthUserFile /etc/apache2/.htpasswd
require valid-user
Require all granted
ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph
ScriptAlias /munin /usr/lib/munin/cgi/munin-cgi-html
Require all granted
SetHandler fcgid-script
SetHandler cgi-script
CustomLog /var/log/apache2/munin.example.org-access.log combined
ErrorLog /var/log/apache2/munin.example.org-error.log
- ''htpasswd -c /etc/apache2/.htpasswd''
- ''a2ensite munin''
- ''a2dissite 000-default''
- ''a2enmod fcgid rewrite''
- ''service apache2 restart''
===== Configuring nodes =====
==== Adding a node ====
To add nodes, all you need to do is this:
- Install munin-node \\ ''apt install munin-node''
- edit /etc/munin/munin and add a line allowing the master to connect, e.g.: \\ allow ^10\.0\.3\.116$
- Optionally, make it listen only on localhost: \\ host 127.0.0.1
- Restart the service. \\ ''systemctl restart munin-node''
On the master:
- Add a new snippet to ''/etc/munin/munin.conf'', e.g.: [Node1]
address 1.2.3.4
use_node_name yes
- Restart the munin master service. ''service munin restart''
===== Enabling/disabling plugins =====
On the nodes, enabled plugins are found in ''/etc/munin/plugins''.
Available plugins are found in ''/usr/share/munin/plugins''. Create symbolic links to the active configuration. Some of the plugins behave differently depending on how the links are named; the plugin files themselves should contain readable documentation for more info.
==== Plugin configuration ====
Plugins can be configured further via setting files in ''/etc/munin/plugin-conf.d''. Here are some examples:
=== diskstats ===
[diskstats]
env.include_only sda,sdb,...
=== df ===
[df]
env.include_re ^/$ ^/var/log$ ^/web$
env.exclude_re ^/dev/shm$ ^/run/lock$ ^/sys/fs/cgroup$
[df_inode]
env.include_re ^/$ ^/var/log$ ^/web$
env.exclude_re ^/dev/shm$ ^/run/lock$ ^/sys/fs/cgroup$
===== Connect a host via ssh =====
A more secure way to connect a node to the master is via ssh. When connecting to a machine on the internet, ssh is a must have.
- Create an SSH keypair on the host for user ''munin''
- since the ''munin'' user can't login by default, create it as ''root'' and change ownership.
- Move the ''.ssh'' folder to ''/var/lib/munin/ssh''
- Make sure it's owned by ''munin'' and not accessible to anyone else. \\ # ls -la /var/lib/munin/ssh
total 20
drwx------ 2 munin munin 4096 Mar 6 20:18 .
drwxr-xr-x 13 munin munin 4096 Mar 8 14:15 ..
-rw------- 1 munin munin 399 Mar 6 20:18 id_ed25519
-rw-r--r-- 1 munin munin 92 Mar 6 20:18 id_ed25519.pub
-rw-r--r-- 1 munin munin 666 Mar 6 20:21 known_hosts
- Add the key to the node's ''.ssh/authorized_keys''
- configure ssh options in ''/etc/munin/munin.conf'': \\ ssh_options -o IdentityFile=/var/lib/munin/ssh/id_ed25519 -o UserKnownHostsFile=/var/lib/munin/ssh/known_hosts -o User=remoteuser -o PreferredAuthentications=publickey
- A node section in ''/etc/munin/munin.conf'' might look like this: \\ [node2.example.com]
address ssh://node2.example.com/bin/nc 127.0.0.1 4949
use_node_name yes
===== (Alternative) init.d script to automatically create an SSH tunnel to a node =====
Though **I would recommend the way outlined in the previous section**, here's an example on how to automatically dig an SSH tunnel to a node system via an init.d script (since we have no systemd on Devuan).
- Create a key pair on the munin master: \\ ''ssh-keygen -t ed25519''
- Add the public key to the remote node's ''authorized_keys'', e.g.: \\ ''cat id_ed25519.pub >> .ssh/authorized_keys''
- Create the script on the munin master: \\ ''vi ssh_example'' \\ #!/bin/sh
### BEGIN INIT INFO
# Provides: ssh_example
# Required-Start: $all
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: your description here
### END INIT INFO
PID_FILE="/var/run/ssh_example.pid"
case "$1" in
start)
if [ -f $PID_FILE ]; then
echo "SSH tunnel is already up apparently"
else
start-stop-daemon --start --exec /usr/bin/ssh --background --pidfile=$PID_FILE --make-pidfile -- -fNL 14949:localhost:4949 user@example.com
fi
;;
stop)
start-stop-daemon --stop --pidfile=$PID_FILE
rm $PID_FILE
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
- ''chmod +x ssh_example''
- ''mv ssh_example /etc/init.d/''
- ''insserv /etc/init.d/ssh_example''
- ''update-rc.d ssh_example defaults''
- ''update-rc.d ssh_example enable''
- ''service ssh_example start''
==== Securing the node ====
- Make sure the node only listens on the loopback interface by removing this line from ''/etc/munin/munin-node.conf'': \\ host *
- and adding either of these instead: \\ host 127.0.0.1
host ::1
- it should only listen to localhost: \\ allow ^127\.0\.0\.1$
allow ^::1$
==== Adding it to the master ====
This one might be obvious. Add a new section to ''/etc/munin/munin.conf'': \\ [example.com]
address 127.0.0.1
port 14949
use_node_name yes
===== See also =====
* [[LXC]]