WordPress 사이트용 MySQL 강화

게시 됨: 2023-01-18

가장 인기 있는 CMS인 WordPress는 가장 인기 있는 데이터베이스인 MySQL에서 실행됩니다. MySQL 설치 및 WordPress 데이터베이스 구성 설치가 일반적인 공격 벡터에 대해 적절하게 강화되도록 시간을 투자하면 위험을 줄이는 데 도움이 될 수 있습니다. MySQL 서버를 직접 관리하는 경우 특히 그렇습니다.

많은 WordPress 설치가 MySQL의 포크인 MariaDB를 사용한다는 점은 주목할 가치가 있습니다. 둘 다 매우 유사하게 작동하므로 MySQL을 사용하여 MySQL과 MariaDB를 모두 의미합니다. 실행 중인 RDMS 유형에 관계없이 MySQL을 강화하면 해커의 공격 위험을 최소화하는 데 도움이 될 수 있습니다. 그러나 이것은 웹 애플리케이션 방화벽 설치, 최신 버전의 플러그인, 테마 및 WordPress 사용, WordPress 강화와 같은 다른 보안 조치를 대체하지 않습니다.

이 문서는 Linux( Ubuntu )에서 실행되는 MySQL 8.0을 대상으로 합니다. 개념은 다른 운영 체제 및 MySQL/MariaDB 버전으로 변환되지만 이 예에서 사용된 명령 및 파일 경로는 다를 수 있습니다. 프로덕션 시스템을 변경하기 전에 스테이징 또는 사전 프로덕션 환경에서 변경 사항을 테스트하는 것이 좋습니다.

자신의 MYSQL을 관리하는 사람들을 주로 대상으로 하는 이 기사에서는 MySQL을 보호하는 방법에 대한 몇 가지 팁과 자습서를 제공합니다. 그럼에도 불구하고 이 기사에 제시된 광범위한 모범 사례 목록은 WordPress 웹 사이트를 관리하는 모든 사람이 읽을 가치가 있습니다. MySQL 서버를 보호하는 것은 안전한 WordPress를 유지하고 다양한 유형의 무차별 대입 공격, 맬웨어 주입 및 기타 유형의 공격으로부터 자신을 보호하는 데 중요한 단계입니다.

목차

  • Database as a Service(DBaaS) 사용 고려
  • MySQL을 최신 상태로 유지
  • 전용 머신에서 MySQL 실행
  • MySQL을 IP 주소에 바인딩
  • 웹 기반 GUI 도구 사용 제한
  • 전용 사용자를 사용하여 MySQL 데몬 실행
  • mysql_secure_installation 스크립트 사용
  • 전용 WordPress 데이터베이스 사용자 생성
  • local_infile이 비활성화되어 있는지 확인하십시오.
  • MySQL 명령 기록 비활성화
  • –skip-grant-tables 인수로 mysqld가 시작되지 않았는지 확인합니다.
  • 데이터베이스 백업
    • 자주 백업하기
    • 백업의 무결성을 자주 확인하십시오.
    • 백업을 안전하게 저장
  • TLS 연결 활성화 및 시행
    • 테이블 접두사 변경
    • 변경 사항을 구현하는 방법
    • 워드프레스 보안 유지

DBaaS(Database as a Service) 사용 고려

관리형 플랜에서 WordPress를 호스팅하지 않는 경우 Database as a Service를 고려해 볼 가치가 있습니다. MySQL을 로컬에 설치하는 기존 모델을 연결하는 서비스로 대체합니다. 관리형 데이터베이스 서비스를 제공하는 호스팅 공급자와 함께 WordPress 사이트를 실행하는 경우 사용 사례에 적합할 수 있습니다. 사용 가능한 옵션에는 일반적으로 Amazon RDS, DigitalOcean Managed MySQL 및 Linode Managed MySQL이 포함됩니다. 액면 그대로 이러한 서비스는 MySQL을 직접 실행하는 것보다 비용이 더 많이 들 수 있습니다. 그러나 프로덕션 등급 데이터베이스를 실행하는 데 필요한 모든 작업을 수행합니다. 대부분의 서비스에는 보안 모범 사례 사전 설정, 지속적인 보안 패치 및 유지 관리, 백업이 포함됩니다.

