Centmin Mod Advanced Customised Installation Guide

The initial Centmin Mod install guide and the Getting Started guide outline the normal way of installing Centmin Mod LEMP stack on CentOS 7.x 64bit based server. However, there’s additional steps you can do to further customise your Centmin Mod LEMP default out of the box configuration and to enable additional optional features.

Updated: June 10, 2024 – included updated variables some which only apply to EL8/EL9 operating system Centmin Mod LEMP stack installs i.e. AlmaLinux/Rocky Linux 8/9.

The following outlined SSH commands are to be run within the same SSH session window.

First set your desired notification email address in variable, EMAIL

# set your email address you want to receive alerts and server emails
EMAIL=youremail@address.com

Then setup the persistent configuration file which allows you to override Centmin Mod’s centmin.sh menu script’s default settings without modifying centmin.sh itself.

# create initial persistent config file to override centmin.sh defaults
# https://centminmod.com/upgrade.html#persistent
mkdir -p /etc/centminmod
touch /etc/centminmod/custom_config.inc

Populate the persistent configuration file with variables which enable advanced features in Centmin Mod LEMP stack

# enable letsencrypt ssl certificate + dual RSA+ECDSA ssl certs https://centminmod.com/acmetool/
echo "LETSENCRYPT_DETECT='y'" >> /etc/centminmod/custom_config.inc
echo "DUALCERTS='y'" >> /etc/centminmod/custom_config.inc

# override Nginx default HTTPS/TLS crypto library used in EL8/EL9 OSes
# set OPENSSL_SYSTEM_USE='n' if you want Nginx to use compiled OpenSSL
# set OPENSSL_SYSTEM_USE='y' which is default now to use EL8 OpenSSL 1.1.1/EL9 OpenSSL 3.0.7 system library with Nginx
# https://community.centminmod.com/threads/25407/
echo "OPENSSL_SYSTEM_USE='y'" >> /etc/centminmod/custom_config.inc

# dynamically tune nginx ssl_session_cache in /usr/local/nginx/conf/ssl_include.conf based
# on system detected memory
# https://community.centminmod.com/posts/76615/
echo "NGINX_SSLCACHE_ALLOWOVERRIDE='y'" >> /etc/centminmod/custom_config.inc

# override Nginx default OCSP response cache refresh time 1h (3600 seconds) to 24hrs (86400 seconds)
# https://community.centminmod.com/threads/19515/
echo "NGINX_STAPLE_CACHE_OVERRIDE='y'" >> /etc/centminmod/custom_config.inc
echo "NGINX_STAPLE_CACHE_TTL='86400'" >> /etc/centminmod/custom_config.inc

# SET_DEFAULT_MYSQLCHARSET='utf8mb4' to override MariaDB MySQL 
# default characterset and collation from default utf8 to utf8mb4
# https://community.centminmod.com/threads/17949/
echo "SET_DEFAULT_MYSQLCHARSET='utf8mb4'" >> /etc/centminmod/custom_config.inc

# enable nginx backlog override https://community.centminmod.com/threads/17620/
echo "AUTOHARDTUNE_NGINXBACKLOG='y'" >> /etc/centminmod/custom_config.inc

# enable zstd compressed logrotation for nginx & php-fpm https://community.centminmod.com/threads/16374/
echo "ZSTD_LOGROTATE_NGINX='y'" >> /etc/centminmod/custom_config.inc
echo "ZSTD_LOGROTATE_PHPFPM='y'" >> /etc/centminmod/custom_config.inc

# enable ECC 256bit ECDSA self-signed SSL certificate generation https://community.centminmod.com/posts/82177/
echo "SELFSIGNEDSSL_ECDSA='y'" >> /etc/centminmod/custom_config.inc

# enable nginx zero downtime on the fly nginx binary upgrades https://community.centminmod.com/threads/8000/
#echo "NGINX_ZERODT='y'" >> /etc/centminmod/custom_config.inc

# enable brotli compression https://community.centminmod.com/threads/10688/
echo "NGINX_LIBBROTLI='y'" >> /etc/centminmod/custom_config.inc
echo "NGXDYNAMIC_BROTLI='y'" >> /etc/centminmod/custom_config.inc

# run needs-restarting command only on Friday, Saturday and Sunday to check if any YUM updates require or recommend a server reboot and alert the user on SSH login https://community.centminmod.com/threads/24083/
echo "NEEDRESTART_CHECK='y'" >> /etc/centminmod/custom_config.inc

