Friday, December 22, 2017

PostgreSQL 9.6.5 STIG Fix Script

The PostgreSQL 9.6.5 has about 111 checks.  Most of these checks are repetitive and deal with settings in the postgresql.conf file. 

The script below assumes that this is a fresh PostgreSQL install.  It fixes 52 of the 111 checks by modifying the postgresql.conf file.  The script can be improved upon and other checks can be added.  But as a start, if you are standing up many PostgreSQL clusters, and need them to be STIG'd, this script can set about half of your open findings.

It assumes that the pgaudit RPMs have not been installed and that these RPMs are available in the same location that the script is run from.  The check_rpm_files functions does this.  The check_rpms functions looks to see if the RPMs are installed.  If not, it will install the RPMs.  If you already have pgaudit installed, comment out these calls in the script.

pg_9.6.5_stig_fixes.sh

#!/bin/bash
check_rpms() {
   # Check if we have pgaudit RPMs installed
   PGAUDIT=`echo $PGAUDITRPM | awk -F ".rpm" '{print $1}'`
   CHECK=`rpm -qa|grep $PGAUDIT`
   if [ $? -ne 1 ]
   then
      echo "$PGAUDITRPM is installed...skipping install"
   else
      RPMLIST="$RPMLIST $PGAUDITRPM"
      echo $RPMLIST
      INSTALLRPM=true
   fi
   PGAUDITDEBUG=`echo $PGAUDITDEBUGRPM | awk -F ".rpm" '{print $1}'`
   CHECK=`rpm -qa|grep $PGAUDITDEBUG`
   if [ $? -ne 1 ]
   then
      echo "$PGAUDITDEBUGRPM is installed...skipping install"
   else
      RPMLIST="$RPMLIST $PGAUDITDEBUGRPM"
      echo "RPMS to install $RPMLIST"
      INSTALLRPM=true
   fi
   if [ "$INSTALLRPM" = true ]
   then
      echo "This is our list.....$RPMLIST"
      yum install $RPMLIST -y
   fi
}
check_pgdata() {
   # Assume that PGDATA=/var/lib/pgsql/9.6/data
   if [ "$1" != "" ]; then
       PGDATA=$1
   else
       PGDATA=/var/lib/pgsql/9.6/data
   fi
   # Check if PGDATA exists
   if [ ! -d $PGDATA ]
   then
       echo "$PGDATA does not exist!"
       exit 1
   fi
}
check_rpm_files() {
   # Our pgaudit RPMs should be in the same directory that the script runs from
   for RPMS in $PGAUDITRPM $PGAUDITDEBUGRPM; do
     if [ ! -f $RPMS ]
     then
        echo "RPM file $RPMS does not exist!"
        exit 1
     fi
   done
}
logger() {
   printf "\n$1\n\n" >> /tmp/$LOGFILE
   #echo $1 >> /tmp/$LOGFILE
}
#############
### FIXES ###
#############
fix_V-72843() {
   CHK=`grep pgaudit.log_catalog $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "pgaudit.log_catalog = on" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i 's/\(#pgaudit\|pgaudit\)\.log_catalog.*/pgaudit.log_catalog = on/g' $PGDATA/postgresql.conf
   fi
   CHK=`grep pgaudit.log_level $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "pgaudit.log_level = log" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i 's/\(#pgaudit\|pgaudit\)\.log_level.*/pgaudit.log_level = log/g' $PGDATA/postgresql.conf
   fi
   CHK=`grep pgaudit.log_parameter $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "pgaudit.log_parameter = on" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i 's/\(#pgaudit\|pgaudit\)\.log_parameter.*/pgaudit.log_parameter = on/g' $PGDATA/postgresql.conf
   fi
   CHK=`grep pgaudit.log_statement_once $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "pgaudit.log_statement_once = off" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i 's/\(#pgaudit\|pgaudit\)\.log_statement_once.*/pgaudit.log_statement_once = off/g' $PGDATA/postgresql.conf
   fi
   CHK=`grep 'pgaudit.log=\|pgaudit.log =' $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "pgaudit.log = 'all, -misc, ddl, write, role, read, function'" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#pgaudit\|pgaudit\)\.log\(=\| =\).*/pgaudit.log = 'all, -misc, ddl, write, role, read, function'/g" $PGDATA/postgresql.conf
   fi
   CHK=`grep log_line_prefix $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "log_line_prefix = '%t [%p]: [%1-1] user=%u,db=%d %m %e %c %r %a %s '" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#log_line_prefix\|log_line_prefix\).*/log_line_prefix = '%t [%p]: [%1-1] user=%u,db=%d %m %e %c %r %a %s '/g" $PGDATA/postgresql.conf
   fi
   CHK=`grep log_error_verbosity $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "log_error_verbosity = default " >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#log_error_verbosity\|log_error_verbosity\).*/log_error_verbosity = default/g" $PGDATA/postgresql.conf
   fi
   logger "FIXED:V-72843:CAT II:PostgreSQL must produce audit records containing sufficient information to establish the outcome (success or failure) of the events."
}
fix_V-72847() {
   # Will fix later
   #logger "FIXED:V-72847:CAT II:The audit information produced by PostgreSQL must be protected from unauthorized modification."
   echo "Will fix later..."
}
fix_V-72851() {
   CHK=`grep client_min_messages $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "client_min_messages = error '" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#client_min_messages\|client_min_messages\).*/client_min_messages = error/g" $PGDATA/postgresql.conf
   fi
   logger "FIXED:V-72851:CAT II:PostgreSQL must provide non-privileged users with error messages that provide information necessary for corrective actions without revealing information that could be exploited by adversaries."
}
fix_V-72853() {
   chown postgres ${PGDATA}/postgresql.conf
   chmod 0600 ${PGDATA}/postgresql.conf
   chown root:root /usr/pgsql-9.*/lib/*.so
   chmod 0755 /usr/pgsql-9.*/lib/*.so
   logger "FIXED:V-72853:CAT II:Privileges to change PostgreSQL software modules must be limited."
}
fix_V-72863() {
   CHK=`grep max_connections $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "max_connections = 500 '" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#max_connections\|max_connections\).*/max_connections = 500/g" $PGDATA/postgresql.conf
   fi
   runuser -l postgres -c psql < $CWD/V-72863.sql > $CWD/fix_V-72863.sql
   # clean up fix file
   sed -i '/\?column\?/d' $CWD/fix_V-72863.sql
   sed -i '/^---*./d' $CWD/fix_V-72863.sql
   sed -i '/([0-9].*/d' $CWD/fix_V-72863.sql
   # run fix file
   runuser -l postgres -c psql < $CWD/fix_V-72863.sql
   logger "FIXED:V-72863:CAT II:PostgreSQL must limit the number of concurrent sessions to an organization-defined number per user for all accounts and/or account types."
}