DBaaS(Database as a Service)를 사용하는 것은 보안 및 안정성 측면에서 최상의 옵션 중 하나입니다. 이것은 필수는 아니지만 여전히 있으면 좋습니다. 그러나 MySQL을 직접 관리하려는 경우 다음은 기억해야 할 강화 팁 모음입니다.

MySQL을 최신 상태로 유지

최신 버전의 WordPress를 실행하는 것이 중요한 것처럼 MySQL을 최신 상태로 유지하는 것도 중요합니다. 대부분의 다른 소프트웨어와 마찬가지로 MySQL 서버에 대한 업데이트는 주기적으로 릴리스됩니다. 이러한 업데이트는 버그를 해결하고 취약성을 완화하며 새로운 기능을 제공합니다. 알려진 취약점이 있는 소프트웨어를 실행하는 위험을 줄이려면 최신 보안 패치로 MySQL을 최신 상태로 유지해야 합니다. 업데이트가 완료되면 'mysql 데몬'을 다시 시작해야 합니다. 이것은 약간의 가동 중지 시간이 발생할 수 있는 프로세스입니다. 항상 그렇듯이 미리 계획하십시오.

전용 머신에서 MySQL 실행

많은 WordPress 설치는 동일한 컴퓨터에서 MySQL, PHP 및 웹 서버(예: Nginx 또는 Apache HTTP Server)를 실행합니다. 이는 성능과 보안 측면에서 최적이 아닙니다. MySQL은 이상적으로는 공격의 폭발 반경을 줄이기 위해 전용 서버에서 실행되어야 합니다. 공격자가 웹 서버에서 권한을 침해하고 에스컬레이션하는 경우 해당 공격자가 측면으로 이동하고 MySQL 서버를 손상시키는 것이 훨씬 더 어려워집니다.

MySQL을 IP 주소에 바인딩

특정 IPv4 또는 IPv6 인터페이스의 TCP/IP 연결만 수락하도록 MySQL을 구성할 수 있습니다. bind-address 구성 옵션을 특정 IP 주소로 설정하기만 하면 됩니다. 이것은 클라이언트 애플리케이션(이 경우 WordPress)이 MySQL에 연결하는 방법에 대한 추가 제어 및 제한을 제공합니다. 기본적으로 이 설정은 *로 설정되어 있으며 기본 MySQL이 모든 인터페이스에서 수신 대기함을 의미합니다.

특정 IP를 수신하도록 구성되지 않은 경우 모든 IP를 사용하여 MySQL에 연결할 수 있습니다. 이 설정은 인터넷에 노출하는 웹 서버와 동일한 시스템에서 MySQL을 실행하는 경우 특히 중요합니다(이 경우 바인드 주소를 127.0.0.1로 설정해야 MySQL이 로컬 호스트에서만 수신 대기함). .

예를 들어 MySQL 서버가 특정 IPv4 주소의 연결만 허용하도록 하려면 아래 예와 유사한 항목을 추가할 수 있습니다. 서버의 /etc/mysql/mysql.conf.d/mysqld.cnf 구성 파일의 [mysqld] 옵션 그룹 아래에 이것을 입력해야 합니다.

바인딩 주소=192.168.0.24

일단 이것을 설정하면 다른 서버 호스트 주소에 대한 연결이 허용되지 않으므로 이 IP 주소를 사용하여 데이터베이스에 연결하도록 WordPress를 다시 구성해야 합니다(이미 그렇게 하고 있지 않은 경우).

웹 기반 GUI 도구 사용 제한

많은 WordPress 설치에는 웹 기반 프런트 엔드 그래픽 관리 도구가 포함되어 있습니다. 일반적인 예로는 Cpanel, phpMyAdmin 또는 Adminer가 있습니다. 이러한 도구를 사용하면 MySQL 및 기본 인프라의 기타 측면을 보다 쉽게 ​​관리할 수 있습니다. 웹 기반 그래픽 인터페이스는 MySQL 데이터베이스를 관리하는 데 도움이 될 수 있지만 이러한 인터페이스는 다른 벡터를 추가하여 공격 표면을 증가시킬 수 있습니다. 또한 데이터베이스에 대해 파괴적이거나 악의적인 SQL 쿼리를 실행하기 위해 공격자가 발견하고 악용할 위험이 있습니다. 공격으로 인해 WordPress 웹 사이트가 완전히 탈취될 수도 있습니다.

