Reference address: https://blog.csdn.net/weixin_34143774/article/details/89561946 , please use the original text mainly, and cite the source.
Question: The company conducts software evaluation today. During the evaluation, the evaluator asked about the number of times the user was locked due to a failed PostgreSQL login. How many times did the account be locked if the password was entered incorrectly?
I searched the Internet for a while. Both Oracle and MySQL have related settings. Only the pg library does not find the related setting parameters. I stumbled upon a post on the Internet and found that the PG library does not yet support related settings.
Quote below:
Database password management is one of the important links of database security. Password management and configuration strategies mainly include:
- Password encrypted storage
- Password validity period
- Password complexity
- Password verification failed delay
- Password verification failure times limit, lock after failure, and unlock time
- When setting a password to prevent the password from being recorded in the database log, the
following will explain how to implement password-related security configuration in PostgreSQL.
1. Password encrypted storage
The password in pg is always stored in the system directory in an encrypted manner. The ENCREPED keyword has no effect, but is accepted for backward compatibility. The encryption method can be configured through the password_encryption parameter.
postgres=# show password_encryption; password_encryption --------------------- md5 (1 row) postgres=# select * from pg_shadow where usename='test'; usename | usesysid | usecreatedb | usesuper | userepl | usebypassrls | passwd | valuntil | usec onfig ---------+----------+-------------+----------+---------+--------------+-------------------------------------+------------------------+----- ------ test | 49156 | f | f | f | f | md52d308906cb4ea734a22f76e7927c046b | 2019-04-10 16:58:00+08 |
2. Password validity period
pg supports password validity period configuration. You can set a password replacement period by configuring the password validity period.
Validity of the setting server Postgres = # ALTER Role an until Test Valid ' 2019-04-10 16:58:00 ' ; the ALTER the ROLE Postgres = # SELECT * from pg_user WHERE usename = ' Test ' ; usename | usesysid | usecreatedb | with usesuper | userepl | usebypassrls | passwd | valuntil | the useconfig -------- + ---------- + ------------- + ---------- + ------ --- + -------------- + ---------- + -------------------- + ----------- ---- the Test | 49156 | f | f | f | f | ******** | 2019 - 04 - 10 16 : 58 : 00 + 08 | ( 1 row) Client connection test [ postgres @ pg2 ~ ] $ date Wed Apr 10 17 : 11 : 49 CST 2019 [postgres@pg2 ~]$ psql -h 192.168.6.12 -U test -d postgres -p 5432 Password for user test: psql: FATAL: password authentication failed for user "test"
note:
- The validity period of the pg password is only valid for the client, and the server is not limited.
- The network access control file cannot be configured as the trust authentication method
3. Password complexity strategy
The passwordcheck.so module can implement password complexity requirements. This module can check passwords. If the password is too weak, he will refuse to connect to
create a user or modify the user's password, forcibly restrict the complexity of the password, and restrict the password from being reused.
For example, the password length, Contains numbers, letters, uppercase and lowercase, special characters, etc., while excluding brute force cracking of strings in the dictionary
3.1, enable the module
Add '$ libdir / passwordcheck' to the parameter shared_preload_libraries, restart
so that the default so files are stored in the $ libdir directory
[pg@pg ~]$ ls -atl $LD_LIBRARY_PATH/passwordcheck* -rwxr-xr-x 1 pg pg 8640 Feb 1 14:23 /opt/postgres/lib/passwordcheck.so postgres=# select name,setting from pg_settings where name like '%dynamic%'; name | setting ----------------------------+--------- dynamic_library_path | $libdir dynamic_shared_memory_type | posix (2 rows) postgres=# alter system set shared_preload_libraries=pg_pathman,pg_stat_statements,passwordcheck; ALTER SYSTEM postgres=# 重启生效
3.2, complexity function verification
Password complexity check module Passwordcheck
- Verify that the created user password meets the rules.
Password: At least 8 characters; must contain numbers and letters; the password cannot contain a username field.
postgres=# alter role test with password 'test'; ERROR: password is too short postgres=# alter role test password '12345678'; ERROR: password must contain both letters and nonletters postgres=# alter role test with password 'test1234'; ERROR: password must not contain user name postgres=# alter role test with password 'tttt1234'; ALTER ROLE
4. Delay in password verification failure
The auth_delay.so module will cause the server to stay briefly before reporting an authentication failure. This is mainly used to prevent brute force cracking. After the authentication fails, a delay of one time window can continue the authentication. Please note that it will not prevent denial-of-service attacks, and may even exacerbate these attacks, because the process that is waiting before reporting an authentication failure will still use the connection slot.
4.1, enable the module
The following parameters need to be configured to achieve the password verification delay failure delay
so libdir files are stored in $ [ PG PG @ lib ] $ LS - ATL the LD_LIBRARY_PATH $ / auth_delay * - rwxr - XR - X . 1 PG PG 8432 On Feb . 1 14 : 23 is / opt / Postgres / lib / auth_delay.so parameter modification shared_preload_libraries - preloading module auth_delay.milliseconds ( int ) - Specifies the time delay Postgres = # ALTER System SET shared_preload_libraries=pg_pathman, pg_stat_statements, passwordcheck,auth_delay; ALTER SYSTEM 重启生效 postgres=# alter system set auth_delay.milliseconds=5000; ALTER SYSTEM reload生效
4.2, verification
[ PG PG @ ~ ] $ the psql - H 192.168 . 6.12 - the U-Test - P 5432 - D Postgres Password for User Test: - 5S the psql: FATAL: password authentication failed for User "Test" [ PG PG @ ~ ] $ input After the password, if the password is incorrect, it will wait 5s, and then return the password failure prompt [ pg @ pg ~ ] $ psql - h 192.168 . 6.12 - U test - p 5432 - d postgres Password for user test: psql ( 10.4 ) Type "help" for help. Postgres => After entering the password, if the password is correct, there is no waiting.
5. Restrictions on the number of password verification failures, lock after failure, and unlock time
Currently PostgreSQL does not support this security strategy, and currently only auth_delay can be used to extend the time of brute force cracking.
6. Prevent the password from being recorded in the database log when setting the password
Password configuration commands may be recorded in the history file and csvlog log file (if DDL or higher level audit log_statement is enabled), these files record the password in plain text, which may cause the risk of password leakage.
6.1. Password is recorded in two places
HISTFILE The file name that will be used to store the history list. If unset, the file name is taken from the PSQL_HISTORY environment variable. If that is not set either, the default is ~/.psql_history, or %APPDATA%\postgresql\psql_history on Windows. For example, putting: \set HISTFILE ~/.psql_history- :DBNAME in ~/.psqlrc will cause psql to maintain a separate history for each database. Note This feature was shamelessly plagiarized from Bash. --??!! csvlog 数据库错误日志
Case:
Such as the following command, will be recorded in the HISTFILE and csvlog logs postgres = # alter role test with password ' tttt1234 ' ; ALTER ROLE history file record [ pg @ pg ~ ] $ cat ~ / .psql_history | grep tttt1234 alter role test with password ' tttt1234 ' ; [ pg @ pg ~ ] $ csvlog record [ pg @ pg ~ ] $ cat $ PGDATA / postgresql.conf | grep log_statement #log_statement = 'none' # none, ddl, mod, all log_statement = 'ddl' #log_statement_stats = off [pg@pg ~]$ [pg@pg ~]$ cat $PGDATA/pg_log/postgresql-2019-04-12_092557.csv |grep tttt1234 2019-04-12 09:33:23.036 CST,"pg","postgres",1309,"[local]",5cafeadb.51d,3,"idle",2019-04-12 09:33:15 CST,3/21,0,LOG,00000,"statement: alter role test with password 'tttt1234';",,,,,,,,,"psql"
6.2. Solution
- Use the -W option of the createuser command-line tool to prompt for a password.
- Use the pg_md5 tool to generate the password, and use ALTER ROLE to fill in the md5 value in psql.
Similar to the above, pg_md5 is a tool provided by pgpool, which actually calls the above function.
[pg@pg ~]$ createuser -l -h 127.0.0.1 -p 5432 -U pg -W tuser Password: [pg@pg ~]$ [pg@pg ~]$ cat $PGDATA/pg_log/postgresql-2019-04-12_092557.csv |grep tuser 2019-04-12 11:17:48.348 CST,"pg","postgres",1574,"localhost:42560",5cb0035c.626,3,"idle",2019-04-12 11:17:48 CST,3/236,0,LOG,00000,"statement: CREATE ROLE tuser NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;",,,,,,,,,"createuser"