capturing current reality
This commit is contained in:
parent
aeed0edb38
commit
f7c0203827
30
slack/prod/tsys-base/files/etc/ssh/sshd_config
Normal file
30
slack/prod/tsys-base/files/etc/ssh/sshd_config
Normal file
@ -0,0 +1,30 @@
|
||||
#Official Turn Net Systems SSHD configuration
|
||||
#Created by Charles Wyble
|
||||
#Sourced from
|
||||
#https://stribika.github.io/2015/01/04/secure-secure-shell.html
|
||||
#https://infosec.mozilla.org/guidelines/openssh
|
||||
|
||||
#Eliminated all the stock bits that had good/sane defaults, below values are set intentionally
|
||||
|
||||
HostKey /etc/ssh/ssh_host_ed25519_key
|
||||
HostKey /etc/ssh/ssh_host_rsa_key
|
||||
PermitRootLogin without-password
|
||||
AuthenticationMethods publickey
|
||||
SyslogFacility AUTH
|
||||
LogLevel VERBOSE
|
||||
StrictModes yes
|
||||
PubkeyAuthentication yes
|
||||
PasswordAuthentication no
|
||||
ChallengeResponseAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
X11Forwarding no
|
||||
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
|
||||
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
|
||||
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256
|
||||
PrintMotd yes
|
||||
Banner /etc/ssh/tsys-banner
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
#Review the following:
|
||||
UsePAM yes
|
||||
AllowAgentForwarding yes
|
||||
|
7
slack/prod/tsys-base/files/usr/local/bin/up2date.sh
Executable file
7
slack/prod/tsys-base/files/usr/local/bin/up2date.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
apt-get update
|
||||
apt-get -y --purge autoremove
|
||||
apt-get -y autoclean
|
||||
apt-get -y upgrade
|
||||
apt-get -y dist-upgrade
|
114
slack/prod/tsys-base/files/usr/local/librenms/distro
Executable file
114
slack/prod/tsys-base/files/usr/local/librenms/distro
Executable file
@ -0,0 +1,114 @@
|
||||
#!/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}
|
25
slack/prod/tsys-base/files/usr/local/librenms/ntp-client.sh
Executable file
25
slack/prod/tsys-base/files/usr/local/librenms/ntp-client.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/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
|
||||
|
73
slack/prod/tsys-base/files/usr/local/librenms/os-updates.sh
Executable file
73
slack/prod/tsys-base/files/usr/local/librenms/os-updates.sh
Executable file
@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bash
|
||||
################################################################
|
||||
# copy this script to /etc/snmp/ and make it executable: #
|
||||
# chmod +x /etc/snmp/os-updates.sh #
|
||||
# ------------------------------------------------------------ #
|
||||
# edit your snmpd.conf and include: #
|
||||
# extend osupdate /opt/os-updates.sh #
|
||||
#--------------------------------------------------------------#
|
||||
# restart snmpd and activate the app for desired host #
|
||||
#--------------------------------------------------------------#
|
||||
# please make sure you have the path/binaries below #
|
||||
################################################################
|
||||
BIN_WC='/usr/bin/wc'
|
||||
BIN_GREP='/bin/grep'
|
||||
CMD_GREP='-c'
|
||||
CMD_WC='-l'
|
||||
BIN_ZYPPER='/usr/bin/zypper'
|
||||
CMD_ZYPPER='-q lu'
|
||||
BIN_YUM='/usr/bin/yum'
|
||||
CMD_YUM='-q check-update'
|
||||
BIN_DNF='/usr/bin/dnf'
|
||||
CMD_DNF='-q check-update'
|
||||
BIN_APT='/usr/bin/apt-get'
|
||||
CMD_APT='-qq -s upgrade'
|
||||
BIN_PACMAN='/usr/bin/pacman'
|
||||
CMD_PACMAN='-Sup'
|
||||
|
||||
################################################################
|
||||
# Don't change anything unless you know what are you doing #
|
||||
################################################################
|
||||
if [ -f $BIN_ZYPPER ]; then
|
||||
# OpenSUSE
|
||||
UPDATES=`$BIN_ZYPPER $CMD_ZYPPER | $BIN_WC $CMD_WC`
|
||||
if [ $UPDATES -ge 2 ]; then
|
||||
echo $(($UPDATES-2));
|
||||
else
|
||||
echo "0";
|
||||
fi
|
||||
elif [ -f $BIN_DNF ]; then
|
||||
# Fedora
|
||||
UPDATES=`$BIN_DNF $CMD_DNF | $BIN_WC $CMD_WC`
|
||||
if [ $UPDATES -ge 1 ]; then
|
||||
echo $(($UPDATES-1));
|
||||
else
|
||||
echo "0";
|
||||
fi
|
||||
elif [ -f $BIN_PACMAN ]; then
|
||||
# Arch
|
||||
UPDATES=`$BIN_PACMAN $CMD_PACMAN | $BIN_WC $CMD_WC`
|
||||
if [ $UPDATES -ge 1 ]; then
|
||||
echo $(($UPDATES-1));
|
||||
else
|
||||
echo "0";
|
||||
fi
|
||||
elif [ -f $BIN_YUM ]; then
|
||||
# CentOS / Redhat
|
||||
UPDATES=`$BIN_YUM $CMD_YUM | $BIN_WC $CMD_WC`
|
||||
if [ $UPDATES -ge 1 ]; then
|
||||
echo $(($UPDATES-1));
|
||||
else
|
||||
echo "0";
|
||||
fi
|
||||
elif [ -f $BIN_APT ]; then
|
||||
# Debian / Devuan / Ubuntu
|
||||
UPDATES=`$BIN_APT $CMD_APT | $BIN_GREP $CMD_GREP 'Inst'`
|
||||
if [ $UPDATES -ge 1 ]; then
|
||||
echo $UPDATES;
|
||||
else
|
||||
echo "0";
|
||||
fi
|
||||
else
|
||||
echo "0";
|
||||
fi
|
13
slack/prod/tsys-base/files/usr/local/librenms/postfix-queues
Executable file
13
slack/prod/tsys-base/files/usr/local/librenms/postfix-queues
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
#Written by Valec 2006. Steal and share.
|
||||
#Get postfix queue lengths
|
||||
|
||||
#extend mailq /opt/observer/scripts/getmailq.sh
|
||||
|
||||
QUEUES="incoming active deferred hold"
|
||||
|
||||
for i in $QUEUES; do
|
||||
COUNT=`qshape $i | grep TOTAL | awk '{print $2}'`
|
||||
printf "$COUNT\n"
|
||||
done
|
363
slack/prod/tsys-base/files/usr/local/librenms/smart
Executable file
363
slack/prod/tsys-base/files/usr/local/librenms/smart
Executable file
@ -0,0 +1,363 @@
|
||||
#!/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;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
smartctl=/usr/sbin/smartctl
|
||||
cache=/var/cache/smart
|
||||
sda
|
266
slack/prod/tsys-base/files/usr/local/librenms/zfs
Executable file
266
slack/prod/tsys-base/files/usr/local/librenms/zfs
Executable file
@ -0,0 +1,266 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a SNMP extend for ZFS and FreeBSD for use with LibreNMS.
|
||||
|
||||
For more information, see L<https://docs.librenms.org/#Extensions/Applications/#zfs>.
|
||||
|
||||
=head1 SWITCHES
|
||||
|
||||
=head2 -p
|
||||
|
||||
Pretty print the JSON.
|
||||
|
||||
=head1 SNMPD SETUP EXAMPLES
|
||||
|
||||
extend zfs /etc/snmp/zfs-freebsd
|
||||
|
||||
=cut
|
||||
|
||||
#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.
|
||||
|
||||
# Many thanks to Ben Rockwood, Jason J. Hellenthal, and Martin Matuska
|
||||
# for zfs-stats and figuring out the math for all the stats
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON;
|
||||
use Getopt::Std;
|
||||
|
||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||
sub main::VERSION_MESSAGE {
|
||||
print "FreeBSD ZFS stats extend 0.0.0\n";
|
||||
}
|
||||
|
||||
sub main::HELP_MESSAGE {
|
||||
|
||||
}
|
||||
|
||||
#this will be dumped to json at the end
|
||||
my %tojson;
|
||||
|
||||
#gets the options
|
||||
my %opts=();
|
||||
getopts('p', \%opts);
|
||||
|
||||
my $sysctls;
|
||||
my @to_pull=(
|
||||
'kstat.zfs',
|
||||
'vfs.zfs',
|
||||
);
|
||||
my @sysctls_pull = `/sbin/sysctl -q @to_pull`;
|
||||
foreach my $stat (@sysctls_pull) {
|
||||
chomp( $stat );
|
||||
my ( $var, $val ) = split(/:/, $stat, 2);
|
||||
|
||||
$val =~ s/^ //;
|
||||
$sysctls->{$var}=$val;
|
||||
}
|
||||
|
||||
# does not seem to exist for me, but some of these don't seem to be created till needed
|
||||
if ( ! defined( $sysctls->{"kstat.zfs.misc.arcstats.recycle_miss"} ) ) {
|
||||
$sysctls->{"kstat.zfs.misc.arcstats.recycle_miss"}=0;
|
||||
}
|
||||
|
||||
##
|
||||
## ARC misc
|
||||
##
|
||||
$tojson{deleted}=$sysctls->{"kstat.zfs.misc.arcstats.deleted"};
|
||||
$tojson{evict_skip}=$sysctls->{"kstat.zfs.misc.arcstats.evict_skip"};
|
||||
$tojson{mutex_skip}=$sysctls->{'kstat.zfs.misc.arcstats.mutex_miss'};
|
||||
$tojson{recycle_miss}=$sysctls->{"kstat.zfs.misc.arcstats.recycle_miss"};
|
||||
|
||||
##
|
||||
## ARC size
|
||||
##
|
||||
my $target_size_percent = $sysctls->{"kstat.zfs.misc.arcstats.c"} / $sysctls->{"kstat.zfs.misc.arcstats.c_max"} * 100;
|
||||
my $arc_size_percent = $sysctls->{"kstat.zfs.misc.arcstats.size"} / $sysctls->{"kstat.zfs.misc.arcstats.c_max"} * 100;
|
||||
my $target_size_adaptive_ratio = $sysctls->{"kstat.zfs.misc.arcstats.c"} / $sysctls->{"kstat.zfs.misc.arcstats.c_max"};
|
||||
my $min_size_percent = $sysctls->{"kstat.zfs.misc.arcstats.c_min"} / $sysctls->{"kstat.zfs.misc.arcstats.c_max"} * 100;
|
||||
|
||||
$tojson{arc_size}=$sysctls->{"kstat.zfs.misc.arcstats.size"};
|
||||
$tojson{target_size_max}=$sysctls->{"kstat.zfs.misc.arcstats.c_max"};
|
||||
$tojson{target_size_min}=$sysctls->{"kstat.zfs.misc.arcstats.c_min"};
|
||||
$tojson{target_size}=$sysctls->{"kstat.zfs.misc.arcstats.c"};
|
||||
$tojson{target_size_per}=$target_size_percent;
|
||||
$tojson{arc_size_per}=$arc_size_percent;
|
||||
$tojson{target_size_arat}=$target_size_adaptive_ratio;
|
||||
$tojson{min_size_per}=$min_size_percent;
|
||||
|
||||
##
|
||||
## ARC size breakdown
|
||||
##
|
||||
my $mfu_size;
|
||||
my $recently_used_percent;
|
||||
my $frequently_used_percent;
|
||||
if ( $sysctls->{"kstat.zfs.misc.arcstats.size"} >= $sysctls->{"kstat.zfs.misc.arcstats.c"} ){
|
||||
$mfu_size = $sysctls->{"kstat.zfs.misc.arcstats.size"} - $sysctls->{"kstat.zfs.misc.arcstats.p"};
|
||||
$recently_used_percent = $sysctls->{"kstat.zfs.misc.arcstats.p"} / $sysctls->{"kstat.zfs.misc.arcstats.size"} * 100;
|
||||
$frequently_used_percent = $mfu_size / $sysctls->{"kstat.zfs.misc.arcstats.size"} * 100;
|
||||
}else{
|
||||
$mfu_size = $sysctls->{"kstat.zfs.misc.arcstats.c"} - $sysctls->{"kstat.zfs.misc.arcstats.p"};
|
||||
$recently_used_percent = $sysctls->{"kstat.zfs.misc.arcstats.p"} / $sysctls->{"kstat.zfs.misc.arcstats.c"} * 100;
|
||||
$frequently_used_percent = $mfu_size / $sysctls->{"kstat.zfs.misc.arcstats.c"} * 100;
|
||||
}
|
||||
|
||||
$tojson{mfu_size}=$mfu_size;
|
||||
$tojson{p}=$sysctls->{"kstat.zfs.misc.arcstats.p"};
|
||||
$tojson{rec_used_per}=$recently_used_percent;
|
||||
$tojson{freq_used_per}=$frequently_used_percent;
|
||||
|
||||
##
|
||||
## ARC efficiency
|
||||
##
|
||||
my $arc_hits = $sysctls->{"kstat.zfs.misc.arcstats.hits"};
|
||||
my $arc_misses = $sysctls->{"kstat.zfs.misc.arcstats.misses"};
|
||||
my $demand_data_hits = $sysctls->{"kstat.zfs.misc.arcstats.demand_data_hits"};
|
||||
my $demand_data_misses = $sysctls->{"kstat.zfs.misc.arcstats.demand_data_misses"};
|
||||
my $demand_metadata_hits = $sysctls->{"kstat.zfs.misc.arcstats.demand_metadata_hits"};
|
||||
my $demand_metadata_misses = $sysctls->{"kstat.zfs.misc.arcstats.demand_metadata_misses"};
|
||||
my $mfu_ghost_hits = $sysctls->{"kstat.zfs.misc.arcstats.mfu_ghost_hits"};
|
||||
my $mfu_hits = $sysctls->{"kstat.zfs.misc.arcstats.mfu_hits"};
|
||||
my $mru_ghost_hits = $sysctls->{"kstat.zfs.misc.arcstats.mru_ghost_hits"};
|
||||
my $mru_hits = $sysctls->{"kstat.zfs.misc.arcstats.mru_hits"};
|
||||
my $prefetch_data_hits = $sysctls->{"kstat.zfs.misc.arcstats.prefetch_data_hits"};
|
||||
my $prefetch_data_misses = $sysctls->{"kstat.zfs.misc.arcstats.prefetch_data_misses"};
|
||||
my $prefetch_metadata_hits = $sysctls->{"kstat.zfs.misc.arcstats.prefetch_metadata_hits"};
|
||||
my $prefetch_metadata_misses = $sysctls->{"kstat.zfs.misc.arcstats.prefetch_metadata_misses"};
|
||||
|
||||
my $anon_hits = $arc_hits - ($mfu_hits + $mru_hits + $mfu_ghost_hits + $mru_ghost_hits);
|
||||
my $arc_accesses_total = $arc_hits + $arc_misses;
|
||||
my $demand_data_total = $demand_data_hits + $demand_data_misses;
|
||||
my $prefetch_data_total = $prefetch_data_hits + $prefetch_data_misses;
|
||||
my $real_hits = $mfu_hits + $mru_hits;
|
||||
|
||||
my $cache_hit_percent = $arc_hits / $arc_accesses_total * 100;
|
||||
my $cache_miss_percent = $arc_misses / $arc_accesses_total * 100;
|
||||
my $actual_hit_percent = $real_hits / $arc_accesses_total * 100;
|
||||
my $data_demand_percent = $demand_data_hits / $demand_data_total * 100;
|
||||
|
||||
my $data_prefetch_percent;
|
||||
if ( $prefetch_data_total != 0 ) {
|
||||
$data_prefetch_percent = $prefetch_data_hits / $prefetch_data_total * 100;
|
||||
}else{
|
||||
$data_prefetch_percent = 0;
|
||||
}
|
||||
|
||||
my $anon_hits_percent;
|
||||
if ( $anon_hits != 0 ) {
|
||||
$anon_hits_percent = $anon_hits / $arc_hits * 100;
|
||||
}else{
|
||||
$anon_hits_percent=0;
|
||||
}
|
||||
|
||||
my $mru_percent = $mru_hits / $arc_hits * 100;
|
||||
my $mfu_percent = $mfu_hits / $arc_hits * 100;
|
||||
my $mru_ghost_percent = $mru_ghost_hits / $arc_hits * 100;
|
||||
my $mfu_ghost_percent = $mfu_ghost_hits / $arc_hits * 100;
|
||||
|
||||
my $demand_hits_percent = $demand_data_hits / $arc_hits * 100;
|
||||
my $prefetch_hits_percent = $prefetch_data_hits / $arc_hits * 100;
|
||||
my $metadata_hits_percent = $demand_metadata_hits / $arc_hits * 100;
|
||||
my $prefetch_metadata_hits_percent = $prefetch_metadata_hits / $arc_hits * 100;
|
||||
|
||||
my $demand_misses_percent = $demand_data_misses / $arc_misses * 100;
|
||||
my $prefetch_misses_percent = $prefetch_data_misses / $arc_misses * 100;
|
||||
my $metadata_misses_percent = $demand_metadata_misses / $arc_misses * 100;
|
||||
my $prefetch_metadata_misses_percent = $prefetch_metadata_misses / $arc_misses * 100;
|
||||
|
||||
# ARC misc. efficient stats
|
||||
$tojson{arc_hits}=$arc_hits;
|
||||
$tojson{arc_misses}=$arc_misses;
|
||||
$tojson{demand_data_hits}=$demand_data_hits;
|
||||
$tojson{demand_data_misses}=$demand_data_misses;
|
||||
$tojson{demand_meta_hits}=$demand_metadata_hits;
|
||||
$tojson{demand_meta_misses}=$demand_metadata_misses;
|
||||
$tojson{mfu_ghost_hits}=$mfu_ghost_hits;
|
||||
$tojson{mfu_hits}=$mfu_hits;
|
||||
$tojson{mru_ghost_hits}=$mru_ghost_hits;
|
||||
$tojson{mru_hits}=$mru_hits;
|
||||
$tojson{pre_data_hits}=$prefetch_data_hits;
|
||||
$tojson{pre_data_misses}=$prefetch_data_misses;
|
||||
$tojson{pre_meta_hits}=$prefetch_metadata_hits;
|
||||
$tojson{pre_meta_misses}=$prefetch_metadata_misses;
|
||||
$tojson{anon_hits}=$anon_hits;
|
||||
$tojson{arc_accesses_total}=$arc_accesses_total;
|
||||
$tojson{demand_data_total}=$demand_data_total;
|
||||
$tojson{pre_data_total}=$prefetch_data_total;
|
||||
$tojson{real_hits}=$real_hits;
|
||||
|
||||
# ARC efficient percents
|
||||
$tojson{cache_hits_per}=$cache_hit_percent;
|
||||
$tojson{cache_miss_per}=$cache_miss_percent;
|
||||
$tojson{actual_hit_per}=$actual_hit_percent;
|
||||
$tojson{data_demand_per}=$data_demand_percent;
|
||||
$tojson{data_pre_per}=$data_prefetch_percent;
|
||||
$tojson{anon_hits_per}=$anon_hits_percent;
|
||||
$tojson{mru_per}=$mru_percent;
|
||||
$tojson{mfu_per}=$mfu_percent;
|
||||
$tojson{mru_ghost_per}=$mru_ghost_percent;
|
||||
$tojson{mfu_ghost_per}=$mfu_ghost_percent;
|
||||
$tojson{demand_hits_per}=$demand_hits_percent;
|
||||
$tojson{pre_hits_per}=$prefetch_hits_percent;
|
||||
$tojson{meta_hits_per}=$metadata_hits_percent;
|
||||
$tojson{pre_meta_hits_per}=$prefetch_metadata_hits_percent;
|
||||
$tojson{demand_misses_per}=$demand_misses_percent;
|
||||
$tojson{pre_misses_per}=$prefetch_misses_percent;
|
||||
$tojson{meta_misses_per}=$metadata_misses_percent;
|
||||
$tojson{pre_meta_misses_per}=$prefetch_metadata_misses_percent;
|
||||
|
||||
#process each pool and shove them into JSON
|
||||
my $zpool_output=`/sbin/zpool list -pH`;
|
||||
my @pools=split( /\n/, $zpool_output );
|
||||
my $pools_int=0;
|
||||
my @toShoveIntoJSON;
|
||||
while ( defined( $pools[$pools_int] ) ) {
|
||||
my %newPool;
|
||||
|
||||
my $pool=$pools[$pools_int];
|
||||
$pool =~ s/\t/,/g;
|
||||
$pool =~ s/\,\-\,/\,0\,/g;
|
||||
$pool =~ s/\%//g;
|
||||
$pool =~ s/\,([0-1\.]*)x\,/,$1,/;
|
||||
|
||||
( $newPool{name}, $newPool{size}, $newPool{alloc}, $newPool{free}, $newPool{expandsz}, $newPool{frag}, $newPool{cap}, $newPool{dedup} )=split(/\,/, $pool);
|
||||
|
||||
push(@toShoveIntoJSON, \%newPool);
|
||||
|
||||
$pools_int++;
|
||||
}
|
||||
$tojson{pools}=\@toShoveIntoJSON;
|
||||
|
||||
my $j=JSON->new;
|
||||
|
||||
if ( $opts{p} ){
|
||||
$j->pretty(1);
|
||||
}
|
||||
|
||||
print $j->encode( \%tojson );
|
||||
|
||||
if (! $opts{p} ){
|
||||
print "\n";
|
||||
}
|
||||
|
||||
exit 0;
|
@ -7,4 +7,11 @@ if [ $ISUCS -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apt -y install htop glances sssd-ad dstat ladvd snmpd ntp tcpdump autofs
|
||||
apt-get update
|
||||
apt-get -y --purge autoremove
|
||||
apt-get -y autoclean
|
||||
apt-get -y upgrade
|
||||
apt-get -y dist-upgrade
|
||||
apt -y install htop glances dstat ladvd snmpd ntp tcpdump autofs logwatch molly-guard
|
||||
|
||||
slack tsys-base-$tsysSysLocation
|
||||
|
@ -7,7 +7,7 @@ filegen clockstats file clockstats type day enable
|
||||
|
||||
server ovh-ucs.turnsys.net
|
||||
server pfv-ucs.turnsys.net
|
||||
server satx-ucs.turnsys.net
|
||||
server pool.ntp.org
|
||||
|
||||
restrict default mssntp noquery
|
||||
restrict 127.0.0.1
|
||||
|
@ -1,3 +1,3 @@
|
||||
domain turnsys.net
|
||||
nameserver 10.253.3.201
|
||||
nameserver 10.40.100.200
|
||||
nameserver 10.251.30.201
|
||||
|
@ -1,10 +0,0 @@
|
||||
===============================================================================
|
||||
|
||||
This is a private computer system. These resources, including all
|
||||
related equipment, networks, and devices, are provided for authorized
|
||||
use only. The system may be monitored for all lawful purposes. Evidence
|
||||
of unauthorized use collected during monitoring may be used for criminal
|
||||
prosecution by staff, legal counsel, and law enforcement agencies.
|
||||
|
||||
===============================================================================
|
||||
|
@ -1,10 +0,0 @@
|
||||
===============================================================================
|
||||
|
||||
This is a private computer system. These resources, including all
|
||||
related equipment, networks, and devices, are provided for authorized
|
||||
use only. The system may be monitored for all lawful purposes. Evidence
|
||||
of unauthorized use collected during monitoring may be used for criminal
|
||||
prosecution by staff, legal counsel, and law enforcement agencies.
|
||||
|
||||
===============================================================================
|
||||
|
@ -7,7 +7,6 @@ filegen clockstats file clockstats type day enable
|
||||
|
||||
server pfv-ucs.turnsys.net
|
||||
server ovh-ucs.turnsys.net
|
||||
server satx-ucs.turnsys.net
|
||||
|
||||
restrict default mssntp noquery
|
||||
restrict 127.0.0.1
|
||||
|
@ -1,3 +1,4 @@
|
||||
domain pfv.turnsys.net
|
||||
nameserver 10.251.30.71
|
||||
nameserver 10.251.3.201
|
||||
search pfv.turnsys.net turnsys.net
|
||||
nameserver 10.251.30.201
|
||||
nameserver 10.253.3.201
|
||||
|
@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
slack common
|
Loading…
Reference in New Issue
Block a user