Redis Login 로그인

<< Connection IP Control Password Encryption >>

로그인 기능 설명

시작하기

ID/Password를 사용한 로그인 기능은 레디스 데이터베이스의 보안을 강화하고자 개발을 시작하였고, 데이터베이스 사용자 관리 전반(사용자 등록, 삭제, 초기화 등)을 개발하였다.   레디스에도 AUTH 기능이 있어서 어느 정도 보안에 신경 쓰고는 있으나, password를 암호화하기 않고 평문(plain text)로 저장하고 있어서 불안한 마음을 가시기 어렵다.   새로 개발한 로그인 기능은 유저의 password을 암호화하여 저장한다.   그리고 슈퍼유저(redis) 기능을 두어 SHUTDOWN, CONFIG 같은 관리 명령은 슈퍼유저만 수행하게 하였다.

이 기능은 접속 IP 통제 기능에 이어 개발한 것으로, 레디스 서버에 원래 있는 기능이 아니고 레디스게이트에서 개발한 것이다.

이 프로그램 소스와 문서는 버전 3.2.2을 기준으로 만들었다.


로그인, 로그아웃, 그리고

LOGIN

  • 명령: login userid password
  • 설명: 로그인 기능이 활성화되어 있으면 레디스의 모든 명령은 로그인 후 사용할 있다.
    로그인 없이 사용할 수 있는 단 하나의 명령은 AUTH이다.   이것은 로그인 기능과 AUTH 기능을 같이 사용할 때, 로그인 없이도 AUTH 명령을 실행할 수 있도록 한 것이다.
    한 유저 ID로 중복 로그인 할 수 있다.
    Password를 3회 틀리면 유저 ID는 잠긴다. 관리자(redis)가 풀어주어야 한다.
  • 사용 예
    127.0.0.1:6000> login user01 password
    OK

WHOAMI

  • 명령: whoami
  • 설명: 이 명령은 어느 유저 ID로 로그인했는지 잊었거나, 오랫동안 자리를 비운 사용자의 유저 ID를 확인할 때 사용한다.
  • 사용 예
    127.0.0.1:6000> whoami
    "user01"

CHPW

  • 명령: chpw new-password
  • 설명: 로그인한 사용자 자신의 password를 변경한다.
  • 사용 예
    127.0.0.1:6000> chpw new-password
    OK

LOGOUT

  • 명령: logout
  • 설명: 로그아웃한다.
  • 사용 예
    127.0.0.1:6000> logout
    OK

슈퍼유저

레디스 서버를 shutdown하거나, 서버 또는 클러스터의 설정을 변경하거나, 모니터링 또는 성능에 영향을 미치는 명령은 슈퍼유저(redis)만 실행할 수 있도록 제한했다.   일반 사용자가 이 관리 명령들을 실행할 수 없게 함므로써 레디스 서버를 더 안전하게 보호, 관리할 수 있게 되었다.

슈퍼유저의 ID는 redis이다.   이 유저 ID는 users.dat 파일에 등록하지 않아도 생성되고, 삭제할 수 없다.   이 유저만이 사용자를 등록, 삭제, 조회할 수 있다.

이런 명령은 레디스에서 관리(admin) 명령으로 분류되어 있는 것을 기준으로 했다.

슈퍼유저만 실행할 수 있는 관리(admin) 명령

  • shutdown: 서버 종료
  • config: 서버 설정 변경
  • cluster: 클러스터 설정 변경
  • client: 클라이언트 관리(조회, 제거, 이름 변경 등)
  • slaveof: 슬레이브 설정 변경
  • save: RDB 파일 저장(foreground 수행)
  • bgsave: RDB 파일 저장(background 수행)
  • bgrewriteaof: AOF 파일 저장(background 수행)
  • monitor: 명령 모니터링
  • latency: 서버 성능 분석
  • slowlog: 명령 성능 측정
  • debug: 다양한 관리 명령을 실행할 수 있음
  • sync: 내부 명령 replication
  • psync: 내부 명령 partial replication
  • replconf: 내부 명령 cluster
  • pfselftest: 내부 명령 HyperLogLog

사용자 관리

사용자 조회

  • 명령: debug userlist/listuser [userid] [pw]
  • 설명: 사용자 정보를 조회한다.   Userid를 입력하지 않으면 모든 사용자를 조회할 수 있다.   Userid에 와일드카드를 사용할 수 있다.   pw 옵션을 사용하면 암호화된 password를 볼 수 있다.   userlist 또는 listuser 둘 다 사용할 수 있다.
  • 항목: userid, login count, login-fail-count, last login time, password
  • 사용 예
    127.0.0.1:6000> debug userlist
    1) "userid: redis, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    2) "userid: user01, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    3) "userid: user02, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    4) "userid: user03, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    5) "userid: user10, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    127.0.0.1:6000> debug userlist user*
    1) "userid: user01, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    2) "userid: user02, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    3) "userid: user03, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    4) "userid: user10, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970"
    127.0.0.1:6000> debug userlist user10 pw
    "userid: user10, login count: 0, login-fail-count: 0, last login time: Thu Jan 1 09:00:00 1970, password: $2b$05$IT6wNVjodDHGcFH3UkPnHeZaWY3jn8w0gNCp2NSMV4C7Zfb7VNU2y"

