[IHS/Liberty] λ³΄μ•ˆ 취약점 쑰치: X-Powered-By 헀더 μˆ¨κΉ€ 및 정보 λ…ΈμΆœ λ°©μ§€ κ°€μ΄λ“œ

IBM HTTP Server(IHS)와 WebSphere Liberty ν™˜κ²½μ—μ„œ X-Powered-By 헀더(예: Servlet/3.1) λ…ΈμΆœμ„ μ°¨λ‹¨ν•˜λŠ” 방법을 μ •λ¦¬ν•©λ‹ˆλ‹€. λ³΄μ•ˆ κ°•ν™”λ₯Ό μœ„ν•΄ μ›Ή μ„œλ²„(IHS) λ‹¨μ—μ„œμ˜ 필터링과 WAS(Liberty) λ‹¨μ—μ„œμ˜ 생성 κΈˆμ§€ 섀정을 λͺ¨λ‘ μ μš©ν•˜λŠ” 것을 ꢌμž₯ν•©λ‹ˆλ‹€.

0. λ°°κ²½ 및 μ „λž΅ (Context)

λ³΄μ•ˆ 취약점 쑰치 μ‹œ, 정보 λ…ΈμΆœ λ°©μ§€λŠ” 닀계측 λ°©μ–΄(Defense in Depth)κ°€ μ€‘μš”ν•©λ‹ˆλ‹€.

계측 μ—­ν•  및 μ€‘μš”μ„±
1. IHS (Web Server) [ν•„μˆ˜] μ΅œμ „λ°© λ°©μ–΄μ„ . λ°±μ—”λ“œ WASκ°€ 무엇이든 상관없이 ν΄λΌμ΄μ–ΈνŠΈλ‘œ λ‚˜κ°€λŠ” λͺ¨λ“  μ‘λ‹΅μ—μ„œ 헀더λ₯Ό κ°•μ œ μ‚­μ œν•©λ‹ˆλ‹€.
2. Liberty (WAS) [ꢌμž₯] μ†ŒμŠ€ 차단. λ‚΄λΆ€λ§μ—μ„œ WAS둜 직접 μ ‘μ†ν•˜λŠ” κ²½μš°λ‚˜ μ›Ή μ„œλ²„ 섀정을 μš°νšŒν•˜λŠ” 경우λ₯Ό λŒ€λΉ„ν•΄ 헀더 생성 자체λ₯Ό λ§‰μŠ΅λ‹ˆλ‹€.

Test Environment

  • Web Server: IBM HTTP Server v9.0 (Apache 2.4 Base)
  • WAS: WebSphere Liberty Core 20.0.x

1. IBM HTTP Server (IHS) μ„€μ •

Apache 기반인 IHSμ—μ„œλŠ” mod_headers λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜μ—¬ 응닡 헀더λ₯Ό μ œμ–΄ν•©λ‹ˆλ‹€.

httpd.conf μˆ˜μ •

μ„€μ • 파일(httpd.conf)을 μ—΄μ–΄ μ•„λž˜ λ‚΄μš©μ„ μ μš©ν•©λ‹ˆλ‹€.

# 1. λͺ¨λ“ˆ λ‘œλ“œ 확인 (주석 ν•΄μ œ ν•„μˆ˜)
LoadModule headers_module modules/mod_headers.so

# 2. 헀더 제거 μ„€μ • (Global μ˜μ—­ λ˜λŠ” VirtualHost 내뢀에 μž‘μ„±)
<IfModule mod_headers.c>
    # λ³΄μ•ˆ 쑰치: 기술 μŠ€νƒ 정보 μˆ¨κΉ€
    Header unset X-Powered-By
    
    # (선택) 좔가적인 정보 λ…ΈμΆœ 헀더 차단
    Header unset X-AspNet-Version
    Header unset X-Runtime
</IfModule>

# 3. μ„œλ²„ 버전 정보 μ΅œμ†Œν™” (OS 정보 λ“± μˆ¨κΉ€)
ServerTokens Prod
Tip: μ„€μ • ν›„μ—λŠ” λ°˜λ“œμ‹œ ./apachectl -t둜 문법을 κ²€μ‚¬ν•˜κ³  μž¬κΈ°λ™(restart λ˜λŠ” graceful)ν•΄μ•Ό ν•©λ‹ˆλ‹€.

2. WebSphere Liberty μ„€μ •

LibertyλŠ” server.xml 파일 ν•˜λ‚˜λ‘œ λŒ€λΆ€λΆ„μ˜ 섀정을 μ²˜λ¦¬ν•©λ‹ˆλ‹€. webContainer μš”μ†Œλ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μˆ˜μ •ν•˜μ—¬ 헀더 생성을 λΉ„ν™œμ„±ν™”ν•©λ‹ˆλ‹€.

server.xml μˆ˜μ •

<server description="Liberty Server">

    <!-- Feature Manager (κΈ°λ³Έ μ„€μ •) -->
    <featureManager>
        <feature>servlet-3.1</feature>
    </featureManager>

    <!-- [λ³΄μ•ˆ 쑰치] X-Powered-By 헀더 λΉ„ν™œμ„±ν™” 속성 μΆ”κ°€ -->
    <webContainer disableXPoweredBy="true" />

</server>

LibertyλŠ” 동적 섀정을 μ§€μ›ν•˜λ―€λ‘œ 파일 μ €μž₯ μ‹œ μ¦‰μ‹œ λ°˜μ˜λ˜μ§€λ§Œ, 운영 ν™˜κ²½μ—μ„œλŠ” ν™•μ‹€ν•œ μ μš©μ„ μœ„ν•΄ μ„œλ²„ μž¬κΈ°λ™μ„ ꢌμž₯ν•©λ‹ˆλ‹€.


3. 검증 (Verification)

curl λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬ 쑰치 μ „ν›„μ˜ 응닡 헀더λ₯Ό λΉ„κ΅ν•©λ‹ˆλ‹€.

쑰치 μ „ (Before)

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.1
Server: IBM_HTTP_Server/9.0.5...
...

쑰치 ν›„ (After)

curl -I http://localhost:80/
HTTP/1.1 200 OK
Server: IBM_HTTP_Server   <-- (Prod μ„€μ •μœΌλ‘œ 버전 μˆ¨κΉ€)
Content-Type: text/html
...                       <-- (X-Powered-By 헀더 μ‚­μ œλ¨)

Next Step:
헀더 μ‘°μΉ˜κ°€ μ™„λ£Œλ˜μ—ˆλ‹€λ©΄, HTTP λ©”μ†Œλ“œ μ œν•œ(GET, POST μ™Έ 차단) 및 SSL/TLS ν”„λ‘œν† μ½œ 버전(TLS 1.2 Only) 섀정을 톡해 μ›Ή μ„œλΉ„μŠ€ λ³΄μ•ˆμ„ ν•œ 단계 더 κ°•ν™”ν•΄ λ³΄μ‹­μ‹œμ˜€.

[Apache] λ³΄μ•ˆ 취약점 쑰치: μ„œλ²„ 버전 정보 숨기기 (ServerTokens, ServerSignature)

Apache μ›Ή μ„œλ²„ 운영 μ‹œ 기본적으둜 λ…ΈμΆœλ˜λŠ” μ„œλ²„ 버전(Version), 운영체제(OS), λͺ¨λ“ˆ(Module) 정보λ₯Ό 숨겨 λ³΄μ•ˆμ„±μ„ λ†’μ΄λŠ” 방법을 μ •λ¦¬ν•©λ‹ˆλ‹€. httpd.conf 파일의 ServerTokens 및 ServerSignature μ§€μ‹œμ–΄λ₯Ό μ΅œμ ν™”ν•˜μ—¬ 정보 유좜 취약점을 μ‘°μΉ˜ν•©λ‹ˆλ‹€.

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 λ“± λ³΄μ•ˆ 헀더 μ μš©μ„ κ²€ν† ν•΄ λ³΄μ‹­μ‹œμ˜€.

