그리드에서 데이터베이스 감사
게시 됨: 2018-09-29SendGrid가 최근 상장 기업이 되면서 데이터베이스의 하위 집합에 대한 모든 변경 사항에 대한 전체 감사 로그가 필요했습니다. 이 하위 집합에는 대량 트래픽이 발생하지 않은 일부 소규모 인스턴스뿐만 아니라 고객 포털 가동 시간 및 가입 흐름에 중요한 일부 이전 클러스터도 포함되었습니다.
이는 높은 가동 시간 요구 사항이 있는 일부 데이터 저장소에도 영향을 미치며 쓰기에 대한 가동 중지 시간 없이 온라인 롤아웃이 바람직했습니다. 외부 마감일이 다가오고 프로젝트의 범위를 알고 있는 우리는 계획을 세우기 시작했습니다.
계획 단계에서 우리는 다음과 같은 답변이 필요한 몇 가지 공개 질문을 식별했습니다.
- 이 작업을 수행할 수 있는 소프트웨어에는 어떤 옵션이 있습니까?
- 예상되는 성능 영향은 무엇이며 사전에 얼마나 테스트할 수 있습니까?
- 쓰기 가용성을 위해 다운타임 없이 이 작업을 수행할 수 있습니까?
선택, 선택
SendGrid에서는 대규모 또는 팀 간 프로젝트에 대한 설계 청사진 프로세스를 따릅니다. 이 프로젝트에는 다음을 비롯한 여러 팀이 이해 관계자로 참여했습니다.
- 내부 감사 는 이 규정 준수 제어 범위에 속하는 데이터 저장소를 정의하고 증거 수집을 담당하는 팀으로서 감사 시간이 옵니다.
- 이러한 데이터베이스 감사 로그에서 파생된 사고 대응을 분석하고 처리하는 팀인 InfoSec
- 이 새로운 기능을 범위 내 데이터베이스에 배포, 관리 및 조정하는 코드를 작성하는 팀으로서 DB Ops
저는 이 청사진을 작성하고 모든 이해 관계자가 검토하고 아키텍처 팀의 승인을 받았는지 확인했습니다. 몇 년 전에 MySQL의 감사 로깅 주제에 대해 조사를 했고 옵션의 환경이 어떤지 어느 정도 알고 있었지만 편견을 가지고 프로젝트에 접근하고 싶지 않았고 여전히 하나 이상의 것을 조사하고 싶었습니다. 옵션을 선택하고 우리가 다른 솔루션보다 하나의 솔루션을 선택해야 하는 이유에 대한 확실한 사례를 모든 사람에게 제공합니다.
이 청사진은 비즈니스 요구 사항에 대한 솔루션이 무엇인지 조사하면서 동시에 작성했다는 점에서 이례적이었습니다. 그래서 나는 우리가 약간의 조사를 하는 동안 많은 세부사항이 채워질 것이라는 것을 알고 있었습니다.
우리의 옵션은 다음과 같습니다.
- Percona 감사 플러그인
- Mcafee MySQL 감사
이것이 시장에 나와 있는 유일한 옵션은 아니지만 실제 베이크오프에 포함되어야 하는 우리의 규모 및 데브옵스 방식에 가장 가깝다고 느꼈습니다. 시장에 나와 있는 다른 상업적 옵션은 이 기준을 통과하지 못해 벤치마크에 포함되지 않았습니다.
후자는 Mcafee에서 최근에 오픈한 새로운 솔루션이었고 Percona 플러그인이 지원하지 않는 테이블 수준 필터링을 지원한다고 주장했기 때문에 조사하기에 충분히 흥미로웠습니다. 범위 내 클러스터 중 하나가 총 300개 중 약 24개 테이블을 실제로 감사해야 한다는 것을 알고 있었기 때문에 이것은 Mcafee 플러그인을 경쟁자로 만들기에 충분한 가치가 있는 기능인 것 같았습니다.
반면에 Percona Audit 플러그인은 이 기능을 위해 가장 널리 사용되는 오픈 소스 솔루션이었습니다. 내장되어 있지만 이미 사용하고 있는 Percona Server에서는 비활성화되어 있습니다. 그러나 이벤트에 대한 테이블 수준 필터링을 제공하지 않으므로 데이터베이스 계층 외부에서 수행해야 합니다.
베이크오프
Pythian의 파트너 팀의 도움으로 우리는 비교 비교를 시작했습니다. 먼저 각 옵션의 설치 및 튜닝 방법을 비교했습니다. 팀은 우리에게 트레이드오프가 있다고 빠르게 결정했습니다. Mcafee 플러그인은 기본적으로 테이블 필터를 지원했지만 이벤트를 스트리밍하는 방법으로 rsyslog를 사용하는 것은 지원하지 않았습니다. 이것은 우리가 그것을 사용한다면 파일을 디스크에 로컬로 쓰고 모니터링 스택으로 보내는 것을 관리해야 한다는 것을 의미했습니다.
이는 감사 플러그인 사용 시 성능 저하를 증가시킬 가능성이 높기 때문에 바람직하지 않은 것으로 간주되었습니다. 감사 이벤트를 로컬로 작성한 다음 별도의 프로세스에서 다시 읽으면 실제 프로덕션 트래픽에서 IOPS 용량이 제거되고 데이터베이스 인스턴스에 대한 위험이 증가합니다. 중단 시간.
반면에 타협은 Percona 플러그인이었습니다. 이벤트를 syslog에 기본적으로 보내는 것을 지원하지만 테이블 필터는 제공하지 않습니다. 우리는 이것이 범위 내에서 더 바쁜 클러스터가 많은 수의 이벤트를 보낼 것임을 의미한다는 것을 알았습니다. 대부분은 실제로 감사하려는 테이블에서 온 것이 아닙니다. 이는 InfoSec 모니터링 스택의 syslog-receive/logstash 계층에 위험을 초래했습니다. DB ops는 그것에 접근할 수 없기 때문에 이 프로젝트의 성공은 공유 소유권 노력이었다는 것을 의미했습니다.
궁극적으로 우리는 덜 움직이는 부분이 있는 솔루션을 사용하기로 결정했고 초당 수천 개의 이벤트 필터링을 처리하기 위해 logstash를 확장해야 하는지 여부를 최대한 빨리 알기 위해 배포를 계획했습니다. 그래서 Percona의 감사 플러그인을 사용하기로 결정했습니다.
배포 계획
설치 범위
우리는 주어진 클러스터의 모든 노드에 플러그인을 설치하고 활성화하여 이 배포를 간단하게 유지하기로 결정했습니다. 즉, 클러스터의 기록기 노드가 변경될 때 감사 기능을 켜거나 끌 수 있도록 오케스트레이션할 필요가 없었습니다. 플러그인은 설계상 복제 스트림 변경 사항을 기록하지 않기 때문에 변경 사항이 적용될 때 중복 이벤트를 일으키는 복제 스트림에 대한 우려가 없었습니다.
다운타임 없음
영향을 받는 클러스터에서 다운타임 없이 원활하게 배포할 수 있도록 하고 싶었습니다. 그렇게 하면 이러한 클러스터를 사용하는 제공 팀과 함께 수행해야 하는 계획 및 조정의 양을 크게 줄이고 고객에게 미치는 영향을 크게 줄일 수 있습니다. 그러나 우리는 또한 플러그인이 이벤트를 InfoSec 팀의 syslog 집계 서버로 보내는 사용자 지정 구성을 사용하여 특정 시설의 rsyslog에 이벤트를 보내기를 원했습니다. 이러한 구성 중 일부는 Percona에 의해 동적이 아닌 것으로 문서화되어 있으며 필요한 감사 플러그인 구성으로 mysql 인스턴스를 다시 시작할 때 이 프로젝트 범위의 모든 인스턴스에서 약간의 가동 중지 시간이 발생할 가능성이 있습니다.
우리는 스테이징 환경에서 전용 테스트 인스턴스를 사용하여 플러그인을 배포할 때 다양한 작업 순서를 테스트하기 시작했으며 구성 관리가 처음에 필요한 모든 구성을 배치한 다음 로드 플러그인 명령을 실행하면 명령이 원하는 구성으로 시작합니다.
이는 이 프로젝트를 완료하기 위한 계획을 단순화하고 프로덕션에서 릴리스하는 시간을 단축하고 이벤트 필터링을 미세 조정하고 분석 및 탐지에 대해 보안 팀과 협력할 시간을 확보하는 데 중요한 역할을 하는 것으로 입증되었습니다.
구성 관리 사용
우리는 Chef 요리 책을 사용하여 데이터베이스를 관리하므로 분명히 Chef를 사용하여 감사 플러그인을 배포, 조정 및 모니터링할 계획이었습니다. 그러나 이것은 클러스터의 하위 집합에서만 활성화해야 했기 때문에 여기에서 비즈니스 목표와 관련이 없는 데이터로 로그 스토리지를 방해하지 않도록 활성화된 위치를 제어하는 방법이 필요했습니다.
MySQL 데이터베이스 관리를 위해 래퍼 쿡북 모델을 사용하여 구성을 관리합니다. 핵심 '기본' 쿡북은 데이터베이스 인스턴스가 어떻게 보여야 하는지 대부분을 정의하고 클러스터별 쿡북은 속성을 수정하거나 특정 클러스터와 관련된 구성을 추가하기 위해 이를 래핑합니다. 그 디자인 덕분에 필요한 구성 파일을 생성하는 대량의 코드를 쉽게 추가한 다음, 하나의 새로운 레시피에 플러그인을 로드한 다음, Chef 속성을 기반으로 켜고 끌 수 있습니다. 또한 우리는 변경 범위를 고려하여 이 코드를 요리책의 새로운 부 버전으로 릴리스해야 한다고 결정했습니다.
또한 속성이 false로 설정된 경우 요리사가 관련 sensu 검사를 제거하고 감사 스트리밍을 끄도록 했습니다. 이는 클러스터가 더 이상 범위에 포함되지 않거나 간헐적인 이유로 중지해야 하는 경우 Chef가 올바른 작업을 수행할 수 있도록 하기 위한 것이므로 속성 변경을 반영하기 위해 노드를 수동으로 변경할 필요가 없습니다.
모니터링
모니터링하지 않는 것의 성공을 선언할 수 없습니다. 그러나 모니터링은 우리가 모니터링하고 있는 실패 사례와 언젠가는 이러한 점검이 실패할 경우 어떤 조치를 기대하는지 생각하지 않고 단지 몇 가지 감각적인 점검을 두드리는 것 이상입니다. 그래서 두 가지를 염두에 두고 이 파이프라인에서 모니터링을 계획하기 시작했습니다.
- 이 시스템의 명시적 소유권 범위에 대해 모두 동의해야 합니다. 특히 이 시스템은 별도의 호출 순환이 있는 2개 팀의 책임에 걸쳐 있기 때문입니다.
- 이를 위해 추가된 모든 새로운 검사는 이 검사가 실패하고 수정하는 방법을 설명하는 검사에서 연결하는 런북과 함께 제공되어야 합니다.
이 두 가지 규칙을 고려하여 매우 구체적인 검사를 추가했습니다. 이 시점에서 종단 간 '종합' 검사를 추가하는 것도 고려했지만 여기서 종단 간 검사는 시스템의 어느 부분이 실패했는지 정확히 알려주지 못하므로 그렇게 하지 않았습니다. 적절한 팀을 호출하는 데도 시간이 걸립니다. 그리고 나는 '만약에 대비하여' 밤에 사람들에게 호출하는 것을 지지하지 않습니다.
우리는 다음에 대해 모니터링하기로 결정했습니다.
- 감사 플러그인의 라이브 mysql 구성을 확인하여 다음을 확인하십시오.
- 플러그인이 활성 상태였습니다.
- audit_log_policy 가 QUERIES 로 설정되었습니다 .
이 검사는 이러한 설정이 동적이고 디스크의 my.cnf 파일 외부에서 변경될 수 있기 때문에 범위 내 DB의 구성이 즉석에서 변경되지 않았음을 확인 합니다.
- 데이터가 흐르는지 확인하기 위해 모니터링 스택에 로그를 보내는 포트를 확인하십시오. 기본적으로 syslog 스트림의 다른 쪽 끝이 작동하는지 확인합니다. 이 검사는 어떤 의미에서 집계 검사 라고 부르는 것으로 처리 되므로 InfoSec 팀을 심하게 호출하지 않습니다.
도중에 장애물
플러그인 구성 감사
이 프로젝트의 초기 반복 중 하나는 우리가 내보내는 이벤트를 데이터 또는 스키마 조작으로만 제한하기 위해 audit_log_exclude_commands 기능을 활용하기 위한 것입니다. 우리는 이 구성의 기반이 되는 목록이 예상보다 훨씬 길다는 것을 빨리 알게 되었습니다.
rsyslog 구성
이 프로젝트 전에는 몰랐던 사실이 있습니다. Rsyslog 구성은 거의 자체 언어입니다. 예를 들어:
- UDP 대신 TCP를 통해 로그를 보내려면 원격 대상 앞에 두 번째 @ 를 사용합니다. 우리는 이 기능을 활용하여 로그가 전달되는 것을 조금 더 보장하고 싶었습니다.
- rsyslog에는 안정적인 포워딩을 위해 구성하는 방법에 대한 전용 페이지 가 있습니다. 이는 저와 같은 도구를 처음 접하는 사람에게 정말 유용한 것으로 판명되었습니다.
- rsyslog는 기본적으로 데이터를 /var/log/messages 에 저장합니다. 이는 많은 이벤트이기 때문에 제 경우에는 바람직하지 않았습니다. 사용 중인 기능을 그렇게 하지 않도록 해야 하는 경우 구성 끝에 local5.* ~ 를 추가해야 합니다.
소방 훈련
나중에 범위 내의 데이터베이스에 대한 성능 영향에 대해 이야기할 것이지만 rsyslog가 이 디자인의 중요한 부분으로 사용되었기 때문에 원격 대상을 사용할 수 없거나 응답하지 않을 때 rsyslog가 어떻게 작동하는지 발사 훈련도 필요했습니다. 이를 수행하는 가장 좋은 방법은 트랜잭션 처리량이 높기 때문에 초당 감사 이벤트가 많은 것으로 알려진 범위의 데이터베이스 중 하나에서 프로덕션 환경에서 iptables 규칙을 사용하여 해당 통신을 중단하는 것입니다. 소방 훈련이 어떻게 진행되었는지는 다음과 같습니다.
- 감사 이벤트가 지정된 TCP 포트를 통해 흐르고 있는지 확인
- iptables 규칙을 사용하여 해당 포트의 모든 트래픽을 삭제합니다. /sbin/iptables -A OUTPUT -p tcp –dport {PORT-NUMBER-HERE} -j DROP
- rsyslog의 구성에서 구성된 WorkDirectory 의 디스크 쓰기 활동 및 파일을 관찰하십시오. 파일 이름은 이러한 이벤트를 수신하는 시설 의 ActionQueueFileName 을 기반으로 합니다.
예상대로 파일이 이 디렉토리에서 스풀링을 시작했습니다. 디스크 IOP 활동이 급증했습니다. 대기열 이름을 정의한 파일 수가 ActionQueueMaxDiskSpace 값으로 합산 되면 rsyslog가 이러한 파일 생성을 중지하고 디스크 IOP가 정규화되었으며 이제 rsyslog 계층에서 바닥에 이벤트를 삭제하고 있음이 분명해졌습니다. 더 인상적이었던 점은 이식 가능한 규칙을 제거한 후 rsyslog가 디스크에 스풀링한 모든 이벤트를 다시 보내므로 스풀 크기를 초과하지 않는 한 분석 저장소에 대한 이벤트 손실이 없다는 것입니다. 우리는 실험을 기반으로 몇 가지를 배웠습니다
- rsyslog가 문서화된 대로 작동합니다. 직접 실험으로 증명하는 것이 항상 더 좋습니다.
- 각각이 생성하는 이벤트의 양에 따라 클러스터마다 다른 큐 디스크 공간을 정의해야 할 가능성이 매우 높습니다. 디스크에서 큐잉하면 IOP 용량과 디스크 용량에 위험이 추가되므로 주기적으로 다시 방문하여 다시 검토해야 합니다.
다음 게시물에서는 이 프로젝트를 프로덕션에 배포한 후 관찰한 내용과 가능한 한 프로덕션에 지장을 주지 않는 요소에 대해 이야기하겠습니다.