Ubuntu 22.04에 Redis 설치 및 보안 설정하는 방법

소개

Redis는 유연성, 성능 및 넓은 언어 지원으로 유명한 인메모리 키-값 저장소입니다. 이 자습서는 Ubuntu 22.04 서버에 Redis를 설치, 구성 및 보안하는 방법을 보여줍니다.

전제 조건

이 가이드를 완료하려면 sudo 권한이 있는 비 루트 사용자가 있는 Ubuntu 22.04 서버에 액세스해야 하며, ufw로 구성된 방화벽이 있어야 합니다. Ubuntu 22.04용 초기 서버 설정 가이드를 따라 이를 설정할 수 있습니다.

단계 1 — Redis 설치 및 구성

공식 Ubuntu 저장소에서 Redis를 설치하기 위해 APT 패키지 관리자를 사용할 것입니다. 작성 시점에서 기본 저장소에서 제공되는 버전은 6.0.16입니다.

로컬 apt 패키지 캐시를 업데이트하여 시작합니다:그런 다음 다음을 입력하여 Redis를 설치합니다:

  1. sudo apt update

그런 다음 Redis를 설치하려면:

  1. sudo apt install redis-server

이렇게 하면 Redis와 그 종속성을 다운로드하고 설치합니다. 이 후 Redis 구성 파일에 중요한 구성 변경 사항을 만들어야 합니다. 이 파일은 설치 중에 자동으로 생성되었습니다.

원하는 텍스트 편집기로 이 파일을 엽니다:

  1. sudo nano /etc/redis/redis.conf

파일 내에서 supervised 지시문을 찾습니다. 이 지시문을 사용하면 Redis를 서비스로 관리하는 init 시스템을 선언하여 작동을 더 잘 제어할 수 있습니다. supervised 지시문은 기본적으로 no로 설정되어 있습니다. Ubuntu를 실행 중이고 Ubuntu는 systemd init 시스템을 사용하므로 이것을 systemd로 변경하십시오:

/etc/redis/redis.conf
. . .

# Redis가 upstart 또는 systemd에서 실행되는 경우 Redis는 귀하의
# 감독 트리와 상호 작용할 수 있습니다. 옵션:
#   supervised no      - 감독 상호 작용 없음
#   supervised upstart - SIGSTOP 모드에서 Redis를 두어 upstart에 신호를 보냅니다.
#   supervised systemd - $NOTIFY_SOCKET에 READY=1을 작성하여 systemd에 신호를 보냅니다.
#   supervised auto    - UPSTART_JOB 또는 NOTIFY_SOCKET 환경 변수를 기반으로 upstart 또는 systemd 방법을 감지
#                        UPSTART_JOB or NOTIFY_SOCKET environment variables
# 참고: 이러한 감독 방법은 "프로세스가 준비되었음"을 신호로 보낼 뿐입니다.
#       귀하의 감독자에게 지속적인 생명력 핑을 반환하도록 설정하지 않습니다.
supervised systemd

. . .

이 시점에서 Redis 구성 파일을 변경해야 할 유일한 항목이므로 완료되면 저장하고 닫으십시오. 파일을 편집하는 데 nano를 사용한 경우 다음 단계를 따라 진행하십시오: CTRL + X, Y, 그런 다음 ENTER.

그런 다음 Redis 서비스를 다시 시작하여 구성 파일에 대한 변경 사항을 반영하십시오:

  1. sudo systemctl restart redis.service

이제 Redis를 설치하고 구성했으며 해당 시스템에서 실행 중입니다. 그러나 사용하기 전에 Redis가 올바르게 작동하는지 먼저 확인하는 것이 좋습니다.

단계 2 — Redis 테스트

새로 설치된 소프트웨어와 마찬가지로 Redis가 예상대로 작동하는지 확인하는 것이 좋습니다. 이 단계에서는 Redis가 올바르게 작동하는지 확인하는 몇 가지 방법을 살펴보겠습니다.