[WebSphere] Log4j λ³΄μ•ˆ 취약점(Log4Shell) κΈ΄κΈ‰ λŒ€μ‘: kc.war 및 uddi.ear 쑰치 κ°€μ΄λ“œ

Apache Log4j 취약점(CVE-2021-44228 λ“±)이 IBM WebSphere Application Server(WAS)에 λ―ΈμΉ˜λŠ” 영ν–₯을 λΆ„μ„ν•©λ‹ˆλ‹€. WAS 9.0의 관리 μ½˜μ†” 도움말(kc.war)κ³Ό μ „ λ²„μ „μ˜ UDDI λ ˆμ§€μŠ€νŠΈλ¦¬(uddi.ear)에 ν¬ν•¨λœ μ·¨μ•½ν•œ 라이브러리λ₯Ό μ œκ±°ν•˜λŠ” μž„μ‹œ 쑰치(Mitigation) 방법을 μ •λ¦¬ν•©λ‹ˆλ‹€.

1. 영ν–₯λ°›λŠ” μ œν’ˆ 및 버전 (Affected Products)

사싀상 ν˜„μž¬ 운영 쀑인 λŒ€λΆ€λΆ„μ˜ WebSphere 버전이 직간접적인 영ν–₯κΆŒμ— μžˆμŠ΅λ‹ˆλ‹€.

μ œν’ˆ (Product) 영ν–₯ 버전 (Versions)
WebSphere Application Server (Traditional) 9.0, 8.5, 8.0, 7.0
WebSphere Liberty Continuous Delivery (All)

2. 취약점 상세 및 쑰치 κ°€μ΄λ“œ (Remediation)

WAS μ—”μ§„ μžμ²΄λ³΄λ‹€λŠ” λ²ˆλ“€λ‘œ μ œκ³΅λ˜λŠ” νŠΉμ • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄μ˜ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ λ¬Έμ œμž…λ‹ˆλ‹€. μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” κΈ°λŠ₯이라면 κ³Όκ°ν•˜κ²Œ μ‚­μ œν•˜λŠ” 것이 κ°€μž₯ ν™•μ‹€ν•œ λ°©λ²•μž…λ‹ˆλ‹€.

Case A: WAS 9.0 - kc.war (관리 μ½˜μ†” 도움말)

WAS 9.0 관리 μ½˜μ†”μ˜ '도움말(Knowledge Center)' κΈ°λŠ₯에 Log4j 2.x μ·¨μ•½ 버전이 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

  • λŒ€μƒ: WAS 9.0 μ‚¬μš©μž
  • 쑰치 방법: ν•΄λ‹Ή 라이브러리 파일 μ‚­μ œ
# 1. 배포된 λ””λ ‰ν† λ¦¬μ—μ„œ 라이브러리 제거
rm -f [WAS_HOME]/systemApps/isclite.ear/kc.war/WEB-INF/lib/log4j*.jar

# 2. μ„€μΉ˜ κ°€λŠ₯ μ•± λ””λ ‰ν† λ¦¬μ—μ„œ 원본 μ•± 제거 (μž¬μ„€μΉ˜ λ°©μ§€)
rm -rf [WAS_HOME]/installableApps/kc.war

# 3. μ„œλ²„ μž¬κΈ°λ™
./stopServer.sh server1 && ./startServer.sh server1
주의: ν–₯ν›„ 9.0.5.11 μ΄μ „μ˜ ν”½μŠ€νŒ©μ„ μ μš©ν•˜λ©΄ μ‚­μ œν•œ 파일이 볡ꡬ될 수 μžˆμœΌλ―€λ‘œ, 패치 ν›„ λ‹€μ‹œ 확인해야 ν•©λ‹ˆλ‹€.

Case B: μ „ 버전 - uddi.ear (UDDI λ ˆμ§€μŠ€νŠΈλ¦¬)

UDDI(Universal Description, Discovery, and Integration) μ„œλΉ„μŠ€μ— Log4j λΌμ΄λΈŒλŸ¬λ¦¬κ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. λŒ€λΆ€λΆ„μ˜ μ΅œμ‹  ν™˜κ²½μ—μ„œλŠ” μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€.

  • λŒ€μƒ: WAS 7.0 ~ 9.0 전체
  • 쑰치 방법: μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ 파일 μ‚­μ œ
# λ―Έμ‚¬μš© μ‹œ (ꢌμž₯)
rm -f [WAS_HOME]/installableApps/uddi.ear

# μ‚¬μš© 쀑일 경우 (라이브러리만 ꡐ체/μ‚­μ œ ν›„ 재배포 ν•„μš”)
# uddi.ear μ••μΆ• ν•΄μ œ -> log4j*.jar μ‚­μ œ -> λ‹€μ‹œ μ••μΆ• -> Redeploy

3. Log4j 1.x κ΄€λ ¨ μΆ”κ°€ 쑰치 (CVE-2021-4104)

Log4j 1.x 버전은 Log4Shell(RCE) μ·¨μ•½μ μ˜ 직접적인 λŒ€μƒμ€ μ•„λ‹ˆμ§€λ§Œ, JMSAppenderλ₯Ό μ‚¬μš©ν•  경우 μœ μ‚¬ν•œ 곡격이 κ°€λŠ₯ν•©λ‹ˆλ‹€. (WAS κΈ°λ³Έ μ„€μ •μ—λŠ” JMSAppenderκ°€ μ—†μœΌλ‚˜, μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ‚¬μš©ν•  수 있음)

쑰치 방법 (JMSAppender 제거)

Log4j 1.xλŠ” 더 이상 λ³΄μ•ˆ νŒ¨μΉ˜κ°€ λ‚˜μ˜€μ§€ μ•ŠμœΌλ―€λ‘œ(EOL), μ·¨μ•½ν•œ 클래슀 파일만 κ°•μ œλ‘œ μ‚­μ œν•˜λŠ” 것이 μœ μΌν•œ λ°©λ²•μž…λ‹ˆλ‹€.

# μ‹œμŠ€ν…œ μ „μ²΄μ—μ„œ log4j-1.2.x.jar νŒŒμΌμ„ μ°Ύμ•„ JMSAppender 클래슀 제거
zip -q -d log4j-1.2.17.jar org/apache/log4j/net/JMSAppender.class

4. 참고 자료 (Reference)

Summary:
WAS μš΄μ˜νŒ€μ€ kc.war와 uddi.ear λ‚΄μ˜ log4j νŒŒμΌμ„ μ‚­μ œν•˜κ³ , κ°œλ°œνŒ€μ€ λ°°ν¬ν•˜λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜(WAR/EAR) 내에 μ·¨μ•½ν•œ Log4j 버전이 ν¬ν•¨λ˜μ§€ μ•Šλ„λ‘ λΉŒλ“œ μ˜μ‘΄μ„±μ„ 점검해야 ν•©λ‹ˆλ‹€.

[WebSphere] λ³΄μ•ˆ 감사 λŒ€μ‘: NCSA Access Log ν™œμ„±ν™” 및 둜그 포맷(User-Agent, Time) μ»€μŠ€ν„°λ§ˆμ΄μ§•

