PN으로 익명 스레드를 게시하거나 익명 피드백을 제공하기 위한 플러그인

:information_source: 요약 두 개의 독립적이고 익명인 게시 양식을 제공합니다
:hammer_and_wrench: 레포지토리 링크 GitHub - elRicharde/discourse-anonymous-feedback: Anonymous Feedback Formular in Discourse · GitHub
:open_book: 설치 가이드 Discourse에서 플러그인 설치하는 방법

이 Discourse 플러그인은 두 개의 독립적이고 익명인 게시 양식인 "익명 피드백(Anonymous Feedback)"과 "화이트보드(White Board)"를 제공합니다. 두 양식 모두 "도어 코드(문 비밀번호)"라는 간단한 비밀번호로 보호되며, 사용자가 계정을 가지고 있지 않더라도 사전에 구성된 사용자 그룹으로 개인 메시지를 보낼 수 있습니다. 포럼이 일반적으로 로그인을 요구하더라도 이 두 양식은 로그인이 필요하지 않습니다.

기술적으로, 게시물은 로그인 없이 웹페이지를 통해 제출되며, 심지어 프라이빗 브라우징 탭에서도 사용할 수 있습니다. IP 주소가 기록되지 않으므로 발신자를 추적할 수 있는 방법이 없습니다. 이 플러그인은 안전하고 기밀성이 보장된 통신 채널을 제공하도록 설계되었습니다.

왜 이 플러그인을 사용해야 하는가?

많은 커뮤니티에서 민감한 주제나 아이디어는 익명성을 보장하고 사회적 압력을 줄이는 피드백 채널이 필요합니다. 이 플러그인은 다음과 같은 주요 과제들을 해결합니다:

  • 억제되지 않은 피드백 촉진: 사용자(도어 코드가 외부에 공유된다면 비사용자 포함)가 판단이나 불이익에 대한 두려움 없이 솔직하고 필터링되지 않은 의견, 우려 사항, 혁신적인 아이디어를 나눌 수 있는 안전한 공간을 제공합니다. 이는 그렇지 않았다면 억제되었을 수 있는 더 담대하고 가치 있는 정보를 이끌어낼 수 있습니다.

  • 기밀성과 신뢰: IP 기록 없이 HMAC 기반 속도 제한과 같은 기술적 조치를 통해 익명성을 보장함으로써, 특히 민감한 주제에 대해 신뢰를 구축하고 더 넓은 참여를 장려합니다.

  • 소통 격차 해소: 공개적으로 게시하기를 망설이거나 Discourse 계정이 없는 개인을 위한 접근 가능한 소통 다리를 만들어 커뮤니티 참여의 범위를 넓힙니다.

  • 구조화된 입력: 피드백을 특정 비공개 그룹으로 전달함으로써 민감한 정보가 적절한 팀 멤버에 의해 검토되도록 보장하여, 공개 시야에서 벗어나 초점을 맞춘 논의와 행동을 가능하게 합니다.

  • 비사용자를 위한 단순성: 도어 코드 메커니즘은 외부 당사자나 일시적인 방문자가 전체 계정 등록의 번거로움 없이 의견을 제공할 수 있게 합니다.

결국, 이 플러그인은 비판적인 논의와 제안에 대해 더 포용적이고 안전한 환경을 가능하게 함으로써 커뮤니티 상호작용을 향상시킵니다.

동작 원리 (기술 개요)

이 플러그인은 익명성과 보안을 중점으로 개발되었습니다.

  1. 접근: 사용자가 /anonymous-feedback 또는 /white-board로 이동합니다.

  2. 잠금 해제: 사용자는 올바른 도어 코드를 입력해야 합니다. 서버는 이 코드를 검증합니다.

    • 브루트포스 공격을 방지하기 위해, 서버는 사용자의 IP 주소와 회전하는 시크릿 기반의 HMAC 해시를 사용하는 속도 제한 시스템을 적용합니다. IP 주소 자체는 절대 저장되지 않습니다.

    • 코드가 올바르면, 서버는 사용자의 세션에 일시적이고 일회성으로 사용 가능한 플래그를 설정합니다.

  3. 제출: 사용자는 메시지를 작성하고 전송합니다.

  4. PM 생성: 서버는 세션 플래그를 확인합니다. 유효한 경우, 구성된 대상 그룹으로 새 개인 메시지를 생성하고 구성된 봇 사용자(또는 시스템 사용자)로 게시합니다. 이후 세션 플래그는 즉시 삭제되므로, 사용자가 추가 메시지를 보내려면 다시 도어 코드를 입력해야 합니다.

