Zabbix - cgi and mysql

From Alpine Linux

Zabbix is the most popular monitoring manager in open source world, there's monitoring itself only like catci, but the hint is that Zabbix is manager also, is ipv6 ready! fully supported, also featured proxy-server for hidden and firewalled networks. Its like nagios one but more big, cutting edge and professional.

In the wiki there are two approaches for its use, the professional one (for servers and deploys) and the fast and simple usage (for developers and/or enthusiasts). For more curses on that (of course focused on alpine) check Complete alpine documentation on english for zabbix curse

This documentation is divided in two big parts.. the prerequisites and the installation of zabbix minimal infrastructure. The first part are in sync with the current alpine wiki pages of Production pages

Note: There is a possibility that this page may have been complexified / obfuscated. See the talk page or review an earlier edit: https://wiki.alpinelinux.org/w/index.php?title=Zabbix&oldid=17984.

Where to use zabbix and alpine

Since Zabbix it focuses on hosts: So is the right choice for monitoring distributed networks (was originally developed for monitoring servers).

In cases where there is no option to install an agent, Zabbix offers basic agentless monitoring. With it, you can check the availability of network services, as well as execute remote commands

Zabbix infraestructure

Zabbix is divided into two large parts: server(s) and agent(s), and yes "servers" cos can be centralized or decentralized due the "proxyes" semi-servers.

  • The servers: represent all the recollected data and has management capabilities. Each one if are more than one, collects and stores statistical data.
  • The agents: represent each host, the clients, those machines or devices from which data is collected. Those support both passive (polling) and active checks (trapping).
  • The proxys: represent a server that can act as man-in-the-middle for distributed load, cases of hideden networking or firewalled, of course with management capabilities cos act as server for those agents/hosts.

Passive checks mean that the Zabbix server requests a value from the Zabbix agent, and the agent processes the request and returns the value to the Zabbix server.

Active checks mean that the Zabbix agent requests a list of active checks from the Zabbix server and then periodically sends the results.

Part 1 Pre-requisites: php, webserver and database

In production web, LAMP means Linux + Apache + Mysql + Php installed and integrated, but today, more and more, Apache is being replaced by Nginx or Lighttpd and MySQL by Mariadb. The LAMP documents are:

1. The web server: Lighttpd

lighttpd is a simple, standards-compliant, secure, and flexible web server, Nginx is the most used due to beeing manageable by ISP panel's software, but lighttpd performs better. Nginx cannot process fast-cgi programs. For more lighttpd information, consult the Production Web server: Lighttpd wiki page.

Lighttpd Installation

Production environment will handle only needed packages. So no doc or managers allowed:

  1. run apk for needed packages

apk add lighttpd gamin

Lighttpd pre php configuration

  1. make the htdos public web root directories
  2. change default port to production one, http is used with 80
  3. use FAM style (gamin) file alteration monitor, increases performance ONLY ON 3.4 to 3.8 releases!!!
  4. use linux event handler, increases performance due Alpine are linux only
  5. added the service to the default runlevel, not to boot, because networking needs to be active first
  6. started the web server service
  7. Enable the mod_status at the config files
  8. change path in the config file, we are using security by obfuscation
  9. restart the service to see changes at the browser

mkdir -p /var/www/localhost/htdocs/stats /var/log/lighttpd /var/lib/lighttpd

sed -i -r 's#\#.*server.port.*=.*#server.port          = 80#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#\#.*server.event-handler = "linux-sysepoll".*#server.event-handler = "linux-sysepoll"#g' /etc/lighttpd/lighttpd.conf

chown -R lighttpd:lighttpd /var/www/localhost/

chown -R lighttpd:lighttpd /var/lib/lighttpd

chown -R lighttpd:lighttpd /var/log/lighttpd

rc-update add lighttpd default

rc-service lighttpd restart

echo "it works" > /var/www/localhost/htdocs/index.html

sed -i -r 's#\#.*mod_status.*,.*#    "mod_status",#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*status.status-url.*=.*#status.status-url  = "/stats/server-status"#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*status.config-url.*=.*#status.config-url  = "/stats/server-config"#g' /etc/lighttpd/lighttpd.conf

rc-service lighttpd restart

For testing, open a browser and go to http://<webserveripaddres>. You will see "it works". The "webserveripaddres" is the ip address of your setup/server machine.

There's a problem in Alpine linux, FAM (gamin) is activated as a lighttpd only service, that makes sense in docker, but on a server, it could be a problem if FAM (gamin) is also needed for other services at the same time.

