Amazon RDS for PostgreSQL이 로그 파일에서 일반 텍스트를 암호를 로깅하지 못하게 하려면 어떻게 해야 합니까?

최종 업데이트 날짜: 2021년 2월 17일

PostgreSQL용 Amazon Relational Database Service(Amazon RDS)를 사용하여 CREATE USER 또는 ALTER USER 문을 실행하고 싶습니다. 이렇게 하면 PostgreSQL이 로그 파일에 일반 텍스트로 암호를 로깅합니다. PostgreSQL이 로그 파일에서 일반 텍스트로 암호를 표시하지 못하게 하려면 어떻게 해야 합니까?

간략한 설명

log_statement 파라미터를 ddl 또는 all로 설정하고 CREATE ROLE/USER... WITH PASSWORD ... 또는 ALTER ROLE/USER ... WITH PASSWORD ... 명령을 실행할 경우, PostgreSQL가 PostgreSQL 로그에 항목을 생성합니다. PostgreSQL은 일반 텍스트로 암호를 로깅하는데, 이는 보안 위험을 초래할 가능성이 있습니다.

현재 PostgreSQL은 민감한 정보를 식별하지 않습니다. PostgreSQL 엔진이 그렇게 설계되어 있으므로 이는 정상적인 동작입니다.

이 예제에서는 암호를 포함하여 CREATE ROLE 문을 실행하고, 로그에서 일반 텍스트로 비밀번호를 표시합니다.

USER@postgresdb:pg> CREATE ROLE test_role WITH PASSWORD 'test123';
CREATE ROLE
Time: 0.003s

로그의 출력:

2020-04-15 14:57:29 UTC:x.x.x.x(42918):USER@pg:[13790]:LOG: statement: CREATE ROLE test_role WITH PASSWORD 'test123'

이 예제에서는 암호를 포함하여 ALTER ROLE 문을 실행하고, 로그에서 일반 텍스트로 암호를 표시합니다.

USER@postgresdb:pg> ALTER ROLE test_role WITH PASSWORD 'test';
You're about to run a destructive command.
Do you want to proceed? (y/n): y
Your call!
ALTER ROLE
Time: 0.004sOutput in the logs:

로그의 출력:

2020-04-15 14:59:45 UTC:x.x.x.x(42918):USER@pg:[13790]:STATEMENT: ALTER ROLE test_role SET PASSWORD 'test'

해결 방법

동적 변수와 함께 PSQL 클라이언트를 사용하여 암호 전달

-c 옵션과 함께 PSQL 클라이언트를 사용하여 CREATE ROLE/AFTER ROLE 명령을 전달합니다. 동적 변수를 사용할 수도 있습니다. 이렇게 하면 PostgreSQL가 로그에 암호를 로깅하지 않습니다. 아래 예제를 참조하세요.

[ec2-user@ip-x.x.x.x ~]$ psql --host=xxxxxxxxxxx.eu-west-1.rds.amazonaws.com --port=5432 --username=USER --dbname=pg -c "create user aaa with password ':pass'" -v pass=test123
Password for user USER:
CREATE ROLE

로그의 출력:

2020-04-08 15:19:32 UTC:x.x.x.x(32974):USER@pg:[5797]:LOG: statement: create user aaa with password ':pass'

PGAudit 플러그인 사용

pgaudit 확장을 사용하여 PostgreSQL 로그에서 암호를 삭제합니다.

  1. Amazon RDS PostgreSQL 인스턴스에 대해 pgaudit을 활성화합니다.
  2. 고객 파라미터 그룹에서 pgaudit.log 파라미터를 설정하여 로깅할 문 클래스를 지정합니다. 이 파라미터는 DDL, role, write, read 등 다양한 값을 입력할 수 있습니다.

참고: pgaudit.log='DDL'과 log_statement='DDL'의 가장 큰 차이점은 pgaudit, DDL은 Postgres 로그에 CREATE/ALTER ROLE 쿼리를 기록하지 않는다는 것입니다.

ROLE을 pgaudit.log에 추가하면 CREATE/ALTER ROLE을 로깅할 수 있습니다. 그러면 암호가 삭제됩니다.

로그의 출력:

2020-07-09 13:33:50 UTC:x.x.x.x(58670):grysa@pg:[26513]:LOG:  
AUDIT: SESSION,3,1,ROLE,CREATE ROLE,,,CREATE ROLE test_role WITH LOGIN 
PASSWORD <REDACTED>,<not logged>

트랜잭션 블록의 세션에서 log_statement를 none으로 설정

트랜잭션 블록의 세션에서 log_statement를 none으로 설정하여 PostgreSQL이 작업을 기록하지 못하도록 완전히 차단합니다.

참고: pgaudit.log와 log_statement가 DDL로 설정되면 세션에서 log_statement를 none으로 설정해야 합니다.

예:

BEGIN;
SET LOCAL log_statement = 'none';
ALTER ROLE ... WITH PASSWORD ...;
COMMIT;

로컬에서 암호 해시 생성

로컬에서 암호 해시를 생성한 다음, 역할이나 사용자 암호를 생성하거나 변경할 때 그 해시를 사용합니다.

참고: 문을 실행하기 위해 생성하고 사용하는 해시는 여전히 로그에 표시됩니다. 이 해시를 복호화할 수는 있지만 일반 텍스트로 로깅되지는 않습니다.

예:

[ec2-user@ip-x.x.x.x ~]$ username='test_1'; dbpass='test123'; echo -n "${dbpass}${username}" | md5sum | awk '{print "md5" $1}'
md574e183386ccb9039d0537aeb03c03db9

USER@postgresdb:pg> CREATE ROLE test_1 WITH PASSWORD 'md574e183386ccb9039d0537aeb03c03db9';
CREATE ROLE
Time: 0.003s

로그의 출력:

2020-04-15 15:12:08 UTC:x.x.x.x(42918):grysa@pg:[13790]:LOG: statement: CREATE ROLE test_1 WITH PASSWORD 
'md574e183386ccb9039d0537aeb03c03db9'

\password 명령 사용

PostgreSQL을 사용할 때는 PostgreSQL 클라이언트에 내장된 \password 함수를 사용할 수 있습니다. 이렇게 하면 기존 역할 암호를 생성하거나 변경할 때 새 암호를 입력하라는 메시지가 나옵니다. PostgreSQL은 그 암호에 대한 해시만 로깅합니다.

참고: 이 솔루션은 Postgres 로그에 암호 해시를 표시하지만 일반 텍스트로 로깅하지는 않습니다.

다음 명령을 실행합니다.

pg=> CREATE ROLE test_role NOLOGIN;
CREATE ROLE
pg=> \password test_role
Enter new password:
Enter it again:
pg=> ALTER ROLE test_role LOGIN;
ALTER ROLE
pg=>

로그의 출력:

2020-04-09 12:29:29 UTC:x.x.x.x(39876):grysa@pg:[1879]:LOG: statement: CREATE ROLE test_role NOLOGIN;
2020-04-09 12:30:02 UTC:x.x.x.x(39876):grysa@pg:[1879]:LOG: statement: show password_encryption
2020-04-09 12:30:02 UTC:x.x.x.x(39876):grysa@pg:[1879]:LOG: statement: ALTER USER test_role PASSWORD 'md5175cad7c36a640b1fcfa0144056923f5'
2020-04-09 12:30:30 UTC:x.x.x.x(39876):grysa@pg:[1879]:LOG: statement: ALTER ROLE test_role LOGIN;