웹사이트 검색

Linux VPS에서 MySQL 및 MariaDB 데이터베이스를 보호하는 방법


소개

Linux 및 Unix 계열 시스템에서 사용할 수 있는 SQL 데이터베이스 언어의 구현이 많이 있습니다. MySQL과 MariaDB는 서버 환경에서 관계형 데이터베이스를 배포하는 데 널리 사용되는 두 가지 옵션입니다.

그러나 대부분의 소프트웨어와 마찬가지로 이러한 도구도 잘못 구성되면 보안 문제가 될 수 있습니다. 이 튜토리얼은 MariaDB 또는 MySQL 데이터베이스를 보호하고 VPS에 대한 열린 문이 아닌지 확인하기 위해 취할 수 있는 몇 가지 기본 단계를 안내합니다.

단순함과 설명을 위해 Ubuntu 12.04 VPS 인스턴스에서 MySQL 서버를 사용합니다. 그러나 이러한 기술은 다른 Linux 배포판에 적용할 수 있으며 MariaDB에서도 사용할 수 있습니다.

초기 설정

MySQL은 설치하는 동안 보안을 향한 첫 걸음을 내딛을 수 있는 기회를 제공합니다. 루트 암호를 설정하도록 요청합니다.

sudo apt-get install mysql-server
 ?????????????????????????? Configuring mysql-server-5.5 ???????????????????????????
 ? While not mandatory, it is highly recommended that you set a password for the   ? 
 ? MySQL administrative "root" user.                                               ? 
 ?                                                                                 ? 
 ? If this field is left blank, the password will not be changed.                  ? 
 ?                                                                                 ? 
 ? New password for the MySQL "root" user:                                         ? 
 ?                                                                                 ? 
 ? _______________________________________________________________________________ ? 
 ?                                                                                 ? 
 ?                                                                             ? 
 ?                                                                                 ? 
 ???????????????????????????????????????????????????????????????????????????????????

루트 암호는 나중에 언제든지 설정할 수 있지만 이 단계를 건너뛸 이유가 없으므로 처음부터 관리자 계정을 보호해야 합니다.

설치가 완료되면 포함된 몇 가지 스크립트를 실행해야 합니다. 먼저 "mysql_install_db" 스크립트를 사용하여 데이터베이스의 디렉토리 레이아웃을 생성합니다.

sudo mysql_install_db

다음으로 "mysql_secure_installation" 스크립트를 실행합니다. 이것은 프로덕션 환경에서 사용하기에 위험한 일부 기본값을 제거하는 몇 가지 절차를 안내합니다.

sudo mysql_secure_installation

먼저 설치 중에 설정한 루트 암호를 묻는 메시지가 표시됩니다. 바로 다음에는 루트 암호를 변경하고 싶은지부터 시작하여 일련의 질문을 받게 됩니다.

아직 변경하지 않은 경우 비밀번호를 안전한 것으로 변경할 수 있는 또 다른 기회입니다.

나머지 모든 질문에 "Y"(예)라고 대답해야 합니다.

이렇게 하면 누구나 기본적으로 MySQL에 로그인할 수 있는 기능이 제거되고, 관리자 계정으로 원격 로그인이 비활성화되고, 안전하지 않은 일부 테스트 데이터베이스가 제거되고, 이러한 변경 사항을 반영하도록 실행 중인 MySQL 인스턴스가 업데이트됩니다.

보안 고려 사항

MySQL(및 거의 모든 다른 시스템) 보안의 가장 중요한 주제는 절대적으로 필요한 경우에만 액세스 권한을 부여해야 한다는 것입니다. 귀하의 데이터 안전은 때때로 편의성과 보안 사이의 균형으로 귀결됩니다.

이 가이드에서는 데이터베이스 소프트웨어의 특정 용도로 인해 이러한 옵션 중에서 선택하고 선택할 수 있지만 보안 측면에 기댈 것입니다.

My.cnf 파일을 통한 보안

MySQL의 기본 구성 파일은 Ubuntu의 \/etc/mysql/\ 디렉토리와 다른 VPS의 \/etc/\ 디렉토리에 있는 \my.cnf\라는 파일입니다.

이 파일의 일부 설정을 변경하여 MySQL 인스턴스를 잠급니다.

루트 권한으로 파일을 엽니다. 다른 시스템에서 이 튜토리얼을 따르는 경우 필요에 따라 디렉토리 경로를 변경하십시오.

sudo nano /etc/mysql/my.cnf

