목차
MariaDB 원격 계정 접속 관리
이 글은 2016년에 작성한 메모를 현재 설치 절차에 맞게 정리한 것이다. 아래 명령은 Ubuntu 24.04 LTS의 MariaDB 10.11 패키지를 기준으로 한다. 먼저
mariadb --version으로 설치 버전을 확인한다. 같은 서버에서만 접속한다면 원격 접속 설정은 필요 없다.
MariaDB 원격 접속은 세 군데가 모두 맞아야 가능하다. 서버가 해당 네트워크 주소에서 연결을 기다려야 하고, 방화벽이 허용해야 하며, 계정의 사용자@호스트와 권한이 맞아야 한다. 어느 한 곳만 열어도 접속이 되지 않는다.
flowchart LR A[클라이언트 10.0.0.20] --> B[방화벽: 3306/TCP] B --> C[서버 사설 주소 10.0.0.10] C --> D[MariaDB 계정과 권한] D --> E[허용된 데이터베이스]
여기서는 DB 서버의 사설 주소를 10.0.0.10, 접속할 애플리케이션 서버를 10.0.0.20이라고 가정한다. 실제 주소는 자신의 내부망 주소로 바꾼다. 인터넷에서 DB 포트에 직접 접근할 수 있게 만들지 않는다.
1. 현재 설정 확인
서버에서 로컬 관리 계정으로 접속해 설정을 확인한다. Ubuntu의 MariaDB 패키지는 보통 로컬 root에 Unix 소켓 인증을 사용하므로, 불필요하게 원격 root 계정을 만들지 않는다.
sudo mariadb
SELECT VERSION();
SHOW VARIABLES LIKE 'bind_address';
SHOW VARIABLES LIKE 'skip_networking';
bind_address가 127.0.0.1이면 서버 밖의 주소로는 연결할 수 없다. skip_networking이 켜져 있어도 TCP 접속이 불가능하다. Ubuntu 패키지에서 흔히 쓰는 설정 파일은 /etc/mysql/mariadb.conf.d/50-server.cnf지만, 실제 읽는 설정은 mariadbd --print-defaults와 배포판 설정 파일을 확인한다.
2. 필요한 사설 인터페이스에만 바인딩
MariaDB 10.11은 여러 주소를 쉼표로 지정할 수 있다. 서버 설정 파일의 서버용 섹션에서 기존 bind-address 항목을 확인한 뒤 다음처럼 설정한다. 로컬 TCP 접속도 사용한다면 loopback 주소를 같이 남긴다.
[mysqld]
bind-address = 127.0.0.1,10.0.0.10
이 단계에서는 설정 파일만 수정한다. TLS와 네트워크 접근 제한을 준비한 5단계에서 재시작한다. 0.0.0.0이나 *로 모든 인터페이스를 여는 방식은 여기서 필요하지 않다. MariaDB 버전과 설정 파일 위치가 다르면 공식 원격 접속 안내에서 해당 버전의 방법을 확인한다.
3. TLS를 먼저 구성
MariaDB 10.11에서는 네트워크 TLS가 자동으로 구성된다고 가정하지 않는다. 신뢰할 수 있는 CA가 서명한 서버 인증서와 개인 키를 준비하고, MariaDB의 TLS 연결 안내에 따라 서버 설정의 ssl_cert, ssl_key, ssl_ca를 지정한다. 인증서의 서버 이름은 클라이언트가 접속할 db.internal.example과 맞아야 한다. 개인 키는 DB 서버의 필요한 계정만 읽을 수 있도록 관리한다.
5단계에서 재시작한 후 SHOW VARIABLES LIKE 'have_ssl';의 결과가 YES인지 확인한다. 인증서를 준비하지 못했다면 DB 포트를 개방하는 대신 VPN이나 SSH 터널로 접속 경로를 제한한다.
4. 작업에 필요한 권한만 부여
다음은 이미 만들어진 appdb의 데이터를 읽기만 하는 보고서용 계정 예시다. <고유한-긴-비밀번호>는 실제 비밀번호가 아니라 교체할 자리다. 운영 비밀번호는 별도 비밀 관리 체계로 생성·보관한다.
CREATE USER 'report_reader'@'10.0.0.20'
IDENTIFIED BY '<고유한-긴-비밀번호>' REQUIRE SSL;
GRANT SELECT ON appdb.* TO 'report_reader'@'10.0.0.20';
SHOW GRANTS FOR 'report_reader'@'10.0.0.20';
REQUIRE SSL은 암호화된 접속을 강제하지만, 서버 신원을 확인하는 일은 클라이언트의 CA와 인증서 검증 설정도 필요하다. root@'%', GRANT ALL ON *.*, mysql.user에 직접 INSERT하는 방식은 사용하지 않는다. 계정 생성과 변경에는 CREATE USER, ALTER USER, GRANT, REVOKE를 사용한다. 이 예시의 계정에 쓰기 작업이 필요하다면 그 작업에 필요한 테이블과 권한만 별도로 추가한다.
5. 클라이언트 한 대만 방화벽에서 허용
TLS와 계정 설정을 확인한 뒤, Ubuntu에서 UFW를 사용한다면 먼저 상태를 확인한다. 다음 규칙은 10.0.0.20에서 들어오는 3306/TCP만 허용한다.
sudo ufw status
sudo ufw allow proto tcp from 10.0.0.20 to any port 3306
sudo ufw status numbered
UFW가 비활성이라면 이 규칙만 추가해서는 보호가 적용되지 않는다. 재시작 전에 실제로 작동하는 방화벽 또는 클라우드 보안 그룹에서 같은 출발지 제한을 설정한다. 원격 SSH 서버에서 방화벽 정책을 변경할 때는 기존 SSH 접속 규칙을 먼저 확인한다. Ubuntu 방화벽 문서에 출발지 제한 문법이 있다.
sudo systemctl restart mariadb
sudo systemctl status mariadb --no-pager
서버에서 SHOW VARIABLES LIKE 'bind_address';와 SHOW VARIABLES LIKE 'have_ssl';로 사설 주소와 TLS 사용 가능 상태를 다시 확인한다. have_ssl이 YES가 아니면 클라이언트 접속을 시도하기 전에 인증서 설정을 고친다.
클라이언트에 CA 인증서를 배포하고 db.internal.example이 10.0.0.10을 가리키게 한 뒤 다음처럼 접속한다.
mariadb --host=db.internal.example --port=3306 --user=report_reader --password \
--ssl-ca=/absolute/path/to/ca.pem --ssl-verify-server-cert appdb
접속한 세션에서 SHOW SESSION STATUS LIKE 'Ssl_version';을 확인한다. 빈 값이 아닌 TLS 버전이 표시되어야 한다.
접속 실패를 구분하기
| 증상 | 먼저 확인할 곳 |
|---|---|
| 연결 거부 또는 시간 초과 | 서버의 bind_address, 서비스 상태, 방화벽과 네트워크 경로 |
Host ... is not allowed | 접속 출발지와 계정의 '사용자'@'호스트' 일치 여부 |
Access denied | 계정 비밀번호와 권한, 접속한 호스트 |
| TLS 협상 또는 인증서 오류 | 서버 TLS 설정, CA 파일, 접속 이름과 인증서 이름 |
접속이 끝난 임시 계정은 DROP USER 'report_reader'@'10.0.0.20';로 제거하고 방화벽 규칙도 검토한다. 계정을 제거할 때는 실제 서비스에서 사용 중이지 않은지 먼저 확인한다.