유일하게 안전한 서버는 스위치를 끄고 플러그를 뽑은 서버이지만 위험은 관리할 수 있습니다. 중요하지 않은 시스템을 제거하는 것이 한 가지 옵션입니다. 그러나 위험을 최소화하기 위해 잠그고 제한할 수도 있습니다.

다양한 방법으로 이러한 도구에 대한 액세스를 제한할 수 있습니다. WordPress용 phpMyAdmin을 원격으로 설치할 수 있으므로 웹 서버에 대한 위험을 최소화할 수 있습니다. 또는 로컬 컴퓨터에서 MySQL Workbench 또는 Beekeeper Studio와 같은 도구를 사용하고 SSH 터널을 통해 데이터베이스 서버에 연결할 수도 있습니다.

전용 사용자를 사용하여 MySQL 데몬 실행

서버에서 실행되는 다른 서비스와 마찬가지로 전용 사용자로 MySQL 데몬을 실행할 수 있습니다. 전용 사용자를 사용하여 MySQL을 실행하면 시스템 내에서 해당 사용자에게 부여되는 권한을 정확하게 정의할 수 있습니다. 전용 사용자로 MySQL을 실행하는 것도 MySQL 취약점의 폭발 반경을 줄이기 때문에 최소 권한 원칙을 따릅니다. 또한 제한된 사용자가 MySQL과 관련되지 않은 리소스(예: 운영 체제 구성 및 비밀)에 액세스할 수 없기 때문에 잘못된 구성이 악용될 가능성도 줄어듭니다.

좋은 소식은 패키지 관리자(예: apt 또는 yum)를 통한 설치가 MySQL을 설치할 때 이 단계를 자동으로 처리한다는 것입니다. MySQL이 전용 사용자로 실행되고 있는지 확인하는 빠른 방법은 MySQL 데몬을 실행하는 시스템에서 다음을 실행하는 것입니다.

ps -ef | egrep "^mysql.*$"

MySQL 전용 사용자를 사용하여 실행 중인 경우 반환된 ps 출력에서 ​​적어도 한 줄을 볼 수 있어야 합니다.

mysql_secure_installation 스크립트 사용

mysql-server 패키지는 mysql_secure_installation이라는 쉘 스크립트 유틸리티와 함께 ​​제공됩니다. 이 스크립트를 사용하여 MySQL 서버의 안전한 시작점을 설정할 수 있습니다. 따라서 MySQL을 새로 설치한 후에 실행해야 합니다. 이 유틸리티는 다음을 지원합니다.

  • 루트 계정의 비밀번호 설정
  • localhost 외부에서 액세스할 수 있는 루트 계정 제거
  • 익명 사용자 계정 제거
  • 테스트 데이터베이스 제거(기본적으로 익명 사용자가 액세스할 수 있음)

mysql_secure_installation을 호출하려면 다음 명령을 실행하십시오.

sudo mysql_secure_installation

설정 프로세스가 시작되면 MySQL 사용자를 위해 선택한 암호의 강도를 테스트하는 데 사용되는 암호 유효성 검사 플러그인을 활성화할지 여부를 묻는 몇 가지 프롬프트가 표시됩니다. 이 플러그인을 활성화하는 것이 좋습니다.

암호 유효성 검사 플러그인을 활성화하면 스크립트에서 암호 유효성 검사 정책을 지정하라는 메시지가 표시됩니다. 여기에서 강력한 암호 정책을 선택해야 합니다. 이후에 루트 사용자의 비밀번호를 재설정하라는 메시지가 표시됩니다.

다음으로 스크립트는 익명의 MySQL 사용자를 제거하라는 메시지를 표시합니다. 이는 공격자가 익명의 MySQL 사용자를 활용하여 데이터베이스 서버에 대한 액세스 권한을 얻을 가능성을 줄이는 데 중요합니다.

