Compare commits

...

134 Commits

Author SHA1 Message Date
b0d1ae0a3e . 2025-07-10 10:13:23 -05:00
a2ff47e5d2 . 2025-07-10 10:11:50 -05:00
b5d09e64f0 we want a bit of observability here.. 2025-07-10 10:09:58 -05:00
edc3ca26ad . 2025-07-10 10:06:52 -05:00
a272764d66 . 2025-07-10 10:05:51 -05:00
97b67ea1fc . 2025-07-10 10:04:23 -05:00
a86b2ea09b and agian... sigh 2025-07-10 10:03:12 -05:00
54cfcf669f fixed agian 2025-07-10 10:01:30 -05:00
28c18a2bda . 2025-07-10 10:00:25 -05:00
168456ee7f fixed 2025-07-10 09:59:35 -05:00
d6364eac7a typo 2025-07-10 09:58:28 -05:00
d2100d1146 dont' need vm management in vms.. 2025-07-10 09:56:18 -05:00
5c20f167b2 adding cockpit 2025-07-10 09:48:01 -05:00
3b705a23ba don't install rsyslog on librenms server
fixed some formatting
2025-07-09 11:24:20 -05:00
319cd61ad4 all the instrumentation/diagnostics... 2025-07-07 12:05:26 -05:00
1e458f0fae being able to use growpart is quite nice 2025-07-05 20:49:40 -05:00
0bf88e3d8c More ubuntu fixes 2025-07-05 17:48:41 -05:00
bf4efcdf5a oops 2025-07-02 22:23:16 -05:00
f9f556111b lldpd enablement for librenms mapping goodness 2025-07-02 22:12:01 -05:00
7e5302b5e6 This allows for chattr +i of snmpd.conf on hosts we don't want to put the standard snmpd.conf on 2025-07-02 21:20:47 -05:00
885487fce5 so close... 2025-07-02 21:12:37 -05:00
ba8efdfa0b more ntp fixes 2025-07-02 21:08:39 -05:00
1d14c9c9a2 netboot is the frontend to take the hit, it forwards to pfvsvrpi. 2025-07-02 20:19:19 -05:00
d3e4fb5014 . 2025-07-02 20:18:28 -05:00
001faf76a3 . 2025-07-02 20:08:07 -05:00
52e8ecf779 we don't want to update the ntp config on our stratum1 ntp server 2025-07-02 20:07:36 -05:00
24946292e7 more ntp tweaks 2025-07-02 20:00:10 -05:00
cb10cdf1cc ntp fix now 2025-07-02 19:44:15 -05:00
f2dc2ce29e automation. no prompts! 2025-07-02 18:52:43 -05:00
d1ef7118d5 debian fails... let's see if this fixes it. 2025-07-02 18:47:21 -05:00
160d1b26cc fixed in ubuntu. will test on debian next. 2025-07-02 18:44:46 -05:00
ce5bb0be6f . 2025-07-02 18:43:18 -05:00
ce1bf7d220 i think this is right... 2025-07-02 18:41:58 -05:00
0175a00458 got to handle the other condition... 2025-07-02 18:25:31 -05:00
0f52d19229 remove debugging 2025-07-02 18:21:56 -05:00
0937036155 had inverse logic. fixed. still shouldn't have caused script to error though... hmm... 2025-07-02 18:15:03 -05:00
02a874f713 . 2025-07-02 18:10:47 -05:00
259a4f07b7 got further . hmm... 2025-07-02 18:09:06 -05:00
f06d8b1fe5 ok. i think this is the last of the regressions. 2025-07-02 18:06:26 -05:00
d76613c0dc . 2025-07-02 18:00:01 -05:00
5deaecd79f . 2025-07-02 17:57:44 -05:00
c58c3f116e . 2025-07-02 17:55:56 -05:00
e4e1c66111 . 2025-07-02 17:52:14 -05:00
d60c03b116 some more resillience 2025-07-02 17:45:56 -05:00
6cdc7bbba7 this code is going to be quite resillient when done.. 2025-07-02 17:43:17 -05:00
ba384498c0 . 2025-07-02 17:41:28 -05:00
8669b64adc i think this should fix ntp/smtp based on my testing. now to e2e test. 2025-07-02 17:40:01 -05:00
13e2678be4 fix NTP graph. by fixing NTP install/config. 2025-07-02 17:16:54 -05:00
1e3c7a97af . 2025-07-02 17:11:06 -05:00
b7c329ddb8 . 2025-07-02 17:09:51 -05:00
3207f1a870 . 2025-07-02 17:03:46 -05:00
0041e95d59 . 2025-07-02 17:02:29 -05:00
c476f84943 . 2025-07-02 16:59:50 -05:00
8c38bcc57c . 2025-07-02 16:54:05 -05:00
7431c1eb4e . 2025-07-02 16:52:35 -05:00
38b779f054 OAM final push. graph all the things! 2025-07-02 16:50:45 -05:00
197d8e2d27 ubuntu bug workaround 2025-07-02 12:23:31 -05:00
0ee847f556 . 2025-07-02 08:17:56 -05:00
7457db098f . 2025-07-02 08:15:55 -05:00
109acf07be . 2025-07-02 08:14:06 -05:00
7ad5a2a8e7 . 2025-07-02 08:12:57 -05:00
86cded93c5 . 2025-07-02 08:11:26 -05:00
ce45ec1684 . 2025-07-02 08:08:16 -05:00
15074a99f4 . 2025-07-02 08:07:45 -05:00
982389fb63 . 2025-07-02 07:56:53 -05:00
7b3549c617 . 2025-07-02 07:55:58 -05:00
a9318aee60 . 2025-07-02 07:55:05 -05:00
ede6aa0562 no more curl 2025-07-02 07:54:13 -05:00
445cbbefde time... 2025-07-02 07:52:08 -05:00
89ac84c4e1 final bits of security hardening as i pivot back to finishing monitoring/alerting OAM bits. next week will be all the security. 2025-07-02 07:46:55 -05:00
5eb2f6b3d5 path issues again. 2025-07-02 07:43:59 -05:00
adc57c1e37 debian netinst is super minimal. lets pull pre-requistes. 2025-07-01 21:05:00 -05:00
29dca6241e extreme path defense 2025-07-01 20:44:22 -05:00
a38eac2e77 more path fixes 2025-07-01 20:09:49 -05:00
0016e1aaeb path issues 2025-07-01 20:06:47 -05:00
80dd021217 found a bug 2025-07-01 20:00:53 -05:00
4e3368156c so close now 2025-06-30 14:45:10 -05:00
46020fecf5 weird one... 2025-06-30 14:41:58 -05:00
e3683db3cf . 2025-06-30 14:38:32 -05:00
c77d932dd2 moving along nicely... 2025-06-30 14:37:37 -05:00
ffdef9500c . 2025-06-30 14:35:48 -05:00
363c845ead almost... 2025-06-30 14:33:24 -05:00
df7f369f8c I think this is it... 2025-06-30 14:30:49 -05:00
63536f2684 . 2025-06-30 14:29:22 -05:00
063cfc2262 . 2025-06-30 14:28:58 -05:00
1887920f52 . 2025-06-30 14:27:56 -05:00
c1791eaa43 paths.... 2025-06-30 14:25:13 -05:00
94eed1ab9d lets see what breaks... 2025-06-30 14:22:43 -05:00
55178257ef OAM. librenms agent stuff. 2025-06-30 13:53:41 -05:00
486a150e5e oops 2025-06-30 13:41:03 -05:00
8c68a975e0 forgot to pretty print that... 2025-06-30 13:40:22 -05:00
066708f101 . 2025-06-30 13:39:09 -05:00
9be83022e6 . 2025-06-30 13:38:52 -05:00
66976c2ed0 / 2025-06-30 13:38:00 -05:00
03abf42065 . 2025-06-30 13:37:22 -05:00
6df6aba2dd . 2025-06-30 13:34:15 -05:00
d80dd973e4 . 2025-06-30 13:33:07 -05:00
fe89e56e4a . 2025-06-30 13:31:53 -05:00
0773dcb372 . 2025-06-30 13:30:35 -05:00
6e6a57f61b D.R.Y. 2025-06-30 13:28:13 -05:00
ccb24fe403 . 2025-06-30 13:25:54 -05:00
c75d0e39a6 few more tweaks... 2025-06-30 13:24:16 -05:00
f3070de151 about to test this on rr-middleware... 2025-06-30 13:23:24 -05:00
d82c8733fa re-factoring into my shell script framework.
shifting away from invoking via curl and using a downloaded zip file or git clone.
2025-06-30 13:07:25 -05:00
d64d75cb3b and it all works now 2025-06-30 12:31:30 -05:00
f0654723e5 curl... 2025-06-30 12:30:12 -05:00
fd9c50d151 . 2025-06-30 12:28:45 -05:00
4375b82f55 . 2025-06-30 12:26:32 -05:00
8d16f8e8f7 . 2025-06-30 12:23:52 -05:00
6d5732964c . 2025-06-30 12:22:32 -05:00
10ce9ca724 . 2025-06-30 12:20:44 -05:00
a277a36b39 start/stop timestamps 2025-06-30 12:19:20 -05:00
87b31b845d log file testing.. 2025-06-30 12:18:15 -05:00
a8a07b7c5d pretty printing to shell. log support coming next push. 2025-06-30 11:44:19 -05:00
f0e8482e71 all the pretty... 2025-06-30 11:39:00 -05:00
17924e8f88 . 2025-06-30 11:36:00 -05:00
a458c39ddc test 2025-06-30 11:34:40 -05:00
7e4aa53c33 now with christmas... 2025-06-30 11:33:06 -05:00
0c75da8b08 oopsie 2025-06-30 11:28:09 -05:00
db6643c825 adding message formatting 2025-06-30 11:18:12 -05:00
7a5b90ae84 lots of things 2025-06-29 19:54:10 -05:00
23cba4713b all the bug squashing and some sec ops 2025-06-27 10:16:36 -05:00
dc40896af0 looking good now after dos2unix 2025-06-26 16:54:40 -05:00
396891af1c here goes a test... 2025-06-26 16:41:42 -05:00
89814e2113 now for the real deal 2025-06-26 16:35:23 -05:00
5549409dcc OAM / security hardending is my entire next week. laying the groundwork. 2025-06-26 14:10:53 -05:00
8c14f7823b . 2025-06-26 13:58:23 -05:00
012fcb1698 all done with this todo now. finally. 2025-06-26 13:30:45 -05:00
93dcd9fc92 same 2025-06-26 13:26:57 -05:00
ef50e10cba squash squash 2025-06-26 13:24:19 -05:00
eeea9a98de bit more functionality 2025-06-26 13:23:13 -05:00
a5f0cba15c more of same 2025-06-26 13:22:30 -05:00
e9874c75a5 more end to end testing across all platofms. few more bugs squahsed. 2025-06-26 13:10:43 -05:00
fe830a1ad9 end to end testing on all platfoirms, finding some issues. fixing. 2025-06-26 12:48:06 -05:00
92 changed files with 6392 additions and 1068 deletions

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"debug.javascript.defaultRuntimeExecutable": {
"pwa-node": "/home/localuser/.local/share/mise/shims/node"
},
"python.defaultInterpreterPath": "/home/localuser/.local/share/mise/installs/python/3.11.13/bin/python"
}

Binary file not shown.

View File

@@ -1 +0,0 @@
Debian-snmp ALL = NOPASSWD: /bin/cat

View File

@@ -0,0 +1,3 @@
#Global Variables used by the framework
export ProjectIncludes="1"

View File

@@ -0,0 +1,19 @@
#Place (primary/unique) key as very first argument on each record below
#Value Fields are (in order), (reference KEY_(VARIABLE) names in the code):
#1)valuex (description)
#2)valuey (description)
#3)valuez (description)
#An example:
#unique key of serverfqdn
#key of: subnet , value of: 10.10.10.0/24
#key of: gateway, value of: 10.10.10.1
#serverfqdn,10.10.10.0/24,10.10.10.1
#Place your records below:
#primary/uniquekey,#value
primarykey1,valuex,valuey,valuez
primarykey2,valuex,valuey,valuez

View File

@@ -0,0 +1,33 @@
function DebugMe() {
[[ $script_debug = 1 ]] && "$@" || :
#to turn debugging on, set script_debug=1
#to turn debugging off, set script_debug=0
# be sure to append || : or || true here or use return 0, since the return code
# of this function should always be 0 to not influence anything else with an unwanted
# "false" return code (for example the script's exit code if this function is used
# as the very last command in the script)
#This function does nothing when script_debug is unset or empty, but it executes the
#given parameters as commands when script_debug is set. Use it like this:
#debugme logger "Sorting the database"
#database_sort
#debugme logger "Finished sorting the database, exit code $?"
# * print commands to be executed to stderr as if they were read from input
# (script file or keyboard)
# * print everything before any ( substitution and expansion, …) is applied
set -v
# * print everything as if it were executed, after substitution and expansion is applied
# * indicate the depth-level of the subshell (by default by prefixing a + (plus) sign to
# the displayed command)
# * indicate the recognized words after word splitting by marking them like 'x y'
# * in shell version 4.1, this debug output can be printed to a configurable file
#descriptor, rather than sdtout by setting the BASH_XTRACEFD variable.
set -x
}

View File

@@ -0,0 +1,55 @@
#!/bin/bash
# Standard strict mode and error handling/tracing boilderplate..
# This is a function I include and execute in every shell script that I write.
# It sets up a bunch of error handling odds and ends
# Bits and pieces Sourced from (as best I recall):
# * https://news.ycombinator.com/item?id=24727495
# * many other hacker news / slashdot etc posts over the years
# * https://www.tothenew.com/blog/foolproof-your-bash-script-some-best-practices/
# * https://translucentcomputing.com/2020/05/unofficial-bash-strict-mode-errexit/
# * http://redsymbol.net/articles/unofficial-bash-strict-mode/
# * the school of hard knocks... (aka my code failures...)
#Here's the beef (as the commercial says..)
export PS4='(${BASH_SOURCE}:${LINENO}): - [${SHLVL},${BASH_SUBSHELL},$?] $ '
function error_out()
{
print_error "$1"
print_error "Bailing out. See above for reason...."
exit 1
}
function handle_failure() {
local lineno=$1
local fn=$2
local exitstatus=$3
local msg=$4
local lineno_fns=${0% 0}
if [[ "$lineno_fns" != "-1" ]] ; then
lineno="${lineno} ${lineno_fns}"
fi
echo "${BASH_SOURCE[0]}: Function: ${fn} Line Number : [${lineno}] Failed with status ${exitstatus}: $msg"
}
trap 'handle_failure "${BASH_LINENO[*]}" "$LINENO" "${FUNCNAME[*]:-script}" "$?" "$BASH_COMMAND"' ERR
#use errexit (a.k.a. set -e) to make your script exit when a command fails.
#add || true to commands that you allow to fail.
set -o errexit
# Use set -o nounset (a.k.a. set -u) to exit when your script tries to use undeclared
# variables.
set -o nounset
#Use set -o pipefail in scripts to catch (for example) mysqldump fails
#in e.g. mysqldump |gzip.
#The exit status of the last command that threw a non-zero exit code is returned
set -o pipefail
#Function tracing...
set -o functrace

View File

@@ -0,0 +1,13 @@
#!/bin/bash
function LocalHelp()
{
echo "$0 is <description here>"
echo "$0 takes <num> arguments: "
echo "1) <stuff>"
echo "2) <other stuff>"
echo "<additional info on arguments...>:"
echo "<put>"
echo "<stuff>"
echo "<here>"
}

5
Framework-Includes/Logging.sh Executable file
View File

@@ -0,0 +1,5 @@
export CURRENT_TIMESTAMP
CURRENT_TIMESTAMP="$(date +%A-%Y-%m-%d-%T)"
export LOGFILENAME
LOGFILENAME="${PROJECT_ROOT_PATH}/logs/$0.${CURRENT_TIMESTAMP}.$$"

View File

@@ -0,0 +1,15 @@
#!/bin/bash
function LookupKV()
{
echo "KV lookup..."
#Arguments:
#$1 <path to key/value table>
#$2 unique record identifier
#Returns:
#Variable/array containing all the values in the record
}

View File

@@ -0,0 +1,19 @@
#!/bin/bash
function PreflightCheck()
{
export curr_user="$USER"
export user_check
user_check="$(echo "$curr_user" | grep -c root)"
if [ $user_check -ne 1 ]; then
print_error "Must run as root."
error_out
fi
echo "All checks passed...."
}

View File

@@ -0,0 +1,20 @@
function print_info()
{
GREEN='\033[0;32m'
NC='\033[0m'
tput bold
echo -e "$GREEN $1${NC}"
echo -e "$GREEN $1${NC}" >> "$LOGFILENAME"
tput sgr0
}
function print_error()
{
RED='\033[0;31m'
NC='\033[0m'
tput bold
echo -e "$RED $1${NC}"
echo -e "$RED $1${NC}" >> "$LOGFILENAME"
echo "$1"
tput sgr0
}

View File

@@ -1,15 +0,0 @@
#!/bin/bash
#lynis
# Sourced from
# https://cisofy.com/documentation/lynis/
# https://jbcsec.com/configure-linux-ssh/
# https://opensource.com/article/20/5/linux-security-lynis
# openvas
# Sourced from
# https://forum.greenbone.net/t/ssh-authentication/13536

View File

@@ -1,8 +0,0 @@
#!/bin/bash
# Sourced from
# https://complianceascode.readthedocs.io/en/latest/manual/developer/01_introduction.html
# https://github.com/ComplianceAsCode/content
# https://github.com/ComplianceAsCode

View File

@@ -1,9 +0,0 @@
#!/bin/bash
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP
ip6tables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
ip6tables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP
service netfilter-persistent save

View File

@@ -1,10 +0,0 @@
#!/bin/bash
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import && chmod 644 /usr/share/keyrings/wazuh.gpg
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" | tee -a /etc/apt/sources.list.d/wazuh.list
apt-get update
WAZUH_MANAGER="tsys-nsm.knel.net" apt-get install wazuh-agent
systemctl daemon-reload
systemctl enable wazuh-agent
systemctl start wazuh-agent
echo "wazuh-agent hold" | dpkg --set-selections