WebSphere v8.5 ν™˜κ²½μ—μ„œ λ³΄μ•ˆ 감사 및 νŠΈλŸ¬λΈ”μŠˆνŒ…μ„ μœ„ν•΄ NCSA Access Logλ₯Ό ν™œμ„±ν™”ν•˜λŠ” 방법을 μ •λ¦¬ν•©λ‹ˆλ‹€. μ„œλ²„ μ „μ—­ μ„€μ •κ³Ό 전솑 체인(Transport Chain)별 섀정을 λͺ¨λ‘ μ μš©ν•΄μ•Ό ν•˜λ©°, accessLogFormat 속성을 톡해 ν΄λΌμ΄μ–ΈνŠΈ IP, μˆ˜ν–‰ μ‹œκ°„, User-Agent 등을 κΈ°λ‘ν•˜λ„λ‘ 포맷을 λ³€κ²½ν•˜λŠ” 방법을 λ‹€λ£Ήλ‹ˆλ‹€.

0. λ°°κ²½ 및 ν•„μš”μ„± (Context)

WAS μ•žλ‹¨μ— μ›Ή μ„œλ²„(Web Server)κ°€ μžˆλ‹€λ©΄ μ›Ή μ„œλ²„ 둜그λ₯Ό λΆ„μ„ν•˜λ©΄ λ˜μ§€λ§Œ, WAS둜 직접 λ“€μ–΄μ˜€λŠ” μš”μ²­μ΄λ‚˜ λ‚΄λΆ€ 톡신, ν˜Ήμ€ μƒμ„Έν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μˆ˜ν–‰ μ‹œκ°„ 뢄석을 μœ„ν•΄μ„œλŠ” WAS 자체의 Access Logκ°€ ν•„μš”ν•©λ‹ˆλ‹€. WebSphereλŠ” NCSA ν‘œμ€€ 포맷을 μ§€μ›ν•©λ‹ˆλ‹€.

Test Environment

  • Version: WebSphere Application Server v8.5

1. μ „μ—­ λ‘œκΉ… μ„œλΉ„μŠ€ ν™œμ„±ν™” (Global Setting)

κ°€μž₯ λ¨Όμ € μ„œλ²„ μ°¨μ›μ—μ„œ λ‘œκΉ… μ„œλΉ„μŠ€λ₯Ό μΌœμ•Ό ν•©λ‹ˆλ‹€.

  1. 관리 μ½˜μ†”μ—μ„œ Servers > Server Types > WebSphere application servers > [μ„œλ²„λͺ…] 클릭
  2. 우츑 ν•˜λ‹¨μ˜ Troubleshooting μ„Ήμ…˜μ—μ„œ NCSA access and HTTP error logging 클릭
  3. μ„€μ • 체크:
    • Enable logging service at server start-up (μ„œλ²„ 기동 μ‹œ μ„œλΉ„μŠ€ ν™œμ„±ν™”)
    • Enable access logging (μ•‘μ„ΈμŠ€ λ‘œκΉ… ν™œμ„±ν™”)
NCSA Logging Global Setting

2. 전솑 체인별 λ‘œκΉ… ν™œμ„±ν™” (Chain Setting)

μ „μ—­ 섀정을 ν–ˆλ”λΌλ„, μ‹€μ œ 톡신을 λ‹΄λ‹Ήν•˜λŠ” 전솑 체인(Transport Chain)μ—μ„œ λ‘œκΉ…μ„ μΌœμ§€ μ•ŠμœΌλ©΄ λ‘œκ·Έκ°€ 남지 μ•ŠλŠ” κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€. μ‚¬μš©ν•˜λŠ” 포트(9080, 9443 λ“±)에 ν•΄λ‹Ήν•˜λŠ” 체인을 μˆ˜μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

μ„€μ • 경둜

[μ„œλ²„λͺ…] > Web Container Settings > Web container transport chains

μ„€μ • 방법

주둜 μ‚¬μš©λ˜λŠ” 체인(WCInboundDefault, HttpQueueInboundDefault λ“±)을 μ„ νƒν•˜μ—¬ μ•„λž˜ μž‘μ—…μ„ λ°˜λ³΅ν•©λ‹ˆλ‹€.

  1. 체인 이름 클릭 (예: WCInboundDefault)
  2. HTTP inbound channel (HTTP_2) 클릭
  3. Enable logging μ²΄ν¬λ°•μŠ€ 선택
Chain Selection Enable Logging Checkbox
Tip: HTTPS(SSL) μš”μ²­μ— λŒ€ν•œ λ‘œκ·Έλ„ 남기렀면 WCInboundDefaultSecure 체인에 λŒ€ν•΄μ„œλ„ λ™μΌν•˜κ²Œ μ„€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

3. 둜그 포맷 μ»€μŠ€ν„°λ§ˆμ΄μ§• (Custom Properties)

κΈ°λ³Έ 포맷(Common Log Format)은 정보가 λΆ€μ‘±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μˆ˜ν–‰ μ‹œκ°„μ΄λ‚˜ μ„Έμ…˜ ID, User-Agent 등을 남기기 μœ„ν•΄ μ‚¬μš©μž μ •μ˜ 속성을 μΆ”κ°€ν•©λ‹ˆλ‹€.

속성 μΆ”κ°€ μœ„μΉ˜

μœ„μ˜ HTTP inbound channel (HTTP_2) μ„€μ • ν™”λ©΄μ—μ„œ 우츑의 Custom properties (μ‚¬μš©μž μ •μ˜ νŠΉμ„±) λ©”λ‰΄λ‘œ μ§„μž…ν•©λ‹ˆλ‹€.

속성 κ°’ (Key & Value)

  • Name: accessLogFormat
  • Value: (μ•„λž˜ μ˜ˆμ‹œ 쀑 선택)
# μ˜ˆμ‹œ 1: ν‘œμ€€ ν™•μž₯ 포맷 (IP, μ‹œκ°„, μš”μ²­, μƒνƒœ, 크기, μˆ˜ν–‰μ‹œκ°„)
%h %u %t "%r" %s %b %D

# μ˜ˆμ‹œ 2: 전체 정보 포함 (Referer, User-Agent, SessionID 포함)
%h %u %t "%r" %s %b %D "%{Referer}i" "%{User-agent}i" %{JSESSIONID}C
Custom Properties List

Setting accessLogFormat

4. μ£Όμš” 포맷 μ§€μ‹œμ–΄ μ„€λͺ…

μ§€μ‹œμ–΄ μ„€λͺ…
%h ν΄λΌμ΄μ–ΈνŠΈ IP μ£Όμ†Œ (Host)
%t μš”μ²­ μ‹œκ°„ (Time)
%r μš”μ²­ 라인 (Request Line) - Method, URI, Protocol
%s 응닡 μƒνƒœ μ½”λ“œ (Status Code, 예: 200, 404, 500)
%D μš”μ²­ 처리 μ†Œμš” μ‹œκ°„ (마이크둜초 λ‹¨μœ„, μ„±λŠ₯ 뢄석 μ‹œ μ€‘μš”)
%{Header}i νŠΉμ • μš”μ²­ 헀더 κ°’ (예: %{User-Agent}i)
%{Cookie}C νŠΉμ • μΏ ν‚€ κ°’ (예: %{JSESSIONID}C)

Next Step:
λͺ¨λ“  섀정을 마친 ν›„μ—λŠ” λ°˜λ“œμ‹œ μ„œλ²„λ₯Ό μž¬κΈ°λ™ν•΄μ•Ό λ‘œκ·Έκ°€ 남기 μ‹œμž‘ν•©λ‹ˆλ‹€. logs/[μ„œλ²„λͺ…]/http_access.log 파일이 μƒμ„±λ˜λŠ”μ§€ ν™•μΈν•˜μ‹­μ‹œμ˜€.