OPTIONAL: alpine packagers are a mess, removed FAM on recent, so older releases of alpine can use compiled FAM packages with sed -i -r 's#.*server.stat-cache-engine.*=.*# server.stat-cache-engine = "fam"#g' /etc/lighttpd/lighttpd.conf

2. php scripting: PHP fpm

In Alpine there are two main languages for programming dynamic web pages: PHP and LUA. Alpine is minimalist so not all PHP packages are need in most cases. Both repositories must be enabled (main and community). Here we explain the most common use in production.

PHP Installation

This material is obsolete ...

Update to a newer or generic php version (Discuss)

apk add php7 php7-bcmath php7-bz2 php7-ctype php7-curl php7-dom php7-enchant php7-exif php7-fpm php7-gd php7-gettext php7-gmp php7-iconv php7-imap php7-intl php7-json php7-mbstring php7-opcache php7-openssl php7-phar php7-posix php7-pspell php7-recode php7-session php7-simplexml php7-sockets php7-sysvmsg php7-sysvsem php7-sysvshm php7-tidy php7-xml php7-xmlreader php7-xmlrpc php7-xmlwriter php7-xsl php7-zip php7-sqlite3
Note: The packages below are only for specific situations. Install them only when needed (especially php-pear), for example, cacti and cacti-php7 depend on php7, but you must install only the cacti package, all the dependencies must be previously installed from stable.
apk add php7-pgsql php7-mysqli php7-mysqlnd php7-snmp php7-soap php7-ldap php7-pcntl php7-pear php7-shmop php7-wddx php7-cgi php7-pdo php7-snmp php7-tokenizer 
Note: The packages below are only for database access using php in specific ways. Install them only if you need them (specially php--pdo ones). For example, cacti and cacti-php7 depend on php7-mysqli, but you must install only the cacti package, all the dependencies like php7 and php7-mysqli must be previously installed from stable.
apk add php7-dba php7-sqlite3 php7-mysqli php7-mysqlnd php7-pgsql php7-pdo_dblib php7-pdo_odbc php7-pdo_pgsql php7-pdo_sqlite 

A special case is php7-odbc. Unless the others, that are able php to connect to only specific database, unixodbc is a universal way to do so. The most important difference is, for example, the php7-mysqli package has better functions to manage data via php.

PHP Global Configuration

  1. Use fix.pathinfo
  2. Set safe mode off
  3. Dont expose php code if something fails
  4. Set amount of memory limit for execution to 536Mb (most servers are minimum of 1 GB of RAM)
  5. Set upload size to 128Mb as maximun.
  6. Set POST max size to 256Mb based on the upload max size limit.
  7. Turn on the URL open method
  8. Set default charset to UTF-8 for increased compatibility
  9. Increase the execution time and the input time for.
sed -i -r 's|.*cgi.fix_pathinfo=.*|cgi.fix_pathinfo=1|g' /etc/php*/php.ini
sed -i -r 's#.*safe_mode =.*#safe_mode = Off#g' /etc/php*/php.ini
sed -i -r 's#.*expose_php =.*#expose_php = Off#g' /etc/php*/php.ini
sed -i -r 's#memory_limit =.*#memory_limit = 536M#g' /etc/php*/php.ini
sed -i -r 's#upload_max_filesize =.*#upload_max_filesize = 128M#g' /etc/php*/php.ini
sed -i -r 's#post_max_size =.*#post_max_size = 256M#g' /etc/php*/php.ini
sed -i -r 's#^file_uploads =.*#file_uploads = On#g' /etc/php*/php.ini
sed -i -r 's#^max_file_uploads =.*#max_file_uploads = 12#g' /etc/php*/php.ini
sed -i -r 's#^allow_url_fopen = .*#allow_url_fopen = On#g' /etc/php*/php.ini
sed -i -r 's#^.default_charset =.*#default_charset = "UTF-8"#g' /etc/php*/php.ini
sed -i -r 's#^.max_execution_time =.*#max_execution_time = 150#g' /etc/php*/php.ini
sed -i -r 's#^max_input_time =.*#max_input_time = 90#g' /etc/php*/php.ini

PHP-FPM Configuration

  1. Create directory for php socket and pid files, MUST BE EQUAL to openrc defined!
  2. Set into configuration file the socket path, MUST BE EQUAL to openrc defined!
  3. Set into configuration file the pid file path, MUST BE EQUAL to openrc defined!

mkdir -p /var/run/php-fpm7/

chown lighttpd:root /var/run/php-fpm7

sed -i -r 's|^.*listen =.*|listen = /run/php-fpm7/php7-fpm.sock|g' /etc/php*/php-fpm.d/www.conf

