#apache

[Apache/IHS] 서버 성능 튜닝의 핵심: MaxRequestWorkers 계산법 및 MPM 설정 완벽 가이드

"사용자가 몰리면 서버가 응답이 없어요." 이런 문제의 90%는 동시 접속자 처리 설정인 MPM(Multi-Processing Module) 튜닝으로 해결됩니다. 물리 메모리 한계 내에서 최대 성능을 끌어내는 MaxRequestWorkers 설정법과 ServerLimit의 관계를 단계별로 정리합니다.

0. 튜닝의 핵심 공식 (The Formula)

튜닝은 '감'으로 하는 것이 아닙니다. 메모리 부족으로 인한 스왑(Swap) 발생을 막는 것이 최우선 목표이며, 이는 정확한 계산에서 시작됩니다.

MaxRequestWorkers = (총 RAM - OS/DB 사용 RAM) / (Apache 프로세스 1개의 평균 메모리)

1. 3단계 계산법: 내 서버의 한계값 찾기

Step 1: Apache 프로세스 평균 메모리 측정

먼저, 현재 구동 중인 httpd(또는 apache2) 프로세스 하나가 실제로 사용하는 메모리(RSS)의 평균을 구합니다.

# SSH 접속 후 실행 (결과 단위: MB)
ps -ylC httpd --sort:rss | awk '{sum+=$8; ++n} END {print "Average RSS: " sum/n/1024 " MB"}'

(예시 결과: 45.5 MB)

Step 2: Apache 가용 RAM 산정

서버의 전체 메모리에서 OS와 다른 애플리케이션(DB 등)이 사용하는 메모리를 제외합니다.

# 전체 메모리 확인
free -m

(예시: 16GB 서버에서 OS/DB가 6GB 사용 중 -> Apache용 가용 메모리 10GB (10,240 MB))

Step 3: 최종 설정값 도출

위에서 구한 값을 공식에 대입합니다.

  • 계산: 10,240 MB / 45.5 MB = 225.05
  • 결론: 소수점은 버리고 225MaxRequestWorkers 값으로 선정합니다.

2. 보이지 않는 벽: Limit 지시어의 이해

MaxRequestWorkers 값만 높인다고 끝이 아닙니다. 이 값은 상위 제한(Hard Limit) 설정인 ServerLimitThreadLimit 안에서만 유효합니다.

  • 규칙: MaxRequestWorkers ≤ (ServerLimit × ThreadsPerChild)

만약 계산된 값이 기본 한계(보통 ServerLimit 16)를 초과한다면, 반드시 설정 파일에 ServerLimit을 명시해야 합니다.


3. 튜닝 전략: 안정성 vs 효율성

Event/Worker MPM을 사용할 때, 성능을 높이는 방향은 두 가지입니다.

구분 ServerLimit 증가 (프로세스 ↑) ThreadsPerChild 증가 (스레드 ↑)
안정성 높음 (하나가 죽어도 나머지는 생존) 낮음 (스레드 하나가 죽으면 프로세스 전체 다운)
메모리 효율 낮음 (독립 메모리 필요) 높음 (메모리 공유)
권장 ✅ 적극 권장 ⚠️ 신중한 접근 필요 (보통 25~64 고정)

4. 최종 설정 예시 (httpd.conf)

위의 계산 결과(MaxRequestWorkers 1000 가정)를 바탕으로 한 Event MPM 최종 설정 예시입니다.

<IfModule mpm_event_module>
    # 1. 스레드 수는 안정적인 값으로 고정 (25)
    ThreadsPerChild         25

    # 2. 필요한 프로세스 수 계산 (1000 / 25 = 40)
    # 기본값(16)보다 크므로 반드시 명시해야 함
    ServerLimit             40

    # 3. 목표 동시 처리 수 (40 * 25 = 1000)
    MaxRequestWorkers       1000

    # 4. 기타 프로세스 관리 옵션
    StartServers            4
    MinSpareThreads         75
    MaxSpareThreads         250
    MaxConnectionsPerChild  0
</IfModule>
Check Point: 설정을 마친 후에는 반드시 apachectl -t 또는 httpd -t 명령어로 문법 오류가 없는지 확인하고 재기동해야 합니다.
Open Stream →
#apache

[Apache] 보안 취약점 조치: 서버 버전 정보 숨기기 (ServerTokens, ServerSignature)

Apache 웹 서버 운영 시 기본적으로 노출되는 서버 버전(Version), 운영체제(OS), 모듈(Module) 정보를 숨겨 보안성을 높이는 방법을 정리합니다. httpd.conf 파일의 ServerTokensServerSignature 지시어를 최적화하여 정보 유출 취약점을 조치합니다.

0. 배경 및 취약점 (Context)

공격자는 Banner Grabbing 기법을 통해 대상 서버의 구체적인 버전 정보를 수집하고, 해당 버전에 알려진 취약점(CVE)을 이용해 공격을 시도합니다. 따라서 서버 정보 노출을 최소화하는 것은 보안 강화(Hardening)의 첫걸음입니다.


1. 필수 설정 (Basic Configuration)

Apache 설정 파일(httpd.conf 또는 security.conf)에서 다음 두 가지 지시어를 찾아 수정하거나 추가합니다.

1) 헤더 정보 제한 (ServerTokens)

HTTP 응답 헤더의 Server 필드에 표시되는 정보량을 제어합니다.

  • 기본값 (Full): Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.0 ... (모두 노출)
  • 권장값 (Prod): Apache (제품명만 노출)
# Server 헤더에 제품명(Apache)만 표시
ServerTokens Prod

2) 에러 페이지 서명 제거 (ServerSignature)

404 Not Found, 403 Forbidden 등 에러 페이지 하단에 표시되는 서버 정보를 제어합니다.

  • 기본값 (On): 에러 메시지 하단에 서버 버전과 포트 정보가 표시됨
  • 권장값 (Off): 하단 서명 라인을 제거함
# 에러 페이지 하단에 서버 정보 숨김
ServerSignature Off

2. 심화 설정 (Advanced Configuration)

위의 ServerTokens Prod 설정을 적용해도 Server: Apache라는 정보는 여전히 남습니다. 보안 감사를 위해 이 헤더조차 아예 삭제하고 싶다면 mod_headers 모듈을 사용해야 합니다.

Pre-check: 이 설정을 사용하려면 LoadModule headers_module modules/mod_headers.so 라인의 주석이 해제되어 있어야 합니다.
<IfModule mod_headers.c>
    # Server 헤더 자체를 응답에서 제거 (권장)
    Header unset Server
    
    # 또는 다른 이름으로 위장 (Security by Obscurity)
    # Header set Server "MySecureServer"
</IfModule>

3. 설정 적용 및 검증 (Verification)

서비스 재기동

# Syntax 검사
apachectl -t

# 서비스 재기동 (CentOS/RHEL)
systemctl restart httpd

# 서비스 재기동 (Ubuntu/Debian)
systemctl restart apache2

적용 확인 (curl)

curl -I 옵션을 사용하여 응답 헤더만 조회해 봅니다.

# 명령 실행
curl -I http://localhost

# [Before]
HTTP/1.1 200 OK
Server: Apache/2.4.6 (CentOS) ... (취약)

# [After 1 - Prod 적용]
Server: Apache

# [After 2 - Header unset 적용]
(Server 헤더가 아예 보이지 않음)

Next Step:
서버 정보 숨김 조치가 완료되었다면, 추가적인 보안 강화를 위해 X-Content-Type-Options, X-Frame-Options 등 보안 헤더 적용을 검토해 보십시오.

Open Stream →
#apache

[Apache] CentOS 7 소스 컴파일 설치 완벽 가이드: 의존성(APR, PCRE, OpenSSL) 포함

CentOS 7 환경에서 Apache HTTP Server 2.4를 소스 코드로 컴파일하여 설치하는 전체 과정을 다룹니다. APR, APR-Util, PCRE, OpenSSL 등 필수 의존성 패키지를 별도 경로(Custom Path)에 설치하고 이를 Apache와 연동하는 방법을 중점적으로 설명합니다.

0. 사전 준비 (Prerequisites)

소스 컴파일을 위해 필요한 C 컴파일러와 기본 라이브러리를 설치합니다.

OS 및 컴파일 도구 확인

  • OS: CentOS 7 (Kernel 3.10.0)
  • 패키지 설치: yum -y install gcc make gcc-c++ pcre-devel expat-devel

1. 의존성 라이브러리 설치 (Dependencies)

Apache 2.4 구동에 필요한 라이브러리들을 /SW/web/tools 하위에 격리하여 설치합니다. 이는 시스템 라이브러리와의 충돌을 방지하기 위함입니다.

1) APR (Apache Portable Runtime)

OS 간의 차이를 추상화해 주는 핵심 라이브러리입니다.

# 다운로드 및 압축 해제 후 이동
./configure --prefix=/SW/web/tools/apr
make && make install

2) APR-Util

APR의 유틸리티 확장판이며, 반드시 APR이 먼저 설치되어 있어야 합니다.

# --with-apr 옵션으로 위에서 설치한 경로 지정 필수
./configure --prefix=/SW/web/tools/apr-util --with-apr=/SW/web/tools/apr
make && make install

3) PCRE (Perl Compatible Regular Expressions)

URL 재작성(Rewrite) 모듈 등 정규 표현식 처리에 사용됩니다.

./configure --prefix=/SW/web/tools/pcre
make && make install

4) OpenSSL (HTTPS 지원)

보안 통신(SSL/TLS)을 위해 OpenSSL 소스를 컴파일합니다.

# config 명령어로 경로 설정
./config --prefix=/SW/web/tools/openssl --openssldir=/SW/web/tools/openssl

make && make install

2. Apache (HTTPD) 컴파일 및 설치

모든 의존성이 준비되었으므로 Apache를 컴파일합니다. configure 단계에서 앞서 설치한 라이브러리들의 경로를 정확히 지정하는 것이 핵심입니다.