[WebSphere] TLS 1.2 μ „ν™˜ μ™„λ²½ κ°€μ΄λ“œ: 버전별 지원 ν˜„ν™© 및 WAS/IHS/Plugin ν•„μˆ˜ μ„€μ •

WebSphere Application Server v7.0, v8.0, v8.5 ν™˜κ²½μ—μ„œ TLS 1.2 ν”„λ‘œν† μ½œμ„ ν™œμ„±ν™”ν•˜κΈ° μœ„ν•œ μ΅œμ†Œ μš”κ΅¬ 사항(Fix Pack, JDK)을 ν™•μΈν•˜κ³ , WAS, IHS, Plugin 각 계측별 ν•„μˆ˜ μ„€μ • 방법을 μ •λ¦¬ν•©λ‹ˆλ‹€. 특히 ν”ŒλŸ¬κ·ΈμΈ μ—°κ²° μ‹œ λ°œμƒν•˜λŠ” GSK_ERROR_SOCKET_CLOSED μ—λŸ¬ 해결법을 ν¬ν•¨ν•©λ‹ˆλ‹€.

1. 버전별 TLS 1.2 지원 ν˜„ν™© (Prerequisites)

TLS 1.2λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ WAS 버전에 λ”°λ₯Έ μ΅œμ†Œ ν”½μŠ€νŒ©(Fix Pack)κ³Ό JDK 버전이 μΆ©μ‘±λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

WAS Version Minimum Fix Pack Required SDK Version
v7.0 7.0.0.23 이상 SDK 6 SR10 FP1 이상
v8.0 8.0.0.3 이상 SDK 6.0.1 (J9 2.6) SR1 FP1 이상
v8.5 8.5.0.0 (κΈ°λ³Έ 지원) SDK 6.0.1 (J9 2.6) SR2 이상
주의 (v7.0 μ œν•œμ‚¬ν•­):
WAS v7.0은 Java λ ˆλ²¨μ—μ„œλŠ” TLS 1.2λ₯Ό μ§€μ›ν•˜μ§€λ§Œ, ν•¨κ»˜ μ œκ³΅λ˜λŠ” Web Server Plugin(GSKit V7 μ‚¬μš©)은 TLS 1.2λ₯Ό μ§€μ›ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ v7.0 ν™˜κ²½μ—μ„œ μ›Ή μ„œλ²„ 연동 κ΅¬κ°„κΉŒμ§€ TLS 1.2λ₯Ό μ μš©ν•˜λ €λ©΄ Plugin λͺ¨λ“ˆ μ—…κ·Έλ ˆμ΄λ“œ ν˜Ήμ€ μ•„ν‚€ν…μ²˜ κ²€ν† κ°€ ν•„μš”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2. WAS μ„€μ • (Application Server)

관리 μ½˜μ†”μ—μ„œ SSL 섀정을 λ³€κ²½ν•˜κ³ , 관리 λͺ…λ Ή(stop/sync) μˆ˜ν–‰μ„ μœ„ν•΄ ν΄λΌμ΄μ–ΈνŠΈ μ„€μ • νŒŒμΌλ„ ν•¨κ»˜ μˆ˜μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

1) 관리 μ½˜μ†” μ„€μ • (QoP)

Security > SSL certificate and key management > SSL configurations λ©”λ‰΄λ‘œ μ΄λ™ν•©λ‹ˆλ‹€. CellDefaultSSLSettings, NodeDefaultSSLSettings λ“± μ‚¬μš© 쀑인 λͺ¨λ“  섀정을 μˆ˜μ •ν•©λ‹ˆλ‹€.

  1. μ„€μ • 이름 클릭 (예: CellDefaultSSLSettings)
  2. 우츑의 Quality of protection (QoP) settings 클릭
  3. Protocol λ“œλ‘­λ‹€μš΄ λ©”λ‰΄μ—μ„œ TLSv1.2 선택
  4. μ €μž₯ (Save)

2) ssl.client.props μˆ˜μ • (μ€‘μš”)

이 섀정을 ν•˜μ§€ μ•ŠμœΌλ©΄ WASκ°€ TLS 1.2둜 μ „ν™˜λœ ν›„, stopNodeλ‚˜ syncNode 같은 관리 λͺ…λ Ήμ–΄κ°€ κ΅¬ν˜• ν”„λ‘œν† μ½œλ‘œ 톡신을 μ‹œλ„ν•˜μ—¬ μ‹€νŒ¨ν•˜κ²Œ λ©λ‹ˆλ‹€.

  • λŒ€μƒ 파일:
    • [PROFILE_HOME]/properties/ssl.client.props
# 파일 λ‚΄ ν•΄λ‹Ή 라인 μˆ˜μ •
com.ibm.ssl.protocol=TLSv1.2

3) μž¬κΈ°λ™ 및 동기화

μ„€μ • μ μš©μ„ μœ„ν•΄ DMGRλΆ€ν„° μˆœμ„œλŒ€λ‘œ μž¬κΈ°λ™ν•©λ‹ˆλ‹€.

# 1. λ…Έλ“œ 및 DMGR 쀑지
./stopNode.sh
./stopManager.sh

# 2. DMGR 기동
./startManager.sh

# 3. λ…Έλ“œ 동기화 (μˆ˜λ™ 동기화 ꢌμž₯)
./syncNode.sh [Dmgr_Host] [Dmgr_SOAP_Port] -username [ID] -password [PW]

# 4. λ…Έλ“œ 기동
./startNode.sh

3. Web Server (IHS) μ„€μ •

IBM HTTP Server의 httpd.conf νŒŒμΌμ—μ„œ SSL 섀정을 κ°•ν™”ν•©λ‹ˆλ‹€.

<VirtualHost *:443>
    SSLEnable
    
    # TLS 1.2 ν™œμ„±ν™”
    SSLProtocolEnable TLSv12
    
    # μ·¨μ•½ν•œ ν•˜μœ„ ν”„λ‘œν† μ½œ λΉ„ν™œμ„±ν™”
    SSLProtocolDisable SSLv2 SSLv3 TLSv10 TLSv11
</VirtualHost>

4. Plugin μ„€μ • (Troubleshooting)

WAS와 IHSλ₯Ό λͺ¨λ‘ TLS 1.2둜 μ„€μ •ν–ˆλŠ”λ°λ„ http_plugin.log에 GSK_ERROR_SOCKET_CLOSED (gsk rc = 420) μ—λŸ¬κ°€ λ°œμƒν•˜λ©° 연결이 μ•ˆ 될 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” ν”ŒλŸ¬κ·ΈμΈμ΄ 기본적으둜 λ³΄μ•ˆ μˆ˜μ€€μ„ μ—„κ²©ν•˜κ²Œ κ²€μ‚¬ν•˜μ§€ μ•Šμ•„μ„œ λ°œμƒν•˜λŠ” ν˜Έν™˜μ„± λ¬Έμ œμž…λ‹ˆλ‹€.

ν•΄κ²° 방법: StrictSecurity 적용

plugin-cfg.xml 파일의 μ΅œμƒλ‹¨ Config νƒœκ·Έμ— 속성을 μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€.

<Config StrictSecurity="true">
    <Log LogLevel="Error" Name="..." />
    ...
