#IBM HTTPServer

[Troubleshooting] Edge 보안 업데이트 대응: IHS & IIS CORS 설정 완벽 가이드

최근 Edge 및 Chrome 브라우저의 보안 정책 업데이트(Private Network Access, SameSite 등)로 인해, 내부망 시스템 간 호출 시 발생하는 CORS(Cross-Origin Resource Sharing) 오류 해결 과정을 정리합니다.

특히 IBM HTTP Server(IHS) 환경에서 Invalid CORS request 오류와 로그가 남지 않는 현상을 해결한 최종 설정 가이드입니다.


1. IHS (IBM HTTP Server) 설정 가이드

이 설정은 단순 CORS 허용뿐만 아니라, WAS(애플리케이션)단의 거부 에러 해결최신 브라우저의 사설망 접근 허용을 모두 포함한 통합본입니다.

📂 설정 파일 경로: IHS_HOME/conf/httpd.conf
📂 적용 위치: <VirtualHost ...> 태그 내부

✅ httpd.conf 최종 적용 코드

<VirtualHost *:8080>
    # ... 기존 설정 ...

    # =========================================================================
    # [1. 브라우저용 설정] CORS 및 PNA(사설망 접근) 보안 정책 대응
    # =========================================================================
    
    # 1. 도메인 화이트리스트 검사 (https 및 모든 서브도메인 허용 정규식)
    # 문법: ^(시작) + http(s):// + .*(와일드카드) + \.도메인\.com + $(끝)
    SetEnvIf Origin "^http(s)?://.*\.test\.com$" ACCESS_CONTROL_ORIGIN=$0

    # 2. 브라우저에게 보내는 허가증 (Response Header)
    Header set Access-Control-Allow-Origin %{ACCESS_CONTROL_ORIGIN}e env=ACCESS_CONTROL_ORIGIN
    
    # 3. SSO 필수: Credentials(쿠키/세션) 전송 허용
    Header set Access-Control-Allow-Credentials "true" env=ACCESS_CONTROL_ORIGIN
    
    # 4. ★핵심: 최신 Edge PNA(Private Network Access) 허용 헤더
    # (공인망에서 사설망 호출 시 차단 방지)
    Header set Access-Control-Allow-Private-Network "true" env=ACCESS_CONTROL_ORIGIN
    
    # 5. 허용 메소드 및 헤더 정의
    Header set Access-Control-Allow-Methods "POST, GET, OPTIONS" env=ACCESS_CONTROL_ORIGIN
    Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With, Access-Control-Allow-Private-Network" env=ACCESS_CONTROL_ORIGIN

    # 6. 캐싱 문제 방지
    Header add Vary Origin


    # =========================================================================
    # [2. WAS(애플리케이션)용 설정] "Invalid CORS request" 해결
    # =========================================================================
    
    # 설명: WAS가 요청 Origin을 엄격하게 검사하여 에러를 뱉는 경우,
    # IHS가 WAS로 넘기기 직전에 Origin 헤더를 '내부 도메인'으로 변조하여 통과시킴.
    
    # ★ 수정 포인트: 아래 주소는 실제 IHS 서버의 호스트 주소(https 포함)로 변경
    RequestHeader set Origin "https://www.test.com"

    # ... 기존 설정 ...
</VirtualHost>
⚠️ 주의사항: 설정 적용 후 반드시 IHS를 재기동해야 합니다.
./apachectl restart

2. 테스트 및 검증 방법

🛠️ 테스트 준비 (필수)

  • 브라우저 캐시 삭제 (Ctrl + Shift + Delete)
  • F12 개발자 도구 실행 → [Network] 탭 확인
  • 팝업이 닫히는 경우: F12 설정(F1) → '팝업용 DevTools 자동 열기' 체크

🔍 성공 기준 (Checklist)

확인 항목 정상 결과
HTTP 상태 코드 200 OK (OPTIONS 및 POST 요청 모두)
Response Header Access-Control-Allow-Origin 값이 요청한 도메인으로 변환되어 있어야 함
Response Header Access-Control-Allow-Private-Network: true 확인

