User agent가 비어 있는 요청을 어떻게 drop할 수 있나요?

빈 User Agent를 가진 악성 봇/크롤러가 제 Discourse 사이트에 대량으로 접근하고 있습니다. 보통 이런 경우 nginx 설정을 수정해서 처리할 텐데, Docker 설치 방식을 사용하면 해당 설정에 접근할 수 없습니다. 가능하다면 이런 사소한 문제 하나 때문에 추가적인 RP를 만들고 싶지는 않습니다.

컨테이너 내부의 nginx 설정을 수정하는 방법의 예시로 discourse_docker/templates/web.ratelimited.template.yml at main · discourse/discourse_docker · GitHub 파일을 참고할 수 있습니다.

이것을 구체적으로 해보고 싶은 다른 분들을 위해, 다음 내용을 포함하여 /var/discourse/templates/web.blockemptyua.yml 파일을 생성했습니다:

run:
  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /listen 443 ssl http2;/
     to: |
       listen 443 ssl http2;
       if ($http_user_agent = "") { return 403; }

그런 다음 /var/discourse/containers/app.yml 파일에서 이 새로운 템플릿 파일을 파일 상단의 템플릿 목록 끝에 추가하고, ./launcher rebuild app 명령을 실행했습니다.

이제 Nginx는 UA가 비어 있는 모든 요청을 거부합니다.

수정: 매칭/교체 위치를 더 적절한 곳으로 변경했습니다.

docker를 잘 모르기 때문에, 혹시 모르니 안전을 위해 여쭤봅니다. replace라는 단어를 볼 때마다 긴장하게 되거든요…

이건 discourse.conf의 내용을 완전히 대체하는 게 아니라, 내용을 추가하는 것인가요?

파일 안의 한 줄을 대체합니다. 따라서 다음 내용의 첫 번째 인스턴스를 찾습니다:

listen 443 ssl http2;

그리고 이를 다음과 같이 대체합니다.

listen 443 ssl http2;
if ($http_user_agent = "") { return 403; }

즉, 파일의 올바른 위치에 새로운 줄을 추가하는 것뿐입니다. 파일의 나머지 부분은 전혀 건드리지 않습니다. 공식 템플릿과 동일한 메커니즘을 사용하여 파일을 안전하게 패치합니다.

앞서 말했듯이 저는 도커에 대해 잘 모릅니다. 저는 그저 복사&붙여넣기 박사학위를 가진 가난한 최종 사용자일 뿐입니다.

그래서 앞으로 검색하실 분들을 위해 한 가지 참고 사항을 드리고 싶습니다:

web.blockemptyua.yml는 선언된 템플릿 중 가장 먼저 올 수 없습니다. 더 정확히 말하면, web.template.yml (또는 어쩌면 모든 web.* 템플릿) 뒤에 와야 합니다.

여기서는 순서가 중요하다고 생각합니다. 만약 이것이 첫 번째로 작동하도록 시도한다면, 그 시점에 /etc/nginx/conf.d/discourse.conf가 존재하지 않기 때문에 재빌드/부트스트랩이 오류로 중단됩니다.

음, 매일 새로운 것을 배우는군요 :wink:

실제로는 끝에 위치해야 합니다. 제 게시글을 수정하여 해당 내용을 추가했습니다 :+1: