IP 주소가 차단되어 SSO가 작동하지 않음

SSO를 사용 중인데, 며칠 전부터 일부 회원이 다음 오류 메시지와 함께 계정에 접근하지 못한다고 보고하고 있습니다:

계정에 문제가 있습니다. 사이트 관리자에게 문의해 주세요.

이전에는 제가 보고한 문제와 관련이 있을 수 있다고 생각하여, 해당 회원들의 IP 주소가 차단된 IP(Screened IPs) 목록에 있는지 확인해 보았습니다. 그중 하나는 목록에 있었지만, 나머지 모든 회원의 IP는 목록에 없었습니다.

verbose sso logging을 활성화한 후 다른 사용자들에게 다시 시도해 달라고 요청했고, /logs에는 해당 IP 주소가 차단되었다고 표시되었습니다:

Verbose SSO log: IP address is blocked xxx.xxx.xxx.xxx

하지만 다시 확인해 보니, 해당 IP 주소는 차단된 IP(Screened IPs) 목록에 표시되지 않았습니다. PostgreSQL의 screened_ip_addresses 테이블에서도 직접 확인해 보았으나 해당 IP 주소에 대한 항목이 없었습니다.

더 이상 아이디어가 떠오르지 않습니다… IP 주소를 차단하는 다른 섹션이 있을까요? 아니면 IP 주소가 차단된 IP(Screened IPs)에 매우 짧은 시간 동안만 추가되어 보고를 받고 나서 확인하려고 하면 이미 사라진 상태(몇 시간 차이)일까요?

정리하자면, 우리는 차단된 IP(Screened IPs)에 IP를 직접 추가하지 않습니다. API를 통해 누군가의 계정을 폐쇄할 때 자동으로 추가되는 것 같습니다(위 링크 참조). 그리고 문서화된 block_ip: false 파라미터를 사용하여 이 동작을 막는 데 실패했습니다.

해결해야 할 문제가 바로 그 부분입니다. Discourse API 역공학 방법을 참고해 보세요.

IP가 Screened IPs에 추가되는 문제는 제가 여기서 보고하려는 문제와는 별개의 문제입니다. Screened IPs에 의해 차단되지 않는 멤버들이 SSO를 통해 계정에 로그인할 수 없는 것을 확인하고 있습니다. 이는 IP address is blocked라는 이유로 발생하는 것으로 보입니다.

Screened IPs 외에 IP 주소를 차단할 수 있는 다른 곳이 있는지 확인해야 할까요?

“스패머로 삭제” 기능을 호출하고 있는 것으로 보입니다. 이 기능은 IP와 이메일 주소를 자동으로 차단 목록에 추가합니다. 해당 코드를 다시 검토해 보시는 것이 좋습니다. UI에 나와 있는 대로 "일반 삭제"를 원하시는 것이므로, "스패머로 삭제"를 사용해서는 안 됩니다.

그렇긴 하지만, 사용자를 삭제하는 방식에 대해서는 여기에서 논의되고 있습니다.

이것이 별개의 문제인지 확실하지는 않지만, IP 차단(Screened IPs) 섹션의 Matches(일치) 열이 모든 항목에서 0으로 표시되는 것을 확인했습니다. 해당 테이블의 내보내기 파일을 살펴보니 모든 IP가 0건으로 일치하는 것이 확인되었습니다. 그런데 매일 SSO를 통해 로그인하는 사용자가 IP 주소로 차단되는 현상이 발생하고 있습니다.

반면, 이메일 차단(Screened Emails)을 살펴보면 대부분 일치 건수가 있습니다. 그리고 거기에도 IP 주소 열이 있더군요… 그래서 원인을 찾았다고 생각했지만, 차단되고 있는 IP 주소도 그곳에 목록에 없었습니다.


아까 /logs에서 확인한 내용입니다:

Screenshot 2021-06-07 at 11.58.56

