Error parsing HTTP request header, java.lang.IllegalArgumentException, 출처불명의 잘못된 요청 막기 위한 EC2 보안 그룹 수정

이제 곧 출시하는 앱의 스프링 부트 프로젝트에 계속해서 글 아래에 첨부한 Error 로그가 발생했다. 이전에 인스턴스 상태검사 실패 때 글로 정리했던 오류가 계속 발생했다. 상황을 정리하면 아래와 같다.

  • EC2 서버 보안 그룹은 사용자 지정 TCP와 스프링 부트 프로젝트의 8080 포트번호, 0.0.0.0/0 소스 인바운드 규칙으로 열려있었다.
  • 정체 불명의 누군가가 EC2 서버로 HTTPS, 8080 포트번호로 요청을 보낸다.
  • 스프링 부트 프로젝트의 내장 톰켓 커넥터는 기본 한 개이고 HTTP 요청을 처리하게 했기 때문에 처리하지 못하는 HTTPS 요청이 들어와서 발생한 오류이다.

HTTPSHTTP 요청 둘 다 TCP 유형으로 EC2 서버 내로 들어올 수 있기 때문에 어떻게 해야 EC2 서버로 들어오는 HTTPS 요청을 막을 수 있을까 많은 고민을 했다. 그러다가 AWS ACM으로 서버의 인증서를 발급 받는다고 EC2 서버와 연결한 로드밸런서의 보안그룹을 활용하면 된다는 친구의 조언을 받았다. 방식은 다음과 같다.

  • HTTPSHTTP를 구별하는건 힘들다.
  • 출처 불명의 HTTPS 요청이 EC2 서버로 바로 들어오는건 비정상적인 요청이다. 정상적인 요청이 EC2 서버에 들어오는 순서는 로드밸런서를 통해서 EC2로 들어오는 순이다.
  • 즉, 인증서를 발급받을 때 EC2와 연결한 로드밸런서로 요청이 먼저 들어오고 로드밸런서가 해당 요청을 EC2HTTP 프로토콜과 8080 포트번호로 포워딩해주는 것이 정상적인 요청 방법이다.
  • 로드밸런서를 통해 들어온 요청을 제외하고, EC2로 들어오는 요청을 모두 막는다. 위에서 EC2 서버 보안그룹에서 열려있다고 한 사용자 지정 TCP와 스프링 부트 프로젝트의 8080 포트번호, 0.0.0.0/0 인바운드 규칙을 삭제하고, 로드밸런서를 통해서 들어오는 요청만 EC2서버로 들어올 수 있게 인바운드 규칙을 수정한다.

이해를 돕기 위해 사진으로 설명하겠다.

로드 밸런서 보안그룹

EC2 보안그룹

위에서 얘기했듯이 EC2로 오는 요청 중 로드밸런서를 통해서 들어온 요청만이 정상적인 요청이다. 그래서 로드밸런서를 통해 들어온 요청만 허용하도록 EC2의 보안 그룹의 기존 사용자 지정 TCP와 스프링 부트 프로젝트의 8080 포트번호, 0.0.0.0/0 소스 인바운드 규칙을 삭제하고 사용자 지정 TCP와 스프링 부트 프로젝트의 8080 포트번호, 로드밸런서의 보안그룹 sg-54fba624 소스의 인바운드 규칙을 추가한다. 그 외에 서버 관리를 위한 SSH 인바운드 규칙을 제외한 어떤 요청도 들어올 수 없도록 설정했다. 테스트 결과 SSH를 제외한 어떤 요청도 로드밸런서를 통하지 않고는 EC2 서버로 들어올 수 없다. 출처 불명의 HTTPS 요청도 더 이상 EC2서버로 직접 들어올 수 없다. 또한 로드밸런서는 요청을 EC2로 포워딩할 때 HTTP프로토콜로 하기 때문에 글 아래에 첨부한 오류도 더 이상 발생하지 않았다.

java.lang.IllegalArgumentException: Invalid character found in method name [0x030x000x00/*0xe00x000x000x000x000x00Cookie: ]. HTTP method names must be tokens
        at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:419) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:269) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.56.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]

좋은 웹페이지 즐겨찾기