fix_V-72885() {
   CHK=`grep log_file_mode $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "log_file_mode = 0600" >> $PGDATA/postgresql.conf
   else
      # Grab the comment after the command
      STRING=`perl -ne '/(\s+# creation mode for log files,.*)/ && print($1)."" && exit' $PGDATA/postgresql.conf`
      # String found
      sed -i "s/\(#log_file_mode\|log_file_mode\).*/log_file_mode = 0600${STRING}/g" $PGDATA/postgresql.conf
   fi
   logger "FIXED:V-72885:CAT II:The audit information produced by PostgreSQL must be protected from unauthorized deletion."
}
fix_V-72891() {
   chown postgres:postgres ${PGDATA?}/postgresql.conf
   chmod 600 ${PGDATA?}/postgresql.conf
   logger "REVIEW:V-72891:CAT II:PostgreSQL must allow only the ISSM (or individuals or roles appointed by the ISSM) to select which auditable events are to be audited."
}
fix_V-72919() {
   logger "fix_V-72919 was fixed by fix_V-72843"
   logger "FIXED:V-72919:CAT II:PostgreSQL must generate audit records when categorized information (e.g., classification levels/security levels) is accessed."
}
fix_V-72921() {
   logger "fix_V-72921 was fixed by fix_V-72843"
   logger "FIXED:V-72921:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to access security objects occur."
}
fix_V-72923() {
   CHK=`grep log_connections $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "log_connections = on" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#log_connections\|log_connections\).*/log_connections = on/g" $PGDATA/postgresql.conf
   fi
   logger "log_line_prefix was fixed by fix_V-72843"
   logger "FIXED:V-72923:CAT II:PostgreSQL must generate audit records when unsuccessful logons or connection attempts occur."
}
fix_V-72925() {
   CHK=`grep log_connections $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "log_disconnections = on" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#log_disconnections\|log_disconnections\).*/log_disconnections = on/g" $PGDATA/postgresql.conf
   fi
   logger "log_line_prefix was fixed by fix_V-72843"
   logger "log_connections was fixed by fix_V-72923"
   logger "FIXED:V-72925:CAT II:PostgreSQL must generate audit records showing starting and ending time for user access to the database(s)."
}

fix_V-72927(){
   logger "fix_V-72927 was fixed by fix_V-72843"
   logger "FIXED:V-72927:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to modify security objects occur."
}
fix_V-72929() {
   logger "fix_V-72929 was fixed by fix_V-72843"
   logger "FIXED:V-72929:CAT II:PostgreSQL must generate audit records when privileges/permissions are added."
}
fix_V-72931() {
   CHK=`grep log_file_mode $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "shared_preload_libraries = 'pgaudit'" >> $PGDATA/postgresql.conf
   else
      # Grab the comment after the command
      STRING=`perl -ne '/(\s+\# \(change requires restart\).*)/ && print($1)."" && exit' $PGDATA/postgresql.conf`
      # String found
      sed -i "s/\(#shared_preload_libraries\|shared_preload_libraries\).*/shared_preload_libraries = 'pgaudit'${STRING}/g" $PGDATA/postgresql.conf
   fi
   logger "FIXED:V-72931:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to delete categorized information (e.g., classification levels/security levels) occur."
}
fix_V-72933() {
   logger "fix_V-72933 was fixed by fix_V-72843 and fix_V-72923"
   logger "FIXED:V-72933:CAT II:PostgreSQL must generate audit records when successful logons or connections occur."
}
fix_V-72939() {
   logger "fix_V-72939 was fixed by fix_V-72843"
   logger "FIXED:V-72939:CAT II:PostgreSQL must generate audit records when security objects are deleted."
}
fix_V-72941() {
   logger "fix_V-72941 was fixed by fix_V-72843"
   logger "FIXED:V-72941:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to retrieve privileges/permissions occur."
}
fix_V-72945() {
   logger "fix_V-72945 was fixed by fix_V-72843"
   logger "FIXED:V-72945:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to delete privileges/permissions occur."
}
fix_V-72947() {
   logger "fix_V-72947 was fixed by fix_V-72843 and fix_V-72931"
   logger "FIXED:V-72947:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to delete privileges/permissions occur."
}
fix_V-72949() {
   logger "fix_V-72949 was fixed by fix_V-72843 and fix_V-72931"
   logger "FIXED:V-72949:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to modify categorized information (e.g., classification levels/security levels) occur."
}