# boost PHP 7 performance by enabling Profile Guided Optimisation flag
# https://centminmod.com/perf/
# will dramatically increase PHP-FPM compile/install times but result in
# 5-20% faster PHP 7+ performance. PHP_PGO='y' only works with servers with
# 2+ or more cpu threads. However, you can force PHP PGO optimisations with
# 1 cpu thread servers via PHP_PGO_ALWAYS='y'
echo "PHP_PGO_ALWAYS='y'" >> /etc/centminmod/custom_config.inc
echo "PHP_PGO='y'" >> /etc/centminmod/custom_config.inc

# php compression extensions https://community.centminmod.com/posts/70777/
echo "PHP_BROTLI='y'" >> /etc/centminmod/custom_config.inc
echo "PHP_LZFOUR='y'" >> /etc/centminmod/custom_config.inc
echo "PHP_LZF='y'" >> /etc/centminmod/custom_config.inc
echo "PHP_ZSTD='y'" >> /etc/centminmod/custom_config.inc

# enable PHP latest version check on SSH logins MOTD
# https://community.centminmod.com/threads/19540/
echo "DMOTD_PHPCHECK='y'" >> /etc/centminmod/custom_config.inc

# php file info
echo "PHPFINFO='y'" >> /etc/centminmod/custom_config.inc

# enable centmin.sh menu option 22 WordPress Cache Enabler Query String inclusions
# https://community.centminmod.com/posts/85927/
echo "WPCLI_CE_QUERYSTRING_INCLUDED='y'" >> /etc/centminmod/custom_config.inc

In May 2022, Centmin Mod’s CSF Firewall switched its geolocation database for IP to Country lookups away from default Maxmind GeoLite2 database to DB-IP database. If you want to continue using Maxmind GeoLite2 database for geolocation lookups, you will need to register your own Maxmind account and generate the token API in Services > My License Key section of your Maxmind account or via link at https://www.maxmind.com/en/accounts/current/license-key. Then set 2 variables in persistent config file /etc/centminmod/custom_config.inc.

MM_LICENSE_KEY='YOUR_OWN_MAXMIND_API_KEY'
MM_CSF_SRC='y'

In June 2022, Centmin Mod 130.00beta01 and newer versions added the ability to run custom SSH commands after Nginx or PHP-FPM installation/recompile/upgrade runs.

  • on centmin.sh menu option 5 runs, added run_after_php_upgrade function which is triggered if prior to run, you create a shell script at /etc/centminmod/run-after-php-upgrade.sh – listing the additional SSH commands you want to run after PHP upgrade/recompiles
  • on initial Centmin Mod installation of PHP, add run_after_php_install function which is triggered when prior to install you create a shell script at /etc/centminmod/run-after-php-install.sh – listing the additional SSH commands you want to run after PHP initial installation
  • on centmin.sh menu option 4 runs, added run_after_nginx_upgrade function which is triggered if prior to run, you create a shell script at /etc/centminmod/run-after-nginx-upgrade.sh – listing the additional SSH commands you want to run after Nginx upgrade/recompiles
  • on initial Centmin Mod installation of Nginx, add run_after_nginx_install function which is triggered when prior to install you create a shell script at /etc/centminmod/run-after-nginx-install.sh – listing the additional SSH commands you want to run after Nginx initial installation
  • For example, for installing PHP event extension which isn’t provided by Centmin Mod requires the SSH commands outlined here. If you placed those commands into /etc/centminmod/run-after-php-upgrade.sh and /etc/centminmod/run-after-php-install.sh, then Centmin Mod will run those commands after initial PHP install completion or after PHP upgrade/recompiles automatically

The actual Centmin Mod LEMP stack install command line using latest betainstaller73.sh script so PHP (php-fpm) 7.3 latest version is default installed. Below are other default PHP version installers – only use one of them and only run once to completion.

# install centmin mod latest beta with php-fpm 7.3 default
# https://community.centminmod.com/threads/centmin-mod-09-beta-branch-testing.4128/
yum -y update; curl -O https://centminmod.com/betainstaller73.sh && chmod 0700 betainstaller73.sh && bash betainstaller73.sh

Or if you prefer to default to PHP 7.4 latest, the Centmin Mod LEMP stack install command line using latest betainstaller74.sh script so PHP (php-fpm) 7.4 latest version is default installed.