sed -i -r 's|^pid =.*|pid = /run/php-fpm7/php7-fpm.pid|g' /etc/php*/php-fpm.conf

sed -i -r 's|^.*listen.mode =.*|listen.mode = 0640|g' /etc/php*/php-fpm.d/www.conf

rc-update add php-fpm7 default

service php-fpm7 restart


The PHP-FPM defines a master process with a process pool for each service request. By default, there's only one process pool, www.

Default values are good for starting, but will need tuning later. The best is a static one, but testing is needed to get the right configuration.

Lighttpd + PHP-FPM

The web server comes with a minimal config file, so we must handle all the required settings:

  1. enable the mod_alias at the config file, a specific path is needed for cgi file security
  2. be sure and disable the fastcgi-php module by cgi only
  3. and then enable the fastcgi-php-fpm specific module then
  4. write a much much better approach of the php handler in the local server using the socket
  5. configure the php to use also the socket for direct connection locally
  6. restart the service to see changes at the browser

mkdir -p /var/www/localhost/cgi-bin

sed -i -r 's#\#.*mod_alias.*,.*#    "mod_alias",#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*include "mod_cgi.conf".*#   include "mod_cgi.conf"#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*include "mod_fastcgi.conf".*#\#   include "mod_fastcgi.conf"#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*include "mod_fastcgi_fpm.conf".*#   include "mod_fastcgi_fpm.conf"#g' /etc/lighttpd/lighttpd.conf

sed -e '/index-file.names/ s/^#*/#/' -i /etc/lighttpd/lighttpd.conf

cat > /etc/lighttpd/mod_fastcgi_fpm.conf << EOF
server.modules += ( "mod_fastcgi" )
index-file.names += ( "index.php" )
fastcgi.server = (
    ".php" => (
      "localhost" => (
        "socket"                => "/var/run/php-fpm7/php7-fpm.sock",
        "broken-scriptfilename" => "enable"
      ))
)
EOF

sed -i -r 's|^.*listen =.*|listen = /var/run/php-fpm7/php7-fpm.sock|g' /etc/php*/php-fpm.d/www.conf

sed -i -r 's|^.*listen.owner = .*|listen.owner = lighttpd|g' /etc/php*/php-fpm.d/www.conf

sed -i -r 's|^.*listen.group = .*|listen.group = lighttpd|g' /etc/php*/php-fpm.d/www.conf

sed -i -r 's|^.*listen.mode = .*|listen.mode = 0660|g' /etc/php*/php-fpm.d/www.conf

rc-service php-fpm7 restart

rc-service lighttpd restart

echo "<?php echo phpinfo(); ?>" > /var/www/localhost/htdocs/info.php

For testing, open a browser and go to http://<webserveripaddres>/info.php. You will see the info as used in production. There's no sense givig too much information to crackers. The "webserveripaddres" is the ip address of your setup/server machine.

After that, all the files with php will be procesed faster than used a host based. Under the /var/www/localhost/cgi-bin directory will be shown as http://localhost/cgi-bin/ path.

Multiple PHP-FPM cluster

As we said, FPM is managed by process pools, but the connection can be over a network or over a direct n socket. The configuration for a typical server that can handle an average number requests is with socket and localhost. For high availability, a CAT6 wired network connection of 1000Mbps and php-fpm by network connection in roundrobin mode is needed.

The PHP FPM pool will be on a specific machine and the web server(s) will simply connect to these machines with PHP to serve the PHP pages. The result is a cluster of lighttpd web servers against other PHP-FPM process clusters. The PHP code can be the same on all web servers and can connect to a single database.

At the Linux console the changes are, for example, two machines 10.10.1.10 and 10.10.2.10 both have php and lighttpd, so each will set up the php of the other:


mkdir -p /var/www/localhost/cgi-bin

sed -i -r 's#\#.*mod_alias.*,.*#    "mod_alias",#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*include "mod_cgi.conf".*#   include "mod_cgi.conf"#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*include "mod_fastcgi.conf".*#\#   include "mod_fastcgi.conf"#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*include "mod_fastcgi_fpm.conf".*#   include "mod_fastcgi_fpm.conf"#g' /etc/lighttpd/lighttpd.conf

cat > /etc/lighttpd/mod_fastcgi_fpm.conf << EOF
server.modules += ( "mod_fastcgi" )
index-file.names += ( "index.php" )
fastcgi.server = ( ".php" => 
  (
    ( "host" => "10.10.1.10",
      "port" => 9000
    ),
    ( "host" => "10.10.2.10",
      "port" => 9000 )
    )
  )