</Config>
Tip: StrictSecurity="true" 섀정은 ν”ŒλŸ¬κ·ΈμΈμ΄ WAS와 톡신할 λ•Œ TLS ν”„λ‘œν† μ½œμ„ μ—„κ²©ν•˜κ²Œ μ€€μˆ˜ν•˜λ„λ‘ κ°•μ œν•˜μ—¬, TLS 1.2 ν•Έλ“œμ‰μ΄ν¬ 문제λ₯Ό ν•΄κ²°ν•©λ‹ˆλ‹€.

5. 검증 (Verification)

openssl λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬ μ„œλ²„κ°€ TLS 1.2만 ν—ˆμš©ν•˜λŠ”μ§€ ν…ŒμŠ€νŠΈν•©λ‹ˆλ‹€.

# TLS 1.2 접속 성곡 확인
openssl s_client -connect [Host]:9443 -tls1_2

# TLS 1.0 접속 μ‹€νŒ¨ 확인 (ν•Έλ“œμ‰μ΄ν¬ μ—λŸ¬κ°€ λ‚˜μ•Ό 정상)
openssl s_client -connect [Host]:9443 -tls1

[WebSphere/IHS] λ³΄μ•ˆ 취약점 쑰치: Server 헀더 숨기기 및 버전 정보 λ…ΈμΆœ λ°©μ§€ μ „λž΅

HTTP 응닡 ν—€λ”μ˜ Server ν•„λ“œ(예: Apache/2.4, WebSphere Application Server/8.5)λ₯Ό 톡해 μ„œλ²„μ˜ μ’…λ₯˜μ™€ 버전이 λ…ΈμΆœλ˜λŠ” 것을 λ°©μ§€ν•˜λŠ” 방법을 μ •λ¦¬ν•©λ‹ˆλ‹€. μ•žλ‹¨μ˜ IBM HTTP Server(IHS)와 λ’·λ‹¨μ˜ WebSphere(WAS) μ–‘μͺ½ λͺ¨λ‘μ˜ 섀정이 ν•„μš”ν•©λ‹ˆλ‹€.

0. λ°°κ²½ 및 원인 (Context)

μ„œλ²„μ˜ ꡬ체적인 버전 정보가 λ…ΈμΆœλ˜λ©΄, ν•΄μ»€λŠ” ν•΄λ‹Ή 버전에 μ•Œλ €μ§„ 취약점(CVE)을 μ°Ύμ•„ λ§žμΆ€ν˜• 곡격을 μ‹œλ„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ λ³΄μ•ˆ λͺ¨λ²” 사둀(Best Practice)μ—μ„œλŠ” μ„œλ²„ 정보λ₯Ό μˆ¨κΈ°κ±°λ‚˜ μ΅œμ†Œν™”ν•  것을 κΆŒκ³ ν•©λ‹ˆλ‹€.

Test Environment

  • OS: CentOS 7.2
  • Web Server: IBM HTTP Server (Apache 기반)
  • WAS: WebSphere Application Server v8.5

1. IBM HTTP Server (Web Server) μ„€μ •

κ°€μž₯ μ•žλ‹¨μ—μ„œ μš”μ²­μ„ λ°›λŠ” μ›Ή μ„œλ²„μ˜ 섀정을 λ³€κ²½ν•©λ‹ˆλ‹€. httpd.conf νŒŒμΌμ— μ•„λž˜ μ§€μ‹œμ–΄λ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μˆ˜μ •ν•©λ‹ˆλ‹€.

μ„€μ • λ‚΄μš© (httpd.conf)

# 1. μ„œλ²„ 정보 μ΅œμ†Œν™” (Apache/x.y.z -> Apache)
ServerTokens Prod

# 2. μ—λŸ¬ νŽ˜μ΄μ§€ ν•˜λ‹¨(Footer)에 μ„œλ²„ 정보 μˆ¨κΉ€
ServerSignature Off

# 3. Server 헀더 자체λ₯Ό μ‘λ‹΅μ—μ„œ 제거 (IHS μ „μš© κΈ°λŠ₯, κ°€λŠ₯ν•  경우 ꢌμž₯)
AddServerHeader Off
Tip: AddServerHeader OffλŠ” ν‘œμ€€ Apacheμ—λŠ” μ—†κ³  IBM HTTP Serverμ—λ§Œ μ‘΄μž¬ν•˜λŠ” μ§€μ‹œμ–΄μΌ 수 μžˆμŠ΅λ‹ˆλ‹€. 적용 ν›„ Syntax Errorκ°€ λ‚œλ‹€λ©΄ ServerTokens ProdκΉŒμ§€λ§Œ μ μš©ν•˜μ‹­μ‹œμ˜€.

2. WebSphere (WAS) μ„€μ •

WASκ°€ 직접 ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 응닡을 쀄 λ•Œ λΆ™λŠ” 헀더λ₯Ό μ œμ–΄ν•©λ‹ˆλ‹€. WAS v8.5.0.2 μ΄μƒλΆ€ν„°λŠ” κΈ°λ³Έ λ™μž‘μ΄ λ³€κ²½λ˜μ—ˆμœΌλ‚˜, λͺ…μ‹œμ μœΌλ‘œ μ œμ–΄ν•˜κΈ° μœ„ν•΄ HTTP 전솑 채널(Transport Channel) 섀정을 μˆ˜μ •ν•©λ‹ˆλ‹€.

μ„€μ • 경둜

μ„œλ²„ > WebSphere Application Server > [μ„œλ²„λͺ…] > μ›Ή μ»¨ν…Œμ΄λ„ˆ μ„€μ • > μ›Ή μ»¨ν…Œμ΄λ„ˆ 전솑 체인 > WCInboundDefault > HTTP μΈλ°”μš΄λ“œ 채널 (HTTP_2) > μ‚¬μš©μž μ •μ˜ νŠΉμ„± (Custom properties)

μ£Όμš” 속성 (택 1)

상황에 맞좰 μ•„λž˜ 두 κ°€μ§€ 속성 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•˜μ—¬ μ μš©ν•©λ‹ˆλ‹€.

속성 이름 (Name) μ„€λͺ… 및 ꢌμž₯ κ°’
RemoveServerHeader κ°’: true
Server 헀더 자체λ₯Ό μ•„μ˜ˆ μ‚­μ œν•©λ‹ˆλ‹€. κ°€μž₯ κ°•λ ₯ν•œ λ³΄μ•ˆ μ„€μ •μž…λ‹ˆλ‹€.
ServerHeaderValue κ°’: (μž„μ˜μ˜ λ¬Έμžμ—΄)
기본값인 "WebSphere Application Server..." λŒ€μ‹  μ‚¬μš©μžκ°€ μ§€μ •ν•œ λ¬Έμžμ—΄(예: "AppServer")둜 μΉ˜ν™˜ν•©λ‹ˆλ‹€.
μ°Έκ³  (WebContainer 속성):
전솑 채널 μ„€μ • 외에도, μ›Ή μ»¨ν…Œμ΄λ„ˆ > μ‚¬μš©μž μ •μ˜ νŠΉμ„±μ—μ„œ com.ibm.ws.webcontainer.disableServerHeader 값을 true둜 μ„€μ •ν•˜λŠ” 방법도 μ‘΄μž¬ν•©λ‹ˆλ‹€. (μ΅œμ‹  λ²„μ „μ—μ„œ ꢌμž₯)

3. 검증 (Verification)

IHS와 WASλ₯Ό λͺ¨λ‘ μž¬κΈ°λ™ν•œ ν›„, curl λͺ…λ Ήμ–΄λ‘œ 응닡 헀더λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

# 헀더 확인
curl -I http://localhost/

# [Before]
HTTP/1.1 200 OK
Server: IBM_HTTP_Server/8.5 ...
...

# [After] 
HTTP/1.1 200 OK
# Server 헀더가 μ•„μ˜ˆ μ—†κ±°λ‚˜ "Apache" λ˜λŠ” μ§€μ •ν•œ κ°’μœΌλ‘œ ν‘œμ‹œλ¨
...

Next Step:
헀더 μˆ¨κΉ€ μ²˜λ¦¬κ°€ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‹€μŒμœΌλ‘œλŠ” HTTP λ©”μ†Œλ“œ(PUT, DELETE, TRACE) 차단 섀정을 톡해 λΆˆν•„μš”ν•œ μš”μ²­μ„ λ§‰λŠ” μ›Ή μ„œλ²„ κ°•ν™” μž‘μ—…μ„ μ§„ν–‰ν•΄ λ³΄μ‹­μ‹œμ˜€.

[WebSphere] λ³΄μ•ˆ 취약점 쑰치: X-Powered-By 및 Server 헀더 숨기기 μ„€μ •

μ›Ή μ„œλ²„ 응닡 헀더에 ν¬ν•¨λœ X-Powered-By 정보(예: Servlet/3.1)λŠ” λΆˆν•„μš”ν•œ μ„œλ²„ 정보λ₯Ό λ…ΈμΆœν•˜μ—¬ λ³΄μ•ˆ μ·¨μ•½μ μœΌλ‘œ λΆ„λ₯˜λ©λ‹ˆλ‹€. IBM WebSphere Application Server(WAS) v8.5 μ΄μƒμ—μ„œ μ›Ή μ»¨ν…Œμ΄λ„ˆ μ‚¬μš©μž μ •μ˜ 속성을 톡해 이 헀더λ₯Ό μ œκ±°ν•˜λŠ” 방법을 μ •λ¦¬ν•©λ‹ˆλ‹€.

0. λ°°κ²½ 및 원인 (Context)

기본적으둜 WASλŠ” ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 응닡을 보낼 λ•Œ, μžμ‹ μ΄ μ‚¬μš©ν•œ 기술 μŠ€νƒμ„ 헀더에 ν¬ν•¨ν•©λ‹ˆλ‹€.

  • X-Powered-By: κ΅¬ν˜„ 기술 정보 (예: Servlet/3.0, JSP/2.2)
  • Server: μ›Ή μ„œλ²„ μ†Œν”„νŠΈμ›¨μ–΄ 정보 (예: WebSphere Application Server/8.5)

κ³΅κ²©μžλŠ” 이 정보λ₯Ό λ°”νƒ•μœΌλ‘œ νŠΉμ • 버전에 μ‘΄μž¬ν•˜λŠ” μ•Œλ €μ§„ 취약점(CVE)을 곡격할 수 μžˆμœΌλ―€λ‘œ, 운영 ν™˜κ²½μ—μ„œλŠ” λ°˜λ“œμ‹œ μˆ¨κ²¨μ•Ό ν•©λ‹ˆλ‹€.

Test Environment

  • OS: CentOS 7.2
  • WAS: WebSphere Application Server v8.5.5

1. X-Powered-By 헀더 제거 μ„€μ •

WAS 관리 μ½˜μ†”(Admin Console)μ—μ„œ μ›Ή μ»¨ν…Œμ΄λ„ˆ 섀정을 λ³€κ²½ν•©λ‹ˆλ‹€.

μ„€μ • 경둜

μ„œλ²„(Servers) > μ„œλ²„ μœ ν˜•(Server Types) > WebSphere application servers > [μ„œλ²„λͺ…] > μ›Ή μ»¨ν…Œμ΄λ„ˆ μ„€μ •(Web Container Settings) > μ›Ή μ»¨ν…Œμ΄λ„ˆ(Web container) > μ‚¬μš©μž μ •μ˜ νŠΉμ„±(Custom properties)

속성 μΆ”κ°€ (New)

이름 (Name) κ°’ (Value)
com.ibm.ws.webcontainer.disablexPoweredBy true
Tip (Server 헀더도 같이 숨기기):
λ³΄μ•ˆ 강도λ₯Ό 더 높이렀면 com.ibm.ws.webcontainer.disableServerHeader 속성도 true둜 μ„€μ •ν•˜μ—¬ WAS 버전 μ •λ³΄κΉŒμ§€ μˆ¨κΈ°λŠ” 것을 ꢌμž₯ν•©λ‹ˆλ‹€.

2. 검증 (Verification)

μ„€μ • μ €μž₯ ν›„ μ„œλ²„λ₯Ό λ°˜λ“œμ‹œ μž¬κΈ°λ™ν•΄μ•Ό μ μš©λ©λ‹ˆλ‹€. curl λͺ…λ Ήμ–΄λ‚˜ λΈŒλΌμš°μ € 개발자 도ꡬ(F12)λ₯Ό 톡해 응닡 헀더λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

λͺ…λ Ήμ–΄ 확인 (Linux)

# -I μ˜΅μ…˜μœΌλ‘œ ν—€λ”λ§Œ 쑰회
curl -I http://localhost:9080/

# 적용 μ „ (λ…ΈμΆœλ¨)
HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0
Content-Type: text/html
...

# 적용 ν›„ (사라짐)
HTTP/1.1 200 OK
Content-Type: text/html
...

λΈŒλΌμš°μ € 확인

Chrome 개발자 도ꡬ > Network νƒ­ > 아무 μš”μ²­ 클릭 > Response Headers μ„Ήμ…˜μ—μ„œ ν•΄λ‹Ή ν•­λͺ©μ΄ μ‚¬λΌμ‘ŒλŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€.


Next Step:
WAS μ„€μ •λΏλ§Œ μ•„λ‹ˆλΌ μ•žλ‹¨μ˜ μ›Ή μ„œλ²„(IHS/Apache)μ—μ„œλ„ ServerTokens Prod 섀정을 톡해 Apache 버전 정보 λ…ΈμΆœμ„ μ΅œμ†Œν™”ν•΄μ•Ό μ™„λ²½ν•œ λ³΄μ•ˆ μ‘°μΉ˜κ°€ λ©λ‹ˆλ‹€.

[JBoss EAP 7] Datasource νŒ¨μŠ€μ›Œλ“œ μ•”ν˜Έν™” κ°€μ΄λ“œ: Picketbox Security Domain μ„€μ •

λ³΄μ•ˆ μ»΄ν”ŒλΌμ΄μ–ΈμŠ€ μ€€μˆ˜λ₯Ό μœ„ν•΄ JBoss EAP 7의 standalone.xml λ˜λŠ” domain.xml 파일 내에 μ €μž₯λ˜λŠ” DB νŒ¨μŠ€μ›Œλ“œλ₯Ό μ•”ν˜Έν™”ν•˜λŠ” 방법을 μ •λ¦¬ν•©λ‹ˆλ‹€. org.picketbox λͺ¨λ“ˆμ„ μ΄μš©ν•˜μ—¬ μ•”ν˜Έν™”λœ λ¬Έμžμ—΄μ„ μƒμ„±ν•˜κ³ , Security Domain을 톡해 λ°μ΄ν„°μ†ŒμŠ€μ™€ μ—°λ™ν•©λ‹ˆλ‹€.

0. λ°°κ²½ 및 μ€€λΉ„ (Context)

JBoss μ„€μ • νŒŒμΌμ— λΉ„λ°€λ²ˆν˜Έλ₯Ό ν‰λ¬ΈμœΌλ‘œ μ €μž₯ν•˜λ©΄ λ³΄μ•ˆ 감사 μ‹œ 지적 λŒ€μƒμ΄ λ©λ‹ˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ JBossλŠ” Security Domain을 톡해 인증 과정을 μœ„μž„ν•˜λŠ” 방식을 μ œκ³΅ν•©λ‹ˆλ‹€.