사용자 등록

  • 명령: debug useradd/adduser userid password
  • 설명: 사용자를 등록한다.   유저 ID(userid)는 알파벳과 숫자로만 구성할 수 있고, 5자 이상 20 이하 이어야 한다.   암호(password)는 구성 문자에 제한이 없으며, 5자 이상 20 이하 이어야 한다.   useradd 또는 adduser 둘 다 사용할 수 있다.
  • 사용 예
    127.0.0.1:6000> debug useradd user10 password
    OK

사용자 삭제

  • 명령: debug userdel/deluser userid
  • 사용자(유저 ID)를 삭제한다.   슈퍼유저인 redis는 삭제할 수 없다.
    userdel 또는 deluser 둘 다 사용할 수 있다.
  • 사용 예
    127.0.0.1:6000> debug userdel user10
    OK

로그인 3회 이상 실패로 잠긴 사용자 해제

  • 명령: debug userunlock/unlockuser userid
  • 설명: 로그인 3회 이상 실패로 잠긴 사용자 해제할 때 사용한다.   login_fail_count를 0으로 초기화한다.
  • 사용 예
    127.0.0.1:6000> debug userunlock user10
    OK

사용자 정보 초기화

  • 명령: debug userreset/resetuser userid [pw]
  • 설명: 사용자 정보를 초기화한다.   login count, login fail count, last login time 이 세 항목을 0으로 초기화한다.   pw 옵션을 사용하면 임의의 password를 새로 발행한다.
  • 사용 예: password 새로 발행
    127.0.0.1:6000> debug userreset user10 pw
    "YH8@4"

암호화된 password 생성

  • 명령: debug newpw/newpassword password
  • 설명: 입력된 password를 암호화해서 보여준다.   이 기능은 users.dat 파일을 만들 때 사용한다.
    동일한 값(password)을 입력해도 암호화된 결과는 매번 다르다.   이것은 정상으로 Cost Factor와 Salt의 영향이며, 자세한 내용은 아래 "암호화 Encryption" 부분을 참고하기 바란다.
  • 사용 예
    127.0.0.1:6000> debug newpw password
    "$2b$05$VzjQIRvGPwg/SBzUU0nESO97Z9E9bV8alrnSVW6CEzQ1Fd5wFYRde"

사용자 정보를 파일에 저장

  • 명령: debug usersave/saveuser
  • 설명: 사용자 정보를 파일에 저장한다.   작업 디렉터리(working directory)에 users.dat에 저장된다.   저장 항목은 userid, last login time, password이다.   서버 종료 시에도 자동 저장된다.
    usersave 또는 saveuser 둘 다 사용할 수 있다.
  • 사용 예
    127.0.0.1:6000> debug usersave
    OK

암호화 Encryption

password는 blowfish 알고리즘을 사용했다.   blowfish 공식 사이트
암호화 소스는 openwall 사이트에서 crypt_blowfish 1.3을 사용했다.
이것은 OpenBSD에서 사용하는 bcrypt와 유사하다.

암호화된 password 구성

  • 전체 길이: 60 바이트
  • prefix: 7 바이트(위치 1 ~ 7): "$2b$05$"
  • salt 값: 22 바이트(위치 8 ~ 29): 예) "VzjQIRvGPwg/SBzUU0nESO"
  • password hash 값: 31 바이트(위치 30 ~ 60): 예) "97Z9E9bV8alrnSVW6CEzQ1Fd5wFYRde"

키 스트레칭(key stretching)

키 스트레칭은 무차별 공격에 대한 시간 끌기 방법으로 일부러 암호화하는데 시간이 많이 걸리게 해서 원 password를 알아내기 어렵게 하는 방법이다.   따라서 일반적인 환경에서 암호화하는데 0.2초 정도의 시간이 걸리도록 하는 것을 권하기도 한다.

키 스트레칭을 위한 Cost factor를 5로 선택한 이유에 대해서 설명

