DevOps

Redis 보안 접근제어 ACL 적용

IT오이시이 2025. 7. 14. 10:41
728x90

 [Redis Architecture] 


 

Redis 보안 접근제어 ACL 적용

 

Redis사용자 , 접근하는 Client의 기능 권한, 정보 조회, Client IP등을  제어 할 수 있다.

redis.conf의 bind를 통해 클라이언트를 제어 한다는 내용은 오역된 내용들이 많아 언급하고 사용자 acl을 정의하는 방법을 정리하고자 한다.

bind 0.0.0.0  or   bind 127.0.0.1   or bind  server_ip       

* bind는 서비스 서버의 IP 네트워크를 정의하는 것이다.    bind  clients_ip  개념이 아님을 ....  

 

🔐 Redis ACL 관련 핵심

1. 사용자 관리

ACL SETUSER ... 사용자 생성 또는 업데이트
ACL DELUSER 사용자 삭제
ACL LIST 모든 사용자 목록 및 권한 확인
ACL GETUSER 특정 사용자에 대한 상세 설정 조회
ACL SAVE 현재 ACL 구성을 redis.acl 파일로 저장

 

 

2. 사용자 권한 설정 요소

on / off 계정 활성화 여부 설정
>password 비밀번호 설정 (예: >mypassword)
~ 키에 대한 접근 제어 (예: ~user:*로 특정 prefix 키만 접근 허용)
+ / +@ 명령어 또는 명령어 그룹에 대한 권한 설정 (+get, +@read)
- / -@ 특정 명령어 또는 그룹에 대해 권한 제거
reset 모든 권한과 설정 초기화

💡 +@all은 모든 명령어 권한을 부여하는 설정입니다. 보안상 권한 최소화 원칙(least privilege)을 지키는 것이 좋습니다.

 

 

3. IP 기반 접근 제한

 - 다음과 같이 클라이언트의 IP를 제안하는 방법을 기술 한다.

ipaddr 192.168.0.0/16 특정 IP 대역에서만 접속 허용
ipaddr 10.10.10.10/32 -@deny 특정 단일 IP에 대해 접속 차단

 

 

4. Redis ACL Best Practices

권한 최소화: 필요 명령어만 허용 (+get +set 등)

키 범위 제한: ~prefix:* 설정으로 키 접근 범위 지정

IP 제한 활성화: 내부 네트워크 또는 신뢰된 IP만 허용

ACL 파일 저장: ACL SAVE로 설정을 파일에 기록하고 redis.conf에서 자동 로딩 설정

테스트 사용자로 검증: 운영 사용자 설정 전에 테스트 계정으로 접속 확인

🧩 Redis Enterprise를 사용하면 이 ACL 기능이 더욱 확장되어 LDAP 인증, RBAC(역할 기반 접근 제어), 감사 로그 등을 통해 더욱 정교한 보안 통제를 할 수 있어요.

 

📌 명령어 구조

bash
ACL SETUSER <username> <flags> <passwords> <allowed commands> <allowed keys>

🧠 해석: appuser 사용자 설정

bash
ACL SETUSER appuser on >appass ipaddr 10.0.2.15/8 +@read ipaddr 192.168.1.100/32 -@all

명령어 설명
appuser 사용자 이름
on 사용자 활성화
>appass 비밀번호 설정 (appass)
ipaddr 10.0.2.15/8 이 IP 범위에서만 접근 허용
+@read 읽기 명령 그룹 허용 (GET, MGET, EXISTS 등)
ipaddr 192.168.1.100/32 이 IP에서도 접근 허용
-@all 다른 모든 명령어는 기본적으로 금지

즉, appuser는 다음 조건을 만족해야 Redis에 접근할 수 있습니다:

  • IP가 10.0.2.0/8 또는 192.168.1.100일 것
  • 비밀번호 appass를 사용할 것
  • 읽기 명령만 사용할 수 있음 (+@read)
  • 다른 모든 명령은 금지됨 (-@all)

 


Redis ACL 적용 예시

  • Redis를 이용한 사용자 패스워드와 client 접속 IP 컨트롤