Test Environment

  • OS: CentOS 7.2
  • WAS: JBoss EAP 7.2
  • JDK: 1.8

1. λΉ„λ°€λ²ˆν˜Έ μ•”ν˜Έν™” λ¬Έμžμ—΄ 생성 (Encryption)

κ°€μž₯ λ¨Όμ € μ‹€μ œ DB νŒ¨μŠ€μ›Œλ“œλ₯Ό μ•”ν˜Έν™”λœ λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. JBoss λ‚΄λΆ€ λͺ¨λ“ˆμΈ picketboxλ₯Ό Java둜 μ‹€ν–‰ν•˜μ—¬ λ³€ν™˜ν•©λ‹ˆλ‹€.

μ•”ν˜Έν™” 슀크립트 (create_encrypt_pw.sh)

JBoss 패치(CP)κ°€ 적용되면 .overlays 디렉토리에 λΌμ΄λΈŒλŸ¬λ¦¬κ°€ 변경될 수 μžˆμŠ΅λ‹ˆλ‹€. μ•„λž˜ μŠ€ν¬λ¦½νŠΈλŠ” 패치 μ—¬λΆ€λ₯Ό μžλ™μœΌλ‘œ κ°μ§€ν•˜μ—¬ μ μ ˆν•œ jar νŒŒμΌμ„ μ°Ύμ•„ μ‹€ν–‰ν•©λ‹ˆλ‹€.

#!/bin/sh

# 1. ν™˜κ²½ λ³€μˆ˜ μ„€μ • (μ‚¬μš©μž ν™˜κ²½μ— 맞게 μˆ˜μ • ν•„μˆ˜)
export JAVA_HOME="/SW/was/java1.8"
export PATH="$JAVA_HOME/bin:$PATH"
JBOSS_HOME="/SW/was/JBoss7.2"

# 2. 라이브러리 경둜 탐색 (Overlay 지원)
OVERLAY_DIRECTORY="$JBOSS_HOME/modules/system/layers/base/.overlays"
SEARCH_DIRECTORY="$JBOSS_HOME/modules/system/layers/base/org/picketbox/main"