EOF

sed -i -r 's|^.*listen =.*|listen = 9000|g' /etc/php*/php-fpm.d/www.conf

sed -i -r 's|^.*listen.owner = .*|listen.owner = lighttpd|g' /etc/php*/php-fpm.d/www.conf

sed -i -r 's|^.*listen.group = .*|listen.group = lighttpd|g' /etc/php*/php-fpm.d/www.conf

sed -i -r 's|^.*listen.mode = .*|listen.mode = 0660|g' /etc/php*/php-fpm.d/www.conf

rc-service php-fpm7 restart

rc-service lighttpd restart

echo "<?php echo phpinfo(); ?>" > /var/www/localhost/htdocs/info.php

3. The DBMS part: mysql/mariadb

Alpine Linux has dummy counterpart packages for those not changed from mysql to mariadb.

Installation

Take into consideration the user mysql was created during package instalation. In the initialization section two users will be created in database init: root and mysql, and at that point only if they are in their respective system accounts, will they be able to connect to the database service.

apk add mysql mysql-client

Initialization

The datadir located at /var/lib/mysql must be owned by the mysql user and group. You can modify this behavior but you must edit the service file at /etc/init.d directory. Also, you need to set datadir=<YOUR_DATADIR> under section [mysqld] at the config file.

  1. Initialize the main mysql database, and the data dir as standardized to /var/lib/mysql by the rc script
  2. Then initialize the service, root account and socket connection are enabled without password at this point
  3. Set up the root account by asigning a proper password. This is pure paranoia. the next step does just that!
  4. Set up and init the installation by running the mysql_secure_installation
  5. Set up permissions for managing other users and databases
  6. Run the mysql_secure_installation script and answer the questions (see section below)

mysql_install_db --user=mysql --datadir=/var/lib/mysql

rc-service mariadb start

mysqladmin -u root password toor

mysql_secure_installation

  1. Enter current password for root (enter for none): must be provided because we set it previously. Correct response is OK, successfully used password, moving on...
  2. Switch to unix_socket authentication [Y/n] this must be disabled, so answer NO, and response will be ... skipping.
  3. Change the root password? [Y/n] Just press "n" only if you provided a good password, otherwise change it!
  4. Remove anonymous users? [Y/n] In any case, production system must remove it, so answer Y and proper respond mus be ... Success!.
  5. Disallow root login remotely? [Y/n] For sure answer Y and proper respond mus be ... Success!.
  6. Remove test database and access to it? [Y/n] Should be removed, so answer Y and proper respond mus be ... Success!.
  7. Reload privilege tables now? [Y/n] Aanswer Y and proper respond mus be ... Success!.

After reponse all the questions.. restart the service with rc-service mariadb restart

Configuration

Newer Alpine system packages can set in independent files. In any case, those commands always work and where not applicable, they'll ignore the output. For more info about that, see the MariaDB Configuration files section of the MariaDB wiki page.

  • On older Alpine system you must set config files for MAX ALLOWED PACKETS to minimun proper amount:
  • Only allow local connections in cases where there's only one server or no expected connections from others:
  • Set default charset to UTF8MB4
  • Add the start service process, but don't set it as a boot process because networking needs to already be running.
  • Restart the service to apply changes.

sed -i "s|.*max_allowed_packet\s*=.*|max_allowed_packet = 100M|g" /etc/mysql/my.cnf
sed -i "s|.*max_allowed_packet\s*=.*|max_allowed_packet = 100M|g" /etc/my.cnf.d/mariadb-server.cnf

sed -i "s|.*bind-address\s*=.*|bind-address=127.0.0.1|g" /etc/mysql/my.cnf
sed -i "s|.*bind-address\s*=.*|bind-address=127.0.0.1|g" /etc/my.cnf.d/mariadb-server.cnf

cat > /etc/my.cnf.d/mariadb-server-default-charset.cnf << EOF
[client]
default-character-set = utf8mb4

[mysqld]
collation_server = utf8mb4_unicode_ci
character_set_server = utf8mb4

[mysql]
default-character-set = utf8mb4
EOF

rc-service mariadb restart

rc-update add mariadb default

Upgrading: If you are unable to run any mysql commands after an upgrade, it's because MySQL cannot start. Try to run MySQL in safe mode with the mysqld_safe --datadir=/var/lib/mysql/ command, then run the mysql_upgrade -u root -p script. For more information see the MariaDB upgrading section of the MariaDB wiki page.

adminer: Web Frontend administration