예시 사용 사례 / 워크플로우

이 플러그인은 유연하도록 설계되었습니다. 구현할 수 있는 두 가지 일반적인 워크플로우를 소개합니다:

사용 사례 1: “화이트보드” - 조정된 공개 공지 게시판

이 사용 사례는 커뮤니티에서 관찰된 민감한 주제나 부적절한 행동(예: 이벤트나 일반적인 상호작용 중)에 대한 가시성을 만드는 데 사용됩니다. 예를 들어, 성차별과 같은 문제를 가시화하는 것입니다.

목표: 보고한 사람의 신원을 노출하지 않고 중요한 문제를 커뮤니티에 가시화하는 것입니다. 초점은 발신자가 아니라 메시지, 그리고 잠재적으로 관련 개인에 있지 않을 수 있습니다. 이름을 명시하지 않고 부적절한 행동 상황을 단순하게 표현하는 것만으로도 가시성을 만들고 인식을 높일 수 있습니다.

워크플로우:

  1. 제출: 사용자가 /white-board 양식을 통해 게시물을 제출합니다. 이는 멤버(MG), 견습생(ANW), 촉진자(FM)가 접근할 수 있습니다. 사용자 "Anonymous"만 게시물을 생성할 수 있습니다.

  2. 비공개 검토: 게시물은 구성된 target_group(예: 조정 팀 또는 “신뢰 및 안전” 위원회)으로 개인 메시지로 도착합니다. “화이트보드” 항목으로 식별됩니다.

  3. 검증: 팀은 사전에 정의된 기준(예: 개인 공격 금지, 모욕 금지, 커뮤니티 가이드라인 준수)에 따라 제출물을 검토합니다.

  4. 게시 (승인 시): 관리자가 메시지에 초대되어 이를 전용 공개 “화이트보드” 카테고리의 공개 토픽으로 변환합니다. 이 토픽은 특정 일반 계정(예: bot_username 설정을 통해 구성된 “WhiteBoardBot” 또는 “Anonymous” 사용자)을 사용하여 게시됩니다. 이 사용자의 로그인 정보는 검토 그룹과 공유할 수 있습니다. 게시는 사용자 "Anonymous"에 의해 수행됩니다.

  5. 토론 제어: “화이트보드” 카테고리 권한은 멤버/견습생/촉진자에게는 보이지만 댓글 달기는 불가능하도록 설정됩니다. 일반 포럼 조정원은 이 특정 영역을 조정하지 않는 것이 기대되며, 이는 지정된 target_group의 전적인 책임입니다. 화이트보드에 하위 카테고리(예: “익명 닫힘” 또는 target_group 게시물을 위한 카테고리)가 포함되어야 하는지에 대한 질문은 여전히 남아 있습니다.

  6. 거절 처리: 익명 발신자에게 연락할 방법이 없으므로, “화이트보드” 카테고리에 게시 기준과 제출물이 거절될 수 있는 이유를 설명하는 고정된 토픽을 두는 것이 좋은 관행입니다. 비게시를 정당화하는 규칙은 항상 포럼의 한 곳에서 공개되어야 합니다.

사용 사례 2: 익명 피드백 - 직접적이고 비공개 채널

이 사용 사례는 모든 종류의 피드백(예: 투표 피드백 또는 기타 익명 제안)을 특정 팀으로 전달하는 직접적이고 기밀성이 보장된 통신 라인을 제공하는 데 사용됩니다.

목표: 멤버와 비멤버 모두에게 커뮤니티 문제, 투표 또는 기타 주제에 대한 피드백을 리더십이나 관련 위원회로 직접 제공할 수 있는 안전한 방법을 제공하는 것입니다.