redis-cli ACL SETUSER myuser <password> \
  ipaddr 192.168.1.0/24 +@allow \
  ipaddr 192.168.2.100/32 -@deny

💡 실제 명령어에서는 부분을 사용자 비밀번호로 교체해야 합니다.

$ redis-cli ACL LOAD /etc/redis/users.acl
Loading ACL file... done.

$ redis-cli ACL SET myuser <my_password>
OK

# Verify that the user and password are set correctly:
$ redis-cli ACL GET myuser
+@allow:ipaddr 192.168.1.0/24
-@deny:ipaddr 192.168.2.100/32

redis-cli ACL SET myuser <password> ipaddr 192.168.1.0/24 +@allow ipaddr 192.168.2.100/32 -@deny

# ACL SET: This is the Redis ACL command to set or update an ACL rule.
# *myuser: The username (in this case, "myuser") that you want to apply these rules to.
# <password>: The password associated with the myuser account. You should replace this with your actual password.
# ipaddr 192.168.1.0/24 +@allow: This rule allows connections from IP addresses within the range of 192.168.1.0/24.
# ipaddr 192.168.2.100/32 -@deny: This rule denies connections from a specific IP address (192.168.2.100).

 

 

🧾 명령어 설명

   
ACL SETUSER ACL 규칙을 특정 사용자에게 설정하거나 업데이트하는 명령어
myuser 대상 사용자 이름
  사용자 비밀번호 설정. 생략하면 인증 없이 접근 가능
ipaddr 192.168.1.0/24 +@allow 192.168.1.0/24 대역 IP에서 접근을 허용
ipaddr 192.168.2.100/32 -@deny 192.168.2.100 단일 IP는 접근을 거부

 

 

  ACL 저장 및 적용

Redis는 ACL 규칙을 redis.acl 파일에 저장하여 재시작 후에도 규칙을 유지할 수 있습니다.

  1. 명령어 입력으로 사용자 규칙 적용
  2. ACL 변경 사항을 파일로 내보내기:
  3. acl 파일 저장
  4. redis-cli ACL SAVE
  5. 저장된 ACL 파일 경로는 redis.conf의 aclfile 설정 항목에서 확인할 수 있어요.

 

✅ 추가  Selinux

  1. redis-cli ACL SAVE  을 실행하면    /etc/redis/users.conf 파일에 설정 내용을 업데이트 하게 되는데 아래와 같이 SElinux의 오류가 발생하는 경우 조치 방안입니다.
SELinux는 /usr/bin/redis-server unlink에서 파일가 users.acl 액세스하지 못하게 합니다.
redis_conf_t, redis_log_t, redis_tmp_t, redis_var_lib_t, redis_var_run_t.#012그런 후 실행합니다

. ACL 파일에 적절한 SELinux 컨텍스트 지정

sudo semanage fcontext -a -t redis_var_lib_t '/etc/redis/users.acl'

* redis_var_lib_t는 Redis가 /var/lib/redis 같은 데이터 파일에 접근할 때 사용하는 SELinux 타입입니다.

 

2. 컨텍스트 적용

sudo restorecon -v '/etc/redis/users.acl'
 

3.  redis-cli ACL SAVE   : 을 실행하면 파일이 저장되어야 합니다.

 
 

✅ 추가 팁

  • ACL 설정은 Redis 6 이상에서 지원됩니다.
  • ACL 명령어는 사용자 인증 + 명령어 권한 + 접속 IP까지 통합 관리할 수 있는 강력한 보안 수단입니다.
  • 설정된 사용자는 ACL LIST, ACL GETUSER myuser, ACL DELUSER로 확인/관리 가능합니다.

 


🛡️ Redis 사용자 ACL 적용 예시

1. 사용자별 역할 분리

사용자역할권한 설정

사용자 역할 권한 설정
readonly 조회 전용 사용자 +@read -@write ~data:*
admin 전체 권한 관리자 +@all ~*
publisher 데이터 쓰기 권한 +set +hset -@read ~data:*
ACL SETUSER readonly on >readonly_pw +@read -@write ~data:*
ACL SETUSER admin on >admin_pw +@all ~*
ACL SETUSER publisher on >publisher_pw +set +hset -@read ~data:*

 

 