# install centmin mod latest beta with php-fpm 7.4 default
# https://community.centminmod.com/threads/centmin-mod-09-beta-branch-testing.4128/
yum -y update; curl -O https://centminmod.com/betainstaller74.sh && chmod 0700 betainstaller74.sh && bash betainstaller74.sh

Or default to PHP 8.0 latest, the Centmin Mod LEMP stack install command line using latest betainstaller80.sh script so PHP (php-fpm) 8.0 latest version is default installed.

# install centmin mod latest beta with php-fpm 8.0 default
# https://community.centminmod.com/threads/centmin-mod-09-beta-branch-testing.4128/
yum -y update; curl -O https://centminmod.com/betainstaller80.sh && chmod 0700 betainstaller80.sh && bash betainstaller80.sh

Or default to PHP 8.1 latest, the Centmin Mod LEMP stack install command line using latest betainstaller81.sh script so PHP (php-fpm) 8.1 latest version is default installed.

# install centmin mod latest beta with php-fpm 8.1 default
# https://community.centminmod.com/threads/centmin-mod-09-beta-branch-testing.4128/
yum -y update; curl -O https://centminmod.com/betainstaller81.sh && chmod 0700 betainstaller81.sh && bash betainstaller81.sh

Then you can pre-create Nginx HTTPS site’s dhparam file before hand to speed up subsequent Nginx vhost creation routines. On slow systems, this command will take a few minutes to complete.

openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048

Then optional extra features you can choose to enable after Centmin Mod LEMP stack has been installed for Auditd and CSF Firewall advance blocklists

# install and configure auditd https://community.centminmod.com/posts/37680/
echo "AUDITD_ENABLE='y'" >> /etc/centminmod/custom_config.inc
/usr/local/src/centminmod/tools/auditd.sh setup

# setup extended CSF Firewall blocklists https://community.centminmod.com/posts/50060/
/usr/local/src/centminmod/tools/csf-advancetweaks.sh

Optionally enable CSF Firewall native fail2ban like rules

# enable CSF Firewall native fail2ban like support
# https://community.centminmod.com/posts/62343/
csf --profile backup backup-b4-customregex
cp -a /usr/local/csf/bin/regex.custom.pm /usr/local/csf/bin/regex.custom.pm.bak
egrep 'CUSTOM1_LOG|CUSTOM2_LOG|CUSTOM3_LOG|CUSTOM4_LOG' /etc/csf/csf.conf
sed -i "s|CUSTOM1_LOG = .*|CUSTOM1_LOG = \"/home/nginx/domains/\*/log/access.log\"|" /etc/csf/csf.conf
sed -i "s|CUSTOM2_LOG = .*|CUSTOM2_LOG = \"/home/nginx/domains/\*/log/error.log\"|" /etc/csf/csf.conf
sed -i "s|CUSTOM3_LOG = .*|CUSTOM3_LOG = \"/var/log/nginx/localhost.access.log\"|" /etc/csf/csf.conf
sed -i "s|CUSTOM4_LOG = .*|CUSTOM4_LOG = \"/var/log/nginx/localhost.error.log\"|" /etc/csf/csf.conf
egrep 'CUSTOM1_LOG|CUSTOM2_LOG|CUSTOM3_LOG|CUSTOM4_LOG' /etc/csf/csf.conf
wget -O /usr/local/csf/bin/regex.custom.pm https://gist.github.com/centminmod/f5551b92b8aba768c3b4db84c57e756d/raw/regex.custom.pm
csf -ra

Then setup disk space usage alerts making use of EMAIL variable you populated at the start of this guide. If you set this up, make sure to do Getting Started guide’s step 20 for proper outbound server email sending and Postfix SMTP relay setup with some VPS providers. Otherwise, you may not receive email alerts from your server’s outbound Postfix MTA server.

# setup email alerts for diskalert cronjob /etc/cron.daily/diskalert
# https://community.centminmod.com/posts/59973/
sed -i "s|EMAIL=.*|EMAIL='$EMAIL'|" /etc/cron.daily/diskalert

Lastly, if you intend to use Cloudflare in front of your Centmin Mod LEMP stack’s Nginx server, you can setup csfcf.sh cronjob to automatically manage Cloudflare’s IPs in CSF Firewall and Nginx real IP address detection. Note Centmin Mod 124.00stable and 130.00beta01 and newer, automatically setup the below tools/csfcf.sh cronjob already.