3. 문제 해결 (Troubleshooting)

❌ 증상 1: 서버에 액세스 로그조차 남지 않음

원인: Mixed Content (HTTPS 페이지에서 HTTP 호출) 또는 브라우저 PNA 정책 차단
해결: 호출 URL을 https://로 변경하고, 위 설정의 PNA 헤더 적용 확인

❌ 증상 2: "Invalid CORS request" 텍스트가 화면에 뜸

원인: WAS(애플리케이션)가 요청 도메인을 거부함
해결: 위 코드의 RequestHeader set Origin "내부주소" 설정이 올바른지 확인

❌ 증상 3: ERR_CONNECTION_RESET 발생

원인: HTTPS(443) 호출을 했으나 IHS 포트가 8080(HTTP)이거나 SSL 설정이 없음
해결: IHS httpd.conf에 SSL 설정(Listen 443, 인증서) 확인

Open Stream →
#mcp

[Node.js] Windows npm 실행 오류 해결: PowerShell 보안 정책(PSSecurityException) 설정 가이드

Windows 환경에서 npm 명령어를 실행할 때 발생하는 "이 시스템에서 스크립트를 실행할 수 없으므로..."(PSSecurityException) 오류를 해결합니다. PowerShell의 실행 정책(Execution Policy)을 이해하고, 보안을 유지하면서 npm을 사용할 수 있도록 RemoteSigned 정책을 적용하는 방법을 정리합니다.

1. 문제 현상 (Issue)

Node.js 설치 후 터미널(VS Code 또는 PowerShell)에서 npm 명령어를 실행하면 다음과 같은 빨간색 에러 메시지가 출력되며 실행이 차단됩니다.

에러 메시지

npm : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\Program Files\nodejs\npm.ps1 파일을 로드할 수 없습니다.
위치 줄:1 문자:1
+ npm install
+ ~~~
    + CategoryInfo          : 보안 오류: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

2. 원인 분석 (Root Cause)

이것은 npm의 문제가 아니라 Windows PowerShell의 보안 정책 때문입니다.

  • Restricted (기본값): Windows 클라이언트 OS의 기본 정책으로, 모든 스크립트 파일(.ps1)의 실행을 차단합니다.
  • npm 명령어는 내부적으로 npm.ps1 스크립트를 실행하려다 이 정책에 막히게 됩니다.

3. 해결 방법 (Solution)

보안 정책을 변경하여 스크립트 실행을 허용해야 합니다. 보안과 편의성의 균형을 위해 RemoteSigned 정책을 현재 사용자(CurrentUser)에게만 적용하는 것을 권장합니다.

Step 1: 현재 정책 확인

PowerShell을 실행하고 아래 명령어를 입력합니다.

Get-ExecutionPolicy

결과가 Restricted로 나온다면 실행이 불가능한 상태입니다.

Step 2: 정책 변경 (권장 설정)

PowerShell을 관리자 권한으로 실행한 뒤, 아래 명령어를 입력합니다.

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
정책 설명:
  • RemoteSigned: 로컬에서 생성한 스크립트는 실행 허용, 인터넷에서 다운로드한 스크립트는 서명된 것만 허용 (가장 권장되는 설정).
  • -Scope CurrentUser: 시스템 전체가 아닌 현재 로그인한 사용자에게만 적용하여 보안 리스크 최소화.

변경 확인 메시지가 나오면 Y (예)를 입력하여 승인합니다.


4. 대안 및 팁 (Alternatives)

방법 A: 일회성 허용 (임시)

정책을 영구적으로 바꾸기 부담스럽다면, 현재 열려있는 창에서만 허용할 수 있습니다.

Set-ExecutionPolicy RemoteSigned -Scope Process

방법 B: Command Prompt (cmd) 사용

PowerShell이 아닌 일반 명령 프롬프트(cmd)Git Bash에서는 해당 보안 정책의 영향을 받지 않으므로, 별도 설정 없이 npm을 사용할 수 있습니다.


5. 검증 (Verification)

설정 후 다시 버전을 확인하거나 명령어를 실행하여 에러가 사라졌는지 확인합니다.

