V-72925
Severity: Medium
Generated
2019-05-20 15:48:11.984914
Status
PostgreSQL must generate audit records showing starting and ending time for user access to the database(s).
NIST 800-53
STIG # | Description | Result |
---|---|---|
AU-12 | AU-12: Audit Generation | failed |
Guidance
For completeness of forensic analysis, it is necessary to know how long a user’s (or other principal’s) connection to PostgreSQL lasts. This can be achieved by recording disconnections, in addition to logons/connections, in the audit logs. Disconnection may be initiated by the user or forced by the system (as in a timeout) or result from a system or network failure. To the greatest extent possible, all disconnections must be logged.
Check
Note: The following instructions use the PGDATA environment
variable. See supplementary content APPENDIX-F for instructions on configuring
PGDATA.
First, log into the database with the postgres user by running the following
commands:
$ sudo su - postgres
$ psql -U postgres
Next, as the database administrator, verify the log for a connection audit trail:
$ sudo su - postgres
$ cat ${PGDATA?}/pg_log/postgresql-Tue.log
< 2016-02-23 20:25:39.931 EST postgres 56cfa993.7a72 postgres: >LOG: connection
authorized: user=postgres database=postgres
< 2016-02-23 20:27:45.428 EST postgres 56cfa993.7a72 postgres: >LOG:
AUDIT: SESSION,1,1,READ,SELECT,,,SELECT current_user;,
Fix
Note: The following instructions use the PGDATA environment variable. See supplementary content APPENDIX-F for instructions on configuring PGDATA. To ensure that logging is enabled, review supplementary content APPENDIX-C for instructions on enabling logging. If logging is enabled the following configurations must be made to log connections, date/time, username, and session identifier. First, as the database administrator (shown here as “postgres”), edit postgresql.conf by running the following: $ sudo su - postgres $ vi ${PGDATA?}/postgresql.conf Edit the following parameters: log_connections = on log_disconnections = on log_line_prefix = ‘< %m %u %c: >’ Where: * %m is the time and date * %u is the username * %c is the session ID for the connection Now, as the system administrator, reload the server with the new configuration: # SYSTEMD SERVER ONLY $ sudo systemctl reload postgresql-9.5 # INITD SERVER ONLY $ sudo service postgresql-9.5 reload
Test Results
Result | |
---|---|
Command: `sed -nre '/2019-05-16 08:11.*LOG:\s+starting tests for V-72925/,$p' /var/vcap/sys/log/postgresql/Thu.pg_log` stdout should match /2019-05-16 08:11.*LOG: +connection authorized:\s+user=crunchy +database=stig_test_db/ | passed |
Command: `sed -nre '/2019-05-16 08:11.*LOG:\s+starting tests for V-72925/,$p' /var/vcap/sys/log/postgresql/Thu.pg_log` stdout should match /2019-05-16 08:11.*LOG:\s+disconnection: session time:.*user=crunchy\s+database=stig_test_db\s+host=(localhost|127.0.0.1)/ | passed |
Code
control "V-72925" do
title "PostgreSQL must generate audit records showing starting and ending time
for user access to the database(s)."
desc "For completeness of forensic analysis, it is necessary to know how long
a user's (or other principal's) connection to PostgreSQL lasts. This can be
achieved by recording disconnections, in addition to logons/connections, in
the audit logs.
Disconnection may be initiated by the user or forced by the system (as in a
timeout) or result from a system or network failure. To the greatest extent
possible, all disconnections must be logged."
impact 0.5
tag "severity": "medium"
tag "gtitle": "SRG-APP-000505-DB-000352"
tag "gid": "V-72925"
tag "rid": "SV-87577r1_rule"
tag "stig_id": "PGS9-00-004700"
tag "cci": "CCI-000172"
tag "nist": ["AU-12 c", "Rev_4"]
tag "check": "Note: The following instructions use the PGDATA environment
variable. See supplementary content APPENDIX-F for instructions on configuring
PGDATA.
First, log into the database with the postgres user by running the following
commands:
$ sudo su - postgres
$ psql -U postgres
Next, as the database administrator, verify the log for a connection audit trail:
$ sudo su - postgres
$ cat ${PGDATA?}/pg_log/postgresql-Tue.log
< 2016-02-23 20:25:39.931 EST postgres 56cfa993.7a72 postgres: >LOG: connection
authorized: user=postgres database=postgres
< 2016-02-23 20:27:45.428 EST postgres 56cfa993.7a72 postgres: >LOG:
AUDIT: SESSION,1,1,READ,SELECT,,,SELECT current_user;,<none>
< 2016-02-23 20:27:47.988 EST postgres 56cfa993.7a72 postgres: >LOG:
disconnection: session time: 0:00:08.057 user=postgres database=postgres
host=[local]
If connections are not logged, this is a finding."
tag "fix": "Note: The following instructions use the PGDATA environment
variable. See supplementary content APPENDIX-F for instructions on configuring
PGDATA.
To ensure that logging is enabled, review supplementary content APPENDIX-C for
instructions on enabling logging.
If logging is enabled the following configurations must be made to log
connections, date/time, username, and session identifier.
First, as the database administrator (shown here as \"postgres\"), edit
postgresql.conf by running the following:
$ sudo su - postgres
$ vi ${PGDATA?}/postgresql.conf
Edit the following parameters:
log_connections = on
log_disconnections = on
log_line_prefix = '< %m %u %c: >'
Where:
* %m is the time and date
* %u is the username
* %c is the session ID for the connection
Now, as the system administrator, reload the server with the new configuration:
# SYSTEMD SERVER ONLY
$ sudo systemctl reload postgresql-9.5
# INITD SERVER ONLY
$ sudo service postgresql-9.5 reload"
sql = postgres_session(PG_DBA, PG_DBA_PASSWORD, PG_HOST)
log_directory_query = sql.query('SHOW log_directory;', [PG_DB])
log_directory = log_directory_query.output
current_log_command = "ls -1t #{log_directory}/*.pg_log | head -1"
current_log = command(current_log_command).stdout.strip
control = File.basename(__FILE__, File.extname(__FILE__))
message = "starting tests for #{control}"
message_sql = "DO language plpgsql $$ BEGIN "\
"RAISE LOG '#{message}'; END $$;"
start = Time.now.strftime('%Y-%m-%d %H:%M')
get_logs = "sed -nre '/#{start}.*LOG:\\s+#{message}/,$p' #{current_log}"
time = Time.now
timestamp = time.strftime('%Y-%m-%d %H:%M')
host = PG_HOST == '127.0.0.1' ? "(localhost|#{PG_HOST})" : PG_HOST
connection_message = "#{timestamp}.*LOG:\s+connection authorized:"\
"\\s+user=#{PG_DBA}\s+database=#{PG_DB}"
connection_regex = Regexp.new(connection_message)
disconnection_message = "#{timestamp}.*LOG:\\s+disconnection: session time:"\
".*user=#{PG_DBA}\\s+database=#{PG_DB}\\s+host=#{host}"
disconnection_regex = Regexp.new(disconnection_message)
sql.query(message_sql, [PG_DB])
sql.query('SELECT now();', [PG_DB])
describe command(get_logs) do
its('stdout') { should match connection_regex }
its('stdout') { should match disconnection_regex }
end
end