워크플로우:

  1. 제출: 사용자가 /anonymous-feedback 양식을 통해 피드백을 제출합니다. 제목 줄은 메시지 분류에 도움이 될 수 있습니다. 이 게시물은 제목 접두사 "Anonymous Message - dd.mm.yyyy, hh:mm:ss"와 함께 target_group의 공동 수신함에 도착합니다.

  2. 비공개 전달: 메시지는 target_group으로 개인 메시지로 도착합니다. 제목 접두사를 통해 "익명 피드백"으로 식별됩니다. target_group은 메시지에 대해 무엇을 할지 결정합니다.

  3. 내부 처리: 팀은 피드백을 비공개로 논의하고, 필요시 다른 관련 당사자를 포함시키거나, 행동 계획을 결정할 수 있습니다. 이 피드백은 투표 피드백이나 기타 익명 제안에 사용될 수 있습니다.

  4. 부적절한 피드백에 대한 모범 사례: 제출물이 부적절할 경우, 팀은 단순히 삭제할 수 있습니다. "[날짜]에 받은 피드백은 우리의 존중 있는 소통 커뮤니티 표준을 위반했기 때문에 처리되지 않았습니다."라는 일반적인 공개 공지(예: “뉴스” 카테고리)를 게시하는 것을 고려할 수 있습니다. 이는 발신자에게 세부 사항을 공개하지 않고 알리며, 더 건설적인 방식으로 재제출하도록 장려합니다. 화이트보드를 위한 게시물인 경우 (특별한 표시가 없거나 도움이 된다면 접미사가 있을 수 있음): 조정원들이 메시지에 초대되지만, 아무도 메시지에 답장하지 않습니다. 조정원들은 메시지를 “화이트보드” 카테고리의 토픽으로 변환합니다 → 멤버/견습생/촉진자에게 보이며 댓글 달기는 불가능합니다.

기능

  • 두 개의 독립적인 엔드포인트: /anonymous-feedback/white-board를 제공하며, 각각 자체의 개별 구성을 가집니다.

  • 도어 코드를 통한 보호: 각 양식은 스팸을 방지하기 위해 자체의 비밀 도어 코드로 보호됩니다. 도어 코드는 모든 사람에게 동일하며, 페이지는 프라이빗 모드나 부모님의 컴퓨터에서도 사용할 수 있습니다.

  • 구성 가능한 대상 그룹: 각 양식에서 온 메시지는 특정, 구성 가능한 사용자 그룹으로 개인 메시지로 전송됩니다.

  • 일회성 세션: 메시지가 성공적으로 전송된 후, 사용자는 도어 코드 화면으로 리디렉션됩니다. 또 다른 메시지를 보내려면 코드를 다시 입력해야 하며, 이는 단순한 다중 게시 스팸을 방지합니다. 전송 후 도어 코드로 돌아오며, 다중 게시는 쉽게 불가능합니다.

  • 익명성을 보존하는 속도 제한: IP 주소를 기록하지 않고도 브루트포스 공격과 스팸으로부터 보호합니다.

  • 봇 보호: 단순한 봇을 포착하기 위한 숨겨진 허니팟 필드를 포함합니다.

  • 사용자 정의 발신 사용자: 각 양식에 대해 개인 메시지가 이 사용자(예: “FeedbackBot”)에 의해 전송된 것처럼 보이도록 봇 사용자를 정의할 수 있습니다. 사용자는 존재해야 합니다. 비어 있으면 기본적으로 시스템 사용자가 사용됩니다.

  • 깔끔하고 현대적인 사용자 인터페이스: 양식은 일관되고 깔끔한 사용자 경험을 위해 재사용 가능한 Ember.js 컴포넌트에 기반합니다.

설치

Discourse 플러그인 설치 표준 가이드를 따르세요: 플러그인 설치.

  1. 플러그인의 레포지토리 URL을 app.yml 파일에 추가합니다:

    hooks:
      after_code:
        - exec:
            cd: $home/plugins
            cmd:
              - git clone https://github.com/elRicharde/discourse-anonymous-feedback
    
  2. 컨테이너를 다시 빌드합니다: cd /var/discourse && ./launcher rebuild app

구성

설치 후, Discourse 관리자 설정에서 플러그인을 구성할 수 있습니다. "anonymous feedback"을 검색하세요. 모든 설정은 "익명 피드백"과 “화이트보드” 양식에 대해 독립적입니다.

설정 설명
anonymous_feedback_enabled /anonymous-feedback 페이지를 켜거나 끕니다.
white_board_enabled /white-board 페이지를 켜거나 끕니다.
... door_code 사용자가 메시지 양식에 접근하기 위해 입력해야 하는 비밀 비밀번호입니다.
... target_group 개인 메시지를 받는 사용자 그룹의 이름입니다. 이 그룹은 존재해야 합니다.
... rate_limit_per_hour 남용을 방지하기 위해 시간당 보낼 수 있는 메시지의 전역 제한입니다. 비활성화하려면 0으로 설정하세요.
... max_message_length 메시지 텍스트에서 허용되는 최대 문자 수입니다.
... hmac_rotation_hours 속도 제한을 위한 시크릿 키가 회전되는 빈도입니다. 더 짧은 기간은 브루트포스 잠금을 더 빨리 재설정하지만 약간 덜 안전합니다.
... bot_username 선택 사항입니다. PM을 보낼 사용자의 사용자 이름입니다. 사용자는 존재해야 합니다. 비어 있으면 시스템 사용자가 사용됩니다.