Configure 실행

tar -zxvf httpd-2.4.41.tar.gz
cd httpd-2.4.41

# 설정 (한 줄로 입력)
./configure \
--prefix=/SW/web/httpd24 \
--enable-so \
--enable-rewrite \
--enable-proxy \
--enable-ssl \
--enable-mods-shared=all \
--enable-modules=shared \
--enable-mpms-shared=all \
--with-mpm=worker \
--with-apr=/SW/web/tools/apr \
--with-apr-util=/SW/web/tools/apr-util \
--with-pcre=/SW/web/tools/pcre \
--with-ssl=/SW/web/tools/openssl \
--enable-unique-id

주요 옵션 설명

  • --enable-so: DSO(Dynamic Shared Object) 모듈 적재 기능 활성화 (필수)
  • --enable-mods-shared=all: 모든 모듈을 동적 모듈로 컴파일
  • --with-mpm=worker: 멀티 프로세스 모듈(MPM)을 Worker 방식으로 지정 (성능 유리)
  • --with-[lib]: 앞서 설치한 의존성 라이브러리 경로 연결

컴파일 및 설치

make && make install

3. 구동 및 검증 (Verification)

설치가 완료되면 서비스를 기동하고 브라우저 접속을 테스트합니다.

서비스 기동

# Apache 컨트롤러 실행
/SW/web/httpd24/bin/apachectl start

# 프로세스 확인
ps -ef | grep httpd
netstat -anotp | grep :80

방화벽 설정 (CentOS 7)

프로세스가 떠 있어도 방화벽이 막혀있으면 접속이 안 됩니다. 80 포트를 열어줍니다.

firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --reload

접속 확인

브라우저 주소창에 서버 IP를 입력하여 "It works!" 페이지가 뜨는지 확인합니다.

Apache It Works Page

[그림] 설치 성공 시 확인 가능한 기본 페이지


Next Step:
기본 설치가 완료되었습니다. 이제 운영 환경에 맞춰 httpd.conf에서 ServerName 경고를 해결하고, httpd-mpm.conf에서 Worker 프로세스 튜닝을 진행해 보십시오.

Open Stream →
#apache

[Apache/IHS] IP 접속 및 미등록 도메인 요청 차단 설정 (Default VirtualHost)

Apache(IHS) 웹 서버에서 도메인명이 아닌 IP 주소로 접속하거나, ServerName에 정의되지 않은 요청이 들어올 경우 이를 차단하거나 에러 페이지를 보여주는 방법을 정리합니다. 가장 먼저 로딩되는 Dummy VirtualHost를 활용하는 것이 핵심입니다.

0. 배경 지식 (Context)

Apache는 클라이언트 요청의 Host 헤더와 일치하는 ServerName(또는 ServerAlias)을 찾지 못할 경우, 설정 파일에서 가장 먼저 정의된 VirtualHost를 기본값(Default)으로 사용하여 요청을 처리합니다.

이 원리를 이용하여, 최상단에 아무런 ServerName을 갖지 않는(혹은 더미 값을 가진) VirtualHost를 배치하고 403 Forbidden 등을 반환하게 하면, 지정된 도메인 외의 모든 접근을 차단할 수 있습니다.

Test Environment

  • OS: CentOS 7.2
  • Web Server: IBM HTTPServer v8.5 (Apache 2.2 Base)

1. httpd.conf 설정 (VirtualHost 구성)

핵심은 순서입니다. 차단용(Dummy) 설정을 정상 서비스 설정보다 반드시 위쪽에 작성해야 합니다.

1) 기본 설정 및 포트 리슨

Listen 80
Listen 4958

# Apache 2.2 / IHS 8.5 이하 필수 (IP 기반 가상호스트 활성화)
NameVirtualHost *:80
NameVirtualHost *:4958

2) 차단용 Dummy VirtualHost (최상단 배치)

이 블록에는 ServerName을 지정하지 않거나 의미 없는 값을 넣습니다. 이곳으로 들어오는 요청은 모두 에러 메시지를 반환합니다.

# [80 포트] 미등록 도메인/IP 접속 차단
<VirtualHost *:80>
    DocumentRoot /app/was/htdocs
    
    # 접근 거부 메시지 설정 (보안상 상세 정보 숨김 권장)
    ErrorDocument 403 "Forbidden: Access is denied."
    ErrorDocument 404 "Not Found."
    ErrorDocument 500 "Internal Server Error."
    
    # 모든 요청에 대해 403 Forbidden 강제 반환 (mod_rewrite 사용 시)
    # RewriteEngine On
    # RewriteRule .* - [R=403,L]
    
    # 또는 디렉토리 접근 권한 제어
    <Directory "/app/was/htdocs">
        Order allow,deny
        Deny from all
    </Directory>
</VirtualHost>

# [4958 포트] 미등록 도메인/IP 접속 차단
<VirtualHost *:4958>
    DocumentRoot /app/was/htdocs
    ErrorDocument 403 "Forbidden: Access is denied."
    # ... (상동)
