토요일, 2월 01, 2020

[B급 프로그래머] MariaDB에서 root 암호 인증 방식이 먹히지 않는 이유(feat. unix_socket)

먼저 내 실수부터 고백을 하고 넘어가야겠다. 최근 서버 설치 작업을 손놓고 있다가 갑자기 현업(?)으로 복귀할 일이 생겼는데, MariaDB를 설치하는 과정에서 이해하기 힘든 상황에 부딪혔다. 간략하게 시나리오를 정리하면 다음과 같다.

  1. 우분투 16.04가 설치된 인스턴스에서 apt로 기본 MaraiDB 서버/클라이언트 패키지를 설치
  2. 여느 때와 마찬가지로 mysql_secure_installation 명령을 내려 보안 강화
  3. localsystem에서 mysql -u root -p로 로그인하려 했으나... 거부(!) 습관적으로 안전을(응?) 위해 root에 암호를 넣어야겠다는 생각이 발동...
  4. root shell에서 그냥 mysql로 접속하니 들어감(이 때 뭔가 쌔한 기분이 느껴지긴 했지만...)
  5. (검색을 해보니 unix_socket 플러그인(!)을 무력화하기 위한 여러 가지 방법이 있어 순진하게 이에 맞춰) root 계정을 암호 사용 방식으로 변경
  6. mysql -u root -p로 로그인 하니까 잘 들어감
  7. 환경 설정 파일에서 몇 가지 설정을 변경한 다음에 룰루랄라 신나서 적용을 위해 systemctl mysql restart하니까 오류 발생(systemctl status mysql 명령을 내려서 확인해보니 root로 접근 거부되는 상황이 벌어짐) ==> 당황하기 시작

마음이 급하신 개발자들을 위해 결론부터 정리하고 들어간다.

  1. 보안을 위해서나 시스템 연동을 위해서나 unix_socket 플러그인을 절대 무력화하지 마시고 그대로 사용해야 함
  2. root 이외 제한된 접근 권한이 있는 별도 계정을 만들어서 이를 사용해 접근하게 만들어야 함

잠시 인스턴트 커피를 마시고 정신을 차린 다음에 다양한 테스트를 해보다 보니까, 범인은 unix_socket 플러그인이었다. 원인을 파악해보니 MariaDB 10.4 이후(또는 우분투 16.04LTS에 apt으로 설치되는 MaraiDB 10.0)부터는 root 인증이 기존의 암호 기반 방식에서 유닉스 소켓 방식으로 변경되었기 때문이었다. MySQL 최신 버전에서는 플러그인을 사용해 다양한 인증 방식을 가능하게 만들었는데, MariaDB는 그 중에서도 로그인한 계정으로 암호없이 직접 접속이 가능한 unix_socket 방식을 기본으로 적용하면서 전통적인 암호 방식과 동작 방식이 달라져버렸다(비단 root뿐만 아니라 유닉스 계정과 MySQL 계정이 일치하기만 하면 unix_socket 방식으로 다른 인증 작업 없이 바로 로그인이 가능해진다). 이렇게 하는 이유는 root가 전지전능하다보니 굳이 데이터베이스 암호를 걸지 않더라도 우회하거나 망가뜨릴 방법이 무궁무진하며, 데이터베이스 root 암호를 소스코드 형상 관리 시스템 여기저기에 다 뿌리고 다니는 보안 취약성도 막을 수 있기 때문이다(자세한 내용은 다음 슬라이드 참고).

systemctl mysql restart가 먹히지 않은 이유도 바로 정책 변경으로 인해 systemctl 스크립트가 unix_socket을 가정하고 mysqld에 접근했기 때문이었는데, 이 문제를 우회하려면 /etc/mysql/debian.cnf 환경 설정 파일에 root 암호를 넣어야 하는 사소하기도 하고 찜찜하기도 하는 문제가 발생하므로 mysql.user 테이블의 plugin 필드를 업데이트해서 unix_socket 플러그인 방식으로 원상복귀한 다음에 문제를 해결했다(unix_socket을 제거하는 방법을 알려주고 부작용은 전혀 이야기하지 않는 다른 블로그와는 달리 MariaDB; 인증(Authentication) 문제 블로그 글은 상당히 이성적으로 분석을 해놓아서 마음에 들었다).

앞서 잠깐 언급했지만 유닉스 계정과 동일한 MySQL 계정(예: scott)을 만들고 플러그인을 unix_socket으로만 지정하면(예: CREATE USER scott IDENTIFIED VIA unix_socket;) 별도 암호없이 바로 접근 가능하므로 이를 활용하면 서비스 설정이 편해질 것이다. 단, MySQL workbench등의 도구로 외부에서 접근할 경우에는 여전히 전통적인 방식(예: 예전 암호 방식으로 되돌리려면 ALTER USER scott@localhost IDENTIFIED VIA mysql_native_password; SET PASSWORD = PASSWORD('tiger');을 사용해야 할 것이다.

공식적인 설명을 보고 싶으면, Authentication Plugin - Unix SocketAuthentication from MariaDB 10.4를 참고하기 바란다.

결론: unix_socket 방식으로 root 계정에 대한 접근 방법을 유지하라. 웹에서 검색해서 영혼없이 결과대로 따라했다가는(예: unix_socket 방법 폭파하기) 곤란한 상황에 처할지도 모른다.

EOB

댓글 4개:

  1. 좋은 글 잘봤습니다.

    root 비번 변경이 잘 안되어 찾아보다 흘러들어오게 되었는데요

    블로그 참고하여 설정 마무리 잘 하였습니다.
    감사합니다~!

    답글삭제
    답글
    1. 도움이 되었다니 다행입니다. 앞으로도 계속 경험담 공유해드리겠습니다. :)

      삭제
  2. 좋은정보 감사합니다

    답글삭제