# cloudflare cronjob
# https://community.centminmod.com/threads/6241/
crontab -l > cronjoblist
sed -i '/csfcf.sh/d' cronjoblist
echo "23 */12 * * * /usr/local/src/centminmod/tools/csfcf.sh auto >/dev/null 2>&1" >> cronjoblist
crontab cronjoblist

End result is an optimised Centmin Mod LEMP stack installation

With Nginx 1.27.0 mainline version with OpenSSL 1.1.1 branch AlmaLinux 8 system version with HTTP/2 HTTPS TLS 1.3 support and built using GCC 13.2.1 compiler

nginx -V
nginx version: nginx/1.27.0 (090624-223722-almalinux8-kvm-916d8c0)
built by gcc 13.2.1 20231205 (Red Hat 13.2.1-6) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: –with-ld-opt=’-Wl,-E -L/usr/local/zlib-cf/lib -L/usr/local/nginx-dep/lib -ljemalloc -Wl,-z,relro,-z,now -Wl,-rpath,/usr/local/zlib-cf/lib:/usr/local/nginx-dep/lib -pie -flto=2 -flto-compression-level=3 -fuse-ld=gold’ –with-cc-opt=’-I/usr/local/zlib-cf/include -I/usr/local/nginx-dep/include -m64 -march=native -fPIC -g -O3 -fstack-protector-strong -flto=2 -flto-compression-level=3 -fuse-ld=gold –param=ssp-buffer-size=4 -Wformat -Wno-pointer-sign -Wimplicit-fallthrough=0 -Wno-cast-align -Wno-implicit-function-declaration -Wno-builtin-declaration-mismatch -Wno-deprecated-declarations -Wno-int-conversion -Wno-unused-result -Wno-vla-parameter -Wno-maybe-uninitialized -Wno-return-local-addr -Wno-array-parameter -Wno-alloc-size-larger-than -Wno-address -Wno-array-bounds -Wno-discarded-qualifiers -Wno-stringop-overread -Wno-stringop-truncation -Wno-missing-field-initializers -Wno-unused-variable -Wno-format -Wno-error=unused-result -Wno-missing-profile -Wno-stringop-overflow -Wno-free-nonheap-object -Wno-discarded-qualifiers -Wno-bad-function-cast -Wno-dangling-pointer -Wno-array-parameter -fcode-hoisting -Wno-cast-function-type -Wno-format-extra-args -Wp,-D_FORTIFY_SOURCE=2′ –prefix=/usr/local/nginx –sbin-path=/usr/local/sbin/nginx –conf-path=/usr/local/nginx/conf/nginx.conf –build=090624-223722-almalinux8-kvm-916d8c0 –with-compat –without-pcre2 –with-http_stub_status_module –with-http_secure_link_module –with-libatomic –with-http_gzip_static_module –with-http_sub_module –with-http_addition_module –with-http_image_filter_module=dynamic –with-http_geoip_module –with-stream_geoip_module –with-stream_realip_module –with-stream_ssl_preread_module –with-threads –with-stream –with-stream_ssl_module –with-http_realip_module –add-dynamic-module=../ngx-fancyindex-0.4.2 –add-module=../ngx_cache_purge-2.5.1 –add-dynamic-module=../ngx_devel_kit-0.3.2 –add-dynamic-module=../set-misc-nginx-module-0.33 –add-dynamic-module=../echo-nginx-module-0.63 –add-module=../redis2-nginx-module-0.15 –add-module=../ngx_http_redis-0.4.0-cmm –add-module=../memc-nginx-module-0.19 –add-module=../srcache-nginx-module-0.33 –add-dynamic-module=../headers-more-nginx-module-0.34 –with-pcre-jit –with-zlib=../zlib-cloudflare-1.3.3 –with-zlib-opt=-fPIC –with-http_ssl_module –with-http_v2_module

PHP 8.0.30 php-fpm build

php -v
PHP 8.0.30 (cli) (built: Jun  9 2024 09:07:45) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.30, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.30, Copyright (c), by Zend Technologies

MariaDB MySQL 10.4 server

mysqladmin ver
mysqladmin  Ver 9.1 Distrib 10.4.34-MariaDB, for Linux on x86_64
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Server version          10.4.34-MariaDB
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /var/lib/mysql/mysql.sock
Uptime:                 14 hours 10 min 47 sec

Threads: 3  Questions: 11  Slow queries: 0  Opens: 20  Flush tables: 1  Open tables: 13  Queries per second avg: 0.000

Then check out the following: