https://sundaland.tistory.com/48
[ ▶ AJP (Apache JServ Protocol) Connector ]
AJP (Apache JServ Protocol) Connector는 Tomcat과 다른 웹 서버(주로 Apache HTTP 서버) 간의 효율적인 통신을 위한 바이너리 프로토콜이다. AJP는 HTTP보다 빠르고, 웹 서버와 애플리케이션 서버 사이의 프록시 역할을 할 때 자주 사용된다. 이 프로토콜은 특히 로드 밸런싱과 클러스터링 환경에서 널리 사용되며, 네트워크 오버헤드를 줄이고 성능을 향상시키는 데 중요한 역할을 한다.
[ ▷ AJP의 정의 및 주요 목적 ]
- AJP (Apache JServ Protocol)은 Apache HTTP 서버나 다른 웹 서버가 프록시 서버 역할을 하면서 Tomcat으로 HTTP 요청을 전달할 때 사용되는 바이너리 프로토콜이다.
- AJP는 Tomcat과 웹 서버 간의 속도와 효율성을 개선하기 위해 설계되었다. HTTP는 텍스트 기반 프로토콜인데 비해, AJP는 바이너리 프로토콜로 더 빠르게 데이터를 처리할 수 있다.
- AJP는 주로 로드 밸런싱이 필요한 대규모 시스템에서 프론트엔드 웹 서버와 백엔드 애플리케이션 서버 간의 통신에 사용된다. 이러한 구성을 통해 프론트엔드에서 정적 콘텐츠를 제공하고, 동적 콘텐츠는 백엔드에서 처리하게 된다.
[ ▷ AJP Connector의 동작 원리 ]
AJP는 웹 서버(Apache HTTP Server 등)가 클라이언트로부터 HTTP 요청을 받으면, 이를 Tomcat에 전달하는 데 사용된다.
△ 웹 서버 → Tomcat 간 통신 과정
- 클라이언트 요청: 클라이언트는 Apache HTTP Server와 같은 웹 서버에 HTTP 요청을 보낸다.
- Apache 웹 서버 처리: Apache 웹 서버는 정적 파일(이미지, CSS, JS 등)을 직접 제공하거나, 동적 콘텐츠 처리를 위해 AJP 커넥터를 통해 Tomcat에 요청을 전달한다.
- AJP 통신: AJP는 이 요청을 바이너리 포맷으로 변환하여 Tomcat의 AJP Connector에 전달한다.
- Tomcat 처리: Tomcat은 이 요청을 적절한 서블릿, JSP 또는 Spring과 같은 애플리케이션으로 전달해 처리하고, 그 결과를 다시 Apache 웹 서버로 돌려준다.
- 클라이언트 응답: Apache 웹 서버는 최종 결과를 클라이언트에게 전달하여, Tomcat이 처리한 동적 데이터를 반환한다.
[ ▷ AJP의 구성 요소 ]
AJP는 여러 구성 요소와 설정 옵션을 통해 웹 서버와 톰캣 간의 통신을 최적화한다.
△ Connector 설정
톰캣에서 AJP 커넥터를 설정하기 위해서는 server.xml 파일에 설정을 추가해야 한다.
- protocol: AJP/1.3은 AJP 프로토콜의 버전을 의미한다. AJP 1.3이 가정 널리 사용된다.
- port: AJP 커넥터가 사용하는 포트이다. 기본적으론 8009 포트가 사용된다.
- redirectPort: HTTPS 요청 시 리디렉션할 포트를 설정한다. 일반적으로 8443 포트를 사용한다.
- maxThreads: AJP 커넥터가 연결을 대기하는 시간 (밀리초)이다. 기본적으로 20초이다.
- address: AJP 커넥터가 바인딩할 IP 주소를 지정한다. 이 옵션을 통해 로켓 네트워크 내부 통신만 허용할 수 있다.
- secret: AJP 커넥터의 보안을 강화하기 위해 비밀 키를 설정할 수 있다. Apahce HTTP Server와 비밀 키를 공유하여 허가된 요청만 처리할 수 있다.
△ Apache HTTP 서버와의 관계
- <Connector protocol="AJP/1.3" port="8009" redirectPort="8443" maxThreads="200" connectionTimeout="20000" address="127.0.0.1" secret="yourSecret" />
- Apache HTTP Server는 mod_proxy_ajp 또는 mod_jk 모듈을 통해 AJP를 지원한다.
- mod_proxy_ajp는 AJP를 이용한 프록시 설정을 단순하게 설정할 수 있으며, 다음과 같이 설정할 수 있다.이 설정은 Apache가 클라이언트로부터 받은 요청을 AJP 포트 8009를 통해 Tomcat으로 프록시하도록 한다. ProxyPassReverse는 Tomcat으로부터 받은 응답을 다시 클라이언트에게 반환하는 역할을 한다.
- <VirtualHost *:80> ProxyPass / ajp://localhost:8009/ ProxyPassReverse / ajp://localhost:8009/ </VirtualHost>
[ ▷ AJP의 주요 기능 및 특징 ]
△ 빠른 통신
- 바이너리 포맷을 사용함으로써, AJP는 HTTP보다 적은 오버헤드로 데이터를 처리한다. HTTP는 텍스트 기반이지만, AJP는 바이너리 형식으로 데이터를 전송하여 처리 속도가 빠르다.
- AJP는 헤더 데이터 압축을 지원하여, 클라이언트와 서버 간의 통신에서 네트워크 대역폭을 줄이고 더 빠르게 데이터를 전솔할 수 있다. 특히 대규모 트래픽이 발생할 때 유리하다.
△ 세션 스티키니스(Session Stickiness)
- AJP는 로드 밸런싱 환경에서 세션 스티키니스 기능을 지원한다. 이는 클라이언트의 세션이 최초 연결된 특정 Tomcat 인스턴스에 계속 연결되도록 보장한다.
- 세션 스티키니스는 여러 서버에서 동일한 사용자의 세션 데이터를 유지해야 할 때 유용하며, 이를 통해 세션 데이터의 일관성을 보장할 수 있다. AJP는 클라이언트의 JSESSIONID를 확인하여 동일한 Tomcat 서버로 요청을 라우팅한다.
△ 보안 강화
- AJP는 비밀 키(secret)를 사용하여 Tomcat과 Apache HTTP 서버 간의 통신을 보호할 수 있다. 이 비밀 키는 server.xml과 Apache 설정에서 동일하게 설정하여, 외부에서 비인가된 요청이 AJP 포트에 접근하지 못하도록 한다.
- Ghostcat 취약점(CVE-2020-1938): AJP는 과거에 보안 취약점이 발견되었다. 특히, Ghostcat 취약점에서는 외부에서 AJP 포트에 접근할 수 있는 경우 Tomcat 서버의 파일 시스템에 접근할 수 있는 문제가 있었다. 이를 해결하기 위해 AJP 포트를 방화벽으로 보호하거나 로컬 호스트로만 제한하는 설정을 권장한다.
△ 클러스터링 지원
- AJP는 로드 밸런서가 여러 Tomcat 인스턴스 간에 요청을 분산할 수 있도록 돕는다. AJP를 사용하여 여러 Tomcat 인스턴스에서 세션 복제와 장애 조치(failover)를 수행할 수 있다.
- 클러스터 환경에서는 Tomcat이 각 인스턴스에서 세션 상태를 복제하여, 하나의 서버가 장애가 나더라도 다른 서버가 세션을 이어받을 수 있도록 한다. 이를 통해 고가용성이 보장다.
[ ▷ AJP와 HTTP의 차이점 ]
특징 | AJP | HTTP |
프로토콜 형식 | 바이너리 | 텍스트 |
속도 | 빠름 | 상대적으로 느림 |
주 사용 사례 | 프록시 서버와 애플리케이션 서버 간 통신 | 클라이언트와 웹 서버 간 통신 |
보안 | 비밀 키를 통한 인증, 기본적으로는 방화벽으로 보호 필요 | SSL/TLS로 암호화 가능 |
세션 스티키니스 | 지원 | 기본 HTTP에서는 지원하지 않음 |
네트워크 오버헤드 | 적음 | 많음 |
[ ▷ AJP의 성능 최적화 및 보안 고려 사항 ]
△ 성능 최적화
- maxThreads: 톰캣이 AJP 요청을 처리할 수 있는 최대 스레드 수를 늘리면 동시 연결 처리를 개선할 수 있다. 일반적으로 로드 밸런싱 환경에서는 요청이 집중될 수 있기 때문에 이 값을 적절히 설정해야 한다.
- connection Timeout: 비활성화 연결을 더 빨리 종료하도록 설정하여 리소스를 절약할 수 있다. 너무 긴 대기 시간은 불필요한 스레스 사용을 초래할 수 있다.
- socketBufferSize: AJP 소켓의 버퍼 크기를 설정하여 대용량 데이터를 더 빠르게 처리할 수 있다. 기본적으로는 적당한 값이 설정되어 있지만, 네트워크 상황에 따라 튜닝이 필요할 수 있다.
△ 보안 고려 사항
- 포트 접근 제한: AJP 포트는 외부에서 접근할 수 없도록 반드시 방화벽을 설정해야 한다. 또한, address 옵션을 통해 로컬 네트워크에서만 AJP 포트에 접근할 수 있도록 제한하는 것이 중요ㅏ다.
- 비밀 키 사용: 비밀 키 (secret)를 설정하여, 프록시 서버와 Tomcat 간에 인증된 요청만 처리하도록 해야 한다. 이 비밀키는 Apache 설정에서도 동일하게 지정하여 일치하도록 해야 한다.
- SSL/TLS: AJP 자체는 암호화를 제공하지 않으므로, 민간함 데이터를 다루는 경우 SSL/TLS로 암호화된 통신을 설정하거나, 외부 네트워크로부터 AJP 포트를 보호해야 한다.
[ ▷ AJP 사용 시의 실제 적용 예시 ]
△ 예시 1: Apache HTTP Server와 Tomcat 간의 통신
Apache HTTP Server가 앞단에서 클라이언트 요청을 받아 정적 리소스는 직접 제공하고, 동적 요청은 AJP를 통해 Tomcat으로 전달하여 처리하게 구성한다. 이때 AJP 1.3을 사용하여 빠른 바이너리 전송이 이루어진다.
△ 예시 2: 로드 밸런싱과 세션 스티키니스 적용
AJP를 사용한 로드 밸런싱 환경에서, 클라이언트는 Apache HTTP Server를 통해 여러 Tomcat 인스턴스에 요청을 보냅니다. AJP는 각 클라이언트의 세션을 고유의 Tomcat 인스턴스에 유지시켜, 동일한 사용자의 요청이 항상 같은 서버에서 처리되도록 보장합니다.
AJP 커넥터는 대규모 웹 애플리케이션의 성능과 확장성을 최적화하는 중요한 요소이다. AJP는 주로 프론트엔드 웹 서버와 백엔드 Tomcat >간의 고속 통신을 위해 사용되며, 로드 밸런싱 및 세션 관리에서 중요한 역할을 한다. 보안 설정 및 성능 최적화를 통해, AJP는 >대규모 분산 시스템에서 특히 유용하게 사용될 수 있다.