다음 프롬프트는 MySQL 서버에 원격으로 인증할 때 루트 사용자를 사용하여 로그인을 비활성화할지 묻습니다. 루트 사용자를 사용한 원격 인증은 위험하며 거의 필요하지 않습니다. 대신 MySQL에 SSH로 연결하고 서버의 MySQL 클라이언트를 사용하여 루트 사용자로 인증하거나 가급적이면 SSH 터널을 사용하여 원격 MySQL 포트를 로컬 시스템으로 전달하고 로컬 클라이언트를 사용하여 연결해야 합니다.

다음으로 MySQL과 함께 제공되는 기본 데이터베이스(있는 경우)를 삭제하라는 메시지가 표시됩니다. 이는 프로덕션 MySQL 서버에 권장되는 방법입니다.

기본 데이터베이스 삭제

마지막으로 적용된 모든 변경 사항을 적용하기 위해 권한 테이블을 다시 로드할지 묻는 메시지가 표시됩니다.

전용 WordPress 데이터베이스 사용자 생성

보안 모범 사례는 의무 또는 역할별로 사용자와 권한을 분리하도록 지시합니다. 즉, 데이터베이스를 사용하는 모든 애플리케이션에는 해당 작업을 수행하는 데 필요한 최소한의 MySQL 데이터베이스 권한을 가진 전용 사용자가 있어야 합니다. 따라서 사용자 권한이 필요한 수준을 초과하지 않도록 해야 합니다.

이 관행은 여러 WordPress 웹사이트를 실행하는 배포로 확장되어야 합니다. 각 WordPress 웹사이트에는 자체 전용 데이터베이스와 MySQL 사용자가 있어야 합니다. 이렇게 하면 언제든지 한 명의 사용자만 한 번에 하나의 데이터베이스에 액세스할 수 있고 사용자는 다른 데이터베이스에 액세스할 수 없으므로 무단 액세스 및 데이터 위반을 방지할 수 있습니다.

다음 SQL 문(필요에 따라 <host> 및 <password> 및 <database>로 대체)을 사용하여 WordPress 웹 사이트에 대한 전용 사용자를 생성하고 일반 사용 권한을 부여할 수 있습니다. 일부 WordPress 플러그인, 테마 및 WordPress 업데이트는 때때로 올바르게 작동하기 위해 추가 권한이 필요할 수 있습니다(자세한 내용은 공식 WordPress 지침 참조).

local_infile이 비활성화되어 있는지 확인하십시오.

LOAD DATA 문을 사용하면 데이터 파일을 데이터베이스 테이블로 로드할 수 있습니다. 특정 조건에서 이것은 MySQL 서버에서 파일을 읽는 데 악용될 수 있습니다. 따라서 WordPress 사이트에서 이에 대한 특정 사용 사례가 없는 한 이 기능을 비활성화해야 합니다.

MySQL과 웹 서버가 동일한 시스템에서 실행 중인 경우 공격자가 LOAD DATA LOCAL 문을 사용하여 웹 서버 프로세스가 읽기 액세스 권한을 가진 임의의 파일을 읽을 수 있습니다. 이는 공격자가 MySQL에 대해 임의의 SQL 문을 실행할 수 있는 능력이 있다고 가정합니다. SQL 인젝션 취약점 또는 악성 WordPress 플러그인 설치를 통한 경우일 수 있습니다. 이것이 웹 서버와 데이터베이스 서버를 분리해야 하는 또 다른 이유입니다.

기본적으로 local_infile은 MySQL 8.0에서 비활성화되어 있습니다(이전 버전의 MySQL에서는 기본적으로 활성화되어 있었습니다). MySQL 서버가 LOAD DATA LOCAL 문을 수락하지 않도록 하려면 mysqld 데몬이 local_infile이 비활성화된 상태로 시작되었는지 확인하십시오.

MySQL 명령 기록 비활성화

Linux에서 대화식으로 실행되는 MySQL 클라이언트 로그 문은 히스토리 파일(일반적으로 $HOME/.mysql_history에 있음)에 저장됩니다. MySQL 명령 기록은 암호, 암호화 키 또는 기타 비밀과 같은 민감한 정보가 노출될 가능성을 줄이기 때문에 이상적으로는 비활성화해야 합니다.