확인해야 할 첫 번째 설정은 "[mysqld]" 섹션 내의 "bind-address" 설정입니다. 이 설정은 로컬 루프백 네트워크 장치("127.0.0.1")로 설정해야 합니다.

bind-address = 127.0.0.1

이렇게 하면 MySQL이 로컬 시스템을 제외한 모든 곳에서 연결을 수락하지 않습니다.

다른 컴퓨터에서 이 데이터베이스에 액세스해야 하는 경우 SSH를 통해 연결하여 로컬에서 데이터베이스 쿼리 및 관리를 수행하고 ssh 터널을 통해 결과를 보내는 것을 고려하십시오.

우리가 패치할 다음 구멍은 MySQL 내에서 기본 파일 시스템에 대한 액세스를 허용하는 기능입니다. 이는 보안에 심각한 영향을 미칠 수 있으며 꼭 필요한 경우가 아니면 차단해야 합니다.

파일의 동일한 섹션에서 로컬 파일을 로드하는 이 기능을 비활성화하는 지시문을 추가합니다.

local-infile=0

이렇게 하면 데이터베이스에 대한 파일 수준 권한이 없는 사용자의 경우 파일 시스템에서 파일을 로드할 수 없습니다.

충분한 공간이 있고 거대한 데이터베이스를 운영하지 않는 경우 의심스러운 활동을 주시하기 위해 추가 정보를 기록하는 것이 도움이 될 수 있습니다.

로깅을 너무 많이 하면 성능이 저하될 수 있으므로 신중하게 판단해야 합니다.

우리가 추가한 동일한 "[mysqld]" 섹션 내에서 로그 변수를 설정할 수 있습니다.

log=/var/log/mysql-logfile

MySQL 로그, 오류 로그 및 mysql 로그 디렉토리를 누구나 읽을 수 없는지 확인하십시오.

sudo ls -l /var/log/mysql*
-rw-r----- 1 mysql adm    0 Jul 23 18:06 /var/log/mysql.err
-rw-r----- 1 mysql adm    0 Jul 23 18:06 /var/log/mysql.log

/var/log/mysql:
total 28
-rw-rw---- 1 mysql adm 20694 Jul 23 19:17 error.log

내부에서 MySQL 보안

보안을 개선하기 위해 MySQL을 사용하는 동안 수행할 수 있는 여러 단계가 있습니다.

이 섹션의 명령을 MySQL 프롬프트 인터페이스에 입력할 것이므로 로그인해야 합니다.

mysql -u root -p

이전에 설정한 루트 비밀번호를 묻는 메시지가 표시됩니다.

암호 및 호스트 연결 보안

먼저 MySQL에 비밀번호나 호스트 연결이 없는 사용자가 없는지 확인합니다.

SELECT User,Host,Password FROM mysql.user;
+------------------+-----------+-------------------------------------------+
| user             | host      | password                                  |
+------------------+-----------+-------------------------------------------+
| root             | localhost | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| demo-user        | %         |                                           |
| root             | 127.0.0.1 | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| root             | ::1       | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| debian-sys-maint | localhost | *ECE81E38F064E50419F3074004A8352B6A683390 |
+------------------+-----------+-------------------------------------------+
5 rows in set (0.00 sec)

보시다시피 설정 예에서 "demo-user" 사용자는 암호가 없으며 그가 있는 호스트에 관계없이 유효합니다. 이것은 매우 안전하지 않습니다.

이 명령으로 사용자의 암호를 설정할 수 있습니다. 지정하려는 비밀번호를 반영하도록 "newPassWord"를 변경하십시오.

UPDATE mysql.user SET Password=PASSWORD('newPassWord') WHERE User="demo-user";

사용자 테이블을 다시 확인하면 이제 데모 사용자에게 암호가 있음을 알 수 있습니다.

SELECT User,Host,Password FROM mysql.user;
+------------------+-----------+-------------------------------------------+
| user             | host      | password                                  |
+------------------+-----------+-------------------------------------------+
| root             | localhost | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| demo-user        | %         | *D8DECEC305209EEFEC43008E1D420E1AA06B19E0 |
| root             | 127.0.0.1 | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| root             | ::1       | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| debian-sys-maint | localhost | *ECE81E38F064E50419F3074004A8352B6A683390 |
+------------------+-----------+-------------------------------------------+
5 rows in set (0.00 sec)

"Host" 필드를 보면 모든 호스트를 의미하는 와일드카드인 "%"가 여전히 있음을 알 수 있습니다. 이것은 우리가 원하는 것이 아닙니다. 이를 "localhost"로 변경합니다.

UPDATE mysql.user SET Host='localhost' WHERE User="demo-user";