Adminer is a simple standalone tool, tons of times faster than PhpMysqladmin that is great but has too many security issues and lots of complex settings. We need a single, simpler solution. One that's easy to manage and upgrade.

Take into consideration this needs as a prerequisite, the previous sections of the web server, php scripting and mysql/mariadb engine configured and running:



mkdir -p /var/www/webapps/adminer

wget https://github.com/vrana/adminer/releases/download/v4.7.6/adminer-4.7.6.php -O /var/www/webapps/adminer/adminer-4.7.6.php

ln -s adminer-4.7.6.php /var/www/webapps/adminer/index.php

cat > /etc/lighttpd/mod_adminer.conf << EOF
# NOTE: this requires mod_alias
alias.url += (
     "/adminer/"	    =>	    "/var/www/webapps/adminer/"
)
$HTTP["url"] =~ "^/adminer/" {
    # disable directory listings
    dir-listing.activate = "disable"
}
EOF

sed -i -r 's#\#.*mod_alias.*,.*#    "mod_alias",#g' /etc/lighttpd/lighttpd.conf

sed -i -r 's#.*include "mod_cgi.conf".*#   include "mod_cgi.conf"#g' /etc/lighttpd/lighttpd.conf

checkssl="";checkssl=$(grep 'include "mod_adminer.conf' /etc/lighttpd/lighttpd.conf);[[ "$checkssl" != "" ]] && echo listo || sed -i -r 's#.*include "mod_cgi.conf".*#include "mod_cgi.conf"\ninclude "mod_adminer.conf"#g' /etc/lighttpd/lighttpd.conf

rc-service lighttpd restart

The administrator must use the exact URL http://<ipaddress>/adminer/index.php There are two reasons: there's no directory listing and there's no direct PHP index reference on the web server, all because of paranoid settings.

Part 2: zabbix

Zabbix depends on which type of database you will use, here we will show you how to doit with mysql, as more easy to use, for production is recommended posrgresql as in

1. install zabbix packages

Remenber that Zabbix has 3 components, and the server is the main one

  • Central servers to represent the data ( can be one zabbix server, o combined zabbix server with more zabbix proxies)
  • Clients hosts to monitored (that is made by Agents, SNMP or just ICMP)
  • Distributed proxy servers (that is only need for hosts behind firewall or closed networks)

In the server we need the central base service at leas, and of course one agent for monitoring that server:


cat > /etc/apk/repositories << EOF
https://dl-4.alpinelinux.org/alpine/v$(cat /etc/alpine-release | cut -d'.' -f1,2)/main
https://dl-4.alpinelinux.org/alpine/v$(cat /etc/alpine-release | cut -d'.' -f1,2)/community
EOF

apk update

apk add zabbix zabbix-mysql zabbix-webif zabbix-setup zabbix-utils zabbix-agentd

Now lest configure the server and the UI frontend in that server:

2. Configure the base service

Server zabbix, or proxy one always need a main database, the service of monitoring is running with it, the UI and agents always send the data to the zabbix server or zabbix proxy (and from proxy to server).

Warning: The zabbix service DB user is zabbixdb and NOT zabbix, the user zabbixdb whatever you use postgresql or mysql, will not be used with password for agent monitoring, cos in postgresql will use the ident way autentication, and in mysql will use the socket way autentication: this makes sense cos user agent is zabbix and does not have home. This is the correct and most secure way.



mysql -u root -e "CREATE USER 'zabbix'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('clavezabix');"
mysql -u root -e "CREATE DATABASE zabbix CHARACTER SET utf8 COLLATE utf8_bin;"
mysql -u root -e "GRANT ALL PRIVILEGES ON zabbixdb.* TO 'zabbixdb'@'localhost' WITH GRANT OPTION;"

mysql -u zabbixdb --password=clavezabix zabbixdb < /usr/share/zabbix/database/mysql/schema.sql
mysql -u zabbixdb --password=clavezabix zabbixdb < /usr/share/zabbix/database/mysql/images.sql
mysql -u zabbixdb --password=clavezabix zabbixdb < /usr/share/zabbix/database/mysql/data.sql