먼저 Redis 서비스가 실행 중인지 확인합니다:

  1. sudo systemctl status redis

오류 없이 실행 중인 경우 다음과 유사한 출력이 생성됩니다:

Output
● redis-server.service - Advanced key-value store Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2022-04-20 20:40:52 UTC; 4s ago Docs: http://redis.io/documentation, man:redis-server(1) Main PID: 2899 (redis-server) Status: "Ready to accept connections" Tasks: 5 (limit: 2327) Memory: 2.5M CPU: 65ms CGroup: /system.slice/redis-server.service └─2899 "/usr/bin/redis-server 127.0.0.1:6379 . . .

이 출력은 Redis가 실행 중이며 이미 활성화되어 있음을 나타냅니다. 즉, 서버 부팅 시 시작되도록 설정되어 있습니다.

참고: Redis의 많은 일반적인 사용 사례에서이 설정이 바람직합니다. 그러나 서버 부팅 시마다 수동으로 Redis를 시작하는 것을 선호하는 경우 다음 명령을 사용하여 이를 구성할 수 있습니다:

  1. sudo systemctl disable redis

Redis가 올바르게 작동하는지 테스트하려면 Redis의 명령 줄 클라이언트인 redis-cli를 사용하여 서버에 연결하십시오:

  1. redis-cli

이어서 다음과 같은 명령을 사용하여 연결을 테스트하십시오:ping:

  1. ping
Output
PONG

이 출력은 서버 연결이 여전히 활성화되어 있는지를 확인합니다. 다음으로 키를 설정할 수 있는지 확인하려면 다음을 실행하십시오:

  1. set test "It's working!"
Output
OK

값을 가져오려면 다음을 입력하십시오:

  1. get test

모든 것이 작동 중인 것으로 가정하면 저장한 값을 검색할 수 있습니다:

Output
"It's working!"

값을 가져올 수 있는지 확인한 후에 Redis 프롬프트를 종료하여 셸로 돌아갑니다:

  1. exit

최종 테스트로 Redis가 중지되거나 다시 시작된 후에도 데이터를 유지할 수 있는지 확인하겠습니다. 이를 위해 먼저 Redis 인스턴스를 다시 시작하십시오:

  1. sudo systemctl restart redis

다시 명령 줄 클라이언트로 연결하십시오:

  1. redis-cli

테스트 값이 여전히 사용 가능한지 확인하십시오:

  1. get test

키의 값은 여전히 접근 가능해야 합니다:

Output
"It's working!"

작업을 마치면 다시 셸로 돌아가십시오:이로써 Redis 설치가 완료되어 사용할 준비가 되었습니다. 그러나 일부 기본 구성 설정은 보안에 취약하며 악의적인 사용자가 서버 및 해당 데이터에 액세스하고 공격할 수 있는 기회를 제공할 수 있습니다. 본 튜토리얼의 나머지 단계는 공식 Redis 웹사이트에서 규정한대로 이러한 취약점을 완화하는 방법을 다룹니다:공식 Redis 웹사이트. 이러한 단계는 선택 사항이며 Redis를 사용하지 않는 경우에도 Redis는 여전히 작동하지만 시스템 보안을 강화하기 위해 이러한 단계를 완료하는 것이 강력히 권장됩니다:

  1. exit

이제 당신의 Redis 설치가 완전히 작동하고 사용할 준비가 되었습니다. 그러나 기본 구성 설정 중 일부는 보안이 취약하며 악의적인 조종자가 서버와 데이터에 대한 액세스를 공격하고 얻을 수 있는 기회를 제공합니다. 이 튜토리얼의 나머지 단계에서는 공식 Redis 웹사이트에 의해 제공된 이러한 취약성을 완화하는 방법을 다룹니다. 이러한 단계를 따르지 않더라도 Redis가 계속 작동하지만 강력하게 시스템의 보안을 강화하기 위해 이러한 단계를 완료하는 것이 좋습니다.