fix_V-72951() {
   logger "fix_V-72951 was fixed by fix_V-72843"
   logger "FIXED:V-72951:CAT II:PostgreSQL must generate audit records when unsuccessful accesses to objects occur."
}
fix_V-72953() {
   logger "fix_V-72931 was fixed by fix_V-72843"
   logger "FIXED:V-72953:CAT II:PostgreSQL must generate audit records for all privileged activities or other system-level access."
}
fix_V-72955() {
   logger "fix_V-72955 was fixed by fix_V-72843"
   logger "FIXED:V-72955:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to access categorized information (e.g., classification levels/security levels) occur."
}
fix_V-72957() {
   logger "fix_V-72957 was fixed by fix_V-72843 and by fix_V-72931"
   logger "FIXED:V-72957:CAT II:PostgreSQL must be able to generate audit records when security objects are accessed."
}
fix_V-72959() {
   logger "fix_V-72959 was fixed by fix_V-72843"
   logger "FIXED:V-72959:CAT II:PostgreSQL must generate audit records when privileges/permissions are deleted."
}
fix_V-72961() {
   logger "fix_V-72961 was fixed by fix_V-72923, fix_V-72925 and fix_V-72843"
   logger "FIXED:V-72961:CAT II:PostgreSQL must generate audit records when concurrent logons/connections by the same user from different workstations occur."
}
fix_V-72963() {
   logger "fix_V-72963 was fixed by fix_V-72931 and fix_V-72843"
   logger "FIXED:V-72963:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to delete security objects occur."
}
fix_V-72965() {
   logger "fix_V-72965 was fixed by fix_V-72931 and fix_V-72843"
   logger "FIXED:V-72965:CAT II:PostgreSQL must generate audit records when privileges/permissions are modified."
}
fix_V-72969() {
   logger "fix_V-72969 was fixed by fix_V-72843"
   logger "FIXED:V-72969:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to execute privileged activities or other system-level access occur."
}
fix_V-72971() {
   logger "fix_V-72971 was fixed by fix_V-72931 and fix_V-72843"
   logger "FIXED:V-72971:CAT II:PostgreSQL must generate audit records when security objects are modified."
}
fix_V-72973() {
   logger "fix_V-72973 was fixed by fix_V-72931 and fix_V-72843"
   logger "FIXED:V-72973:CAT II:PostgreSQL must generate audit records when categorized information (e.g., classification levels/security levels) is modified."
}