npm --version

Next Step:
이제 npm이 정상 작동하므로, npm install을 통해 필요한 패키지를 설치하거나 npx create-react-app 등의 프로젝트 생성 명령어를 실행해 보십시오.

Open Stream →
#Troubleshooting

[WebSphere] native_stderr 로그 비대화 해결: Verbose GC 로그 분리 및 로테이션 설정

WebSphere의 native_stderr.log 파일에는 로테이션(Rotation) 기능이 내장되어 있지 않습니다. 따라서 Verbose GC가 활성화된 경우 파일 용량이 무한정 증가합니다. 이를 해결하기 위해 JVM 옵션을 사용하여 GC 로그를 별도 파일로 분리하고 순환시키는 방법을 정리합니다.

1. 원인 분석 (Root Cause)

WebSphere는 SystemOut.logSystemErr.log에 대해서는 시간/크기 기반의 로그 순환을 지원합니다. 하지만, JVM 프로세스 자체의 출력을 담는 native 로그는 WAS가 제어하지 못합니다.

  • 문제점: 관리 콘솔에서 "Verbose garbage collection"을 체크하면, GC 수행 기록이 native_stderr.log에 누적됩니다.
  • 결과: 시간이 지남에 따라 파일이 GB 단위로 커지며, 디스크 Full 장애를 유발할 수 있습니다.

Test Environment

  • OS: CentOS 7 (3.10.0-957.el7.x86_64)
  • WAS: WebSphere Application Server v8.5 / 9.0
  • JDK: IBM JDK (WebSphere 기본)

2. 해결 방법: GC 로그 분리 설정

해결의 핵심은 native 로그에 GC 내용을 남기지 않고, 별도의 파일로 빼내는 것입니다. 사용하는 JDK 벤더에 따라 옵션이 다릅니다.

Step 1: 기본 Verbose GC 비활성화

JVM 옵션으로 제어하기 위해, 콘솔의 체크박스 옵션은 해제해야 합니다.

  • 경로: 서버 > 서버 유형 > WebSphere Application Server > [서버명] > Java 및 프로세스 관리 > 프로세스 정의 > Java 가상 머신
  • 조치: Verbose garbage collection 체크박스 해제 (Uncheck)
Disable Verbose GC Checkbox

[그림] 기본 Verbose GC 옵션 해제

Step 2: 일반 JVM 인수(Generic JVM arguments) 추가

같은 화면의 Generic JVM arguments 입력란에 아래 옵션을 추가합니다.

Case A: IBM JDK 사용 시 (WebSphere 기본)

IBM JDK는 -Xverbosegclog 옵션을 사용하여 로그 파일 경로와 로테이션 규칙을 지정합니다.

# 구문: -Xverbosegclog:[경로/파일명][,X,Y]
# X: 파일 개수, Y: 파일당 GC 사이클 수

# 예시 1: 날짜/PID 포함하여 단일 파일 생성 (가장 일반적)
-Xverbosegclog:${SERVER_LOG_ROOT}/gc.%Y%m%d.%H%M%S.%pid.txt

# 예시 2: 10,000 사이클마다 파일 교체, 총 10개 파일 유지 (로테이션)
-Xverbosegclog:${SERVER_LOG_ROOT}/verbosegc.log,10,10000

Case B: Oracle/HotSpot JDK 사용 시

드물지만 Solaris나 특정 환경에서 HotSpot 계열 JDK를 사용하는 경우입니다.

-verbose:gc
-Xloggc:${SERVER_LOG_ROOT}/verbosegc.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=20M
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
Tip: ${SERVER_LOG_ROOT} 변수를 사용하면 하드코딩된 경로 대신 각 서버의 로그 디렉토리를 자동으로 찾아가므로 관리가 용이합니다.

3. 적용 확인 (Verification)

  1. 설정 저장 후 서버를 재기동합니다.
  2. ps -ef | grep java 명령어로 프로세스를 확인했을 때, 추가한 옵션이 적용되어 있는지 확인합니다.
  3. 로그 디렉토리(logs/[서버명]/)에 gc...txt 또는 설정한 이름의 파일이 생성되는지 확인합니다.