.mysql_history 파일이 시스템에 존재하지 않는지 확인하려면 다음 명령을 실행하십시오.

찾기 /home -name ".mysql_history"
/root -name ".mysql_history" 찾기

위의 명령이 출력을 반환하면 .mysql_history 파일을 제거하십시오. 또한 다음과 같이 $HOME/.mysql_history를 /dev/null에 대한 심볼릭 링크로 설정할 수 있습니다.

ln -s /dev/null $HOME/.mysql_history

–skip-grant-tables 인수로 mysqld가 시작되지 않았는지 확인합니다.

MySQL의 루트 암호가 잘못된 경우 선호하는 방법은 아니지만 일부 MySQL 관리자는 –skip-grant-tables 인수로 시작하도록 MySQL을 설정할 수 있습니다. 이 매개변수를 사용하여 MySQL을 시작하면 클라이언트가 쿼리를 연결하거나 실행할 때 그랜트 테이블을 확인하지 않으므로 어디서나(네트워크를 통해 데이터베이스에 연결할 수 있는 경우) 누구나 데이터베이스 서버에서 무엇이든 할 수 있습니다.

–skip-grant-tables가 활성화되지 않았는지 확인하려면 서버의 /etc/mysql/mysql.conf.d/mysqld.cnf 구성 파일을 열고 skip-grant-tables를 찾습니다. 값을 설정하지 않거나 skip-grant-tables = FALSE로 설정해야 합니다.

데이터베이스 백업

재난이나 공격으로부터 신속하게 복구하려면 WordPress 데이터베이스를 백업하는 것이 절대적으로 중요합니다. WordPress 백업 플러그인 및 서비스에서 정기적으로 데이터베이스 덤프를 수행하는 자체 개발 스크립트에 이르기까지 WordPress 데이터베이스를 백업하는 방법은 무수히 많지만 다음은 염두에 두어야 할 몇 가지 중요한 팁입니다.

자주 백업하기

정기적인 백업을 수행하는 것은 매우 명확하고 자명합니다. 데이터베이스 백업을 자주 수행할수록 데이터 손실 사고에서 복구하기가 더 쉬워집니다. 백업 빈도는 실행 중인 WordPress 사이트 유형에 따라 다르지만 일반적으로 매일 백업하는 것이 대부분의 사용 사례에 적합합니다.

백업의 무결성을 자주 확인하십시오.

백업은 작동하는 경우에만 유용합니다. 그리고 데이터 복구를 시도하는 사건의 한가운데에 있는 동안 발견하지 않는 것을 선호할 것입니다. 이에 대한 간단한 해결 방법은 수시로 테스트 복원을 수행하여 백업이 실제로 작동하는지 자주 확인하는 것입니다. 이렇게 하는 좋은 방법은 백업이 여전히 예상대로 작동하는지 확인하기 위해 복원 절차를 거치도록 몇 달마다 일정 이벤트를 설정하는 것입니다. 또한 데이터베이스 복원 단계를 문서화하는 것도 좋은 생각입니다. 사고에 대응할 때 추측이 적을수록 좋습니다.

백업을 안전하게 저장

웹 또는 데이터베이스 서버(특히 웹 서버)에 WordPress 사이트의 백업을 보관하지 마십시오. 백업은 공격자가 쓰레기 수거통 다이빙을 할 수 있는 좋은 장소입니다. 안전한 오프사이트 위치에 백업을 저장하는 것이 좋습니다. 주기적으로 데이터베이스 덤프를 수행하는 경우 오브젝트 스토리지 서비스에 데이터베이스 덤프를 저장하는 것이 좋습니다. 여기에는 Amazon S3, Cloudflare R2, DigitalOcean Spaces, Linode Object Storage 등이 포함될 수 있습니다. 이 방법을 사용하면 데이터베이스 백업을 저장하는 비용 효율적이고 훌륭한 방법이 될 수 있습니다. 그러나 사용 중인 저장소 버킷을 공개적으로 액세스할 수 있도록 하지 않도록 각별히 주의하십시오.

TLS 연결 활성화 및 시행

