mod_jk.so 를 이용한 Apache httpd 와 Apache Tomcat 연동
1. mod_jk.so 모듈 설치
1.1. Apache httpd 를 컴파일해서 설치한 경우
Apache Tomcat® 공식 홈페이지에서 왼쪽 메뉴의 Download > Tomcat Connectors 를 통해 Tomcat Connectors (mod_jk) Downloads 페이지에 접속해서 최신 버전을 다운로드 받는다.
설치를 위해 apxs 경로를 찾아야 한다.
일반적으로 Apache httpd 설치 디렉토리의 bin 에 위치한다.
여기서는 /opt/httpd-2.4.66/bin/apxs 에 있다고 가정한다.
tomcat-connectors-1.2.50-src.tar.gz 파일을 다운로드 받았다면,
다음과 같이 설치한다.
tar xvfz tomcat-connectors-1.2.50-src.tar.gz cd tomcat-connectors-1.2.50-src/native ./configure \ --with-apxs=/opt/httpd-2.4.66/bin/apxs make make install
--with-apxs=/opt/httpd-2.4.66/bin/apxs는 apxs 의 경로로 변경한다.
1.2. Ubuntu 에서 apt 로 Apache httpd 를 설치한 경우
mod_jk 패키지의 이름을 찾는다.
sudo apt search mod_jk
결과는 대략 다음과 같다.
libapache2-mod-jk/focal-updates,focal-security 1:1.2.46-1ubuntu0.1 amd64 Apache 2 connector for the Tomcat Java servlet engine
mod_jk 를 설치한다.
sugo apt install libapache2-mod-jk
2. mod_jk.so 모듈 활성화
2.1. Apache httpd 를 컴파일해서 설치한 경우
make install 까지 성공했다면
Apache httpd 의 modules 아래에 mod_jk.so 파일이 복사되었다.
설정파일의 sample 은 tomcat-connectors-1.2.50-src 아래에 conf 에 있다.
tomcat-connectors-1.2.50-src/conf 아래의 httpd-jk.conf 파일을 Apache httpd 의 conf 디렉토리에 복사한다.
https://github.com/apache/tomcat-connectors/tree/main/conf 에서도 찾을 수 있다.
workers.properties 파일의 경우 새로 작성하면 된다.
Apache httpd 의 conf 아래의 httpd.conf 파일을 열어 다음과 같은 내용을 추가한다.
Include conf/httpd-jk.conf
2.2. Ubuntu 에서 apt 로 Apache httpd 를 설치한 경우
sugo apt install libapache2-mod-jk 으로 설치했다면,
이미 mod_jk.so 모듈이 활성화되어 있을 것으로 예상하지만,
다음과 같이 확인한다.
a2query -m jk
ls /etc/apache2/mods-enabled/jk.conf
만약 jk.conf 파일이 없다면,
/etc/apache2/mods-available/httpd-jk.conf 파일이 있는지 확인하고,
다음과 같이 파일을 복사한다.
cd /etc/apache2/mods-available cp httpd-jk.conf jk.conf
다음과 같이 mod_jk.so 모듈을 다시 활성화한다.
sudo a2enmod jk
3. Apache Tomcat 설정
3.1. AJP/1.3 활성화
Apache Tomcat 를 설치하고 아무 것도 하지 않았다면, AJP 를 활성화해야 한다.
Apache Tomcat 을 다운로드 받아 압축을 해제하는 방법으로 설치했다면,
conf/server.xml 파일에서
8009 를 검색하는 방법으로
다음과 같이 주석으로 막힌 부분을 찾아서 주석을 풀어준다.
<Connector protocol="AJP/1.3" address="::1" port="8009" redirectPort="8443" maxParameterCount="1000" secret="passw0rd" />
secret="passw0rd" 부분은 필자가 임의로 추가했다.
secret="passw0rd"혹은secretRequired="false"속성을 추가해야 하며, 그렇지 않을 경우 8009 포트가 열려있지만, Apache httpd 에서 접속이 되지 않는다.
Ubuntu 에서 apt 으로 Apache Tomcat 을 설치했다면,
설정파일은 /var/lib/tomcat9/conf/server.xml 에 있는데,
"AJP/1.3" 에 대한 부분이 없으므로,
다음에서 찾아서 복사해서 붙여넣기를 한다.
<Connector port="8080"> 의 아래나 위에 붙여넣으면 되고, Apache Tomcat 을 다시 시작해야 변경사항이 반영된다.
address="::1" 의 ::1 는 ipv6 의 loopback 표기이고,
Apache httpd 의 설정에서 [::1] 나
/etc/hosts 설정에 따라 ip6-localhost 로 연결할 수도 있다.
ipv4 표기법인 127.0.0.1 으로 변경하고, Apache httpd 의 설정에서도 127.0.0.1 로 기재해도 무방하다.
만약,
loopback 이 아닌 곳에서도 접속을 허용한다면,
address 속성을 삭제하거나
address 속성값을 0.0.0.0 혹은 ipv6 표기인 :: 로 하면 된다.
loopback 에서는 접속이 안되도록 하려면
address속성값을192.168.0.3같이 할 수도 있다.
secret="passw0rd" 는 httpd.conf(apache2.conf) 에서 참조 할 것이다.
만약,
loopback 에서만 접속이 가능하도록 설정하거나,
iptables 와 같이 방화벽으로 8009 포트 자체를 차단한다면,
secret="passw0rd" 는
secretRequired="false" 으로 대체한다.
3.1. Sticky Session 설정
conf/server.xml 에서 <Engine 을 찾아
다음과 같이
jvmRoute="node_001" 속성을 추가한다.
<Engine name="Catalina" defaultHost="localhost" jvmRoute="node_001">
Apache Tomcat 마다 서로 다르게,
예를 들면 node_001, node_002 와 같이 한다.
jvmRoute="node_001" 속성 값은 JSESSIONID Cookie 값에 붙어다닌다.
4. Apache httpd 설정
4.1. localhost 에 1개의 Apache Tomcat 을 두는 경우
Apache httpd 의 VirtualHost 설정에 다음과 같은 내용을 추가한다.
<VirtualHost 0.0.0.0:443> JkMount /* balancer </VirtualHost>
다음과 같이
Apache httpd 의 conf/workers.properties
혹은 /etc/libapache2-mod-jk/workers.properties 파일을 만든다.
sample 로 제공되는
workers.properties는 이것보다 조금 더 복잡하지만, 최소한의 설정은 다음의 5줄이면 충분하다.
worker.list=balancer worker.balancer.port=8009 worker.balancer.host=127.0.0.1 worker.balancer.type=ajp13 worker.balancer.secret=passw0rd
balancer는 임의로 정한, 그리고 httpd.conf 혹은 apache2.conf 의<VirtualHost>에서 참조하는 이름이다.
worker.balancer.secret=passw0rd 부분은
Apache Tomcat 의 server.xml 에서 secret="passw0rd" 설정을 전제한 것이다.
Apache Tomcat 의 server.xml 에서 secretRequired="false" 으로 설정했다면,
worker.balancer.secret=passw0rd 부분은 주석으로 막는다.
후술할 것이지만, 8009 포트는 낮은 수준에서 차단하는 것이 일반적이므로
secretRequired="false"속성을 사용하는 것이 일반적이다.
server.xml 의 <Connector protocol="AJP/1.3"> 에 address 속성값을
::1 로 했다면 다음과 같이 한다.
worker.list=balancer worker.balancer.port=8009 worker.balancer.host=::1 worker.balancer.type=ajp13 worker.balancer.secret=passw0rd
worker.balancer.secret=passw0rd부분은 위에서 설명한 것을 참조한다.
workers.properties 파일의 경로는 httpd-jk.conf 파일에 다음과 같이 정의되어 있다.
JkWorkersFile conf/workers.properties
Ubuntu 에서 apt 로 Apache httpd 를 설치했다면
/etc/apache2/mods-available/jk.conf 에 다음과 같이 정의되어 있다.
JkWorkersFile /etc/libapache2-mod-jk/workers.properties
4.2. 2개 이상의 Apache Tomcat 을 두는 경우
Apache httpd 의 VirtualHost 에 다음과 같은 내용을 추가한다.
<VirtualHost 0.0.0.0:443> JkMount /* balancer </VirtualHost>
workers.properties 파일은 다음과 같이 편집한다.
worker.list=balancer worker.balancer.type=lb worker.balancer.balance_workers=node_001 worker.node_001.reference=worker.template worker.node_001.host=127.0.0.1 worker.node_001.port=8009 worker.node_001.secret=passw0rd worker.balancer.balance_workers=node_002 worker.node_002.reference=worker.template worker.node_002.host=192.168.0.2 worker.node_002.port=8009 worker.node_002.secret=passw0rd worker.template.type=ajp13
worker.node_001.secret=passw0rd과worker.node_002.secret=passw0rd는 위에서 설명한 것을 참조한다.
workers.properties 와 관련한 자세한 사항은
https://tomcat.apache.org/connectors-doc/reference/workers.html
을 참조한다.
만약, Apache Tomcat 의 manager 와 같은 context 를 차단하고 싶다면, 다음과 같이 할 수 있다.
<VirtualHost 0.0.0.0:443> JkMount /* balancer JkUnMount /docs/* balancer JkUnMount /examples/* balancer JkUnMount /host-manager/* balancer JkUnMount /manager/* balancer </VirtualHost>
4.3. Sticky Session 설정
mod_jk 에서 Sticky Session 은 기본 값이다.
만약,
Sticky Session 이 동작하지 않는다면,
worker.balancer.balance_workers=node_001 의
"node_001" 이
Apache Tomcat 의 server.xml 에서
<Engine jvmRoute="node_001"> 의 jvmRoute 속성 값(여기서는 "node_001") 과
다른 것이 원인일 가능성이 높다.
4.4. jk-status 설정
mod_jk 를 처음 설정하면 mod_jk 가 잘 동작하는지 확인하기 위해서 jk-status 가 필요할 수도 있다.
workers.properties 에 다음과 같은 사항을 추가한다.
worker.list=jk-status worker.jk-status.type=status worker.jk-status.read_only=true worker.list=jk-manager worker.jk-manager.type=status
"jk-status" 와 "jk-manager" 의 차이는
worker.jk-status.read_only=true 이다.
"jk-status" 는 jk 의 상태를 조회만 할 수 있고, "jk-manager" 는 설정 값의 일부를 변경 할 수 있다.
<VirtualHost> 부분은 다음과 같이 설정한다.
<Location /jk-status> JkMount jk-status Require ip 127.0.0.1 </Location> <Location /jk-manager> JkMount jk-manager Require ip 127.0.0.1 </Location>
추가적으로 접속을 허용할 IP 주소는 Require ip 127.0.0.1 뒤에 기재한다.
공식문서에 의하면 Apache Ant Tasks 도 지원하며, 자세한 사항은 다음을 참조한다.
https://tomcat.apache.org/connectors-doc/miscellaneous/jkstatustasks.html
5. 주의사항
5.1. 8009 포트 보안과 관련해서
특단의 사정이 없다면, Apache httpd 외의 다른 곳에서 8009 포트로 접근하는 것은 차단한다.
Apache Tomcat 이 loopback 에 있다면,
<Connector 의 address 속성값을
::1 나 127.0.0.1 같은 것으로 해서
외부 접속을 차단한다.
Apache Tomcat 이 loopback 이 아닌 다른 곳에 있다면, iptables 를 이용해서 접속이 허용하는 ip 를 지정하고, 나머지 ip 는 모두 차단한다.
80 25 443 포트는 모든 곳에 열어주고, 22 995 465 5432 8005 8009 8080 포트는 ip 를 지정해서 열어주고, 나머지 연결 모두를 거부하는 예제는 서버 호스팅 Linux 의 보안 설정 에서 찾을 수 있다.
이상과 같이 8009 포트에 대한 외부 접속을 차단했다면,
Apache Tomcat 의 server.xml 에서
<Connector protocol="AJP/1.3" 부분의
secret="passw0rd" 속성은 삭제하고
secretRequired="false" 속성을 추가한다.
workers.properties 파일에서는
worker.balancer.secret=passw0rd,
worker.node_001.secret=passw0rd 과
worker.node_002.secret=passw0rd
부분을 주석으로 막는다.
Apache Tomcat 을 Apache httpd 뒤에 두기로 했다면, 8080, 8443 과 같은 포트는 열지 않는다.
부득이 8080 포트를 열어야 한다면, iptables 로 외부 접속을 차단하거나 8009 와 같이 loopback 에서만 접속하게 한다.
5.2. Apache Tomcat 의 manager 등의 Context 와 관련해서
Apache Tomcat 을 다운로드 받아 압축을 해제하는 방법으로 설치했다면, 다음과 같은 Context 가 설정되어 있다.
- docs
- examples
- host-manager
- manager
위의 것들은 있는지도 모르는 경우가 많으므로 webapps 디렉토리에서 삭제한다.
만약 반드시 필요하다면,
<VirtualHost> 내에 다음과 같은 설정을 추가하여
인터넷에서 mod_jk 를 타고 접속하는 것을 차단한다.
JkUnMount /docs/* balancer JkUnMount /examples/* balancer JkUnMount /host-manager/* balancer JkUnMount /manager/* balancer