2. IP 기반 접근 제한 예시

  • 특정 대역은 허용, 일부 IP는 차단:

bash

ACL SETUSER netuser on >net_pw ipaddr 10.0.0.0/8 +@read ipaddr 192.168.1.100/32 -@all

 

✅ 접근 허용: 10.0.0.0/8
❌ 접근 차단: 192.168.1.100

 

3. 키 패턴 제한

  • 특정 prefix 또는 데이터 범주에만 접근 허용:

bash

ACL SETUSER analyst on >analyst_pw +get +mget ~metrics:* ~logs:*

🔍 이 사용자에게는 metrics:*와 logs:*로 시작하는 키에 대해서만 get, mget 명령이 허용됩니다.

 

4. ACL 파일 저장 및 적용 흐름

1️⃣ 사용자 설정:

bash

redis-cli ACL SETUSER appuser on >apppass +@read ~app:data:*

2️⃣ 변경사항 저장:

bash

redis-cli ACL SAVE

3️⃣ ACL 파일 내용 확인 (/etc/redis/users.acl 예시):

user appuser on >apppass +@read ~app:data:*

4️⃣ Redis 설정 파일(redis.conf) 적용:

aclfile /etc/redis/users.acl

Redis를 재시작하면 해당 ACL 규칙이 자동 로딩됩니다.

 

 

 

🧠 실무 적용 팁

  • 비밀번호 암호화는 Redis 내부에서 처리되며, 파일에 평문으로 저장되므로 서버 파일 접근 권한도 철저히 관리하세요.
  • ✅ 변경 후 반드시 ACL SAVE를 실행해야 파일에 반영됩니다.
  • 🔒 ACL은 Redis 6 이상에서만 지원됩니다.
  • 🧪 redis-cli -u redis://:6379 -a 로 테스트 로그인 후 권한 확인 가능

 

 

Docker를 이용한 Redis 설정


Podman-Docker(docker 명령어 호환)를 사용해 Redis 컨테이너를 띄우고, appuser 계정에 비밀번호·읽기 권한·키 패턴·접속 IP 제한을 적용하는 방법입니다.

1. 사전 준비

  • Podman-Docker 설치 (Ubuntu 기준)
    bash
    sudo apt update
    sudo apt install -y podman-docker
    
  • 작업 디렉터리 생성
    mkdir -p ~/redis-conf
    cd ~/redis-conf
    

2. 설정 파일 작성

2.1 redis.conf

파일명: redis.conf

conf
bind 0.0.0.0
port 6379

# ACL 파일 경로 지정
aclfile /etc/redis/users.acl

 

2.2 users.acl

파일명: users.acl 설정 내용:

conf
# 기본 사용자 비활성화 (보안 강화)
user default off

# appuser 계정 정의
user appuser on >apppass    \
  +@read                    \
  ~app:data:*               \
  ipaddr=192.168.1.100/32
  • on : 계정 활성화
  • >apppass : 비밀번호 설정
  • +@read : 읽기 명령어 그룹 허용
  • ~app:data:* : app:data: 접두사 키만 접근 허용
  • ipaddr=…/32 : 192.168.1.100 단일 IP에서만 접속 허용

 

3. Redis 컨테이너 실행

 

다음과 같이 Redis 컨테이너를 실행 합니다.

podman run -d --name redis \
  -v $(pwd)/redis.conf:/etc/redis/redis.conf:Z \
  -v $(pwd)/users.acl:/etc/redis/users.acl:Z \
  -p 6379:6379 \
  docker.io/library/redis:8 \
  redis-server /etc/redis/redis.conf
  • -d  : 백그라운드 실행
  • --name redis   : 컨테이너 이름 "redis" 지정
  • -v …:Z : SELinux 환경에서도 마운트 권한 보장
  • -p  6379:6379  :  호스트와 컨테이너 포트 매핑
  • redis:8 : Redis 8 공식 이미지 사용
  • 마지막 인자로 redis.conf 경로 지정 하여 실행

 