sed -i 's|.*DBHost.*=.*|DBHost=localhost|g' /etc/zabbix/zabbix_server.conf
sed -i 's|DBName.*=.*|DBName=zabbixdb|g' /etc/zabbix/zabbix_server.conf
sed -i 's|.*DBPassword.*=.*|DBPassword=zabbixdb.db.1.com.1|g' /etc/zabbix/zabbix_server.conf
sed -i 's|.*DBUser.*=.*|DBUser=zabbixdb|g' /etc/zabbix/zabbix_server.conf
sed -i 's|.*DBSocket.*=.*|DBSocket=/run/mysqld/mysqld.sock|g' /etc/zabbix/zabbix_server.conf
sed -i 's|.*Fping6Location.*=.*|Fping6Location=|g' /etc/zabbix/zabbix_server.conf
sed -i 's|.*FpingLocation.*=.*|FpingLocation=/usr/sbin/fping|g' /etc/zabbix/zabbix_server.conf
sed -i 's|Nostname=.*|Nostname=monitor.zabbixnetwork|g' /etc/zabbix/zabbix_server.conf
sed -i 's|.*SourceIP.*=.*|SourceIP=0.0.0.0|g' /etc/zabbix/zabbix_server.conf

chown root:zabbix /usr/sbin/fping

rc-update add zabbix-server default

rc-service zabbix-server restart

Note: Remenber that the hostname of the server is monitor.zabbixnetwork, you can use the ip address too, but this name must be the same in the config files for active or passive servers, the web ui configured hostname server and/or zabbix configured hostname proxy server.

3. Setup and configure web frontend

The main server can be managed with the zabbix-frontend:


cp /usr/share/webapps/zabbix/conf/zabbix.conf.php.example /usr/share/webapps/zabbix/conf/zabbix.conf.php

sed -i "s|.*DB\['TYPE'\].*=.*|\$DB\['TYPE'\] = 'MYSQL';|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php
sed -i "s|.*DB\['SERVER'\].*=.*|\$DB\['SERVER'\] = 'localhost';|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php
sed -i "s|.*DB\['DATABASE'\].*=.*|\$DB\['DATABASE'\] = 'zabbixdb';|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php
sed -i "s|.*DB\['USER'\].*=.*|\$DB\['USER'\] = 'zabbixdb';|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php
sed -i "s|.*DB\['PASSWORD'\].*=.*|\$DB\['PASSWORD'\] = 'zabbixdb.db.1.com.1';|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php
sed -i "s|.*ZBX_SERVER_PORT.*=.*|\$ZBX_SERVER_PORT = '10051';|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php
sed -i "s|.*ZBX_SERVER_NAME.*=.*|\$ZBX_SERVER_NAME = 'monitor.ruices';|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php
sed -i "s|.*IMAGE_FORMAT_DEFAULT.*=.*|\$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_GIF;|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php
sed -i "s|.*ZBX_SERVER.*=.*'localhost';|\$ZBX_SERVER = 'localhost';|g" /usr/share/webapps/zabbix/conf/zabbix.conf.php

cat > /usr/share/webapps/zabbix/.user.ini << EOF
date.timezone = "America/Caracas"
display_errors  =  Off
log_errors  =  On
upload_max_filesize  =  16M
post_max_size  =  24M
memory_limit  =  512M
register_globals  =  Off
magic_quotes_gpc  =  Off
magic_quotes_runtime  =  Off
session.auto_start  = 0
mbstring.func_overload = 0
max_execution_time = 600
max_input_time = 600
EOF

We do not use the stupid link of direct put on htdocs, we are professional and we use aliasing, now lest configure the webserver to server the frontend by web:


cat > /etc/lighttpd/mod_zabbix.conf << EOF
alias.url += (
     "/zabbix/"    =>    "/usr/share/webapps/zabbix/"
)
\$HTTP["url"] =~ "^/zabbix/" {
    dir-listing.activate = "disable"
}
EOF

sed -i 's#\#.*mod_rewrite.*,.*#    "mod_rewrite",#g' /etc/lighttpd/lighttpd.conf
sed -i 's#\#.*mod_alias.*,.*#    "mod_alias",#g' /etc/lighttpd/lighttpd.conf
sed -i 's#\#.*mod_accesslog.*,.*#    "mod_accesslog",#g' /etc/lighttpd/lighttpd.conf
sed -i 's#\#.*mod_setenv.*,.*#    "mod_setenv",#g' /etc/lighttpd/lighttpd.conf
sed -i 's#\#.*mod_redirect.*,.*#    "mod_redirect",#g' /etc/lighttpd/lighttpd.conf

sed -i 's#.*include "mod_cgi.conf".*#   include "mod_cgi.conf"#g' /etc/lighttpd/lighttpd.conf

check="";check=$(grep 'include "mod_zabbix.conf' /etc/lighttpd/lighttpd.conf);[[ "$check" != "" ]] && echo listo || sed -i 's#.*include "mod_fastcgi_fpm.conf".*#include "mod_fastcgi_fpm.conf"\ninclude "mod_zabbix.conf"#g' /etc/lighttpd/lighttpd.conf