if [ -d "$OVERLAY_DIRECTORY" ]; then
    # μ΅œμ‹  패치 디렉토리 확인
    PATCH_SUBDIRECTORY=$(ls -dt $OVERLAY_DIRECTORY/* | grep "CP" | head -n 1)
    if [ -n "$PATCH_SUBDIRECTORY" ]; then
        echo "Info: Patch directory detected: $PATCH_SUBDIRECTORY"
        SEARCH_DIRECTORY="$PATCH_SUBDIRECTORY/org/picketbox/main"
    fi
fi

# 3. Classpath μ„€μ •
export CLASSPATH=$(find "$SEARCH_DIRECTORY" -name "*.jar" -print | tr '\n' ':')$CLASSPATH

# 4. μ•”ν˜Έν™” μ‹€ν–‰
echo ""
read -p "Enter Database Password : " PASSWORD
echo ""
echo "####################################################"
java org.picketbox.datasource.security.SecureIdentityLoginModule "$PASSWORD"
echo "####################################################"
echo ""

μ‹€ν–‰ κ²°κ³Ό μ˜ˆμ‹œ

Encoded password: 9fdd42c2a7390d3

좜λ ₯된 Encoded password 값을 볡사해 λ‘‘λ‹ˆλ‹€.


2. Security Domain μ„€μ • (standalone.xml)

μƒμ„±ν•œ μ•”ν˜Έν™” νŒ¨μŠ€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” λ³΄μ•ˆ 도메인을 μ •μ˜ν•©λ‹ˆλ‹€. security μ„œλΈŒμ‹œμŠ€ν…œ 내에 μž‘μ„±ν•©λ‹ˆλ‹€.

μ„€μ • λ‚΄μš©

<subsystem xmlns="urn:jboss:domain:security:2.0">
    <security-domains>
        
        <security-domain name="encryptedSecurityDB" cache-type="default">
            <authentication>
                <login-module code="org.picketbox.datasource.security.SecureIdentityLoginModule" flag="required">
                    <module-option name="username" value="sa"/>
                    <module-option name="password" value="9fdd42c2a7390d3"/> <!-- μ•”ν˜Έν™”λœ κ°’ -->
                    <module-option name="managedConnectionFactoryName" value="jboss.jca:service=LocalTxCM"/>
                </login-module>
            </authentication>
        </security-domain>
        
    </security-domains>
</subsystem>
μ˜΅μ…˜ μ„€λͺ…:
  • username: DB 접속 계정 ID (평문)
  • password: μœ„μ—μ„œ μƒμ„±ν•œ μ•”ν˜Έν™”λœ νŒ¨μŠ€μ›Œλ“œ
  • managedConnectionFactoryName: jboss.jca:service=LocalTxCM (κ³ μ •κ°’ μ‚¬μš©)

3. Datasource 연동 μ„€μ •

이제 λ°μ΄ν„°μ†ŒμŠ€κ°€ 평문 λΉ„λ°€λ²ˆν˜Έ λŒ€μ‹  μœ„μ—μ„œ λ§Œλ“  Security Domain을 바라보도둝 μˆ˜μ •ν•©λ‹ˆλ‹€.

μˆ˜μ • μ „ (Before)

<datasource ...>
    ...
    <security>
        <user-name>sa</user-name>
        <password>admin1234</password>
    </security>
</datasource>

μˆ˜μ • ν›„ (After)

user-nameκ³Ό password νƒœκ·Έλ₯Ό μ‚­μ œν•˜κ³  security-domain νƒœκ·Έλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
    <driver>h2</driver>
    
    <security>
        <security-domain>encryptedSecurityDB</security-domain>
    </security>
</datasource>

4. 검증 (Verification)

  1. μ„€μ • μ €μž₯ ν›„ JBoss μ„œλ²„λ₯Ό μž¬κΈ°λ™(Reload)ν•©λ‹ˆλ‹€.
  2. 관리 μ½˜μ†” λ˜λŠ” CLIμ—μ„œ Test Connection을 μˆ˜ν–‰ν•˜μ—¬ μ—°κ²° 성곡 μ—¬λΆ€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.
  3. μ—°κ²° 성곡 μ‹œ, μ„€μ • νŒŒμΌμ— λΉ„λ°€λ²ˆν˜Έ 평문이 λ‚¨μ•„μžˆμ§€ μ•Šμ€μ§€ μž¬ν™•μΈν•©λ‹ˆλ‹€.

Next Step:
λ§Œμ•½ λΉ„λ°€λ²ˆν˜Έ 뿐만 μ•„λ‹ˆλΌ ν‚€μŠ€ν† μ–΄ νŒ¨μŠ€μ›Œλ“œ λ“± JBoss μ„€μ • μ „λ°˜μ˜ 민감 정보λ₯Ό λ³΄ν˜Έν•΄μ•Ό ν•œλ‹€λ©΄, Vault(볼트) ꡬ성을 μΆ”κ°€λ‘œ κ²€ν† ν•΄ λ³΄μ‹­μ‹œμ˜€.

[IBM HTTPServer] SSL(HTTPS) ꡬ성 및 가상 호슀트 μ„€μ • κ°€μ΄λ“œ

IBM HTTP Server(IHS)에 SSL μΈμ¦μ„œλ₯Ό μ μš©ν•˜μ—¬ HTTPS 톡신을 ν™œμ„±ν™”ν•˜κ³ , WebSphere Application Server(WAS)와 μ •μƒμ μœΌλ‘œ μ—°λ™ν•˜κΈ° μœ„ν•œ μ„€μ • 절차λ₯Ό μ •λ¦¬ν•©λ‹ˆλ‹€. httpd.conf μ„€μ •, ν‚€ 파일(KDB) μ§€μ •, 그리고 WAS 가상 호슀트 포트 등둝 과정을 ν¬ν•¨ν•©λ‹ˆλ‹€.

Test Environment

  • OS: CentOS 7.2 (κ²½λ‘œλŠ” Linux κΈ°μ€€, WindowsλŠ” λ“œλΌμ΄λΈŒλͺ… μ°Έμ‘°)
  • Web Server: IBM HTTP Server v8.5
  • WAS: WebSphere Application Server v8.5

1. μ›Ή μ„œλ²„ μ„€μ • (httpd.conf)

IHS의 메인 μ„€μ • νŒŒμΌμ—μ„œ SSL λͺ¨λ“ˆμ„ λ‘œλ“œν•˜κ³ , 443 ν¬νŠΈμ— λŒ€ν•œ VirtualHostλ₯Ό ꡬ성해야 ν•©λ‹ˆλ‹€.

μ„€μ • 파일 μˆ˜μ •

  • 파일 μœ„μΉ˜: [IHS_ROOT]/conf/httpd.conf
  • μ£Όμš” μž‘μ—…: λͺ¨λ“ˆ 주석 ν•΄μ œ, 포트 리슨, μΈμ¦μ„œ ν‚€ 파일(KDB) 경둜 μ§€μ •
### 1. SSL Module Load ###
LoadModule ibm_ssl_module modules/mod_ibm_ssl.so

### 2. Port Listen ###
Listen 0.0.0.0:443

### 3. Virtual Host Configuration ###
# 80 포트 (HTTP) μ„€μ •
<VirtualHost *:80>
    ServerName ad1.test.com
    DocumentRoot "/opt/IBM/HTTPServer/htdocs"
    # Redirect permanent / https://ad1.test.com/  (ν•„μš” μ‹œ HTTPS둜 λ¦¬λ‹€μ΄λ ‰νŠΈ)
</VirtualHost>

# 443 포트 (HTTPS) μ„€μ •
<VirtualHost *:443>
    SSLEnable
    SSLClientAuth none
    ServerName ad1.test.com
    DocumentRoot "/opt/IBM/HTTPServer/htdocs"
    
    # 둜그 μ„€μ • (ꢌμž₯)
    ErrorLog logs/ssl_error_log
    CustomLog logs/ssl_access_log common
</VirtualHost>

### 4. Global SSL Config ###
# VirtualHost λ°–μ—μ„œ μ „μ—­ μ„€μ •μœΌλ‘œ Keyfile μ§€μ •
SSLDisable
Keyfile "/opt/IBM/HTTPServer/ssl/key.kdb"

# λ³΄μ•ˆ κ°•ν™”λ₯Ό μœ„ν•œ ν”„λ‘œν† μ½œ μ„€μ • μ˜ˆμ‹œ (TLS 1.2만 ν—ˆμš© μ‹œ)
# SSLProtocolDisable SSLv2 SSLv3 TLSv10 TLSv11
# SSLProtocolEnable TLSv12

Note: Keyfile μ§€μ‹œμ–΄λŠ” kdb 파일의 경둜λ₯Ό μ§€μ •ν•©λ‹ˆλ‹€. ν•΄λ‹Ή κ²½λ‘œμ— key.sth (Stash file)이 ν•¨κ»˜ μ‘΄μž¬ν•΄μ•Ό μ•”ν˜Έλ₯Ό 묻지 μ•Šκ³  κ΅¬λ™λ©λ‹ˆλ‹€.


2. μΈμ¦μ„œ ν‚€ 파일 (KDB) μ€€λΉ„

IHSλŠ” CMS Key Database (.kdb) 포맷을 μ‚¬μš©ν•©λ‹ˆλ‹€. ikeyman GUI νˆ΄μ΄λ‚˜ gskcapicmd(CLI)λ₯Ό μ‚¬μš©ν•˜μ—¬ κ°œμΈν‚€μ™€ μΈμ¦μ„œλ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.

  • 도ꡬ μœ„μΉ˜: [IHS_ROOT]/bin/ikeyman (GUI μ‹€ν–‰ μ‹œ X-Window ν•„μš”)
  • μž‘μ—… λ‚΄μš©:
    • μƒˆλ‘œμš΄ KDB 파일 생성 (CMS νƒ€μž…)
    • κ°œμΈν‚€ 생성 (CSR) 및 λ°œκΈ‰λ°›μ€ μΈμ¦μ„œ(Signer, Personal) Import
    • μ€‘μš”: "Stash password to a file" μ˜΅μ…˜μ„ μ²΄ν¬ν•˜μ—¬ .sth 파일 생성 ν•„μˆ˜

3. WAS 가상 호슀트 (Virtual Host) 등둝

μ›Ή μ„œλ²„ 섀정을 λ§ˆμ³€λ”λΌλ„, WAS의 가상 호슀트 λͺ©λ‘μ— SSL 포트(443)κ°€ λ“±λ‘λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ©΄ ν”ŒλŸ¬κ·ΈμΈμ΄ μš”μ²­μ„ κ±°λΆ€ν•˜κ±°λ‚˜ WASκ°€ μš”μ²­μ„ μΈμ‹ν•˜μ§€ λͺ»ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

관리 μ½˜μ†” μ„€μ •

  1. μœ„μΉ˜: ν™˜κ²½(Environment) > 가상 호슀트(Virtual Hosts) > default_host (λ˜λŠ” μ‚¬μš©ν•˜λŠ” 가상 호슀트) > 호슀트 별λͺ…(Host Aliases)
  2. μž‘μ—…: μƒˆλ‘œ μž‘μ„±(New) 클릭
  3. μž…λ ₯:
    • 호슀트 이름: * (λͺ¨λ“  호슀트) λ˜λŠ” ad1.test.com
    • 포트: 443
  4. μ €μž₯: λ§ˆμŠ€ν„° ꡬ성에 μ €μž₯ ν›„ λ³€κ²½ 사항 동기화.

4. 검증 및 μž¬κΈ°λ™

μ„€μ • 파일의 문법 였λ₯˜λ₯Ό μ²΄ν¬ν•˜κ³  μ›Ή μ„œλ²„λ₯Ό μž¬κΈ°λ™ν•˜μ—¬ λ³€κ²½ 사항을 μ μš©ν•©λ‹ˆλ‹€.

Syntax Check

# IHS bin λ””λ ‰ν† λ¦¬λ‘œ 이동
./apachectl -t

# κ²°κ³Όκ°€ 'Syntax OK'μ—¬μ•Ό 함

Server Restart

./apachectl restart

Next Step:
λΈŒλΌμš°μ €μ—μ„œ https://ad1.test.com으둜 μ ‘μ†ν•˜μ—¬ μžλ¬Όμ‡  μ•„μ΄μ½˜μ΄ μ •μƒμ μœΌλ‘œ ν‘œμ‹œλ˜λŠ”μ§€ ν™•μΈν•˜κ³ , SSL Labs λ“±μ˜ 도ꡬλ₯Ό 톡해 적용된 μ•”ν˜Έν™” ν”„λ‘œν† μ½œ(TLS 1.2 λ“±)의 λ³΄μ•ˆ 등급을 μ κ²€ν•΄λ³΄μ‹œκΈ° λ°”λžλ‹ˆλ‹€.