View File

@@ -0,0 +1,3 @@
export DL_ROOT
DL_ROOT="https://dl.knownelement.com/KNEL/FetchApply/"

View File

@@ -0,0 +1,13 @@
function pi-detect()
{
print_info Now running "$FUNCNAME"....
if [ -f /sys/firmware/devicetree/base/model ] ; then
export IS_RASPI="1"
fi
if [ ! -f /sys/firmware/devicetree/base/model ] ; then
export IS_RASPI="0"
fi
print_info Completed running "$FUNCNAME"
}

View File

@@ -0,0 +1,9 @@
[Unit]
Description=Check_MK LibreNMS Agent Socket
[Socket]
ListenStream=6556
Accept=yes
[Install]
WantedBy=sockets.target

View File

@@ -0,0 +1,7 @@
[Unit]
Description=Check_MK LibreNMS Agent Service
After=network.target
[Service]
ExecStart=/usr/bin/check_mk_agent
StandardOutput=socket

View File

@@ -0,0 +1,659 @@
#!/bin/bash
# +------------------------------------------------------------------+
# | ____ _ _ __ __ _ __ |
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
# | | |___| | | | __/ (__| < | | | | . \ |
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
# | |
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation in version 2. check_mk is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
# ails. You should have received a copy of the GNU General Public
# License along with GNU Make; see the file COPYING. If not, write
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA.
# Remove locale settings to eliminate localized outputs where possible
export LC_ALL=C
unset LANG
export MK_LIBDIR="/usr/lib/check_mk_agent"
export MK_CONFDIR="/etc/check_mk"
export MK_VARDIR="/var/lib/check_mk_agent"
# Provide information about the remote host. That helps when data
# is being sent only once to each remote host.
if [ "$REMOTE_HOST" ] ; then
export REMOTE=$REMOTE_HOST
elif [ "$SSH_CLIENT" ] ; then
export REMOTE=${SSH_CLIENT%% *}
fi
# Make sure, locally installed binaries are found
PATH=$PATH:/usr/local/bin
# All executables in PLUGINSDIR will simply be executed and their
# ouput appended to the output of the agent. Plugins define their own
# sections and must output headers with '<<<' and '>>>'
PLUGINSDIR=$MK_LIBDIR/plugins
# All executables in LOCALDIR will by executabled and their
# output inserted into the section <<<local>>>. Please
# refer to online documentation for details about local checks.
LOCALDIR=$MK_LIBDIR/local
# All files in SPOOLDIR will simply appended to the agent
# output if they are not outdated (see below)
SPOOLDIR=$MK_VARDIR/spool
# close standard input (for security reasons) and stderr
if [ "$1" = -d ]
then
set -xv
else
exec </dev/null 2>/dev/null
fi
# Runs a command asynchronous by use of a cache file
function run_cached () {
local section=
if [ "$1" = -s ] ; then local section="echo '<<<$2>>>' ; " ; shift ; fi
local NAME=$1
local MAXAGE=$2
shift 2
local CMDLINE="$section$@"
if [ ! -d $MK_VARDIR/cache ]; then mkdir -p $MK_VARDIR/cache ; fi
CACHEFILE="$MK_VARDIR/cache/$NAME.cache"
# Check if the creation of the cache takes suspiciously long and return
# nothing if the age (access time) of $CACHEFILE.new is twice the MAXAGE
local NOW=$(date +%s)
if [ -e "$CACHEFILE.new" ] ; then
local CF_ATIME=$(stat -c %X "$CACHEFILE.new")
if [ $((NOW - CF_ATIME)) -ge $((MAXAGE * 2)) ] ; then
# Kill the process still accessing that file in case
# it is still running. This avoids overlapping processes!
fuser -k -9 "$CACHEFILE.new" >/dev/null 2>&1
rm -f "$CACHEFILE.new"
return
fi
fi
# Check if cache file exists and is recent enough
if [ -s "$CACHEFILE" ] ; then
local MTIME=$(stat -c %Y "$CACHEFILE")
if [ $((NOW - MTIME)) -le $MAXAGE ] ; then local USE_CACHEFILE=1 ; fi
# Output the file in any case, even if it is
# outdated. The new file will not yet be available
cat "$CACHEFILE"
fi
# Cache file outdated and new job not yet running? Start it
if [ -z "$USE_CACHEFILE" -a ! -e "$CACHEFILE.new" ] ; then
echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; $CMDLINE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | nohup bash >/dev/null 2>&1 &
fi
}
# Make run_cached available for subshells (plugins, local checks, etc.)
export -f run_cached
echo '<<<check_mk>>>'
echo Version: 1.2.6b5
echo AgentOS: linux
echo AgentDirectory: $MK_CONFDIR
echo DataDirectory: $MK_VARDIR
echo SpoolDirectory: $SPOOLDIR
echo PluginsDirectory: $PLUGINSDIR
echo LocalDirectory: $LOCALDIR
# If we are called via xinetd, try to find only_from configuration
if [ -n "$REMOTE_HOST" ]
then
echo -n 'OnlyFrom: '
echo $(sed -n '/^service[[:space:]]*check_mk/,/}/s/^[[:space:]]*only_from[[:space:]]*=[[:space:]]*\(.*\)/\1/p' /etc/xinetd.d/* | head -n1)
fi
# Print out Partitions / Filesystems. (-P gives non-wrapped POSIXed output)
# Heads up: NFS-mounts are generally supressed to avoid agent hangs.
# If hard NFS mounts are configured or you have too large nfs retry/timeout
# settings, accessing those mounts from the agent would leave you with
# thousands of agent processes and, ultimately, a dead monitored system.
# These should generally be monitored on the NFS server, not on the clients.
echo '<<<df>>>'
# The exclusion list is getting a bit of a problem. -l should hide any remote FS but seems
# to be all but working.
excludefs="-x smbfs -x cifs -x iso9660 -x udf -x nfsv4 -x nfs -x mvfs -x zfs"
df -PTlk $excludefs | sed 1d
# df inodes information
echo '<<<df>>>'
echo '[df_inodes_start]'
df -PTli $excludefs | sed 1d
echo '[df_inodes_end]'
# Filesystem usage for ZFS
if type zfs > /dev/null 2>&1 ; then
echo '<<<zfsget>>>'
zfs get -Hp name,quota,used,avail,mountpoint,type -t filesystem,volume || \
zfs get -Hp name,quota,used,avail,mountpoint,type
echo '[df]'
df -PTlk -t zfs | sed 1d
fi
# Check NFS mounts by accessing them with stat -f (System
# call statfs()). If this lasts more then 2 seconds we
# consider it as hanging. We need waitmax.
if type waitmax >/dev/null
then
STAT_VERSION=$(stat --version | head -1 | cut -d" " -f4)
STAT_BROKE="5.3.0"
echo '<<<nfsmounts>>>'
sed -n '/ nfs4\? /s/[^ ]* \([^ ]*\) .*/\1/p' < /proc/mounts |
sed 's/\\040/ /g' |
while read MP
do
if [ $STAT_VERSION != $STAT_BROKE ]; then
waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" || \
echo "$MP hanging 0 0 0 0"
else
waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" && \
printf '\n'|| echo "$MP hanging 0 0 0 0"
fi
done
echo '<<<cifsmounts>>>'
sed -n '/ cifs\? /s/[^ ]* \([^ ]*\) .*/\1/p' < /proc/mounts |
sed 's/\\040/ /g' |
while read MP
do
if [ $STAT_VERSION != $STAT_BROKE ]; then
waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" || \
echo "$MP hanging 0 0 0 0"
else
waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" && \
printf '\n'|| echo "$MP hanging 0 0 0 0"
fi
done
fi
# Check mount options. Filesystems may switch to 'ro' in case
# of a read error.
echo '<<<mounts>>>'
grep ^/dev < /proc/mounts
# processes including username, without kernel processes
echo '<<<ps>>>'
ps ax -o user,vsz,rss,cputime,pid,command --columns 10000 | sed -e 1d -e 's/ *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) */(\1,\2,\3,\4,\5) /'
# Memory usage
echo '<<<mem>>>'
egrep -v '^Swap:|^Mem:|total:' < /proc/meminfo
# Load and number of processes
echo '<<<cpu>>>'
echo "$(cat /proc/loadavg) $(grep -E '^CPU|^processor' < /proc/cpuinfo | wc -l)"
# Uptime
echo '<<<uptime>>>'
cat /proc/uptime
# New variant: Information about speed and state in one section
echo '<<<lnx_if:sep(58)>>>'
sed 1,2d /proc/net/dev
if type ethtool > /dev/null
then
for eth in $(sed -e 1,2d < /proc/net/dev | cut -d':' -f1 | sort)
do
echo "[$eth]"
ethtool $eth | egrep '(Speed|Duplex|Link detected|Auto-negotiation):'
echo -en "\tAddress: " ; cat /sys/class/net/$eth/address ; echo
done
fi
# Current state of bonding interfaces
if [ -e /proc/net/bonding ] ; then
echo '<<<lnx_bonding:sep(58)>>>'
pushd /proc/net/bonding > /dev/null ; head -v -n 1000 * ; popd
fi
# Same for Open vSwitch bonding
if type ovs-appctl > /dev/null ; then
echo '<<<ovs_bonding:sep(58)>>>'
for bond in $(ovs-appctl bond/list | sed -e 1d | cut -f2) ; do
echo "[$bond]"
ovs-appctl bond/show $bond
done
fi
# Number of TCP connections in the various states
echo '<<<tcp_conn_stats>>>'
# waitmax 10 netstat -nt | awk ' /^tcp/ { c[$6]++; } END { for (x in c) { print x, c[x]; } }'
# New implementation: netstat is very slow for large TCP tables
cat /proc/net/tcp /proc/net/tcp6 2>/dev/null | awk ' /:/ { c[$4]++; } END { for (x in c) { print x, c[x]; } }'
# Linux Multipathing
if type multipath >/dev/null ; then
echo '<<<multipath>>>'
multipath -l
fi
# Performancecounter Platten
echo '<<<diskstat>>>'
date +%s
egrep ' (x?[shv]d[a-z]*|cciss/c[0-9]+d[0-9]+|emcpower[a-z]+|dm-[0-9]+|VxVM.*|mmcblk.*) ' < /proc/diskstats
if type dmsetup >/dev/null ; then
echo '[dmsetup_info]'
dmsetup info -c --noheadings --separator ' ' -o name,devno,vg_name,lv_name
fi
if [ -d /dev/vx/dsk ] ; then
echo '[vx_dsk]'
stat -c "%t %T %n" /dev/vx/dsk/*/*
fi
# Performancecounter Kernel
echo '<<<kernel>>>'
date +%s
cat /proc/vmstat /proc/stat
# Hardware sensors via IPMI (need ipmitool)
if type ipmitool > /dev/null
then
run_cached -s ipmi 300 "ipmitool sensor list | grep -v 'command failed' | sed -e 's/ *| */|/g' -e 's/ /_/g' -e 's/_*"'$'"//' -e 's/|/ /g' | egrep -v '^[^ ]+ na ' | grep -v ' discrete '"
fi
# IPMI data via ipmi-sensors (of freeipmi). Please make sure, that if you
# have installed freeipmi that IPMI is really support by your hardware.
if type ipmi-sensors >/dev/null
then
echo '<<<ipmi_sensors>>>'
# Newer ipmi-sensors version have new output format; Legacy format can be used
if ipmi-sensors --help | grep -q legacy-output; then
IPMI_FORMAT="--legacy-output"
else
IPMI_FORMAT=""
fi
# At least with ipmi-sensoirs 0.7.16 this group is Power_Unit instead of "Power Unit"
run_cached -s ipmi_sensors 300 "for class in Temperature Power_Unit Fan
do
ipmi-sensors $IPMI_FORMAT --sdr-cache-directory /var/cache -g "$class" | sed -e 's/ /_/g' -e 's/:_\?/ /g' -e 's@ \([^(]*\)_(\([^)]*\))@ \2_\1@'
# In case of a timeout immediately leave loop.
if [ $? = 255 ] ; then break ; fi
done"
fi
# RAID status of Linux software RAID
echo '<<<md>>>'
cat /proc/mdstat
# RAID status of Linux RAID via device mapper
if type dmraid >/dev/null && DMSTATUS=$(dmraid -r)
then
echo '<<<dmraid>>>'
# Output name and status
dmraid -s | grep -e ^name -e ^status
# Output disk names of the RAID disks
DISKS=$(echo "$DMSTATUS" | cut -f1 -d\:)
for disk in $DISKS ; do
device=$(cat /sys/block/$(basename $disk)/device/model )
status=$(echo "$DMSTATUS" | grep ^${disk})
echo "$status Model: $device"
done
fi
# RAID status of LSI controllers via cfggen
if type cfggen > /dev/null ; then
echo '<<<lsi>>>'
cfggen 0 DISPLAY | egrep '(Target ID|State|Volume ID|Status of volume)[[:space:]]*:' | sed -e 's/ *//g' -e 's/:/ /'
fi
# RAID status of LSI MegaRAID controller via MegaCli. You can download that tool from:
# http://www.lsi.com/downloads/Public/MegaRAID%20Common%20Files/8.02.16_MegaCLI.zip
if type MegaCli >/dev/null ; then
MegaCli_bin="MegaCli"
elif type MegaCli64 >/dev/null ; then
MegaCli_bin="MegaCli64"
elif type megacli >/dev/null ; then
MegaCli_bin="megacli"
else
MegaCli_bin="unknown"
fi
if [ "$MegaCli_bin" != "unknown" ]; then
echo '<<<megaraid_pdisks>>>'
for part in $($MegaCli_bin -EncInfo -aALL -NoLog < /dev/null \
| sed -rn 's/:/ /g; s/[[:space:]]+/ /g; s/^ //; s/ $//; s/Number of enclosures on adapter ([0-9]+).*/adapter \1/g; /^(Enclosure|Device ID|adapter) [0-9]+$/ p'); do
[ $part = adapter ] && echo ""
[ $part = 'Enclosure' ] && echo -ne "\ndev2enc"
echo -n " $part"
done
echo
$MegaCli_bin -PDList -aALL -NoLog < /dev/null | egrep 'Enclosure|Raw Size|Slot Number|Device Id|Firmware state|Inquiry|Adapter'
echo '<<<megaraid_ldisks>>>'
$MegaCli_bin -LDInfo -Lall -aALL -NoLog < /dev/null | egrep 'Size|State|Number|Adapter|Virtual'
echo '<<<megaraid_bbu>>>'
$MegaCli_bin -AdpBbuCmd -GetBbuStatus -aALL -NoLog < /dev/null | grep -v Exit
fi
# RAID status of 3WARE disk controller (by Radoslaw Bak)
if type tw_cli > /dev/null ; then
for C in $(tw_cli show | awk 'NR < 4 { next } { print $1 }'); do
echo '<<<3ware_info>>>'
tw_cli /$C show all | egrep 'Model =|Firmware|Serial'
echo '<<<3ware_disks>>>'
tw_cli /$C show drivestatus | egrep 'p[0-9]' | sed "s/^/$C\//"
echo '<<<3ware_units>>>'
tw_cli /$C show unitstatus | egrep 'u[0-9]' | sed "s/^/$C\//"
done
fi
# RAID controllers from areca (Taiwan)
# cli64 can be found at ftp://ftp.areca.com.tw/RaidCards/AP_Drivers/Linux/CLI/
if type cli64 >/dev/null ; then
run_cached -s arc_raid_status 300 "cli64 rsf info | tail -n +3 | head -n -2"
fi
# VirtualBox Guests. Section must always been output. Otherwise the
# check would not be executed in case no guest additions are installed.
# And that is something the check wants to detect
echo '<<<vbox_guest>>>'
if type VBoxControl >/dev/null 2>&1 ; then
VBoxControl -nologo guestproperty enumerate | cut -d, -f1,2
[ ${PIPESTATUS[0]} = 0 ] || echo "ERROR"
fi
# OpenVPN Clients. Currently we assume that the configuration # is in
# /etc/openvpn. We might find a safer way to find the configuration later.
if [ -e /etc/openvpn/openvpn-status.log ] ; then
echo '<<<openvpn_clients:sep(44)>>>'
sed -n -e '/CLIENT LIST/,/ROUTING TABLE/p' < /etc/openvpn/openvpn-status.log | sed -e 1,3d -e '$d'
fi
# Time synchronization with NTP
if type ntpq > /dev/null 2>&1 ; then
# remove heading, make first column space separated
run_cached -s ntp 30 "waitmax 5 ntpq -np | sed -e 1,2d -e 's/^\(.\)/\1 /' -e 's/^ /%/'"
fi
# Time synchronization with Chrony
if type chronyc > /dev/null 2>&1 ; then
# Force successful exit code. Otherwise section will be missing if daemon not running
run_cached -s chrony 30 "waitmax 5 chronyc tracking || true"
fi
if type nvidia-settings >/dev/null && [ -S /tmp/.X11-unix/X0 ]
then
echo '<<<nvidia>>>'
for var in GPUErrors GPUCoreTemp
do
DISPLAY=:0 waitmax 2 nvidia-settings -t -q $var | sed "s/^/$var: /"
done
fi
if [ -e /proc/drbd ]; then
echo '<<<drbd>>>'
cat /proc/drbd
fi
# Status of CUPS printer queues
if type lpstat > /dev/null 2>&1; then
if pgrep cups > /dev/null 2>&1; then
echo '<<<cups_queues>>>'
CPRINTCONF=/etc/cups/printers.conf
if [ -r "$CPRINTCONF" ] ; then
LOCAL_PRINTERS=$(grep -E "<(Default)?Printer .*>" $CPRINTCONF | awk '{print $2}' | sed -e 's/>//')
lpstat -p | while read LINE
do
PRINTER=$(echo $LINE | awk '{print $2}')
if echo "$LOCAL_PRINTERS" | grep -q "$PRINTER"; then
echo $LINE
fi
done
echo '---'
lpstat -o | while read LINE
do
PRINTER=${LINE%%-*}
if echo "$LOCAL_PRINTERS" | grep -q "$PRINTER"; then
echo $LINE
fi
done
else
lpstat -p
echo '---'
lpstat -o | sort
fi
fi
fi
# Heartbeat monitoring
# Different handling for heartbeat clusters with and without CRM
# for the resource state
if [ -S /var/run/heartbeat/crm/cib_ro -o -S /var/run/crm/cib_ro ] || pgrep crmd > /dev/null 2>&1; then
echo '<<<heartbeat_crm>>>'
crm_mon -1 -r | grep -v ^$ | sed 's/^ //; /^\sResource Group:/,$ s/^\s//; s/^\s/_/g'
fi
if type cl_status > /dev/null 2>&1; then
echo '<<<heartbeat_rscstatus>>>'
cl_status rscstatus
echo '<<<heartbeat_nodes>>>'
for NODE in $(cl_status listnodes); do
if [ $NODE != $(echo $HOSTNAME | tr 'A-Z' 'a-z') ]; then
STATUS=$(cl_status nodestatus $NODE)
echo -n "$NODE $STATUS"
for LINK in $(cl_status listhblinks $NODE 2>/dev/null); do
echo -n " $LINK $(cl_status hblinkstatus $NODE $LINK)"
done
echo
fi
done
fi
# Postfix mailqueue monitoring
#
# Only handle mailq when postfix user is present. The mailq command is also
# available when postfix is not installed. But it produces different outputs
# which are not handled by the check at the moment. So try to filter out the
# systems not using postfix by searching for the postfix user.a
#
# Cannot take the whole outout. This could produce several MB of agent output
# on blocking queues.
# Only handle the last 6 lines (includes the summary line at the bottom and
# the last message in the queue. The last message is not used at the moment
# but it could be used to get the timestamp of the last message.
if type postconf >/dev/null ; then
echo '<<<postfix_mailq>>>'
postfix_queue_dir=$(postconf -h queue_directory)
postfix_count=$(find $postfix_queue_dir/deferred -type f | wc -l)
postfix_size=$(du -ks $postfix_queue_dir/deferred | awk '{print $1 }')
if [ $postfix_count -gt 0 ]
then
echo -- $postfix_size Kbytes in $postfix_count Requests.
else
echo Mail queue is empty
fi
elif [ -x /usr/sbin/ssmtp ] ; then
echo '<<<postfix_mailq>>>'
mailq 2>&1 | sed 's/^[^:]*: \(.*\)/\1/' | tail -n 6
fi
#Check status of qmail mailqueue
if type qmail-qstat >/dev/null
then
echo "<<<qmail_stats>>>"
qmail-qstat
fi
# Check status of OMD sites
if type omd >/dev/null
then
run_cached -s omd_status 60 "omd status --bare --auto"
fi
# Welcome the ZFS check on Linux
# We do not endorse running ZFS on linux if your vendor doesnt support it ;)
# check zpool status
if type zpool >/dev/null; then
echo "<<<zpool_status>>>"
zpool status -x
fi
# Fileinfo-Check: put patterns for files into /etc/check_mk/fileinfo.cfg
if [ -r "$MK_CONFDIR/fileinfo.cfg" ] ; then
echo '<<<fileinfo:sep(124)>>>'
date +%s
stat -c "%n|%s|%Y" $(cat "$MK_CONFDIR/fileinfo.cfg")
fi
# Get stats about OMD monitoring cores running on this machine.
# Since cd is a shell builtin the check does not affect the performance
# on non-OMD machines.
if cd /omd/sites
then
echo '<<<livestatus_status:sep(59)>>>'
for site in *
do
if [ -S "/omd/sites/$site/tmp/run/live" ] ; then
echo "[$site]"
echo -e "GET status" | waitmax 3 /omd/sites/$site/bin/unixcat /omd/sites/$site/tmp/run/live
fi
done
fi
# Get statistics about monitored jobs. Below the job directory there
# is a sub directory per user that ran a job. That directory must be
# owned by the user so that a symlink or hardlink attack for reading
# arbitrary files can be avoided.
if pushd $MK_VARDIR/job >/dev/null; then
echo '<<<job>>>'
for username in *
do
if [ -d "$username" ] && cd "$username" ; then
su "$username" -c "head -n -0 -v *"
cd ..
fi
done
popd > /dev/null
fi
# Gather thermal information provided e.g. by acpi
# At the moment only supporting thermal sensors
if ls /sys/class/thermal/thermal_zone* >/dev/null 2>&1; then
echo '<<<lnx_thermal>>>'
for F in /sys/class/thermal/thermal_zone*; do
echo -n "${F##*/} "
if [ ! -e $F/mode ] ; then echo -n "- " ; fi
cat $F/{mode,type,temp,trip_point_*} | tr \\n " "
echo
done
fi
# Libelle Business Shadow
if type trd >/dev/null; then
echo "<<<libelle_business_shadow:sep(58)>>>"
trd -s
fi
# MK's Remote Plugin Executor
if [ -e "$MK_CONFDIR/mrpe.cfg" ]
then
echo '<<<mrpe>>>'
grep -Ev '^[[:space:]]*($|#)' "$MK_CONFDIR/mrpe.cfg" | \
while read descr cmdline
do
PLUGIN=${cmdline%% *}
OUTPUT=$(eval "$cmdline")
echo -n "(${PLUGIN##*/}) $descr $? $OUTPUT" | tr \\n \\1
echo
done
fi
# Local checks
echo '<<<local>>>'
if cd $LOCALDIR ; then
for skript in $(ls) ; do
if [ -f "$skript" -a -x "$skript" ] ; then
./$skript
fi
done
# Call some plugins only every X'th minute
for skript in [1-9]*/* ; do
if [ -x "$skript" ] ; then
run_cached local_${skript//\//\\} ${skript%/*} "$skript"
fi
done
fi
# Plugins
if cd $PLUGINSDIR ; then
for skript in $(ls) ; do
if [ -f "$skript" -a -x "$skript" ] ; then
./$skript
fi
done
# Call some plugins only every Xth minute
for skript in [1-9]*/* ; do
if [ -x "$skript" ] ; then
run_cached plugins_${skript//\//\\} ${skript%/*} "$skript"
fi
done
fi
# Agent output snippets created by cronjobs, etc.
if [ -d "$SPOOLDIR" ]
then
pushd "$SPOOLDIR" > /dev/null
now=$(date +%s)
for file in *
do
# output every file in this directory. If the file is prefixed
# with a number, then that number is the maximum age of the
# file in seconds. If the file is older than that, it is ignored.
maxage=""
part="$file"
# Each away all digits from the front of the filename and
# collect them in the variable maxage.
while [ "${part/#[0-9]/}" != "$part" ]
do
maxage=$maxage${part:0:1}
part=${part:1}
done
# If there is at least one digit, than we honor that.
if [ "$maxage" ] ; then
mtime=$(stat -c %Y "$file")
if [ $((now - mtime)) -gt $maxage ] ; then
continue
fi
fi
# Output the file
cat "$file"
done
popd > /dev/null
fi

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
echo '<<<dmi>>>'
# requires dmidecode
for FIELD in bios-vendor bios-version bios-release-date system-manufacturer system-product-name system-version system-serial-number system-uuid baseboard-manufacturer baseboard-product-name baseboard-version baseboard-serial-number baseboard-asset-tag chassis-manufacturer chassis-type chassis-version chassis-serial-number chassis-asset-tag processor-family processor-manufacturer processor-version processor-frequency
do
echo $FIELD="$(dmidecode -s $FIELD | grep -v '^#')"
done

View File

@@ -0,0 +1,22 @@
#!/bin/bash
# Cache the file for 30 minutes
# If you want to override this, put the command in cron.
# We cache because it is a 1sec delay, which is painful for the poller
if [ -x /usr/bin/dpkg-query ]; then
DATE=$(date +%s)
FILE=/var/cache/librenms/agent-local-dpkg
[ -d /var/cache/librenms ] || mkdir -p /var/cache/librenms
if [ ! -e $FILE ]; then
dpkg-query -W --showformat='${Status} ${Package} ${Version} ${Architecture} ${Installed-Size}\n'|grep " installed "|cut -d\ -f4- > $FILE
fi
FILEMTIME=$(stat -c %Y $FILE)
FILEAGE=$(($DATE-$FILEMTIME))
if [ $FILEAGE -gt 1800 ]; then
dpkg-query -W --showformat='${Status} ${Package} ${Version} ${Architecture} ${Installed-Size}\n'|grep " installed "|cut -d\ -f4- > $FILE
fi
echo "<<<dpkg>>>"
cat $FILE
fi

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
#!/bin/sh
# Please make sure the paths below are correct.
# Alternatively you can put them in $0.conf, meaning if you've named
# this script ntp-client then it must go in ntp-client.conf .
#
# NTPQV output version of "ntpq -c rv"
# Version 4 is the most common and up to date version.
#
# If you are unsure, which to set, run this script and make sure that
# the JSON output variables match that in "ntpq -c rv".
#
################################################################
# Don't change anything unless you know what are you doing #
################################################################
BIN_NTPQ='/usr/bin/env ntpq'
BIN_GREP='/usr/bin/env grep'
BIN_AWK='/usr/bin/env awk'
CONFIG=$0".conf"
if [ -f "$CONFIG" ]; then
# shellcheck disable=SC1090
. "$CONFIG"
fi
NTP_OFFSET=$($BIN_NTPQ -c rv | $BIN_GREP "offset" | $BIN_AWK -Foffset= '{print $2}' | $BIN_AWK -F, '{print $1}')
NTP_FREQUENCY=$($BIN_NTPQ -c rv | $BIN_GREP "frequency" | $BIN_AWK -Ffrequency= '{print $2}' | $BIN_AWK -F, '{print $1}')
NTP_SYS_JITTER=$($BIN_NTPQ -c rv | $BIN_GREP "sys_jitter" | $BIN_AWK -Fsys_jitter= '{print $2}' | $BIN_AWK -F, '{print $1}')
NTP_CLK_JITTER=$($BIN_NTPQ -c rv | $BIN_GREP "clk_jitter" | $BIN_AWK -Fclk_jitter= '{print $2}' | $BIN_AWK -F, '{print $1}')
NTP_WANDER=$($BIN_NTPQ -c rv | $BIN_GREP "clk_wander" | $BIN_AWK -Fclk_wander= '{print $2}' | $BIN_AWK -F, '{print $1}')
NTP_VERSION=$($BIN_NTPQ -c rv | $BIN_GREP "version" | $BIN_AWK -F'ntpd ' '{print $2}' | $BIN_AWK -F. '{print $1}')
echo '{"data":{"offset":"'"$NTP_OFFSET"'","frequency":"'"$NTP_FREQUENCY"'","sys_jitter":"'"$NTP_SYS_JITTER"'","clk_jitter":"'"$NTP_CLK_JITTER"'","clk_wander":"'"$NTP_WANDER"'"},"version":"'"$NTP_VERSION"'","error":"0","errorString":""}'
exit 0

View File

@@ -8,6 +8,6 @@
QUEUES="incoming active deferred hold"
for i in $QUEUES; do
COUNT=`qshape $i | grep TOTAL | awk '{print $2}'`
COUNT=$(qshape "$i" | grep TOTAL | awk '{print $2}')
printf "$COUNT\n"
done

View File

@@ -86,10 +86,10 @@ my ( $received,
$rardnf,
$rarnfqa,
$iuscp,
$msefl,
$sce,
$scp,
$urr) = split ( /\n/, $old );
$urr,
$msefl) = split ( /\n/, $old );
if ( ! defined( $received ) ){ $received=0; }
if ( ! defined( $delivered ) ){ $delivered=0; }
@@ -142,7 +142,6 @@ my $recipientsC=0;
my $recipienthdC=0;
my $deferralcrC=0;
my $deferralhidC=0;
my $chrC=0;
my $hcrnfqhC=0;
my $sardnfC=0;
my $sarnobuC=0;
@@ -193,14 +192,15 @@ sub newValue{
}
my $output=`$pflogsumm /var/log/mail.log`;
#holds client host rejected values till the end when it is compared to the old one
my $chrNew=0;
my $output=`$pflogsumm /var/log/maillog`;
#holds RBL values till the end when it is compared to the old one
my $buNew=0;
#holds client host rejected values till the end when it is compared to the old one
my $chrNew=0;
# holds recipient address rejected values till the end when it is compared to the old one
my $raruuNew=0;
@@ -353,6 +353,7 @@ while ( defined( $outputA[$int] ) ){
# deferrals Host is down
if ( ( $line =~ /Host is down$/ ) && ( ! $handled ) ){
$line=~s/ .*//;
$deferralcrC=$line;
$deferralhidC=$line;
$deferralhid=newValue( $deferralhid, $line );
$handled=1;
@@ -429,8 +430,8 @@ while ( defined( $outputA[$int] ) ){
#Improper use of SMTP command pipelining
if ( ( $line =~ /Improper use of SMTP command pipelining/ ) && ( ! $handled ) ){
$line=~s/.*\: //g;
$iuoscpC=$line;
$iuoscp=newValue( $iuoscp, $line );
$iuscpC=$line;
$iuscp=newValue( $iuscp, $line );
}
#Message size exceeds fixed limit
@@ -460,9 +461,11 @@ while ( defined( $outputA[$int] ) ){
$urrC=$line;
$urr=newValue( $urr, $line );
}
$int++;
}
# final client host rejected total
$chr=newValue( $chr, $chrNew );
@@ -502,8 +505,8 @@ my $data=$received."\n".
$iuscp."\n".
$sce."\n".
$scp."\n".
$urr."\n";
$msefl."\n".
$urr."\n".
$msefl."\n";
print $data;
@@ -535,10 +538,10 @@ my $current=$receivedC."\n".
$rardnfC."\n".
$rarnfqaC."\n".
$iuscpC."\n".
$mseflC."\n".
$sceC."\n".
$scpC."\n".
$urrC."\n";
$urrC."\n".
$mseflC."\n";
open(my $fh, ">", $cache) or die "Can't open '".$cache."'";
print $fh $current;

View File

@@ -0,0 +1,46 @@
#!/bin/bash
#######################################
# please read DOCS to succesfully get #
# raspberry sensors into your host #
#######################################
picmd='/usr/bin/vcgencmd'
pised='/bin/sed'
getTemp='measure_temp'
getVoltsCore='measure_volts core'
getVoltsRamC='measure_volts sdram_c'
getVoltsRamI='measure_volts sdram_i'
getVoltsRamP='measure_volts sdram_p'
getFreqArm='measure_clock arm'
getFreqCore='measure_clock core'
getStatusH264='codec_enabled H264'
getStatusMPG2='codec_enabled MPG2'
getStatusWVC1='codec_enabled WVC1'
getStatusMPG4='codec_enabled MPG4'
getStatusMJPG='codec_enabled MJPG'
getStatusWMV9='codec_enabled WMV9'
$picmd $getTemp | $pised 's|[^0-9.]||g'
$picmd "$getVoltsCore" | $pised 's|[^0-9.]||g'
$picmd "$getVoltsRamC" | $pised 's|[^0-9.]||g'
$picmd "$getVoltsRamI" | $pised 's|[^0-9.]||g'
$picmd "$getVoltsRamP" | $pised 's|[^0-9.]||g'
$picmd "$getFreqArm" | $pised 's/frequency([0-9]*)=//g'
$picmd "$getFreqCore" | $pised 's/frequency([0-9]*)=//g'
$picmd "$getStatusH264" | $pised 's/H264=//g'
$picmd "$getStatusMPG2" | $pised 's/MPG2=//g'
$picmd "$getStatusWVC1" | $pised 's/WVC1=//g'
$picmd "$getStatusMPG4" | $pised 's/MPG4=//g'
$picmd "$getStatusMJPG" | $pised 's/MJPG=//g'
$picmd "$getStatusWMV9" | $pised 's/WMV9=//g'
$picmd "$getStatusH264" | $pised 's/enabled/2/g'
$picmd "$getStatusMPG2" | $pised 's/enabled/2/g'
$picmd "$getStatusWVC1" | $pised 's/enabled/2/g'
$picmd "$getStatusMPG4" | $pised 's/enabled/2/g'
$picmd "$getStatusMJPG" | $pised 's/enabled/2/g'
$picmd "$getStatusWMV9" | $pised 's/enabled/2/g'
$picmd "$getStatusH264" | $pised 's/disabled/1/g'
$picmd "$getStatusMPG2" | $pised 's/disabled/1/g'
$picmd "$getStatusWVC1" | $pised 's/disabled/1/g'
$picmd "$getStatusMPG4" | $pised 's/disabled/1/g'
$picmd "$getStatusMJPG" | $pised 's/disabled/1/g'
$picmd "$getStatusWMV9" | $pised 's/disabled/1/g'

View File

@@ -0,0 +1,929 @@
#!/usr/bin/env perl
#Copyright (c) 2024, Zane C. Bowers-Hadley
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without modification,
#are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
#INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
#THE POSSIBILITY OF SUCH DAMAGE.
=for comment
Add this to snmpd.conf like below.
extend smart /etc/snmp/smart
Then add to root's cron tab, if you have more than a few disks.
*/5 * * * * /etc/snmp/extends/smart -u
You will also need to create the config file, which defaults to the same path as the script,
but with .config appended. So if the script is located at /etc/snmp/smart, the config file
will be /etc/snmp/extends/smart.config. Alternatively you can also specific a config via -c.
Anything starting with a # is comment. The format for variables is $variable=$value. Empty
lines are ignored. Spaces and tabes at either the start or end of a line are ignored. Any
line with out a matched variable or # are treated as a disk.
#This is a comment
cache=/var/cache/smart
smartctl=/usr/local/sbin/smartctl
useSN=0
ada0
da5 /dev/da5 -d sat
twl0,0 /dev/twl0 -d 3ware,0
twl0,1 /dev/twl0 -d 3ware,1
twl0,2 /dev/twl0 -d 3ware,2
The variables are as below.
cache = The path to the cache file to use. Default: /var/cache/smart
smartctl = The path to use for smartctl. Default: /usr/bin/env smartctl
useSN = If set to 1, it will use the disks SN for reporting instead of the device name.
1 is the default. 0 will use the device name.
A disk line is can be as simple as just a disk name under /dev/. Such as in the config above
The line "ada0" would resolve to "/dev/ada0" and would be called with no special argument. If
a line has a space in it, everything before the space is treated as the disk name and is what
used for reporting and everything after that is used as the argument to be passed to smartctl.
If you want to guess at the configuration, call it with -g and it will print out what it thinks
it should be.
Switches:
-c <config> The config file to use.
-u Update
-p Pretty print the JSON.
-Z GZip+Base64 compress the results.
-g Guess at the config and print it to STDOUT
-C Enable manual checking for guess and cciss.
-S Set useSN to 0 when using -g
-t <test> Run the specified smart self test on all the devices.
-U When calling cciss_vol_status, call it with -u.
-G <modes> Guess modes to use. This is a comma seperated list.
Default :: scan-open,cciss-vol-status
Guess Modes:
- scan :: Use "--scan" with smartctl. "scan-open" will take presidence.
- scan-open :: Call smartctl with "--scan-open".
- cciss-vol-status :: Freebsd/Linux specific and if it sees /dev/sg0(on Linux) or
/dev/ciss0(on FreebSD) it will attempt to find drives via cciss-vol-status,
and then optionally checking for disks via smrtctl if -C is given. Should be noted
though that -C will not find drives that are currently missing/failed. If -U is given,
cciss_vol_status will be called with -u.
=cut
##
## You should not need to touch anything below here.
##
use warnings;
use strict;
use Getopt::Std;
use JSON;
use MIME::Base64;
use IO::Compress::Gzip qw(gzip $GzipError);
my $cache = '/var/cache/smart';
my $smartctl = '/usr/bin/env smartctl';
my @disks;
my $useSN = 1;
$Getopt::Std::STANDARD_HELP_VERSION = 1;
sub main::VERSION_MESSAGE {
print "SMART SNMP extend 0.3.2\n";
}
sub main::HELP_MESSAGE {
&VERSION_MESSAGE;
print "\n" . "-u Update '" . $cache . "'\n" . '-g Guess at the config and print it to STDOUT
-c <config> The config file to use.
-p Pretty print the JSON.
-Z GZip+Base64 compress the results.
-C Enable manual checking for guess and cciss.
-S Set useSN to 0 when using -g
-t <test> Run the specified smart self test on all the devices.
-U When calling cciss_vol_status, call it with -u.
-G <modes> Guess modes to use. This is a comma seperated list.
Default :: scan-open,cciss-vol-status
Scan Modes:
- scan :: Use "--scan" with smartctl. "scan-open" will take presidence.
- scan-open :: Call smartctl with "--scan-open".
- cciss-vol-status :: Freebsd/Linux specific and if it sees /dev/sg0(on Linux) or
/dev/ciss0(on FreebSD) it will attempt to find drives via cciss-vol-status,
and then optionally checking for disks via smrtctl if -C is given. Should be noted
though that -C will not find drives that are currently missing/failed. If -U is given,
cciss_vol_status will be called with -u.
';
} ## end sub main::HELP_MESSAGE
#gets the options
my %opts = ();
getopts( 'ugc:pZhvCSGt:U', \%opts );
if ( $opts{h} ) {
&HELP_MESSAGE;
exit;
}
if ( $opts{v} ) {
&VERSION_MESSAGE;
exit;
}
#
# figure out what scan modes to use if -g specified
#
my $scan_modes = {
'scan-open' => 0,
'scan' => 0,
'cciss_vol_status' => 0,
};
if ( $opts{g} ) {
if ( !defined( $opts{G} ) ) {
$opts{G} = 'scan-open,cciss_vol_status';
}
$opts{G} =~ s/[\ \t]//g;
my @scan_modes_split = split( /,/, $opts{G} );
foreach my $mode (@scan_modes_split) {
if ( !defined $scan_modes->{$mode} ) {
die( '"' . $mode . '" is not a recognized scan mode' );
}
$scan_modes->{$mode} = 1;
}
} ## end if ( $opts{g} )
# configure JSON for later usage
# only need to do this if actually running as in -g is not specified
my $json;
if ( !$opts{g} ) {
$json = JSON->new->allow_nonref->canonical(1);
if ( $opts{p} ) {
$json->pretty;
}
}
#
#
# guess if asked
#
#
if ( defined( $opts{g} ) ) {
#get what path to use for smartctl
$smartctl = `which smartctl`;
chomp($smartctl);
if ( $? != 0 ) {
warn("'which smartctl' failed with a exit code of $?");
exit 1;
}
#try to touch the default cache location and warn if it can't be done
system( 'touch ' . $cache . '>/dev/null' );
if ( $? != 0 ) {
$cache = '#Could not touch ' . $cache . "You will need to manually set it\n" . "cache=?\n";
} else {
system( 'rm -f ' . $cache . '>/dev/null' );
$cache = 'cache=' . $cache . "\n";
}
my $drive_lines = '';
#
#
# scan-open and scan guess mode handling
#
#
if ( $scan_modes->{'scan-open'} || $scan_modes->{'scan'} ) {
# used for checking if a disk has been found more than once
my %found_disks_names;
my @argumentsA;
# use scan-open if it is set, overriding scan if it is also set
my $mode = 'scan';
if ( $scan_modes->{'scan-open'} ) {
$mode = 'scan-open';
}
#have smartctl scan and see if it finds anythings not get found
my $scan_output = `$smartctl --$mode`;
my @scan_outputA = split( /\n/, $scan_output );
# remove non-SMART devices sometimes returned
@scan_outputA = grep( !/ses[0-9]/, @scan_outputA ); # not a disk, but may or may not have SMART attributes
@scan_outputA = grep( !/pass[0-9]/, @scan_outputA ); # very likely a duplicate and a disk under another name
@scan_outputA = grep( !/cd[0-9]/, @scan_outputA ); # CD drive
if ( $^O eq 'freebsd' ) {
@scan_outputA = grep( !/sa[0-9]/, @scan_outputA ); # tape drive
@scan_outputA = grep( !/ctl[0-9]/, @scan_outputA ); # CAM target layer
} elsif ( $^O eq 'linux' ) {
@scan_outputA = grep( !/st[0-9]/, @scan_outputA ); # SCSI tape drive
@scan_outputA = grep( !/ht[0-9]/, @scan_outputA ); # ATA tape drive
}
# make the first pass, figuring out what all we have and trimming comments
foreach my $arguments (@scan_outputA) {
my $name = $arguments;
$arguments =~ s/ \#.*//; # trim the comment out of the argument
$name =~ s/ .*//;
$name =~ s/\/dev\///;
if ( defined( $found_disks_names{$name} ) ) {
$found_disks_names{$name}++;
} else {
$found_disks_names{$name} = 0;
}
push( @argumentsA, $arguments );
} ## end foreach my $arguments (@scan_outputA)
# second pass, putting the lines together
my %current_disk;
foreach my $arguments (@argumentsA) {
my $not_virt = 1;
# check to see if we have a virtual device
my @virt_check = split( /\n/, `smartctl -i $arguments 2> /dev/null` );
foreach my $virt_check_line (@virt_check) {
if ( $virt_check_line =~ /(?i)Product\:.*LOGICAL VOLUME/ ) {
$not_virt = 0;
}
}
my $name = $arguments;
$name =~ s/ .*//;
$name =~ s/\/dev\///;
# only add it if not a virtual RAID drive
# HP RAID virtual disks will show up with very basical but totally useless smart data
if ($not_virt) {
if ( $found_disks_names{$name} == 0 ) {
# If no other devices, just name it after the base device.
$drive_lines = $drive_lines . $name . " " . $arguments . "\n";
} else {
# if more than one, start at zero and increment, apennding comma number to the base device name
if ( defined( $current_disk{$name} ) ) {
$current_disk{$name}++;
} else {
$current_disk{$name} = 0;
}
$drive_lines = $drive_lines . $name . "," . $current_disk{$name} . " " . $arguments . "\n";
}
} ## end if ($not_virt)
} ## end foreach my $arguments (@argumentsA)
} ## end if ( $scan_modes->{'scan-open'} || $scan_modes...)
#
#
# scan mode handler for cciss_vol_status
# /dev/sg* devices for cciss on Linux
# /dev/ccis* devices for cciss on FreeBSD
#
#
if ( $scan_modes->{'cciss_vol_status'} && ( $^O eq 'linux' || $^O eq 'freebsd' ) ) {
my $cciss;
if ( $^O eq 'freebsd' ) {
$cciss = 'ciss';
} elsif ( $^O eq 'linux' ) {
$cciss = 'sg';
}
my $uarg = '';
if ( $opts{U} ) {
$uarg = '-u';
}
# generate the initial device path that will be checked
my $sg_int = 0;
my $device = '/dev/' . $cciss . $sg_int;
my $sg_process = 1;
if ( -e $device ) {
my $output = `which cciss_vol_status 2> /dev/null`;
if ( $? != 0 && !$opts{C} ) {
$sg_process = 0;
$drive_lines
= $drive_lines
. "# -C not given, but "
. $device
. " exists and cciss_vol_status is not present\n"
. "# in path or 'ccis_vol_status -V "
. $device
. "' is failing\n";
} ## end if ( $? != 0 && !$opts{C} )
} ## end if ( -e $device )
my $seen_lines = {};
my $ignore_lines = {};
while ( -e $device && $sg_process ) {
my $output = `cciss_vol_status -V $uarg $device 2> /dev/null`;
if ( $? != 0 && $output eq '' && !$opts{C} ) {
# just empty here as we just want to skip it if it fails and there is no C
# warning is above
} elsif ( $? != 0 && $output eq '' && $opts{C} ) {
my $drive_count = 0;
my $continue = 1;
while ($continue) {
my $output = `$smartctl -i $device -d cciss,$drive_count 2> /dev/null`;
if ( $? != 0 ) {
$continue = 0;
} else {
my $add_it = 0;
my $id;
while ( $output =~ /(?i)Serial Number:(.*)/g ) {
$id = $1;
$id =~ s/^\s+|\s+$//g;
}
if ( defined($id) && !defined( $seen_lines->{$id} ) ) {
$add_it = 1;
$seen_lines->{$id} = 1;
}
if ( $continue && $add_it ) {
$drive_lines
= $drive_lines
. $cciss . '0-'
. $drive_count . ' '
. $device
. ' -d cciss,'
. $drive_count . "\n";
}
} ## end else [ if ( $? != 0 ) ]
$drive_count++;
} ## end while ($continue)
} else {
my $drive_count = 0;
# count the connector lines, this will make sure failed are founded as well
my $seen_conectors = {};
while ( $output =~ /(connector +\d+[IA]\ +box +\d+\ +bay +\d+.*)/g ) {
my $cciss_drive_line = $1;
my $connector = $cciss_drive_line;
$connector =~ s/(.*\ bay +\d+).*/$1/;
if ( !defined( $seen_lines->{$cciss_drive_line} )
&& !defined( $seen_conectors->{$connector} )
&& !defined( $ignore_lines->{$cciss_drive_line} ) )
{
$seen_lines->{$cciss_drive_line} = 1;
$seen_conectors->{$connector} = 1;
$drive_count++;
} else {
# going to be a connector we've already seen
# which will happen when it is processing replacement drives
# so save this as a device to ignore
$ignore_lines->{$cciss_drive_line} = 1;
}
} ## end while ( $output =~ /(connector +\d+[IA]\ +box +\d+\ +bay +\d+.*)/g)
my $drive_int = 0;
while ( $drive_int < $drive_count ) {
$drive_lines
= $drive_lines
. $cciss
. $sg_int . '-'
. $drive_int . ' '
. $device
. ' -d cciss,'
. $drive_int . "\n";
$drive_int++;
} ## end while ( $drive_int < $drive_count )
} ## end else [ if ( $? != 0 && $output eq '' && !$opts{C})]
$sg_int++;
$device = '/dev/' . $cciss . $sg_int;
} ## end while ( -e $device && $sg_process )
} ## end if ( $scan_modes->{'cciss_vol_status'} && ...)
my $useSN = 1;
if ( $opts{S} ) {
$useSN = 0;
}
print '# scan_modes='
. $opts{G}
. "\nuseSN="
. $useSN . "\n"
. 'smartctl='
. $smartctl . "\n"
. $cache
. $drive_lines;
exit 0;
} ## end if ( defined( $opts{g} ) )
#get which config file to use
my $config = $0 . '.config';
if ( defined( $opts{c} ) ) {
$config = $opts{c};
}
#reads the config file, optionally
my $config_file = '';
open( my $readfh, "<", $config ) or die "Can't open '" . $config . "'";
read( $readfh, $config_file, 1000000 );
close($readfh);
#
#
# parse the config file and remove comments and empty lines
#
#
my @configA = split( /\n/, $config_file );
@configA = grep( !/^$/, @configA );
@configA = grep( !/^\#/, @configA );
@configA = grep( !/^[\s\t]*$/, @configA );
my $configA_int = 0;
while ( defined( $configA[$configA_int] ) ) {
my $line = $configA[$configA_int];
chomp($line);
$line =~ s/^[\t\s]+//;
$line =~ s/[\t\s]+$//;
my ( $var, $val ) = split( /=/, $line, 2 );
my $matched;
if ( $var eq 'cache' ) {
$cache = $val;
$matched = 1;
}
if ( $var eq 'smartctl' ) {
$smartctl = $val;
$matched = 1;
}
if ( $var eq 'useSN' ) {
$useSN = $val;
$matched = 1;
}
if ( !defined($val) ) {
push( @disks, $line );
}
$configA_int++;
} ## end while ( defined( $configA[$configA_int] ) )
#
#
# run the specified self test on all disks if asked
#
#
if ( defined( $opts{t} ) ) {
# make sure we have something that atleast appears sane for the test name
my $valid_tesks = {
'offline' => 1,
'short' => 1,
'long' => 1,
'conveyance' => 1,
'afterselect,on' => 1,
};
if ( !defined( $valid_tesks->{ $opts{t} } ) && $opts{t} !~ /select,(\d+[\-\+]\d+|next|next\+\d+|redo\+\d+)/ ) {
print '"' . $opts{t} . "\" does not appear to be a valid test\n";
exit 1;
}
print "Running the SMART $opts{t} on all devices in the config...\n\n";
foreach my $line (@disks) {
my $disk;
my $name;
if ( $line =~ /\ / ) {
( $name, $disk ) = split( /\ /, $line, 2 );
} else {
$disk = $line;
$name = $line;
}
if ( $disk !~ /\// ) {
$disk = '/dev/' . $disk;
}
print "\n------------------------------------------------------------------\nDoing "
. $smartctl . ' -t '
. $opts{t} . ' '
. $disk
. " ...\n\n";
print `$smartctl -t $opts{t} $disk` . "\n";
} ## end foreach my $line (@disks)
exit 0;
} ## end if ( defined( $opts{t} ) )
#if set to 1, no cache will be written and it will be printed instead
my $noWrite = 0;
#
#
# if no -u, it means we are being called from snmped
#
#
if ( !defined( $opts{u} ) ) {
# if the cache file exists, print it, otherwise assume one is not being used
if ( -f $cache ) {
my $old = '';
open( my $readfh, "<", $cache ) or die "Can't open '" . $cache . "'";
read( $readfh, $old, 1000000 );
close($readfh);
print $old;
exit 0;
} else {
$opts{u} = 1;
$noWrite = 1;
}
} ## end if ( !defined( $opts{u} ) )
#
#
# Process each disk
#
#
my $to_return = {
data => { disks => {}, exit_nonzero => 0, unhealthy => 0, useSN => $useSN },
version => 1,
error => 0,
errorString => '',
};
foreach my $line (@disks) {
my $disk;
my $name;
if ( $line =~ /\ / ) {
( $name, $disk ) = split( /\ /, $line, 2 );
} else {
$disk = $line;
$name = $line;
}
if ( $disk !~ /\// ) {
$disk = '/dev/' . $disk;
}
my $output = `$smartctl -A $disk`;
my %IDs = (
'5' => 'null',
'10' => 'null',
'173' => 'null',
'177' => 'null',
'183' => 'null',
'184' => 'null',
'187' => 'null',
'188' => 'null',
'190' => 'null',
'194' => 'null',
'196' => 'null',
'197' => 'null',
'198' => 'null',
'199' => 'null',
'231' => 'null',
'232' => 'null',
'233' => 'null',
'9' => 'null',
'disk' => $disk,
'serial' => undef,
'selftest_log' => undef,
'health_pass' => 0,
max_temp => 'null',
exit => $?,
);
$IDs{'disk'} =~ s/^\/dev\///;
# if polling exited non-zero above, no reason running the rest of the checks
my $disk_id = $name;
if ( $IDs{exit} != 0 ) {
$to_return->{data}{exit_nonzero}++;
} else {
my @outputA;
if ( $output =~ /NVMe Log/ ) {
# we have an NVMe drive with annoyingly different output
my %mappings = (
'Temperature' => 194,
'Power Cycles' => 12,
'Power On Hours' => 9,
'Percentage Used' => 231,
);
foreach ( split( /\n/, $output ) ) {
if (/:/) {
my ( $key, $val ) = split(/:/);
$val =~ s/^\s+|\s+$|\D+//g;
if ( exists( $mappings{$key} ) ) {
if ( $mappings{$key} == 231 ) {
$IDs{ $mappings{$key} } = 100 - $val;
} else {
$IDs{ $mappings{$key} } = $val;
}
}
} ## end if (/:/)
} ## end foreach ( split( /\n/, $output ) )
} else {
@outputA = split( /\n/, $output );
my $outputAint = 0;
while ( defined( $outputA[$outputAint] ) ) {
my $line = $outputA[$outputAint];
$line =~ s/^ +//;
$line =~ s/ +/ /g;
if ( $line =~ /^[0123456789]+ / ) {
my @lineA = split( /\ /, $line, 10 );
my $raw = $lineA[9];
my $normalized = $lineA[3];
my $id = $lineA[0];
# Crucial SSD
# 202, Percent_Lifetime_Remain, same as 231, SSD Life Left
if ( $id == 202
&& $line =~ /Percent_Lifetime_Remain/ )
{
$IDs{231} = $raw;
}
# single int raw values
if ( ( $id == 5 )
|| ( $id == 10 )
|| ( $id == 173 )
|| ( $id == 183 )
|| ( $id == 184 )
|| ( $id == 187 )
|| ( $id == 196 )
|| ( $id == 197 )
|| ( $id == 198 )
|| ( $id == 199 ) )
{
my @rawA = split( /\ /, $raw );
$IDs{$id} = $rawA[0];
} ## end if ( ( $id == 5 ) || ( $id == 10 ) || ( $id...))
# single int normalized values
if ( ( $id == 177 )
|| ( $id == 230 )
|| ( $id == 231 )
|| ( $id == 232 )
|| ( $id == 233 ) )
{
# annoying non-standard disk
# WDC WDS500G2B0A
# 230 Media_Wearout_Indicator 0x0032 100 100 --- Old_age Always - 0x002e000a002e
# 232 Available_Reservd_Space 0x0033 100 100 004 Pre-fail Always - 100
# 233 NAND_GB_Written_TLC 0x0032 100 100 --- Old_age Always - 9816
if ( $id == 230
&& $line =~ /Media_Wearout_Indicator/ )
{
$IDs{233} = int($normalized);
} elsif ( $id == 232
&& $line =~ /Available_Reservd_Space/ )
{
$IDs{232} = int($normalized);
} else {
# only set 233 if it has not been set yet
# if it was set already then the above did it and we don't want
# to overwrite it
if ( $id == 233 && $IDs{233} eq "null" ) {
$IDs{$id} = int($normalized);
} elsif ( $id != 233 ) {
$IDs{$id} = int($normalized);
}
} ## end else [ if ( $id == 230 && $line =~ /Media_Wearout_Indicator/)]
} ## end if ( ( $id == 177 ) || ( $id == 230 ) || (...))
# 9, power on hours
if ( $id == 9 ) {
my @runtime = split( /[\ h]/, $raw );
$IDs{$id} = $runtime[0];
}
# 188, Command_Timeout
if ( $id == 188 ) {
my $total = 0;
my @rawA = split( /\ /, $raw );
my $rawAint = 0;
while ( defined( $rawA[$rawAint] ) ) {
$total = $total + $rawA[$rawAint];
$rawAint++;
}
$IDs{$id} = $total;
} ## end if ( $id == 188 )
# 190, airflow temp
# 194, temp
if ( ( $id == 190 )
|| ( $id == 194 ) )
{
my ($temp) = split( /\ /, $raw );
$IDs{$id} = $temp;
}
} ## end if ( $line =~ /^[0123456789]+ / )
# SAS Wrapping
# Section by Cameron Munroe (munroenet[at]gmail.com)
# Elements in Grown Defect List.
# Marking as 5 Reallocated_Sector_Ct
if ( $line =~ "Elements in grown defect list:" ) {
my @lineA = split( /\ /, $line, 10 );
my $raw = $lineA[5];
# Reallocated Sector Count ID
$IDs{5} = $raw;
}
# Current Drive Temperature
# Marking as 194 Temperature_Celsius
if ( $line =~ "Current Drive Temperature:" ) {
my @lineA = split( /\ /, $line, 10 );
my $raw = $lineA[3];
# Temperature C ID
$IDs{194} = $raw;
}
# End of SAS Wrapper
$outputAint++;
} ## end while ( defined( $outputA[$outputAint] ) )
} ## end else [ if ( $output =~ /NVMe Log/ ) ]
#get the selftest logs
$output = `$smartctl -l selftest $disk`;
@outputA = split( /\n/, $output );
my @completed = grep( /Completed/, @outputA );
$IDs{'completed'} = scalar @completed;
my @interrupted = grep( /Interrupted/, @outputA );
$IDs{'interrupted'} = scalar @interrupted;
my @read_failure = grep( /read failure/, @outputA );
$IDs{'read_failure'} = scalar @read_failure;
my @read_failure2 = grep( /Failed in segment/, @outputA );
$IDs{'read_failure'} = $IDs{'read_failure'} + scalar @read_failure2;
my @unknown_failure = grep( /unknown failure/, @outputA );
$IDs{'unknown_failure'} = scalar @unknown_failure;
my @extended = grep( /\d.*\ ([Ee]xtended|[Ll]ong).*(?![Dd]uration)/, @outputA );
$IDs{'extended'} = scalar @extended;
my @short = grep( /[Ss]hort/, @outputA );
$IDs{'short'} = scalar @short;
my @conveyance = grep( /[Cc]onveyance/, @outputA );
$IDs{'conveyance'} = scalar @conveyance;
my @selective = grep( /[Ss]elective/, @outputA );
$IDs{'selective'} = scalar @selective;
my @offline = grep( /(\d|[Bb]ackground|[Ff]oreground)+\ +[Oo]ffline/, @outputA );
$IDs{'offline'} = scalar @offline;
# if we have logs, actually grab the log output
if ( $IDs{'completed'} > 0
|| $IDs{'interrupted'} > 0
|| $IDs{'read_failure'} > 0
|| $IDs{'extended'} > 0
|| $IDs{'short'} > 0
|| $IDs{'conveyance'} > 0
|| $IDs{'selective'} > 0
|| $IDs{'offline'} > 0 )
{
my @headers = grep( /(Num\ +Test.*LBA| Description .*[Hh]ours)/, @outputA );
my @log_lines;
push( @log_lines, @extended, @short, @conveyance, @selective, @offline );
$IDs{'selftest_log'} = join( "\n", @headers, sort(@log_lines) );
} ## end if ( $IDs{'completed'} > 0 || $IDs{'interrupted'...})
# get the drive serial number, if needed
$disk_id = $name;
$output = `$smartctl -i $disk`;
# generally upper case, HP branded drives seem to report with lower case n
while ( $output =~ /(?i)Serial Number:(.*)/g ) {
$IDs{'serial'} = $1;
$IDs{'serial'} =~ s/^\s+|\s+$//g;
}
if ($useSN) {
$disk_id = $IDs{'serial'};
}
while ( $output =~ /(?i)Model Family:(.*)/g ) {
$IDs{'model_family'} = $1;
$IDs{'model_family'} =~ s/^\s+|\s+$//g;
}
while ( $output =~ /(?i)Device Model:(.*)/g ) {
$IDs{'device_model'} = $1;
$IDs{'device_model'} =~ s/^\s+|\s+$//g;
}
while ( $output =~ /(?i)Model Number:(.*)/g ) {
$IDs{'model_number'} = $1;
$IDs{'model_number'} =~ s/^\s+|\s+$//g;
}
while ( $output =~ /(?i)Firmware Version:(.*)/g ) {
$IDs{'fw_version'} = $1;
$IDs{'fw_version'} =~ s/^\s+|\s+$//g;
}
# mainly HP drives
while ( $output =~ /(?i)Vendor:(.*)/g ) {
$IDs{'vendor'} = $1;
$IDs{'vendor'} =~ s/^\s+|\s+$//g;
}
# mainly HP drives
while ( $output =~ /(?i)Product:(.*)/g ) {
$IDs{'product'} = $1;
$IDs{'product'} =~ s/^\s+|\s+$//g;
}
# mainly HP drives
while ( $output =~ /(?i)Revision:(.*)/g ) {
$IDs{'revision'} = $1;
$IDs{'revision'} =~ s/^\s+|\s+$//g;
}
# figure out what to use for the max temp, if there is one
if ( $IDs{'190'} =~ /^\d+$/ ) {
$IDs{max_temp} = $IDs{'190'};
} elsif ( $IDs{'194'} =~ /^\d+$/ ) {
$IDs{max_temp} = $IDs{'194'};
}
if ( $IDs{'194'} =~ /^\d+$/ && defined( $IDs{max_temp} ) && $IDs{'194'} > $IDs{max_temp} ) {
$IDs{max_temp} = $IDs{'194'};
}
$output = `$smartctl -H $disk`;
if ( $output =~ /SMART\ overall\-health\ self\-assessment\ test\ result\:\ PASSED/ ) {
$IDs{'health_pass'} = 1;
} elsif ( $output =~ /SMART\ Health\ Status\:\ OK/ ) {
$IDs{'health_pass'} = 1;
}
if ( !$IDs{'health_pass'} ) {
$to_return->{data}{unhealthy}++;
}
} ## end else [ if ( $IDs{exit} != 0 ) ]
# only bother to save this if useSN is not being used
if ( !$useSN ) {
$to_return->{data}{disks}{$disk_id} = \%IDs;
} elsif ( $IDs{exit} == 0 && defined($disk_id) ) {
$to_return->{data}{disks}{$disk_id} = \%IDs;
}
# smartctl will in some cases exit zero when it can't pull data for cciss
# so if we get a zero exit, but no serial then it means something errored
# and the device is likely dead
if ( $IDs{exit} == 0 && !defined( $IDs{serial} ) ) {
$to_return->{data}{unhealthy}++;
}
} ## end foreach my $line (@disks)
my $toReturn = $json->encode($to_return);
if ( !$opts{p} ) {
$toReturn = $toReturn . "\n";
}
if ( $opts{Z} ) {
my $toReturnCompressed;
gzip \$toReturn => \$toReturnCompressed;
my $compressed = encode_base64($toReturnCompressed);
$compressed =~ s/\n//g;
$compressed = $compressed . "\n";
if ( length($compressed) < length($toReturn) ) {
$toReturn = $compressed;
}
} ## end if ( $opts{Z} )
if ( !$noWrite ) {
open( my $writefh, ">", $cache ) or die "Can't open '" . $cache . "'";
print $writefh $toReturn;
close($writefh);
} else {
print $toReturn;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,45 @@
#!/bin/sh
################################################################
# Instructions: #
# 1. copy this script to /etc/snmp/ and make it executable: #
# chmod +x ups-nut.sh #
# 2. make sure UPS_NAME below matches the name of your UPS #
# 3. edit your snmpd.conf to include this line: #
# extend ups-nut /etc/snmp/ups-nut.sh #
# 4. restart snmpd on the host #
# 5. activate the app for the desired host in LibreNMS #
################################################################
UPS_NAME="${1:-APCUPS}"
PATH=$PATH:/usr/bin:/bin
TMP=$(upsc $UPS_NAME 2>/dev/null)
for value in "battery\.charge: [0-9.]+" "battery\.(runtime\.)?low: [0-9]+" "battery\.runtime: [0-9]+" "battery\.voltage: [0-9.]+" "battery\.voltage\.nominal: [0-9]+" "input\.voltage\.nominal: [0-9.]+" "input\.voltage: [0-9.]+" "ups\.load: [0-9.]+"
do
OUT=$(echo "$TMP" | grep -Eo "$value" | awk '{print $2}' | LANG=C sort | head -n 1)
if [ -n "$OUT" ]; then
echo "$OUT"
else
echo "Unknown"
fi
done
for value in "ups\.status:[A-Z ]{0,}OL" "ups\.status:[A-Z ]{0,}OB" "ups\.status:[A-Z ]{0,}LB" "ups\.status:[A-Z ]{0,}HB" "ups\.status:[A-Z ]{0,}RB" "ups\.status:[A-Z ]{0,}CHRG" "ups\.status:[A-Z ]{0,}DISCHRG" "ups\.status:[A-Z ]{0,}BYPASS" "ups\.status:[A-Z ]{0,}CAL" "ups\.status:[A-Z ]{0,}OFF" "ups\.status:[A-Z ]{0,}OVER" "ups\.status:[A-Z ]{0,}TRIM" "ups\.status:[A-Z ]{0,}BOOST" "ups\.status:[A-Z ]{0,}FSD" "ups\.alarm:[A-Z ]"
do
UNKNOWN=$(echo "$TMP" | grep -Eo "ups\.status:")
if [ -z "$UNKNOWN" ]; then
echo "Unknown"
else
OUT=$(echo "$TMP" | grep -Eo "$value")
if [ -n "$OUT" ]; then
echo "1"
else
echo "0"
fi
fi
done
UPSTEMP="ups\.temperature: [0-9.]+"
OUT=$(echo "$TMP" | grep -Eo "$UPSTEMP" | awk '{print $2}' | LANG=C sort | head -n 1)
[ -n "$OUT" ] && echo "$OUT" || echo "Unknown"

View File

@@ -0,0 +1,46 @@
#
# Known Element Enterprises Customized Config File
# auditd
# Initial version 2025-06-27
#
local_events = yes
write_logs = yes
log_file = /var/log/audit/audit.log
log_group = adm
log_format = ENRICHED
flush = INCREMENTAL_ASYNC
freq = 50
max_log_file = 8
num_logs = 5
priority_boost = 4
name_format = NONE
max_log_file_action = keep_logs
space_left = 75
space_left_action = email
action_mail_acct = root
admin_space_left_action = halt
disk_full_action = SUSPEND
disk_error_action = SUSPEND
admin_space_left = 50
verify_email = yes
use_libwrap = yes
tcp_listen_queue = 5
tcp_max_per_addr = 1
tcp_client_max_idle = 0
transport = TCP
distribute_network = no
q_depth = 2000
overflow_action = SYSLOG
max_restarts = 10
plugin_dir = /etc/audit/plugins.d
end_of_event_timeout = 2
##tcp_client_ports = 1024-65535
##tcp_listen_port = 60
##krb5_key_file = /etc/audit/audit.key
krb5_principal = auditd
##name = mydomain

View File

@@ -0,0 +1,5 @@
This system is the property of Known Element Enterprises LLC.
Authorized uses only. All activity may be monitored and reported.
All activities subject to monitoring/recording/review in real time and/or at a later time.

View File

@@ -0,0 +1,5 @@
This system is the property of Known Element Enterprises LLC.
Authorized uses only. All activity may be monitored and reported.
All activities subject to monitoring/recording/review in real time and/or at a later time.

View File

@@ -0,0 +1,5 @@
This system is the property of Known Element Enterprises LLC.
Authorized uses only. All activity may be monitored and reported.
All activities subject to monitoring/recording/review in real time and/or at a later time.

View File

@@ -0,0 +1,23 @@
# see "man logrotate" for details
# global options do not affect preceding include directives
# rotate log files weekly
weekly
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create 0640 root utmp
# use date as a suffix of the rotated file
#dateext
# uncomment this if you want your log files compressed
#compress
# packages drop log rotation information into this directory
include /etc/logrotate.d
# system-specific logs may also be configured here.

View File

@@ -0,0 +1 @@
install cramfs /bin/true

View File

@@ -0,0 +1 @@
install dccp /bin/true

View File

@@ -0,0 +1 @@
install freevxfs /bin/true

View File

@@ -0,0 +1 @@
install hfs /bin/true

View File

@@ -0,0 +1 @@
install hfsplus /bin/true

View File

@@ -0,0 +1 @@
install jffs2 /bin/true

View File

@@ -0,0 +1 @@
install rds /bin/true

View File

@@ -0,0 +1 @@
install sctp /bin/true

View File

@@ -0,0 +1 @@
install squashfs /bin/true

View File

@@ -0,0 +1 @@
install tipc /bin/true

View File

@@ -0,0 +1 @@
install udf /bin/true

View File

@@ -0,0 +1 @@
install usb-storage /bin/true

View File

@@ -1,5 +1,7 @@
driftfile /var/lib/ntp/ntp.drift
leapfile /usr/share/zoneinfo/leap-seconds.list
server pfv-netboot.taile3044.ts.net
server pfv-netboot.knel.net
restrict 127.0.0.1
restrict ::1
interface ignore wildcard
interface listen 127.0.0.1

View File

@@ -0,0 +1,2 @@
# Uncomment to start SNMP subagent and enable CDP, SONMP and EDP protocol
DAEMON_ARGS="-x -c -s -e"

View File

@@ -0,0 +1 @@
Debian-snmp ALL = NOPASSWD: /bin/cat

View File

@@ -0,0 +1,46 @@
##########################################################################
# snmpd.conf
# Created by CNW on 11/3/2018 via snmpconf wizard and manual post tweaks
###########################################################################
# SECTION: Monitor Various Aspects of the Running Host
#
# disk: Check for disk space usage of a partition.
# The agent can check the amount of available disk space, and make
# sure it is above a set limit.
#
load 3 3 3
rocommunity kn3lmgmt
sysservices 76
#syslocation Rack, Room, Building, City, Country [Lat, Lon]
syslocation R4, Server Room, SITER, Pflugerville, United States
syscontact coo@turnsys.com
#NTP
extend ntp-client /usr/lib/check_mk_agent/local/ntp-client
#SMTP
extend mailq /usr/lib/check_mk_agent/local/postfix-queues
extend postfixdetailed /usr/lib/check_mk_agent/local/postfixdetailed
#OS Distribution Detection
extend distro /usr/local/bin/distro
extend osupdate /usr/lib/check_mk_agent/local/os-updates.sh
#Hardware Detection
extend manufacturer /usr/bin/sudo /usr/bin/cat /sys/devices/virtual/dmi/id/sys_vendor
extend hardware /usr/bin/sudo /usr/bin/cat /sys/devices/virtual/dmi/id/product_name
extend serial /usr/bin/sudo /usr/bin/cat /sys/devices/virtual/dmi/id/product_serial
#SMART
extend smart /usr/lib/check_mk_agent/local/smart
#Temperature
pass_persist .1.3.6.1.4.1.9.9.13.1.3 /usr/local/bin/temper-snmp
# Allow Systems Management Data Engine SNMP to connect to snmpd using SMUX
# smuxpeer .1.3.6.1.4.1.674.10892.1
# LLDP collection
master agentx

View File

@@ -18,15 +18,15 @@ syslocation SITER, Pflugerville, United States
syscontact coo@turnsys.com
#NTP
extend ntp-client /usr/local/librenms/ntp-client.sh
extend ntp-client /usr/lib/check_mk_agent/local/ntp-client
#SMTP
extend mailq /usr/local/librenms/postfix-queues
extend postfixdetailed /usr/local/librenms/postfixdetailed
extend mailq /usr/lib/check_mk_agent/local/postfix-queues
extend postfixdetailed /usr/lib/check_mk_agent/local/postfixdetailed
#OS Distribution Detection
extend distro /usr/local/bin/distro
extend osupdate /usr/local/librenms/os-updates.sh
extend osupdate /usr/lib/check_mk_agent/local/os-updates.sh
#Hardware Detection
@@ -35,3 +35,6 @@ extend serial /usr/bin/sudo /usr/bin/cat /sys/firmware/devicetree/base/serial-nu
# Allow Systems Management Data Engine SNMP to connect to snmpd using SMUX
# smuxpeer .1.3.6.1.4.1.674.10892.1
# LLDP collection
master agentx

View File

@@ -18,16 +18,18 @@ syslocation R4, Server Room, SITER, Pflugerville, United States
syscontact coo@turnsys.com
#NTP
extend ntp-client /usr/local/librenms/ntp-client.sh
extend ntp-client /usr/lib/check_mk_agent/local/ntp-client
#SMTP
extend mailq /usr/local/librenms/postfix-queues
extend postfixdetailed /usr/local/librenms/postfixdetailed
extend mailq /usr/lib/check_mk_agent/local/postfix-queues
extend postfixdetailed /usr/lib/check_mk_agent/local/postfixdetailed
#OS Distribution Detection
extend distro /usr/local/bin/distro
extend osupdate /usr/local/librenms/os-updates.sh
extend osupdate /usr/lib/check_mk_agent/local/os-updates.sh
# Socket statistics
extend ss /usr/lib/check_mk_agent/local/ss.py
#Hardware Detection
# (uncomment for x86 platforms)
@@ -35,6 +37,8 @@ extend manufacturer /usr/bin/sudo /usr/bin/cat /sys/devices/virtual/dmi/id/sys_v
extend hardware /usr/bin/sudo /usr/bin/cat /sys/devices/virtual/dmi/id/product_name
extend serial /usr/bin/sudo /usr/bin/cat /sys/devices/virtual/dmi/id/product_serial
# Allow Systems Management Data Engine SNMP to connect to snmpd using SMUX
# smuxpeer .1.3.6.1.4.1.674.10892.1
# LLDP collection
master agentx

View File

@@ -2,12 +2,19 @@ Include /etc/ssh/sshd_config.d/*.conf
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
KbdInteractiveAuthentication no
X11Forwarding yes
PrintMotd no
PasswordAuthentication no
AllowTcpForwarding no
X11Forwarding no
ChallengeResponseAuthentication no
Banner none
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
UsePAM yes
Banner /etc/issue.net
MaxAuthTries 2
MaxStartups 10:30:100
PermitRootLogin prohibit-password
ClientAliveInterval 300
ClientAliveCountMax 3
AllowUsers root localuser subodev
LoginGraceTime 60

View File

@@ -0,0 +1,31 @@
[Journal]
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=10000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48K
#ReadKMsg=yes
#Audit=no
Storage=persistent

View File

@@ -0,0 +1,57 @@
#Boilerplate and support functions
FrameworkIncludeFiles="$(ls -1 --color=none ../../../Framework-Includes/*)"
IFS=$'\n\t'
for file in ${FrameworkIncludeFiles[@]}; do
source "$file"
done
unset IFS
ProjectIncludeFiles="$(ls -1 --color=none ../../../Project-Includes/*)"
IFS=$'\n\t'
for file in ${ProjectIncludeFiles[@]}; do
source "$file"
done
unset IFS
print_info "Setting up librenms agent..."
cat ../../Agents/librenms/distro > /usr/local/bin/distro
chmod +x /usr/local/bin/distro
if [ ! -d /usr/lib/check_mk_agent ]; then
mkdir -p /usr/lib/check_mk_agent
fi
if [ ! -d /usr/lib/check_mk_agent/plugins ]; then
mkdir -p /usr/lib/check_mk_agent/plugins
fi
if [ ! -d /usr/lib/check_mk_agent/local ]; then
mkdir -p /usr/lib/check_mk_agent/local
fi
cat ../../Agents/librenms/check_mk_agent > /usr/bin/check_mk_agent
chmod +x /usr/bin/check_mk_agent
cat ../../Agents/librenms/check_mk@.service > /etc/systemd/system/check_mk@.service
cat ../../Agents/librenms/check_mk.socket > /etc/systemd/system/check_mk.socket
systemctl enable check_mk.socket
systemctl start check_mk.socket
#Modules commented out below, we will roll out on systems that use them, most of the fleet doesn't use those modules
cat ../../Agents/librenms/dmi.sh > /usr/lib/check_mk_agent/local/dmi.sh
cat ../../Agents/librenms/dpkg.sh > /usr/lib/check_mk_agent/local/dpkg.sh
#cat ../../Agents/librenms/mysql.sh > /usr/lib/check_mk_agent/local/mysql.sh
cat ../../Agents/librenms/ntp-client > /usr/lib/check_mk_agent/local/ntp-client
#cat ../../Agents/librenms/ntp-server.sh > /usr/lib/check_mk_agent/local/ntp-server.sh
cat ../../Agents/librenms/os-updates.sh > /usr/lib/check_mk_agent/local/os-updates.sh
cat ../../Agents/librenms/postfixdetailed > /usr/lib/check_mk_agent/local/postfixdetailed
cat ../../Agents/librenms/postfix-queues > /usr/lib/check_mk_agent/local/postfix-queues
#cat ../../Agents/librenms/smart.sh > /usr/lib/check_mk_agent/local/smart
#cat ../../Agents/librenms/smart.sh.config > /usr/lib/check_mk_agent/local/smart.config
chmod +x /usr/lib/check_mk_agent/local/*

View File

@@ -0,0 +1,52 @@
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
set -o functrace
export PS4='(${BASH_SOURCE}:${LINENO}): - [${SHLVL},${BASH_SUBSHELL},$?] $ '
function error_out()
{
echo "Bailing out. See above for reason...."
exit 1
}
function handle_failure() {
local lineno=$1
local fn=$2
local exitstatus=$3
local msg=$4
local lineno_fns=${0% 0}
if [[ "$lineno_fns" != "-1" ]] ; then
lineno="${lineno} ${lineno_fns}"
fi
echo "${BASH_SOURCE[0]}: Function: ${fn} Line Number : [${lineno}] Failed with status ${exitstatus}: $msg"
}
trap 'handle_failure "${BASH_LINENO[*]}" "$LINENO" "${FUNCNAME[*]:-script}" "$?" "$BASH_COMMAND"' ERR
export DL_ROOT
DL_ROOT="https://dl.knownelement.com/KNEL/FetchApply/"
# Material herein Sourced from
# https://cisofy.com/documentation/lynis/
# https://jbcsec.com/configure-linux-ssh/
# https://opensource.com/article/20/5/linux-security-lynis
# https://forum.greenbone.net/t/ssh-authentication/13536
# openvas
#lynis
#Auditd
curl --silent ${DL_ROOT}/ConfigFiles/AudidD/auditd.conf > /etc/audit/auditd.conf
# Systemd
curl --silent ${DL_ROOT}/ConfigFiles/Systemd/journald.conf > /etc/systemd/journald.conf
# logrotate
curl --silent ${DL_ROOT}/ConfigFiles/Logrotate/logrotate.conf > /etc/logrotate.conf

View File

@@ -0,0 +1,108 @@
#!/bin/bash
#Framework variables are read from hee
source $PROJECT_ROOT_PATH/Framework-ConfigFiles/FrameworkVars
#Boilerplate and support functions
for framework_include_file in ../Framework-Includes/*; do
source "$framework_include_file"
done
for project_include_file in ../Project-Includes/*; do
source "$project_include_file"
done
# Actual script logic starts here
# Sourced from
# https://complianceascode.readthedocs.io/en/latest/manual/developer/01_introduction.html
# https://github.com/ComplianceAsCode/content
# https://github.com/ComplianceAsCode
#apparmor
#enforcing
#enabled in bootloader config
#aide
#auditd
#disable auto mounting
#disable usb storage
#motd
#remote login warning banner
#Ensure time sync is working
#systemd-timesync
#ntp
#chrony
#password complexity
#password expiration warning
#password expiration time
#password hashing algo
#fix grub perms
if [ "$IS_RASPI" = 0 ] ; then
chown root:root /boot/grub/grub.cfg
chmod og-rwx /boot/grub/grub.cfg
chmod 0400 /boot/grub/grub.cfg
fi
#disable auto mounting
systemctl --now disable autofs || true
apt-get -y --purge remove autofs || true
#disable usb storage
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/usb_storage.conf > /etc/modprobe.d/usb_storage.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/dccp.conf > /etc/modprobe.d/dccp.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/rds.conf > /etc/modprobe.d/rds.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/sctp.conf > /etc/modprobe.d/sctp.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/tipc.conf > /etc/modprobe.d/tipc.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/cramfs.conf > /etc/modprobe.d/cramfs.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/freevxfs.conf > /etc/modprobe.d/freevxfs.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/hfs.conf > /etc/modprobe.d/hfs.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/hfsplus.conf > /etc/modprobe.d/hfsplus.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/jffs2.conf > /etc/modprobe.d/jffs2.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/squashfs.conf > /etc/modprobe.d/squashfs.conf
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ModProbe/udf.conf > /etc/modprobe.d/udf.conf
#banners
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/BANNERS/issue > /etc/issue
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/BANNERS/issue.net > /etc/issue.net
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/BANNERS/motd > /etc/motd
#Cron perms
if [ -f /etc/cron.deny ]; then
rm /etc/cron.deny || true
fi
touch /etc/cron.allow
chmod g-wx,o-rwx /etc/cron.allow
chown root:root /etc/cron.allow
chmod og-rwx /etc/crontab
chmod og-rwx /etc/cron.hourly/
chmod og-rwx /etc/cron.daily/
chmod og-rwx /etc/cron.weekly/
chmod og-rwx /etc/cron.monthly/
chown root:root /etc/cron.d/
chmod og-rwx /etc/cron.d/
# At perms
rm -f /etc/at.deny || true
touch /etc/at.allow
chmod g-wx,o-rwx /etc/at.allow
chown root:root /etc/at.allow

View File

@@ -0,0 +1,74 @@
#!/bin/bash
for framework_include_file in ../../../Framework-Includes/*; do
source "$framework_include_file"
done
for project_include_file in ../../../Project-Includes/*; do
source "$project_include_file"
done
export SUBODEV_CHECK
SUBODEV_CHECK="$(getent passwd | grep -c subodev || true)"
export LOCALUSER_CHECK
LOCALUSER_CHECK="$(getent passwd | grep -c localuser || true)"
export ROOT_SSH_DIR
ROOT_SSH_DIR="/root/.ssh"
export LOCALUSER_SSH_DIR
LOCALUSER_SSH_DIR="/home/localuser/.ssh"
export SUBODEV_SSH_DIR
SUBODEV_SSH_DIR="/home/subodev/.ssh"
if [ ! -d $ROOT_SSH_DIR ]; then
mkdir /root/.ssh/
fi
curl --silent "${DL_ROOT}"/ProjectCode/ConfigFiles/SSH/AuthorizedKeys/root-ssh-authorized-keys >/root/.ssh/authorized_keys
chmod 400 /root/.ssh/authorized_keys
chown root: /root/.ssh/authorized_keys
if [ "$LOCALUSER_CHECK" -gt 0 ]; then
if [ ! -d $LOCALUSER_SSH_DIR ]; then
mkdir -p /home/localuser/.ssh/
fi
curl --silent "${DL_ROOT}"/ProjectCode/ConfigFiles/SSH/AuthorizedKeys/localuser-ssh-authorized-keys >/home/localuser/.ssh/authorized_keys &&
chown localuser /home/localuser/.ssh/authorized_keys &&
chmod 400 /home/localuser/.ssh/authorized_keys
fi
if [ "$SUBODEV_CHECK" = 1 ]; then
if [ ! -d $SUBODEV_SSH_DIR ]; then
mkdir /home/subodev/.ssh/
fi
curl --silent "${DL_ROOT}"/ProjectCode/ConfigFiles/SSH/AuthorizedKeys/localuser-ssh-authorized-keys >/home/subodev/.ssh/authorized_keys &&
chmod 400 /home/subodev/.ssh/authorized_keys &&
chown subodev: /home/subodev/.ssh/authorized_keys
fi
cat ../../ConfigFiles/SSH/Configs/tsys-sshd-config >/etc/ssh/sshd_config
#Don't deploy this config to a ubuntu server, it breaks openssh server. Works on kali/debian.
export UBUNTU_CHECK
UBUNTU_CHECK="$(distro | grep -c Ubuntu||true)"
if [ "$UBUNTU_CHECK" -ne 1 ]; then
cat ../../ConfigFiles/SSH/Configs/ssh-audit-hardening.conf >/etc/ssh/sshd_config.d/ssh-audit_hardening.conf
chmod og-rwx /etc/ssh/sshd_config.d/*
fi
# Perms on sshd_config
chmod og-rwx /etc/ssh/sshd_config
#todo
# only strong MAC algos are used

View File

@@ -0,0 +1,27 @@
#!/bin/bash
# We don't want to run this on the wazuh server, otherwise bad things happen...
export TSYS_NSM_CHECK
TSYS_NSM_CHECK="$(hostname |grep -c tsys-nsm ||true)"
if [ "$TSYS_NSM_CHECK" -eq 0 ]; then
if [ -f /usr/share/keyrings/wazuh.gpg ]; then
rm -f /usr/share/keyrings/wazuh.gpg
fi
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import
chmod 644 /usr/share/keyrings/wazuh.gpg
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" > /etc/apt/sources.list.d/wazuh.list
apt-get update
WAZUH_MANAGER="tsys-nsm.knel.net" apt-get -y install wazuh-agent
systemctl daemon-reload
systemctl enable wazuh-agent
systemctl start wazuh-agent
echo "wazuh-agent hold" | dpkg --set-selections
fi

View File

@@ -0,0 +1,399 @@
#!/usr/bin/bash
#####
#Core framework functions...
#####
export PROJECT_ROOT_PATH
PROJECT_ROOT_PATH="$(realpath ../)"
#Framework variables are read from hee
source $PROJECT_ROOT_PATH/Framework-ConfigFiles/FrameworkVars
for framework_include_file in ../Framework-Includes/*; do
source "$framework_include_file"
done
for project_include_file in ../Project-Includes/*; do
source "$project_include_file"
done
# Start actual script logic here...
#################
#Global variables
#################
apt-get -y install git sudo dmidecode curl
export IS_PHYSICAL_HOST
IS_PHYSICAL_HOST="$(/usr/sbin/dmidecode -t System | grep -c Dell || true)"
export SUBODEV_CHECK
SUBODEV_CHECK="$(getent passwd | grep -c subodev || true)"
export LOCALUSER_CHECK
LOCALUSER_CHECK="$(getent passwd | grep -c localuser || true)"
export DL_ROOT
DL_ROOT="https://dl.knownelement.com/KNEL/FetchApply/"
#######################
# Support functions
#######################
function global-oam() {
print_info "Now running "$FUNCNAME"...."
cat ./scripts/up2date.sh >/usr/local/bin/up2date.sh && chmod +x /usr/local/bin/up2date.sh
cd Modules/OAM || exit
bash ./oam-librenms.sh
cd - || exit
print_info "Completed running "$FUNCNAME""
}
function global-systemServiceConfigurationFiles() {
print_info "Now running" $FUNCNAME....""
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/ZSH/tsys-zshrc >/etc/zshrc
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/SMTP/aliases >/etc/aliases
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/Syslog/rsyslog.conf >/etc/rsyslog.conf
newaliases
print_info "Completed running "$FUNCNAME""
}
function global-installPackages() {
print_info "Now running "$FUNCNAME"...."""
# Setup webmin repo, used for RBAC/2fa PAM
curl https://raw.githubusercontent.com/webmin/webmin/master/webmin-setup-repo.sh >/tmp/webmin-setup.sh
sh /tmp/webmin-setup.sh -f && rm -f /tmp/webmin-setup.sh
# Setup lynis repo, used for sec ops/compliance
if [ -f /etc/apt/trusted.gpg.d/cisofy-software-public.gpg ]; then
rm -f /etc/apt/trusted.gpg.d/cisofy-software-public.gpg
fi
curl -fsSL https://packages.cisofy.com/keys/cisofy-software-public.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/cisofy-software-public.gpg
echo "deb [arch=amd64,arm64 signed-by=/etc/apt/trusted.gpg.d/cisofy-software-public.gpg] https://packages.cisofy.com/community/lynis/deb/ stable main" | sudo tee /etc/apt/sources.list.d/cisofy-lynis.list
# Setup tailscale
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
#
#Patch the system
#
/usr/local/bin/up2date.sh
#Remove stuff we don't want
export UBUNTU_CHECK
UBUNTU_CHECK="$(distro | grep -c Ubuntu || true)"
if [ "$UBUNTU_CHECK" -eq 1 ]; then
apt-get --yes --purge remove chrony telnet inetutils-telnet
fi
if [ "$UBUNTU_CHECK" -eq 0 ]; then
apt-get --yes --purge remove systemd-timesyncd chrony telnet inetutils-telnet
fi
#export DEBIAN_FRONTEND="noninteractive" && apt-get -qq --yes -o Dpkg::Options::="--force-confold" --purge remove nano
# add stuff we want
print_info ""Now installing all the packages...""
DEBIAN_FRONTEND="noninteractive" apt-get -qq --yes -o Dpkg::Options::="--force-confold" install \
virt-what \
auditd \
audispd-plugins \
cloud-guest-utils \
aide \
htop \
snmpd \
ncdu \
iftop \
iotop \
latencytop \
cockpit \
cockpit-bridge \
cockpit-doc \
cockpit-networkmanager \
cockpit-packagekit \
cockpit-pcp \
cockpit-sosreport \
cockpit-storaged \
cockpit-system \
cockpit-tests \
cockpit-ws \
nethogs \
sysstat \
ngrep \
acct \
lsb-release \
screen \
tailscale \
tmux \
vim \
command-not-found \
lldpd \
net-tools \
dos2unix \
gpg \
molly-guard \
lshw \
fzf \
ripgrep \
sudo \
mailutils \
clamav \
sl \
logwatch \
git \
net-tools \
tshark \
tcpdump \
lynis \
glances \
zsh \
zsh-autosuggestions \
zsh-syntax-highlighting \
fonts-powerline \
webmin \
usermin \
ntpsec \
ntpsec-ntpdate \
tuned \
cockpit \
iptables \
netfilter-persistent \
iptables-persistent \
pflogsumm \
postfix
export KALI_CHECK
KALI_CHECK="$(distro | grep -c kali || true)"
export VIRT_TYPE
VIRT_TYPE="$(virt-what)"
export IS_VIRT_GUEST
IS_VIRT_GUEST="$(echo "$VIRT_TYPE" | egrep -c 'hyperv|kvm' || true)"
export IS_KVM_GUEST
IS_KVM_GUEST="$(echo "$VIRT_TYPE" | grep -c 'kvm' || true)"
if [[ $IS_KVM_GUEST = 1 ]]; then
apt -y install qemu-guest-agent
fi
if [[ $IS_PHYSICAL_HOST -gt 0 ]]; then
export DEBIAN_FRONTEND="noninteractive" && apt-get -qq --yes -o Dpkg::Options::="--force-confold" install \
i7z \
thermald \
cpufrequtils \
linux-cpupower
# power-profiles-daemon
fi
print_info "Completed running "$FUNCNAME""
}
function global-postPackageConfiguration() {
print_info "Now running "$FUNCNAME""
systemctl --now enable auditd
systemctl stop postfix
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/SMTP/postfix_generic >/etc/postfix/generic
postmap /etc/postfix/generic
postconf -e "inet_protocols = ipv4"
postconf -e "inet_interfaces = 127.0.0.1"
postconf -e "mydestination= 127.0.0.1"
postconf -e "relayhost = tsys-cloudron.knel.net"
postconf -e "smtp_generic_maps = hash:/etc/postfix/generic"
# smtp_generic_maps = hash:/etc/postfix/generic
systemctl restart postfix
#This is under test/dev and may fail
echo "hi from root to root" | mail -s "hi directly to root from $(hostname)" root
chsh -s $(which zsh) root
if [ "$LOCALUSER_CHECK" -gt 0 ]; then
chsh -s "$(which zsh)" localuser
fi
if [ "$SUBODEV_CHECK" -gt 0 ]; then
chsh -s "$(which zsh)" subodev
fi
###Post package deployment bits
curl --silent ${DL_ROOT}/ProjectCode/ConfigFiles/DHCP/dhclient.conf >/etc/dhcp/dhclient.conf
systemctl stop snmpd && /etc/init.d/snmpd stop
cat ./ConfigFiles/SNMP/snmp-sudo.conf >/etc/sudoers.d/Debian-snmp
sed -i "s|-Lsd|-LS6d|" /lib/systemd/system/snmpd.service
pi-detect
if [ "$IS_RASPI" = 1 ]; then
cat ./ConfigFiles/SNMP/snmpd-rpi.conf >/etc/snmp/snmpd.conf || true
fi
if [ "$IS_PHYSICAL_HOST" = 1 ]; then
cat ./ConfigFiles/SNMP/snmpd-physicalhost.conf >/etc/snmp/snmpd.conf || true
fi
if [ "$IS_VIRT_GUEST" = 1 ]; then
cat ./ConfigFiles/SNMP/snmpd.conf >/etc/snmp/snmpd.conf || true
fi
systemctl daemon-reload && systemctl restart snmpd && /etc/init.d/snmpd restart
cat ./ConfigFiles/NetworkDiscovery/lldpd >/etc/default/lldpd
systemctl restart lldpd
export LIBRENMS_CHECK
LIBRENMS_CHECK="$(hostname | grep -c tsys-librenms || true)"
if [ "$LIBRENMS_CHECK" -eq 0 ]; then
DEBIAN_FRONTEND="noninteractive" apt-get -qq --yes -o Dpkg::Options::="--force-confold" install rsyslog
systemctl stop rsyslog
systemctl start rsyslog
fi
export NTP_SERVER_CHECK
NTP_SERVER_CHECK="$(hostname | egrep -c 'pfv-netboot|pfvsvrpi' || true)"
if [ "$NTP_SERVER_CHECK" -eq 0 ]; then
cat ./ConfigFiles/NTP/ntp.conf >/etc/ntpsec/ntp.conf
systemctl restart ntpsec.service
fi
systemctl stop postfix
systemctl start postfix
/usr/sbin/accton on
if [ "$IS_PHYSICAL_HOST" -gt 0 ]; then
cpufreq-set -r -g performance
cpupower frequency-set --governor performance
# Potentially merge the below if needed.
# power-profiles-daemon
# powerprofilesctl set performance
#tsys1# systemctl enable power-profiles-daemon
#tsys1# systemctl start power-profiles-daemon
fi
if [ "$IS_VIRT_GUEST" = 1 ]; then
tuned-adm profile virtual-guest
fi
print_info "Completed running "$FUNCNAME""
}
####################################################################################################
# Run various modules
####################################################################################################
####################################################################################################
# Security Hardening
####################################################################################################
# SSH
function secharden-ssh() {
print_info "Now running "$FUNCNAME""
cd ./Modules/Security
bash ./secharden-ssh.sh
cd -
print_info "Completed running "$FUNCNAME""
}
function secharden-wazuh() {
print_info "Now running "$FUNCNAME""
bash ./Modules/Security/secharden-wazuh.sh
print_info "Completed running "$FUNCNAME""
}
function secharden-auto-upgrades() {
print_info "Now running "$FUNCNAME""
#curl --silent ${DL_ROOT}/Modules/Security/secharden-ssh.sh|$(which bash)
print_info "Completed running "$FUNCNAME""
}
function secharden-2fa() {
print_info "Now running "$FUNCNAME""
#curl --silent ${DL_ROOT}/Modules/Security/secharden-2fa.sh|$(which bash)
print_info "Completed running "$FUNCNAME""
}
function secharden-agents() {
print_info "Now running "$FUNCNAME""
#curl --silent ${DL_ROOT}/Modules/Security/secharden-audit-agents.sh|$(which bash)
print_info "Completed running "$FUNCNAME""
}
function secharden-scap-stig() {
print_info "Now running "$FUNCNAME""
bash ./Modules/Security/secharden-scap-stig.sh
print_info "Completed running "$FUNCNAME""
}
####################################################################################################
# Authentication
####################################################################################################
function auth-cloudron-ldap() {
print_info "Now running "$FUNCNAME""
#curl --silent ${DL_ROOT}/Modules/Auth/auth-cloudron-ldap.sh|$(which bash)
print_info "Completed running "$FUNCNAME""
}
####################################################################################################
# RUn the various functions in the correct order
####################################################################################################
echo >$LOGFILENAME
print_info "Execution starting at $CURRENT_TIMESTAMP..."
PreflightCheck
global-oam
global-installPackages
global-systemServiceConfigurationFiles
global-postPackageConfiguration
secharden-ssh
secharden-wazuh
secharden-scap-stig
#secharden-agents
#secharden-auto-upgrades
#secharden-2fa
#auth-cloudron-ldap
print_info "Execution ended at $CURRENT_TIMESTAMP..."

View File

@@ -1,462 +0,0 @@
#!/usr/bin/bash
# Standard strict mode and error handling boilderplate...
set -e
set -o pipefail
set -o functrace
# Start actual script logic here...
#################
#Global variables
#################
export SUBODEV_CHECK
SUBODEV_CHECK="$(getent passwd|grep -c subodev || true)"
export LOCALUSER_CHECK
LOCALUSER_CHECK="$(getent passwd|grep -c localuser || true)"
export DL_ROOT
DL_ROOT="https://dl.knownelement.com/KNEL/FetchApply/"
#######################
# Support functions
#######################
function error_out()
{
echo "Bailing out. See above for reason...."
exit 1
}
function handle_failure() {
local lineno=$1
local fn=$2
local exitstatus=$3
local msg=$4
local lineno_fns=${0% 0}
if [[ "$lineno_fns" != "-1" ]] ; then
lineno="${lineno} ${lineno_fns}"
fi
echo "${BASH_SOURCE[0]}: Function: ${fn} Line Number : [${lineno}] Failed with status ${exitstatus}: $msg"
}
trap 'handle_failure "${BASH_LINENO[*]}" "$LINENO" "${FUNCNAME[*]:-script}" "$?" "$BASH_COMMAND"' ERR
function PreflightCheck()
{
export curr_user="$USER"
export user_check
user_check="$(echo "$curr_user" | grep -c root)"
if [ $user_check -ne 1 ]; then
echo "Must run as root."
error_out
fi
#Your additional stuff here...
echo "All checks passed...."
}
function pi-detect()
{
echo Now running "$FUNCNAME"....
if [ -f /sys/firmware/devicetree/base/model ] ; then
export IS_RASPI="1"
fi
if [ ! -f /sys/firmware/devicetree/base/model ] ; then
export IS_RASPI="0"
fi
echo Completed running "$FUNCNAME"
}
function global-oam()
{
echo Now running "$FUNCNAME"....
curl --silent ${DL_ROOT}/scripts/distro > /usr/local/bin/distro && chmod +x /usr/local/bin/distro
curl --silent ${DL_ROOT}/scripts/up2date.sh > /usr/local/bin/up2date.sh && chmod +x /usr/local/bin/up2date.sh
echo "Setting up librenms agent..."
rm -rf /usr/local/librenms-agent || true
curl --silent ${DL_ROOT}/Agents/librenms.tar.gz > /usr/local/librenms.tar.gz
cd /usr/local && tar xfz librenms.tar.gz && rm -f /usr/local/librenms.tar.gz
echo Completed running "$FUNCNAME"
}
function global-systemServiceConfigurationFiles()
{
echo Now running "$FUNCNAME"....
curl --silent ${DL_ROOT}/ConfigFiles/ZSH/tsys-zshrc > /etc/zshrc
curl --silent ${DL_ROOT}/ConfigFiles/SMTP/aliases > /etc/aliases
curl --silent ${DL_ROOT}/ConfigFiles/Syslog/rsyslog.conf > /etc/rsyslog.conf
curl --silent ${DL_ROOT}/ConfigFiles/SSH/Configs/tsys-sshd-config > /etc/ssh/sshd_config
curl --silent ${DL_ROOT}/ConfigFiles/SSH/Configs/ssh-audit_hardening.conf > /etc/ssh/sshd_config.d/ssh-audit_hardening.conf
export ROOT_SSH_DIR="/root/.ssh"
export LOCALUSER_SSH_DIR="/home/localuser/.ssh"
export SUBODEV_SSH_DIR="/home/subodev/.ssh"
if [ ! -d $ROOT_SSH_DIR ]; then
mkdir /root/.ssh/
fi
curl --silent ${DL_ROOT}/ConfigFiles/SSH/AuthorizedKeys/root-ssh-authorized-keys > /root/.ssh/authorized_keys
chmod 400 /root/.ssh/authorized_keys
chown root: /root/.ssh/authorized_keys
if [ "$LOCALUSER_CHECK" = 1 ]; then
if [ ! -d $LOCALUSER_SSH_DIR ]; then
mkdir -p /home/localuser/.ssh/
fi
curl --silent ${DL_ROOT}/ConfigFiles/SSH/AuthorizedKeys/localuser-ssh-authorized-keys > /home/localuser/.ssh/authorized_keys \
&& chown localuser /home/localuser/.ssh/authorized_keys \
&& chmod 400 /home/localuser/.ssh/authorized_keys
fi
if [ "$SUBODEV_CHECK" = 1 ]; then
if [ ! -d $SUBODEV_SSH_DIR ]; then
mkdir /home/subodev/.ssh/
fi
curl --silent ${DL_ROOT}/ConfigFiles/SSH/AuthorizedKeys/localuser-ssh-authorized-keys > /home/subodev/.ssh/authorized_keys \
&& chmod 400 /home/subodev/.ssh/authorized_keys \
&& chown subodev: /home/subodev/.ssh/authorized_keys
fi
newaliases
echo Completed running "$FUNCNAME"
}
function global-installPackages()
{
echo Now running "$FUNCNAME"....
# Setup webmin repo, used for RBAC/2fa PAM
curl https://raw.githubusercontent.com/webmin/webmin/master/webmin-setup-repo.sh > /tmp/webmin-setup.sh
sh /tmp/webmin-setup.sh -f && rm -f /tmp/webmin-setup.sh
# Setup lynis repo, used for sec ops/compliance
echo "deb https://packages.cisofy.com/community/lynis/deb/ stable main" > /etc/apt/sources.list.d/cisofy-lynis.list
curl --silent --insecure -s https://packages.cisofy.com/keys/cisofy-software-public.key | apt-key add -
# Setup tailscale
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
#
#Patch the system
#
/usr/local/bin/up2date.sh
#Remove stuff we don't want
#export DEBIAN_FRONTEND="noninteractive" && apt-get -qq --yes -o Dpkg::Options::="--force-confold" --purge remove nano
# add stuff we want
echo "Now installing all the packages..."
DEBIAN_FRONTEND="noninteractive" apt-get -qq --yes -o Dpkg::Options::="--force-confold" install \
virt-what \
htop \
dstat \
snmpd \
ncdu \
iftop \
acct \
nethogs \
sysstat \
ngrep \
lsb-release \
screen \
tailscale \
tmux \
vim \
command-not-found \
lldpd \
net-tools \
dos2unix \
gpg \
molly-guard \
fail2ban \
lshw \
sudo \
mailutils \
clamav \
sl \
rsyslog \
logwatch \
git \
rsync \
net-tools \
tshark \
tcpdump \
lynis \
glances \
zsh \
zsh-autosuggestions \
zsh-syntax-highlighting \
fonts-powerline \
webmin \
usermin \
iotop \
tuned \
cockpit \
iptables \
netfilter-persistent \
iptables-persistent \
postfix \
telnet
export KALI_CHECK
KALI_CHECK="$(distro |grep -c kali ||true)"
if [ "$KALI_CHECK" = 0 ]; then
export DEBIAN_FRONTEND="noninteractive" ; apt-get -qq --yes -o Dpkg::Options::="--force-confold" install \
ntpdate \
ntp
fi
if [ "$KALI_CHECK" = 1 ]; then
export DEBIAN_FRONTEND="noninteractive" ; apt-get -qq --yes -o Dpkg::Options::="--force-confold" install \
ntpsec-ntpdate \
ntpsec
fi
export VIRT_TYPE
VIRT_TYPE="$(virt-what)"
export VIRT_GUEST
VIRT_GUEST="$(echo "$VIRT_TYPE"|egrep 'hyperv|kvm' ||true )"
export KVM_GUEST
KVM_GUEST="$(echo "$VIRT_TYPE"|grep 'kvm' || true)"
if [[ $KVM_GUEST = 1 ]]; then
apt -y install qemu-guest-agent
fi
export PHYSICAL_HOST
PHYSICAL_HOST="$(dmidecode -t System|grep -c Dell ||true)"
if [[ $PHYSICAL_HOST -gt 0 ]]; then
export DEBIAN_FRONTEND="noninteractive" && apt-get -qq --yes -o Dpkg::Options::="--force-confold" install \
i7z \
thermald \
linux-cpupower
# power-profiles-daemon
fi
echo Completed running "$FUNCNAME"
}
function global-postPackageConfiguration()
{
echo Now running "$FUNCNAME"
apt-file update
systemctl stop postfix
curl --silent ${DL_ROOT}/ConfigFiles/SMTP/postfix_generic> /etc/postfix/generic
dos2unix /etc/postfix/generic
postmap /etc/postfix/generic
postconf -e "inet_protocols = ipv4"
postconf -e "inet_interfaces = 127.0.0.1"
postconf -e "mydestination= 127.0.0.1"
postconf -e "relayhost = tsys-cloudron.knel.net"
postconf -e "smtp_generic_maps = hash:/etc/postfix/generic"
# smtp_generic_maps = hash:/etc/postfix/generic
systemctl restart postfix
#This is under test/dev and may fail
echo "hi from root to root" | mail -s "hi directly to root from $(hostname)" root
chsh -s $(which zsh) root
if [ "$LOCALUSER_CHECK" = 1 ]; then
chsh -s "$(which zsh)" localuser
fi
if [ "$SUBODEV_CHECK" = 1 ]; then
chsh -s "$(which zsh)" localuser
fi
###Post package deployment bits
curl --silent ${DL_ROOT}/ConfigFiles/DHCP/dhclient.conf > /etc/dhcp/dhclient.conf
systemctl stop snmpd && /etc/init.d/snmpd stop
curl --silent ${DL_ROOT}/ConfigFiles/SNMP/snmp-sudo.conf > /etc/sudoers.d/Debian-snmp
sed -i "s|-Lsd|-LS6d|" /lib/systemd/system/snmpd.service
pi-detect
if [ $IS_RASPI = 1 ] ; then
curl --silent ${DL_ROOT}/ConfigFiles/SNMP/snmpd-rpi.conf > /etc/snmp/snmpd.conf
fi
if [ $IS_RASPI != 1 ] ; then
curl --silent ${DL_ROOT}/ConfigFiles/SNMP/snmpd.conf > /etc/snmp/snmpd.conf
fi
systemctl daemon-reload && systemctl restart snmpd && /etc/init.d/snmpd restart
systemctl stop rsyslog
systemctl start rsyslog
logger "hi hi from $(hostname)"
if [ "$KALI_CHECK" -eq 0 ]; then
curl --silent ${DL_ROOT}/ConfigFiles/NTP/ntp.conf > /etc/ntpsec/ntp.conf
systemctl restart ntp
fi
if [ "$KALI_CHECK" -eq 1 ]; then
curl --silent ${DL_ROOT}/ConfigFiles/NTP/ntp.conf > /etc/ntp.conf
systemctl restart ntpsec.service
fi
systemctl stop postfix
systemctl start postfix
/usr/sbin/accton on
if [ $PHYSICAL_HOST -gt 0 ]; then
cpufreq-set -r -g performance
cpupower frequency-set --governor performance
# Potentially merge the below if needed.
# power-profiles-daemon
# powerprofilesctl set performance
#tsys1# systemctl enable power-profiles-daemon
#tsys1# systemctl start power-profiles-daemon
fi
if [ "$VIRT_GUEST" = 1 ]; then
tuned-adm profile virtual-guest
fi
echo Completed running "$FUNCNAME"
}
####################################################################################################
# Run various modules
####################################################################################################
####################################################################################################
# Security Hardening
####################################################################################################
# SSH
function secharden-ssh()
{
echo Now running "$FUNCNAME"
curl --silent ${DL_ROOT}/Modules/Security/secharden-ssh.sh|$(which bash)
echo Completed running "$FUNCNAME"
}
function secharden-wazuh()
{
echo Now running "$FUNCNAME"
curl --silent ${DL_ROOT}/Modules/Security/secharden-wazuh.sh|$(which bash)
echo Completed running "$FUNCNAME"
}
function secharden-auto-upgrades()
{
echo Now running "$FUNCNAME"
#curl --silent ${DL_ROOT}/Modules/Security/secharden-ssh.sh|$(which bash)
echo Completed running "$FUNCNAME"
}
function secharden-2fa()
{
echo Now running "$FUNCNAME"
#curl --silent ${DL_ROOT}/Modules/Security/secharden-2fa.sh|$(which bash)
echo Completed running "$FUNCNAME"
}
function secharden-audit-agents()
{
echo Now running "$FUNCNAME"
#curl --silent ${DL_ROOT}/Modules/Security/secharden-audit-agents.sh|$(which bash)
echo Completed running "$FUNCNAME"
}
function secharden-scap-stig()
{
echo Now running "$FUNCNAME"
#curl --silent ${DL_ROOT}/Modules/Security/secharden-scap-stig.sh|$(which bash)
echo Completed running "$FUNCNAME"
}
####################################################################################################
# Authentication
####################################################################################################
function auth-cloudron-ldap()
{
echo Now running "$FUNCNAME"
#curl --silent ${DL_ROOT}/Modules/Auth/auth-cloudron-ldap.sh|$(which bash)
echo Completed running "$FUNCNAME"
}
####################################################################################################
# RUn the various functions in the correct order
####################################################################################################
PreflightCheck
global-oam
global-installPackages
global-systemServiceConfigurationFiles
global-postPackageConfiguration
secharden-ssh
secharden-wazuh
#secharden-2fa
#secharden-auto-upgrades
#secharden-audit-agents
#secharden-scap-stig
#auth-cloudron-ldap

View File

@@ -1,25 +0,0 @@
#!/usr/bin/env bash
################################################################
# copy this script to somewhere like /opt and make chmod +x it #
# edit your snmpd.conf and include #
# extend ntp-client /opt/ntp-client.sh #
# restart snmpd and activate the app for desired host #
# please make sure you have the path/binaries below #
################################################################
# Binaries and paths required #
################################################################
BIN_NTPQ="$(command -v ntpq)"
BIN_GREP="$(command -v grep)"
BIN_TR="$(command -v tr)"
BIN_CUT="$(command -v cut)"
################################################################
# Don't change anything unless you know what are you doing #
################################################################
CMD1=`$BIN_NTPQ -c rv | $BIN_GREP 'jitter' | $BIN_TR '\n' ' '`
IFS=', ' read -r -a array <<< "$CMD1"
for value in 2 3 4 5 6
do
echo ${array["$value"]} | $BIN_CUT -d "=" -f 2
done

View File

@@ -1,363 +0,0 @@
#!/usr/bin/env perl
#Copyright (c) 2017, Zane C. Bowers-Hadley
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without modification,
#are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
#INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
#THE POSSIBILITY OF SUCH DAMAGE.
=for comment
Add this to snmpd.conf like below.
extend smart /etc/snmp/smart
Then add to root's cron tab, if you have more than a few disks.
*/3 * * * * /etc/snmp/smart -u
You will also need to create the config file, which defaults to the same path as the script,
but with .config appended. So if the script is located at /etc/snmp/smart, the config file
will be /etc/snmp/smart.config. Alternatively you can also specific a config via -c.
Anything starting with a # is comment. The format for variables is $variable=$value. Empty
lines are ignored. Spaces and tabes at either the start or end of a line are ignored. Any
line with out a = or # are treated as a disk.
#This is a comment
cache=/var/cache/smart
smartctl=/usr/local/sbin/smartctl
useSN=0
ada0
ada1
The variables are as below.
cache = The path to the cache file to use. Default: /var/cache/smart
smartctl = The path to use for smartctl. Default: /usr/bin/env smartctl
useSN = If set to 1, it will use the disks SN for reporting instead of the device name.
1 is the default. 0 will use the device name.
If you want to guess at the configuration, call it with -g and it will print out what it thinks
it should be.
=cut
##
## You should not need to touch anything below here.
##
use warnings;
use strict;
use Getopt::Std;
my $cache='/var/cache/smart';
my $smartctl='/usr/bin/env smartctl';
my @disks;
my $useSN=1;
$Getopt::Std::STANDARD_HELP_VERSION = 1;
sub main::VERSION_MESSAGE {
print "SMART SNMP extend 0.0.0\n";
};
sub main::HELP_MESSAGE {
print "\n".
"-u Update '".$cache."'\n".
"-g Guess at the config and print it to STDOUT.\n".
"-c <config> The config file to use.\n";
}
#gets the options
my %opts=();
getopts('ugc:', \%opts);
# guess if asked
if ( defined( $opts{g} ) ){
#get what path to use for smartctl
$smartctl=`which smartctl`;
chomp($smartctl);
if ( $? != 0 ){
warn("'which smartctl' failed with a exit code of $?");
exit 1;
}
#try to touch the default cache location and warn if it can't be done
system('touch '.$cache.'>/dev/null');
if ( $? != 0 ){
$cache='#Could not touch '.$cache. "You will need to manually set it\n".
"cache=?\n";
}else{
$cache='cache='.$cache."\n";
}
my %found_disks;
#check for drives named /dev/sd*
my @matches=glob('/dev/sd*');
@matches=grep(!/[0-9]/, @matches);
my $matches_int=0;
while ( defined( $matches[$matches_int] ) ){
my $device=$matches[$matches_int];
system( $smartctl.' -A '.$device.' > /dev/null' );
if ( $? == 0 ){
$device =~ s/\/dev\///;
$found_disks{$device}=1;
}
$matches_int++;
}
#check for drives named /dev/ada*
@matches=glob('/dev/ada*');
@matches=grep(!/[ps]/, @matches);
$matches_int=0;
while ( defined( $matches[$matches_int] ) ){
my $device=$matches[$matches_int];
system( $smartctl.' -A '.$device.' > /dev/null' );
if ( $? == 0 ){
$device =~ s/\/dev\///;
$found_disks{$device}=1;
}
$matches_int++;
}
#check for drives named /dev/da*
@matches=glob('/dev/da*');
@matches=grep(!/[ps]/, @matches);
$matches_int=0;
while ( defined( $matches[$matches_int] ) ){
my $device=$matches[$matches_int];
system( $smartctl.' -A '.$device.' > /dev/null' );
if ( $? == 0 ){
$device =~ s/\/dev\///;
$found_disks{$device}=1;
}
$matches_int++;
}
#have smartctl scan and see if it finds anythings not get found
my $scan_output=`$smartctl --scan-open`;
my @scan_outputA=split(/\n/, $scan_output);
@scan_outputA=grep(!/ses[0-9]/, @scan_outputA); # not a disk, but may or may not have SMART attributes
@scan_outputA=grep(!/pass[0-9]/, @scan_outputA); # very likely a duplicate and a disk under another name
$matches_int=0;
while ( defined( $scan_outputA[$matches_int] ) ){
my $device=$scan_outputA[$matches_int];
$device =~ s/ .*//;
system( $smartctl.' -A '.$device.' > /dev/null' );
if ( $? == 0 ){
$device =~ s/\/dev\///;
$found_disks{$device}=1;
}
$matches_int++;
}
print "useSN=0\n".'smartctl='.$smartctl."\n".
$cache.
join( "\n", keys(%found_disks) )."\n";
exit 0;
}
#get which config file to use
my $config=$0.'.config';
if ( defined( $opts{c} ) ){
$config=$opts{c};
}
#reads the config file, optionally
my $config_file='';
open(my $readfh, "<", $config) or die "Can't open '".$config."'";
read($readfh , $config_file , 1000000);
close($readfh);
#parse the config file and remove comments and empty lines
my @configA=split(/\n/, $config_file);
@configA=grep(!/^$/, @configA);
@configA=grep(!/^\#/, @configA);
@configA=grep(!/^[\s\t]*$/, @configA);
my $configA_int=0;
while ( defined( $configA[$configA_int] ) ){
my $line=$configA[$configA_int];
$line=~s/^[\t\s]+//;
$line=~s/[\t\s]+$//;
my ( $var, $val )=split(/=/, $line, 2);
if ( $var eq 'cache' ){
$cache=$val;
}
if ( $var eq 'smartctl' ){
$smartctl=$val;
}
if ( $var eq 'useSN' ){
$useSN=$val;
}
if ( !defined( $val ) ){
push(@disks, $var);
}
$configA_int++;
}
#if set to 1, no cache will be written and it will be printed instead
my $noWrite=0;
# if no -u, it means we are being called from snmped
if ( ! defined( $opts{u} ) ){
# if the cache file exists, print it, otherwise assume one is not being used
if ( -f $cache ){
my $old='';
open(my $readfh, "<", $cache) or die "Can't open '".$cache."'";
read($readfh , $old , 1000000);
close($readfh);
print $old;
exit 0;
}else{
$opts{u}=1;
$noWrite=1;
}
}
my $toReturn='';
my $int=0;
while ( defined($disks[$int]) ) {
my $disk=$disks[$int];
my $disk_sn=$disk;
my $output=`$smartctl -A /dev/$disk`;
my %IDs=( '5'=>'null',
'10'=>'null',
'173'=>'null',
'177'=>'null',
'183'=>'null',
'184'=>'null',
'187'=>'null',
'188'=>'null',
'190'=>'null',
'194'=>'null',
'196'=>'null',
'197'=>'null',
'198'=>'null',
'199'=>'null',
'231'=>'null',
'233'=>'null',
);
my @outputA=split( /\n/, $output );
my $outputAint=0;
while ( defined($outputA[$outputAint]) ) {
my $line=$outputA[$outputAint];
$line=~s/^ +//;
$line=~s/ +/ /g;
if ( $line =~ /^[0123456789]+ / ) {
my @lineA=split(/\ /, $line, 10);
my $raw=$lineA[9];
my $id=$lineA[0];
# single int raw values
if (
( $id == 5 ) ||
( $id == 10 ) ||
( $id == 173 ) ||
( $id == 177 ) ||
( $id == 183 ) ||
( $id == 184 ) ||
( $id == 187 ) ||
( $id == 196 ) ||
( $id == 197 ) ||
( $id == 198 ) ||
( $id == 199 ) ||
( $id == 231 ) ||
( $id == 233 )
) {
$IDs{$id}=$raw;
}
# 188, Command_Timeout
if ( $id == 188 ) {
my $total=0;
my @rawA=split( /\ /, $raw );
my $rawAint=0;
while ( defined( $rawA[$rawAint] ) ) {
$total=$total+$rawA[$rawAint];
$rawAint++;
}
$IDs{$id}=$total;
}
# 190, airflow temp
# 194, temp
if (
( $id == 190 ) ||
( $id == 194 )
) {
my ( $temp )=split(/\ /, $raw);
$IDs{$id}=$temp;
}
}
$outputAint++;
}
#get the selftest logs
$output=`$smartctl -l selftest /dev/$disk`;
@outputA=split( /\n/, $output );
my $completed=scalar grep(/Completed without error/, @outputA);
my $interrupted=scalar grep(/Interrupted/, @outputA);
my $read_failure=scalar grep(/read failure/, @outputA);
my $unknown_failure=scalar grep(/unknown failure/, @outputA);
my $extended=scalar grep(/Extended/, @outputA);
my $short=scalar grep(/Short/, @outputA);
my $conveyance=scalar grep(/Conveyance/, @outputA);
my $selective=scalar grep(/Selective/, @outputA);
# get the drive serial number, if needed
my $disk_id=$disk;
if ( $useSN ){
while (`$smartctl -i /dev/$disk` =~ /Serial Number:(.*)/g) {
$disk_id = $1;
$disk_id =~ s/^\s+|\s+$//g;
}
}
$toReturn=$toReturn.$disk_id.','.$IDs{'5'}.','.$IDs{'10'}.','.$IDs{'173'}.','.$IDs{'177'}.','.$IDs{'183'}.','.$IDs{'184'}.','.$IDs{'187'}.','.$IDs{'188'}
.','.$IDs{'190'} .','.$IDs{'194'}.','.$IDs{'196'}.','.$IDs{'197'}.','.$IDs{'198'}.','.$IDs{'199'}.','.$IDs{'231'}.','.$IDs{'233'}.','.
$completed.','.$interrupted.','.$read_failure.','.$unknown_failure.','.$extended.','.$short.','.$conveyance.','.$selective."\n";
$int++;
}
if ( ! $noWrite ){
open(my $writefh, ">", $cache) or die "Can't open '".$cache."'";
print $writefh $toReturn;
close($writefh);
}else{
print $toReturn;
}

View File

@@ -1,32 +0,0 @@
##########################################################################
# snmpd.conf
# Created by CNW on 11/3/2018 via snmpconf wizard and manual post tweaks
###########################################################################
# SECTION: Monitor Various Aspects of the Running Host
#
# The following check up on various aspects of a host.
# disk: Check for disk space usage of a partition.
# The agent can check the amount of available disk space, and make
# sure it is above a set limit.
#
load 3 3 3
rocommunity kn3lmgmt 10.253.3.99
syslocation PFV
syscontact prodtechopsalerts@turnsys.com
sysservices 76
#TSYS tweaks
#Temperature
#pass_persist .1.3.6.1.4.1.9.9.13.1.3 /usr/local/bin/temper-snmp
#Smart
extend smart /usr/local/librenms/smart
#NTP
extend ntp-client /usr/local/librenms/ntp-client.sh
#SMTP
extend mailq /usr/local/librenms/postfix-queues
#Distro Detection
extend .1.3.6.1.4.1.2021.7890.1 distro /usr/local/librenms/distro
#extend zfs /usr/local/bin/zfs
extend osupdate /usr/local/librenms/os-updates.sh

1
logs/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
!.gitignore

View File

@@ -1,114 +0,0 @@
#!/usr/bin/env bash
# Detects which OS and if it is Linux then it will detect which Linux Distribution.
OS=`uname -s`
REV=`uname -r`
MACH=`uname -m`
if [ "${OS}" = "SunOS" ] ; then
OS=Solaris
ARCH=`uname -p`
OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
elif [ "${OS}" = "AIX" ] ; then
OSSTR="${OS} `oslevel` (`oslevel -r`)"
elif [ "${OS}" = "Linux" ] ; then
KERNEL=`uname -r`
if [ -f /etc/fedora-release ]; then
DIST=$(cat /etc/fedora-release | awk '{print $1}')
REV=`cat /etc/fedora-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/redhat-release ] ; then
DIST=$(cat /etc/redhat-release | awk '{print $1}')
if [ "${DIST}" = "CentOS" ]; then
DIST="CentOS"
elif [ "${DIST}" = "Mandriva" ]; then
DIST="Mandriva"
PSEUDONAME=`cat /etc/mandriva-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/mandriva-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/oracle-release ]; then
DIST="Oracle"
else
DIST="RedHat"
fi
PSEUDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/mandrake-release ] ; then
DIST='Mandrake'
PSEUDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/devuan_version ] ; then
DIST="Devuan `cat /etc/devuan_version`"
REV=""
elif [ -f /etc/debian_version ] ; then
DIST="Debian `cat /etc/debian_version`"
REV=""
ID=`lsb_release -i | awk -F ':' '{print $2}' | sed 's/ //g'`
if [ "${ID}" = "Raspbian" ] ; then
DIST="Raspbian `cat /etc/debian_version`"
fi
elif [ -f /etc/gentoo-release ] ; then
DIST="Gentoo"
REV=$(tr -d '[[:alpha:]]' </etc/gentoo-release | tr -d " ")
elif [ -f /etc/arch-release ] ; then
DIST="Arch Linux"
REV="" # Omit version since Arch Linux uses rolling releases
IGNORE_LSB=1 # /etc/lsb-release would overwrite $REV with "rolling"
elif [ -f /etc/os-release ] ; then
DIST=$(grep '^NAME=' /etc/os-release | cut -d= -f2- | tr -d '"')
REV=$(grep '^VERSION_ID=' /etc/os-release | cut -d= -f2- | tr -d '"')
elif [ -f /etc/openwrt_version ] ; then
DIST="OpenWrt"
REV=$(cat /etc/openwrt_version)
elif [ -f /etc/pld-release ] ; then
DIST=$(cat /etc/pld-release)
REV=""
elif [ -f /etc/SuSE-release ] ; then
DIST=$(echo SLES $(grep VERSION /etc/SuSE-release | cut -d = -f 2 | tr -d " "))
REV=$(echo SP$(grep PATCHLEVEL /etc/SuSE-release | cut -d = -f 2 | tr -d " "))
fi
if [ -f /etc/lsb-release -a "${IGNORE_LSB}" != 1 ] ; then
LSB_DIST=$(lsb_release -si)
LSB_REV=$(lsb_release -sr)
if [ "$LSB_DIST" != "" ] ; then
DIST=$LSB_DIST
fi
if [ "$LSB_REV" != "" ] ; then
REV=$LSB_REV
fi
fi
if [ "`uname -a | awk '{print $(NF)}'`" = "DD-WRT" ] ; then
DIST="dd-wrt"
fi
if [ -n "${REV}" ]
then
OSSTR="${DIST} ${REV}"
else
OSSTR="${DIST}"
fi
elif [ "${OS}" = "Darwin" ] ; then
if [ -f /usr/bin/sw_vers ] ; then
OSSTR=`/usr/bin/sw_vers|grep -v Build|sed 's/^.*:.//'| tr "\n" ' '`
fi
elif [ "${OS}" = "FreeBSD" ] ; then
OSSTR=`/usr/bin/uname -mior`
fi
echo ${OSSTR}