chown -R lighttpd:www-data /usr/share/webapps/zabbix/

rc-service lighttpd restart


You should now be able to browse to the Zabbix frontend: http://yourservername/zabbix/ or in http://localhost/zabbix.

The login using: Login name: Admin Password:zabbix. (as described at https://www.zabbix.com/documentation/4.0/manual/installation)

There's no need to web setup cos we made all in cli as best hackers admins.

Zabbix tools for items maps or scripts

There's no complete features in busybox so need more tools, also, Zabbix requires special permissions to use tools


apk add bash fping tcptraceroute coreutils net-snmp-tools nmap perl rrdtool font-dejavu net-snmp-libs

chown root:zabbix /usr/sbin/fping

chmod u+s /usr/bin/ping

chmod u+s /bin/ping

chmod u+s /usr/bin/nmap 

Warning: this is preferable to use sudo, that has more issues in security holes, so set ui bit is a security mess buyt less than the crap usage or "sudo", cos these tools are need to run as root to right usage


Zabbix and the Monitored host

Zabbix can monitor almost any device system, including Alpine Linux hosts, home computers, celphones, network devices, etc.

types of monitoring

The zabbix agent is a zabbix service that runs on computers and is fully feartured, the SNMP(Simple Network Manager Protocol) is a common standard protocol and is the second most supported, the ICMP(Internet Control Message Protocol) is the most used and simples way but most limited, check the features:

Feature By Agent By SNMP By ICMP
Ping to check alive (direct ip) Yes Yes but with zabbbix proxy if firewall Only on direct ip, no firewall
Retreive data from programs (direct ping) Yes Yes but with zabbbix proxy if firewall No
Send commands to manage Yes Yes but using zabbix proxy if firewall No
Runs on any device No, only computers Mostly any network device Yes
Runs on any OS YEs, limited in androita and mainframes Yes Yes
Requires provilegies Not necesary for most fearures It depends No
Note: Support to allow zabbix-agentd to view running processes on Alpine Linux has been added since linux-grsec-2.6.35.9-r2. Please ensure you have that kernel installed prior to attempting to run zabbix-agentd.

Ensure that the readproc group exists (support added since alpine-baselayout-2.0_rc1-r1), by adding the following line to /etc/group:

readproc:x:30:zabbix

Monitoring by Zabbix Agents

The agent way to monitoring is the most complete featured, but only applies to computers host, becouse the zabbiz-agent software is only available for those devices, for networking devices you must use ICMP or SNMP (check next subsection).

So, install the agent package and configure it on each host to be monitored/managed (on server too):

Note: Remenber that the hostname of the server is monitor.zabbixnetwork, you can use the ip address too, but this name must be the same in the config files for active or passive servers, the web ui configured hostname server and/or zabbix configured hostname proxy server.

cat > /etc/apk/repositories << EOF
https://dl-4.alpinelinux.org/alpine/v$(cat /etc/alpine-release | cut -d'.' -f1,2)/main
https://dl-4.alpinelinux.org/alpine/v$(cat /etc/alpine-release | cut -d'.' -f1,2)/community
EOF

apk update

apk add zabbix-agent net-snmp-libs net-snmp-agent-libs

sed -i 's|.*ListenPort.*=.*|ListenPort=10050|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|.*Hostname=.*|Hostname=monitordhost1|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|Server =.*|Server=localhost,monitor.zabbixnetwork|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|ServerActive.*=.*|ServerActive=localhost,monitor.zabbixnetwork |g' /etc/zabbix/zabbix_agentd.conf|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|.*EnableRemoteCommands.*=.*|EnableRemoteCommands=1|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|.*LogRemoteCommands.*=.*|LogRemoteCommands=1|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|# Include=.*|Include=/etc/zabbix/zabbix_agentd.d/*.conf|' /etc/zabbix/zabbix_agentd.conf

rc-update add zabbix-agentd default

rc-service zabbix-agentd restart

Note: The configured hostname in agent here is monitordhost1, you can use the ip address too, but this name must be the same in the config files for active or passive host configured in the web ui, if the agent way will be used.
Warning: The zabbix service DB user is zabbixdb and NOT zabbix, the user zabbixdb whatever you use postgresql or mysql, will not be used with password for agent monitoring, cos in postgresql will use the ident way autentication, and in mysql will use the socket way autentication: this makes sense cos user agent is zabbix and does not have home. This is the correct and most secure way.


Monitor by SNMP protocol

Then in each monitor system, you shoul define a community word due ISP's always will punish if you used public and open SNMP to world, inclusivelly you shoul protect inside your private network too, so on each host to be monitored you shoul made those commands to configure SNMP (including the zabbix server) using the :


apk add net-snmp net-snmp-perl net-snmp-tools

cat > /etc/snmp/snmpd.conf << EOF
view systemonly included .1.3.6.1.2.1.1
view systemonly included .1.3.6.1.2.1.25.1
rocommunity  monitor
rocommunity  public localhost
rocommunity  public default -V systemonly
sysLocation    client host at monitor.zabbixnetwork
sysContact     infoadmin <venenux@venenux.net>
sysServices    72
EOF

rc-update add snmpd default

rc-service snmpd restart 

This will allow to any host consult SNMP v2c with word "monitor", but is best you use if have distributed network a SNMP v3 autentiated.

Warning: So in zabbix web ui you must use "monitor" in the community word.


DB monitoring

Due limitations any host server that will have and database, must have and agent aither have behind or not have direct zabbix server/proxy connection.

In this case we used Mysql as example

on the monitored side: DBMS server to monitor


apk add zabbix-agent

sed -i 's|.*ListenPort.*=.*|ListenPort=10050|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|.*Hostname=.*|Hostname=theDBserver|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|Server =.*|Server=monitor.zabbixnetwork|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|ServerActive.*=.*|ServerActive=monitor.zabbixnetwork|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|.*EnableRemoteCommands.*=.*|EnableRemoteCommands=1|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|.*LogRemoteCommands.*=.*|LogRemoteCommands=1|g' /etc/zabbix/zabbix_agentd.conf
sed -i 's|# Include=|Include=/etc/zabbix/zabbix_agentd.d/*.conf|g' /etc/zabbix/zabbix_agentd.conf

rc-update add zabbix-agentd default

rc-service zabbix-agentd restart

apk add mariadb-client 

wget -O /etc/zabbix/zabbix-agent/userparameter_mysql.conf "https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/conf/zabbix_agentd/userparameter_mysql.conf?at=release/5.0"

mysql -u root -e "CREATE USER 'zabbix'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('zabbix.db.1.com.1');"
mysql -u root -e "GRANT USAGE,REPLICATION CLIENT,PROCESS,SHOW DATABASES,SHOW VIEW ON *.* TO 'zabbix'@'localhost';"

Note: The configured hostname in agent here is theDBserver, you can use the ip address too, but this name must be the same in the config files for active or passive host configured in the web ui, if the agent way will be used to monitor this server host.
Warning: An new issue of missing files is on alpine zabbix packages so read https://gitlab.alpinelinux.org/alpine/aports/-/issues/12791, for files that you could download manually


on the zabbix server side: to configure the monitored host

Use the template DB mysql o DB postgresql on the configured host and remenber that hostname in the configured host must be the same in the hostname configured in the agent configuration file of the monitored host.

For most details check the next section crash course:

Optional: Crash course in adding hosts, checks, and notifications

Note: This is optional since it's not specific to Alpine Linux, but I wanted a couple notes for how to perform a simple check on a server that doesn't have the agent installed on it, and be notified on state changes.

Administration -> Media Types -> Email

  • Setup server, helo, email from address

Administration -> Users

  • Setup each user who'll get notified, make sure they have media type "Email" added with their address

Configuration -> Hosts -> Create host

  • In Linux Servers hostgroup
  • Define dns name, ip, connect by IP
  • If the machine is a simple networking device that will only be monitored using SNMP, add it to Template_SNMPv2_Device, and you're done.

Configuration -> Templates -> Create template

  • Give it a name (Template_Alpine_Linux_Infra_HTTP)
  • In Templates group

Configuration -> Templates -> Template_Alpine_Linux_Infra_HTTP -> Items

  • Create Item
  • Host: Template_Alpine_Linux_Infra_HTTP
  • Description: HTTP Basic Check
  • Type: Simple_check
  • Key: http,80

Configuration -> Templates -> Template_Alpine_Linux_Infra_HTTP -> Triggers

  • Create Trigger
  • Name: "HTTP Trigger"
  • Expression: {Template_Alpine_Linux_Infra_HTTP:http,80.last(0)}#1
  • Severity: High

Configuration -> Actions ->

  • Create Action
  • name: Email notifications
  • Event source: triggers
  • Default Subject: add "{HOST.DNS}:" to the beginning
  • Default message: add "{HOST.DNS}:" to the beginning
  • Conditions: make host have to be from "Linux Servers" hostgroup, and Template_Alpine_Linux_Infra_HTTP:HTTP trigger" is not 1
  • Email affected users

See also

External resources and complete guides