웹 서버와 동일한 시스템에서 MySQL을 실행하지 않는 한(위에서 이미 다룬 것처럼 이상적인 보안 관행이 아님) 전송 계층 보안(TLS 인증서)을 사용하여 WordPress와 MySQL 사이의 데이터를 암호화하는 것이 좋습니다. 이전에는 SSL 인증서(Secure Socket Layer)라고 했습니다.

기본적으로 MySQL을 설치하면 자체 서명된 인증서가 자동으로 생성됩니다. 다음을 실행하여 이를 확인할 수 있습니다(또는 mysql_ssl_rsa_setup 스크립트를 사용하여 새 인증서를 생성할 수 있음).

위 목록(예: SCP를 통해)에서 ca.pem을 WordPress 웹사이트를 실행하는 서버로 복사해야 합니다. ca.pem 파일을 WordPress 서버에 업로드하면 인증서를 운영 체제의 인증서 신뢰 저장소로 이동하고 다음과 같이 인증서 신뢰 저장소를 업데이트해야 합니다.

CA 인증서의 파일 이름은 .crt 파일 확장자로 끝나야 합니다(예: mysql-ca.crt는 유효하지만 mysql-ca.pem.crt 또는 mysql-ca.pem은 유효하지 않음).

sudo mv ca.pem /usr/local/share/ca-certificates/mysql-ca.crt
sudo 업데이트-ca-인증서

다음으로 WordPress 설치의 wp-config.php 파일에 다음을 추가하여 MySQL에 연결할 때 TLS를 사용하도록 WordPress를 구성해야 합니다.

정의('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

wp-config.php를 업데이트하면 WordPress는 TLS를 사용하여 MySQL 서버에 대한 연결을 시작합니다.

다음으로 /etc/mysql/mysql.conf.d/mysqld.cnf 파일에 다음을 추가하여 require_secure_transport 시스템 변수를 사용하여 MySQL 서버에 TLS 연결을 적용하는 것이 좋습니다.

require_secure_transport = 켜짐

마지막으로 변경 사항을 적용하려면 MySQL을 다시 시작하십시오.

systemctl 재시작 mysql

테이블 접두사 변경

기본적으로 모든 WordPress 테이블은 'wp_' 접두사로 생성됩니다. 이렇게 하면 공격자가 데이터베이스 테이블의 이름을 알고 있기 때문에 SQL 삽입과 같은 특정 공격에서 더 쉽게 성공할 수 있습니다. 이것만으로는 당신을 보호할 수 없지만 많은 사람들이 최고의 WordPress 보안 사례로 권장하는 간단한 연습입니다.

설치 프로세스 중이나 이후 어느 시점에서나 데이터베이스 접두어를 변경할 수 있지만 후자가 약간 더 복잡합니다. 어느 쪽이든 WordPress 데이터베이스 접두사 변경에 대한 온라인 자습서를 찾을 수 있습니다.

변경 사항을 구현하는 방법

이 기사가 WordPress 웹 사이트를 실행하는 맥락에서 MySQL 보안 강화에 대한 개요를 제공했기를 바랍니다. 웹 사이트 보안에 묘책은 없지만 약간의 노력을 기울이면 보안에 대한 계층화된 심층 방어 접근 방식을 취하면 공격자가 웹 사이트를 공격하기가 훨씬 더 어려워집니다.
이 가이드는 MySQL을 위한 여러 강화 기술을 제시하지만 MySQL은 WordPress 에코시스템의 한 구성 요소일 뿐입니다. 따라서 WordPress 보안 강화 가이드에서 다루는 WordPress 보안의 다른 측면도 고려해야 합니다. 이는 WordPress 2단계 인증과 같은 입증된 보안 조치와 결합되어 최대한 안전함을 보장하는 데 도움이 됩니다.

받아들일 것이 많다고 느껴지면 이 가이드에서 다루는 다양한 경화 기술을 점진적으로 적용할 수 있으며 아마도 적용해야 한다는 점을 기억하십시오.

워드프레스 보안 유지

공격자는 보안이 취약한 웹 사이트를 악용하는 데 많은 노력을 기울일 필요가 없기 때문에 종종 소프트 타겟을 쫓는다는 점을 명심하십시오. 다음 WordPress 웹 사이트의 보안 상태보다 한 발 앞서 있으면 덜 매력적인 대상이 됩니다.