</VirtualHost>

3) 실제 서비스 VirtualHost

정상적인 도메인(ServerName)을 가진 요청만 처리하는 블록입니다. Proxy 설정을 포함합니다.

# Reverse Proxy 사용 시 Open Relay 방지
ProxyRequests Off

# [80 포트] 정상 서비스
<VirtualHost *:80>
    ServerName test.apache.com
    
    # WAS 또는 백엔드 서버로 프록시
    ProxyPass / http://172.31.98.155/ Keepalive=on
    ProxyPassReverse / http://172.31.98.155/
    
    # Host 헤더 유지 (WAS가 도메인을 인식하도록 함)
    ProxyPreserveHost On
    
    ErrorLog /app/was/HTTPServer/logs/test_proxy_error.log
    CustomLog /app/was/HTTPServer/logs/test_proxy_access.log combined
</VirtualHost>

# [4958 포트] 정상 서비스
<VirtualHost *:4958>
    ServerName test.httpserver.com
    
    ProxyPass / http://172.31.98.209/ Keepalive=on
    ProxyPassReverse / http://172.31.98.209/
    ProxyPreserveHost On
    
    ErrorLog /app/was/HTTPServer/logs/http_proxy_error.log
    CustomLog /app/was/HTTPServer/logs/http_proxy_access.log combined
</VirtualHost>
Tip: ProxyPreserveHost On 옵션은 클라이언트가 요청한 도메인 정보(Host Header)를 백엔드 서버(WAS)까지 그대로 전달합니다. WAS에서 가상 호스트를 구분해야 한다면 필수 옵션입니다.

2. 검증 (Verification)

설정 적용 후 웹 서버를 재기동하고 curl을 이용하여 테스트합니다.

1) 정상 도메인 접속 테스트

# 정상 응답(200 OK)이 와야 함
curl -v -H "Host: test.apache.com" http://localhost:80/

2) IP 접속 및 미등록 도메인 테스트

# 1. IP로 직접 요청 -> 403 또는 설정한 에러 메시지 출력되어야 함
curl -v http://localhost:80/

# 2. 엉뚱한 도메인 요청 -> 403 출력되어야 함
curl -v -H "Host: unknown.com" http://localhost:80/

Next Step:
Apache 2.4 (IHS 9.0 이상)를 사용 중이라면, NameVirtualHost 지시어는 더 이상 필요하지 않으므로 삭제하고, 접근 제어 구문을 Require all denied 등으로 변경해야 합니다.

Open Stream →
#apache

[OpenSSL/Apache] 사설 인증서(Self-Signed Certificate) 생성 및 적용 완벽 가이드

개발 및 테스트 환경의 HTTPS 구현을 위해 OpenSSL로 사설 인증서를 생성하는 방법을 정리합니다. 실무에서 혼동하기 쉬운 Key, CSR, CRT 파일의 정확한 역할 정의부터, 개인키 패스워드 제거 및 Apache 적용까지의 전체 프로세스를 다룹니다.

0. 배경 지식: 인증서 파일의 종류와 역할

SSL 인증서 발급 과정은 개인키 생성 → 인증 요청(CSR) → 인증서 발급(CRT)의 순서로 진행됩니다. 각 단계에서 생성되는 파일의 역할을 명확히 이해해야 합니다.

  • 1. Private Key (.key):
    • 서버가 갖는 비밀 열쇠입니다. 데이터를 암호화/복호화하는 핵심 파일로, 절대 외부로 유출되어서는 안 됩니다.
    • 이 키를 분실하면 인증서를 재발급받아야 합니다.
  • 2. CSR (.csr - Certificate Signing Request):
    • 인증 기관(CA)에 "내 인증서를 만들어 달라"고 보내는 신청서입니다.
    • 공개키(Public Key) 정보와 도메인, 회사 정보(DN)가 포함되어 있습니다.
  • 3. Certificate (.crt):
    • 최종적으로 발급된 인증서(신분증)입니다.
    • CSR 내용을 바탕으로 CA(혹은 본인)가 전자 서명을 한 파일이며, 클라이언트(브라우저)에게 전송됩니다.

Test Environment

  • OS: CentOS 7.2
  • Web Server: Apache HTTP Server
  • Tool: OpenSSL

1. 개인키(Private Key) 생성

가장 먼저 모든 암호화 통신의 기반이 되는 개인키를 생성합니다.

1) 암호화된 개인키 생성

des3 알고리즘을 사용하여 2048비트 길이의 RSA 키를 생성합니다. 이때 설정하는 패스워드(Pass Phrase)는 키를 보호하기 위한 장치입니다.

[root@web01 test]# openssl genrsa -des3 -out test.vn.key 2048

Generating RSA private key, 2048 bit long modulus
..........................+++
e is 65537 (0x10001)
Enter pass phrase for test.vn.key: [패스워드 입력]
Verifying - Enter pass phrase for test.vn.key: [패스워드 확인]

2) 개인키 패스워드 제거 (필수 권장)