3단계 – localhost 바인딩

기본적으로 Redis는 localhost에서만 액세스할 수 있습니다. 그러나 이 튜토리얼과 다른 튜토리얼을 따라 Redis를 설치하고 구성한 경우 구성 파일을 업데이트하여 어디서나 연결을 허용했을 수 있습니다. 이는 localhost에 바인딩하는 것만큼 안전하지 않습니다.

이를 수정하려면 Redis 구성 파일을 편집하여 열기:

  1. sudo nano /etc/redis/redis.conf

이 줄을 찾아 주석을 해제해야 합니다(존재하는 경우 # 제거).

/etc/redis/redis.conf
. . .
bind 127.0.0.1 ::1
. . .

완료되면 파일을 저장하고 닫습니다( CTRL + X , Y 를 누른 다음 ENTER 를 누릅니다).

그런 다음 시스템 디렉터리가 변경 사항을 읽도록 서비스를 다시 시작합니다.

  1. sudo systemctl restart redis

이 변경 사항이 적용되었는지 확인하려면 다음 netstat 명령을 실행하세요:

  1. sudo netstat -lnp | grep redis
Output
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 14222/redis-server tcp6 0 0 ::1:6379 :::* LISTEN 14222/redis-server

참고: netstat 명령은 기본적으로 시스템에 사용 가능하지 않을 수 있습니다. 이 경우 다음 명령으로 설치할 수 있습니다 (다양한 다른 편리한 네트워킹 도구와 함께):

  1. sudo apt install net-tools

이 출력은 redis-server 프로그램이 로컬호스트 (127.0.0.1)에 바인딩되어 있음을 보여줍니다. 이는 방금 구성 파일에 대한 변경 사항을 반영합니다. 그 열에 다른 IP 주소가 있는 경우 (0.0.0.0 예를 들어), 올바른 줄을 주석 처리 해제했는지 다시 확인하고 Redis 서비스를 다시 시작해야 합니다.

이제 오직 로컬호스트에서만 듣고 있는 오니 Redis 설치는 악의적인 조치에 대한 요청이나 서버에 대한 액세스를 얻는 것이 더 어려워집니다. 하지만 현재 Redis는 사용자가 구성을 변경하거나 데이터를 보유하기 전에 인증해야 하는지 요구하지 않습니다. Redis는 이를 해결하기 위해 Redis 클라이언트 (redis-cli)를 통해 변경을 요청하기 전에 사용자가 비밀번호로 인증해야 합니다.

4단계 – Redis 암호 구성

# 경고: Redis는 매우 빠르기 때문에 외부 사용자는 좋은 서버에서

  1. sudo nano /etc/redis/redis.conf

# 초당 150,000개의 암호를 시도할 수 있습니다. 이는 매우 강력한 암호를

/etc/redis/redis.conf
. . .
# 사용해야 한다는 것을 의미하며, 그렇지 않으면 암호를 쉽게 뚫을 수 있습니다.
. . .

따라서 암호로 매우 강력하고 긴 값을 지정하는 것이 중요합니다. 자신만의 암호를 만들기보다는 openssl 명령어를 사용하여 임의의 암호를 생성할 수 있습니다. 다음 예제와 같이 첫 번째 명령어의 출력을 두 번째 openssl 명령어로 파이프하여 첫 번째 명령어가 생성한 줄 바꿈을 제거합니다:

이 명령어는 다음과 같은 출력을 반환합니다:그 출력을 requirepass의 새 값으로 복사하여 붙여넣은 후 읽을 수 있습니다:

/etc/redis/redis.conf
. . .
암호를 설정한 후 파일을 저장하고 닫습니다. 그런 다음 Redis를 다시 시작합니다:
암호가 작동하는지 테스트하려면 Redis 클라이언트를 열어보십시오:
다음은 Redis 암호가 작동하는지 테스트하는 데 사용되는 명령어 시퀀스입니다. 인증 전에 키를 값으로 설정하려는 첫 번째 명령어:
#
. . .

인증하지 않았기 때문에 Redis는 오류를 반환합니다:

  1. openssl rand 60 | openssl base64 -A

다음 명령어는 Redis 구성 파일에 지정된 암호로 인증합니다:

Output
RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

Redis는 확인합니다:

/etc/redis/redis.conf
requirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

그 후 이전 명령어를 다시 실행하면 성공합니다:get key1은 Redis에게 새 키의 값을 요청합니다.

  1. sudo systemctl restart redis.service

암호가 작동하는지 테스트하려면 Redis 클라이언트를 열어보세요:

  1. redis-cli

다음은 Redis 암호가 작동하는지 테스트하는 데 사용되는 명령어 시퀀스를 보여줍니다. 첫 번째 명령은 인증 전에 키를 값에 설정하려고 시도합니다:

  1. set key1 10

인증하지 않았으므로 Redis는 오류를 반환합니다:

Output
(error) NOAUTH Authentication required.

다음 명령은 Redis 구성 파일에 지정된 암호로 인증합니다:

  1. auth your_redis_password

Redis는 승인합니다:

Output
OK

그 후 이전 명령을 다시 실행하면 성공합니다:

  1. set key1 10
Output
OK

get key1은 Redis에 새 키의 값을 쿼리합니다.

  1. get key1
Output
"10"

인증 후 Redis 클라이언트에서 명령을 실행할 수 있음을 확인한 후 redis-cli를 종료할 수 있습니다:

  1. quit

다음으로 Redis 명령어를 이름 변경하는 방법에 대해 설명하겠습니다. 실수로 또는 악의적인 조치로 입력되면 데이터에 심각한 영향을 미칠 수 있습니다.

5단계 – 위험한 명령어 이름 변경

Redis에 내장된 다른 보안 기능은 위험하다고 간주되는 특정 명령어의 이름을 변경하거나 완전히 비활성화하는 것입니다.

비인가된 사용자가 실행할 경우 이러한 명령어를 사용하여 재구성, 파괴 또는 데이터를 삭제할 수 있습니다. 인증 암호와 마찬가지로 명령어의 이름 변경 또는 비활성화는 /etc/redis/redis.conf 파일의 SECURITY 섹션에서 구성됩니다.

被视为危险的一些命令包括:FLUSHDBFLUSHALLKEYSPEXPIREDELCONFIGSHUTDOWNBGREWRITEAOFBGSAVESAVESPOPSREMRENAME,以及DEBUG。这并不是一个完整的列表,但是禁用或重命名列表中的所有命令是提高您的Redis服务器安全性的一个良好起点。

您是否应该禁用或重命名命令取决于您的特定需求或您的网站的需求。如果您知道您永远不会使用可能被滥用的命令,那么您可以禁用它。否则,重命名它可能更符合您的最佳利益。

要重命名或禁用Redis命令,请再次打开配置文件:

  1. sudo nano /etc/redis/redis.conf

警告:以下展示如何禁用和重命名命令的步骤是示例。您应该只选择禁用或重命名对您有意义的命令。您可以在redis.io/commands查看完整的命令列表,并确定它们可能如何被误用。

要禁用命令,请将其重命名为空字符串(由一对引号表示,引号之间没有字符),如下所示:

/etc/redis/redis.conf
. . .
# 也可以通过将其重命名为空字符串来完全禁用一个命令:
# 空字符串:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
. . .

要重命名命令,请给它另一个名称,如下面的示例所示。重命名的命令应该对其他人难以猜测,同时对于您来说容易记住:

/etc/redis/redis.conf
. . .
# rename-command CONFIG ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG
. . .

변경 사항을 저장하고 파일을 닫습니다.

명령어를 변경한 후에는 Redis를 재시작하여 변경 사항을 적용합니다:

  1. sudo systemctl restart redis.service

새 명령어를 테스트하려면 Redis 명령 줄에 입력합니다:

  1. redis-cli

그런 다음 인증합니다:

  1. auth your_redis_password
Output
OK

앞의 예제에서처럼 CONFIG 명령어를 ASC12_CONFIG로 이름을 변경하였다고 가정합시다. 먼저 원래 CONFIG 명령어를 사용해 보십시오. 실패할 것입니다,因为它已被重命名:

  1. config get requirepass
Output
(error) ERR unknown command `config`, with args beginning with:

하지만 이름을 변경한 명령어를 호출하면 성공할 것입니다. 대소문자를 구분하지 않습니다:

  1. asc12_config get requirepass
Output
1) "requirepass" 2) "your_redis_password"