GC Log File Created

Next Step:
분리된 GC 로그 파일은 IBM GCMV (Garbage Collection and Memory Visualizer) 도구에 넣어 분석하면 메모리 누수나 튜닝 포인트를 시각적으로 확인할 수 있습니다.

Open Stream →
#security

[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.waruddi.ear 내의 log4j 파일을 삭제하고, 개발팀은 배포하는 애플리케이션(WAR/EAR) 내에 취약한 Log4j 버전이 포함되지 않도록 빌드 의존성을 점검해야 합니다.
Open Stream →
#security

[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로 전환된 후, stopNodesyncNode 같은 관리 명령어가 구형 프로토콜로 통신을 시도하여 실패하게 됩니다.

  • 대상 파일:
    • [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.logGSK_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
Open Stream →
#AIX

[Linux/AIX] 윈도우 파일 업로드 시 발생하는 개행 문자(^M) 제거 방법 (Perl, vi, sed)

Windows(CRLF)에서 작성한 파일을 Unix/Linux(LF) 계열 서버로 업로드하면, 라인 끝에 ^M 특수문자가 붙어 스크립트 실행 에러(bad interpreter)를 유발합니다. AIX 환경에서도 확실하게 동작하는 Perl 명령어를 이용한 일괄 제거 방법을 정리합니다.

0. 원인 및 증상 (Context)

운영체제마다 줄바꿈(New Line)을 처리하는 방식이 다릅니다.

  • Windows: CR(Carriage Return, \r) + LF(Line Feed, \n)
  • Unix/Linux/AIX: LF(\n)

FTP 전송 시 ASCII 모드가 아닌 Binary 모드로 전송하거나, 단순 복사/붙여넣기를 할 경우 Windows의 CR(\r) 문자가 그대로 남아 vi 에디터에서 ^M으로 표시됩니다.

Test Environment

  • OS: AIX (또는 Linux)
  • Shell: sh, ksh, bash

1. 문제 확인 (Issue Identification)

쉘 스크립트 실행 시 에러가 발생하거나, vi로 파일을 열었을 때 라인 끝마다 ^M이 붙어있는 것을 확인할 수 있습니다.

vi 에디터 화면

#!/bin/sh^M
#./startServer.sh server_name^M
#./stopServer.sh server_name -username username -password password^M

2. 해결 방법 A: Perl 명령어 사용 (권장)

AIX의 기본 sed 명령어는 -i(파일 직접 수정) 옵션을 지원하지 않는 경우가 많습니다. 따라서 Perl을 사용하는 것이 가장 호환성이 좋고 간편합니다.

명령어 구문

^M을 직접 입력하기 번거로우므로, 8진수 코드인 \015를 사용하는 것이 안전합니다.

# 구문: perl -pi -e 's/찾을문자/바꿀문자/g' [파일명]
perl -pi -e 's/\015//g' stopWasAll.sh

다중 파일 일괄 처리

와일드카드(*)를 사용하여 여러 파일을 한 번에 변환할 수 있습니다.

# 현재 경로의 모든 .sh 파일에서 CR 제거
perl -pi -e 's/\015//g' *.sh

3. 해결 방법 B: vi 에디터 내부 치환

파일을 열어놓은 상태에서 수정하고 싶을 때 사용합니다.

  1. vi로 파일 열기
  2. 명령 모드(ESC)에서 치환 명령어 입력
:%s/^M//g
Tip: 위 명령어의 ^MShift + 6, M을 타이핑하는 것이 아닙니다.
반드시 Ctrl + V를 누른 상태에서 Ctrl + M을 눌러야 입력됩니다.

4. 해결 방법 C: dos2unix 유틸리티

리눅스(CentOS/Ubuntu) 환경이라면 전용 도구를 설치하여 해결하는 것이 가장 쉽습니다.

# 설치 (CentOS)
yum install -y dos2unix

# 변환
dos2unix stopWasAll.sh

5. 검증 (Verification)

변환 후 다시 vi로 파일을 열어 ^M 문자가 사라졌는지 확인합니다.

test1 root [/was8/bin]# vi stopWasAll.sh

#!/bin/sh
#./startServer.sh server_name
#./stopServer.sh server_name -username username -password password
#PropFilePasswordEncoder.sh
#export LANG=en_us.utf8

깔끔하게 정리된 것을 확인할 수 있습니다.

Open Stream →
#EAP7

[JBoss EAP 7] MS SQL Server Non-XA 데이터소스 연결 오류: connection-url 무시 현상 해결

JBoss EAP 7에서 MS SQL Server용 Non-XA Datasource를 설정할 때, <datasource-class> 태그를 사용하면 <connection-url> 설정이 무시되어 "Connection refused" 에러가 발생하는 현상을 해결합니다. 올바른 설정 방법은 무엇인지 정리합니다.

1. 문제 현상 (Issue)

MS SQL Server와 연결하기 위해 데이터소스를 설정하고 테스트 연결을 시도했으나, 아래와 같은 Connection refused 에러가 발생하며 실패합니다.

에러 로그

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 
The TCP/IP connection to the host localhost, port 1433 has failed. 
Error: "Connection refused. Verify the connection properties. ... Make sure that TCP connections to the port are not blocked by a firewall."

방화벽이나 DB 서버 상태는 정상이지만, JBoss가 localhost:1433(기본값)으로만 접속을 시도하거나 URL 정보를 전혀 읽지 못하는 상황입니다.


2. 원인 분석 (Root Cause)

이 문제는 JBoss의 데이터소스 설정 우선순위 메커니즘 때문에 발생합니다.

  • Non-XA 환경의 특성: JDBC 4 표준을 따르는 드라이버를 사용할 때, 일반적으로 java.sql.Driver 메커니즘(URL 방식)을 사용합니다.
  • 충돌 발생: 설정 파일(standalone.xml)에 <datasource-class>가 명시되면, JBoss는 이를 우선시하여 javax.sql.DataSource 구현체를 사용하려고 시도합니다.
  • 결과: 이 과정에서 <connection-url> 속성은 무시(Ignored)됩니다. 결과적으로 JDBC URL 정보가 전달되지 않아 연결에 실패하게 됩니다.

3. 해결 방법 (Resolution)

Non-XA 데이터소스 설정에서는 datasource-class를 제거하고, driver-classconnection-url 조합을 사용해야 합니다.

설정 파일 수정 (standalone.xml)

<datasource-class> 태그가 있는 라인을 삭제하십시오.

<datasource jndi-name="java:/mssql" pool-name="mssqljdbc" statistics-enabled="true">
    
    <connection-url>jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ucpost</connection-url>
    <driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
    
    <driver>sqlserver</driver>
    ...
</datasource>

4. 적용 및 검증 (Verification)

  1. 설정 파일 저장 후 JBoss를 재기동(Reload)합니다.
  2. 관리 콘솔 또는 CLI에서 데이터소스 연결 테스트(Test Connection)를 수행합니다.
  3. 정상적으로 Success 메시지가 뜨는지 확인합니다.
Tip: 만약 XA Datasource(분산 트랜잭션용)를 설정하는 경우에는 반대로 xa-datasource-class 설정이 필수적이며 URL 방식은 사용되지 않을 수 있습니다. 설정하려는 타입(XA vs Non-XA)을 명확히 구분해야 합니다.
Open Stream →
#EAP7

[JBoss EAP 7] 마이그레이션 이슈 해결: Apache CXF 라이브러리 충돌 (WFLYWS0059)

JBoss EAP 6.4에서 7.x로 마이그레이션 시, 애플리케이션에 포함된 Apache CXF 라이브러리와 JBoss 내부의 WebServices 서브시스템이 충돌하여 배포가 실패하는 현상(WFLYWS0059)을 해결합니다. jboss-deployment-structure.xml을 통한 모듈 제외(Exclude) 설정을 다룹니다.

1. 문제 현상 및 로그 분석 (Issue)

기존 EAP 6에서는 잘 돌던 애플리케이션이 EAP 7 배포 시 PARSE 단계에서 실패하며 아래와 같은 에러를 뱉어냅니다.

에러 로그

WFLYSRV0153: Failed to process phase PARSE of deployment "sso.war"
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: 
WFLYWS0059: Apache CXF library (cxf-api-2.7.8.jar) detected in ws endpoint deployment; 
either provide a proper deployment replacing embedded libraries with container module dependencies 
or disable the webservices subsystem for the current deployment adding a proper jboss-deployment-structure.xml descriptor to it.

원인 분석

  • JBoss EAP 7: 기본적으로 최신 Apache CXF 기반의 WebServices 서브시스템을 로드합니다.
  • 애플리케이션: WEB-INF/lib 안에 자체적인 CXF 라이브러리(예: cxf-api-2.7.8.jar)를 포함하고 있습니다.
  • 충돌: JBoss는 애플리케이션이 자체 라이브러리 대신 컨테이너가 제공하는 모듈을 사용하길 권장하며, 중복이 감지되면 배포를 중단시킵니다.

2. 해결 방법 (Resolution)

애플리케이션이 JBoss의 WebServices 기능을 사용하지 않고, "내가 가진 라이브러리를 쓰겠다"고 선언해야 합니다. 이를 위해 jboss-deployment-structure.xml 파일을 생성하여 컨테이너의 특정 서브시스템을 비활성화합니다.

설정 파일 위치

  • WAR 파일: WEB-INF/jboss-deployment-structure.xml
  • EAR 파일: META-INF/jboss-deployment-structure.xml

작성 내용

JBoss의 webservicesjaxrs 서브시스템을 제외(exclude)하고, 필요한 기본 API만 의존성(dependencies)으로 추가합니다.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
    <deployment>
        
        <!-- 1. JBoss 내부 서브시스템 비활성화 -->
        <exclude-subsystems>
            <!-- JBoss의 CXF 모듈이 로드되지 않도록 차단 -->
            <subsystem name="webservices" />
            <!-- RESTful 서비스 충돌 방지 (필요 시) -->
            <subsystem name="jaxrs" />
        </exclude-subsystems>
        
        <!-- 2. 필수 API 의존성 추가 -->
        <!-- 서브시스템은 뺐지만, 기본적인 Java EE API는 필요하므로 명시적 로드 -->
        <dependencies>
            <module name="javax.xml.ws.api"/>
            <module name="javax.jws.api"/>
        </dependencies>
        
    </deployment>
</jboss-deployment-structure>

3. 적용 결과 및 주의사항

  • 결과: 위 파일을 추가하고 재배포하면, JBoss는 해당 애플리케이션에 대해 WebServices 서브시스템 초기화를 건너뛰고 WEB-INF/lib 내의 jar 파일들을 우선적으로 로딩합니다.
  • 주의: 이 방식을 사용하면 JBoss 관리 콘솔에서 제공하는 웹 서비스 모니터링이나 관리 기능을 해당 애플리케이션에 대해서는 사용할 수 없게 됩니다. (애플리케이션 자체 프레임워크인 Spring-CXF 등이 전적으로 처리함)
Open Stream →
#EAP7

[JBoss EAP 7.2] Windows Service 등록 및 멀티 인스턴스 구성 가이드 (Jsvc, Port Offset)

JBoss EAP 7.2를 Windows 서비스로 등록하여 시스템 부팅 시 자동으로 실행되도록 설정합니다. Apache Jsvc를 활용한 서비스 등록 방법, 멀티 인스턴스 구성을 위한 포트 오프셋(Port Offset) 설정, 그리고 특수문자 패스워드 처리 팁을 정리합니다.

0. 사전 준비 (Prerequisites)

JBoss EAP 7부터는 서비스 등록을 위해 JBoss Core Services (JBCS) - Apache Jsvc 패키지가 필요할 수 있습니다. Red Hat 포털에서 해당 바이너리를 다운로드하여 준비합니다.

필수 다운로드 및 환경 변수

  • JBoss EAP 7.2: 설치 파일 압축 해제
  • Apache Jsvc: Windows용 바이너리 (sbin 폴더 내 prunsrv.exe 등 포함)
  • 환경 변수:
    • JAVA_HOME: JDK 설치 경로
    • NOPAUSE=1: 서비스 종료 시 배치 파일이 멈추지 않도록 필수 설정

1. 단일 인스턴스 서비스 등록

기본적으로 제공되는 service.bat 스크립트를 사용하여 서비스를 등록합니다.

등록 명령어

아래 명령어를 관리자 권한 CMD 창에서 실행합니다. 로그 경로(/logpath)는 미리 생성되어 있어야 합니다.

:: JBoss bin 디렉토리로 이동
cd %JBOSS_HOME%\bin

:: 서비스 등록 실행
service.bat install /name "JBoss7-Server01" ^
 /controller "localhost:9990" ^
 /config "standalone-ha.xml" ^
 /jbossuser "admin" ^
 /jbosspass "admin1@34" ^
 /logpath "E:\app\Redhat\waslog\testsvr01"
주의 (Password Special Characters):
비밀번호에 &, <, >, | 등의 특수문자가 포함된 경우 CMD 창에서 오류가 발생할 수 있습니다. 가능한 경우 특수문자를 피하거나, 쌍따옴표(")로 감싸고 이스케이프 문자(^)를 사용하는 등 주의가 필요합니다.

2. 멀티 인스턴스(Multi-Instance) 구성

하나의 장비에 여러 개의 JBoss 서비스를 등록할 때는 서비스 이름, 포트, 로그 경로가 겹치지 않아야 합니다.

Step 1: Port Offset 설정 (XML 수정)

service.bat의 파라미터로 포트 오프셋을 넘기는 것이 불안정할 수 있으므로, 설정 파일(standalone.xml) 자체를 수정하는 것을 권장합니다.

<socket-binding-group name="standard-sockets" default-interface="public" 
    port-offset="${jboss.socket.binding.port-offset:100}">
    </socket-binding-group>

Step 2: Jsvc 경로 수정 (필요 시)

멀티 인스턴스 환경에서 각 서버별로 다른 Jsvc 바이너리를 사용해야 하거나 경로가 특수한 경우, service.bat 파일을 열어 PRUNSRV 경로를 수동으로 지정해야 할 수 있습니다.

rem service.bat 파일 편집
set PRUNSRV=

rem 커스텀 경로 우선 확인 로직 예시
if exist "%JBOSS_HOME%\..\test01-jbcs-jsvc-1.1\sbin\prunsrv.exe" (
  set PRUNSRV="%JBOSS_HOME%\..\test01-jbcs-jsvc-1.1\sbin\prunsrv.exe"
) else if exist "%JBOSS_HOME%\bin\prunsrv.exe" (
  set PRUNSRV="%JBOSS_HOME%\bin\prunsrv.exe"
) else (
  echo Please install native utilities into expected location...
  goto cmdEnd
)

Step 3: 추가 인스턴스 등록

서비스 이름과 컨트롤러 포트, 로그 경로를 변경하여 등록합니다.

service.bat install /name "JBoss7-Server02" ^
 /controller "localhost:10090" ^
 /config "standalone-ha.xml" ^
 /jbossuser "admin" ^
 /jbosspass "admin1@34" ^
 /logpath "E:\app\Redhat\waslog\testsvr02"

3. 서비스 제어 및 삭제

등록된 서비스는 Windows 서비스 관리자(services.msc) 또는 명령어로 제어할 수 있습니다.

서비스 삭제 (Uninstall)

설정을 변경하거나 재등록할 경우 기존 서비스를 삭제해야 합니다. /name 옵션에 등록했던 서비스명을 정확히 입력합니다.

:: 서비스 중지
sc stop JBoss7-Server01

:: 서비스 삭제 (service.bat 이용)
service.bat uninstall /name "JBoss7-Server01"

4. 검증 (Verification)

  1. 서비스 실행: net start JBoss7-Server01
  2. 포트 확인: netstat -an | findstr "9990" (또는 오프셋이 적용된 포트)
  3. 로그 확인: 지정한 /logpath 경로에 로그 파일이 생성되는지 확인합니다.
Open Stream →
#JBoss

[JBoss EAP 7] JSESSIONID 형식 변경 이슈 분석 및 jvmRoute(Instance-ID) 설정 가이드

JBoss EAP 7 도입 시 JSESSIONID 뒤에 예상치 못한 문자열(서버명, 그룹명 등)이 붙거나 길이가 늘어나는 현상을 분석합니다. 이는 Undertow 엔진의 JvmRouteHandler 동작 방식 때문이며, 이를 제어하기 위한 설정 방법을 정리합니다.

1. 이슈 현상 및 원인 분석 (Context)

EAP 6와 EAP 7은 세션 ID를 생성하고 관리하는 방식에 차이가 있습니다. 특히 클러스터링 환경에서 Sticky Session(세션 고정)을 위해 ID 뒤에 붙이는 식별자(Route)의 기본 동작이 다릅니다.

버전별 차이점

구분 JBoss EAP 6.x (JBossWeb) JBoss EAP 7.x (Undertow)
Engine Apache Tomcat Fork Undertow
Format [ID].[jvmRoute] [ID].[instance-id]
Default 설정 없으면 ID만 생성하거나 Hostname 부착 강제로 jboss.node.name 부착

기술적 원인 (Undertow JvmRouteHandler)

EAP 7의 웹 엔진인 Undertow는 io.undertow.server.JvmRouteHandler를 통해 세션 ID를 처리합니다. 이 핸들러는 클러스터링 설정 여부와 관계없이, 설정된 instance-id가 있다면 무조건 세션 ID 뒤에 붙이도록 설계되어 있습니다. 또한, 이 값은 null이거나 비활성화(disable)할 수 없으며 기본적으로 노드 이름을 따라갑니다.


2. 해결 및 설정 방법 (Configuration)

JSESSIONID 뒤에 붙는 값을 제어하기 위해서는 undertow 서브시스템의 instance-id 속성을 명시적으로 변경해야 합니다.

설정 파일 수정 (standalone.xml / domain.xml)

Undertow 서브시스템 설정에서 instance-id 값을 원하는 식별자(기존 jvmRoute와 동일한 역할)로 지정합니다.

<subsystem xmlns="urn:jboss:domain:undertow:3.1">
    <buffer-cache name="default"/>
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
        <ajp-listener name="ajp" socket-binding="ajp"/>
        <host name="default-host" alias="localhost">
            ...
        </host>
    </server>
    
    <servlet-container name="default" default-session-timeout="30" instance-id="${jboss.node.name}" />
    
</subsystem>

CLI를 이용한 변경

운영 중인 환경에서 값을 변경하려면 관리 CLI를 사용하는 것이 안전합니다.

# instance-id를 'node1'으로 변경하는 예시
/subsystem=undertow/servlet-container=default:write-attribute(name=instance-id, value="node1")

# 설정 적용을 위해 리로드 필요
reload
주의 (Warning):
instance-id를 변경하면 기존에 발급된 세션 ID와 매핑이 달라지므로, 기존 사용자들의 세션이 끊길(Invalidate) 수 있습니다. 서비스 점검 시간에 수행하십시오.

3. 검증 (Verification)

설정 변경 후 애플리케이션을 호출하여 쿠키 값을 확인합니다.

개발자 도구 확인

  1. 브라우저 F12 (개발자 도구) 실행
  2. Application 탭 > Cookies 선택
  3. JSESSIONID의 값 확인

결과 예시:

  • 변경 전: abcde12345.server-one-instance-group-a (길고 복잡함)
  • 변경 후: abcde12345.node1 (설정한 값으로 깔끔해짐)

Next Step:
만약 앞단의 웹 서버(Apache/IHS)와 mod_cluster 또는 mod_jk로 연동 중이라면, 웹 서버 설정의 jvmRoute 값과 JBoss의 instance-id 값이 정확히 일치해야 스티키 세션(Sticky Session)이 정상 작동합니다. 반드시 양쪽 설정을 맞춰주세요.

Open Stream →