패스워드가 걸린 키를 웹 서버에 그대로 적용하면, 서버가 재기동될 때마다 관리자가 매번 패스워드를 입력해야 합니다. 자동 운영을 위해 패스워드를 제거한 키를 다시 생성합니다.

# 1. 원본 키 백업
cp test.vn.key test.vn.key.orig

# 2. 패스워드가 제거된 키 생성 (덮어쓰기)
openssl rsa -in test.vn.key.orig -out test.vn.key

# 결과 메시지
Enter pass phrase for test.vn.key.orig: [기존 패스워드 입력]
writing RSA key

2. 인증 요청서(CSR) 생성

생성된 개인키(.key)를 바탕으로 인증서 발급 신청서(.csr)를 작성합니다.

CSR 생성 명령어

openssl req -new -key test.vn.key -out test.vn.csr

주요 입력 정보 (DN: Distinguished Name)

명령 실행 후 입력해야 할 정보입니다. 다른 정보는 임의로 입력해도 되지만, Common Name은 반드시 정확해야 합니다.

  • Country Name: 국가 코드 (예: KR, VN)
  • State / Locality: 지역 정보 (예: Seoul)
  • Organization: 회사명/부서명 (예: IT Team)
  • Common Name (CN): 서비스 도메인 주소 (가장 중요! 예: *.test.vn)
Note: 추가 정보인 'Challenge password' 등은 입력하지 않고 Enter를 눌러 넘어가도 무방합니다.

3. 사설 인증서(CRT) 생성 (Self-Signing)

우리는 공인 인증 기관(VeriSign 등)이 없으므로, 생성한 CSR에 내 개인키로 직접 서명(Self-Sign)하여 인증서(CRT)를 만듭니다.

인증서 생성

유효기간을 365일로 설정하여 최종 인증서를 생성합니다.

# -req : CSR을 입력받음
# -signkey : 스스로 서명할 키 지정
openssl x509 -req -days 365 -in test.vn.csr -signkey test.vn.key -out test.vn.crt

# 성공 시 출력 메시지
Signature ok
subject=/C=VN/ST=Hanoi/L=lotte/O=admin/OU=admin/CN=*.test.vn
Getting Private key

최종 파일 확인

작업이 완료되면 다음 3개의 파일이 있어야 합니다.

  • test.vn.key: 개인키 (패스워드 제거됨, 서버 설정에 사용)
  • test.vn.crt: 인증서 (서버 설정에 사용)
  • test.vn.csr: 신청서 (발급 완료 후에는 불필요)

4. Apache 설정 및 검증

생성된 키와 인증서를 Apache 설정 파일(httpd.conf 또는 ssl.conf)에 등록하여 HTTPS를 활성화합니다.

설정 적용

# SSL 엔진 활성화
SSLEngine on

# 1. 인증서 파일 경로 지정 (.crt)
SSLCertificateFile /etc/httpd/conf/ssl/test.vn.crt

# 2. 개인키 파일 경로 지정 (.key)
SSLCertificateKeyFile /etc/httpd/conf/ssl/test.vn.key

검증 (Verification)

Apache를 재기동하고 브라우저로 접속해 봅니다. 패스워드를 묻지 않고 기동되어야 정상입니다.

  1. 재기동: systemctl restart httpd
  2. 브라우저 접속: https://test.vn
주의 (Warning):
사설 인증서는 브라우저가 신뢰하는 기관(CA) 목록에 없으므로, 접속 시 "주의 요함" 또는 "안전하지 않음" 경고가 뜨는 것이 정상입니다. 테스트 환경에서는 예외를 추가하여 진행하면 됩니다.
Open Stream →
#apache

[Apache/Tomcat] 다중 도메인 구성을 위한 VirtualHost 및 AJP 포트 매핑 가이드

하나의 물리 서버에서 여러 도메인(예: aaa.com, bbb.com)을 서비스하기 위해 Apache의 VirtualHost와 Tomcat의 멀티 Service 구성을 연동하는 방법을 정리합니다. 도메인별로 다른 AJP 포트를 할당하여 요청을 분리하는 것이 핵심입니다.

1. 아키텍처 및 원리 (Context)

설정의 목표는 요청 흐름을 다음과 같이 분리하는 것입니다.

  • AAA.test.com (Apache:80) → Worker(aaa) → Tomcat AJP(8009) → Service A
  • BBB.test.com (Apache:80) → Worker(bbb) → Tomcat AJP(8010) → Service B
  • CCC.test.com (Apache:80) → Worker(ccc) → Tomcat AJP(8011) → Service C

2. Apache 설정 (httpd-vhosts.conf)

가장 먼저 Apache가 들어오는 도메인(ServerName)을 구분하여 적절한 mod_jk 워커에게 토스하도록 설정합니다.

설정 활성화 (httpd.conf)

# 주석 해제하여 vhosts 설정 파일 로드
Include conf/extra/httpd-vhosts.conf

가상 호스트 정의 (httpd-vhosts.conf)