fix_V-72975() {
   logger "fix_V-72975 was fixed by fix_V-72843"
   logger "FIXED:V-72975:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to modify privileges/permissions occur."
}
fix_V-72977() {
   logger "fix_V-72977 was fixed by fix_V-72843"
   logger "FIXED:V-72977:CAT II:PostgreSQL must generate audit records when unsuccessful attempts to add privileges/permissions occur."
}
fix_V-72985() {
   logger "fix_V-72985 was fixed by fix_V-72843"
   logger "FIXED:V-72985:CAT II:PostgreSQL must generate time stamps, for audit records and application data, with a minimum granularity of one second."
}
fix_V-72987() {
   logger "fix_V-72987 was fixed by fix_V-72843"
   logger "FIXED:V-72987:CAT II:PostgreSQL must produce audit records containing sufficient information to establish the identity of any user/subject or process associated with the event."
}
fix_V-73001() {
   logger "fix_V-73001 was fixed by fix_V-72931"
   logger "FIXED:V-73001:CAT II:PostgreSQL must initiate session auditing upon startup."
}
fix_V-73005() {
   CHK=`grep log_hostname $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "log_hostname = on" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#log_hostname\|log_hostname\).*/log_hostname = on/g" $PGDATA/postgresql.conf
   fi
   logger "fix_V-73001 log_line_prefix was fixed by fix_V-72843"
   logger "FIXED:V-73005:CAT II:PostgreSQL must produce audit records containing sufficient information to establish the sources (origins) of the events."
}
fix_V-73015() {
   CHK=`grep password_encryption $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "password_encryption = on" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#password_encryption\|password_encryption\).*/password_encryption = on/g" $PGDATA/postgresql.conf
   fi
   logger "FIXED:V-73015:CAT II:If passwords are used for authentication, PostgreSQL must store only hashed, salted representations of passwords."
}

fix_V-73019() {
   CHK=`grep pgaudit.log_relation $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "pgaudit.log_relation = on" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#pgaudit.log_relation\|pgaudit.log_relation\).*/pgaudit.log_relation = on/g" $PGDATA/postgresql.conf
   fi
   logger "fix_V-73019 was fixed by fix_V-72923 and fix_V-72931"
   logger "FIXED:V-73019:CAT II:PostgreSQL must protect against a user falsely repudiating having performed organization-defined actions."
}
fix_V-73021(){
   logger "fix_V-73021 was fixed by fix_V-72843, fix_V-72925 and fix_V-72843"
   logger "FIXED:V-73019:CAT II:PostgreSQL must protect against a user falsely repudiating having performed organization-defined actions."
}
fix_V-73025() {
   CHK=`grep pgaudit.role $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "pgaudit.role = 'auditor'" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#pgaudit.role\|pgaudit.role\).*/pgaudit.role = 'auditor'/g" $PGDATA/postgresql.conf
   fi
   logger "fix_V-73025 shared_preload_libraries was fixed by fix_V-72931"
   logger "FIXED:V-73025:CAT II:PostgreSQL must provide the means for individuals in authorized roles to change the auditing to be performed on all application components, based on all selectable event criteria within organization-defined time thresholds."
}
fix_V-73033() {
   logger "fix_V-73033 was fixed by fix_V-72923, fix_V-72925 and fix_V-72843"
   logger "FIXED:V-73033:CAT II:PostgreSQL must produce audit records containing sufficient information to establish what type of events occurred."
}

