From 35d887d1a5c1627341a48baee00bc6d30f85007d Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Mon, 7 Sep 2026 22:29:21 -0700 Subject: [PATCH 1/5] docs: comprehensive audit, Spine poller overhaul, and technical refactor - Overhaul Spine documentation (Spine.md) with complete end-to-end guide: architecture, prerequisites for modern distros (EL8/9 CRB, Ubuntu 22/24, Debian 11/12, FreeBSD), SUID root permissions, secure spine.conf setup (0640), Web UI configuration (Paths, Poller type, Data Collectors tuning), MySQL max_connections sizing, and troubleshooting. - Fix broken links and anchors (Hardening, SNMP data queries, Hook API references). - Fix broken image reference in Sites.md (add-site.JPG -> add-site.png). - Fix syntax errors in documentation PHP code blocks, including invalid parenthesization, missing SQL execute quotes, and malformed comments in FAQ. - Fix DevOps installation commands: use config.php.dist, correct systemctl service names for MySQL/MariaDB/PHP-FPM, remove nonexistent php-json, add missing composer install, and correct Debian/Ubuntu systemd environment path. - Correct grammatical errors, repeated words, and typos across all markdown documents. - Remove obsolete unreferenced duplicate installation guides. Signed-off-by: Thomas Vincent --- Aggregate-Templates.md | 2 +- Command-Line-Scripts.md | 2 +- Data-Collectors.md | 2 +- Data-Sources.md | 2 +- Export-Template.md | 2 +- Frequently-Asked-Questions.md | 4 +- GPRINTs.md | 6 +- General-Installing-Instructions.md | 18 +- Hardening-Cacti-Installation.md | 2 +- How-To-Determine-Template-Version.md | 2 +- How-To-Existing-SNMP-Data-Queries.md | 2 +- How-To-New-SNMP-Data-Queries.md | 2 +- How-To-Script-Data-Queries.md | 6 +- How-To-Work-With-Templates.md | 2 +- Install-Under-Enterprise-Linux-LAMP.md | 14 +- Install-Under-Enterprise-Linux-LEMP.md | 16 +- Install-Under-RHEL-Compatible_LAMP.md | 571 ------------------------ Install-Under-RHEL-Compatible_LEMP.md | 581 ------------------------- Installing-Under-Ubuntu-Debian.md | 19 +- Navigating-The-User-Interface.md | 2 +- Plugin-Guidelines.md | 2 +- Plugin-Hook-API-Ref.md | 35 +- Plugin-Reference.md | 2 +- RRDproxy.md | 2 +- RRDtool-Specific-Features.md | 2 +- SNMP-Options.md | 2 +- Settings-Data.md | 4 +- Settings-Paths.md | 11 +- Settings-Visual.md | 2 +- Sites.md | 13 +- Spine.md | 471 ++++++++++++-------- Standards-Code-Formatting.md | 2 +- Standards-FileSystem-Layout.md | 2 + Standards-PHP-Spec-Constructs.md | 20 +- Standards-SQL.md | 6 +- Templates.md | 4 +- User-Domains.md | 2 +- User-Management.md | 2 +- 38 files changed, 409 insertions(+), 1432 deletions(-) delete mode 100644 Install-Under-RHEL-Compatible_LAMP.md delete mode 100644 Install-Under-RHEL-Compatible_LEMP.md diff --git a/Aggregate-Templates.md b/Aggregate-Templates.md index b9960e51..f61d3769 100644 --- a/Aggregate-Templates.md +++ b/Aggregate-Templates.md @@ -39,7 +39,7 @@ references can be used in the `Prefix` section in order to uniquely identify the **Graph Item**. There are several `Graph Types` transformations that deal with how `AREA`, -`LINEX` and `STACK` items are handled in the resulting **Aggeregate Graph**, +`LINEX` and `STACK` items are handled in the resulting **Aggregate Graph**, they include: - **Keep Graph Types** - No transformation will occur. All `AREA`, `LINE`, and diff --git a/Command-Line-Scripts.md b/Command-Line-Scripts.md index f691d75d..ddda4cf1 100644 --- a/Command-Line-Scripts.md +++ b/Command-Line-Scripts.md @@ -30,7 +30,7 @@ briefly. | Script | Category | Description | | ------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| input_whitelist.php | Maintenance | To to onboard new Data Input Methods when using Cacti in a high security environment where new Data Input Methods must always be vetted before enabling for general use. | +| input_whitelist.php | Maintenance | To onboard new Data Input Methods when using Cacti in a high security environment where new Data Input Methods must always be vetted before enabling for general use. | | poller_graphs_reapply_names.php | Maintenance | Allows selecting re-running of Cacti's suggested values engine for Graphs | | poller_reindex_hosts.php | Maintenance | Batch method to re-index Cacti Devices | | analyze_database.php | Maintenance | Analyzes all Cacti tables rebuilding their index cardinality. Important to run after having added large numbers of Devices and Graphs to Cacti. | diff --git a/Data-Collectors.md b/Data-Collectors.md index 1456044e..4296a3ed 100644 --- a/Data-Collectors.md +++ b/Data-Collectors.md @@ -76,7 +76,7 @@ serves as the master **Data Collector** performing key maintenance operations for the entire system. In the edit page below, you can see what options are available when editing the -**Main Data Collector**. It is important the the hostname used is resolvable +**Main Data Collector**. It is important that the hostname used is resolvable by the **Remote Data Collectors**. ![Data Collectors Edit Main](images/data-collectors-edit-main.png) diff --git a/Data-Sources.md b/Data-Sources.md index 64640608..f1e87e19 100644 --- a/Data-Sources.md +++ b/Data-Sources.md @@ -69,7 +69,7 @@ may be interested in to view the Data sources in use ![device datasources](images/data-sources-per-device.png) You can also view Orphaned data sources in this view by setting Orphaned from -All to Orphaned Orphaned data sources are where the graph has been deleted but +Orphaned data sources are where the graph has been deleted but the data source was not deleted --- diff --git a/Export-Template.md b/Export-Template.md index 2a6f42f0..22baea36 100644 --- a/Export-Template.md +++ b/Export-Template.md @@ -4,7 +4,7 @@ Cacti allows **Device**, **Graph**, and **Data** Templates to be exported in XML format. You can access the screen below by going to `Console > Import / Export > Template Export`. When you get to this page, the most popular option is to export the **Device Template**, but the discretion is -upto the user. Once you pick the object type, the list of available templates is +up to the user. Once you pick the object type, the list of available templates is presented. The most popular option is to save to a file, but you have additional options. diff --git a/Frequently-Asked-Questions.md b/Frequently-Asked-Questions.md index fe433b8f..52babd64 100644 --- a/Frequently-Asked-Questions.md +++ b/Frequently-Asked-Questions.md @@ -49,6 +49,8 @@ presented with text that looks like: | modify it under the terms of the GNU General Public License | | as published by the Free Software Foundation; either version 2 | | of the License, or (at your option) any later version. | + +-------------------------------------------------------------------------+ +*/ ``` If this happens, it usually means that you have not enabled the PHP module to @@ -101,7 +103,7 @@ to run. **A:** Give Spine, the fast replacement for poller.php a try. Unlike poller.php, Spine is written in c and makes use of threads. On a typical installation, it is not uncommon for Spine to poll about 50000 items in less then 10 seconds. Spine -supports upto several threads per poller process and can also poll a single +supports up to several threads per poller process and can also poll a single hosts with more than a single thread. If using spine alone does not help, look to both the amount of memory and CPU diff --git a/GPRINTs.md b/GPRINTs.md index fee39e80..a96dcb9a 100644 --- a/GPRINTs.md +++ b/GPRINTs.md @@ -2,7 +2,7 @@ GPRINT Presets are an object in Cacti used for formatting Legend output on RRDtool Graphs. These GPrint Presets -closely fillow printf(), sprintf() ANSI syntax. They +closely follow printf(), sprintf() ANSI syntax. They are simple to create and edit. You can find the format strings on the [RRDtool Website](https://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html#PRINT). @@ -14,11 +14,11 @@ they are portable once created. In the image below, you can see the default GPrint Presets and the actions that can be taken on them. Keep in mind that once a GPrint Preset is being used by a **Graph** -or a **Graph Template**. It can not be removed. +or a **Graph Template**, it cannot be removed. ![GPRINT Presets](images/gprint-presets.png) -Below you can see the GPrint Preset edit screeen. +Below you can see the GPrint Preset edit screen. ![GPRINT Presets Edit](images/gprint-presets-edit.png) diff --git a/General-Installing-Instructions.md b/General-Installing-Instructions.md index dee68535..15eaa08d 100644 --- a/General-Installing-Instructions.md +++ b/General-Installing-Instructions.md @@ -60,7 +60,7 @@ packages will vary by operating system. ### Database -MySQL versions to 5.7 are supported. MariaDB to 10.2 is also supported. +MySQL versions 8.0/8.4+ and MariaDB versions 10.5 through 11.x+ are supported. - mysql @@ -148,22 +148,23 @@ prepared. Both ways have few pros and cons: pkg install git git clone https://git.FreeBSD.org/ports.git /usr/ports git -C /usr/ports pull - cd /usr/ports/databases/mariadb106-server (or mysql80-server) - make install + # Choose either MariaDB or MySQL: + cd /usr/ports/databases/mariadb106-server + make install clean cd /usr/ports/net-mgmt/cacti make install cd /usr/ports/net-mgmt/spine make install ``` -Apache and other software is possible install with package or Ports too. +Apache and other software can be installed using packages or Ports as well. Everything in FreeBSD is installed to /usr/local/ directory! In this documentation you can see paths like /etc/php.ini, /usr/bin/spine, ... Please use correct paths - /usr/local/etc, /usr/local/bin/spine, ... -For Spine set suid bit (without this isn't possible make ICMP ping): +For Spine set suid bit (without this, ICMP ping cannot function): ```sh chmod +s /usr/local/bin/spine @@ -218,13 +219,12 @@ DirectoryIndex index.php ## Configure MySQL/MariaDB -Set a password for the root user, and record this password. If you loose control +Set a password for the root user, and record this password. If you lose control of this password, you may have to re-install your database server in the case of any system disaster or recovering from a crash. -```sh -shell> mysqladmin --user=root password somepassword -shell> mysqladmin --user=root --password reload +```console +mysql_secure_installation ``` You must also load timezone information into the database. This is required for diff --git a/Hardening-Cacti-Installation.md b/Hardening-Cacti-Installation.md index 8e4c1584..10466db7 100644 --- a/Hardening-Cacti-Installation.md +++ b/Hardening-Cacti-Installation.md @@ -321,7 +321,7 @@ After applying all controls, confirm: ## See Also - [Installing Under Ubuntu/Debian](Installing-Under-Ubuntu-Debian.md) -- [Installing Under CentOS (LAMP)](Install-Under-CentOS_LAMP.md) +- [Installing Under Enterprise Linux (LAMP)](Install-Under-Enterprise-Linux-LAMP.md) - [Standards Security](Standards-Security.md) --- diff --git a/How-To-Determine-Template-Version.md b/How-To-Determine-Template-Version.md index d90180f5..ef6c365e 100644 --- a/How-To-Determine-Template-Version.md +++ b/How-To-Determine-Template-Version.md @@ -14,7 +14,7 @@ The next 32 digits are a random number. ## List of Versions -```php +```text "0.8.4" => "0000", "0.8.5" => "0001", "0.8.5a" => "0002", diff --git a/How-To-Existing-SNMP-Data-Queries.md b/How-To-Existing-SNMP-Data-Queries.md index 89438546..0d2e2008 100644 --- a/How-To-Existing-SNMP-Data-Queries.md +++ b/How-To-Existing-SNMP-Data-Queries.md @@ -69,7 +69,7 @@ indexes, the XML defines descriptive parameters (direction: input) to be displayed in the selection table. A walkthrough for this is given now. It is based on the already supplied -interfaces.xml XML file. +interfaces.xml file. ## Create a Data Query to tell cacti how to retrieve data diff --git a/How-To-New-SNMP-Data-Queries.md b/How-To-New-SNMP-Data-Queries.md index 5d2b2332..412f84e3 100644 --- a/How-To-New-SNMP-Data-Queries.md +++ b/How-To-New-SNMP-Data-Queries.md @@ -329,7 +329,7 @@ of the page and check **Index Type, Index Value and Output Type Id** ### Defining the Graph Template The Graph Template will define, how the data is presented. For more information -about the principles of operation, please see [Common Tasks](Common-Tasks.md). +about the principles of operation, please see [Principles of Operation](Principles-of-Operation.md). Please go to Graph Templates and Add: ![Defining Graph Template](images/gt-01.preview.png) diff --git a/How-To-Script-Data-Queries.md b/How-To-Script-Data-Queries.md index 1ea78822..ce03a045 100644 --- a/How-To-Script-Data-Queries.md +++ b/How-To-Script-Data-Queries.md @@ -135,9 +135,9 @@ As you see, my `` has 4 indices (interfaces). You may wonder why this function drops in. Well, lets have a look at `cacti_snmp_walk`. This function is part of cacti itself and eases the use of -SNMP. That's why I call it here. But unfortunately, it's output looks like +SNMP. That's why I call it here. But unfortunately, its output looks like: -```php +```text Array ( [0] => Array @@ -381,7 +381,7 @@ Last option is the **get** function # it has to respond with # the description of the interface for interface #1 # ------------------------------------------------------------------------- -} elseif ($cmd == "get" $$ isset($query_field) && isset($query_index)) { +} elseif ($cmd == "get" && isset($query_field) && isset($query_index)) { print (cacti_snmp_get($hostname, $snmp_community, $oids[$query_field] . ".$query_index", $snmp_version, $snmp_auth_username, $snmp_auth_password, $snmp_auth_protocol, $snmp_priv_passphrase, $snmp_priv_protocol, diff --git a/How-To-Work-With-Templates.md b/How-To-Work-With-Templates.md index 85baea1e..69079de1 100644 --- a/How-To-Work-With-Templates.md +++ b/How-To-Work-With-Templates.md @@ -112,7 +112,7 @@ next step. Now, you may add this new **Graph Template** to any **Devices** that responds to the udp OID we specified in the **Data Template**. But in this case, please wait a moment. Let's first proceed to the **Device Template** -and use this new **Graph Gemplate** for our first own **Device Template**. +and use this new **Graph Template** for our first own **Device Template**. ## Device Template Creation diff --git a/Install-Under-Enterprise-Linux-LAMP.md b/Install-Under-Enterprise-Linux-LAMP.md index b301f050..81c721d0 100644 --- a/Install-Under-Enterprise-Linux-LAMP.md +++ b/Install-Under-Enterprise-Linux-LAMP.md @@ -32,7 +32,7 @@ cores: 2 hostname: cacti memory: 2048 net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=mac-id,ip=dhcp,type=veth -ostype: ubuntu +ostype: rocky rootfs: local-lvm:vm-110-disk-0,size=8G swap: 2048 lxc.apparmor.profile: unconfined @@ -169,7 +169,7 @@ major divergence occurs that cannot be bridged. 1. Install MariaDB server ```console - yum install -y MariaDB-server MariaDB-client + dnf install -y mariadb-server mariadb ``` 2. Enable and start the service to ensure it starts when the system reboots @@ -242,7 +242,7 @@ during the installation. 2. Restart MySQL/MariaDB to apply the changes ```console - systemctl restart mysql + systemctl restart mysqld # or: systemctl restart mariadb ``` 3. Populate the timezone table @@ -307,7 +307,7 @@ PHP and the following packages are required for Cacti to operate. ```console yum install -y php php-common php-bcmath php-cli \ php-mysqlnd php-gd php-gmp php-intl \ - php-json php-ldap php-mbstring \ + php-ldap php-mbstring \ php-pdo php-pear php-snmp php-process \ php-xml php-zip composer ``` @@ -355,7 +355,7 @@ the basics for Cacti. 2. Create the config.php file ```console - mv -v /var/www/html/cacti/include/config.php-dist /var/www/html/cacti/include/config.php + cp -v /var/www/html/cacti/include/config.php.dist /var/www/html/cacti/include/config.php ``` 3. Update the `database_` fields with your own details. This section applies @@ -484,8 +484,8 @@ If you have trouble accessing the web interface, disable SELinux temporarily to determine whether the SELinux policy is the cause. Do not disable SELinux permanently. -The [CentOS SELinux HowTo](https://wiki.centos.org/HowTos/SELinux) provides -guidance on writing a correct SELinux policy. +The [Rocky Linux SELinux Guide](https://docs.rockylinux.org/guides/security/learning_selinux/) provides +guidance on managing SELinux policies. 1. Check SELinux status diff --git a/Install-Under-Enterprise-Linux-LEMP.md b/Install-Under-Enterprise-Linux-LEMP.md index f13b9eb6..f6e7960d 100644 --- a/Install-Under-Enterprise-Linux-LEMP.md +++ b/Install-Under-Enterprise-Linux-LEMP.md @@ -55,7 +55,7 @@ server { gzip_min_length 1000; location / { - try_files $uri $uri/ /index.php$query_string; + try_files $uri $uri/ /index.php?$query_string; } error_page 404 /404.html; @@ -108,7 +108,7 @@ server { } } - location /cacti/rra/ { + location ~ ^/(cacti/)?(rra|log|cache)/ { deny all; } @@ -170,7 +170,7 @@ major divergence occurs that cannot be bridged. 1. Install MariaDB server ```console - yum install -y MariaDB-server MariaDB-client + dnf install -y mariadb-server mariadb ``` 2. Enable and start the service @@ -244,7 +244,7 @@ prompt you with more accurate recommendations during installation. 2. Restart MySQL/MariaDB to apply the changes ```console - systemctl restart mysql + systemctl restart mysqld # or: systemctl restart mariadb ``` 3. Populate the timezone table @@ -309,7 +309,7 @@ PHP and the following packages are required for Cacti to operate. ```console yum install -y php php-common php-bcmath php-cli \ php-mysqlnd php-gd php-gmp php-intl \ - php-json php-ldap php-mbstring \ + php-ldap php-mbstring \ php-pdo php-pear php-snmp php-process \ php-xml php-zip php-fpm composer ``` @@ -403,7 +403,7 @@ the basics for Cacti. 2. Create the config.php file ```console - mv -v /usr/share/nginx/html/cacti/include/config.php-dist /usr/share/nginx/html/cacti/include/config.php + cp -v /usr/share/nginx/html/cacti/include/config.php.dist /usr/share/nginx/html/cacti/include/config.php ``` 3. Update the `database_` fields with your own details. This section applies @@ -512,8 +512,8 @@ If you have trouble accessing the web interface, disable SELinux temporarily to determine whether the SELinux policy is the cause. Do not disable SELinux permanently. -The [CentOS SELinux HowTo](https://wiki.centos.org/HowTos/SELinux) provides -guidance on writing a correct SELinux policy. +The [Rocky Linux SELinux Guide](https://docs.rockylinux.org/guides/security/learning_selinux/) provides +guidance on managing SELinux policies. 1. Check SELinux status diff --git a/Install-Under-RHEL-Compatible_LAMP.md b/Install-Under-RHEL-Compatible_LAMP.md deleted file mode 100644 index 28620e6e..00000000 --- a/Install-Under-RHEL-Compatible_LAMP.md +++ /dev/null @@ -1,571 +0,0 @@ -# Installing on CentOS/RHEL/Rocky Linux/AlmaLinux - -> **Note:** CentOS Linux reached end-of-life on June 30, 2024 (CentOS 7) and December 31, 2021 (CentOS 8). New installations should use [Rocky Linux](https://rockylinux.org/) or [AlmaLinux](https://almalinux.org/), which are binary-compatible RHEL rebuilds. The commands in this guide apply to both. - -> **Note**: As of Cacti 1.2.31, PHP 8.1 is required and PHP Composer is required. -> Composer will be used to ensure all of the libraries are installed and are up to date. - -## LAMP (Linux, Apache, MySQL/MariaDB, PHP) Required packages - -### Web Server (Apache) - -1. For RHEL/Rocky Linux/AlmaLinux 8+ - - ```console - dnf module reset php - dnf module enable php:8.1 - ``` - -### A special Note on installing Cacti in LXC Containers such as the ones found on Proxmox - -It is recommended to create a privileged container you may need to update your containers config file with - -```console -lxc.apparmor.profile: unconfined -``` -This will allow for ICMP ping and other functions to work - -A tested configuration file like below should be good however tune to your needs/standards - -```console -arch: amd64 -cores: 2 -hostname: cacti -memory: 2048 -net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=mac-id,ip=dhcp,type=v> -ostype: ubuntu -rootfs: local-lvm:vm-110-disk-0,size=8G -swap: 2048 -lxc.apparmor.profile: unconfined -``` - - -### A special note for systems using PHP-FPM - -Prior to starting the setup process of Cacti you should restart the PHP-FPM -Daemon to rebuild the Cache or you may receive a HTTP 500 Error - - ```console - systemctl restart php-fpm - ``` - -2. Install Apache - - ```console - dnf install -y httpd - ``` - -3. Enable and start the service to ensure it starts when the system reboots - - ```console - systemctl start httpd - systemctl enable httpd - ``` - -### Example configuration file for Apache 2.4 and SSL - -This example configuration assumes you have your own certificates already. You -should make sure you change the paths to match your setup. - -Replace `YourOwnCertFile.crt` and `YourOwnCertFile.key` with the names of the -files holding your certificate (`.crt`) and private key (`.key`). - -```console -# -# Cacti: An RRDtool based graphing web application -# - -# For security reasons, the Cacti web interface is accessible only to -# localhost in the default configuration. If you want to allow other clients -# to access your Cacti installation, change the httpd ACLs below. -# For example: -# On httpd 2.4, change "Require host localhost" to "Require all granted". -# On httpd 2.2, change "Allow from localhost" to "Allow from all". - - - LogLevel warn - - ServerName cacti.yourdomain.com - ServerAdmin admin@yourdomain.com - - DocumentRoot "/var/www/html/cacti" - Alias /cacti /var/www/html/cacti - SSLEngine On - SSLCertificateFile /etc/ssl/certs/YourOwnCertFile.crt - SSLCertificateKeyFile /etc/ssl/private/YourOwnCertKey.key - - - - # httpd 2.4 - Require all granted - - - # httpd 2.2 - Order deny,allow - Deny from all - Allow from all - - - - - # mod_security overrides. - # Uncomment these if you use mod_security. - # allow POST of application/x-www-form-urlencoded during install - #SecRuleRemoveById 960010 - # permit the specification of the RRDtool paths during install - #SecRuleRemoveById 900011 - - - # These sections marked "Require all denied" (or "Deny from all") - # should not be modified. - # These are in place in order to harden Cacti. - - - Require all denied - - - Order deny,allow - Deny from all - - - - - Require all denied - - - Order deny,allow - Deny from all - - - -``` - -### Database Server - -The choice between MySQL server and MariaDB is normally down to the OS -maintainers if you use one of the predefined LAMP setup installations. If you -are deciding between these yourself, you should research this via your -favorite search engine. - -Whilst MySQL is the original open source SQL database server created in 1995 -which is now owned by Oracle, MariaDB is designed as a drop-in replacement by -some of the original MySQL developers / owners. This will likely continue to -be a drop-in alternative until there is a major divergence that can not be -bridged. - -#### MySQL - -1. Install MySQL server - - ```console - dnf install -y mysql mysql-server - ``` - -2. Enable and start the service to ensure it starts when the system reboots - - ```console - systemctl enable mysqld - systemctl start mysqld - ``` - -#### MariaDB - -1. Install MariaDB server - - ```console - dnf install -y MariaDB-server MariaDB-client - ``` - -2. Enable and start the service to ensure it starts when the system reboots - - ```console - systemctl enable mariadb - systemctl start mariadb - ``` - -### MySQL/MariaDB common tasks and recommendations - -**IMPORTANT**: Secure your MySQL installation before doing any more changes - -```console -/usr/bin/mysql_secure_installation -``` - -The following MySQL/MariaDB recommendations may vary depending on your system -setup. In any case, Cacti will prompt you with more accurate recommendations -during the installation. - -1. Edit your `server.cnf` file - - ```console - vim /etc/my.cnf.d/server.cnf - ``` - - The following `[mysqld]` section is a base configuration. The installer - will provide recommendations based on the actual system which will be more - tailored to your environment. - - If using MariaDB less than version 11.1 or MySQL use the settings below. - Note that you should revise up or down your settings depending on - the Cacti recommendation that you see once you start the installer. - - ```shell - [mysqld] - character-set-server=utf8mb4 - collation-server=utf8mb4_unicode_ci - max_allowed_packet = 16777777 - join_buffer_size = 32M - innodb_file_per_table = ON - innodb_buffer_pool_size = 250M - innodb_flush_log_at_trx_commit = 2 - log-error = /var/log/mysql/mysql-error.log - log-queries-not-using-indexes = 1 - slow-query-log = 1 - slow-query-log-file = /var/log/mysql/mysql-slow.log - ``` - - If using MariaDB 11.0 or higher, use the settings below: - - ```shell - [mariadb] - max_heap_table_size=500M - character_set_client=utf8mb4 - character_set_server=utf8mb4 - collation_server=utf8mb4_unicode_ci - innodb_buffer_pool_size=8G - innodb_doublewrite=OFF - tmp_table_size=500M - log-error = /var/log/mysql/mysql-error.log - log-queries-not-using-indexes = 1 - slow-query-log = 1 - slow-query-log-file = /var/log/mysql/mysql-slow.log - ``` - -3. Restart MySQL/MariaDB service to pick up the changes - - ```console - systemctl restart mysql - ``` - -4. Populate timezone table with available timezones - - ```console - mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql - ``` - -#### Setup Cacti database - -1. Login to MySQL/MariaDB as root to create Cacti database - - ```console - # mysql -u root -p - MariaDB [(none)]> create database if not exists cacti; - Query OK, 1 row affected (0.00 sec) - ``` - -2. Import Cacti database from SQL file - - ```sql - MariaDB [(none)]> use cacti; - Database changed - MariaDB [(cacti)]> source /var/www/html/cacti/cacti.sql - ``` - -3. Grant Cacti username access to Cacti database. Replace `your_cacti_username` - and `your_cacti_password` with your own details. - - ```sql - MariaDB [(none)]> CREATE USER 'your_cacti_username'@'localhost' - IDENTIFIED BY 'your_cacti_password'; - Query OK, 0 rows affected (0.00 sec) - MariaDB [(none)]> GRANT ALL PRIVILEGES ON cacti.* TO 'your_cacti_username'@'localhost'; - Query OK, 0 rows affected (0.00 sec) - ``` - -4. Grant cacti username to MySQL timezone table - - ```sql - MariaDB [(none)]> GRANT SELECT ON mysql.time_zone_name TO 'your_cacti_username'@'localhost'; - Query OK, 0 rows affected (0.00 sec) - MariaDB [(none)]> FLUSH PRIVILEGES; - Query OK, 0 rows affected (0.00 sec) - ``` - -5. Save the Database Charset and Collation - - ```sql - MariaDB [(none)]> ALTER DATABASE cacti CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - MariaDB [(none)]> FLUSH PRIVILEGES; - ``` - -### Common packages - -#### PHP - -PHP and various packages are all required by Cacti for successful operation - -1. Install PHP and required packages. - - ```console - dnf install -y php php-common php-bcmath php-cli \ - php-mysqlnd php-gd php-gmp php-intl \ - php-json php-ldap php-mbstring \ - php-pdo php-pear php-snmp php-process \ - php-xml php-zip composer - ``` - -2. Set a timezone to your PHP.INI configuration - - Edit php.ini typically located at `/etc/php.ini` - - ```console - date.timezone = Pacific/Auckland - ``` - -#### RRDtool - -RRDtool is required to store the data retrieved from devices in `.rra` files to -produce the graphs which are shown within Cacti - -```console -dnf install -y rrdtool -``` - -#### SNMP - -SNMP is used to query most devices for information. - -```console -dnf install -y net-snmp net-snmp-utils -``` - -### Cacti - -The following steps will show you how to manually download, install and -configure the basics for Cacti. - -1. Download Cacti source code from [Cacti Web - Site](https://www.cacti.net/download_cacti.php) - - ```console - cd /tmp - wget https://www.cacti.net/downloads/cacti-1.y.z.tar.gz - tar -zxvf cacti-1.y.z.tar.gz - mv -v cacti-1.y.z /var/www/html/cacti - ``` - -2. Edit the config.php file - - ```console - mv -v /var/www/html/cacti/include/config.php-dist /var/www/html/cacti/include/config.php - ``` - -3. Update `database_` fields with your own details. This section only applies - to the Main Cacti Server - - ```php - $database_type = 'mysql'; - $database_default = 'your_cacti_database'; - $database_hostname = 'localhost'; - $database_username = 'your_cacti_username'; - $database_password = 'your_cacti_password'; - $database_port = '3306'; - $database_ssl = false; - $database_ssl_key = ''; - $database_ssl_cert = ''; - $database_ssl_ca = ''; - ``` - -4. Create your cron task file or systemd units file - - Starting with Cacti 1.2.16, you have the option to use either the - legacy Crontab entry, or an optional cactid units file and server - to run your Cacti pollers. - - For Crontab use, follow the instructions below: - - Create and edit `/etc/cron.d/cacti` file. - Make sure to setup the correct path to poller.php - - ```console - */5 * * * * apache php /var/www/html/cacti/poller.php &>/dev/null - ``` - - For systemd unit's file install, you will need to modify the - included units file to following your install location - and desired user and group's to run the Cacti poller as. - To complete the task, follow the procedure below: - - ```console - vim /var/www/html/cacti/service/cactid.service (edit the path) - touch /etc/sysconfig/cactid - cp -p /var/www/html/cacti/service/cactid.service /etc/systemd/system - systemctl enable cactid - systemctl start cactid - systemctl status cactid - ``` - - The systemd units file makes managing a highly available Cacti - setup a bit more convenient. - -#### Spine - -1. Install the necessary packages to compile and install spine - - On RHEL 8 / Rocky Linux 8 / AlmaLinux 8, enable the PowerTools repository first: - - ```console - dnf config-manager --set-enabled powertools - ``` - - On RHEL 9 / Rocky Linux 9 / AlmaLinux 9, the equivalent repository is called `crb`: - - ```console - dnf config-manager --set-enabled crb - ``` - - Then install the build dependencies: - - ```console - dnf install -y autoconf automake libtool dos2unix help2man \ - openssl-devel mariadb-devel net-snmp-devel - ``` - -2. Download spine source code from [Cacti Web - Site](https://www.cacti.net/spine_download.php) - - Go to /tmp to download the source code and extract it - - ```console - cd /tmp - wget https://www.cacti.net/downloads/spine/cacti-spine-1.y.z.tar.gz - tar -zxvf cacti-spine-1.y.z.tar.gz - cd cacti-spine-1.y.z - ``` - -3. Run the configure script and compile spine. - - ```console - # ./configure - # make & make install - config/install-sh -c -d '/usr/local/spine/bin' - /bin/sh ./libtool --mode=install /usr/bin/install -c spine '/usr/local/spine/bin' - libtool: install: /usr/bin/install -c spine /usr/local/spine/bin/spine - config/install-sh -c -d '/usr/local/spine/etc' - /usr/bin/install -c -m 644 spine.conf.dist '/usr/local/spine/etc' - config/install-sh -c -d '/usr/local/spine/share/man/man1' - /usr/bin/install -c -m 644 spine.1 '/usr/local/spine/share/man/man1' - ``` - -4. Edit spine.conf - - Rename spine.conf.dist to spine.conf - - ```console - mv -v /usr/local/spine/etc/spine.conf.dist /usr/local/spine/etc/spine.conf - vi /usr/local/spine/etc/spine.conf - ``` - -5. Now set up your database connection - - ```console - DB_Host localhost - DB_Database your_cacti_database - DB_User your_cacti_username - DB_Pass your_cacti_password - DB_Port 3306 - #DB_UseSSL 0 - #RDB_SSL_Key - #RDB_SSL_Cert - #RDB_SSL_CA - ``` - -### Security Enhanced Linux (SELinux) - -If you suspect SELinux is blocking Cacti, disable it temporarily to confirm, then re-enable it and apply the correct policy rather than leaving it disabled. - -The [RHEL SELinux documentation](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/using_selinux/) covers policy management in depth and applies equally to Rocky Linux and AlmaLinux. - -1. Check SELinux status - - ```console - getenforce - ``` - -2. Disable SELinux temporarily for testing - - ```console - setenforce 0 - ``` - -3. Re-enable SELinux - - ```console - setenforce 1 - ``` - -4. Configure SELinux booleans for Cacti - - Cacti requires two booleans so Apache can reach the database and make outbound SNMP connections during polling: - - ```console - setsebool -P httpd_can_network_connect 1 - setsebool -P httpd_can_network_connect_db 1 - ``` - -5. Set file contexts (only needed if Cacti is outside `/var/www/html`) - - If you installed Cacti to a non-default path, apply the correct SELinux file contexts. The `semanage` command is provided by `policycoreutils-python-utils`; install it first if not already present: - - ```console - dnf install -y policycoreutils-python-utils - ``` - - Replace `/path/to/cacti` with your actual install path: - - ```console - semanage fcontext -a -t httpd_sys_content_t "/path/to/cacti(/.*)?" - semanage fcontext -a -t httpd_sys_rw_content_t "/path/to/cacti/rra(/.*)?" - semanage fcontext -a -t httpd_sys_rw_content_t "/path/to/cacti/log(/.*)?" - restorecon -Rv /path/to/cacti - ``` - - These labels grant Apache read access to Cacti's files and write access to the RRD and log directories. Without `httpd_sys_rw_content_t` on `rra/` and `log/`, graph generation silently fails even when UNIX permissions appear correct. - -### Considerations when using Proxies in front of Cacti (Cacti 1.2.23+) - -For optimal security, only specify the HTTP headers that are set by your proxy -software to prevent unauthorized access. -These can be set by editing the following section of config.php - -```ini - * Allow the use of Proxy IPs when searching for client - * IP to be used - * - * This can be set to one of the following: - * - false: to use only REMOTE_ADDR - * - true: to use all allowed headers (not advised) - * - array of one or more the following: - *'X-Forwarded-For', - *'X-Client-IP', - *'X-Real-IP', - *'X-ProxyUser-Ip', - *'CF-Connecting-IP', - *'True-Client-IP', - *'HTTP_X_FORWARDED', - *'HTTP_X_FORWARDED_FOR', - *'HTTP_X_CLUSTER_CLIENT_IP', - *'HTTP_FORWARDED_FOR', - *'HTTP_FORWARDED', - *'HTTP_CLIENT_IP', - * - * NOTE: The following will always be checked: - *'REMOTE_ADDR', - */ -$proxy_headers = null; -``` - -**Note:** If you installed Cacti outside `/var/www/html`, run the `semanage fcontext` and `restorecon` commands from step 5 of the SELinux section above to apply the correct file contexts. - ---- -Copyright (c) 2004-2026 The Cacti Group diff --git a/Install-Under-RHEL-Compatible_LEMP.md b/Install-Under-RHEL-Compatible_LEMP.md deleted file mode 100644 index ae7d13d1..00000000 --- a/Install-Under-RHEL-Compatible_LEMP.md +++ /dev/null @@ -1,581 +0,0 @@ -# Installing on CentOS/RHEL/Rocky Linux/AlmaLinux (LEMP) - -> **Note:** CentOS Linux reached end-of-life on June 30, 2024 (CentOS 7) and December 31, 2021 (CentOS 8). New installations should use [Rocky Linux](https://rockylinux.org/) or [AlmaLinux](https://almalinux.org/), which are binary-compatible RHEL rebuilds. The commands in this guide apply to both. - -> **Note**: As of Cacti 1.2.31, PHP 8.1 is required and PHP Composer is required. -> Composer will be used to ensure all of the libraries are installed and are up to date. - -## LEMP (Linux, Nginx, MySQL, PHP) Required packages - -### Web Server - -1. Install Nginx - - ```console - dnf install -y nginx - ``` - -2. Enable and start the service to ensure it starts when the system reboots - - ```console - systemctl start nginx - systemctl enable nginx - ``` - -### Example configuration file for Nginx and SSL - -This example assumes you have your own certificates already. You should make -sure you change the paths to match your setup. - -Replace `YourOwnCertFile.crt` and `YourOwnCertFile.key` with the names of the -files holding your certificate (`.crt`) and private key (`.key`). - -```console -/etc/nginx/conf.d/cacti.conf -``` - -```console -# Advanced config for NGINX -#server_tokens off; -add_header X-XSS-Protection "1; mode=block"; -add_header X-Content-Type-Options nosniff; - -# Redirect all HTTP traffic to HTTPS -server { - listen 80; - server_name cacti.yourdomain.com; - return 301 https://$host$request_uri; -} - -# SSL configuration -server { - listen 443 ssl default deferred; - server_name cacti.yourdomain.com; - root /usr/share/nginx/html/cacti; - index index.php index.html index.htm; - - # Compression increases performance0 - gzip on; - gzip_types text/plain text/html text/xml text/css application/xml application/javascript application/x-javascript application/rss+xml application/xhtml+xml; - gzip_proxied no-cache no-store private expired auth; - gzip_min_length 1000; - - location / { - try_files $uri $uri/ /index.php$query_string; - } - - error_page 404 /404.html; - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html/; - } - - location ~ \.php$ { - alias /usr/share/nginx/html/cacti; - index index.php - try_files $uri $uri/ =404; - fastcgi_split_path_info ^(.+\.php)(/.+)$; - - # you may have to change the path here for your OS - fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - include /etc/nginx/fastcgi_params; - } - - location /cacti { - root /usr/share/nginx/html/; - index index.php index.html index.htm; - location ~ ^/cacti/(.+\.php)$ { - try_files $uri =404; - root /usr/share/nginx/html; - - # you may have to change the path here for your OS - fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - include /etc/nginx/fastcgi_params; - } - - location ~* ^/cacti/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ { - expires max; - log_not_found off; - } - } - - location /doc/ { - alias /usr/share/nginx/html/cacti/doc/; - location ~* ^/docs/(.+\.(html|md|txt))$ { - root /usr/share/nginx/html/cacti/; - autoindex on; - allow 127.0.0.1; # Change this to allow your local networks - allow ::1; - deny all; - } - } - - location /cacti/rra/ { - deny all; - } - - ## Access and error logs. - access_log /var/log/nginx/cacti_access.log; - error_log /var/log/nginx/cacti_error.log info; - - ssl_certificate /etc/ssl/certs/YourOwnCertFile.crt; - ssl_certificate_key /etc/ssl/private/YourOwnCertKey.key; - - # Improve HTTPS performance with session resumption - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 5m; - - # Prefer server cipher order; use only TLS 1.2+ (TLS 1.0/1.1 prohibited by RFC 8996) - ssl_prefer_server_ciphers on; - ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:!ADH:!AECDH:!MD5; - - ssl_protocols TLSv1.2 TLSv1.3; - - # Diffie-Hellman parameter for DHE cipher suites - # $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 - ssl_dhparam /etc/ssl/certs/dhparam.pem; - - # Enable HSTS (https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security) - add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; -} -``` - -### Database Server - -The choice between MySQL server and MariaDB is normally down to the OS -maintainers if you use one of the predefined LAMP setup installations. If you -are deciding between these yourself, you should research this via your favorite -search engine. - -Whilst MySQL is the original open source SQL database server created in 1995 -which is now owned by Oracle, MariaDB is designed as a drop-in replacement by -some of the original MySQL developers / owners. This will likely continue to be -a drop-in alternative until there is a major divergence that can not be bridged. - -#### MySQL - -1. Install MySQL server - - ```console - dnf install -y mysql mysql-server - ``` - -2. Enable and start the service to ensure it starts when the system reboots - - ```console - systemctl enable mysqld - systemctl start mysqld - ``` - -#### MariaDB - -1. Install MariaDB server - - ```console - dnf install -y MariaDB-server MariaDB-client - ``` - -2. Enable and start the service to ensure it starts when the system reboots - - ```console - systemctl enable mariadb - systemctl start mariadb - ``` - -### MySQL/MariaDB common tasks and recommendations - -**IMPORTANT**: Secure your MySQL installation before doing any more changes - -```console -/usr/bin/mysql_secure_installation -``` - -The following MySQL/MariaDB recommendations may vary depending on your system -setup. In any case, Cacti will prompt you with more accurate recommendations -during the installation. - -1. Edit your **server.cnf** file - - ```console - vim /etc/my.cnf.d/server.cnf - ``` - - The following `[mysqld]` section is a base configuration. The installer will - provide recommendations based on the actual system which will be more - tailored to your environment. - - If using MariaDB less than version 11.1 or MySQL use the settings below. - Note that you should revise up or down your settings depending on - the Cacti recommendation that you see once you start the installer. - - ```shell - [mysqld] - character_set_client = utf8mb4 - character-set-server = utf8mb4 - collation-server = utf8mb4_unicode_ci - max_allowed_packet = 16777777 - max_heap_table_size = 500M - join_buffer_size = 32M - innodb_file_per_table = ON - innodb_buffer_pool_size = 500M - innodb_flush_log_at_trx_commit = 2 - log-error = /var/log/mysql/mysql-error.log - log-queries-not-using-indexes = 1 - slow-query-log = 1 - slow-query-log-file = /var/log/mysql/mysql-slow.log - ``` - - If using MariaDB 11.0 or higher, use the settings below: - - ```shell - [mariadb] - character_set_client = utf8mb4 - character_set_server = utf8mb4 - collation_server = utf8mb4_unicode_ci - max_heap_table_size = 500M - join_buffer_size = 32M - innodb_buffer_pool_size = 8G - innodb_doublewrite = OFF - tmp_table_size = 500M - log-error = /var/log/mysql/mysql-error.log - log-queries-not-using-indexes = 1 - slow-query-log = 1 - slow-query-log-file = /var/log/mysql/mysql-slow.log - ``` - -2. Restart MySQL/MariaDB service to pick up the changes - - ```console - systemctl restart mysql - ``` - -3. Populate timezone table with available timezones - - ```console - mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql - ``` - -#### Setup Cacti database - -1. Login to MySQL/MariaDB as root to create Cacti database - - ```console - # mysql -u root -p - MariaDB [(none)]> create database if not exists cacti; - Query OK, 1 row affected (0.00 sec) - ``` - -2. Import Cacti database from SQL file - - ```sql - MariaDB [(none)]> use cacti; - Database changed - MariaDB [(cacti)]> source /usr/share/nginx/html/cacti/cacti.sql - ``` - -3. Grant Cacti username access to Cacti database. Replace `your_cacti_username` - and `your_cacti_password` with your own details. - - ```sql - MariaDB [(none)]> GRANT ALL PRIVILEGES ON cacti.* TO 'your_cacti_username'@'localhost' IDENTIFIED BY 'your_cacti_password'; - Query OK, 0 rows affected (0.00 sec) - ``` - -4. Grant cacti username to MySQL timezone table - - ```sql - MariaDB [(none)]> 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) - ``` - -5. Save the Database Charset and Collation - - ```sql - MariaDB [(none)]> ALTER DATABASE cacti CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - MariaDB [(none)]> FLUSH PRIVILEGES; - ``` - -### Common PHP packages - -#### PHP - -PHP and various packages are all required by Cacti for successful operation - -1. Install PHP and required packages. - - ```console - dnf install -y php php-common php-bcmath php-cli \ - php-mysqlnd php-gd php-gmp php-intl \ - php-json php-ldap php-mbstring \ - php-pdo php-pear php-snmp php-process \ - php-xml php-zip php-fpm composer - ``` - ---- - -Note: **php-fpm** is only required if your Web Server is Nginx - -1. Set a timezone to your PHP.INI configuration - - Edit php.ini, typically located at `/etc/php.ini` - - ```console - date.timezone = Pacific/Auckland - ``` - -2. Disable insecure `cgi.fix_pathinfo` - - ```console - cgi.fix_pathinfo=0 - ``` - -#### Setup php-fpm - -1. Enable and start the service to ensure it starts when the system reboots - - ```console - systemctl start php-fpm - systemctl enable php-fpm - ``` - -2. Edit `/etc/php-fpm.d/www.conf` - - Find `listen = 127.0.0.1:9000` and add the following line below - - ```console - listen = /var/run/php-fpm/php-fpm.sock - ``` - - Find `listen.owner` and `listen.group` and set them to nginx - - ```console - listen.owner = nginx - listen.group = nginx - ``` - - Find user and group and set them to `nginx` - - ```console - user = nginx - group = nginx - ``` - - Restart php-fpm to pick up the changes - - ```console - systemctl restart php-fpm - ``` - -### RRDtool - -RRDtool is required to store the data retrieved from devices in `.rra` files to -produce the graphs which are shown within Cacti - -```console -dnf install -y rrdtool -``` - -### SNMP - -SNMP is used to query most devices for information. - -```console -dnf install -y net-snmp net-snmp-utils -echo "rocommunity public" > /etc/snmp/snmpd.conf -systemctl enable snmpd -systemctl start snmpd -``` - -### Cacti - -The following steps will show you how to manually download, install and -configure the basics for Cacti. - -1. Download Cacti source code from - [Cacti Web Site](https://www.cacti.net/download_cacti.php) - - ```console - cd /tmp - wget https://www.cacti.net/downloads/cacti-1.y.z.tar.gz - tar -zxvf cacti-1.y.z.tar.gz - mv -v cacti-1.y.z /usr/share/nginx/html/cacti - ``` - -2. Edit the config.php file - - ```console - mv -v /usr/share/nginx/html/cacti/include/config.php-dist /usr/share/nginx/html/cacti/include/config.php - ``` - -3. Update database\_ fields with your own details. This section only applies to - the Main Cacti Server - - ```php - $database_type = 'mysql'; - $database_default = 'your_cacti_database'; - $database_hostname = 'localhost'; - $database_username = 'your_cacti_username'; - $database_password = 'your_cacti_password'; - $database_port = '3306'; - $database_ssl = false; - $database_ssl_key = ''; - $database_ssl_cert = ''; - $database_ssl_ca = ''; - ``` - -4. Set your cookie domain to match your web site domain name - - ```console - $cacti_cookie_domain = 'cacti.yourdomain.com'; - ``` - -5. Create your cron task file or systemd units file - - Starting with Cacti 1.2.16, you have the option to use either the legacy - Crontab entry, or an optional cactid units file and server to run your Cacti - pollers. - - For Crontab use, follow the instructions below: - - Create and edit `/etc/cron.d/cacti` file. Make sure to setup the correct path - to poller.php - - ```console - */5 * * * * nginx php /usr/share/nginx/html/cacti/poller.php &>/dev/null - ``` - - For systemd unit's file install, you will need to modify the included units - file to following your install location and desired user and group's to run - the Cacti poller as. To complete the task, follow the procedure below: - - ```console - vim /var/www/html/cacti/service/cactid.service (edit the path) - touch /etc/sysconfig/cactid - cp -p /var/www/html/cacti/service/cactid.service /etc/systemd/system - systemctl enable cactid - systemctl start cactid - systemctl status cactid - ``` - - The systemd units file makes managing a highly available Cacti setup a bit - more convenient. - -#### Spine - -1. Install the necessary packages to compile and install spine - - ```console - dnf install -y autoconf automake libtool dos2unix help2man \ - openssl-devel mariadb-devel net-snmp-devel - ``` - -2. Download spine source code from - [Cacti Web Site](https://www.cacti.net/spine_download.php) - - Go to /tmp to download the source code and extract it - - ```console - cd /tmp - wget https://www.cacti.net/downloads/spine/cacti-spine-1.y.z.tar.gz - tar -zxvf cacti-spine-1.y.z.tar.gz - cd cacti-spine-1.y.z - ``` - -3. Run the configure script and compile spine. - - ```console - # ./configure - # make & make install - config/install-sh -c -d '/usr/local/spine/bin' - /bin/sh ./libtool --mode=install /usr/bin/install -c spine '/usr/local/spine/bin' - libtool: install: /usr/bin/install -c spine /usr/local/spine/bin/spine - config/install-sh -c -d '/usr/local/spine/etc' - /usr/bin/install -c -m 644 spine.conf.dist '/usr/local/spine/etc' - config/install-sh -c -d '/usr/local/spine/share/man/man1' - /usr/bin/install -c -m 644 spine.1 '/usr/local/spine/share/man/man1' - ``` - -4. Edit spine.conf - - Rename spine.conf.dist to spine.conf - - ```console - mv -v /usr/local/spine/etc/spine.conf.dist /usr/local/spine/etc/spine.conf - vi /usr/local/spine/etc/spine.conf - ``` - -5. Now set up your database connection - - ```console - DB_Host localhost - DB_Database your_cacti_database - DB_User your_cacti_username - DB_Pass your_cacti_password - DB_Port 3306 - #DB_UseSSL 0 - #RDB_SSL_Key - #RDB_SSL_Cert - #RDB_SSL_CA - ``` - -### Security Enhanced Linux (SELinux) - -If you suspect SELinux is blocking Cacti, disable it temporarily to confirm, then re-enable it and apply the correct policy rather than leaving it disabled. - -The [RHEL SELinux documentation](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/using_selinux/) covers policy management in depth and applies equally to Rocky Linux and AlmaLinux. - -1. Check SELinux status - - ```console - getenforce - ``` - -2. Disable SELinux temporarily for testing - - ```console - setenforce 0 - ``` - -3. Re-enable SELinux - - ```console - setenforce 1 - ``` - -4. Configure SELinux booleans for Cacti - - Cacti requires two booleans so Nginx/PHP-FPM can reach the database and make outbound SNMP connections during polling: - - ```console - setsebool -P httpd_can_network_connect 1 - setsebool -P httpd_can_network_connect_db 1 - ``` - -5. Set file contexts (only needed if Cacti is outside `/usr/share/nginx/html`) - - If you installed Cacti to a non-default path, apply the correct SELinux file contexts. The `semanage` command is provided by `policycoreutils-python-utils`; install it first if not already present: - - ```console - dnf install -y policycoreutils-python-utils - ``` - - Replace `/path/to/cacti` with your actual install path: - - ```console - semanage fcontext -a -t httpd_sys_content_t "/path/to/cacti(/.*)?" - semanage fcontext -a -t httpd_sys_rw_content_t "/path/to/cacti/rra(/.*)?" - semanage fcontext -a -t httpd_sys_rw_content_t "/path/to/cacti/log(/.*)?" - restorecon -Rv /path/to/cacti - ``` - - These labels grant the web server read access to Cacti's files and write access to the RRD and log directories. Without `httpd_sys_rw_content_t` on `rra/` and `log/`, graph generation silently fails even when UNIX permissions appear correct. - ---- - -Copyright (c) 2004-2026 The Cacti Group diff --git a/Installing-Under-Ubuntu-Debian.md b/Installing-Under-Ubuntu-Debian.md index a1b91cc3..e2590a69 100644 --- a/Installing-Under-Ubuntu-Debian.md +++ b/Installing-Under-Ubuntu-Debian.md @@ -12,8 +12,8 @@ apt-get update apt-get install -y apache2 rrdtool mariadb-server snmp snmpd \ php8.3 php8.3-mysql php8.3-snmp php8.3-xml php8.3-mbstring \ - php8.3-json php8.3-gd php8.3-gmp php8.3-zip php8.3-ldap \ - php8.3-intl php8.3-curl composer + php8.3-gd php8.3-gmp php8.3-zip php8.3-ldap \ + php8.3-intl php8.3-curl php8.3-fpm composer ``` ### A special note for systems using PHP-FPM @@ -22,7 +22,7 @@ Before starting the Cacti setup process, restart the PHP-FPM daemon to rebuild its cache, or you may receive an HTTP 500 error. ```console -systemctl restart php-fpm +systemctl restart php8.3-fpm ``` ### A special note on installing Cacti in LXC containers (e.g. Proxmox) @@ -58,10 +58,12 @@ Once the OS packages are installed, clone the Cacti repository: git clone -b 1.2.x https://github.com/Cacti/cacti.git ``` -Move the files into the web root: +Move the files into the web root and install Composer dependencies: ```console mv cacti /var/www/html +cd /var/www/html/cacti +composer install --no-dev ``` ### Database creation @@ -126,13 +128,20 @@ and the desired user and group, then: ```console vim /var/www/html/cacti/service/cactid.service -touch /etc/sysconfig/cactid cp -p /var/www/html/cacti/service/cactid.service /etc/systemd/system +mkdir -p /etc/default && touch /etc/default/cactid +systemctl daemon-reload systemctl enable cactid systemctl start cactid systemctl status cactid ``` +Set directory ownership so Apache and the poller can write to necessary directories: + +```console +chown -R www-data:www-data /var/www/html/cacti/rra /var/www/html/cacti/log /var/www/html/cacti/cache /var/www/html/cacti/resource +``` + The system is now ready. Browse to [http://serverip/cacti](http://serverip/cacti) to start the Cacti initialization wizard. diff --git a/Navigating-The-User-Interface.md b/Navigating-The-User-Interface.md index eeb499aa..a66db600 100644 --- a/Navigating-The-User-Interface.md +++ b/Navigating-The-User-Interface.md @@ -149,7 +149,7 @@ into separate sub-menus. We will describe the purpose of each next. - **Management** - This is where all core Cacti **Site**, **Graph**, **Device**, **Tree**, **Data Source**, and **Aggregate** non-templated objects reside. When you install Cacti **Plugins**, you will find - they they extend this sub-menu. + they extend this sub-menu. - **Data Collection** - This is where you define rules for **Data Collection** Examples include: **Data Collectors**, **Data Input Methods** and **Data Queries** diff --git a/Plugin-Guidelines.md b/Plugin-Guidelines.md index 26c3719b..43a95546 100644 --- a/Plugin-Guidelines.md +++ b/Plugin-Guidelines.md @@ -4,7 +4,7 @@ This section will help the Cacti plugin developer structure their plugins. However, the best way to create a plugin is to borrow someone elses. There -are Cacti plugin examples on [Cactis GitHub page](https://github.com/Cacti) and +are Cacti plugin examples on [Cacti's GitHub page](https://github.com/Cacti) and you can find them all over GitHub just by searching. ## Plugin Creation diff --git a/Plugin-Hook-API-Ref.md b/Plugin-Hook-API-Ref.md index 8bde7e06..9758459e 100644 --- a/Plugin-Hook-API-Ref.md +++ b/Plugin-Hook-API-Ref.md @@ -49,7 +49,7 @@ of their function. | [user_admin_edit](Plugin-Hook-API-Ref.md#user_admin_edit) | [user_admin_run_action](Plugin-Hook-API-Ref.md#user_admin_run_action) | [user_admin_setup_sql_save](Plugin-Hook-API-Ref.md#user_admin_setup_sql_save) | | [user_admin_tab](Plugin-Hook-API-Ref.md#user_admin_tab) | [user_admin_user_save](Plugin-Hook-API-Ref.md#user_admin_user_save) | [user_group_admin_action](Plugin-Hook-API-Ref.md#user_group_admin_action) | | [user_group_admin_edit](Plugin-Hook-API-Ref.md#user_group_admin_edit) | [user_group_admin_save](Plugin-Hook-API-Ref.md#user_group_admin_save) | [user_group_admin_setup_sql_save](Plugin-Hook-API-Ref.md#user_group_admin_setup_sql_save) | -| [user_group_admin_run_action] (Plugin-Hook-API-Ref.md#user_group_admin_run_action) | [user_group_admin_tab] (Plugin-Hook-API-Ref.md#user_group_admin_tab) | [user_group_remove] (Plugin-Hook-API-Ref.md#user_group_remove) | +| [user_group_admin_run_action](Plugin-Hook-API-Ref.md#user_group_admin_run_action) | [user_group_admin_tab](Plugin-Hook-API-Ref.md#user_group_admin_tab) | [user_group_remove](Plugin-Hook-API-Ref.md#user_group_remove) | | [user_remove](Plugin-Hook-API-Ref.md#user_remove) | [utilities_action](Plugin-Hook-API-Ref.md#utilities_action) | [utilities_array](Plugin-Hook-API-Ref.md#utilities_array) | | [utilities_list](Plugin-Hook-API-Ref.md#utilities_list) | [valid_host_fields](Plugin-Hook-API-Ref.md#valid_host_fields) | @@ -590,7 +590,7 @@ graph is required to be outputted. ## graph_items_remove -This hook is called when when the data source is deleted, and the option to +This hook is called when the data source is deleted, and the option to remove all graph items tied to the data source is selected. | file | introduced | retired | @@ -934,6 +934,21 @@ things like THolds fast poller for example. | lib/api_device.php | | | lib/poller.php | 1.0.0 | +## report_filters + +Allows plugins to add custom filter criteria to report generation interfaces. + +| File | Release | +| --- | --- | +| reports.php | 1.0.0 | + +```php +function myplugin_report_filters($filters) { + // Modify or add custom report filters + return $filters; +} +``` + ## resolve_dependencies | file | introduced | retired | @@ -1007,7 +1022,7 @@ calls the graph header) ## top_header -This hooks enables you to output custom HTML on top the the graph view page, if +This hook enables you to output custom HTML on top of the graph view page, if navigation tabs are not rendered. Allows you to override the rendering of the top_header.php include. @@ -1130,19 +1145,25 @@ See the explanation on `user_admin_action` | -------------------- | :--------- | :------ | | user_group_admin.php | 1.0.0 | -## user_group_admin_action +## user_group_admin_run_action + +Similar to `user_admin_run_action` | file | introduced | retired | | -------------------- | :--------- | :------ | | user_group_admin.php | 1.0.0 | -## user_group_admin_edit +## user_group_admin_tab + +Similar to `user_admin_tab` | file | introduced | retired | | -------------------- | :--------- | :------ | | user_group_admin.php | 1.0.0 | -## user_group_admin_save +## user_group_remove + +Similar to `user_remove` for user groups. | file | introduced | retired | | -------------------- | :--------- | :------ | @@ -1166,7 +1187,7 @@ plugin maintains user settings. ## utilities_action -This hook set's up the function to be executed from within Cacti's utilities +This hook sets up the function to be executed from within Cacti's utilities section. | file | introduced | retired | diff --git a/Plugin-Reference.md b/Plugin-Reference.md index 916979dd..a13113e4 100644 --- a/Plugin-Reference.md +++ b/Plugin-Reference.md @@ -1,6 +1,6 @@ # Reference Plugins -FIXME The reference plugin is under development. Nothing to see here yet. +This guide outlines the architecture and standard conventions for reference plugins in Cacti. The Reference Plugin(s) are generic plugins that implement key pieces of the Plugin Architecture. diff --git a/RRDproxy.md b/RRDproxy.md index 30f7e324..427bd2eb 100644 --- a/RRDproxy.md +++ b/RRDproxy.md @@ -105,7 +105,7 @@ Setting | Default | Comment CLI System Prompt | rrdp | Max 8 chars IPv4 Listen Addr | 0.0.0.0 | Listen all addr Client Proxy Port | 40301 | Connections from a client -Proxy Proxy port | 40302 | Connections from another proxy +Proxy port | 40302 | Connections from another proxy Dedicated CLI port | 40303 | Connections to the RRDproxy cli ## Command Line Interface diff --git a/RRDtool-Specific-Features.md b/RRDtool-Specific-Features.md index 7e487dbc..d613f01a 100644 --- a/RRDtool-Specific-Features.md +++ b/RRDtool-Specific-Features.md @@ -437,7 +437,7 @@ GPRINT:cdefcd:MAX:"Maximum:%8.2lf%sn" `cdefca` calculates the `SUM` of `all traffic_in` data sources, but pays attention only to consolidation function `AVERAGE`. Duplicate suppression makes sure, that the second occurrence of the `1`. target is not taken into account. -So it's only summing data source `a` and `c`. `cdefca` is used the the `LINE1` +So it's only summing data source `a` and `c`. `cdefca` is used for the `LINE1` graph item with exact match for consolidation function `AVERAGE` as well as for the best matched consolidation functions `LAST` and `MIN`. diff --git a/SNMP-Options.md b/SNMP-Options.md index 22ec0913..4305df6e 100644 --- a/SNMP-Options.md +++ b/SNMP-Options.md @@ -3,7 +3,7 @@ This section will describe **SNMP Options** in Cacti. The SNMP options page is used to enter your SNMP Strings and Credentials to be -used for the automation plugin in Cacti cacti support SNMP V1/V2/V3 below you +used for the automation plugin in Cacti support SNMP V1/V2/V3 below you will enter your networks specific SNMP details for the devices you will be polling diff --git a/Settings-Data.md b/Settings-Data.md index 1e8ad1ae..ef8b71db 100644 --- a/Settings-Data.md +++ b/Settings-Data.md @@ -31,7 +31,7 @@ Those settings include: - **Daily Update Frequency** - This setting determines how often daily averages and peaks should be calculated. You can set - it to run hourly, upto every 6 hours, or after Cacti's boost + it to run hourly, up to every 6 hours, or after Cacti's boost process completes. - **Hourly Average Window** - This is a floating time window where @@ -65,7 +65,7 @@ Those settings include: - **Check Frequency** - This setting determines how often checks should be executed. You can set - it to run hourly, upto 24 hours, or after Cacti's boost + it to run hourly, up to 24 hours, or after Cacti's boost process completes. ## Data Storage Settings diff --git a/Settings-Paths.md b/Settings-Paths.md index 074fe638..62028a80 100644 --- a/Settings-Paths.md +++ b/Settings-Paths.md @@ -77,12 +77,11 @@ Older files will be removed automatically. ## Alternate Poller Path -The sub-section hold information on how to find Cacti's `spine` binary if it's -installed. Since `spine` is written in ANSI C, it is not provided as a part of -the Cacti install and must be compiled by the Cacti Administrator. The benefit -of the `spine` binary is that it's mufti-threaded and extremely scalable. -It's possible to poll enterprises with excess of 30,000 devices using spine on -a reasonably large system. The image below show's this sub-section. +This subsection holds information on how to configure Cacti's `spine` binary path. +Since `spine` is written in C, it is compiled by the Cacti Administrator to match +the system's environment. The primary benefit of `spine` is that it is +multi-threaded and highly scalable, capable of polling tens of thousands of data +sources per minute. The image below shows this subsection. ![Alternate Poller Path](images/settings-paths-alternate.png) diff --git a/Settings-Visual.md b/Settings-Visual.md index 2551880a..463f8dd5 100644 --- a/Settings-Visual.md +++ b/Settings-Visual.md @@ -85,7 +85,7 @@ Those settings include: - **Enable Real-time Graphing** - Allow Realtime graphs to be used in Cacti. -- **Graph Time-span** - The default system level `Graph Timespan` use use when a +- **Graph Time-span** - The default system level `Graph Timespan` to use when a user opens a Realtime **Graph** for the first time. - **Refresh Interval** - The default system level `Refresh Interval` for the diff --git a/Sites.md b/Sites.md index 87b169ae..a1f889a8 100644 --- a/Sites.md +++ b/Sites.md @@ -13,15 +13,16 @@ be a customer site or data center location Below is an example of some of the attribute data you can enter for the site/location -Enter the appropriate information for the site and click create on the -below right side +Enter the appropriate information for the site and click **Create** in the +lower right corner: -![cacti add sites](images/add-site.JPG). +![cacti add sites](images/add-site.png) -Once you have created a site while you are creating a device manually -you can now associate the device to the site +Once a site has been created, you can associate devices with it when adding +or editing a device: + +![cacti add device site](images/add-device-site.png) -![cacti add device site](images/add-device-site.png). You can also associate the discovered devices via automation to a particular site. diff --git a/Spine.md b/Spine.md index 252be839..f74a4d2e 100644 --- a/Spine.md +++ b/Spine.md @@ -1,248 +1,351 @@ # Spine -Spine is the fast replacement for `cmd.php`. It is written in C to ensure -ultimate performance for device polling and is multi-threaded. Expect a decrease -in polling time of an order of magnitude. Polling times far less than 60 seconds -for about 20,000 data sources are achievable e.g. on a dual XEON system supplied -with 4 GB RAM and standard local disks. - -When using Spine, don't change crontab or systemd settings. The poller entry -point is always `poller.php`. Spine is invoked by the poller, not directly -from cron or systemd. - -To activate Spine instead of cmd.php, please visit -`Console > Configuration > Settings > Poller` and select spine and save as the -`Poller Type`. If it's not showing as an available `Poller Type` this means -either it has not been installed, or it's path has not been defined on the -`Paths` tab within Settings. - -Once saved, poller.php will use Spine on all subsequent polling cycles. Before -making this change, ensure that Spine runs properly from the command line using -the following test: +Spine is the high-speed, multi-threaded poller replacement for `cmd.php`. Written in C, +it provides dramatic performance improvements for data collection. Where `cmd.php` +can take several minutes to poll large installations, Spine routinely polls tens of +thousands of data sources in well under 60 seconds on modern multi-core hardware. -```console -cd /usr/local/spine/bin -./spine -R -V 3 -S -``` +Spine does not replace your cron or systemd scheduling entries. The scheduler entry point +remains `poller.php`. When Spine is selected as the poller engine, `poller.php` launches +Spine processes to perform the data collection across all configured devices. + +--- + +## Spine Architecture and Operating Principles + +1. **Multi-Threaded Polling**: Spine executes a thread-per-device polling model within + multiple concurrent processes, allowing hundreds of metrics to be collected simultaneously. +2. **Persistent PHP Script Server**: For custom scripts, Spine starts and maintains + long-running PHP script server processes (`script_server.php`). This eliminates the + heavy overhead of repeatedly spawning the PHP binary for every individual script item. +3. **Privilege Separation (SUID Root)**: To perform raw ICMP pings without invoking external + ping utilities, Spine requires raw socket access. Spine achieves this by shipping with the + SUID root bit enabled (`chmod u+s`). At runtime, Spine strictly limits elevated privileges: + it elevates effective UID only during raw socket creation (serialized by an internal lock) + and immediately drops back to the calling user (such as `apache` or `www-data`). +4. **Direct Database Communication**: Spine queries the Cacti database directly via the + MySQL/MariaDB client library to retrieve polling targets and writes collected data directly + into the poller cache and RRD files. -You should receive quite a bit of output depending on the size of your system. -To increase the number of Threads and concurrent processes, you must modify the -setting when editing your Data Collector under -`Console > Data Collection > Data Collectors`. +--- -While Spine is really fast, choosing the correct setup will ensure that all -processor resources are used. Required settings for Maximum Concurrent Poller -Processes are 1-2 times the number of CPU cores available for Spine. +## Installing Spine -When using spine, you must be sensitive to the number of connections that are -available for MySQL or MariaDB. Under -`Console > Utilities > System Utilities > General` Cacti will provide a -recommended `max_connection` for MySQL/MariaDB. +Because Spine is written in C, it must be compiled against your local database and Net-SNMP +client development libraries. -###### Table 15-1. Spine Parameters maintained at the System Level +### Prerequisites by Distribution -| Name | Description | -| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Script and Script Server Timeout Value | The maximum time that Spine will wait on a script to complete, in units of seconds. If a Script Server Script is terminated due to timeout conditions, the value entered into the RRDfile will be NaN | +#### Enterprise Linux 8 & 9 (RHEL, Rocky Linux, AlmaLinux) -###### Table 15-2. Spine Parameters maintained at the Data Collector Level +Spine requires development headers found in the CodeReady Builder (`crb`) repository on EL 9, +or `powertools` on EL 8: -| Name | Description | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Maximum Threads per Process | The maximum threads allowed per process. Using a higher number when using Spine will improve performance. Required settings are 10-15. Values above 50 are most often insane and may degrade performance vs. improve it. | -| Number of PHP Script Servers | The number of concurrent script server processes to run per Spine process. Settings between 1 and 15 are accepted. Script Servers will pre-load a PHP environment. Then, the Script Server Scripts are included into that environment to save the overhead of reloading PHP and re-interpreting the binary for each call. | +1. Enable the repository: -###### Table 15-3. Spine Parameters maintained at the Device Level + ```console + # On EL 9 (RHEL 9, Rocky Linux 9, AlmaLinux 9): + dnf config-manager --set-enabled crb -| Name | Description | -| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| The Maximum SNMP OIDs Per SNMP Get Request | The maximum number of SNMP get OIDs to issue per SNMP request. Increasing this value increases poller performance over slow links. The maximum value is 60 OIDs, but that value is highly dependent on the MTU for your links to the remote devices. In some cases, using a **Remote Data Collector** is much more effective for polling remote **Devices**. Additionally, some **Device Types** do not handle large SNMP OID get requests. It's best to experiment until you find the correct setting. | -| Device Threads | The maximum number spine threads used to gather information from a **Device**. When using this setting at the **Device** level, you have to ensure that you have enough threads allocated to a process so as to not block other **Devices** being polled from the same spine binary. | + # On EL 8 (RHEL 8, Rocky Linux 8, AlmaLinux 8): + dnf config-manager --set-enabled powertools + ``` -### Installing Spine +2. Install compiler tools and development libraries: -As Spine is written in C is must be compiled on the local system that it is to -be installed on below is an example of compiling on centos and Ubuntu + ```console + dnf install -y gcc autoconf automake libtool dos2unix help2man \ + openssl-devel mariadb-devel net-snmp-devel + ``` -### Ubuntu +#### Ubuntu and Debian -Install the required system packages +On Ubuntu (22.04 LTS / 24.04 LTS) and Debian (11 / 12): ```console -apt-get install -y build-essential dos2unix dh-autoreconf libtool help2man libssl-dev default-libmysqlclient-dev librrd-dev libsnmp-dev +apt-get update +apt-get install -y build-essential autoconf automake libtool dos2unix help2man \ + libssl-dev default-libmysqlclient-dev librrd-dev libsnmp-dev ``` -Download the version of Spine that matches your Cacti version. Replace `X.Y.Z` -with the actual release number (e.g., `1.2.31`): +#### FreeBSD + +On FreeBSD, Spine can be installed directly from pre-built packages or compiled from Ports: ```console -wget https://github.com/Cacti/spine/archive/release/X.Y.Z.zip -unzip X.Y.Z.zip -cd spine-release-X.Y.Z +# Using binary packages: +pkg install spine + +# Or via FreeBSD Ports: +cd /usr/ports/net-mgmt/spine +make install clean ``` -Once you are in the spine directory its time to compile the poller by issuing -the following commands: +--- + +### Downloading and Compiling Spine + +> **Important**: The version of Spine MUST match your Cacti version (e.g., Spine 1.2.31 for Cacti 1.2.31). + +1. Download the release archive matching your Cacti version (replace `X.Y.Z` with your version): + + ```console + cd /tmp + wget https://github.com/Cacti/spine/archive/refs/tags/release/X.Y.Z.tar.gz -O cacti-spine-X.Y.Z.tar.gz + tar -zxvf cacti-spine-X.Y.Z.tar.gz + cd spine-release-X.Y.Z + ``` + +2. Bootstrap, configure, and compile: + + ```console + ./bootstrap + ./configure + make + make install + ``` + + By default, Spine is installed to `/usr/local/spine`. + +3. Set binary permissions (SUID Root): + + Spine must be owned by `root` with the setuid bit set so it can open raw ICMP sockets: + + ```console + chown root:root /usr/local/spine/bin/spine + chmod u+s /usr/local/spine/bin/spine + ``` + +--- + +## Configuring `spine.conf` + +Spine reads its database connection parameters from `spine.conf`. + +1. Create the configuration file from the template: + + ```console + cp /usr/local/spine/etc/spine.conf.dist /usr/local/spine/etc/spine.conf + ``` + +2. Secure the file permissions: + + Because `spine.conf` contains the database password in plaintext, restrict permissions + so only `root` and the web server / poller group can read it: + + ```console + # On RHEL / Rocky / AlmaLinux (web group: apache): + chown root:apache /usr/local/spine/etc/spine.conf + chmod 0640 /usr/local/spine/etc/spine.conf + + # On Ubuntu / Debian (web group: www-data): + chown root:www-data /usr/local/spine/etc/spine.conf + chmod 0640 /usr/local/spine/etc/spine.conf + ``` + +3. Edit `/usr/local/spine/etc/spine.conf` and update the database settings to match your + Cacti `config.php`: + + ```ini + DB_Host localhost + DB_Database cacti + DB_User cactiuser + DB_Pass cactiuser_password + DB_Port 3306 + #DB_UseSSL 0 + #RDB_SSL_Key + #RDB_SSL_Cert + #RDB_SSL_CA + ``` + +--- + +## Testing Spine from the Command Line + +Before activating Spine in the Cacti web interface, verify that it can connect to the database, +query devices, and send ICMP pings without error. + +### 1. Read-Only Global Test + +Run Spine in read-only test mode (`-R`) with summary statistics (`-S`) and verbosity level 3 (`-V 3`). +In this mode, Spine polls devices but does not write results into the database: ```console -./bootstrap -./configure -make -make install -chown root:root /usr/local/spine/bin/spine -chmod u+s /usr/local/spine/bin/spine +/usr/local/spine/bin/spine -R -V 3 -S ``` -Once that has completed, you will need to configure spine's config file +Verify that the output shows Spine reading `/usr/local/spine/etc/spine.conf` and completes with: +`SPINE: Execution Time: ... Total Hosts: ...` + +### 2. Device-Specific Test + +To test a single device without polling your entire infrastructure, pass the host ID range using +`-f -l `: ```console -vi /usr/local/spine/etc/spine.conf +/usr/local/spine/bin/spine -R -f 1 -l 1 -V 5 ``` -Below is an example of a configuration however yours should match your cacti -database username and password +Check the verbose output for ICMP ping success, SNMP retrieval, and script execution without errors. -```console -DB_Host localhost -DB_Database cacti -DB_User spine -DB_Pass spine -DB_Port 3306 -#DB_UseSSL 0 -#RDB_SSL_Key -#RDB_SSL_Cert -#RDB_SSL_CA +--- + +## Enabling Spine in the Cacti Web UI + +Once command-line verification passes, activate Spine in Cacti: + +### Step 1: Set the Binary Path + +1. Log in to Cacti as an administrator. +2. Navigate to **Console > Configuration > Settings > Paths**. +3. Under **Spine Poller File Path** (or **Spine Binary File Location**), enter: + `/usr/local/spine/bin/spine` +4. Optionally, set **Spine Config File Path** to `/usr/local/spine/etc/spine.conf` (if left blank, + Spine automatically searches its sibling `../etc` directory). +5. Verify that Cacti indicates `[OK: FILE FOUND]`. +6. Click **Save**. + +![Alternate Poller Path](images/settings-paths-alternate.png) + +### Step 2: Switch the Poller Engine + +1. Navigate to **Console > Configuration > Settings > Poller**. +2. Change the **Poller Type** dropdown from `cmd.php` to `spine`. +3. Click **Save**. + +The next scheduled polling cycle by `poller.php` will immediately invoke Spine. + +--- + +## Tuning Spine for Optimal Performance + +Spine parameters are configured at three distinct levels: + +### 1. System-Level Settings + +Configured under **Console > Configuration > Settings > Poller**: + +| Parameter | Recommended Value | Description | +| :--- | :--- | :--- | +| **Script and Script Server Timeout** | 25 seconds | Maximum duration Spine waits for an external script or Script Server call before timing out and returning `NaN`. Must be less than your polling interval. | + +### 2. Data Collector-Level Settings + +Configured under **Console > Data Collection > Data Collectors** (select your collector): + +| Parameter | Recommended Value | Description | +| :--- | :--- | :--- | +| **Maximum Concurrent Poller Processes** | 1–2 per CPU core | Number of Spine processes launched concurrently. For a 4-core system, 4 to 8 processes is typical. | +| **Maximum Threads per Process** | 10–20 threads | Number of concurrent threads per process. Do not set higher than 50, as excessive context switching degrades performance. | +| **Number of PHP Script Servers** | 2–5 per process | Number of persistent `script_server.php` workers maintained per Spine process to handle script data queries. | + +### 3. Device-Level Overrides + +Configured on individual devices under **Console > Management > Devices**: + +| Parameter | Default | Description | +| :--- | :--- | :--- | +| **Device Threads** | 1 | Number of concurrent threads dedicated to polling this specific device. Increase for high-density switches or routers with hundreds of interfaces. | +| **Maximum OIDs Per Get Request** | 10–60 | Number of SNMP OIDs bundled into a single SNMP GET request. Higher values increase throughput over high-latency links, provided the device agent supports it. | + +--- + +## Database Connection Sizing (`max_connections`) + +Each concurrent Spine process, thread, and script server requires database connections. Ensure your +MySQL/MariaDB `max_connections` limit is sized adequately: + +Total Connections >= (Data Collectors * Processes * (Threads + Script Servers + 2)) + 50 + +If this setting is too low, Spine will fail with `FATAL: Connection to MySQL database failed`. + +Edit `/etc/my.cnf.d/server.cnf` (or `/etc/mysql/mariadb.conf.d/50-server.cnf`) and set: + +```ini +[mysqld] +max_connections = 500 ``` -### CentOS +Restart the database server after changing `max_connections`. -Install required system packages +--- + +## Security Policies (SELinux & AppArmor) + +### SELinux (RHEL, Rocky Linux, AlmaLinux) + +If SELinux is enforcing, allow the web server and poller to establish outgoing network connections: ```console -yum install -y gcc mysql-devel net-snmp-devel autoconf automake libtool dos2unix help2man +setsebool -P httpd_can_network_connect 1 +setsebool -P httpd_can_network_connect_db 1 ``` -Then compile using the following commands +Ensure the Spine binary has the appropriate system binary context (`bin_t`): ```console -./bootstrap -./configure -make -make install -chown root:root /usr/local/spine/bin/spine -chmod u+s /usr/local/spine/bin/spine +semanage fcontext -a -t bin_t "/usr/local/spine/bin/spine" +restorecon -v /usr/local/spine/bin/spine ``` -### Testing/Debugging spine via command line - -Spine offers a few different ways at the command line to test its -functionality. Here are a few examples of some tests you can run by executing -Spine. - -#### Test Spine without writing results to database - -This test allows you to run spine and display the results to the console. This -will not commit any of the data to the database by specifying the -R option. - -```shell -/usr/local/spine/bin# ./spine -R -V 5 -SPINE: Using spine config file [../etc/spine.conf] -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The path_php_server variable is /var/www/html/cacti/script_server.php -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The path_cactilog variable is /var/www/html/cacti/log/cacti.log -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The log_destination variable is 1 (FILE) -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The path_php variable is /usr/bin/php -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The availability_method variable is 2 -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The ping_recovery_count variable is 3 -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The ping_failure_count variable is 2 -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The ping_method variable is 2 -2021-01-08 14:26:25 - SPINE: Poller[1] PID[13482] DEBUG: The ping_retries variable is 1 -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] POLLER: Active Threads is 1, Pending is 1 -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] DEBUG: Entering ICMP Ping -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] DEBUG: Attempting to ping 192.168.1.5, seq 9 (Retry 0 of 1) -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] DEBUG: Attempting to ping 192.168.1.5, seq 9 (Retry 0 of 1) -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] DEBUG: ICMP Device Alive, Try Count:1, Time:0.4990 ms -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] PING: Result ICMP: Device is Alive -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] HT[1] Device has no information for recache. -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] HT[1] NOTE: There are '1' Polling Items for this Device -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] DEBUG: The NIFTY POPEN returned the following File Descriptor 5 -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] HT[1] DS[64] TT[9.95] SCRIPT: perl /var/www/html/cacti/scripts/ping.pl '192.168.1.5', output: 0.047 -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] HT[1] Total Time: 0.018 Seconds -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] Device[38] HT[1] DEBUG: HOST COMPLETE: About to Exit Device Polling Thread Function -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] DEBUG: The Value of Active Threads is 0 for Device ID 38 -2021-01-08 14:31:40 - SPINE: Poller[1] PID[13804] POLLER: Active Threads is 0, Pending is 0 -``` +### AppArmor (Ubuntu / Debian) -#### Running spine for a specific host - -If you want to run spine for a specific host you are able to do that with the -following command: - -```shell -/usr/local/spine/bin# ./spine -R -f 42 -l 42 -V 5 -SPINE: Using spine config file [../etc/spine.conf] -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] DEBUG: The path_php_server variable is /var/www/html/cacti/script_server.php -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] DEBUG: The path_cactilog variable is /var/www/html/cacti/log/cacti.log -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] DEBUG: The log_destination variable is 1 (FILE) -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] DEBUG: The path_php variable is /usr/bin/php -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] DEBUG: The Value of Active Threads is 1 for Device ID 0 -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] POLLER: Active Threads is 1, Pending is 0 -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] SPINE: Active Threads is 1, Pending is 1 -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] DEBUG: In Poller, About to Start Polling of Device for Device ID 42 -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] IPv4 address 1.1.1.30 (1.1.1.30) -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] DEBUG: Entering ICMP Ping -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] DEBUG: Attempting to ping 1.1.1.30, seq 0 (Retry 0 of 1) -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] DEBUG: ICMP Device Alive, Try Count:1, Time:26.5849 ms -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] PING: Result ICMP: Device is Alive -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] HT[1] Device has no information for recache. -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] HT[1] NOTE: There are '1' Polling Items for this Device -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] DEBUG: The NIFTY POPEN returned the following File Descriptor 7 -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] HT[1] DS[68] TT[42.86] SCRIPT: perl /var/www/html/cacti/scripts/ping.pl '1.1.1.30', output: 26.9 -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] HT[1] Total Time: 0.077 Seconds -2021-01-08 14:34:14 - SPINE: Poller[1] PID[14296] Device[42] HT[1] DEBUG: HOST COMPLETE: About to Exit Device Polling Thread Function -``` +If using a confined profile for Apache or PHP-FPM, allow execution of the Spine binary: -#### Spine debug via GUI +```console +# Add to /etc/apparmor.d/local/usr.sbin.apache2: +/usr/local/spine/bin/spine rix, +/usr/local/spine/etc/spine.conf r, +``` -You are also able to view spine debug information via the log file also spine -allows you to raise the level of detail it provides in the log if you want to -debug a specific device and see the spine output click enable device debug. +Reload AppArmor: -Below is an example output of Spine debug info via the log file +```console +apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2 +``` -![spine](images/spine-debug-gui.png) +--- -To enable more detailed spine logging go to -`Console > Configuration > Settings > Poller` +## Troubleshooting Spine -You can choose from Detailed,Summary or No logging for Invalid data +### Common Errors and Solutions -Detailed Logging will be similar to cmd.php in that you will get a report for -each data source that is having an issue +#### 1. `FATAL: Unable to read configuration file! (Spine init)` -Summary provides a count of how many data sources are having an issue per device +* **Cause**: Spine cannot locate or read `spine.conf`. +* **Fix**: Ensure `/usr/local/spine/etc/spine.conf` exists and is readable by the user executing + the poller (e.g. `apache` or `www-data`): + ```console + ls -la /usr/local/spine/etc/spine.conf + chmod 640 /usr/local/spine/etc/spine.conf + ``` -![spine](images/spine-parameters.png) +#### 2. `DEBUG: Falling back to UDP Ping Due to SetUID Issues` -### Common Spine related errors +* **Cause**: Spine is missing the SUID root permission required to open raw ICMP sockets. +* **Fix**: Restore SUID permissions on the binary: + ```console + chown root:root /usr/local/spine/bin/spine + chmod u+s /usr/local/spine/bin/spine + ``` -```shell -2021/01/08 14:38:44 - SPINE: Poller[1] PID[14838] FATAL: Unable to read configuration file! (Spine init) -``` +#### 3. `FATAL: Connection to MySQL database failed` -Ensure that you have spine.conf in /usr/local/spine/etc on first install -`spine.conf` may be `spine.conf.dist`. +* **Cause**: Incorrect database credentials in `spine.conf`, database host unreachable, or + MySQL/MariaDB `max_connections` reached. +* **Fix**: Test database connectivity manually with `mysql -u cactiuser -p -h localhost cacti` + and increase `max_connections` in your MySQL configuration. -```shell -DEBUG Falling back to UDP Ping Due to SetUID Issues -``` +#### 4. Verification in Cacti Log -This is a permissions issue with spine ensure you have give spine the proper -permissions +To confirm Spine is functioning in production, open **Console > Utilities > System Utilities > View Cacti Log**. +Look for the poller completion summary line: -```shell -chmod u+s /usr/local/spine/bin/spine +```text +SYSTEM STATS: Time:12.3456 Method:spine Processes:4 Threads:40 Hosts:250 HostsPerProcess:63 DataSources:12400 RRDsProcessed:6200 ``` ---- +If the log displays `Method:spine`, Spine is running successfully. +--- Copyright (c) 2004-2026 The Cacti Group diff --git a/Standards-Code-Formatting.md b/Standards-Code-Formatting.md index 0fbf53ae..3d403b00 100644 --- a/Standards-Code-Formatting.md +++ b/Standards-Code-Formatting.md @@ -295,7 +295,7 @@ function that needs to use it. $graph_unit_exponent_values = array( '-18' => 'a - atto', '-15' => 'f - femto', - ... + // ... ); function graph_unit_exponent_values_list() { diff --git a/Standards-FileSystem-Layout.md b/Standards-FileSystem-Layout.md index e6c93b95..f0b7d9e0 100644 --- a/Standards-FileSystem-Layout.md +++ b/Standards-FileSystem-Layout.md @@ -181,6 +181,8 @@ reading graph information. The `require_once` directive is used instead of function api_graph_item_save($graph_item_id, &$_fields_graph_item) { require_once(CACTI_BASE_PATH . '/lib/sys/sequence.php'); require_once(CACTI_BASE_PATH . '/lib/graph/graph_info.php'); + // Function implementation... +} ``` --- diff --git a/Standards-PHP-Spec-Constructs.md b/Standards-PHP-Spec-Constructs.md index 0cfcd5a4..9335f8d6 100644 --- a/Standards-PHP-Spec-Constructs.md +++ b/Standards-PHP-Spec-Constructs.md @@ -5,11 +5,10 @@ Use the ```foreach ($array as $name => $value)``` syntax instead of ```while (list($name, $value) = each($array))``` syntax when traversing arrays. The former has been demonstrated to be more efficient and does not increment the -internal pointer of the array. The `foreach` construct will error if the array -is empty or is not an array, so you must check this first. +internal pointer of the array. Ensure the variable is an array or iterable object before passing it to `foreach` to prevent type warnings on null or boolean values. ```php -if ((is_array($array)) && (sizeof($array) > 0)) { +if (is_array($array) && !empty($array)) { foreach ($array as $name => $value) { // code } @@ -17,14 +16,11 @@ if ((is_array($array)) && (sizeof($array) > 0)) { ``` It should be noted that with PHP 7.2 use of `list() = each()` syntax will result -in warnings and/or errors. It should also be noted that 7.2 also introduced the -need for the variable to implement ICountable which are arrays and objects. You -should therefore check if `variable !=== false` before using `sizeof()` or -`count()` +in warnings and/or errors. It should also be noted that PHP 7.2 introduced warnings when passing non-countable types to `count()` or `sizeof()`. Variables must implement `Countable` or be an `array`. You should verify `is_array($variable) || $variable instanceof Countable` before calling `count()`. ## Error Return Values -When an a function needs to return a generic error, it is best to return boolean +When a function needs to return a generic error, it is best to return boolean `false` in PHP. This makes it very straightforward to check for. ```php @@ -41,14 +37,10 @@ functions such as `strstr()`, `str_replace()`, `substr()`, and `explode()` can be used, and are much faster. ```php -$items = explode(':', $string)); +$items = explode(':', $string); ``` -It's much quicker than: - -```php -$items = split(':', $string)); -``` +Avoid legacy POSIX regex functions such as `split()`, which was removed in PHP 7.0. ## Use `preg` Functions Instead of `ereg` diff --git a/Standards-SQL.md b/Standards-SQL.md index b9e283f9..3db4108d 100644 --- a/Standards-SQL.md +++ b/Standards-SQL.md @@ -34,13 +34,13 @@ attacks from the Cacti website. Examples include: // Example prepared statements $hostname = db_fetch_cell_prepared('SELECT hostname FROM host WHERE id = ?', array($id)); $host = db_fetch_row_prepared('SELECT * FROM host WHERE id = ?', array($id)); -$graphs = db_fetch_assoc('SELECT * FROM graph_local WHERE host_id = ?', array($id)); +$graphs = db_fetch_assoc_prepared('SELECT * FROM graph_local WHERE host_id = ?', array($id)); db_execute_prepared('UPDATE host SET description = ? WHERE id = ?', array('Local Machines', $id)); // Escape strings if using legacy functions $hostname = db_qstr('myhost.com'); -db_execute(UPDATE host SET hostname = '$myhost' WHERE id = $id"); +db_execute("UPDATE host SET hostname = '$hostname' WHERE id = $id"); ``` @@ -91,7 +91,7 @@ db_execute(UPDATE host SET hostname = '$myhost' WHERE id = $id"); #### Before formatting ```php -$templates = db_fetch_assoc('SELECT DISTINCT gt.id, gt.name FROM graph_templates AS gt INNER JOIN graph_templates_graph AS gtg ON gt.id = gtg.graph_template_id INNER JOIN graph_templates_item AS gti ON gtg.graph_template_id=gti.graph_template_id INNER JOIN data_template_rrd AS dtr ON gti.task_item_id=dtr.id INNER JOIN data_template_data AS dtd ON dtd.data_template_id=dtr.data_template_id AND dtd.local_data_id = 0 WHERE gtg.local_graph_id=0 AND dtr.local_data_id = 0 AND dtd.local_data_id = 0 AND dtd.data_input_id in (2,11,12) ORDER BY gt.name;' +$templates = db_fetch_assoc('SELECT DISTINCT gt.id, gt.name FROM graph_templates AS gt INNER JOIN graph_templates_graph AS gtg ON gt.id = gtg.graph_template_id INNER JOIN graph_templates_item AS gti ON gtg.graph_template_id=gti.graph_template_id INNER JOIN data_template_rrd AS dtr ON gti.task_item_id=dtr.id INNER JOIN data_template_data AS dtd ON dtd.data_template_id=dtr.data_template_id AND dtd.local_data_id = 0 WHERE gtg.local_graph_id=0 AND dtr.local_data_id = 0 AND dtd.local_data_id = 0 AND dtd.data_input_id in (2,11,12) ORDER BY gt.name;'); ``` #### Corrected formatting with prepared usage diff --git a/Templates.md b/Templates.md index c63f5525..107f09a6 100644 --- a/Templates.md +++ b/Templates.md @@ -114,7 +114,7 @@ non-templated fields. | Data Source Profile | The **Data Source Profile** will define how often to collect data for the resulting **Data Source**, and how long to keep that data in the RRDfile. | | Data Source Active | This is a quick and easy to tell Cacti to stop gathering data for this **Data Template**. The resulting **Data Source** can still be used on **Graphs**, but no data will be fed to it until it is made active again. | -> **NOTE:** For most **Data Templates**, you will should not have to to check +> **NOTE:** For most **Data Templates**, you should not have to check > the Use Per-Graph Value check-box for the name field. The Templating should > handle this just fine. However, the Generic SNMP OID **Data Template** has > this value checked to allow you to create Graphs and Data Sources on a @@ -411,7 +411,7 @@ If the XML file was downloaded, simply select that file from the Downloads location on your local system. Cacti no longer supports pasting the XML into the browser window. -Please pay attention the the `Data Source Profile` field. By default, cacti will +Please pay attention to the `Data Source Profile` field. By default, cacti will attempt to use your default **Data Source Profile**. However, you can change that at import time to use an alternate **Data Source Profile** or even the one from the **Template** itself, if it includes one. diff --git a/User-Domains.md b/User-Domains.md index 726a7979..fec12265 100644 --- a/User-Domains.md +++ b/User-Domains.md @@ -16,7 +16,7 @@ A use example would be for example 3 levels of customers who will have access to the system. For example lets say those three groups are: -- Adminnistrators +- Administrators - Managers - Client Team diff --git a/User-Management.md b/User-Management.md index ea4ac1cb..975b7a54 100644 --- a/User-Management.md +++ b/User-Management.md @@ -306,7 +306,7 @@ will be used as the source **User**. ![Copy a User Part 2](images/users-copy2.png) Specify the New Username, New Full Name and New Realm of the new user. Click -`Continue` to copy the selected template user to the the designated new user. An +`Continue` to copy the selected template user to the designated new user. An error will be returned if you attempt to copy over an existing user. If you would like to copy over an existing user, use Batch Copy. From e21ae6a111b9c42d23aea740c91937c3bf41669c Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Tue, 8 Sep 2026 00:16:07 -0700 Subject: [PATCH 2/5] docs: correct reviewed examples and guidance Signed-off-by: Thomas Vincent --- Data-Sources.md | 6 +++--- SNMP-Options.md | 7 +++---- Standards-PHP-Spec-Constructs.md | 2 +- Standards-SQL.md | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Data-Sources.md b/Data-Sources.md index f1e87e19..a379a823 100644 --- a/Data-Sources.md +++ b/Data-Sources.md @@ -68,9 +68,9 @@ may be interested in to view the Data sources in use ![device datasources](images/data-sources-per-device.png) -You can also view Orphaned data sources in this view by setting Orphaned from -Orphaned data sources are where the graph has been deleted but -the data source was not deleted +You can also view orphaned data sources in this view by changing the Orphaned +filter from **All** to **Orphaned**. Orphaned data sources are those whose graph +has been deleted but whose data source was not deleted. --- diff --git a/SNMP-Options.md b/SNMP-Options.md index 4305df6e..bac97b0c 100644 --- a/SNMP-Options.md +++ b/SNMP-Options.md @@ -2,10 +2,9 @@ This section will describe **SNMP Options** in Cacti. -The SNMP options page is used to enter your SNMP Strings and Credentials to be -used for the automation plugin in Cacti support SNMP V1/V2/V3 below you -will enter your networks specific SNMP details for the devices you will be -polling +The SNMP Options page stores the SNMP strings and credentials used by Cacti's +automation features. Cacti supports SNMP v1, v2, and v3. Enter the +network-specific SNMP details for the devices you will be polling below. ![SNMP Options](images/automation-snmp-options.png). diff --git a/Standards-PHP-Spec-Constructs.md b/Standards-PHP-Spec-Constructs.md index 9335f8d6..cf285f09 100644 --- a/Standards-PHP-Spec-Constructs.md +++ b/Standards-PHP-Spec-Constructs.md @@ -8,7 +8,7 @@ former has been demonstrated to be more efficient and does not increment the internal pointer of the array. Ensure the variable is an array or iterable object before passing it to `foreach` to prevent type warnings on null or boolean values. ```php -if (is_array($array) && !empty($array)) { +if (is_iterable($array)) { foreach ($array as $name => $value) { // code } diff --git a/Standards-SQL.md b/Standards-SQL.md index 3db4108d..61fcadcf 100644 --- a/Standards-SQL.md +++ b/Standards-SQL.md @@ -40,7 +40,7 @@ db_execute_prepared('UPDATE host SET description = ? WHERE id = ?', array('Local // Escape strings if using legacy functions $hostname = db_qstr('myhost.com'); -db_execute("UPDATE host SET hostname = '$hostname' WHERE id = $id"); +db_execute("UPDATE host SET hostname = $hostname WHERE id = $id"); ``` From 5d0b123a2830ab1b5f768928100361695afc956a Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Tue, 8 Sep 2026 00:29:07 -0700 Subject: [PATCH 3/5] docs: correct guidance that disagrees with the Cacti source Verified each claim against include/global_arrays.php, lib/auth.php, lib/functions.php, host_templates.php and the Spine config parser. The notable ones: api_plugin_safe_exec() does not exist on either branch, Spine reads DB_Pass rather than DB_Password, and the CDEF special data source table was missing five entries and renamed four others. Signed-off-by: Thomas Vincent --- CDEFs.md | 38 ++++---- Cacti-Log.md | 40 ++++---- Color-Templates.md | 12 +-- Colors.md | 21 ++-- Data-Sources.md | 6 +- Device-Templates.md | 29 +++--- GPRINTs.md | 25 +++-- General-Installing-Instructions.md | 148 +++++++++++++++-------------- Graph-Overview.md | 2 +- Requirements.md | 108 +++++++++++---------- SNMP-Options.md | 6 +- Settings-Auth.md | 60 ++++++------ Standards-PHP-Spec-Constructs.md | 13 ++- Standards-SQL.md | 5 +- Standards-Security.md | 53 ++++++----- Tree-Rules.md | 2 +- VDEFs.md | 20 ++-- 17 files changed, 316 insertions(+), 272 deletions(-) diff --git a/CDEFs.md b/CDEFs.md index fafb4dd4..752b7706 100644 --- a/CDEFs.md +++ b/CDEFs.md @@ -3,7 +3,7 @@ ## Background CDEF's in Cacti are a one to one analog to CDEF's in RRDtool. Cacti -simply provides and interface to create and manage them. Once the +simply provides an interface to create and manage them. Once the CDEF's are created in Cacti they can be imported and exported globally. CDEF's are mathematical formulas that either modify the numeric data from @@ -12,7 +12,7 @@ one to many data sources or VNAMES that you have in your **Graph Template**. The format of the mathematical formulas is called Reverse Polish Notation (RPN). RPN was and is an early form of how Engineers entered equations into early HP and other Calculators to solve Engineering problems. The reason we still -use it today, is that it follows a simple Stack principle. In other words, +use it today is that it follows a simple Stack principle. In other words, it's not broken. CDEF's can get very complex as there are several mathematical functions @@ -36,9 +36,9 @@ When you Click on the CDEF's name, you will enter into an Edit screen. From the you will see an ordered list of your Stack. It normally will begin with something like the CURRENT_DATA_SOURCE which means that when you Add a **Graph Item** to either a **Graph Template** or **Graph**, you can select a CDEF. The -**Data Source** associated with that **Graph Items** is the CURRENT_DATA_SOURCE. +**Data Source** associated with that **Graph Item** is the CURRENT_DATA_SOURCE. -After that, you may see a numeric number, followed by a math operator. That the +After that, you may see a number, followed by a math operator. That is the simplest form of a CDEF. If you have drag & drop enabled, you can re-order the CDEF items using drag & drop. Otherwise you will see arrows that allow you to move the CDEF Items up and down. @@ -46,20 +46,21 @@ to move the CDEF Items up and down. ![CDEFs Edit](images/cdefs-edit1.png) When editing a CDEF, the first decision is what Type of Data you want to put on -the Stack, you options as shown in the image below. They include: +the Stack. Your options are shown in the image below. They include: Name | Description --- | --- Function | A mathematical function that we will describe below Operator | Common mathematical operators including (+, -, *, /, and %) Another CDEF | Another Cacti CDEF. That could be confusing +Special Data Source | A value drawn from the Graph, the Data Source, or the poller, described below Custom String | Something like a number, a 'U' or 'Nan' for example ![CDEFs Item Type Edit](images/cdefs-edit3.png) ## Special Data Sources -In this next Image, you will find a CDEF Item in the process of being added. Note +In this next image, you will find a CDEF Item in the process of being added. Note that when you pick `Special Data Source` you have a drop-down that appears with the flavor of `Special Data Source`. There are many. They include: @@ -67,18 +68,23 @@ Name | Description --- | --- Current Graph Item Data Source | The value of the Data Source associated with the Graph Item Current Graph Item Polling Interval | This value is otherwise known as the Step in RRDtool terminology -All Data Sources (No Dupes) | The total of all Data Sources removing any duplicate DEF's -All Data Sources (With Dupes) | Add the values from all the Data Sources whether or not they are duplicated -All Similar Data Sources (No Dupes) | Means all Data Sources with the same RRDtool Data Source name like traffic_in, and traffic_out -All Similar Data Sources (No Dupes) Poller Interval | The max of the poller intervals returned from all similar Data Sources +All Data Sources (Do not Include Duplicates) | The total of all Data Sources removing any duplicate DEF's +All Data Sources (Include Duplicates) | Add the values from all the Data Sources whether or not they are duplicated +All Similar Data Sources (Do not Include Duplicates) | Means all Data Sources with the same RRDtool Data Source name like traffic_in, and traffic_out +All Similar Data Sources (Do not Include Duplicates) Polling Interval | The max of the poller intervals returned from all similar Data Sources +All Similar Data Sources (Include Duplicates) | Add the values from all similar Data Sources whether or not they are duplicated Current Data Source Item: Minimum Value | The RRDtool minimum value of the Current Data Source Current Data Source Item: Maximum Value | The RRDtool maximum value of the Current Data Source +Current Data Source Item: Least Squares Line Function | The RRDtool LSLINT, LSLSLOPE and LSLCORREL set as a least squares line +Current Data Source Item: Least Squares Line Y-intercept | The y-intercept of the least squares line for the Current Data Source +Current Data Source Item: Least Squares Line Slope | The slope of the least squares line for the Current Data Source +Current Data Source Item: Least Squares Line Correlation Coefficient | The correlation coefficient of that least squares line Graph: Lower Limit | The lower Limit of the Graph Graph: Upper Limit | The upper Limit of the Graph -Count of All Data Sources (No Dupes) | The total count of all Data Sources without Duplication -Count of All Data Sources (With Dupes) | The total count of all Data Sources including Duplicates -Count of Similar Data Sources (No Dupes) | The total count of Data Sources with the same RRDtool Data Source Name -Count of Similar Data Sources (With Dupes) | The total count of Data Sources with the same RRDtool Data Source Name +Count of All Data Sources (Do not Include Duplicates) | The total count of all Data Sources without Duplication +Count of All Data Sources (Include Duplicates) | The total count of all Data Sources including Duplicates +Count of All Similar Data Sources (Do not Include Duplicates) | The total count of Data Sources with the same RRDtool Data Source Name, counted once each +Count of All Similar Data Sources (Include Duplicates) | The total count of Data Sources with the same RRDtool Data Source Name, including Duplicates As you can see there is quite a bit of information that can be pulled from RRDtool for performing Graphical manipulation of Data. @@ -89,8 +95,8 @@ RRDtool for performing Graphical manipulation of Data. This list of CDEF functions is long and it's best to refer directly to the [RRDtool Manual](https://oss.oetiker.ch/rrdtool/doc/rrdgraph_rpn.en.html) for meanings -and examples of their use. Cacti supports all of them, if you find one that is not -supported, open an [Issue on Github](https://github.com/Cacti/cacti/issues). +and examples of their use. Cacti supports most of them. If you find one that +is not supported, open an [Issue on GitHub](https://github.com/Cacti/cacti/issues). --- Copyright (c) 2004-2026 The Cacti Group diff --git a/Cacti-Log.md b/Cacti-Log.md index cac56abb..f23e17c0 100644 --- a/Cacti-Log.md +++ b/Cacti-Log.md @@ -2,8 +2,9 @@ ## Summary -The Cacti Log is where all Cacti statistics, warnings, errors and other log messages -are sent to. Cacti can optionally log some information to your syslog or event log +The Cacti Log is where all Cacti statistics, warnings, errors and other log +messages are sent. Cacti can optionally log some information to your syslog or +event log depending on your OS type. The Cacti Log is by default ordered from newest event to oldest event, and @@ -24,46 +25,51 @@ An image of the Cacti Log file can be seen below. ## Cacti Log Filters -What we like to see in the Cacti Log is a lot of Green, which means good. By default, +What we like to see in the Cacti Log is a lot of Green, which means good. By +default, WARNINGS are yellow, and ERRORS are red. But there are other types of messages that highlight differently. Generally, you can filter for these message types. The filters include: -- **File** - The Cacti Log file to view. They are suffixed by a data when they were rotated - using the following pattern: YYYY-MM-DD. +- **File** - The Cacti Log file to view. Rotated files are suffixed with the + date they were rotated, using the pattern YYYY-MM-DD. - **Tail Lines** - The number of lines to view from the selected Cacti Log. - **Types** - The message types to view. These will be explained below. -- **Display Order** - The order to display the Log lines, either *Newest First* or *Oldest First*. +- **Display Order** - The order to display the Log lines, either *Newest First* + or *Oldest First*. - **Refresh** - How often to Auto-refresh the interface. -- **Search** - A perl compatible Regular Expression to search the log with. +- **Search** - A Perl compatible regular expression to search the log with. The Cacti Log **Types** include the following: - **Stats** - Anything that includes the word **STATS** - **Warnings** - Anything that includes the word **WARNING** -- **Warnings++** - Anything of each **WARNING**, **ERROR**, **DEBUG**, and **SQL** - this one is good for debugging, and it will include most important - errors to the Cacti Administrator. +- **Warnings++** - Anything of each **WARNING**, **ERROR**, **DEBUG**, and + **SQL**. This one is good for debugging, and it includes the errors that + matter most to the Cacti Administrator. - **Errors** - Anything that includes the word **ERROR** - **Errors++** - Anything of each **ERROR**, **DEBUG**, and **SQL** - **Debug** - Anything that includes the word **DEBUG** -- **AutoM8** - Anything that includes the word **AUTOM8**. These message come from - Cacti automation of Devices, Graphs, and Trees +- **SQL Calls** - Anything that includes the word **SQL** +- **AutoM8** - Anything that includes the word **AUTOM8**. These messages come + from Cacti automation of Devices, Graphs, and Trees - **Non Stats** - Anything that does not include the word **STATS**. - **Boost** - Anything that contains the word **BOOST**. -- **Device Up/Down** - Any device Up/Down notification including t - hose that come from *Thold* or *Monitor* Plugins. +- **Device Up/Down** - Any device Up/Down notification, including those that + come from the *Thold* or *Monitor* plugins. - **Recaches** - Any Device Recache Events. -- **Threshold** - If the *Thold* plugins is installed, - any of it's threshold breach and restoration events. +- **Security Issues** - Added in Cacti 1.3. Anything logged by Cacti's + security auditing. +- **Threshold** - If the *Thold* plugin is installed, any of its threshold + breach and restoration events. ## Differences between User and Administrative Views As previously mentioned, the Cacti log has two permission levels, the User Permission level will not include the *Purge* button, and can have some information hidden from public view -whereas the Administrative view includes all Log messages and a *Purge** button. +whereas the Administrative view includes all Log messages and a *Purge* button. --- Copyright (c) 2004-2026 The Cacti Group diff --git a/Color-Templates.md b/Color-Templates.md index 7a83d490..51092383 100644 --- a/Color-Templates.md +++ b/Color-Templates.md @@ -10,20 +10,20 @@ So, for example, if your **Color Template** uses 8 differing **Colors**, and your **Aggregate Graph** includes 16 *Graph Items*, then each color will be used twice in the **Aggregate Graph**. -Below, you can see the four standard **Color Templates**, you can see that you -have the ability to either *Delete* or *Duplicate* the **Color Templates**. As -with other Cacti objects, you will not be allowed to *Delete* a **Color -Template** in use. +Below, you can see the four standard **Color Templates**. From the Actions +drop down you can *Delete*, *Duplicate*, or *Sync Aggregates* for the selected +**Color Templates**. As with other Cacti objects, you will not be allowed to +*Delete* a **Color Template** in use. ![Color Templates](images/color-templates.png) -In the image below, you can see the **Color Template** edit screen. This simply +In the image below, you can see the **Color Template** edit screen. This simple screen allows you to add, remove and re-order colors in the list. ![Color Templates Edit](images/color-templates-edit1.png) Shown in the image below, only Cacti **Colors** are allowed to be selected for -Aggregate **Color Templates**. The **Color** drop down can by typed into if you +Aggregate **Color Templates**. The **Color** drop down can be typed into if you wish to search through the list of approximately 340 legacy and *Named Colors*. ![Color Templates Item Edit](images/color-templates-edit2.png) diff --git a/Colors.md b/Colors.md index 0ae90e7e..f22f6104 100644 --- a/Colors.md +++ b/Colors.md @@ -1,18 +1,18 @@ # Colors -Colors in Cacti come in two types and used to maintain a list of colors that can -be used in Cacti for **Graph Templates** and **Graphs**. +Colors in Cacti come in two types. They maintain a list of colors that can be +used in Cacti for **Graph Templates** and **Graphs**. -The first type are the legacy Cacti colors imported from earlier versions of -Cacti. Starting with Cacti 1.0, Cacti started to support the concept of *Named -Colors* which come from a well known dictionary of well defined colors. *Named -Colors* are read only in Cacti. While the legacy Cacti colors can be named as -the Cacti administrator desires. +The first type is the legacy Cacti colors imported from earlier versions of +Cacti. Starting with Cacti 1.0, Cacti supports the concept of *Named Colors*, +which come from a well known dictionary of well defined colors. *Named Colors* +are read only in Cacti, while the legacy Cacti colors can be named as the Cacti +administrator desires. The image below shows a list of Cacti *Named Colors*. You can see that there is a search bar and check boxes for showing just *Named Colors* or all colors, and another check box for showing Colors that are used in **Graph Templates** and -*Graphs*. You can not remove either the *Named Colors* or Colors that are in +**Graphs**. You can not remove either the *Named Colors* or Colors that are in use by either a **Graph Template** or **Graph**. ![Colors](images/colors.png) @@ -24,9 +24,8 @@ Color hex value. ![Colors Edit](images/colors-edit1.png) -Below, you can see the color picker that allows you to visually find the -appealing color. You can also use hex values that were previously supported in -earlier Cacti version. +Below, you can see the color picker that allows you to pick a color visually. +You can also use the hex values that were supported in earlier Cacti versions. ![Colors Color Edit](images/colors-edit2.png) diff --git a/Data-Sources.md b/Data-Sources.md index a379a823..4b2c7a19 100644 --- a/Data-Sources.md +++ b/Data-Sources.md @@ -68,9 +68,9 @@ may be interested in to view the Data sources in use ![device datasources](images/data-sources-per-device.png) -You can also view orphaned data sources in this view by changing the Orphaned -filter from **All** to **Orphaned**. Orphaned data sources are those whose graph -has been deleted but whose data source was not deleted. +You can also list orphaned data sources from this page by ticking the +**Orphaned** filter checkbox. An orphaned data source is one whose graph was +deleted while the data source itself was left behind. --- diff --git a/Device-Templates.md b/Device-Templates.md index c33cf31c..29cc326b 100644 --- a/Device-Templates.md +++ b/Device-Templates.md @@ -1,8 +1,8 @@ # Device Templates -**Device Templates** are Cacti objects that allows you to define classes of -**Devices** that includes from one to many **Graph Templates**, **Data Queries** -and other **Plugin** related object types. +**Device Templates** are Cacti objects that allow you to define classes of +**Devices** that include one or more **Graph Templates**, **Data Queries** and +other **Plugin** related object types. The purpose of **Device Templates** is to simplify the **Automation** process by pre-defining the **Graphs** that should be created for every **Device** that is @@ -14,32 +14,39 @@ The **Device Templates** main screen looks like the image below: ![Device Templates Page](images/device-templates.png) -From this page, you can see the title of each **Device Template**, it's ID which -is important for the Cacti CLI scripts. You can see if the **Device Template** -can be removed, and the number of **Devices** using the **Device Template**. +From this page, you can see the title of each **Device Template**, and its ID, +which is important for the Cacti CLI scripts. You can see if the **Device +Template** can be removed, and the number of **Devices** using the **Device +Template**. Templates that are used by **Devices** can not be removed and therefore if you -attempt to remove one of these Templates, you will receive and error message. +attempt to remove one of these Templates, you will receive an error message. -From the drop down there are three options, they are: +From the drop down there are the following options: Option | Description --- | --- Delete | Remove the **Device Template** if it's *Deletable* Duplicate | Make an exact copy of the **Device Template**. Sync Devices | Update all **Devices** using this **Device Template** with the latest definition, adding, but not removing **Graph Templates**, and **Data Queries**. +Archive | Store a copy of the current **Device Template** definition with an optional *Archive Note*. Archives are listed on the *Archives* tab of the same page. +Download | Download the **Device Template** as a Cacti **Package**. + +*Archive* and *Download* were added in Cacti 1.3; Cacti 1.2.x offers only the +first three options. They appear only once the package signing keys exist, +which `cli/genkey.php` creates. When editing a **Device Template**, you will see the page as displayed below. From this page, you can add and remove **Graph Templates**, **Data Queries**, and other **Plugin** objects. In the image below, you can see that the *Cisco -Router* has one **Graph Template** that of *Cisco - CPU Usage* and one **Data -Query** that of *SNMP - Interface Statistics*. There are no **Threshold +Router* has one **Graph Template**, *Cisco - CPU Usage*, and one **Data Query**, +*SNMP - Interface Statistics*. There are no **Threshold Templates** defined on the system, so there is no way to select one. ![Device Template Edit Page](images/device-templates-edit.png) To add a **Graph Template** or **Data Query** to the **Device Template**, simply select it from the drop down, and press the *Add* button. There is no need to -*Save* afterwards. To removed one of these items, simply press the x glyph to +*Save* afterwards. To remove one of these items, simply press the x glyph to the right of the desired **Graph Template** or **Data Query**. --- diff --git a/GPRINTs.md b/GPRINTs.md index a96dcb9a..1a6a7d2f 100644 --- a/GPRINTs.md +++ b/GPRINTs.md @@ -1,24 +1,21 @@ # GPRINT Presets -GPRINT Presets are an object in Cacti used for formatting -Legend output on RRDtool Graphs. These GPrint Presets -closely follow printf(), sprintf() ANSI syntax. They -are simple to create and edit. You can find the format -strings on the [RRDtool Website](https://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html#PRINT). +GPRINT Presets are an object in Cacti used for formatting Legend output on +RRDtool Graphs. These GPRINT Presets closely follow printf(), sprintf() ANSI +syntax. They are simple to create and edit. You can find the format strings on +the [RRDtool Website](https://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html#PRINT). -The stock GPrint Presets are generally sufficient for most -**Graph Templates**, but they can easily be extended, -and are a part of the Graph Template Export XML file. So, -they are portable once created. +The stock GPRINT Presets are generally sufficient for most **Graph Templates**, +but they can easily be extended, and are a part of the Graph Template Export XML +file. So, they are portable once created. -In the image below, you can see the default GPrint Presets -and the actions that can be taken on them. Keep in mind -that once a GPrint Preset is being used by a **Graph** -or a **Graph Template**, it cannot be removed. +In the image below, you can see the default GPRINT Presets and the actions that +can be taken on them. Keep in mind that once a GPRINT Preset is being used by a +**Graph** or a **Graph Template**, it cannot be removed. ![GPRINT Presets](images/gprint-presets.png) -Below you can see the GPrint Preset edit screen. +Below you can see the GPRINT Preset edit screen. ![GPRINT Presets Edit](images/gprint-presets-edit.png) diff --git a/General-Installing-Instructions.md b/General-Installing-Instructions.md index 15eaa08d..3be2f6f1 100644 --- a/General-Installing-Instructions.md +++ b/General-Installing-Instructions.md @@ -1,30 +1,33 @@ # General Installing Instructions -> **Note**: As of Cacti 1.2.31, PHP 8.1 is required and PHP Composer is required. -> Composer will be used to ensure all of the libraries are installed and are up to date. +> **Note**: As of Cacti 1.2.31, PHP 8.1 is required and PHP Composer is +> required. Composer installs the vendor libraries and keeps them up to date. Make sure the following packages are installed according to your operating -systems requirements. Verify, that httpd/apache and MySQL/MariaDB are started at -system startup. +system's requirements. Verify that Apache and MySQL/MariaDB start at system +startup. -### A special Note on installing Cacti in LXC Containers such as the ones found on Proxmox +### A special note on installing Cacti in LXC containers such as those found on Proxmox -We recommend creating a privileged container. You may need to update your container's config file with +We recommend creating a privileged container. You may need to update your +container's config file with ```console lxc.apparmor.profile: unconfined ``` -This will allow for ICMP ping and other functions to work -A tested configuration file like below should be good however tune to your needs/standards +This will allow ICMP ping and other functions to work. + +A tested configuration file like the one below should work. Tune it to your own +needs and standards. ```console arch: amd64 cores: 2 hostname: cacti memory: 2048 -net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=mac-id,ip=dhcp,type=v> +net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=mac-id,ip=dhcp,type=veth ostype: ubuntu rootfs: local-lvm:vm-110-disk-0,size=8G swap: 2048 @@ -35,15 +38,15 @@ lxc.apparmor.profile: unconfined ## Required Packages for Most Operating Systems Depending on your operating system and PHP version, certain packages are -required for Cacti. The largest variable in these requirements come with regard -to PHP and MySQL/MariaDB. +required for Cacti. The largest variable in these requirements comes with +regard to PHP and MySQL/MariaDB. Installation requirements include the packages below. The installation of these packages will vary by operating system. ### Base OS -- apache, IIS, or nginx +- Apache, IIS, or nginx - net-snmp, net-snmp-utils @@ -78,8 +81,8 @@ or ### PHP Modules -The installation of these modules vary by OS. Use the `php -m` command to verify -that they are installed. +The installation of these modules varies by OS. Use the `php -m` command to +verify that they are installed. - posix @@ -115,12 +118,12 @@ The following modules are optional, but preferred to be installed. - gmp (for plugin support) -- com or dotnet (windows only) +- com or dotnet (Windows only) ### A special note for systems using PHP-FPM -Prior to starting the setup process of Cacti you should restart the PHP-FPM -Daemon to rebuild the Cache or you may receive a HTTP 500 Error +Before starting the Cacti setup process, restart the PHP-FPM daemon to rebuild +its cache, or you may receive an HTTP 500 error. ```console systemctl restart php-fpm @@ -128,21 +131,21 @@ systemctl restart php-fpm ## FreeBSD -When installing on FreeBSD you can use two ways. For both ways, cacti has a lot -of dependent packages, you don't need to install anything else. Everything is -prepared. Both ways have few pros and cons: +There are two ways to install on FreeBSD. In both cases Cacti pulls in its +dependent packages, so you do not need to install anything else. Each way has +trade-offs: -- Compiled packages - fast, but invariant dependencies (like older MySQL server, - PHP version, ...) +- Compiled packages: fast, but with fixed dependency versions (for example an + older MySQL server or PHP version). ```sh pkg install cacti pkg install spine ``` -- FreeBSD ports - compilation could last long time, but without invariant - dependencies (See - [Howto use ports](https://www.freebsd.org/doc/handbook/ports-using.html)) +- FreeBSD ports: compilation can take a long time, but dependency versions are + not fixed (see + [Using the Ports Collection](https://docs.freebsd.org/en/books/handbook/ports/)) ```sh pkg install git @@ -159,12 +162,12 @@ prepared. Both ways have few pros and cons: Apache and other software can be installed using packages or Ports as well. -Everything in FreeBSD is installed to /usr/local/ directory! In this -documentation you can see paths like /etc/php.ini, /usr/bin/spine, ... +Everything in FreeBSD is installed under /usr/local/. This documentation shows +paths such as /etc/php.ini and /usr/bin/spine. -Please use correct paths - /usr/local/etc, /usr/local/bin/spine, ... +Use the FreeBSD equivalents instead: /usr/local/etc, /usr/local/bin/spine. -For Spine set suid bit (without this, ICMP ping cannot function): +For Spine, set the suid bit (without it, ICMP ping cannot function): ```sh chmod +s /usr/local/bin/spine @@ -186,12 +189,11 @@ no need to discuss that here. ## Configure the Webserver (Apache) -Most Linux/UNIX OS' automatically configure the Web Server to allow PHP content. -So there should be no need to provide additional configuration. However, the -following section is included below for reference in the case that you are -running a UNIX version that does not properly configure the Webserver properly. -The documentation below is written specifically for RHEL and variants. So, the -instructions may vary. +Most Linux and UNIX systems automatically configure the web server to allow PHP +content, so no additional configuration should be needed. The section below is +included for reference in case you are running a UNIX version that does not +configure the web server correctly. It is written specifically for RHEL and its +variants, so the instructions may vary. Find the file `/etc/httpd/conf/httpd.conf` or its equivalent and make the following changes to it: @@ -240,27 +242,32 @@ the default character set for MySQL/MariaDB be i18n compatible. The Cacti installer will make specific recommendations on MySQL/MariaDB settings. Follow those as applicable for your OS. -Galera clustering: There are several tables which are set to use the MEMORY -storage engine which do not get replicated among nodes which can cause problems. -If you configure Cacti to only connect to one node of your cluster and are not -load balancing this does not apply to you. +Galera clustering: several tables use the MEMORY storage engine. Those tables +are not replicated among nodes, which can cause problems. If you configure Cacti +to connect to only one node of your cluster and are not load balancing, this +does not apply to you. If you are running multiple nodes in a load-balanced environment where you -connect to a VIP you should remove all but one node from rotation during Cacti -installation or update. After the installation/update login to your MySQL server -and execute the following commands to update those tables to use the InnoDB +connect to a VIP, remove all but one node from rotation during Cacti +installation or update. After the installation or update, log in to your MySQL +server and run the following commands to convert those tables to the InnoDB engine: ```sql MariaDB [(none)]> use cacti; -MariaDB [cacti]>> ALTER TABLE `automation_ips` ENGINE=InnoDB; -MariaDB [cacti]>> ALTER TABLE `automation_processes` ENGINE=InnoDB; -MariaDB [cacti]>> ALTER TABLE `data_source_stats_hourly_cache` ENGINE=InnoDB; -MariaDB [cacti]>> ALTER TABLE `data_source_stats_hourly_last` ENGINE=InnoDB; -MariaDB [cacti]>> ALTER TABLE `poller_output` ENGINE=InnoDB; -MariaDB [cacti]>> ALTER TABLE `poller_output_boost_processes` ENGINE=InnoDB; +MariaDB [cacti]> ALTER TABLE `automation_ips` ENGINE=InnoDB; +MariaDB [cacti]> ALTER TABLE `automation_processes` ENGINE=InnoDB; +MariaDB [cacti]> ALTER TABLE `data_source_stats_hourly_cache` ENGINE=InnoDB; +MariaDB [cacti]> ALTER TABLE `data_source_stats_hourly_last` ENGINE=InnoDB; +MariaDB [cacti]> ALTER TABLE `poller_output` ENGINE=InnoDB; +MariaDB [cacti]> ALTER TABLE `poller_output_boost_local_data_ids` ENGINE=InnoDB; +MariaDB [cacti]> ALTER TABLE `poller_output_boost_processes` ENGINE=InnoDB; +MariaDB [cacti]> ALTER TABLE `processes` ENGINE=InnoDB; ``` +On Cacti 1.3 the `data_source_stats_hourly_cache` table already uses InnoDB, +so that one statement is a no-op there. It is still required on 1.2.x. + These changes should replicate to the other nodes in your cluster. Allow Cacti to run at least two or three full polling cycles before placing the other nodes back into rotation. @@ -289,11 +296,9 @@ back into rotation. ```sql shell> mysql --user=root mysql - mysql> CREATE DATABASE cacti - mysql> CREATE USER 'cacti'@'localhost'; - mysql> ALTER USER 'cacti'@'localhost' IDENTIFIED BY 'somepassword'; - mysql> GRANT ALL PRIVILEGES ON cacti.* to 'cacti'@'localhost'; - mysql> GRANT SELECT ON mysql.time_zone_name TO 'cacti'@'localhost'; + mysql> CREATE USER 'cactiuser'@'localhost' IDENTIFIED BY 'somepassword'; + mysql> GRANT ALL PRIVILEGES ON cacti.* TO 'cactiuser'@'localhost'; + mysql> GRANT SELECT ON mysql.time_zone_name TO 'cactiuser'@'localhost'; mysql> FLUSH PRIVILEGES; ``` @@ -340,17 +345,18 @@ back into rotation. to poller.php ```console - */5 * * * * apache php /poller.php &>/dev/null + */5 * * * * apache php /poller.php >/dev/null 2>&1 ``` - For systemd unit's file install, you will need to modify the included units - file to following your install location and desired user and group's to run - the Cacti poller as. To complete the task, follow the procedure below: + To install the systemd unit file, first edit the included unit file to match + your install location and the user and group the Cacti poller should run as. + Then follow the procedure below: ```console vim /service/cactid.service (edit the path) touch /etc/sysconfig/cactid cp -p /service/cactid.service /etc/systemd/system + systemctl daemon-reload systemctl enable cactid systemctl start cactid systemctl status cactid @@ -363,9 +369,13 @@ back into rotation. and directories: ```sh - shell> chown -R resource scripts include/config.php + shell> chown -R apache:apache resource scripts include/config.php ``` + Use the account your web server runs as. That is `apache` on Enterprise + Linux and `www-data` on Debian and Ubuntu. Do not use the database + account here, because it is a MySQL user rather than a system user. + Once the installation is complete, you may change the permissions to more restrictive settings. @@ -373,7 +383,7 @@ back into rotation. `http:///cacti/` - Log in the with a username/password of _admin_. You will be required to + Log in with a username and password of _admin_. You will be required to change this password immediately. Make sure to fill in all of the path variables carefully and correctly on the following screen. @@ -381,38 +391,38 @@ back into rotation. Spine is a very fast data collection engine, written in C. It is an optional replacement for cmd.php. If you decide to use it, you will have to install it -explicitly. It does not come with cacti itself. +explicitly. It does not come with Cacti itself. The easiest way is to install Spine using rpm or ports. You will find packages -for Spine at the main cacti site or from your distribution. +for Spine at the main Cacti site or from your distribution. To compile Spine, download it to any location of your liking. Then, issue from the downloaded directory following commands ```sh -shell>./bootstrap +shell> ./bootstrap ``` If the `bootstrap` script is successful, you then will follow the instructions it provides to compile and install. -Assuming, you've managed to install spine correctly, you will have to configure -it. The configuration file may be placed in the same directory as spine itself -or at /etc/spine.conf. +Assuming you installed Spine correctly, you must now configure it. The +configuration file may be placed in the same directory as Spine itself or at +/etc/spine.conf. ```ini DB_Host 127.0.0.1 or hostname (not localhost) DB_Database cacti DB_User cactiuser -DB_Password cacti +DB_Pass cactiuser DB_Port 3306 ``` ### Considerations when using Proxies in front of Cacti (Cacti 1.2.23+) -For optimal security, only specify the HTTP headers that are set by your proxy -software. to prevent unauthorized access, These can be set by editing the -following section of config.php +For optimal security, specify only the HTTP headers that your proxy software +sets. This prevents unauthorized access through header spoofing. Set them by +editing the following section of `config.php`: ```php /* diff --git a/Graph-Overview.md b/Graph-Overview.md index ecd86bef..13fea646 100644 --- a/Graph-Overview.md +++ b/Graph-Overview.md @@ -6,7 +6,7 @@ pick. While it is possible to manually create graphs through this interface, new users should follow the instructions provided in the next chapter for creating **New Graphs** in Cacti. -For users who are familiar with [RRDtool](http://www.RRDtool.org/), you will +For users who are familiar with [RRDtool](https://www.rrdtool.org/), you will immediately recognize that a **Graph** in Cacti is closely modeled after RRDtool's graphs. This makes sense since Cacti provides a user friendly interface to RRDtool without requiring users to understand how RRDtool works. With this in diff --git a/Requirements.md b/Requirements.md index fbaa3102..2f2a0cc1 100644 --- a/Requirements.md +++ b/Requirements.md @@ -2,9 +2,9 @@ ## Hardware Sizing -The table below covers common deployment sizes. These are starting points; actual -requirements depend on polling interval, number of data sources per device, use of -Spine vs cmd.php, and whether remote pollers are used. +The table below covers common deployment sizes. These are starting points; +actual requirements depend on polling interval, number of data sources per +device, use of Spine vs cmd.php, and whether remote pollers are used. | Deployment size | Devices | Data sources | CPU cores | RAM | Disk | |---|---|---|---|---|---| @@ -24,25 +24,28 @@ Spine vs cmd.php, and whether remote pollers are used. consider it when you accept the durability trade-off (e.g. strong backup/replication strategy and tolerance for potential data loss on an unclean shutdown). -- Spine is CPU-bound. Each spine process spawns threads up to your configured - maximum; allocate 1–2 spine processes per CPU core for best throughput. -- Very large deployments (> 10,000 devices) require remote pollers deployed close to the devices - they poll rather than scaling a single main poller vertically. +- Spine is CPU-bound. Each Spine process spawns threads up to your configured + maximum; allocate 1–2 Spine processes per CPU core for best throughput. +- Very large deployments (> 10,000 devices) require remote pollers deployed + close to the devices they poll rather than scaling a single main poller + vertically. ## Software Requirements Cacti requires that the following software is installed on your system. -> **Note**: As of Cacti 1.2.31, PHP 8.1 is required. When installing from source or -> the develop branch, PHP Composer is required to install vendor dependencies. Pre-packaged -> releases include the required vendor files, so Composer is not needed for standard installs. +> **Note**: As of Cacti 1.2.31, PHP 8.1 is required. When installing from +> source or the develop branch, PHP Composer is required to install vendor +> dependencies. Pre-packaged releases include the required vendor files, so +> Composer is not needed for standard installs. -- Web Server that supports PHP e.g. Apache, Nginx, or IIS +- Web server that supports PHP, for example Apache, nginx, or IIS -- Build environment when using spine (gcc, automake, autoconf, libtool, +- Build environment when using Spine (gcc, automake, autoconf, libtool, help2man) -- RRDtool 1.5 or greater (1.8+ required for Cacti 1.3.x / develop branch) +- RRDtool 1.5 or greater (Cacti 1.3.x offers version settings for RRDtool 1.5 + through 1.11) - PHP 8.1 or greater - Required modules: @@ -50,14 +53,14 @@ Cacti requires that the following software is installed on your system. - hash, json, ldap, mbstring, mysqlnd, openssl, pcre - PDO, pdo_mysql, Phar, session, simplexml, sockets, spl - sqlite3, standard, xml, zlib - - com_dotnet (windows only) - - pcntl, posix (linux only) + - com_dotnet (Windows only) + - pcntl, posix (Linux only) - Optional modules: - - snmp - The PHP SNMP extension is optional. Cacti selectively bypasses it in - favor of Net-SNMP binaries for SNMPv3 queries, IPv6 targets, bulkwalk, and - hex-string output. You do not need to remove php-snmp; Cacti handles the - fallback automatically based on query type and device configuration. + - snmp - The PHP SNMP extension is optional. Cacti selectively bypasses it + in favor of Net-SNMP binaries for SNMPv3 queries, IPv6 targets, bulkwalk, + and hex-string output. You do not need to remove php-snmp; Cacti handles + the fallback automatically based on query type and device configuration. - Problematic software and configuration - SELinux, AppArmor, and ModSecurity can interfere with ICMP ping, socket @@ -85,17 +88,17 @@ Cacti requires that the following software is installed on your system. - **collation_server = utf8mb4_unicode_ci** When using Cacti with languages other than English, it is important to - use the utf8_general_ci collation type as some characters take more than - a single byte. If you are first just now installing Cacti, stop, make - the changes and start over again. If your Cacti has been running and is - in production, see the internet for instructions on converting your - databases and tables if you plan on supporting other languages. + use the utf8mb4_unicode_ci collation type as some characters take more + than a single byte. If you are first just now installing Cacti, stop, + make the changes and start over again. If your Cacti has been running + and is in production, see the internet for instructions on converting + your databases and tables if you plan on supporting other languages. - **character_set_client = utf8mb4** - **character_set_server = utf8mb4** When using Cacti with languages other than English, it is important to - use the utf8 character set as some characters take more than a single + use the utf8mb4 character set as some characters take more than a single byte. If you are first just now installing Cacti, stop, make the changes and start over again. If your Cacti has been running and is in production, see the internet for instructions on converting your @@ -103,10 +106,10 @@ Cacti requires that the following software is installed on your system. - **max_connections >= 100** - Depending on the number of logins and use of spine data collector, + Depending on the number of logins and use of the Spine data collector, MySQL/MariaDB will need many connections. The calculation for spine is: - ```php + ```text total_connections = total_processes * (total_threads + script_servers + 1) ``` @@ -141,7 +144,7 @@ Cacti requires that the following software is installed on your system. - **table_open_cache >= 200** - Keeping the table cache larger means less file open/close operations + Keeping the table cache larger means fewer file open/close operations when using innodb_file_per_table. (Note: `table_cache` was renamed to `table_open_cache` in MySQL 5.1.3; use `table_open_cache` on all current MySQL and MariaDB releases.) @@ -154,8 +157,8 @@ Cacti requires that the following software is installed on your system. - **tmp_table_size >= 64M** - When executing subqueries, having a larger temporary table size, keep - those temporary tables in memory. + When executing subqueries, a larger temporary table size keeps those + temporary tables in memory. - **join_buffer_size >= 64M** @@ -165,7 +168,7 @@ Cacti requires that the following software is installed on your system. - **innodb_file_per_table = ON** When using InnoDB storage it is important to keep your table spaces - separate. This makes managing the tables simpler for long time users of + separate. This makes managing the tables simpler for long-time users of MySQL/MariaDB. If you are running with this currently off, you can migrate to the per file storage by enabling the feature, and then running an alter statement on all InnoDB tables. @@ -174,7 +177,8 @@ Cacti requires that the following software is installed on your system. deprecated the variable in 11.0, so only set it where an older my.cnf turned it off. - - **innodb_data_file_path = ibdata1:12M:autoextend:autoshrink** (MariaDB 11.2.0+) + - **innodb_data_file_path = ibdata1:12M:autoextend:autoshrink** + (MariaDB 11.2.0+) Long running installs that accumulated blocking queries can end up with a very large ibdata1 file that never shrinks back down. The autoshrink @@ -189,12 +193,12 @@ Cacti requires that the following software is installed on your system. - **innodb_buffer_pool_size >= 25% of system RAM** - InnoDB will hold as much tables and indexes in system memory as is + InnoDB will hold as many tables and indexes in system memory as possible. Therefore, you should make the innodb_buffer_pool large - enough to hold as much of the tables and index in memory. Checking the - size of the /var/lib/mysql/cacti directory will help in determining this - value. We are recommending 25% of your systems total memory, but your - requirements will vary depending on your systems size. + enough to hold as many of the tables and indexes in memory as you can. + Checking the size of the /var/lib/mysql/cacti directory will help in + determining this value. We are recommending 25% of your system's total + memory, but your requirements will vary depending on your system's size. - **innodb_doublewrite = OFF** @@ -205,15 +209,17 @@ Cacti requires that the following software is installed on your system. on a volume with hardware-level write atomicity guarantees. Do not set on spinning disk or consumer SSDs without power-loss protection. - - ~~**innodb_additional_mem_pool_size**~~ (removed in MySQL 5.7.4 / MariaDB 10.0) + - ~~**innodb_additional_mem_pool_size**~~ (removed in MySQL 5.7.4 / + MariaDB 10.0) This setting no longer exists. MySQL/MariaDB manages metadata memory - internally. Remove it from my.cnf if present; MySQL 8.0+ will error on startup. + internally. Remove it from my.cnf if present; MySQL 8.0+ will error on + startup. - **innodb_lock_wait_timeout >= 50** - Rogue queries should not for the database to go offline to others. Kill - these queries before they kill your system. + Rogue queries should not cause the database to go offline to others. + Kill these queries before they kill your system. - **innodb_flush_log_at_trx_commit = 2** @@ -223,17 +229,17 @@ Cacti requires that the following software is installed on your system. - **innodb_flush_log_at_timeout >= 3** - If your MySQL/MariaDB version supports it, the you can control how often + If your MySQL/MariaDB version supports it, you can control how often MySQL/MariaDB flushes transactions to disk. The default is 1 second, but in high I/O systems setting to a value greater than 1 can allow disk - I/O to be more sequential + I/O to be more sequential. - - **innodb_read_IO_threads >= 32** + - **innodb_read_io_threads >= 32** With modern SSD type storage, having multiple read IO threads is advantageous for applications with high IO characteristics. - - **innodb_write_IO_threads >= 16** + - **innodb_write_io_threads >= 16** With modern SSD type storage, having multiple write IO threads is advantageous for applications with high IO characteristics. @@ -241,7 +247,7 @@ Cacti requires that the following software is installed on your system. - **innodb_buffer_pool_instances >= 16** (MySQL only) MySQL will divide the innodb_buffer_pool into memory regions to improve - performance with a maximum value is 64. When your innodb_buffer_pool is + performance, up to a maximum value of 64. When your innodb_buffer_pool is less than 1GB, you should use the pool size divided by 128MB. Continue to use this equation up to the max of 64. @@ -253,13 +259,13 @@ Cacti requires that the following software is installed on your system. > on the version of MySQL/MariaDB you are running, and some should be > scaled where appropriate. - - Newer MySQL/MariaDB software are using [strict - modes](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html) and it can + - Newer MySQL/MariaDB releases use [strict + modes](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html), which can cause unexpected problems when importing dumps of Cacti databases from older systems, like **Can't create table `cacti`.`poller_output_boost` (errno: 140 "Wrong create options")**. - You have more possibilities: + You have several options: - disable appropriate strict mode - not recommended @@ -269,8 +275,8 @@ Cacti requires that the following software is installed on your system. - before mysqldump run query: **ALTER TABLE `poller_output_boost` ROW_FORMAT=DYNAMIC;** -To implement the above mysql recommendations you can use the below entries and -paste them into my.cnf +To implement the above MySQL recommendations, you can paste the entries below +into my.cnf ```console innodb_flush_log_at_timeout = 4 diff --git a/SNMP-Options.md b/SNMP-Options.md index bac97b0c..39925269 100644 --- a/SNMP-Options.md +++ b/SNMP-Options.md @@ -2,9 +2,9 @@ This section will describe **SNMP Options** in Cacti. -The SNMP Options page stores the SNMP strings and credentials used by Cacti's -automation features. Cacti supports SNMP v1, v2, and v3. Enter the -network-specific SNMP details for the devices you will be polling below. +The SNMP Options page holds the SNMP strings and credentials that automation +uses when it scans a network. Cacti supports SNMP v1, v2c and v3, so enter the +details that match the devices you intend to poll. ![SNMP Options](images/automation-snmp-options.png). diff --git a/Settings-Auth.md b/Settings-Auth.md index 2cc1bd22..b2540f2f 100644 --- a/Settings-Auth.md +++ b/Settings-Auth.md @@ -2,51 +2,53 @@ ## Overview -Cacti provides four Authentication methods that can be leveraged to provide -Authentication services. When combined with the variety of Apache and NGINX -Modules, Cacti can support just about every Authentication method available -today in the industry. Those Authentication method include: +Cacti provides four Authentication methods. Combined with the Apache and +nginx authentication modules, Cacti can support most of the Authentication +methods in common use. Those Authentication methods are: -- **Built-in Authentication** - When using the method, Cacti will store both - the user account, and it's password on the Cacti server. When using this - method, Cacti will encrypt the users password using a strong password - encryption method and it will be rehashed periodically automatically. - Also, when using this method, Cacti complies with C3 password requirements. -- **Web Basic Authentication** - With this method, the Web Server itself - controls the Authentication. Using this method, Cacti can support protocols - such as SAML2 via OpenITC, NIS, LDAP, local password, TACAC+, etc. -- **LDAP/AD Authentication** - Cacti supports direct communications with LDAP +- **Built-in Authentication** - With this method, Cacti stores both the user + account and its password on the Cacti server. The password is hashed with + PHP's `password_hash()` using the default algorithm, and it is rehashed on + login whenever that default algorithm or its cost changes. This method + also supports the local complexity, history and expiry policies described + in [Local Authentication](Settings-Auth-Local.md). +- **Web Basic Authentication** - With this method, the web server itself + controls the Authentication. Cacti then accepts whatever the web server + authenticated, so the web server can front Cacti with SAML 2.0, Kerberos, + NIS, LDAP, a local password file, TACACS+ or another scheme. +- **LDAP Authentication** - Cacti supports direct communication with LDAP and Active Directory servers as well. When using this method, Cacti can limit what User Group may access Cacti based upon more detailed settings. - **Multiple LDAP/AD Domains** - When you have multiple security levels and/or LDAP and AD Domains that you wish to support, for example maybe you have Admins, Power Users, and General Users groups defined - and you wish to restrict who can login as who, this Authentication - method allows you to setup that type of security system. + and you wish to restrict who can log in as whom, this Authentication + method lets you set up that type of security system. For most of these `Authentication Methods`, there are some common settings -showing in the image below. +shown in the image below. ![Common Authentication Options](images/settings-auth-common.png) Those options include: - **Authentication Method** - One of the options below. -- **Support Authentication Cookies** - Provide Remember me that will keep a user - logged in from a single browser instance for up-to 90 days without - requesting that they re-validate their passwords. +- **Support Authentication Cookies** - Offers a `Keep me signed in` checkbox + on the login page. The authentication cookie keeps the user signed in on + that browser and expires after 90 days without use. The client must use + HTTPS for the cookie to be issued. - **Primary Admin** - This is the Primary Cacti Admin account. This user - account will receive all Cacti Administrative notification like when - the Cacti system is experiencing issues. + account receives Cacti administrative notifications, such as when the + Cacti system is experiencing issues. - **Guest User** - If you select a **Guest User**, people within an organization will be able to access certain Cacti pages without first authenticating. - This setting is good for the pages like the **Graph Page** where you may - with to embed live Cacti **Graphs** in other corporate websites. -- **User Template**, when creating new accounts, either LDAP, Web Basic, - or new Cacti local accounts, Cacti will pull the users default Authorization - from this Template User account. For some Cacti **Authentication Methods**, - you can have more than one Template User, for example: + This setting is good for pages like the **Graph Page** where you may + wish to embed live Cacti **Graphs** in other corporate websites. +- **User Template** - When creating new accounts, whether LDAP, Web Basic, + or new Cacti local accounts, Cacti takes the user's default authorization + from this Template User account. For some Cacti **Authentication Methods** + you can have more than one Template User, for example **Multiple LDAP/AD Domains**. In the sections below, we will go over these various @@ -56,9 +58,9 @@ In the sections below, we will go over these various [Web Basic Authentication](Settings-Auth-Basic.md) -[LDAP/AD Authentication](Settings-Auth-LDAP.md) +[LDAP Authentication](Settings-Auth-LDAP.md) -[Multiple LDAP/AD Authentication](Settings-Domains.md) +[Multiple LDAP/AD Domains](Settings-Domains.md) --- Copyright (c) 2004-2026 The Cacti Group diff --git a/Standards-PHP-Spec-Constructs.md b/Standards-PHP-Spec-Constructs.md index cf285f09..f881e8dd 100644 --- a/Standards-PHP-Spec-Constructs.md +++ b/Standards-PHP-Spec-Constructs.md @@ -5,10 +5,11 @@ Use the ```foreach ($array as $name => $value)``` syntax instead of ```while (list($name, $value) = each($array))``` syntax when traversing arrays. The former has been demonstrated to be more efficient and does not increment the -internal pointer of the array. Ensure the variable is an array or iterable object before passing it to `foreach` to prevent type warnings on null or boolean values. +internal pointer of the array. Check that the variable is an array before +passing it to `foreach`, otherwise a null or boolean value raises a warning. ```php -if (is_iterable($array)) { +if (is_array($array)) { foreach ($array as $name => $value) { // code } @@ -16,7 +17,10 @@ if (is_iterable($array)) { ``` It should be noted that with PHP 7.2 use of `list() = each()` syntax will result -in warnings and/or errors. It should also be noted that PHP 7.2 introduced warnings when passing non-countable types to `count()` or `sizeof()`. Variables must implement `Countable` or be an `array`. You should verify `is_array($variable) || $variable instanceof Countable` before calling `count()`. +in warnings and/or errors. PHP 7.2 also made `count()` and `sizeof()` warn on +non-countable values, so the argument must be an array or implement +`Countable`. Verify `is_array($variable) || $variable instanceof Countable` +before calling either function. ## Error Return Values @@ -40,7 +44,8 @@ be used, and are much faster. $items = explode(':', $string); ``` -Avoid legacy POSIX regex functions such as `split()`, which was removed in PHP 7.0. +Avoid legacy POSIX regex functions such as `split()`, which was removed in +PHP 7.0. ## Use `preg` Functions Instead of `ereg` diff --git a/Standards-SQL.md b/Standards-SQL.md index 61fcadcf..6a00cb90 100644 --- a/Standards-SQL.md +++ b/Standards-SQL.md @@ -38,9 +38,10 @@ $graphs = db_fetch_assoc_prepared('SELECT * FROM graph_local WHERE host_id = ? db_execute_prepared('UPDATE host SET description = ? WHERE id = ?', array('Local Machines', $id)); -// Escape strings if using legacy functions +// Escape strings if using legacy functions. db_qstr() returns the value +// already wrapped in quotes, so do not quote it again. $hostname = db_qstr('myhost.com'); -db_execute("UPDATE host SET hostname = $hostname WHERE id = $id"); +db_execute("UPDATE host SET hostname = $hostname WHERE id = " . (int) $id); ``` diff --git a/Standards-Security.md b/Standards-Security.md index 37d48b25..9aed55d9 100644 --- a/Standards-Security.md +++ b/Standards-Security.md @@ -4,7 +4,7 @@ Never trust input regardless of where it is coming from! The responsibility falls on the library functions to ensure that potentially dangerous input does -not introduce a security hole. Some sort of sanitation, validation, or quoting +not introduce a security hole. Some sort of sanitization, validation, or quoting must be provided for **all** arguments in a function. This ensures that bad data does not make its way into an SQL string, a filename, an executable, or even another function. @@ -19,14 +19,16 @@ you are using unvalidated data. They include: is actually an integer, if not, Cacti will block the page function from continuing. -* get_filter_request_var('somevariable', 'options') - This version of the - function can do all sorts of verification and sanitization. +* get_filter_request_var('somevariable', $filter, $options) - The second + argument is a PHP filter constant such as `FILTER_VALIDATE_INT` or + `FILTER_VALIDATE_REGEXP`, and the third is the matching options array. + This form covers the rest of the verification and sanitization cases. * set_request_var('somevariable', 'somevalue') - This function will set the Cacti request variable superglobal with a value. -Generally speaking, you should never use either `$_GET`, `$_REQUEST` or -`$_POST` in your Cacti code. Use the validators. When you do, you can +Generally speaking, you should never use `$_GET`, `$_POST` or `$_REQUEST` +directly in your Cacti code. Use the validators. When you do, you can turn on the Cacti setting `Log Input Validation Issues` when you are developing, and your Cacti log will include warnings when an invalid variable has been encountered. @@ -34,23 +36,27 @@ variable has been encountered. ## OS Command Injection Never pass unsanitized input to shell execution functions (`exec()`, -`shell_exec()`, `system()`, `passthru()`, `popen()`). Device fields, -OID strings, community names, and any other user-influenced values must -be treated as untrusted. - -Always escape arguments with `escapeshellarg()`. If you need to run an -external command from a plugin, use Cacti's `api_plugin_safe_exec()` API -where available, as it enforces an allowlist of permitted executables and -strips dangerous characters before any shell invocation. +`shell_exec()`, `system()`, `passthru()`, `popen()`, `proc_open()`). Device +fields, OID strings, community names, and any other user-influenced values +must be treated as untrusted. + +Escape every argument with Cacti's `cacti_escapeshellarg()` rather than the +PHP `escapeshellarg()` directly. The Cacti wrapper strips carriage returns +and line feeds, and it quotes correctly on both Unix and Windows, where +`escapeshellarg()` blanks out percent signs that RRDtool format strings need. +Where a whole command string has to be escaped, use `cacti_escapeshellcmd()`. +Neither function is a substitute for validating the value first: resolve +binaries from a fixed path and check arguments against an expected pattern +before the command is built. ## Prepared Statements The second method of hardening your Cacti application is through the use -of prepared SQL statements. When you use prepared SQL statements, the -Database API will validate that all variables have been properly escaped -making it much more difficult to perform SQL injection attacks on Cacti. +of prepared SQL statements. A prepared statement sends the query and the +values separately, so a value can never be parsed as SQL. This removes the +injection risk that string interpolation creates. -Examples of non-prepared function calls and prepared include: +Examples of a non-prepared call and its prepared equivalent: ```php $somevalue = db_fetch_cell("SELECT COUNT(*) @@ -71,19 +77,18 @@ $somevalue = db_fetch_cell_prepared('SELECT COUNT(*) ## Output Escaping Cacti provides an escaping function to reduce the likelihood of XSS -vulnerabilities in Cacti leading to exploitation of other Web Sites. -Cacti itself has a very restrictive XSS mitigation policy in affect -by default, but following proper output escaping minimizes problems. +vulnerabilities in Cacti leading to exploitation of other websites. +Cacti itself has a restrictive XSS mitigation policy in effect +by default, but proper output escaping still matters. -The following example is how to, and not to escape output: +The following examples show how, and how not, to escape output: ```php print "" . $some_variable . ""; ``` -Using the print statement above, for values that come from the database -can lead to Stored XSS vulnerabilities in your code. So, it's better -to use the following: +The print statement above can lead to Stored XSS in your code whenever the +value comes from the database. Use the following instead: ```php print "" . html_escape($some_variable) . ""; diff --git a/Tree-Rules.md b/Tree-Rules.md index df9ff7f7..665dd51a 100644 --- a/Tree-Rules.md +++ b/Tree-Rules.md @@ -36,7 +36,7 @@ a new tree Named Linux will be created if it does not already exist. ## Video Walkthrough -[![Video Tutorial](http://img.youtube.com/vi/yxO-CgaeFNc/0.jpg)](https://youtu.be/yxO-CgaeFNc "Video Tutorial") +[![Video Tutorial](https://img.youtube.com/vi/yxO-CgaeFNc/0.jpg)](https://youtu.be/yxO-CgaeFNc "Video Tutorial") --- Copyright (c) 2004-2026 The Cacti Group diff --git a/VDEFs.md b/VDEFs.md index 891a5e9b..9d08fb84 100644 --- a/VDEFs.md +++ b/VDEFs.md @@ -3,15 +3,15 @@ ## Background VDEF's in Cacti are a one to one analog to VDEF's in RRDtool. Cacti -simply provides and interface to create and manage them. Once the +simply provides an interface to create and manage them. Once the VDEF's are created in Cacti they can be imported and exported globally. -VDEFS's are mathematical formulas that instead of operating on just -one Data Point in the RRDfile, oerate on the entire Data Set in the time -range selected. So, VDEF's become an excellent tool to replace -Nth Percentile and Bandwidth function in Cacti with the VDEF equivalents. +VDEF's are mathematical formulas that, instead of operating on just +one Data Point in the RRDfile, operate on the entire Data Set in the time +range selected. So, VDEF's become a useful tool to replace the +Nth Percentile and Bandwidth functions in Cacti with the VDEF equivalents. -The are referenced in Cacti graphs as VNAMES. However, as mentioned before +They are referenced in Cacti graphs as VNAMES. However, as mentioned before Cacti automatically assigns VNAMES. So, to perform complex operations, you will have to experiment to determine the VNAME of your VDEF as you build your **Graph Template**. But in their simplest forms, they are @@ -20,13 +20,13 @@ quite easy to use. The format of the mathematical formulas is called Reverse Polish Notation (RPN). RPN was and is an early form of how Engineers entered equations into early HP and other Calculators to solve Engineering problems. The reason we still -use it today, is that it follows a simple Stack principle. In other words, +use it today is that it follows a simple Stack principle. In other words, it's not broken. ## VDEF Interface In the image below, you can see all the VDEF's that are included in Cacti by -default. They are included just to get you thinking about how your would use +default. They are included just to get you thinking about how you would use them. You can see straight away the first and the last items are 95th Percentile and Bandwidth (or Total) VDEF's. Other examples are pretty self explanatory. @@ -35,7 +35,7 @@ CDEF's you can not Delete a VDEF that is being used in a **Graph**. ![VDEFS](images/vdefs.png) -In the image below, you can also see that their interface very closely resembles +In the image below, you can also see that their interface closely resembles the CDEF Interface. Unlike the CDEF's, there is presently only one `Special Data Source` and that's the Current Data Source, which makes sense when you think about it. @@ -47,7 +47,7 @@ Percentile of the Current Data Source. Pretty straightforward. ![VDEF Item Edit](images/vdefs-edit2.png) -In the next two images, you can see the VDEF Item Types and the comprehensive +In the next two images, you can see the VDEF Item Types and the complete list of VDEF functions. Again, you can reference the [RRDtool Documentation](https://oss.oetiker.ch/rrdtool/doc/rrdgraph_rpn.en.html) for usage examples for more information. From 086e938082cc1b1b45aeea6c4a3274266abc484a Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Tue, 8 Sep 2026 00:29:12 -0700 Subject: [PATCH 4/5] docs: wrap Spine prose and fence the connection sizing formula The formula's bare asterisks rendered as emphasis, dropping the multiplication signs. Signed-off-by: Thomas Vincent --- Spine.md | 142 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 59 deletions(-) diff --git a/Spine.md b/Spine.md index f74a4d2e..48e01b80 100644 --- a/Spine.md +++ b/Spine.md @@ -1,45 +1,50 @@ # Spine -Spine is the high-speed, multi-threaded poller replacement for `cmd.php`. Written in C, -it provides dramatic performance improvements for data collection. Where `cmd.php` -can take several minutes to poll large installations, Spine routinely polls tens of -thousands of data sources in well under 60 seconds on modern multi-core hardware. +Spine is the high-speed, multi-threaded poller replacement for `cmd.php`. +Written in C, it provides dramatic performance improvements for data collection. +Where `cmd.php` can take several minutes to poll large installations, Spine +routinely polls tens of thousands of data sources in well under 60 seconds on +modern multi-core hardware. -Spine does not replace your cron or systemd scheduling entries. The scheduler entry point -remains `poller.php`. When Spine is selected as the poller engine, `poller.php` launches -Spine processes to perform the data collection across all configured devices. +Spine does not replace your cron or systemd scheduling entries. The scheduler +entry point remains `poller.php`. When Spine is selected as the poller engine, +`poller.php` launches Spine processes to perform the data collection across all +configured devices. --- ## Spine Architecture and Operating Principles -1. **Multi-Threaded Polling**: Spine executes a thread-per-device polling model within - multiple concurrent processes, allowing hundreds of metrics to be collected simultaneously. -2. **Persistent PHP Script Server**: For custom scripts, Spine starts and maintains - long-running PHP script server processes (`script_server.php`). This eliminates the - heavy overhead of repeatedly spawning the PHP binary for every individual script item. -3. **Privilege Separation (SUID Root)**: To perform raw ICMP pings without invoking external - ping utilities, Spine requires raw socket access. Spine achieves this by shipping with the - SUID root bit enabled (`chmod u+s`). At runtime, Spine strictly limits elevated privileges: - it elevates effective UID only during raw socket creation (serialized by an internal lock) - and immediately drops back to the calling user (such as `apache` or `www-data`). -4. **Direct Database Communication**: Spine queries the Cacti database directly via the - MySQL/MariaDB client library to retrieve polling targets and writes collected data directly - into the poller cache and RRD files. +1. **Multi-Threaded Polling**: Spine executes a thread-per-device polling model + within multiple concurrent processes, allowing hundreds of metrics to be + collected simultaneously. +2. **Persistent PHP Script Server**: For custom scripts, Spine starts and + maintains long-running PHP script server processes (`script_server.php`). + This eliminates the heavy overhead of repeatedly spawning the PHP binary for + every individual script item. +3. **Privilege Separation (SUID Root)**: To perform raw ICMP pings without + invoking external ping utilities, Spine requires raw socket access. Spine + achieves this by shipping with the SUID root bit enabled (`chmod u+s`). At + runtime, Spine strictly limits elevated privileges: it elevates effective UID + only during raw socket creation (serialized by an internal lock) and + immediately drops back to the calling user (such as `apache` or `www-data`). +4. **Direct Database Communication**: Spine queries the Cacti database directly + via the MySQL/MariaDB client library to retrieve polling targets and writes + collected data directly into the poller cache and RRD files. --- ## Installing Spine -Because Spine is written in C, it must be compiled against your local database and Net-SNMP -client development libraries. +Because Spine is written in C, it must be compiled against your local database +and Net-SNMP client development libraries. ### Prerequisites by Distribution #### Enterprise Linux 8 & 9 (RHEL, Rocky Linux, AlmaLinux) -Spine requires development headers found in the CodeReady Builder (`crb`) repository on EL 9, -or `powertools` on EL 8: +Spine requires development headers found in the CodeReady Builder (`crb`) +repository on EL 9, or `powertools` on EL 8: 1. Enable the repository: @@ -70,7 +75,8 @@ apt-get install -y build-essential autoconf automake libtool dos2unix help2man \ #### FreeBSD -On FreeBSD, Spine can be installed directly from pre-built packages or compiled from Ports: +On FreeBSD, Spine can be installed directly from pre-built packages or compiled +from Ports: ```console # Using binary packages: @@ -85,9 +91,11 @@ make install clean ### Downloading and Compiling Spine -> **Important**: The version of Spine MUST match your Cacti version (e.g., Spine 1.2.31 for Cacti 1.2.31). +> **Important**: The version of Spine MUST match your Cacti version. Use +> Spine 1.2.31 with Cacti 1.2.31. -1. Download the release archive matching your Cacti version (replace `X.Y.Z` with your version): +1. Download the release archive matching your Cacti version (replace `X.Y.Z` + with your version): ```console cd /tmp @@ -109,7 +117,8 @@ make install clean 3. Set binary permissions (SUID Root): - Spine must be owned by `root` with the setuid bit set so it can open raw ICMP sockets: + Spine must be owned by `root` with the setuid bit set so it can open raw ICMP + sockets: ```console chown root:root /usr/local/spine/bin/spine @@ -130,8 +139,8 @@ Spine reads its database connection parameters from `spine.conf`. 2. Secure the file permissions: - Because `spine.conf` contains the database password in plaintext, restrict permissions - so only `root` and the web server / poller group can read it: + Because `spine.conf` contains the database password in plaintext, restrict + permissions so only `root` and the web server / poller group can read it: ```console # On RHEL / Rocky / AlmaLinux (web group: apache): @@ -143,8 +152,8 @@ Spine reads its database connection parameters from `spine.conf`. chmod 0640 /usr/local/spine/etc/spine.conf ``` -3. Edit `/usr/local/spine/etc/spine.conf` and update the database settings to match your - Cacti `config.php`: +3. Edit `/usr/local/spine/etc/spine.conf` and update the database settings to + match your Cacti `config.php`: ```ini DB_Host localhost @@ -162,31 +171,33 @@ Spine reads its database connection parameters from `spine.conf`. ## Testing Spine from the Command Line -Before activating Spine in the Cacti web interface, verify that it can connect to the database, -query devices, and send ICMP pings without error. +Before activating Spine in the Cacti web interface, verify that it can connect +to the database, query devices, and send ICMP pings without error. ### 1. Read-Only Global Test -Run Spine in read-only test mode (`-R`) with summary statistics (`-S`) and verbosity level 3 (`-V 3`). -In this mode, Spine polls devices but does not write results into the database: +Run Spine in read-only test mode (`-R`) with summary statistics (`-S`) and +verbosity level 3 (`-V 3`). In this mode, Spine polls devices but does not write +results into the database: ```console /usr/local/spine/bin/spine -R -V 3 -S ``` -Verify that the output shows Spine reading `/usr/local/spine/etc/spine.conf` and completes with: -`SPINE: Execution Time: ... Total Hosts: ...` +Verify that the output shows Spine reading `/usr/local/spine/etc/spine.conf` and +completes with: `SPINE: Execution Time: ... Total Hosts: ...` ### 2. Device-Specific Test -To test a single device without polling your entire infrastructure, pass the host ID range using -`-f -l `: +To test a single device without polling your entire infrastructure, pass the +host ID range using `-f -l `: ```console /usr/local/spine/bin/spine -R -f 1 -l 1 -V 5 ``` -Check the verbose output for ICMP ping success, SNMP retrieval, and script execution without errors. +Check the verbose output for ICMP ping success, SNMP retrieval, and script +execution without errors. --- @@ -200,8 +211,9 @@ Once command-line verification passes, activate Spine in Cacti: 2. Navigate to **Console > Configuration > Settings > Paths**. 3. Under **Spine Poller File Path** (or **Spine Binary File Location**), enter: `/usr/local/spine/bin/spine` -4. Optionally, set **Spine Config File Path** to `/usr/local/spine/etc/spine.conf` (if left blank, - Spine automatically searches its sibling `../etc` directory). +4. Optionally, set **Spine Config File Path** to + `/usr/local/spine/etc/spine.conf` (if left blank, Spine automatically + searches its sibling `../etc` directory). 5. Verify that Cacti indicates `[OK: FILE FOUND]`. 6. Click **Save**. @@ -231,7 +243,8 @@ Configured under **Console > Configuration > Settings > Poller**: ### 2. Data Collector-Level Settings -Configured under **Console > Data Collection > Data Collectors** (select your collector): +Configured under **Console > Data Collection > Data Collectors** (select your +collector): | Parameter | Recommended Value | Description | | :--- | :--- | :--- | @@ -252,14 +265,19 @@ Configured on individual devices under **Console > Management > Devices**: ## Database Connection Sizing (`max_connections`) -Each concurrent Spine process, thread, and script server requires database connections. Ensure your -MySQL/MariaDB `max_connections` limit is sized adequately: +Each concurrent Spine process, thread, and script server requires database +connections. Ensure your MySQL/MariaDB `max_connections` limit is sized +adequately: +```text Total Connections >= (Data Collectors * Processes * (Threads + Script Servers + 2)) + 50 +``` -If this setting is too low, Spine will fail with `FATAL: Connection to MySQL database failed`. +If this setting is too low, Spine will fail with `FATAL: Connection to MySQL +database failed`. -Edit `/etc/my.cnf.d/server.cnf` (or `/etc/mysql/mariadb.conf.d/50-server.cnf`) and set: +Edit `/etc/my.cnf.d/server.cnf` (or `/etc/mysql/mariadb.conf.d/50-server.cnf`) +and set: ```ini [mysqld] @@ -274,7 +292,8 @@ Restart the database server after changing `max_connections`. ### SELinux (RHEL, Rocky Linux, AlmaLinux) -If SELinux is enforcing, allow the web server and poller to establish outgoing network connections: +If SELinux is enforcing, allow the web server and poller to establish outgoing +network connections: ```console setsebool -P httpd_can_network_connect 1 @@ -290,7 +309,8 @@ restorecon -v /usr/local/spine/bin/spine ### AppArmor (Ubuntu / Debian) -If using a confined profile for Apache or PHP-FPM, allow execution of the Spine binary: +If using a confined profile for Apache or PHP-FPM, allow execution of the Spine +binary: ```console # Add to /etc/apparmor.d/local/usr.sbin.apache2: @@ -313,8 +333,9 @@ apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2 #### 1. `FATAL: Unable to read configuration file! (Spine init)` * **Cause**: Spine cannot locate or read `spine.conf`. -* **Fix**: Ensure `/usr/local/spine/etc/spine.conf` exists and is readable by the user executing - the poller (e.g. `apache` or `www-data`): +* **Fix**: Ensure `/usr/local/spine/etc/spine.conf` exists and is readable by + the user executing the poller (e.g. `apache` or `www-data`): + ```console ls -la /usr/local/spine/etc/spine.conf chmod 640 /usr/local/spine/etc/spine.conf @@ -322,8 +343,10 @@ apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2 #### 2. `DEBUG: Falling back to UDP Ping Due to SetUID Issues` -* **Cause**: Spine is missing the SUID root permission required to open raw ICMP sockets. +* **Cause**: Spine is missing the SUID root permission required to open raw ICMP + sockets. * **Fix**: Restore SUID permissions on the binary: + ```console chown root:root /usr/local/spine/bin/spine chmod u+s /usr/local/spine/bin/spine @@ -331,15 +354,16 @@ apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2 #### 3. `FATAL: Connection to MySQL database failed` -* **Cause**: Incorrect database credentials in `spine.conf`, database host unreachable, or - MySQL/MariaDB `max_connections` reached. -* **Fix**: Test database connectivity manually with `mysql -u cactiuser -p -h localhost cacti` - and increase `max_connections` in your MySQL configuration. +* **Cause**: Incorrect database credentials in `spine.conf`, database host + unreachable, or MySQL/MariaDB `max_connections` reached. +* **Fix**: Test database connectivity manually with `mysql -u cactiuser -p -h + localhost cacti` and increase `max_connections` in your MySQL configuration. #### 4. Verification in Cacti Log -To confirm Spine is functioning in production, open **Console > Utilities > System Utilities > View Cacti Log**. -Look for the poller completion summary line: +To confirm Spine is functioning in production, open **Console > Utilities > +System Utilities > View Cacti Log**. Look for the poller completion summary +line: ```text SYSTEM STATS: Time:12.3456 Method:spine Processes:4 Threads:40 Hosts:250 HostsPerProcess:63 DataSources:12400 RRDsProcessed:6200 From 1f55c0ed52f2d051a20c521c60cdafe02a336d3b Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Tue, 8 Sep 2026 00:29:13 -0700 Subject: [PATCH 5/5] chore: refresh copyright year in scripts and issue templates Signed-off-by: Thomas Vincent --- .github/ISSUE_TEMPLATE/bad_link.md | 2 +- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- bin/build_html_docs.sh | 2 +- bin/check_markdown_style.sh | 2 +- bin/check_missing_link.sh | 2 +- bin/copyright_year.sh | 2 +- resources/unused_images.sh | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bad_link.md b/.github/ISSUE_TEMPLATE/bad_link.md index 9d42d51a..d4ccd97f 100644 --- a/.github/ISSUE_TEMPLATE/bad_link.md +++ b/.github/ISSUE_TEMPLATE/bad_link.md @@ -8,7 +8,7 @@ assignees: '' --- # Describe the link diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 3471bf10..b01ea0ea 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -8,7 +8,7 @@ assignees: '' --- # Describe the bug diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index f21f4fff..37d8ce17 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -8,7 +8,7 @@ assignees: '' --- # Feature Request diff --git a/bin/build_html_docs.sh b/bin/build_html_docs.sh index 8f628bdc..8f43233f 100755 --- a/bin/build_html_docs.sh +++ b/bin/build_html_docs.sh @@ -1,6 +1,6 @@ #!/bin/bash # +-------------------------------------------------------------------------+ -# | Copyright (C) 2004-2025 The Cacti Group | +# | Copyright (C) 2004-2026 The Cacti Group | # | | # | This program is free software; you can redistribute it and/or | # | modify it under the terms of the GNU General Public License | diff --git a/bin/check_markdown_style.sh b/bin/check_markdown_style.sh index 7f6ac0f3..ddf6b289 100755 --- a/bin/check_markdown_style.sh +++ b/bin/check_markdown_style.sh @@ -1,6 +1,6 @@ #!/bin/sh # +-------------------------------------------------------------------------+ -# | Copyright (C) 2004-2025 The Cacti Group | +# | Copyright (C) 2004-2026 The Cacti Group | # | | # | This program is free software; you can redistribute it and/or | # | modify it under the terms of the GNU General Public License | diff --git a/bin/check_missing_link.sh b/bin/check_missing_link.sh index e8653c8f..569e1abe 100755 --- a/bin/check_missing_link.sh +++ b/bin/check_missing_link.sh @@ -1,6 +1,6 @@ #!/bin/bash # +-------------------------------------------------------------------------+ -# | Copyright (C) 2004-2025 The Cacti Group | +# | Copyright (C) 2004-2026 The Cacti Group | # | | # | This program is free software; you can redistribute it and/or | # | modify it under the terms of the GNU General Public License | diff --git a/bin/copyright_year.sh b/bin/copyright_year.sh index 4b46337f..235bd47a 100644 --- a/bin/copyright_year.sh +++ b/bin/copyright_year.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # +-------------------------------------------------------------------------+ -# | Copyright (C) 2004-2025 The Cacti Group | +# | Copyright (C) 2004-2026 The Cacti Group | # | | # | This program is free software; you can redistribute it and/or | # | modify it under the terms of the GNU General Public License | diff --git a/resources/unused_images.sh b/resources/unused_images.sh index 442675de..128b5681 100644 --- a/resources/unused_images.sh +++ b/resources/unused_images.sh @@ -1,6 +1,6 @@ #!/bin/sh # +-------------------------------------------------------------------------+ -# | Copyright (C) 2004-2025 The Cacti Group | +# | Copyright (C) 2004-2026 The Cacti Group | # | | # | This program is free software; you can redistribute it and/or | # | modify it under the terms of the GNU General Public License |