마지막으로 redis-cli에서 나갈 수 있습니다:

  1. exit

이미 Redis 명령 줄을 사용 중이고 Redis를 재시작하면 다시 인증해야 할 필요가 있음을 참고하십시오. 그렇지 않으면 명령을 입력할 때 다음과 같은 오류가 발생할 것입니다:

Output
NOAUTH Authentication required.

경고: 명령어 이름 변경의 실습에 관한 주의 사항은 /etc/redis/redis.confSECURITY 섹션 끝에 다음과 같은 문구가 있습니다:

/etc/redis/redis.conf
. . .
# AOF 파일에 로그되거나 레플리카에 전송되는 명령어의 이름을 변경하는 것
#可能会导致问题。
. . .

참고: Redis 프로젝트는 “master”와 “slave”라는 용어를 사용하지만, DigitalOcean은 일반적으로 “primary”와 “secondary”라는 대안을 선호합니다. 혼동을 피하기 위해 Redis 문서에서 사용하는 용어를 여기에서 선택했습니다.

즉, 이름이 바뀐 명령이 AOF 파일에 없거나 AOF 파일이 슬레이브로 전송되지 않은 경우 문제가 발생하지 않아야 합니다.

따라서 명령어 이름을 변경하려고 할 때 이를 염두에 두세요. 명령어 이름을 변경하기에 가장 좋은 시기는 AOF 지속성을 사용하지 않거나 설치 직후, 즉 Redis를 사용하는 애플리케이션이 배포되기 전입니다.

