Under Construction
Step 4: Messages and Error Messages
The included scripts log all commands executed in the script to the log file /etc/security/aixpert/log/aixpert.log. They also check for correct script invocation (correct number and type of arguments) and display additional messages.
The file /etc/security/aixpert/bin/initialize_variables contains some variables that contain, for example, log files, report files, and other paths. All predefined scripts read the contents of this file. Here is a brief summary of the file’s contents:
# cat /etc/security/aixpert/bin/initialize_variables
#!/usr/bin/ksh
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
# bos720 src/bos/usr/lib/security/aixpert/scripts/initialize_variables.sh 1.3
#
# Licensed Materials - Property of IBM
#
# Restricted Materials of IBM
#
# COPYRIGHT International Business Machines Corp. 2006,2007
# All Rights Reserved
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
# IBM_PROLOG_END_TAG
# @(#)89 1.3 src/bos/usr/lib/security/aixpert/scripts/initialize_variables.sh, aixpert, bos720 2/20/07 02:11:57
LOG=/etc/security/aixpert/log/aixpert.log
REPORT=/etc/security/aixpert/check_report.txt
SAVE=/etc/security/aixpert/undo/data
SCPTDIR=/etc/security/aixpert/undo
UNDOXML=/etc/security/aixpert/core/undo.xml
AIXPERT_FIFO=/etc/security/aixpert/tmp/AIXPERT
TMPDIR=/etc/security/aixpert/tmp
#
We take over the beginning of the supplied scripts:
export PATH=/usr/bin:/usr/sbin:$PATH
# Initialize variables AIXPERT_FIFO, LOG, REPORT, SCPTDIR and UNDOXML
. /etc/security/aixpert/bin/initialize_variables
Redefining the PATH variables ensures that /usr/bin and /usr/sbin are first searched for commands. Then, the initialize_variables file is sourced.
Next, the following lines redirect standard output and standard error channels to the log file /etc/security/aixpert/log/aixpert.log ($LOG):
# Log output and errors to /etc/security/aixpert/log/aixpert.log
exec 1>>$LOG
exec 2>&1
All output goes into the log file mentioned!
To make it clear in the log which script the output comes from, a header line is generated in the log:
# echo all the commands and the current time and date to the AIXpert log
set -x
date
echo $0 $@ AIXPERT_CHECK_REPORT=$AIXPERT_CHECK_REPORT BASE_REPT=$BASE_REPT DETAILED_REPT=$DETAILED_REPT
Finally, we perform a check on the arguments passed in. For now, our script should not be called with arguments:
if [ $# -ne 0 ]
then
echo "Usage : local_chsshdconf\n"
exit 1
fi
(We will add arguments later.)
This results in the following version of the script:
# cat /etc/security/aixpert/bin/local_chsshdconf
#! /bin/ksh
export PATH=/usr/bin:/usr/sbin:$PATH
# Initialize variables AIXPERT_FIFO, LOG, REPORT, SCPTDIR and UNDOXML
. /etc/security/aixpert/bin/initialize_variables
# Log output and errors to /etc/security/aixpert/log/aixpert.log
exec 1>>$LOG
exec 2>&1
# echo all the commands and the current time and date to the AIXpert log
set -x
date
echo $0 $@ AIXPERT_CHECK_REPORT=$AIXPERT_CHECK_REPORT BASE_REPT=$BASE_REPT DETAILED_REPT=$DETAILED_REPT
if [ $# -ne 0 ]
then
echo "Usage : local_chsshdconf\n"
exit 1
fi
# Check whether AIXPERT_CHECK_REPORT environment variable is set or not.
report=`echo $AIXPERT_CHECK_REPORT`
if [ "$report" = "1" ]
then
ret=1
permit=$( awk '$1 ~ /^PermitRootLogin$/ { print $2; }' /etc/ssh/sshd_config 2>/dev/null | tail -n 1 )
case "${permit}" in
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]) ret=0 ;;
esac
exit $ret
fi
exit 0
#
We perform another test run:
/etc/security/aixpert # aixpert -c -P custom/sshd.xml
Processedrules=1 Passedrules=0 Failedrules=1 Level=TEST
Input file=custom/sshd.xml
/etc/security/aixpert #
A review of the log file aixpert.log shows that all commands executed in the script have now been logged:
/etc/security/aixpert # cat log/aixpert.log
+ date
Fri Dec 2 15:21:21 CET 2022
+ echo /etc/security/aixpert/bin/local_chsshdconf AIXPERT_CHECK_REPORT=1 BASE_REPT= DETAILED_REPT=
/etc/security/aixpert/bin/local_chsshdconf AIXPERT_CHECK_REPORT=1 BASE_REPT= DETAILED_REPT=
+ [ 0 -ne 0 ]
+ + echo 1
report=1
+ [ 1 = 1 ]
+ ret=1
+ + awk $1 ~ /^PermitRootLogin$/ { print $2; } /etc/ssh/sshd_config
+ 2> /dev/null
+ tail -n 1
permit=yes
+ exit 1
/etc/security/aixpert #
If a check fails, a corresponding message should be output in /etc/security/aixpert/check_report.txt. Here is an example message from another script:
chusrattr.sh: User attribute minlen, for srvproxy should have value 8, but it is 6 now
In the standard scripts, for a normal report, such a message is appended to /etc/security/aixpert/check_report.txt ($REPORT) and to /etc/security/aixpert/tmp/AIXPERT ($AIXPERT_FIFO):
dspmsg -s 4 aixpert.cat 3 "chusrattr.sh: User attribute %s, for $username should have value %s, but it is %s now\n" $usrattr $value $defvalue >>$REPORT
dspmsg -s 4 aixpert.cat 3 "chusrattr.sh: User attribute %s, for $username should have value %s, but it is %s now\n" $usrattr $value $defvalue >>$AIXPERT_FIFO
We will not deal with locale-dependent messages here and therefore use a simple printf for the output in our script:
printf "local_chsshdconf.sh: sshd attribute %s should have value %s, but it is %s now\n" PermitRootLogin no $permit >>$REPORT
printf "local_chsshdconf.sh: sshd attribute %s should have value %s, but it is %s now\n" PermitRootLogin no $permit >>$AIXPERT_FIFO
The messages will only be generated if the verification was unsuccessful, meaning PermitRootLogin is allowed. We therefore place the two lines in the body of an if statement that checks for “$ret = 1“. The overall result is the following version:
# cat /etc/security/aixpert/bin/local_chsshdconf
#! /bin/ksh
export PATH=/usr/bin:/usr/sbin:$PATH
# Initialize variables AIXPERT_FIFO, LOG, REPORT, SCPTDIR and UNDOXML
. /etc/security/aixpert/bin/initialize_variables
# Log output and errors to /etc/security/aixpert/log/aixpert.log
exec 1>>$LOG
exec 2>&1
# echo all the commands and the current time and date to the AIXpert log
set -x
date
echo $0 $@ AIXPERT_CHECK_REPORT=$AIXPERT_CHECK_REPORT BASE_REPT=$BASE_REPT DETAILED_REPT=$DETAILED_REPT
if [ $# -ne 0 ]
then
echo "Usage : local_chsshdconf\n"
exit 1
fi
# Check whether AIXPERT_CHECK_REPORT environment variable is set or not.
report=`echo $AIXPERT_CHECK_REPORT`
if [ "$report" = "1" ]
then
ret=1
permit=$( awk '$1 ~ /^PermitRootLogin$/ { print $2; }' /etc/ssh/sshd_config 2>/dev/null | tail -n 1 )
case "${permit}" in
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]) ret=0 ;;
esac
if [ $ret = 1 ]
then
printf "local_chsshdconf.sh: sshd attribute %s should have value %s, but it is %s now\n" PermitRootLogin no $permit >>$REPORT
printf "local_chsshdconf.sh: sshd attribute %s should have value %s, but it is %s now\n" PermitRootLogin no $permit >>$AIXPERT_FIFO
fi
exit $ret
fi
exit 0
#
Another run of aixpert followed by a look at /etc/security/aixpert/check_report.txt shows that there are now corresponding messages about the failed check:
/etc/security/aixpert # cat check_report.txt
…
***** aix01 : Dec 2 15:42:31 ******
local_chsshdconf.sh: sshd attribute PermitRootLogin should have value no, but it is yes now
Processedrules=1 Passedrules=0 Failedrules=1 Level=TEST
Input file=custom/sshd.xml
/etc/security/aixpert #
The AIX Security Expert offers two additional options during the check (aixpert -c):
-r : Generating a base compliance report
-R: Generating a description report
If a check is called with the additional option “-r” (base compliance report), the variable BASE_REPT=1 is set for the script call. For the option “-R” (description report), DETAILED_REPT=1 is set for the script call. In both cases, the file to be logged is passed via the TMPREPT variable. Specific messages about the failed check are then written to the file /etc/security/aixpert/check_report.csv instead of /etc/security/aixpert/check_report.txt.
The standard scripts typically process the first two variables in the following form:
BrType=`echo $BASE_REPT`
DrType=`echo $DETAILED_REPT`
These lines are immediately after setting the variable report.
If a check fails and BrType is “1” (aixpert was started with the -r option), the message “Base Compliance Report” is appended to aixpert.log and a message is written to $TMPREPT. If DrType is “1” (aixpert was started with the -R option), the message “Description Report” is appended to aixpert.log, and a specific message about the failed check is written to $TMPREPT.
We add a corresponding case distinction to our script, again based on the existing scripts from IBM:
# cat /etc/security/aixpert/bin/local_chsshdconf
#! /bin/ksh
export PATH=/usr/bin:/usr/sbin:$PATH
# Initialize variables AIXPERT_FIFO, LOG, REPORT, SCPTDIR and UNDOXML
. /etc/security/aixpert/bin/initialize_variables
# Log output and errors to /etc/security/aixpert/log/aixpert.log
exec 1>>$LOG
exec 2>&1
# echo all the commands and the current time and date to the AIXpert log
set -x
date
echo $0 $@ AIXPERT_CHECK_REPORT=$AIXPERT_CHECK_REPORT BASE_REPT=$BASE_REPT DETAILED_REPT=$DETAILED_REPT
if [ $# -ne 0 ]
then
echo "Usage : local_chsshdconf\n"
exit 1
fi
# Check whether AIXPERT_CHECK_REPORT environment variable is set or not.
report=`echo $AIXPERT_CHECK_REPORT`
BrType=`echo $BASE_REPT`
DrType=`echo $DETAILED_REPT`
if [ "$report" = "1" ]
then
ret=1
permit=$( awk '$1 ~ /^PermitRootLogin$/ { print $2; }' /etc/ssh/sshd_config 2>/dev/null | tail -n 1 )
case "${permit}" in
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]) ret=0 ;;
esac
if [ $ret = 1 ]
then
if [ "$BrType" = "1" ]
then
echo "Base Compliance Report\n";
printf "local_chsshdconf: sshd attribute %s should have value %s, but it is %s now\n" PermitRootLogin no $permit >>$TMPREPT
elif [ "$DrType" = "1" ]
then
echo "Description Report\n";
printf "local_chsshdconf: sshd attribute %s should have value %s, but it is %s now\n" PermitRootLogin no $permit >>$TMPREPT
else
printf "local_chsshdconf: sshd attribute %s should have value %s, but it is %s now\n" PermitRootLogin no $permit >>$REPORT
printf "local_chsshdconf: sshd attribute %s should have value %s, but it is %s now\n" PermitRootLogin no $permit >>$AIXPERT_FIFO
fi
fi
exit $ret
fi
exit 0
#
A run with the “-r” option set, shows that corresponding messages now appear in /etc/security/aixpert/check_report.csv:
/etc/security/aixpert # aixpert -c -P custom/sshd.xml -r
Processedrules=1 Passedrules=0 Failedrules=1 Level=TEST
Input file=custom/sshd.xml
/etc/security/aixpert #
/etc/security/aixpert # cat check_report.csv
Admin:root
Report date and Time:Dec 2 17:34:09
Report Version 1.0
HostName,IP Address,Description,Command Arguments,Result,Reason for failure
aix01,192.168.188.19,"Ensure that PermitRootLogin is False.",/etc/security/aixpert/bin/local_chsshdconf ,FAIL, sshd attribute PermitRootLogin should have value no, but it is yes now
Processedrules=1 Passedrules=0 Failedrules=1 Level=TEST
Input file=custom/sshd.xml
/etc/security/aixpert #
This supports checking the PermitRootLogin setting for the SSH daemon from your own script.
Next, setting PermitRootLogin via aixpert and the script will be shown.