# 작동 상태 확인
podman ps      : 작동중인 컨테이너 조회
podman ps -a   : 작동하지 않는 컨테이너 포함 조회

podman logs redis

redis-cli -h 127.0.0.1 -p 6379

 

시스템 재부팅시 자동 시작 설정

# Podman은 데몬리스 구조이므로 systemd와 연동해 자동 실행할 수 있습니다:


$podman generate systemd --name redis --files --new


# 생성된 .service 파일을 /etc/systemd/system/에 복사하고 활성화:
$sudo cp container-redis.service /etc/systemd/system/
$sudo systemctl daemon-reload
$sudo systemctl enable --now container-redis.service

 

(참고) Podman 3.0 이상에서는 --replace 옵션을 사용하면 기존 컨테이너를 자동으로 제거하고 새로 생성할 수 있어요:

podman run --replace -d --name redis \
  -v $(pwd)/redis.conf:/etc/redis/redis.conf:Z \
  -v $(pwd)/users.acl:/etc/redis/users.acl:Z \
  -p 6379:6379 \
  docker.io/library/redis:8 \
  redis-server /etc/redis/redis.conf

 

기존 컨테이너 재실행: podman start

# 기존 컨테이너 재실행: podman start
podman start redis

 

4. ACL 설정 검증

 

1. appuser 정보 확인

bash
podman exec -it redis redis-cli ACL GETUSER appuser

출력 예시:

1) "flags"
2) 1) "on"
3) "passwords"
4) 1) "afe1d2... (해시)"
5) "commands"
6) 1) "@read"
7) "keys"
8) 1) "app:data:*"
9) "selectors"
10) 1) "192.168.1.100/32"

 

2. 실제 접속 테스트

bash
redis-cli -h 127.0.0.1 -p 6379 -u redis://appuser:apppass@127.0.0.1:6379 \
  GET app:data:1
  • 허용된 IP 및 키 패턴이므로 정상 실행
  • 차단된 IP에서 실행 시 NOAUTH 또는 NOPERM 오류 발생

 

5. 운영 팁

  • /etc/redis/users.acl 파일을 직접 편집한 다음 podman exec redis redis-cli ACL LOAD 로 즉시 반영 가능
  • 비밀번호는 파일에 해시된 형태로 저장되지만, ACL 파일 권한(600) 관리 필수
  • 필요 시 여러 IP 대역, 키 패턴, 명령어 그룹을 추가해 최소 권한 원칙 적용

 

https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/


https://semaphore.io/blog/redis-architectures

 

 

 

🔍 (참고) Redis 컨테이너 정보 확인 명령어

 
기능 명령어 설명
컨테이너 목록 확인 podman ps -a 실행 중 또는 중지된 모든 컨테이너 목록
Redis 컨테이너 상세 정보 podman inspect redis 환경 변수, 포트, 이미지, 마운트 정보 등 JSON 형식으로 출력
Redis 로그 확인 podman logs redis Redis 서버의 stdout/stderr 로그 출력
Redis 프로세스 확인 podman top redis 컨테이너 내부에서 실행 중인 프로세스 목록
Redis 이미지 정보 podman images 로컬에 저장된 Redis 이미지 정보
Redis 컨테이너 IP 확인 podman inspect -f '{{.NetworkSettings.IPAddress}}' redis 컨테이너의 내부 IP 주소 출력

 

 

 

redis.conf

  *    grep -v "#" redis.conf | grep -v "^$" >  a.conf

더보기

bind 0.0.0.0
protected-mode yes
port 6379

tcp-backlog 511
timeout 0
tcp-keepalive 300

daemonize no

pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log


aclfile /etc/redis/users.acl

databases 16
always-show-logo no
set-proc-title yes
proc-title-template "{title} {listen-addr} {server-mode}"
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no

dir /var/lib/redis

replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100


acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
lazyfree-lazy-user-flush no

oom-score-adj no
oom-score-adj-values 0 200 800

disable-thp yes
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes

lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128

latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes

client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes

728x90
반응형