다시 확인하면 이제 User 테이블에 적절한 필드가 설정되어 있음을 알 수 있습니다.

SELECT User,Host,Password FROM mysql.user;

테이블에 빈 사용자가 포함되어 있으면("mysql_secure_installation"을 실행했기 때문에 지금은 없어야 하지만 이 부분은 어쨌든 다룰 것입니다) 제거해야 합니다.

이를 위해 다음 호출을 사용하여 액세스 테이블에서 빈 사용자를 삭제할 수 있습니다.

DELETE FROM mysql.user WHERE User="";

사용자 테이블 수정을 완료한 후 새 권한을 구현하려면 다음 명령을 입력해야 합니다.

FLUSH PRIVILEGES;

애플리케이션별 사용자 구현

Linux 내에서 격리된 사용자로 프로세스를 실행하는 방식과 유사하게 MySQL은 동일한 종류의 격리에서 이점을 얻습니다.

MySQL을 사용하는 각 애플리케이션에는 제한된 권한만 있고 실행에 필요한 데이터베이스에만 액세스할 수 있는 자체 사용자가 있어야 합니다.

MySQL을 사용하도록 새 애플리케이션을 구성할 때 해당 애플리케이션에 필요한 데이터베이스를 생성해야 합니다.

create database testDB;
Query OK, 1 row affected (0.00 sec)

다음으로 해당 데이터베이스를 관리할 사용자를 생성하고 필요한 권한만 할당해야 합니다. 이것은 응용 프로그램에 따라 다르며 일부 사용에는 다른 것보다 더 많은 공개 권한이 필요합니다.

새 사용자를 생성하려면 다음 명령을 사용하십시오.

CREATE USER 'demo-user'@'localhost' IDENTIFIED BY 'password';

다음 명령을 사용하여 새 테이블에 대한 새 사용자 권한을 부여할 수 있습니다. 특정 권한에 대한 자세한 내용은 MySQL에서 새 사용자를 생성하고 권한을 부여하는 방법에 대한 자습서를 참조하십시오.

GRANT SELECT,UPDATE,DELETE ON testDB.* TO 'demo-user'@'localhost';

예를 들어 나중에 계정에서 업데이트 권한을 취소해야 하는 경우 다음 명령을 사용할 수 있습니다.

REVOKE UPDATE ON testDB.* FROM 'demo-user'@'localhost';

특정 데이터베이스에 대한 모든 권한이 필요한 경우 다음과 같이 지정할 수 있습니다.

GRANT ALL ON testDB.* TO 'demo-user'@'localhost';

사용자의 현재 권한을 표시하려면 먼저 "권한 삭제" 명령을 사용하여 지정한 권한을 구현해야 합니다. 그런 다음 사용자에게 부여된 권한을 쿼리할 수 있습니다.

FLUSH PRIVILEGES;
show grants for 'demo-user'@'localhost';
+------------------------------------------------------------------------------------------------------------------+
| Grants for demo-user@localhost                                                                                   |
+------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'demo-user'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' |
| GRANT SELECT, UPDATE, DELETE ON `testDB`.* TO 'demo-user'@'localhost'                                            |
+------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

변경을 마치면 항상 권한을 플러시합니다.

루트 사용자 변경

수행할 수 있는 추가 단계는 루트 로그인 이름을 변경하는 것입니다. 공격자가 루트 MySQL 로그인에 액세스하려는 경우 사용자 이름을 찾는 추가 단계를 수행해야 합니다.

루트 로그인은 다음 명령으로 변경할 수 있습니다.

rename user 'root'@'localhost' to 'newAdminUser'@'localhost';

사용자 데이터베이스에 대해 사용한 것과 동일한 쿼리를 사용하여 변경 사항을 확인할 수 있습니다.

select user,host,password from mysql.user;

다시 말하지만, 이러한 변경 사항이 발생하려면 권한을 플러시해야 합니다.

FLUSH PRIVILEGES;

지금부터 관리 작업을 수행하려면 새로 생성된 사용자 이름으로 MySQL에 로그인해야 합니다.

mysql -u newAdminUser -p

결론

이것이 MySQL 및 MariaDB 보안 사례의 전체 목록은 아니지만 데이터베이스를 보호할 때 내려야 하는 결정의 종류에 대한 좋은 소개를 제공해야 합니다.

구성 및 보안에 대한 자세한 내용은 MySQL 및 MariaDB 웹 사이트와 해당 매뉴얼 페이지에서 찾을 수 있습니다. 사용하기로 선택한 응용 프로그램은 보안 조언을 제공할 수도 있습니다.