Prefix에서 5를 cost factor라고 하며, 5이면 2^5 승 32회, 2^10 승이면 1024회 for loop를 돌면서 암호화한다.   따라서 이 수치가 높을수록 암호화하는데 시간이 많이 걸린다.   일반적으로 이 값을 높여서 방어 수단으로 사용되지만, 싱글 스레드인 레디스 서버에서는 무조건 높일 수 없는 상황이다.   5로 했을 때 테스트 서버에서 약 2~5 millisecond가 걸린다.   레디스 서버 내부에서 set 명령을 처리하는 3~5 microsecond가 걸리는 것과 비교하면 매우 시간이 오래 걸리는 것으로, 이 값을 높이면 레디스 서버가 암호화하는데 불필요하게 많은 시간을 사용할 것이기 때문에 적정한 수치인 5를 선택했다.

솔트 값(salt)

솔트 값은 password를 암호화(hash) 하는데 사용되는 것이다.   OpenBSD에서는 arc4random_buf() 함수를 이용해서 임의의 16 바이트 문자를 사용한다.   여기서는 random() 함수를 이용해서 임의의 30 바이트 문자로 22 바이트 솔트 값을 생성한다.

암호화 결과가 다른 이유

같은 입력값(password)도 Cost Factor와 Salt에 따라 다른 결과가 나온다.   여기서는 Cost Factor는 같지만, Salt가 매번 다르기 때문에 암호화(hash) 결과가 달라지는 것이다.   이것은 새 암호를 생성할 때 적용되고, password check 시에는 암호와 같이 저장된 Cost Factor와 Salt를 사용하기 때문에 원 password와 암호화된 password를 비교할 수 있는 것이다.


설정 관리

REQUIRELOGIN 파라미터

  • 설명: 파라미터 requirelogin이 yes 일 경우 로그인 기능이 활성화된다.   디폴트는 no이다.   config set requirelogin yes/no 명령으로 수정할 수 있다.
  • 사용 예
    127.0.0.1:6000> config get requirelogin
    1) "requirelogin"
    2) "no"
    127.0.0.1:6000> config set requirelogin yes
    OK
    127.0.0.1:6000> config rewrite
    OK

LOGIN-FAIL-COUNT 파라미터

  • 설명: 잘못된 password를 login-fail-count 이상 입력하면 사용자가 잠긴다.   0 이면 로그인 실패를 체크하지 않는다.   디폴트는 3이다.
    config set login-fail-count 5 명령으로 수정할 수 있다.
  • 사용 예
    127.0.0.1:6000> config get login-fail-count
    1) "login-fail-count"
    2) "3"
    127.0.0.1:6000> config set login-fail-count 5
    OK

로그인 관련해서 추가로 개발한 기능

REDIS-CLI -LOGIN

  • 명령: redis-cli -login userid password
  • 로그인 기능을 추가하면서 redis-cli에서도 명령어 라인에서도 userid password를 바로 입력할 수 있도록 수정했다.

CLUSTER ADDSLOTS-RANGE

  • 명령: cluster addslots-range slot_from slot_to
  • 기존 addslots 명령은 슬롯을 하나씩 지정했다.  여기서는 범위로 슬롯을 지정할 수 있도록 명령을 추가했다.
  • 사용 예
    127.0.0.1:6000> cluster addslots-range 0 16383
    OK

적용 범위

  • Standalone: OK
  • Sentinel: 개발, 데스트 중
  • Cluster: OK
  • 로그인 기능은 AUTH와 같이 사용할 수 있습니다.

테스트 서버 Spec

OS : CentOS 7
H/W Model: HP DL320e Gen8 v2
Processor : Intel Xeon E3-1231V3.3 3.4GHz
Main Memory: DDR3 8GB RAM


라이선스와 법적 책임

  • 본 소스는 BSD 라이선스에 기반을 둡니다
  • 레디스게이트에서는 본 기능을 여러 번 테스트를 했으나 문제 발생 가능성은 있습니다.
    문제 발생에 대한 책임이 레디스게이트에 없음을 알려드립니다.
  • 버그 발견 시 본 페이지에 댓글 또는 redisgate@gmail.com으로 알려주시기 바랍니다.

소스 파일 리스트

  • 수정 파일 목록: server.h, server.c, debug.c, replication.c, config.c, util.h, util.c, cluster.c, redis-cli.c, Makefile
  • 새로 작성한 파일 목록: users.h, users.c, crypt_blowfish.h, crypt_blowfish.c

받기(download)

위 리스트에 있는 수정 파일, 새로 작성한 파일을 zip으로 묶었습니다.   클릭해서 다운 받으세요.
레디스 버전 3.2.2 소스에 다운 받은 파일을 복사하고 make로 컴파일하세요.
본 소스는 레디스 버전 3.2.2로 만들었습니다.
redis-users.zip      




<< Connection IP Control Login Password Encryption >>

질문하거나 댓글을 보려면 클릭하세요.  댓글수 :    조회수 :

Email 返事がかかってなれば、メールでお知らせします。