Miro의 Splunk 통합은 Enterprise 고객이 조직 전반에 걸쳐 고급 보안 모니터링, 규정 준수 보고 및 운영 분석을 위해 두 가지 유형의 로그 데이터를 Splunk로 내보낼 수 있도록 합니다. 이 통합은 지원합니다:
- 감사 로그: 사용자 액세스, 보드 공유, 권한 변경, 앱 설치, 로그인 및 관리 작업과 같은 사용자 및 시스템 수준 활동을 조직 전반에 걸쳐 캡처합니다.
-
콘텐츠 로그(Enterprise Guard 애드온): Miro 보드 내에서 콘텐츠 수준의 활동을 자세히 기록하고, 보드 객체(위젯, 스티커 메모, 이미지, 텍스트, 프레임)의 생성, 편집, 삭제와 댓글 활동을 포착합니다.
모범 사례
- 감사 로그와 콘텐츠 로그를 각각 별도의 색인으로 사용하세요.
- 규정 준수 요구 사항에 따라 보유 기간을 계획하세요.
- 포괄적인 활동 모니터링을 위해 두 가지 로그 유형을 함께 검토하세요.
사전 준비
- 엔터프라이즈 플랜 구독
- 콘텐츠 로그를 활성화하려면 Enterprise Guard 애드온이 필요합니다.
- 둘 다에 대한 관리자 액세스:
- Miro 관리자 콘솔(SIEM을 활성화하고 토큰을 생성하려면)
- Splunk 인스턴스(데이터 입력 구성)
Miro에서 액세스 토큰 생성
감사 로그와 콘텐츠 로그 토큰은 Miro에서 동일한 위치에서 생성할 수 있습니다.
- 관리자 콘솔에서 Enterprise 통합 → 앱 및 통합으로 이동하세요.
- 감사 로그: SIEM 토글을 활성화하세요.
콘텐츠 로그에 대하여: eDiscovery 토글을 활성화하세요.
또는 맞춤형 Miro 앱을 등록하여 다음 범위로 토큰을 생성할 수 있습니다: auditlogs:read, contentlogs:export.
⚠️ 감사 로그와 콘텐츠 로그는 별도의 토큰을 사용합니다. 각 입력 유형에 맞는 올바른 토큰을 선택하세요.
조직 ID도 필요한데, 이는 관리 콘솔 URL에서 복사할 수 있습니다.https://miro.com/app/org/{organization_id}/...
Miro용 Splunk 앱 설치 및 구성하기
- Splunkbase에서 Miro Splunk 앱을 설치하세요.
- 사용 중인 Splunk 인스턴스에서 미로 앱 → 입력으로 이동합니다.
- 새 입력 만들기를 클릭하세요.
- 원하는 입력 유형을 선택하세요: 감사 로그 또는 콘텐츠 로그 (Enterprise Guard 고객용).
- 다음 정보를 제공하세요:
- 토큰 — 입력 유형에 따라 적절한 토큰을 선택하세요.
- 조직 ID
- 시간 간격 — Splunk이 새로운 이벤트를 가져오는 빈도를 결정합니다.
- 색인 - 로그 데이터를 저장할 색인을 지정하세요. 콘텐츠 로그의 경우, 높은 볼륨과 데이터 민감성 때문에 별도의 인덱스를 추천합니다.
구성이 완료되면 Splunk가 Miro에서 로그 이벤트 수집을 시작합니다.
문제 해결
- 토큰이 올바르게 생성되고 올바른 입력 유형에 매핑되었는지 확인하세요.
- 조직 ID가 관리자 콘솔과 일치하는지 확인하세요.
- Splunk에서 인덱스가 올바르게 생성되고 권한이 할당되었는지 확인하세요.
Splunk에서 로그 검색 방법
데이터 입력을 구성한 후, 감사 로그와 콘텐츠 로그에 지정한 인덱스를 사용해 Splunk에서 로그를 검색하고 분석할 수 있습니다.
-
감사 로그:
index="your_audit_index" source="miro_audit_logs"
-
콘텐츠 로그:
index="your_content_index" source="miro_content_logs"
your_audit_index
와 your_content_index
를 입력 설정 시 지정한 인덱스로 교체하세요. 일반적인 Splunk 검색, 필터링 및 시각화 기능을 두 로그 유형 모두에 사용할 수 있습니다.
Splunk에서의 데이터 시각화
Miro용 Splunk 앱에는 사용자 및 시스템 활동을 모니터링하는 데 도움이 되는 감사 로그에 대한 사전 구축된 대시보드가 포함되어 있습니다. 콘텐츠 로그를 설정한 후에는 Splunk의 표준 시각화 도구를 사용하여 보드 수준의 콘텐츠 변경 사항을 시각화할 수 있는 맞춤형 대시보드를 구축할 수 있습니다.
필터, 차트 및 시간 기반 그래프를 사용해 다음과 같은 트렌드를 분석하세요:
- 보드 내용 삭제 또는 변경 내역
- 대량 콘텐츠 수정에 대한 스파이크 감지
- 민감한 보드에서의 사용자 활동
Splunk 앱의 Out-of-the-box 대시보드는 현재 감사 로그를 위해 설계되어 있습니다. 조직의 필요에 따라 맞춤형 검색 쿼리와 대시보드를 통해 콘텐츠 로그를 분석할 수 있습니다.
<dashboard theme="light" version="1.1">
<label>Miro 사용자 활동</label>
<description>Miro 계정의 사용자 이벤트 개요입니다.</description>
<search id="basesearch">
<query>source=miro_audit_logs | fields * | eval context.team.name = if(isnull('context.team'), 'context.team.name', "None") | search context.organization.name = "$form.organization$" context.team.name = "$form.team$"</query>
<earliest>$time.earliest$</earliest>
<latest>최신 $time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>시간 범위</label>
<default>
<earliest>-30일@일</earliest>
<latest>지금</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>조직</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| table context.organization.name | dedup context.organization.name</query>
</search>
<choice value="*">모두</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>팀</label>
<choice value="*">모두</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>context.team.name</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| 테이블 context.team.name | context.team.name 중복 제거</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>
<title>전체 이벤트</title>
<search base="basesearch">기반 검색
<query>| stats count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
</row>
<row>
<panel>패널
<chart>
<title>날짜별 이벤트</title>
<search base="basesearch">
<query>| timechart count as 이벤트</query>
</search>
<option name="charting.axisTitleX.visibility">숨김</option>
<option name="charting.axisTitleY.visibility">표시됨</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">영역</option>
<option name="charting.chart.nullValueMode">갭</option>
<option name="charting.chart.stackMode">스택형</option>
<option name="charting.drilldown">없음</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">표준</option>
<option name="charting.legend.placement">없음</option>
<option name="refresh.display">프로그레스바</option>
</chart>
</panel>
<panel>
<chart>
<title>팀별 이벤트</title>
<search base="basesearch">검색 기준
<query>| context.team.name을 팀으로 이름 변경 | stats count를 "이벤트"로 변경하여 팀별로 분류 | "이벤트"에 따라 정렬</query>
</search>
<option name="charting.chart">파이 옵션</option>
<option name="charting.chart.sliceCollapsingThreshold">0.03</option>
<option name="charting.drilldown">모두</option>
<option name="refresh.display">진행 상태 막대</option>
<drilldown>
<set token="form.team">$클릭.값$</set>
</drilldown>
</chart>
</panel>
</row>
<row>
<panel>
<single>
<title>보드 이벤트</title>
<search base="basesearch">
<query>| 검색 event = board_* | stats count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
<panel>
<single>
<title>생성된 보드</title>
<search base="basesearch">
<query>| search event = 보드_생성됨 | stats count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
<panel>패널
<single>
<title>보드 열림</title>
<search base="basesearch">
<query>| 검색 이벤트 = 보드_열림 | 통계 카운트</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>열거나 생성된 보드</title>
<search base="basesearch">
<query>| search event = board_created OR event = board_opened | timechart count as "생성된 보드" by event</query>
</search>
<option name="charting.axisTitleX.visibility">접힘</option>
<option name="charting.axisTitleY.visibility">표시됨</option>
<option name="charting.chart">열</option>
<option name="charting.chart.stackMode">스택됨</option>
<option name="charting.drilldown">없음</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.placement">오른쪽</option>
<option name="refresh.display">진행 표시줄</option>
</chart>
</panel>
</row>
</dashboard>
<dashboard theme="light" version="1.1">
<label>Miro 보안 액티비티</label>
<description>Miro 계정의 보안 이벤트 개요.</description>
<search id="basesearch">
<query>source=miro_audit_logs | fields * | search context.organization.name = "$form.organization$"</query>
<earliest>$time.earliest$</earliest>
<latest>최신 $time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>시간 범위</label>
<default>
<earliest>-30일@d</earliest>
<latest>지금</latest>
</default>
</입력></input>
<input type="dropdown" token="organization">
<label>조직</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| table context.organization.name | context.organization.name의 중복 제거</query>
</search>
<choice value="*">모두</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>팀</label>
<choice value="*">모두</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>context.team.name</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| table context.team.name | dedup context.team.name</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>
<title>로그인 성공</title>
<search base="basesearch">검색 기본
<query>| search event = sign_in_succeeded | stats count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
<panel>
<single>
<title>로그인 실패</title>
<search base="basesearch">
<query>| search event = sign_in_failed | stats count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>인증 방법별 로그인</title>
<search base="basesearch">
<query>| 이벤트 sign_in_* 검색 | timechart count as Events by details.authType</query>
</search>
<option name="charting.axisTitleX.visibility">숨김</option>
<option name="charting.axisTitleY.visibility">표시</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">열</option>
<option name="charting.chart.nullValueMode">간격</option>
<option name="charting.chart.stackMode">스택 모드</option>
<option name="charting.drilldown">없음</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">표준</option>
<option name="charting.legend.placement">오른쪽</option>
<option name="refresh.display">progressbar</option>
</chart>
</panel>
</row>
<row>
<panel>
<table>
<title>이벤트 공유</title>
<search base="basesearch">
<query>| 이벤트 = *public_link* OR 이벤트 = *sharing*을 검색합니다 | context.team.name을 팀으로, createdBy.name을 사용자로, object.name을 보드로, details.role을 세부사항으로, event를 이벤트로 이름을 바꿉니다 | id, _time, 이벤트, 팀, 사용자, 보드, 세부사항 테이블</query>
</search>
<option name="count">10</option>
<option name="drilldown">셀</option>
<option name="refresh.display">프로그레스바</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<title>파일 이벤트</title>
<search base="basesearch">기반 검색에서 검색
<query>| 이벤트 = 보드_내보내기 OR 이벤트 = 파일_* | context.team.name을 팀으로, createdBy.name을 사용자로, object.name을 보드로, details.type을 유형으로, details.object를 오브젝트로, event를 이벤트로 바꿉니다. | 테이블 id _time 이벤트 팀 사용자 보드 유형 오브젝트</query>
</search>
<option name="count">옵션 이름</option>
<option name="drilldown">셀</option>
<option name="refresh.display">진행률 표시기</option>
</table>
</panel>
</row>
</dashboard>
도표 18: 대시보드 편집
사용자 활동
첫 번째 시각화는 사용자 활동으로, Miro에서 사용자의 이벤트 개요를 확인할 수 있습니다. 다음과 같습니다:
- 팀별 및 총 이벤트 수에 대한 시간 경과 정보입니다.
-
보드 이벤트: 생성된 보드, 열린 보드 및 총 수.
그림 19: 사용자 활동
<dashboard theme="light" version="1.1">
<label>Miro 사용자 활동</label>
<description>Miro 계정의 사용자 이벤트 개요입니다.</description>
<search id="basesearch">
<query>source=miro_audit_logs | fields * | eval context.team.name = if(isnull('context.team'), 'context.team.name', "None") | search context.organization.name = "$form.organization$" context.team.name = "$form.team$"</query>
<earliest>$time.가장빠름$</earliest>
<latest>$time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>시간 범위</label>
<default>
<earliest>-30일@d</earliest>
<latest>지금</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>조직</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| table context.organization.name | context.organization.name 중복 제거</query>
</search>
<choice value="*">전체</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>팀</label>
<choice value="*">모두</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>context.team.name</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| table context.team.name | dedup context.team.name</query>
</search>
</input>
</fieldset>
<row>
<panel>
<single>
<title>총 이벤트</title>
<search base="basesearch">
<query>| 통계 count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>날짜별 이벤트</title>
<search base="basesearch">
<query>| timechart count as 이벤트</query>
</search>
<option name="charting.axisTitleX.visibility">축 제목 X 가시성</option>
<option name="charting.axisTitleY.visibility">표시</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">영역</option>
<option name="charting.chart.nullValueMode">간격</option>
<option name="charting.chart.stackMode">스택된</option>
<option name="charting.drilldown">없음</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">표준</option>
<option name="charting.legend.placement">없음</option>
<option name="refresh.display">프로그레스바</option>
</chart>
</panel>
<panel>
<chart>
<title>팀별 이벤트</title>
<search base="basesearch">
<query>| context.team.name을 팀으로 이름 바꾸기 | stats를 "이벤트"로 계산하기 by 팀 | 이벤트로 내림차순 정렬하다</query>
</search>
<option name="charting.chart">파이</option>
<option name="charting.chart.sliceCollapsingThreshold">0.03</option>
<option name="charting.drilldown">모두</option>
<option name="refresh.display">진행 표시줄</option>
<drilldown>
<set token="form.team">$click.value$</set>
</drilldown>
</chart>
</panel>
</row>
<row>
<panel>
<single>
<title>보드 이벤트</title>
<search base="basesearch">
<query>| 이벤트 = 보드_* 검색 | 통계 count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
<panel>
<single>
<title>생성된 보드</title>
<search base="basesearch">
<query>| search event = board_created | stats count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
<panel>패널
<single>
<title>보드 열기</title>
<search base="basesearch">
<query>| search event = 보드_열림 | stats count</query>
</search>
<option name="drilldown">사용 안 함</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>열리거나 생성된 보드</title>
<search base="basesearch">
<query>| search event = board_created OR event = board_opened | timechart count as "생성한 보드" by event</query>
</search>
<option name="charting.axisTitleX.visibility">축 제목 X 축 보기 설정</option>
<option name="charting.axisTitleY.visibility">표시</option>
<option name="charting.chart">세로 막대형</option>
<option name="charting.chart.stackMode">스택 모드</option>
<option name="charting.drilldown">없음</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.placement">오른쪽</option>
<option name="refresh.display">진행률 표시줄</option>
</chart>
</panel>
</row>
</dashboard>
보안 활동
두 번째 시각화는 보안 활동으로 Miro에서 사용자 이벤트 개요를 확인할 수 있는 곳입니다. 이는 다음과 같습니다:
- 로그인 활동: 성공 및 실패한 로그인 수.
-
공유 이벤트: 보드를 공유할 때 사용자의 이벤트 목록.
도표 20: 보안 활동
<dashboard theme="light" version="1.1">
<label>Miro 보안 액티비티</label>
<description>Miro 계정의 보안 이벤트 개요입니다.</description>
<search id="basesearch">검색
<query>source=miro_audit_logs | fields * | search context.organization.name = "$form.organization$"</query>
<earliest>$time.earliest$</earliest>
<latest>최신 $time.latest$</latest>
</search>
<fieldset submitButton="false">
<input type="time" token="time">
<label>시간 범위</label>
<default>
<earliest>-30일@d</earliest>
<latest>지금</latest>
</default>
</input>
<input type="dropdown" token="organization">
<label>조직</label>
<fieldForLabel>context.organization.name</fieldForLabel>
<fieldForValue>context.organization.name</fieldForValue>
<search base="basesearch">
<query>| table context.organization.name | 테이블 context.organization.name 중복 제거</query>
</search>
<choice value="*">모두</choice>
<default>*</default>
<initialValue>*</initialValue>
</input>
<input type="dropdown" token="team">
<label>팀</label>
<choice value="*">모두 선택</choice>
<default>*</default>
<initialValue>*</initialValue>
<fieldForLabel>context.team.name</fieldForLabel>
<fieldForValue>context.team.name</fieldForValue>
<search base="basesearch">
<query>| table context.team.name | context.team.name 중복 제거</query>
</search>
입력</input>
</fieldset>
<row>
<panel>
<single>
<title>성공적인 로그인</title>
<search base="basesearch">팀 이름으로 검색
<query>| 이벤트 = sign_in_succeeded를 검색 | 통계 count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
<panel>패널
<single>
<title>로그인 실패</title>
<search base="basesearch">
<query>| search 이벤트 = sign_in_failed | stats count</query>
</search>
<option name="drilldown">없음</option>
</single>
</panel>
</row>
<row>
<panel>
<chart>
<title>인증 방법별 로그인</title>
<search base="basesearch">기본 검색으로 검색
<query>| search event = sign_in_* | timechart count as Events by details.authType</query>
</search>
<option name="charting.axisTitleX.visibility">축 제목 X 가시성</option>
<option name="charting.axisTitleY.visibility">표시</option>
<option name="charting.axisY2.enabled">0</option>
<option name="charting.chart">열</option>
<option name="charting.chart.nullValueMode">간격</option>
<option name="charting.chart.stackMode">스택됨</option>
<option name="charting.drilldown">없음</option>
<option name="charting.layout.splitSeries">0</option>
<option name="charting.legend.mode">표준</option>
<option name="charting.legend.placement">오른쪽</option>
<option name="refresh.display">진행률 막대</option>
</chart>
</panel>
</row>
<row>
<panel>
<table>표
<title>이벤트 공유</title>
<search base="basesearch">
<query>| search event = *public_link* OR event = *sharing* | rename context.team.name as 팀 createdBy.name as 사용자 object.name as 보드 details.role as Details event as Event | table id _time Event 팀 사용자 보드 Details</query>
</search>
<option name="count">10</option>
<option name="drilldown">셀</option>
<option name="refresh.display">진행 표시줄</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<title>파일 이벤트</title>
<search base="basesearch">
<query>| 검색 이벤트 = board_exported 또는 이벤트 = file_* | context.team.name을 팀으로, createdBy.name을 사용자로, object.name을 보드로, details.type을 유형으로, details.object를 오브젝트로, event를 이벤트로 이름을 바꿉니다 | 테이블 id _time 이벤트 팀 사용자 보드 유형 오브젝트</query>
</search>
<option name="count">10</option>
<option name="drilldown">셀</option>
<option name="refresh.display">진행 표시줄</option>
</table>
</panel>
</row>
</dashboard>