AOF를 사용하고 마스터-슬레이브 설치를 처리하는 경우 프로젝트의 GitHub 이슈 페이지에서 이 답변을 참고하세요. 다음은 작성자의 질문에 대한 답변입니다:

명령어는 전송되는 방식과 동일하게 AOF에 기록되고 슬레이브로 복제되므로, 동일한 이름 변경이 적용되지 않은 인스턴스에서 AOF를 재생하려고 하면 명령어를 실행할 수 없기 때문에 불일치가 발생할 수 있습니다 (슬레이브도 마찬가지입니다).

따라서 이러한 경우 이름 변경을 처리하는 가장 좋은 방법은 마스터-슬레이브 설치의 모든 인스턴스에 이름이 변경된 명령어가 적용되도록 하는 것입니다.

결론

이 튜토리얼에서 Redis를 설치하고 구성했으며, Redis 설치가 올바르게 작동하는지 검증하고 내장된 보안 기능을 사용하여 악의적인 공격자로부터 덜 취약하도록 만들었습니다.

로그인한 사용자가 서버에 로그인하면 Redis에 특화된 보안 기능을 우회하는 것이 매우 쉽습니다. 따라서 Redis 서버에서 가장 중요한 보안 기능은 방화벽입니다(사전 준비 초기 서버 설정 튜토리얼을 따르면 구성할 수 있음). 왜냐하면 이는 악의적인 사용자가 그 울타리를 넘기 어렵게 만듭니다.

Source:
https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-22-04