개발 / 아키텍처

  • 백엔드: 단일 Ruby on Rails 컨트롤러인 AnonymousFeedbackController가 두 엔드포인트의 모든 요청을 처리합니다. 이는 요청 경로(/anonymous-feedback/white-board 비교)를 확인하여 어떤 구성을 사용할지 결정하는 kind 메서드를 사용합니다. 이는 코드 중복을 방지합니다. 동적 setting 헬퍼는 구성 읽기를 추가로 단순화합니다.

  • 프론트엔드: 사용자 인터페이스는 단일, 재사용 가능한 Ember.js 컴포넌트인 <AnonymousFeedbackForm />에 기반합니다.

    • 이 컴포넌트는 양식의 상태(잠금 해제, 전송, 오류 처리)에 대한 전체 HTML, CSS, JavaScript 로직을 포함합니다.

    • 라우트 템플릿(anonymous-feedback.hbswhite-board.hbs)은 이제 매우 단순합니다. 이 컴포넌트를 인스턴스화하고 올바른 매개변수(예: 제목, API URL)를 전달하는 것만 합니다. 이 DRY(반복하지 않기) 접근 방식은 프론트엔드 코드를 깔끔하고 유지보수하기 쉽게 만듭니다.

심층 분석: 익명성 및 속도 제한 (HMAC)

이 플러그인의 핵심 기능은 절대적 익명성남용(스팸)에 대한 보호 사이의 균형입니다.

문제: 유한한 IP 주소

IPv4 주소는 유한한 조합의 집합(약 43억 개)으로 구성됩니다.

  • 위험: 해시 함수(SHA256 등)는 비가역적 일방향 함수입니다. 그러나 단순히 SHA256(IP_Address)를 저장한다면, 공격자(또는 관리자)는 모든 기존 IP 주소에 대한 해시를 몇 초 안에 사전 계산(“무지개 테이블”)할 수 있습니다. 저장된 해시를 그들의 목록과 비교함으로써 즉시 원래 IP를 드러낼 수 있습니다.

해결책: 회전하는 시크릿을 사용한 HMAC

HMAC(해시 기반 메시지 인증 코드)을 사용합니다. 이는 해시하기 전에 메시지(IP)를 암호화 시크릿 키와 결합합니다.

  • 메커니즘: Identifier = HMAC(IP_Address + Secret_Key)

  • 왜 작동하는가: 공격자가 모든 가능한 IP 주소를 알고 있더라도, 그들은 Secret Key모릅니다. 이 키가 없으면 해시를 사전 계산할 수 없습니다. 시크릿 변수가 없으므로 “무지개 테이블” 공격은 불가능해집니다.

진행적 기밀성 (키 회전)

Secret Key는 자동으로 회전됩니다(예: 4시간마다).

  • 시나리오: 서버가 해킹되어 공격자가 현재 시크릿 키와 데이터베이스를 탈취했다고 상상해 보십시오.

  • 보호: 키가 정기적으로 변경되고 이전 키는 영구적으로 폐기되므로, 공격자는 현재 시간 창(예: 지난 4시간)의 IP 해시만 계산할 수 있습니다. 어제나 지난 주에 있었던 모든 활동은 더 이상 존재하지 않는 키로 해시되었습니다. 이는 진행적 기밀성을 보장합니다: 현재 시스템이 침해되더라도 과거의 익명성은 깨지지 않습니다.

빠른 회전 vs. 느린 회전

회전 간격(hmac_rotation_hours)을 구성할 수 있습니다.

  • 빠른 회전 (예: 1시간):

    • 장점: 최대 익명성. 구분 가능한 행동이 동일한 (알 수 없는) 행위자와 연결될 수 있는 시간 창이 매우 짧습니다.

    • 단점: 속도 제한에 대한 “기억 상실”. 키가 회전되면 서버는 이미 메시지를 보낸 사람을 “잊습니다”. 1시간 차에 차단된 스팸머는 2시간 차에 사실상 차단 해제됩니다.

  • 느린 회전 (예: 24시간):

    • 장점: 차단이 더 오래 지속되므로 스팸에 대한 더 강력한 보호.

    • 단점: 이 24시간 창 내에서, 관리자는 "사용자 X"가 5개의 메시지를 보냈다는 것을 볼 수 있지만, "사용자 X"가 누구인지는 알지 못합니다 (연결 가능성).

권장 사항: 4시간에서 12시간 사이의 값은 견고한 균형을 제공합니다.

3개의 좋아요