IP 차단(Screened IPs) 검색 결과입니다;

이메일 차단(Screened Emails)도 확인해 보았는데, 방금 로그인이 차단된 계정의 IP 주소나 이메일 주소도 그곳에 없습니다.

어디서 더 확인해 볼 수 있는지 조언이 있을까요?

여기서 문제를 찾은 것 같습니다 (결국 문제는 우리 쪽에 있었지만), 보고할 버그가 몇 가지 있습니다. 다만 제가 익숙하지 않은 스택이라, 누군가가 더 자세히 살펴봐 주시면 좋겠습니다.

먼저 원인에 대해 말씀드리겠습니다. screened_ip_addresses 데이터베이스 테이블을 직접 확인해 보니, 차단되어서는 안 되는 두 개의 전체 블록(176.59.0.0/16과 109.252.0.0/16)이 차단되어 있었습니다. 이 항목들이 어떻게 추가되었는지 솔직히 모르겠고, 두 항목은 2월부터 존재하고 있었습니다. Discourse 관리자 화면에서 /16 블록 전체를 한 번에 차단할 수 있는 버튼이 있나요?!

어쨌든, 이것이 제 초기 문제의 주된 원인일 가능성이 높습니다. 이 문제를 해결하는 데 특히 어려웠던 점은 Discourse 팀이 살펴볼 필요가 있는 몇 가지 문제가 남아 있다는 것입니다:

  • 차단된 이 범위는 어떤 이유인지 Screened IPs 목록에 표시되지 않습니다. 직접 데이터베이스를 확인해야만 찾을 수 있었습니다. 하지만 “176.59” 또는 "109.252"로 검색하면 항목들이 표시됩니다. /admin/logs/screened_ip_addresses에서 결과 개수 제한이 적용되고 있는 건가요?

  • 내보내기(Export) 시에는 176.59.0.0과 109.252.0.0으로 표시되며, 즉 블록 정보가 표시되지 않습니다. 기본 범위(127.0.0.0/8, 10.0.0.0/8 등)의 경우에도 마찬가지입니다 — 내보내기 파일에는 마스커가 표시되지 않습니다.

  • 이 항목들이 사용자를 차단하고 있음에도 불구하고 match_count 값은 0이고 last_match_at는 비어 있습니다(테이블 전체가 동일합니다). 이것이 의도된 동작인가요? 아마 모든 allow 매칭을 카운트하길 원하지는 않을 수 있지만, 차단이 카운트되지 않는다면 이 컬럼들은 사용되지 않거나 필요하지 않은 것 같습니다. 아니면 SSO를 통한 로그인이 이러한 매칭을 트리거하지 않는 건가요?

다시 말씀드리지만, API를 통해 "스패머로 삭제"를 호출하고 있다고 거의 확신합니다. 관련 IP 주소에서 스팸머 삭제 횟수가 충분히 많으면 IP 주소 차단 범위가 자동으로 넓어집니다. 여기에서 보고 계신 현상이 바로 그것이라고 상당히 확신합니다.

이 부분은 그렇습니다. 스크리닝된 IP 목록이 이렇게 큰 이유는, 오랫동안 "스패머로 삭제"를 해왔기 때문일 수 있습니다. 그렇게 하고 싶지는 않을 것입니다.

"삭제만"을 원하시는 것이지, "삭제 및 차단"을 원하시는 것이 아닙니다. 하지만 게시하신 거의 모든 내용은 API를 통해 "삭제 및 차단"을 호출하고 있음을 보여줍니다.

문제는 사용된 엔드포인트가 아니라 파라미터였습니다. API는 bool 값을 ‘true’/‘false’ 문자열로 기대하는데, 저는 그 사실을 몰랐습니다.

위에서 언급한 다른 버그들도 몇 가지 있었는데, 이 버그들이 처리 대상인지 모르겠습니다. 그 외에는 이 이슈를 닫으셔도 됩니다. 감사합니다.