fix_V-73037() {
   CHK=`grep statement_timeout $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "statement_timeout = 10000" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#statement_timeout\|statement_timeout\).*/statement_timeout = 10000/g" $PGDATA/postgresql.conf
   fi
   CHK=`grep net.ipv4.tcp_keepalive_time /etc/sysctl.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "net.ipv4.tcp_keepalive_time = 1000" >> /etc/sysctl.conf
   else
      # String found
      sed -i "s/\(#net.ipv4.tcp_keepalive_time\|net.ipv4.tcp_keepalive_time\).*/net.ipv4.tcp_keepalive_time = 1000/g" /etc/sysctl.conf
   fi
   CHK=`grep net.ipv4.tcp_keepalive_intvl /etc/sysctl.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "net.ipv4.tcp_keepalive_intvl = 1000" >> /etc/sysctl.conf
   else
      # String found
      sed -i "s/\(#net.ipv4.tcp_keepalive_intvl\|net.ipv4.tcp_keepalive_intvl\).*/net.ipv4.tcp_keepalive_intvl = 1000/g" /etc/sysctl.conf
   fi
   CHK=`grep net.ipv4.tcp_keepalive_probes /etc/sysctl.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "net.ipv4.tcp_keepalive_probes = 10" >> /etc/sysctl.conf
   else
      # String found
      sed -i "s/\(#net.ipv4.tcp_keepalive_probes\|net.ipv4.tcp_keepalive_probes\).*/net.ipv4.tcp_keepalive_probes = 10/g" /etc/sysctl.conf
   fi
   /sbin/sysctl -p
   logger "FIXED:V-73037:CAT II:PostgreSQL must invalidate session identifiers upon user logout or other session termination."
}
fix_V-73039() {
   chown -R postgres:postgres ${PGDATA?}
   chown -R root:root /usr/pgsql-9.*/share/contrib/pgaudit 2>/dev/null
   logger "NOTE: RUN SQL TO CHECK - FIX THIS TO BE AUTOMATED "
   logger "FIXED:V-73039:CAT II:PostgreSQL must protect its audit features from unauthorized access."
}
fix_V-73041() {
   logger "fix_V-73041 was fixed by fix_V-72843"
   logger "FIXED:V-73041:CAT II:PostgreSQL must produce audit records containing time stamps to establish when the events occurred."
}
fix_V-73043() {
   chown -R root:root /usr/pgsql-9*/bin
   chown -R root:root /usr/pgsql-9*/share
   chown -R root:root /usr/pgsql-9*/include
   logger "fix_V-73043 was fixed by fix_V-73039"
   logger "FIXED:V-73043:CAT II:PostgreSQL must protect its audit features from unauthorized removal."
}
fix_V-73045() {
   CHK=`grep log_destination $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "log_destination = 'syslog'" >> $PGDATA/postgresql.conf
   else
      # Grab the comment after the command
      STRING=`perl -ne '/(\s+\# Valid values are combinations of.*)/ && print($1)."" && exit' $PGDATA/postgresql.conf`
      # String found
      sed -i "s/\(#log_destination\|log_destination\).*/log_destination = 'syslog'${STRING}/g" $PGDATA/postgresql.conf
   fi
   CHK=`grep syslog_facility $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "syslog_facility = 'LOCAL0'" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#syslog_facility\|syslog_facility\).*/syslog_facility = 'LOCAL0'/g" $PGDATA/postgresql.conf
   fi
   CHK=`grep syslog_ident $PGDATA/postgresql.conf`
   if [ $? -eq 1 ]
   then
      # String not found, add it
      echo "syslog_ident = 'postgres'" >> $PGDATA/postgresql.conf
   else
      # String found
      sed -i "s/\(#syslog_ident\|syslog_ident\).*/syslog_ident = 'postgres'/g" $PGDATA/postgresql.conf
   fi
   logger "FIXED:V-73045:CAT II:PostgreSQL must off-load audit data to a separate log management facility; this must be continuous and in near real time for systems with a network connection to the storage facility and weekly or more often for stand-alone systems."
}
fix_V-73061() {
   chown postgres:postgres ${PGDATA?}/*.conf
   chmod 0600 ${PGDATA?}/*.conf
   logger "fix_V-73061 was fixed by fix_V-72885"
   logger "FIXED:V-73061:CAT II:PostgreSQL must protect its audit configuration from unauthorized modification."
}
fix_V-73065() {
   logger "fix_V-73065 was fixed by fix_V-72843 and fix_V-72931"
   logger "FIXED:V-73065:CAT II:Audit records must be generated when categorized information (e.g., classification levels/security levels) is deleted."
}
fix_V-73067() {
   logger "fix_V-73067 was fixed by fix_V-72843 and fix_V-72931"
   logger "FIXED:V-73067:CAT II:PostgreSQL must generate audit records when successful accesses to objects occur."
}
fix_V-73069() {
   logger "fix_V-73069 was fixed by fix_V-72843, fix_V-72923 and fix_V-72925"
   logger "FIXED:V-73069:CAT II:PostgreSQL must generate audit records for all direct access to the database(s)."
}
fix_V-73123() {
   logger "fix_V-73123 was fixed by fix_V-72843"
   logger "FIXED:V-73123:CAT II:PostgreSQL must produce audit records containing sufficient information to establish where the events occurred."
}
######################
####### main #########
######################
# Run as root.  Assumes that pgaudit11_96 RPMS are accessible and will be installed.
# Set up our globals
PGAUDITRPM=pgaudit11_96-1.1.1-1.rhel7.x86_64.rpm
PGAUDITDEBUGRPM=pgaudit11_96-debuginfo-1.1.1-1.rhel7.x86_64.rpm
SCRIPT=`realpath $0`
CWD=`dirname $SCRIPT`
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root"
   exit 1
fi
# Log file
LOGFILE=stig_fix_`date +%Y%m%d-%H%M%S`.log
check_pgdata $1
# Backup the postgresql.conf file
cp -rfp $PGDATA/postgresql.conf $PGDATA/postgresql.conf.`date +%Y%m%d-%H%M%S`
check_rpm_files
check_rpms
# 52 fixes
fix_V-72843
fix_V-72847
fix_V-72851
fix_V-72853
fix_V-72863
fix_V-72885
fix_V-72891
fix_V-72919
fix_V-72921
fix_V-72923
fix_V-72925
fix_V-72927
fix_V-72929
fix_V-72931
fix_V-72933
fix_V-72939
fix_V-72941
fix_V-72945
fix_V-72947
fix_V-72949
fix_V-72951
fix_V-72953
fix_V-72955
fix_V-72957
fix_V-72959
fix_V-72961
fix_V-72963
fix_V-72965
fix_V-72969
fix_V-72971
fix_V-72973
fix_V-72975
fix_V-72977
fix_V-72985
fix_V-72987
fix_V-73001
fix_V-73005
fix_V-73015
fix_V-73019
fix_V-73021
fix_V-73025
fix_V-73033
fix_V-73037
fix_V-73039
fix_V-73041
fix_V-73043
fix_V-73045
#fix_V-73047 - Easy fix with ssl=on in postgresql.conf
fix_V-73065
fix_V-73061
fix_V-73067
fix_V-73069
fix_V-73123


Place the V-72863.sql file in the same directory as the pg_9.6.5_stig_fixes.sh file:

-- V-72863.sql SQL file
SELECT 'ALTER ROLE '||rolname||' CONNECTION LIMIT 100;'
FROM pg_roles
WHERE rolconnlimit = -1
AND rolname <> 'pg_signal_backend';