diff --git a/assets/default.nginxconf b/assets/default.nginxconf index 30f3d21..102629c 100644 --- a/assets/default.nginxconf +++ b/assets/default.nginxconf @@ -76,6 +76,13 @@ server { return 404; } + location /nginx_status { + stub_status on; + access_log off; + allow 127.0.0.1; + allow ZABBIX-SERVER-IP; + deny all; + } } diff --git a/assets/zabbix/apt.conf b/assets/zabbix/apt.conf new file mode 100644 index 0000000..84f1589 --- /dev/null +++ b/assets/zabbix/apt.conf @@ -0,0 +1,6 @@ +# Treat security and regular updates differently +# This is just a simulation, that can be run under zabbix user +# Since updating packages lists (apt-get update) requires root user, +# use APT::Periodic or some other functionality for that +UserParameter=apt.security,apt-get -s upgrade | grep -ci ^inst.*security | tr -d '\n' +UserParameter=apt.updates,apt-get -s upgrade | grep -iPc '^Inst((?!security).)*$' | tr -d '\n' diff --git a/assets/zabbix/debian-updates-BAD.conf b/assets/zabbix/debian-updates-BAD.conf new file mode 100644 index 0000000..b575cbf --- /dev/null +++ b/assets/zabbix/debian-updates-BAD.conf @@ -0,0 +1,6 @@ +# Check for debian updates +UserParameter=debian_updates[*], aptitude -F%p search "?upgradable ?archive(`sed '/^deb .*$1/!d;s/^deb [^ ]* \([^ ]*\) .*/\1/;q' /etc/apt/sources.list`)" 2>/dev/null | wc -l +# Increase the global timeout (unfortunately), or zabbix killing +# aptitude will leave a /tmp/aptitude-zabbix.* directory turd every +# now and then. +Timeout=12 diff --git a/assets/zabbix/misc/02periodic b/assets/zabbix/misc/02periodic new file mode 100644 index 0000000..18ec023 --- /dev/null +++ b/assets/zabbix/misc/02periodic @@ -0,0 +1,2 @@ +APT::Periodic::Enable "1"; +APT::Periodic::Update-Package-Lists "1"; diff --git a/assets/zabbix/promox-ct.conf b/assets/zabbix/promox-ct.conf new file mode 100644 index 0000000..97c1c89 --- /dev/null +++ b/assets/zabbix/promox-ct.conf @@ -0,0 +1,5 @@ +# https://support.zabbix.com/browse/ZBX-12164 +# https://github.com/kvaps/zabbix-linux-container-template +UserParameter=ct.memory.size[*],free -b | awk '$ 1 == "Mem:" {total=$ 2; used=($ 3+$ 5); pused=(($ 3+$ 5)*100/$ 2); free=$ 4; pfree=($ 4*100/$ 2); shared=$ 5; buffers=$ 6; cache=$ 6; available=($ 6+$ 7); pavailable=(($ 6+$ 7)*100/$ 2); if("$1" == "") {printf("%.0f", total )} else {printf("%.0f", $1 "" )} }' +UserParameter=ct.swap.size[*],free -b | awk '$ 1 == "Swap:" {total=$ 2; used=$ 3; free=$ 4; pfree=($ 4*100/$ 2); pused=($ 3*100/$ 2); if("$1" == "") {printf("%.0f", free )} else {printf("%.0f", $1 "" )} }' +UserParameter=ct.cpu.load[*],uptime | awk -F'[, ]+' '{avg1=$(NF-2); avg5=$(NF-1); avg15=$(NF)}{print $2/'$(nproc)'}' diff --git a/assets/zabbix/scripts/nginx-stat.py b/assets/zabbix/scripts/nginx-stat.py new file mode 100644 index 0000000..6a8ce43 --- /dev/null +++ b/assets/zabbix/scripts/nginx-stat.py @@ -0,0 +1,91 @@ +#!/usr/bin/python +# +# Options: +# +# -a active +# -a accepted +# -a handled +# -a requests +# -a reading +# -a writing +# -a waiting +# + + +import sys +import getopt +import urllib2 +import re +import ssl + + +def usage(): + print "usage: nginx-stat.py -h 127.0.0.1 -p 80 -a [active|accepted|handled|request|reading|writing|waiting]" + sys.exit(2) + + +def main(): + + # Default values + host = "localhost" + port = "80" + getInfo = "None" + proto = "http" + _headers = {} + gcontext = "" + + + if len(sys.argv) < 2: + usage() + + try: + opts, _ = getopt.getopt(sys.argv[1:], "h:p:a:") + except getopt.GetoptError: + usage() + + # Assign parameters as variables + for opt, arg in opts: + if opt == "-h": + host = arg + if opt == "-p": + port = arg + if opt == "-a": + getInfo = arg + + if port == "443": + proto = "https" + _headers = {'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'} + gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) + + url = proto + "://" + host + ":" + port + "/nginx_status/" + request = urllib2.Request(url, headers=_headers) + result = urllib2.urlopen(request, context=gcontext) + + buffer = re.findall(r'\d{1,8}', result.read()) + +## Format: +## Active connections: 196 +## server accepts handled requests +## 272900 272900 328835 +## Reading: 0 Writing: 6 Waiting: 190 + + if getInfo == "active": + print buffer[0] + elif getInfo == "accepted": + print buffer[1] + elif getInfo == "handled": + print buffer[2] + elif getInfo == "requests": + print buffer[3] + elif getInfo == "reading": + print buffer[4] + elif getInfo == "writing": + print buffer[5] + elif getInfo == "waiting": + print buffer[6] + else: + print "unknown" + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/assets/zabbix/templates/apt-updates.xml b/assets/zabbix/templates/apt-updates.xml new file mode 100644 index 0000000..05bc877 --- /dev/null +++ b/assets/zabbix/templates/apt-updates.xml @@ -0,0 +1,170 @@ + + + 3.2 + 2017-01-29T14:52:23Z + + + Templates + + + + + + + + {Template App APT Updates:apt.security.last()}>0 and {Template App APT Updates:apt.updates.last()}>0 + 0 + + {ITEM.LASTVALUE1} security and {ITEM.LASTVALUE2} regular updates on {HOST.NAME} + 0 + + + 0 + 2 + + 0 + 1 + + + + + {Template App APT Updates:apt.updates.last()}>0 and {Template App APT Updates:apt.security.last()}=0 + 0 + + {ITEM.LASTVALUE} regular updates on {HOST.NAME} + 0 + + + 0 + 1 + + 0 + 1 + + + + + {Template App APT Updates:apt.security.last()}>0 and {Template App APT Updates:apt.updates.last()}=0 + 0 + + {ITEM.LASTVALUE} security updates on {HOST.NAME} + 0 + + + 0 + 2 + + 0 + 1 + + + + + diff --git a/assets/zabbix/templates/zbx_linux_container_template.xml b/assets/zabbix/templates/zbx_linux_container_template.xml new file mode 100644 index 0000000..017bcd3 --- /dev/null +++ b/assets/zabbix/templates/zbx_linux_container_template.xml @@ -0,0 +1,2487 @@ + + + 3.4 + 2018-01-25T15:03:17Z + + + Templates + + + + + + + + {Template Linux Container:vfs.file.cksum[/etc/passwd].diff(0)}>0 + 0 + + /etc/passwd has been changed on {HOST.NAME} + 0 + + + 0 + 2 + + 0 + 0 + + + + + {Template Linux Container:kernel.maxfiles.last(0)}<1024 + 0 + + Configured max number of opened files is too low on {HOST.NAME} + 0 + + + 0 + 1 + + 0 + 0 + + + + + {Template Linux Container:kernel.maxproc.last(0)}<256 + 0 + + Configured max number of processes is too low on {HOST.NAME} + 0 + + + 0 + 1 + + 0 + 0 + + + + + {Template Linux Container:system.cpu.util[,iowait].avg(5m)}>75 + 0 + + Disk I/O is overloaded on {HOST.NAME} + 0 + + + 0 + 2 + OS spends significant time waiting for I/O (input/output) operations. It could be indicator of performance issues with storage system. + 0 + 0 + + + + + {Template Linux Container:system.uname.diff(0)}>0 + 0 + + Host information was changed on {HOST.NAME} + 0 + + + 0 + 1 + + 0 + 0 + + + + + {Template Linux Container:system.hostname.diff(0)}>0 + 0 + + Hostname was changed on {HOST.NAME} + 0 + + + 0 + 1 + + 0 + 0 + + + + + {Template Linux Container:ct.memory.size[available].last(0)}<20M + 0 + + Lack of available memory on server {HOST.NAME} + 0 + + + 0 + 3 + + 0 + 0 + + + + + {Template Linux Container:ct.swap.size[pused].last(0)}>50 + 0 + + Lack of free swap space on {HOST.NAME} + 0 + + + 1 + 2 + It probably means that the systems requires more physical memory. + 0 + 0 + + + + + {Template Linux Container:ct.cpu.load[percpu,avg1].avg(5m)}>20 + 0 + + Processor load is too high on {HOST.NAME} + 0 + + + 0 + 2 + + 0 + 0 + + + + + {Template Linux Container:proc.num[].avg(5m)}>1000 + 0 + + Too many processes on {HOST.NAME} + 0 + + + 0 + 2 + + 0 + 0 + + + + + {Template Linux Container:proc.num[,,run].avg(5m)}>100 + 0 + + Too many processes running on {HOST.NAME} + 0 + + + 0 + 2 + + 0 + 0 + + + + + {Template Linux Container:system.uptime.change(0)}<0 + 0 + + {HOST.NAME} has just been restarted + 0 + + + 0 + 1 + + 0 + 0 + + + + + + + CPU jumps + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 0 + 0 + 0 + 0 + + + 0 + 0 + 009900 + 0 + 2 + 0 + + Template Linux Container + system.cpu.switches + + + + 1 + 0 + 000099 + 0 + 2 + 0 + + Template Linux Container + system.cpu.intr + + + + + + CPU load + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 1 + 0 + 0 + 0 + + + 0 + 0 + 009900 + 0 + 2 + 0 + + Template Linux Container + ct.cpu.load[percpu,avg1] + + + + 1 + 0 + 000099 + 0 + 2 + 0 + + Template Linux Container + ct.cpu.load[percpu,avg5] + + + + 2 + 0 + 990000 + 0 + 2 + 0 + + Template Linux Container + ct.cpu.load[percpu,avg15] + + + + + + CPU utilization + 900 + 200 + 0.0000 + 100.0000 + 1 + 0 + 1 + 1 + 0 + 0.0000 + 0.0000 + 1 + 1 + 0 + 0 + + + 0 + 1 + FF5555 + 0 + 2 + 0 + + Template Linux Container + system.cpu.util[,steal] + + + + 1 + 1 + 55FF55 + 0 + 2 + 0 + + Template Linux Container + system.cpu.util[,softirq] + + + + 2 + 1 + 009999 + 0 + 2 + 0 + + Template Linux Container + system.cpu.util[,interrupt] + + + + 3 + 1 + 990099 + 0 + 2 + 0 + + Template Linux Container + system.cpu.util[,nice] + + + + 4 + 1 + 999900 + 0 + 2 + 0 + + Template Linux Container + system.cpu.util[,iowait] + + + + 5 + 1 + 990000 + 0 + 2 + 0 + + Template Linux Container + system.cpu.util[,system] + + + + 6 + 1 + 000099 + 0 + 2 + 0 + + Template Linux Container + system.cpu.util[,user] + + + + 7 + 1 + 009900 + 0 + 2 + 0 + + Template Linux Container + system.cpu.util[,idle] + + + + + + Memory usage + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 1 + 2 + 0 + + Template Linux Container + ct.memory.size[total] + + + + 0 + 1 + BB0000 + 0 + 2 + 0 + + Template Linux Container + ct.memory.size[total] + + + + 1 + 1 + 00C800 + 0 + 2 + 0 + + Template Linux Container + ct.memory.size[available] + + + + + + Swap usage + 600 + 340 + 0.0000 + 0.0000 + 0 + 0 + 2 + 1 + 0 + 0.0000 + 0.0000 + 0 + 0 + 0 + 0 + + + 0 + 0 + AA0000 + 0 + 2 + 0 + + Template Linux Container + ct.swap.size[used] + + + + 1 + 0 + 00AA00 + 0 + 2 + 2 + + Template Linux Container + ct.swap.size[total] + + + + + + diff --git a/assets/zabbix/templates/zbx_template_nginx.xml b/assets/zabbix/templates/zbx_template_nginx.xml new file mode 100644 index 0000000..5aae3d2 --- /dev/null +++ b/assets/zabbix/templates/zbx_template_nginx.xml @@ -0,0 +1,560 @@ + + + 3.4 + 2017-12-20T20:10:24Z + + + Templates + + + + + + + + Nginx Connection Status + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 0 + 0 + 0 + 0 + + + 0 + 5 + 00C800 + 0 + 2 + 0 + + Template App Nginx + nginx.active[{HOST.IP},{$NGINX_PORT}] + + + + 1 + 0 + 0000C8 + 0 + 2 + 0 + + Template App Nginx + nginx.reading[{HOST.IP},{$NGINX_PORT}] + + + + 2 + 0 + C80000 + 0 + 2 + 0 + + Template App Nginx + nginx.waiting[{HOST.IP},{$NGINX_PORT}] + + + + 3 + 0 + C800C8 + 0 + 2 + 0 + + Template App Nginx + nginx.writing[{HOST.IP},{$NGINX_PORT}] + + + + + + Nginx Requests Statistics + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 0 + 0 + 0 + 0 + + + 0 + 5 + 00C800 + 0 + 2 + 0 + + Template App Nginx + nginx.handled[{HOST.IP},{$NGINX_PORT}] + + + + 1 + 0 + 0000C8 + 0 + 2 + 0 + + Template App Nginx + nginx.accepted[{HOST.IP},{$NGINX_PORT}] + + + + 2 + 0 + C80000 + 0 + 2 + 0 + + Template App Nginx + nginx.total[{HOST.IP},{$NGINX_PORT}] + + + + + + diff --git a/assets/zabbix/userparamater_nginx.conf b/assets/zabbix/userparamater_nginx.conf new file mode 100644 index 0000000..c7b3843 --- /dev/null +++ b/assets/zabbix/userparamater_nginx.conf @@ -0,0 +1,21 @@ +# in nginx config: +# location /nginx_status { +# # Turn on nginx stats +# stub_status on; +# # I do not need logs for stats +# access_log off; +# # Security: Only allow access from IP # +# allow $1; +# # Send rest of the world to /dev/null # +# deny all; +# } + +UserParameter=nginx.accepted[*],/etc/zabbix/zabbix_agentd.scripts/nginx-stat.py -h $1 -p $2 -a accepted +UserParameter=nginx.active[*],/etc/zabbix/zabbix_agentd.scripts/nginx-stat.py -h $1 -p $2 -a active +UserParameter=nginx.handled[*],/etc/zabbix/zabbix_agentd.scripts/nginx-stat.py -h $1 -p $2 -a handled +UserParameter=nginx.reading[*],/etc/zabbix/zabbix_agentd.scripts/nginx-stat.py -h $1 -p $2 -a reading +UserParameter=nginx.total[*],/etc/zabbix/zabbix_agentd.scripts/nginx-stat.py -h $1 -p $2 -a requests +UserParameter=nginx.waiting[*],/etc/zabbix/zabbix_agentd.scripts/nginx-stat.py -h $1 -p $2 -a waiting +UserParameter=nginx.writing[*],/etc/zabbix/zabbix_agentd.scripts/nginx-stat.py -h $1 -p $2 -a writing + +UserParameter=nginx.version,nginx -v 2>&1 diff --git a/assets/zabbix/userparameter_mysql.conf b/assets/zabbix/userparameter_mysql.conf new file mode 100644 index 0000000..ebd516d --- /dev/null +++ b/assets/zabbix/userparameter_mysql.conf @@ -0,0 +1,18 @@ +# For all the following commands HOME should be set to the directory that has .my.cnf file with password information. + +# Flexible parameter to grab global variables. On the frontend side, use keys like mysql.status[Com_insert]. +# Key syntax is mysql.status[variable]. +UserParameter=mysql.status[*],echo "show global status where Variable_name='$1';" | HOME=/var/lib/zabbix mysql -N | awk '{print $$2}' + +# Flexible parameter to determine database or table size. On the frontend side, use keys like mysql.size[zabbix,history,data]. +# Key syntax is mysql.size[,,]. +# Database may be a database name or "all". Default is "all". +# Table may be a table name or "all". Default is "all". +# Type may be "data", "index", "free" or "both". Both is a sum of data and index. Default is "both". +# Database is mandatory if a table is specified. Type may be specified always. +# Returns value in bytes. +# 'sum' on data_length or index_length alone needed when we are getting this information for whole database instead of a single table +UserParameter=mysql.size[*],bash -c 'echo "select sum($(case "$3" in both|"") echo "data_length+index_length";; data|index) echo "$3_length";; free) echo "data_free";; esac)) from information_schema.tables$([[ "$1" = "all" || ! "$1" ]] || echo " where table_schema=\"$1\"")$([[ "$2" = "all" || ! "$2" ]] || echo "and table_name=\"$2\"");" | HOME=/var/lib/zabbix mysql -N' + +UserParameter=mysql.ping,HOME=/var/lib/zabbix mysqladmin ping | grep -c alive +UserParameter=mysql.version,mysql -V diff --git a/bin/zabbix.sh b/bin/zabbix.sh index 1002fde..46ac130 100755 --- a/bin/zabbix.sh +++ b/bin/zabbix.sh @@ -14,7 +14,17 @@ if [ "$EUID" -ne 0 ]; then exit fi -cd +# get the current position +_cwd="$(pwd)" +# check for assets forlder +_assets="$_cwd/assets" +if [ ! -d "$_assets" ]; then + _assets="$_cwd/../assets" + if [ ! -d "$_assets" ]; then + echo "!! can't find assets directory !!" + exit + fi +fi wget -P /tmp/ http://repo.zabbix.com/zabbix/3.4/debian/pool/main/z/zabbix-release/zabbix-release_3.4-1+stretch_all.deb dpkg -i /tmp/zabbix-release_3.4-1+stretch_all.deb @@ -28,11 +38,63 @@ echo -n "Please provide the zabbix-server's ip : " read _ip echo -n "Please provide the hostname of this agent : " read _host_name +echo -n "Please provide the mysql root password : " +read _root_mysql_passwd -sed -i 's#Server=127.0.0.1#Server=$_ip#g' /etc/zabbix/zabbix-agent.confd -sed -i 's#Hostname=Zabbix server#Hostname=$_host_name#g' +_agent_conf_d="/etc/zabbix/zabbix_agentd.d" # for debian 8 +if [ ! -d "$_agent_conf_d" ]; then + _agent_conf_d="/etc/zabbix/zabbix_agentd.conf.d" # for debian 9 +fi + +# configure zabbix agent +sed -i 's#Server=127.0.0.1#Server=$_ip#g' /etc/zabbix/zabbix_agentd.conf +sed -i 's#ServerActive=127.0.0.1#ServerActive=$_ip#g' /etc/zabbix/zabbix_agentd.conf +sed -i 's#Hostname=Zabbix server#Hostname=$_host_name#g' /etc/zabbix/zabbix_agentd.conf + +# APT +# check for debian security updates +# not working : https://www.osso.nl/blog/zabbix-counting-security-updates +# https://github.com/theranger/zabbix-apt +# enable automatic update of apt +cp "$_assets"/zabbix/misc/02periodic /etc/apt/apt.conf.d/ +cp "$_assets"/zabbix/apt.conf "$_agent_conf_d"/ + +# MYSQL +# https://serverfault.com/questions/737018/zabbix-user-parameter-mysql-status-setting-home +# create zabbix user home +mkdir /var/lib/zabbix +# generate random password for zabbix mysql user +_passwd="$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c12)" +# add mysql credentials to zabbix home +printf "[client]\n +user=zabbix\n +password=$_passwd" > /var/lib/zabbix/.my.cnf +# create zabbix mysql user +mysql -uroot -p"$_root_mysql_passwd" -e "CREATE USER 'zabbix' IDENTIFIED BY '$_passwd';" +mysql -uroot -p"$_root_mysql_passwd" -e "GRANT USAGE ON *.* TO 'zabbix'@'localhost' IDENTIFIED BY '$_passwd';" +# add zabbix-agent parameter +cp "$_assets"/zabbix/userparameter_mysql.conf "$_agent_conf_d"/ + +# NGINX +# https://github.com/sfuerte/zbx-nginx +# nginxconf already included in default.nginxconf asset +sed -i "s#ZABBIX-SERVER-IP#$_ip#g" /etc/nginx/sites-available/default +cp "$_assets"/zabbix/userparameter_nginx.conf "$_agent_conf_d"/ +mkdir /etc/zabbix/zabbix_agentd.scripts +cp "$_assets"/zabbix/nginx-stat.py /etc/zabbix/zabbix_agentd.scripts/ + + +# TODO add modules path to agent ?? + +# allow comm. port with zabbix-server +ufw allow from "$_ip" to any port 10050 +ufw allow from "$_ip" to any port 22 +# ufw allow from "$_ip" to any port 10051 +# iptables -A INPUT -p tcp -m tcp --dport 10050 -j ACCEPT systemctl restart zabbix-agent systemctl enable zabbix-agent -echo -e "\033[92;1mZabbix-agent installed and configured, please add the host in your zabbix-server \033[Om" +echo -e "\033[92;1mZabbix-agent installed and configured, please add the host $_host_name in your zabbix-server \033[Om" +echo -e "\033[92;1mAnd import requested templates in assets/zabbix/templates/ \033[Om" +echo -e "\033[92;1mzabbix user mysql password is $_passwd \033[Om" diff --git a/install-debian-server.sh b/install-debian-server.sh index 050d02e..a06d16e 100755 --- a/install-debian-server.sh +++ b/install-debian-server.sh @@ -72,7 +72,28 @@ else echo -e 'lemp server not installed' fi -. bin/vhost.sh +while [ "$_install_vhost" != "yes" ] && [ "$_install_vhost" != "no" ] +do + echo -n "Should we install a vhost ? [yes|no] " + read _install_vhost +done +if [ "$_install_vhost" = "yes" ]; then + . bin/vhost.sh +else + echo -e 'no vhost installed' +fi + +while [ "$_install_zabbix_agent" != "yes" ] && [ "$_install_zabbix_agent" != "no" ] +do + echo -n "Should we install zabbix-agent ? [yes|no] " + read _install_zabbix_agent +done +if [ "$_install_zabbix_agent" = "yes" ]; then + . bin/zabbix.sh +else + echo -e 'zabbix-agent not installed' +fi + . bin/dotfiles.sh . bin/autoupdate.sh