각 도메인별로 VirtualHost 블록을 생성하고 JkMount를 통해 서로 다른 워커 이름을 지정합니다.

# 1. AAA 도메인 설정
<VirtualHost *:80>
    ServerName AAA.test.com
    DocumentRoot "/WAS/apps/test1"
    
    ErrorLog "logs/aaa-error_log"
    CustomLog "logs/aaa-access_log" common
    
    # 워커 'aaa'에게 모든 요청 전달
    JkMount /* aaa
</VirtualHost>

# 2. BBB 도메인 설정
<VirtualHost *:80>
    ServerName BBB.test.com
    DocumentRoot "/WAS/apps/test2"
    
    ErrorLog "logs/bbb-error_log"
    CustomLog "logs/bbb-access_log" common
    
    # 워커 'bbb'에게 모든 요청 전달
    JkMount /* bbb
</VirtualHost>

# 3. CCC 도메인 설정
<VirtualHost *:80>
    ServerName CCC.test.com
    DocumentRoot "/WAS/apps/test3"
    
    ErrorLog "logs/ccc-error_log"
    CustomLog "logs/ccc-access_log" common
    
    # 워커 'ccc'에게 모든 요청 전달
    JkMount /* ccc
</VirtualHost>

3. mod_jk 워커 설정 (workers.properties)

Apache에서 지정한 워커 이름(aaa, bbb, ccc)이 실제로 통신할 Tomcat의 AJP 포트를 정의합니다.

# 워커 리스트 정의
worker.list=aaa,bbb,ccc

# [aaa] 워커 정의 (기본 포트 8009)
worker.aaa.port=8009
worker.aaa.host=localhost
worker.aaa.type=ajp13

# [bbb] 워커 정의 (포트 8010)
worker.bbb.port=8010
worker.bbb.host=localhost
worker.bbb.type=ajp13

# [ccc] 워커 정의 (포트 8011)
worker.ccc.port=8011
worker.ccc.host=localhost
worker.ccc.type=ajp13

4. Tomcat 설정 (server.xml)

Tomcat 하나에서 여러 포트를 리슨하기 위해 <Service> 태그를 복제하여 구성합니다. 각 서비스마다 포트(HTTP, HTTPS, AJP)가 겹치지 않도록 주의해야 합니다.

서비스 A (AAA) 설정

<Service name="CatalinaA">
    <!-- HTTP Port: 8080 -->
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
    
    <!-- AJP Port: 8009 (workers.properties의 aaa와 매핑) -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="CatalinaA" defaultHost="localhost">
        <Host name="localhost" appBase="/WAS/apps/aaa" unpackWARs="true" autoDeploy="true">
            <Context path="" docBase="." reloadable="true"/>
        </Host>
    </Engine>
</Service>

서비스 B (BBB) 설정

<Service name="CatalinaB">
    <!-- HTTP Port: 8081 (충돌 방지) -->
    <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8444" />
    
    <!-- AJP Port: 8010 (workers.properties의 bbb와 매핑) -->
    <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="CatalinaB" defaultHost="localhost">
        <Host name="localhost" appBase="/WAS/apps/bbb" unpackWARs="true" autoDeploy="true">
            <Context path="" docBase="." reloadable="true"/>
        </Host>
    </Engine>
</Service>

서비스 C (CCC) 설정

<Service name="CatalinaC">
    <!-- HTTP Port: 8082 (충돌 방지) -->
    <Connector port="8082" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8445" />
    
    <!-- AJP Port: 8011 (workers.properties의 ccc와 매핑) -->
    <Connector port="8011" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="CatalinaC" defaultHost="localhost">
        <Host name="localhost" appBase="/WAS/apps/ccc" unpackWARs="true" autoDeploy="true">
            <Context path="" docBase="." reloadable="true"/>
        </Host>
    </Engine>
</Service>
Tip (docBase 설정):
appBaseContext docBase 설정이 꼬일 경우 404 에러가 발생할 수 있습니다. 가장 확실한 방법은 docBase에 절대 경로를 명시하는 것입니다.
예: docBase="/WAS/apps/ccc"

5. 검증 및 테스트

  1. Tomcat 재기동: server.xml 수정 후 재기동.
    netstat -anotp | grep java 
    # 8009, 8010, 8011 포트가 모두 LISTEN 상태인지 확인
  2. Apache 재기동: 설정 적용.
    ./apachectl restart
  3. 브라우저 접속: 각 도메인으로 접속하여 서로 다른 페이지가 뜨는지 확인합니다.
Apache Tomcat VirtualHost mapping test result

[그림] 도메인별 연동 테스트 결과 화면

Open Stream →
#apache

[Apache/Tomcat] 웹 서버 연동 가이드: mod_jk (AJP) 설정 완벽 정리

Apache HTTP Server와 Tomcat을 연동(Interlink)하여 정적 컨텐츠 처리 성능을 높이고 부하 분산(Load Balancing) 환경을 구성합니다. 가장 널리 사용되는 mod_jk 모듈의 설치(컴파일)부터 workers.properties 설정까지의 전체 과정을 다룹니다.

0. 기본 개념 (Concepts)

  • mod_jk: Apache가 Tomcat과 통신하기 위해 사용하는 플러그인 모듈입니다.
  • AJP (Apache JServ Protocol): 웹 서버와 WAS 간의 효율적인 통신을 위해 최적화된 바이너리 프로토콜입니다. (Tomcat 기본 AJP 포트: 8009)

1. mod_jk 설치 (Compile)

mod_jk는 Apache 배포판에 기본 포함되어 있지 않으므로, 소스를 다운로드하여 컴파일해야 합니다. 이 과정에서 Apache의 확장 도구인 apxs가 필요합니다.

다운로드 및 압축 해제

최신 버전은 Tomcat Connectors 다운로드 페이지에서 확인 가능합니다.

# 1. 소스 다운로드 (버전은 시점에 따라 다를 수 있음)
wget http://apache.mirror.cdnetworks.com/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.41-src.tar.gz

# 2. 압축 해제
tar -zxvf tomcat-connectors-1.2.41-src.tar.gz

Configure 및 컴파일

native 디렉토리로 이동하여 컴파일을 수행합니다. 주의: --with-apxs 옵션에는 현재 설치된 Apache의 apxs 바이너리 절대 경로를 정확히 입력해야 합니다.

cd tomcat-connectors-1.2.41-src/native

# Apache 설치 경로에 맞춰 apxs 경로 지정 (/WAS/apache/bin/apxs)
./configure --with-apxs=/WAS/apache/bin/apxs

# 컴파일 및 설치
make && make install

설치 확인 (Verification)

설치가 완료되면 Apache의 modules 디렉토리에 mod_jk.so 파일이 생성되었는지 확인합니다.

ls -l /WAS/apache/modules/mod_jk.so

2. 워커 설정 (workers.properties)

Apache에게 "어떤 Tomcat 인스턴스와 통신할지" 알려주는 설정 파일입니다. 일반적으로 conf 디렉토리에 생성합니다.

파일 생성

vi /WAS/apache/conf/workers.properties

설정 내용 작성

# Tomcat 및 Java 경로 (환경에 맞게 수정)
workers.tomcat_home="/WAS/tomcat8"
workers.java_home="/usr/bin/java"
ps=/

# 워커 목록 정의 (콤마로 구분하여 다수 정의 가능)
worker.list=test1

# [test1] 워커 상세 설정
worker.test1.port=8009
worker.test1.host=localhost
worker.test1.type=ajp13
# worker.test1.lbfactor=1 (로드밸런싱 시 사용)
Note: worker.test1.port는 Tomcat의 server.xml<Connector protocol="AJP/1.3" ... /> 에 설정된 포트와 일치해야 합니다. (기본값: 8009)

3. Apache 설정 (httpd.conf)

마지막으로 Apache가 mod_jk 모듈을 로드하고, 특정 요청을 Tomcat(워커)으로 보내도록 설정합니다.

파일 수정

vi /WAS/apache/conf/httpd.conf

추가 내용

# 1. mod_jk 모듈 로드
LoadModule jk_module modules/mod_jk.so

<IfModule jk_module>
    # 2. 워커 설정 파일 위치 지정
    JkWorkersFile "conf/workers.properties"

    # 3. 로그 설정 (트러블슈팅을 위해 필수)
    JkLogFile "logs/mod_jk.log"
    JkLogLevel info
    JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
    JkRequestLogFormat "%w %V %T"
    
    # 4. URL 매핑 (JkMount)
    # /* : 모든 요청을 test1 워커(Tomcat)로 전달
    # 특정 확장자만 보내려면: JkMount *.jsp test1
    JkMount /* test1
</IfModule>

4. 기동 및 연동 테스트

설정이 완료되면 Apache와 Tomcat을 재기동합니다. 순서는 Tomcat 구동 -> Apache 구동 순서를 권장합니다.

설정 검증 (Syntax Check)

# Apache 설정 문법 검사
/WAS/apache/bin/apachectl -t
# "Syntax OK" 출력 확인

서비스 재기동

# Tomcat 재기동
/WAS/tomcat8/bin/shutdown.sh
/WAS/tomcat8/bin/startup.sh

# Apache 재기동
/WAS/apache/bin/apachectl restart

최종 확인

브라우저에서 Apache 포트(보통 80)로 접속했을 때, Tomcat의 페이지가 보인다면 연동에 성공한 것입니다.

Apache Tomcat 연동 성공 화면


Next Step:
연동에 성공했다면 정적 파일(이미지, CSS, JS)은 Apache가 처리하고, 동적 파일(JSP)만 Tomcat이 처리하도록 JkMountJkUnMount 설정을 튜닝하여 성능을 최적화해 보세요.

Open Stream →
#apache

[Apache] Linux 소스 컴파일 설치 가이드 (httpd, apr, pcre)

Linux 환경에서 yum이나 apt 같은 패키지 매니저 대신, Apache HTTP Server(httpd)를 소스 코드로 직접 컴파일하여 설치하는 방법을 정리합니다. 특정 버전이 필요하거나, 모듈을 커스터마이징해야 할 때 필수적인 기술입니다.

0. 시작하기 전에 (Why & Prerequsite)

왜 소스 컴파일을 하나요?

  • 버전 관리: OS 저장소(Repository)에서 제공하는 구버전이 아닌, 최신 보안 패치가 적용된 버전을 사용할 수 있습니다.
  • 최적화: 불필요한 모듈을 빼거나, 경로를 /usr/local이 아닌 /WAS 등 원하는 곳으로 지정하여 관리 효율성을 높일 수 있습니다.

필수 컴파일 도구 설치

소스 코드를 기계어로 번역하기 위해서는 컴파일러(gcc)와 빌드 도구(make)가 반드시 필요합니다. 설치 전 아래 명령어로 환경을 준비해주세요.

# CentOS/RHEL 기준
yum install -y gcc gcc-c++ make expat-devel

1. 소스 파일 다운로드

각 프로젝트의 공식 홈페이지에서 Stable(안정) 버전을 다운로드합니다. 보통 /usr/local/src 나 임시 디렉토리에서 작업합니다.

다운로드 링크

※ Apache 2.4 버전부터는 APR(Apache Portable Runtime)과 PCRE(정규표현식 라이브러리)가 내장되어 있지 않아 별도 설치가 필수입니다.


2. 의존성 라이브러리 설치

Apache 본체를 설치하기 전에 기초가 되는 라이브러리를 먼저 깔아야 합니다. 관리 편의를 위해 모든 경로는 /WAS 하위로 통일하겠습니다.

1) APR (Apache Portable Runtime) 설치

OS(Linux, Windows 등)에 상관없이 Apache가 실행될 수 있도록 도와주는 플랫폼 추상화 라이브러리입니다.

tar -zxvf apr-1.5.2.tar.gz
cd apr-1.5.2

# --prefix 옵션으로 설치 경로 지정
./configure --prefix=/WAS/apr
make && make install

2) APR-Util 설치

APR의 유틸리티 확장판입니다. 반드시 위에서 설치한 APR의 경로를 지정해야 합니다.

tar -zxvf apr-util-1.5.4.tar.gz
cd apr-util-1.5.4

# --with-apr 옵션 중요!
./configure --prefix=/WAS/aprutil --with-apr=/WAS/apr
make && make install

3) PCRE (Perl Compatible Regular Expressions) 설치

Apache의 URL 재작성(Rewrite) 모듈 등에서 사용하는 정규표현식 라이브러리입니다.

tar -zxvf pcre-8.37.tar.gz
cd pcre-8.37

./configure --prefix=/WAS/pcre
make && make install

3. Apache HTTP Server 설치

이제 주인공인 Apache를 설치합니다. configure 단계에서 앞서 설치한 라이브러리들의 경로를 연결해주는 것이 핵심입니다.

Configuration 실행

tar -zxvf httpd-2.4.16.tar.gz
cd httpd-2.4.16

# 한 줄씩 옵션을 확인하며 입력하세요.
./configure \
--prefix=/WAS/apache \
--enable-mods-shared=all \
--enable-so \
--enable-rewrite \
--enable-auth-digest \
--with-apr=/WAS/apr \
--with-apr-util=/WAS/aprutil \
--with-pcre=/WAS/pcre

주요 옵션 설명

  • --enable-mods-shared=all: 모듈을 동적(Dynamic)으로 컴파일하여, 추후 httpd.conf에서 Load/Unload가 가능하게 합니다.
  • --enable-rewrite: URL 주소를 변경하는 Rewrite 기능을 활성화합니다. (실무 필수)

컴파일 및 설치

# 에러 없이 완료되면 실행
make && make install

4. 기동 및 검증 (Verification)

설치가 끝났다고 바로 브라우저가 열리는 것은 아닙니다. 프로세스를 띄우고 포트를 확인해야 합니다.

1) 서비스 기동

# Apache 기동 스크립트 실행
/WAS/apache/bin/apachectl start

# 프로세스 확인 (httpd 프로세스가 보여야 함)
ps -ef | grep httpd

2) 포트 리슨 확인

웹 서버의 기본 포트인 80번이 열려있는지 확인합니다.

netstat -anotp | grep :80

3) 방화벽 설정 (중요!)

프로세스가 떴는데 브라우저 접속이 안 된다면 99%는 방화벽 문제입니다. 테스트를 위해 방화벽을 잠시 끄거나 80포트를 열어야 합니다.

# CentOS 7 (firewalld) 포트 오픈 예시
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --reload

4) 최종 접속 테스트

PC 브라우저 주소창에 http://[서버IP]를 입력합니다. 화면에 "It works!"가 보인다면 성공입니다.


Next Step:
이제 /WAS/apache/conf/httpd.conf 파일을 열어 ServerName 경고 메시지를 해결하고, DocumentRoot(웹 문서 위치)를 실제 운영 경로로 변경해 보세요.

Open Stream →