Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Marcus Klang
Host Monitor
Commits
9ef09759
Commit
9ef09759
authored
Jun 02, 2021
by
Peter Möller
Browse files
Update linux/host-monitor.sh
parents
Changes
1
Hide whitespace changes
Inline
Side-by-side
linux/host-monitor.sh
0 → 100644
View file @
9ef09759
#!/bin/bash
# Collecting host data and sending it to the CS monitor server
# Linux version
# 2021-06-02/PM
MONITOR_RESTAPI_URL
=
https://monitor.cs.lth.se/api/v1
source
/opt/monitoring/host-monitor.template
# 1. Generating data
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# sysinfo
# Operating System (OS='Ubuntu 20.04.1 LTS'):
# Find out distro
# Fist: look at the /etc/*-release files
OS
=
"
$(
less
$(
ls
-1
/etc/mageia-release /etc/centos-release /etc/redhat-release /etc/gentoo-release /etc/fedora-release 2>/dev/null |
head
-1
)
2>/dev/null
)
"
# If no such file, look for /etc/os-release
if
[
-z
"
$OS
"
]
;
then
[[
-f
/etc/os-release
]]
&&
OS
=
"
$(
less /etc/os-release |
grep
PRETTY_NAME |
cut
-d
\"
-f2
)
"
fi
# If no such file, look for /etc/lsb-release
if
[
-z
"
$OS
"
]
;
then
[[
-f
/etc/lsb-release
]]
&&
OS
=
"
$(
less /etc/os-release |
grep
DISTRIB_DESCRIPTION |
cut
-d
\"
-f2
)
"
fi
# If no such file, look for /proc/version
if
[
-z
"
$OS
"
]
;
then
[[
-f
/proc/version
]]
&&
OS
=
"
$(
less /proc/version |
cut
-d
\(
-f1
)
"
fi
# OK, so it an unknown system
if
[
-z
"
$OS
"
]
;
then
OS
=
"Unknown Linux-distro"
fi
##OS="$(lsb_release -ds)"
# Kind of CPU (CPUModel='Intel® Xeon® CPU E5-2680 v4 @ 2.40GHz'):
CPUModel
=
"
$(
egrep
"^model name"
/proc/cpuinfo |
sort
-u
|
cut
-d
:
-f2
|
sed
-e
's/^ //'
-e
's/(R)/®/g'
)
"
# Number of CPU:s (NbrCPUs=2):
NbrCPUs
=
$(
egrep
"^processor"
/proc/cpuinfo |
wc
-l
)
# Size of memory [kB]
#RAM=$(egrep "^MemTotal" /proc/meminfo | awk '{print $2}')
RAM
=
$(
/usr/sbin/dmidecode
-t
17 |
grep
"Size.*MB"
|
awk
'{s+=$2} END {print s * 1024}'
)
# Ex: RAM=4194304
# Kind of memory (ECC='No ECC' or ECC='Multi-bit ECC'):
ECC
=
"
$(
/usr/sbin/dmidecode
-t
memory | egrep
"Error Correction Type"
|
sort
-u
|
cut
-d
:
-f2
|
sed
-e
's/^ //'
-e
's/None/No ECC/'
)
"
# What kind of authentication? Ex: Authentication=Lucat
Authentication
=
"
$(
if
[
-n
"
$(
egrep
-v
"#|^$"
/etc/pam.d/common-account | egrep pam_krb5.so
)
"
-a
-n
"
$(
egrep
"default_realm = UW.LU.SE"
/etc/krb5.conf
)
"
]
;
then
echo
Lucat
;
else
echo
Standalone
;
fi
)
"
AuthStr
=
"
\"
authentication
\"
:
\"
${
Authentication
}
\"
"
# Ex: AuthStr='"authentication": "Lucat"'
# Firewall. Ex: Firewall=ufw
Firewall
=
"
$(
systemctl list-units
--type
=
service
--state
=
active | egrep
-i
"^
\
*(iptables|firewalld|ufw)"
|
awk
'{print $1}'
|
cut
-d
\.
-f1
)
"
FirewWStr
=
"
\"
firewall
\"
:
\"
${
Firewall
}
\"
"
# Ex: FirewWStr='"firewall":"ufw"'
# Disks
Filesystems
=
"
$(
df
-kT
-t
xfs
-t
ext4 | egrep
"
\/
"
|
awk
'{print $1" "$2" "$3" "$7}'
)
"
# Ex: a number of rows with
# Filesystem Type 1K-blocks Mounted on
# /dev/mapper/vg0-ubuntu ext4 13343816 /
LVMDisks
=
"
$(
LANG
=
C lsblk | egrep
-i
lvm |
awk
'{print $4" "$NF}'
| egrep
-vi
swap |
sort
-u
)
"
# Ex:
# LVMDisks='13G /
# 500G /Websites
# 50G /var/log/apache2'
# Flags
# SELinux
SELinux
=
"
$(
if
sestatus &>/dev/null
;
then
sestatus | egrep
"^Current mode:"
|
awk
'{print $NF}'
;
else
echo
"Not present"
;
fi
)
"
# CPU bugs
CPUBugs
=
"
$(
egrep
"^bugs"
/proc/cpuinfo |
cut
-d
:
-f2
|
cut
-c2-
|
uniq
)
"
# Ex: CPUBugs='cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit'
Kernel
=
"
$(
uname
-r
2>/dev/null
)
"
# Ex: Kernel=5.4.0-62-generic
Architecture
=
"
$(
uname
-m
2>/dev/null
)
"
# Ex: Architecture=x86_64
# Are we in a Virtual environment? This one is a bit tricky since there are many ways to cover this.
# Read this for more info: http://unix.stackexchange.com/questions/89714/easy-way-to-determine-virtualization-technology
VMenv
=
"
$(
dmesg 2>/dev/null |
grep
-i
" Hypervisor detected: "
2>/dev/null |
cut
-d
:
-f2
|
sed
's/^ *//'
)
"
# Ex: VMenv='VMware'
if
[
-z
"
${
USER
/root/
}
"
-o
-z
"
${
UID
/0/
}
"
]
;
then
# Get a better VMenv if found
if
[
-n
"
$VMenv
"
]
;
then
VMenv
=
"
$(
/usr/sbin/dmidecode
-s
system-product-name 2>/dev/null
)
"
fi
# Ex: VMenv='VMware Virtual Platform'
# It may still be a VM environment
if
[
-z
"
$VMenv
"
]
;
then
VMenv
=
"
$(
virt-what 2>/dev/null
)
"
# Ex: VMenv='vmware'
fi
if
[
-z
"
$VMenv
"
]
;
then
VMenv
=
"
$(
if
[
-n
"
$(
grep
"^flags.*
\
hypervisor
\
"
/proc/cpuinfo
)
"
]
;
then
echo
"VM environment detected"
;
fi
)
"
# Ex: VMenv='VM environment detected'
fi
fi
# Get more platform data
PlatformManufacturer
=
"
$(
/usr/sbin/dmidecode
-t
2 2>/dev/null | egrep
"^
\s
*Manufacturer:"
|
cut
-d
:
-f2
|
cut
-c2-
)
"
# Ex: PlatformManufacturer=LNVO
PlatformType
=
"
$(
/usr/sbin/dmidecode
-t
2 2>/dev/null | egrep
"^
\s
*Type:"
|
cut
-d
:
-f2
|
cut
-c2-
)
"
# Ex: PlatformType=Motherboard
# Network interfaces
IFs
=
$(
ip a |awk
'/state UP/{print $2}'
|
sed
's/://'
)
# Ex: IFs='ens192
# br-8ebd54cbbafb
# veth079b7c8@if123'
# fail2ban
case
$(
systemctl status fail2ban &>/dev/null
;
echo
$?
)
in
0
)
Fail2Ban
=
"Active"
;;
1
)
Fail2Ban
=
"Generic failure or unspecified error"
;;
2
)
Fail2Ban
=
"Invalid or excess arguments"
;;
3
)
Fail2Ban
=
"Unimplemented"
;;
4
)
Fail2Ban
=
"Not installed"
;;
5
)
Fail2Ban
=
"Not installed"
;;
6
)
Fail2Ban
=
"Not configured"
;;
7
)
Fail2Ban
=
"Not running"
;;
esac
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Security patches
SecurityPatches
=
"
$(
apt-get update &>/dev/null
&&
apt list
--upgradable
2>/dev/null | egrep
"
\-
security"
|
sed
-e
's/\[upgradable from: //'
-e
's/\]//'
|
tr
'[/ ]'
'\t'
)
"
# List of: Package Channel CurrentVer Arch NewVersion
# intel-microcode focal-updates,focal-security,focal-updates,focal-security 3.20210216.0ubuntu0.20.04.1 amd64 3.20201110.0ubuntu0.20.04.2
# libhogweed5 focal-updates,focal-security,focal-updates,focal-security 3.5.1+really3.5.1-2ubuntu0.1 amd64 3.5.1+really3.5.1-2
# libmysqlclient21 focal-updates,focal-security,focal-updates,focal-security 8.0.25-0ubuntu0.20.04.1 amd64 8.0.22-0ubuntu0.20.04.3
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Listening ports
ListeningPorts
=
"
$(
lsof +c 0
-i
4
-i
6
-n
-P
2>/dev/null |
grep
LISTEN |
awk
'{print $1" "$3" "$5" "$8" "$9 }'
|
sed
's/\(.*\):/\1 /'
|
sort
-u
)
"
# List of: Application User IPver Proto Servicerange Port
# apache2 root IPv6 TCP * 88
# apache2 www-data IPv6 TCP * 88
# cupsd root IPv4 TCP 127.0.0.1 631
# cupsd root IPv6 TCP [::1] 631
# dnsmasq nobody IPv4 TCP 127.0.1.1 53
# docker-proxy root IPv6 TCP * 4000
# dsmcad root IPv4 TCP * 1581
# dsmcad root IPv4 TCP * 2123
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Firewall -- No longer used as of 2021-05-28
FWrules
=
"
$(
ufw status verbose 2>/dev/null | egrep
"(ALLOW|DENY) IN"
|
awk
'{print $1}'
|
cut
-d
\/
-f1
| egrep
-vi
"^anywhere|out"
|
tr
','
$'
\n
'
|
sort
-nu
)
"
# Ex:
# FWrules='22
# 161
# 2500:5000
# 5666'
####################################################################################################################################################################
####################################################################################################################################################################
# 2. Generate JSON-parts
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# sysinfo
# Create a string for the CPU Bugs (to make the final assemble shorter)
CPUBugsStr
=
"
$(
if
[
-n
"
$CPUBugs
"
]
;
then
echo
",
\"
cpu-bugs:
${
CPUBugs
// /\
",
\"
cpu-bugs:}
\"
"
; fi)
"
# Assemble the Flags string
Flags="
\
"selinux:
$SELinux
\"
,
\"
kernel:
${
Kernel
}
\"
$CPUBugsStr
,
\"
arch:
${
Architecture
:-
--
}
\"
,
\"
fail2ban:
$Fail2Ban
\"
"
# partitions
OUTPUT=
""
while read -r Filesystem Type Kblocks MountP
do
if [ -n
"
$(
echo
"
$LVMDisks
"
| egrep
"
\s
${
MountP
}
$"
)
"
]; then
LVM=
"LVM"
case
$(
echo
"
$LVMDisks
"
| egrep
"
\s
${
MountP
}
$"
|
awk
'{print $1}'
|
sed
's/[0-9.]*//'
)
in
M) ScaleFactor=1024;;
G) ScaleFactor=1048576;;
T) ScaleFactor=1073741824;;
esac
Kblocks=
$(
echo
"scale=0;
$(
echo
"
$LVMDisks
"
| egrep
"
\s
${
MountP
}
$"
|
awk
'{print $1}'
|
sed
's/[MGT]//'
)
*
$ScaleFactor
"
| bc
-l
)
else
LVM=
""
fi
OUTPUT+=
"{
\"
partition
\"
:
\"
$Filesystem
\"
,
\"
mount-point
\"
:
\"
$MountP
\"
,
\"
type
\"
:
\"
$Type
\"
,
\"
total-kb
\"
:
$Kblocks
,
\"
storage
\"
:
\"
${
LVM
:-
direct
}
\"
},"
done <<<
"
$Filesystems
"
# Assemble the complete string (minus the final comma)
FilesystemStr=
"
\"
partitions
\"
: [
${
OUTPUT
%%,
}
]"
# Network interfaces
OUTPUT=
""
for iname in
$IFs
do
IP4=
$(
ip
-4
-o
a show
${
iname
%%@if[0-9]*
}
|
awk
'{print $4}'
)
IP6=
$(
ip
-6
-o
a show
${
iname
%%@if[0-9]*
}
|
awk
'{print $4}'
)
MAC=
"
$(
ip
link
show dev
${
iname
%%@if[0-9]*
}
|awk
'/link/{print $2}'
)
"
MAC_P=
$(
ethtool
-P
${
iname
%%@if[0-9]*
}
|
awk
'{print $NF}'
)
Speed=
"
$(
ethtool
${
iname
%%@if[0-9]*
}
|
grep
"Speed:"
|
awk
'{print $NF}'
)
"
OUTPUT+=
"{
\"
interface
\"
:
\"
$iname
\"
,
\"
ip4
\"
:
\"
${
IP4
}
\"
,
\"
ip6
\"
:
\"
${
IP6
}
\"
,
\"
mac
\"
:
\"
${
MAC
}
\"
,
\"
mac-p
\"
:
\"
${
MAC_P
}
\"
,
\"
speed
\"
:
\"
${
Speed
}
\"
},"
done
NIStr=
"
\"
network-interfaces
\"
: [
$(
echo
"
${
OUTPUT
}
"
|
sed
's/,$//'
)
]"
# Ex
:
NIStr=
'"network-interfaces": [ { "interface": "ens192", "ip4": "130.235.16.11/23", "ip6": "fe80::250:56ff:feb6:b194/64", "mac": "00:50:56:b6:b1:94", "mac-p": "00:50:56:b6:b1:94", "speed": "10000Mb/s" } ]'
# Platform
if [ -n
"
$VMenv
"
]; then
PlatformStr=
"
\"
platform
\"
: {
\"
virtualized
\"
: true,
\"
name
\"
:
\"
$VMenv
\"
}"
else
PlatformStr=
"
\"
platform
\"
: {
\"
virtualized
\"
: false,
\"
name
\"
:
\"
type:
$PlatformType
\"
}"
fi
# network
AliasName=
",
\"
alias
\"
: [
\"
$DNSAlias
\"
] "
NetworkStr=
"
\"
network
\"
: {
\"
hostname
\"
:
\"
$(
hostname
-f
)
\"
$AliasName
}"
CPUstr=
"
\"
cpu
\"
: {
\"
name
\"
:
\"
${
CPUModel
:-
--
}
\"
,
\"
threads
\"
:
${
NbrCPUs
:-
--
}
}"
RAMStr=
"
\"
memory
\"
: {
\"
total-kb
\"
:
${
RAM
:-
--
}
,
\"
type
\"
:
\"
${
ECC
:-
--
}
\"
}"
SysinfoStr=
"
\"
sysinfo
\"
: {
\"
os
\"
:
\"
${
OS
:-
--
}
\"
,
\"
authentication
\"
:
\"
${
Authentication
}
\"
,
\"
firewall
\"
:
\"
${
Firewall
}
\"
,
\"
flags
\"
: [
${
Flags
}
],
$CPUstr
,
$RAMStr
,
$FilesystemStr
,
$NIStr
,
$PlatformStr
,
$NetworkStr
}"
# Ex
:
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# listening ports
if [ -n
"
$ListeningPorts
"
]; then
OUTPUT=
""
while read -r line
do
read Application User IPver Proto Binding Port <<<
"
$line
"
# Determine if there
's some form of firewall rule that covers $Port:
FWrule="null"
if [ -n "$Firewall" ]; then
if [ -n "$(echo "$FWrules" | egrep "$Port")" ]; then
FWrule="true"
else
FWrule="false"
fi
fi
#OUTPUT+="{ \"binding\": \"${Binding:--}\", \"port\": ${Port:--}, \"process-owner\": \"${Application:--}\", \"process-user\": \"${User:--}\", \"IPver\": \"${IPver:--}\", \"protocol\": \"${Proto:--}\" },"
OUTPUT+="{ \"binding\": \"${Binding:--}\", \"port\": ${Port:--}, \"process-owner\": \"${Application:--}\", \"process-user\": \"${User:--}\", \"protocol\": \"${Proto:--}\", \"firewall-rule\": $FWrule },"
done <<< "$ListeningPorts"
# Assemble the complete string (minus the final comma)
ListenStr=", \"listen-ports\": [ ${OUTPUT%%,} ]"
else
ListenStr=""
fi
# Ex:
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# security patches
if [ -n "$SecurityPatches" ]; then
OUTPUT=""
while read -r Package Sources InstalledVer Arch NewVer
do
Source="$(echo -e ${Sources//,/'
\n
'} | sort -u | sed -z '
s
/\n/,/g;s/,
$/
\n/
')"
STR="\"${Sources//,/\",\"}\""
SourceArr="$(echo -e ${STR//,/'
\n
'} | sort -u | sed -z '
s
/\n/,/g;s/,
$/
\n/
')"
OUTPUT+="{ \"installed-version\": \"$InstalledVer\", \"new-version\": \"$NewVer\", \"package\": \"$Package\", \"sources\": [ $SourceArr ] },"
done <<< "$SecurityPatches"
# Assemble the complete string (minus the final comma)
SecurityPatchStr=", \"security-patches\": [ ${OUTPUT%%,} ]"
else
SecurityPatchStr=""
fi
# Ex:
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# firewall rules
#OUTPUT=""
#if [ -n "$FWrules" ]; then
#while read -r Rule Binding
#do
#if echo "$Rule" | egrep ":" &>/dev/null ; then
#OUTPUT+="{ \"binding\": \"${Binding:-*}\", \"port\": [$(echo $Rule | cut -d: -f1), $(echo $Rule | cut -d: -f2)] },"
#else
#OUTPUT+="{ \"binding\": \"${Binding:-*}\", \"port\": $Rule },"
#fi
#done <<< "$FWrules"
#FWrulesStr=", \"firewall-rules\": [ $(echo "$OUTPUT" | sed '
s
/,
$/
/
') ]"
#else
#FWrulesStr=""
#fi
# Ex:
# FWrulesStr='
,
"firewall-rules"
:
[ {
"binding"
:
"*"
,
"port"
:
22
}
,{ "
binding
": "
*
", "
port
": 161 },{ "
binding
": "
*
", "
port
": [2500, 5000] },{ "
binding
": "
*
", "
port
": 5666 } ]'
# 3. Build observation string and check for errors
OBSERVATIONS="
{
${
SysinfoStr
//\
"--
\"
/null}
${
ListenStr
//\
"--
\"
/null}
${
SecurityPatchStr
}
}"
# 4. Upload results
curl --silent -X POST
"
$MONITOR_RESTAPI_URL
/hosts/monitor?token=
$SOURCE_TOKEN
"
\
-H
"accept: application/json"
\
-H
"Content-Type: application/json"
\
-d
"
$OBSERVATIONS
"
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment