#Error

[JBoss EAP 7] 설치 오류 해결: java.lang.UnsupportedClassVersionError (JDK 버전 호환성)

JBoss EAP 7 설치 또는 기동 중 java.lang.UnsupportedClassVersionError가 발생한다면, 현재 서버에 설정된 Java 버전이 JBoss가 요구하는 최소 사양(JDK 1.8)보다 낮기 때문입니다. 에러 메시지의 major.minor version 숫자를 통해 원인을 분석하는 방법을 알아봅니다.

1. 문제 현상 및 원인 분석

JBoss 설치 스크립트 실행 시 아래와 같은 에러 로그가 출력되며 프로세스가 종료됩니다.

Exception in thread "main" java.lang.UnsupportedClassVersionError: 
com/ibm/websphere/... : Unsupported major.minor version 52.0
    at java.lang.ClassLoader.defineClass1(Native Method)
    ...

원인 (Root Cause)

이 에러는 컴파일된 클래스 파일의 버전(Target JVM)보다 현재 실행 중인 JVM 버전(Runtime)이 낮을 때 발생합니다.

  • JBoss EAP 7.x 요구사항: 최소 JDK 1.8 이상
  • 현재 서버 상황: JDK 1.7 이하가 설치되어 있거나 JAVA_HOME이 구버전을 가리키고 있음

2. 버전 매핑 테이블 (Class File Format)

에러 메시지에 뜨는 숫자(52.0, 51.0 등)는 Java 클래스 파일 포맷의 메이저 버전을 의미합니다. 아래 표를 참고하여 현재 필요한 Java 버전을 확인하십시오.

Java Version (SE) Major Version (Hex) Major Version (Dec)
Java 14 0x3A 58
Java 13 0x39 57
Java 12 0x38 56
Java 11 0x37 55
Java 9 0x35 53
Java 8 0x34 52
Java 7 0x33 51
Java 6 0x32 50
분석 예시:
에러 메시지가 Unsupported major.minor version 52.0이라면, 해당 프로그램은 Java 8로 컴파일되었으므로 서버에도 Java 8 이상이 설치되어야 합니다.

3. 해결 방법 (Solution)

1) 현재 Java 버전 확인

java -version

출력 결과가 1.7.x 이하라면 JDK 업그레이드가 필요합니다.

2) JDK 설치 및 환경 변수 변경

서버에 JDK 1.8 이상을 설치한 후, JBoss가 참조하는 설정 파일에서 JAVA_HOME 경로를 수정해야 합니다.

  • Standalone 모드: [EAP_HOME]/bin/standalone.conf (Windows는 .bat)
  • Domain 모드: [EAP_HOME]/bin/domain.conf (Windows는 .bat)
# standalone.conf 예시
# JAVA_HOME="/usr/lib/jvm/java-1.7.0"  <-- 기존 (주석 처리)
JAVA_HOME="/usr/lib/jvm/java-1.8.0"    <-- 신규 경로로 변경

Next Step:
JDK 버전을 올린 후에는 기존 애플리케이션(WAR/EAR)이 새 Java 버전에서 정상적으로 동작하는지, -Xmx 등 메모리 옵션이 변경된 버전에 맞게 설정되었는지 확인해야 합니다.

Open Stream →
#command

[Windows] CMD를 리눅스 터미널처럼: doskey를 이용한 Alias(매크로) 설정 및 영구 적용

Windows CMD 환경에서 ls, cp, rm 등 익숙한 Linux 명령어를 사용하기 위해 doskey 매크로를 설정하는 방법을 정리합니다. 배치 파일(alias.cmd)을 작성하고 레지스트리(AutoRun)에 등록하여 CMD 실행 시 자동으로 별칭이 적용되도록 구성합니다.

0. 배경 (Context)

Windows CMD는 기본적으로 dir, copy, del 등의 명령어를 사용합니다. Linux의 ls, cp 등에 익숙한 사용자는 매번 오타를 내거나 불편함을 겪게 됩니다. 이를 해결하기 위해 doskey 명령어를 사용하여 명령어의 별칭(Alias)을 지정할 수 있습니다.

Test Environment

  • OS: Windows 10 / 11
  • Shell: Command Prompt (CMD)

1. 매크로 파일 작성 (alias.cmd)

먼저, 매크로 정의를 담을 배치 파일을 생성합니다. 적당한 위치(예: C:\Utils\alias.cmd)에 파일을 만들고 아래 내용을 작성합니다.

Tip: $*는 입력된 모든 인자(Arguments)를 그대로 전달하겠다는 의미입니다. (예: ls -al 입력 시 dir -al로 변환)
@echo off

:: --- System & Utility ---
doskey alias   = doskey $*
doskey clear   = cls
doskey history = doskey /history
doskey man     = help $*

:: --- Process Management ---
doskey ps      = tasklist $*
doskey kill    = taskkill /PID $*

:: --- File & Directory Management ---
doskey ls      = dir $*
doskey ll      = dir $*
doskey cat     = type $*
doskey pwd     = cd
doskey cp      = copy $*
doskey mv      = move $*
doskey rm      = del $*

:: --- Search (grep -> findstr 권장) ---
:: find는 단순 문자열 검색, findstr은 정규식 지원
doskey grep    = find $* :: --- Permissions (Approximate) ---
doskey sudo    = runas /user:administrator $*

2. 레지스트리 등록 (영구 적용)

위에서 만든 alias.cmd 파일은 CMD를 켤 때마다 실행해줘야 하는 번거로움이 있습니다. 이를 자동화하기 위해 레지스트리의 AutoRun 기능을 사용합니다.

설정 경로 및 값

  • 경로: HKEY_CURRENT_USER\Software\Microsoft\Command Processor
  • 문자열 값(String Value): AutoRun
  • 데이터(Data): [alias.cmd 파일의 절대 경로]

등록 방법 A: 명령어로 한방에 등록 (권장)

관리자 권한으로 CMD를 열고 아래 명령어를 입력합니다. (경로는 본인 파일 위치에 맞게 수정하세요)

:: 경로 예시: E:\software\google\2_Shellscript\alias.cmd
reg add "HKCU\Software\Microsoft\Command Processor" /v AutoRun /t REG_SZ /d "E:\software\google\2_Shellscript\alias.cmd" /f

등록 방법 B: regedit 사용 (수동)

  1. Win + R 키를 누르고 regedit 실행
  2. 컴퓨터\HKEY_CURRENT_USER\Software\Microsoft\Command Processor 경로로 이동
  3. 우측 빈 공간 우클릭 > 새로 만들기 > 문자열 값 선택
  4. 이름을 AutoRun으로 지정
  5. 더블 클릭하여 값 데이터에 alias.cmd절대 경로 입력

3. 적용 확인 (Verification)

설정이 완료되었다면, 새로운 CMD 창을 열어서 리눅스 명령어가 작동하는지 확인합니다.

:: 1. CMD 실행
C:\Users\User>

:: 2. ls 명령어 테스트
C:\Users\User> ls
 C 드라이브의 볼륨에는 이름이 없습니다.
 ... (디렉토리 목록 출력) ...

:: 3. alias 목록 확인
C:\Users\User> alias /macros

Next Step:
만약 CMD가 아닌 PowerShell을 주로 사용하신다면, Microsoft.PowerShell_profile.ps1 파일에 Set-Alias 명령어를 추가하여 동일한 환경을 구축할 수 있습니다.

Open Stream →
#command

[Linux] 서버 관리 필수 명령어 모음: 로그 정리(find), 네트워크(netstat), 메모리 점검

리눅스 시스템 운영 중 로그 파일 정리, 디스크 용량 확보, 네트워크 연결 상태 점검, 메모리 사용률 확인을 위해 자주 사용하는 명령어 패턴(One-Liner)을 정리합니다. RedHat/CentOS 7 환경을 기준으로 작성되었습니다.

Test Environment

  • OS: CentOS 7, RedHat 7.2
  • Shell: Bash

1. 파일 검색 및 정리 (File Management)

서버 운영 중 가장 흔한 이슈는 로그 파일로 인한 디스크 풀(Disk Full)입니다. find 명령어를 사용하여 오래된 파일을 검색하고 삭제하는 패턴입니다.

최근 수정된 파일 찾기

설정 파일(xml 등)이 최근에 변경되었는지 확인할 때 사용합니다.

# 최근 7일 이내(-7)에 수정된 xml 파일 검색
find . -type f -name "*.xml" -mtime -7 -print

오래된 로그 파일 삭제

로그 디렉토리 관리를 위해 일정 기간이 지난 파일을 삭제합니다. 삭제 명령(rm)을 실행하기 전, 반드시 조회(ls)를 먼저 수행하여 대상을 검증해야 합니다.

# 1. 대상 확인 (7일이 지난 로그 파일 조회)
find /log/server1 -name "*.log" -mtime +7 -print

# 2. 삭제 실행 (방법 A: -delete 옵션 사용)
find /log/server1 -name "*.log" -mtime +7 -delete

# 2. 삭제 실행 (방법 B: -exec rm 사용, 가장 범용적)
find /log/server1 -name "*.log" -mtime +7 -exec rm -f {} \;

# 3. 30일 이상 된 로그 파일만 강제 삭제
find /log/server1 -type f -name "*.log" -ctime +30 -exec rm -rf {} \;

대용량 파일 검색

디스크 용량을 많이 차지하는 파일을 찾습니다.

# 3GB 이상인 파일을 찾아 용량과 함께 출력
find . -size +3000000k -exec ls -lh {} \+

날짜순 파일 정렬 보기

기본 ls -l의 날짜 포맷이 보기 힘들 때 ISO 포맷으로 변환하여 확인합니다.

ls --time-style="+%Y-%m-%d %H:%M:%S" -altr | grep ^- | more

2. 네트워크 상태 점검 (Network Monitoring)

웹 서버나 DB 서버의 현재 연결 상태를 확인하여 트래픽 스파이크나 연결 누수(Leak)를 점검합니다.

동시 접속자 수 확인 (Web Server)

ESTABLISHED 상태는 현재 연결이 수립되어 데이터를 주고받는 상태를 의미합니다.

# 80 포트 동시 접속자 수 카운트
netstat -nap | grep :80 | grep ESTABLISHED | wc -l

# 8080 포트(WAS) 동시 접속자 수 카운트
netstat -nap | grep :8080 | grep ESTABLISHED | wc -l

DB 연결 풀(Connection Pool) 확인

WAS에서 DB로 맺은 연결 개수를 확인합니다. 포트 번호로 grep하여 정렬합니다.

# 특정 포트와 연결된 소켓 정보 확인
netstat -anp | grep {port_number}

# 연결 개수 카운트
netstat -anp | grep {port_number} | wc -l

3. 메모리 사용률 점검 (Memory Check)

리눅스의 free 명령어는 버퍼/캐시 메모리를 포함하여 보여주기 때문에, 실제 애플리케이션이 사용하는 메모리(Actual Used)를 계산하기 위해서는 별도의 연산이 필요할 때가 있습니다.

메모리 계산 스크립트 (Shell)

전체 메모리 대비 실제 사용률을 백분율(%)로 계산하는 스크립트입니다.

#!/bin/sh
# free 명령어의 출력 컬럼 위치는 OS 버전에 따라 다를 수 있으므로 확인 필요 (awk $2, $3...)

# Total Memory
TOTAL=`free | grep ^Mem | awk '{print $2}'`

# Used Memory (OS 관점)
USED1=`free | grep ^Mem | awk '{print $3}'`

# Used Memory (Buffer/Cache 제외, CentOS 6 이하 구버전 방식)
# USED2=`free | grep ^-/+ | awk '{print $3}'`

# CentOS 7 이상 (available 컬럼 등 고려 필요하나 단순 계산 시)
# 버퍼/캐시를 포함한 단순 사용률
NOMINAL=$((100*USED1/TOTAL))

echo "Memory Usage: ${NOMINAL}%"

One-Liner (간편 계산)

awk를 사용하여 한 줄로 메모리 사용률을 출력합니다.

# 전체 메모리 대비 사용량(Used) 비율
awk '/^Mem/ {printf("Used: %u%%", 100*$3/$2);}' <(free -m)

# (참고) 버퍼/캐시를 제외한 실 사용률 계산은 free -m의 available 컬럼을 활용하는 것이 정확합니다.
free -m | awk 'NR==2{printf "Memory Usage: %.2f%%\n", ($3/$2)*100 }'

Next Step:
반복적으로 사용하는 위 명령어들을 ~/.bash_profilealias로 등록해두면, 긴 명령어를 타이핑하는 수고를 덜고 오타로 인한 사고를 방지할 수 있습니다.

Open Stream →
#Liberty

[WebSphere] Liberty Profile & Eclipse 연동 개발 환경 구축 가이드 (WDT 설치)

IBM WebSphere Liberty Profile(WLP)을 로컬 개발 환경인 Eclipse에 연동하여 애플리케이션 개발, 배포, 디버깅 환경을 구축하는 절차를 정리합니다. IBM WebSphere Developer Tools(WDT) 플러그인 설치 및 서버 런타임 구성 과정을 포함합니다.

Test Environment

  • OS: Windows 10
  • IDE: Eclipse IDE for Enterprise Java Developers (2020-06 이상 권장)
  • Middleware: WebSphere Liberty Profile (Kernel or Core)

1. 사전 준비 (Prerequisites)

Liberty 개발 환경을 구축하기 위해서는 Java SDK와 Eclipse가 미리 설치되어 있어야 합니다.

  • JDK: 1.8 이상 설치 및 환경 변수(JAVA_HOME) 설정.
  • Eclipse: 'Eclipse IDE for Enterprise Java and Web Developers' 패키지 사용 권장.

2. WebSphere Developer Tools (WDT) 플러그인 설치

Eclipse에서 Liberty 서버를 제어하기 위해서는 전용 플러그인을 설치해야 합니다.

설치 절차

  1. Eclipse 메뉴에서 Help > Eclipse Marketplace...를 선택합니다.
  2. 검색창에 IBM Liberty 또는 WebSphere Developer Tools를 입력합니다.
  3. "IBM Liberty Developer Tools" 항목을 찾아 Install 버튼을 클릭합니다.
  4. 라이선스 동의 후 설치를 진행하며, 완료 후 Eclipse를 재시작합니다.

3. Liberty 런타임(Runtime) 등록

이미 설치된 Liberty Core를 Eclipse에 등록하거나, Eclipse를 통해 새로 다운로드할 수 있습니다.

서버 등록 과정

  1. Servers 뷰에서 우클릭 > New > Server 선택.
  2. 서버 타입에서 IBM > WebSphere Liberty 선택.
  3. Server's host namelocalhost, Server name은 식별 가능한 이름 입력.
  4. Runtime Environment 설정 단계:
    • 기존 설치된 경우: 'Choose an existing installation' 선택 후 Liberty 설치 경로(wlp 폴더) 지정.
    • 새로 설치할 경우: 'Install from an archive or a repository' 선택 후 원하는 버전 다운로드.
  5. Finish를 클릭하여 설정을 완료합니다.

4. 서버 구동 및 애플리케이션 배포

설정이 완료되면 Eclipse 내에서 서버를 제어할 수 있습니다.

서버 제어

  • Start: Servers 뷰에서 서버 우클릭 > Start (또는 Debug).
  • Console 확인: CWWKF0011I: The server defaultServer is ready to run a smarter planet. 메시지가 뜨면 정상 구동된 것입니다.

프로젝트 배포

  1. Dynamic Web Project 생성.
  2. 프로젝트 우클릭 > Run As > Run on Server.
  3. 등록한 Liberty 서버를 선택하고 Finish.
  4. server.xml에 애플리케이션 구성이 자동으로 추가되며 배포가 진행됩니다.

5. 참고 영상 (Reference Video)

실제 설치 및 구동 과정에 대한 데모 영상입니다.


Next Step:
개발 환경 구축이 완료되었다면, server.xml 파일의 <featureManager> 섹션을 수정하여 필요한 기능(JSP, Servlet, JDBC 등)을 활성화하는 방법을 학습해 보십시오.

Open Stream →
#tomcat

[Tomcat] Windows 환경 Apache Tomcat 9 설치 및 디렉토리 구조 완벽 가이드

Windows 10 환경에서 Java 기반 웹 애플리케이션 서버인 Apache Tomcat 9을 설치하는 과정을 정리합니다. JDK 설치 확인부터 다운로드, 압축 해제, 그리고 주요 디렉토리(bin, conf, logs)의 역할과 구동 테스트까지 다룹니다.

0. 사전 준비 (Prerequisites)

Tomcat은 Java로 구동되므로 JDK(Java Development Kit)가 필수입니다. 설치 전 반드시 Java 환경 변수가 설정되어 있는지 확인해야 합니다.

Java 설치 확인

:: CMD 창에서 확인
java -version
javac -version
Check Point: 버전 정보가 출력되지 않는다면 JDK를 먼저 설치하고, 시스템 환경 변수(JAVA_HOME, PATH)를 설정해야 합니다. Tomcat은 실행 시 JAVA_HOME을 참조합니다.

1. 다운로드 및 설치 (Download & Install)

설치형(Installer)보다는 압축형(Zip)을 사용하는 것이 디렉토리 관리가 용이하고, 여러 버전을 동시에 관리하기 좋습니다.

다운로드

  • 공식 사이트: http://tomcat.apache.org/
  • 버전 선택: Tomcat 9 (Latest Stable) > Binary Distributions > Core: zip (64-bit/32-bit Windows)

설치 (압축 해제)

다운로드한 Zip 파일을 원하는 경로에 압축 해제하는 것만으로 설치는 끝납니다.

  • 설치 경로 예시: E:\APP\WAS\TOMCAT9

2. 주요 디렉토리 구조 (Directory Structure)

압축을 해제하면 다음과 같은 폴더 구조를 볼 수 있습니다. 각 폴더의 역할을 이해하는 것이 WAS 운영의 첫걸음입니다.

디렉토리 역할 및 주요 파일
/bin 서버 실행 및 종료 스크립트가 위치합니다.
- startup.bat: 서버 시작 (Windows)
- shutdown.bat: 서버 중지 (Windows)
- catalina.bat: 실행 환경 변수 및 옵션 설정
/conf 서버 전체 설정 파일이 위치합니다.
- server.xml: 포트(8080, 8009), 엔진 설정
- web.xml: 세션 타임아웃, MIME 타입 등 공통 설정
/lib Tomcat 구동에 필요한 라이브러리(Jar) 저장소 (JDBC 드라이버 등 포함)
/logs 서버 로그가 저장됩니다.
- catalina.yyyy-mm-dd.log: 엔진 로그
- localhost_access_log: 접속 로그
/webapps 웹 애플리케이션(WAR 파일)을 배포하는 기본 경로입니다.

3. 구동 및 검증 (Start & Verify)

설치가 제대로 되었는지 서버를 켜서 확인합니다.

서버 구동

:: bin 디렉토리로 이동
cd E:\APP\WAS\TOMCAT9\bin

:: 실행 스크립트 동작
startup.bat

새로운 CMD 창이 뜨면서 로그가 올라가고, 마지막에 Server startup in [xxx] ms 메시지가 보이면 구동 성공입니다.

접속 테스트

브라우저를 열고 http://localhost:8080 에 접속합니다. 고양이 그림이 있는 Tomcat 기본 페이지가 뜬다면 정상적으로 설치된 것입니다.


Next Step:
기본 설치가 완료되었습니다. 다음 포스팅에서는 server.xml을 수정하여 HTTP 포트를 변경하거나, 인코딩 설정을 추가하는 Tomcat 기본 설정 튜닝에 대해 알아보겠습니다.

Open Stream →
#IBM HTTPServer

[IHS] SSL/TLS 보안 강화: Protocol 비활성화 및 Cipher Suite 화이트리스트 설정

IBM HTTP Server(IHS)는 Apache 기반이지만, SSL 모듈은 별도의 mod_ibm_ssl을 사용합니다. 따라서 커뮤니티 Apache(mod_ssl)와 프로토콜 설정 문법이 상이합니다. 두 서버 간의 설정 차이를 비교하고, IHS v8.5 환경에서의 보안 강화 설정을 정리합니다.

[Image of SSL TLS handshake process]

1. Apache vs IHS 설정 차이점 (Comparison)

두 웹 서버는 SSL/TLS 핸드쉐이크를 처리하는 엔진과 모듈이 다르기 때문에, httpd.conf에 작성하는 지시어(Directive)가 다릅니다. 마이그레이션이나 운영 시 혼동하지 않도록 주의해야 합니다.

구분 Apache HTTP Server (Community) IBM HTTP Server (IHS)
사용 모듈 mod_ssl (OpenSSL 기반) mod_ibm_ssl (IBM GSKit 기반)
프로토콜 설정 SSLProtocol (한 줄로 제어) SSLProtocolDisable
SSLProtocolEnable (개별 제어)
Cipher 설정 SSLCipherSuite SSLCipherSpec

설정 문법 비교 예시

Apache (mod_ssl)

# 모든 프로토콜에서 SSLv2, SSLv3 제외
SSLProtocol all -SSLv2 -SSLv3

# Cipher Suite 설정 (OpenSSL 명명규칙 사용)
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5

IHS (mod_ibm_ssl)

# 개별적으로 활성/비활성 지정
SSLProtocolDisable SSLv2
SSLProtocolDisable SSLv3
SSLProtocolEnable TLSv12

# Cipher Spec 설정 (Long Name 사용, 초기화 후 추가 방식 권장)
SSLCipherSpec ALL NONE
SSLCipherSpec ALL +TLS_RSA_WITH_AES_128_CBC_SHA

2. IHS 보안 설정 가이드 (Configuration)

IHS v8.5 이상 환경에서 취약한 프로토콜을 차단하고 안전한 Cipher만 허용하는 설정입니다.

LoadModule ibm_ssl_module modules/mod_ibm_ssl.so
Listen 443

# IP 기반 가상 호스트 활성화 (IHS 8.5 이하 필수)
NameVirtualHost *:443

<VirtualHost *:443>
    ServerName www.example.com
    DocumentRoot /app/EAR/SSL
    
    # SSL 엔진 활성화
    SSLEnable
    
    # 1. 취약 프로토콜 명시적 비활성화
    # (TLS 1.0, 1.1도 보안 정책에 따라 차단 고려)
    SSLProtocolDisable SSLv2
    SSLProtocolDisable SSLv3
    SSLProtocolDisable TLSv10
    SSLProtocolDisable TLSv11
    
    # 2. 안전한 프로토콜 활성화
    SSLProtocolEnable TLSv12
    
    # 3. Cipher Suite 화이트리스트 설정
    # 중요: 'ALL NONE'으로 기존 설정 초기화
    SSLCipherSpec ALL NONE
    
    # Forward Secrecy(PFS)를 지원하는 ECDHE 계열 우선 배치
    SSLCipherSpec ALL +TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    SSLCipherSpec ALL +TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    
    # 호환성을 위한 RSA/AES 계열 추가
    SSLCipherSpec ALL +TLS_RSA_WITH_AES_256_CBC_SHA +TLS_RSA_WITH_AES_128_CBC_SHA
</VirtualHost>

KeyFile /SW/web/HTTPServer/key/key.kdb
SSLDisable

3. 설정 검증 (Verification)

설정 적용 후 IHS를 재기동하기 전, 명령어를 통해 적용된 Cipher 목록을 확인합니다.

적용된 Cipher 확인

cd [IHS_HOME]/bin
./apachectl -t -D DUMP_SSL_CONFIG

접속 테스트 (nmap)

외부에서 스캔하여 취약한 프로토콜(SSLv3 등)이 노출되지 않는지 교차 검증합니다.

nmap --script ssl-enum-ciphers -p 443 [Target_IP]

Next Step:
IHS 9.0 (Apache 2.4 기반)으로 업그레이드할 경우, SSLProtocol 지시어를 Apache 스타일로 사용할 수 있게 되지만, 기존 IHS 설정과의 호환성을 위해 IBM 문서를 반드시 참조하시기 바랍니다.

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 →
#command

[Linux] CentOS 7 호스트네임(Hostname) 영구 변경 및 필수 후속 조치 (hostnamectl)

CentOS 7 및 systemd 기반 리눅스 시스템에서 hostnamectl 명령어를 사용하여 호스트네임을 영구적으로 변경하는 방법을 정리합니다. 변경 후 쉘 프롬프트에 즉시 반영하는 방법과 /etc/hosts 파일 수정의 중요성을 포함합니다.

0. 배경 지식 (Context)

호스트네임은 네트워크 상에서 서버를 식별하는 이름입니다. 과거에는 /etc/sysconfig/network 파일을 수정하고 재부팅해야 했으나, CentOS 7부터는 hostnamectl 명령어를 통해 재부팅 없이 즉시 설정을 영구 반영할 수 있습니다.

Test Environment

  • OS: CentOS 7.2
  • System: systemd based

1. 호스트네임 변경 (hostnamectl)

hostnamectl 명령은 커널 호스트네임 설정과 /etc/hostname 파일 수정을 동시에 수행합니다.

현재 상태 확인

hostnamectl status

변경 명령어

# 구문: hostnamectl set-hostname [새로운_이름]
hostnamectl set-hostname web-server-01

2. 변경 사항 확인 및 적용 (Verification)

명령어 실행 즉시 시스템 설정은 변경되지만, 현재 로그인된 터미널의 프롬프트(Shell Prompt)에는 반영되지 않을 수 있습니다.

변경 확인

# 1. 설정값 확인
hostname

# 2. 상세 확인
hostnamectl status

터미널 프롬프트 갱신

로그아웃 후 다시 로그인(Reconnect)하면 프롬프트가 변경됩니다. 재접속 없이 바로 확인하려면 아래 명령어를 사용하세요.

# 현재 쉘 세션 갱신
exec bash

결과: [root@old-name ~]# 에서 [root@web-server-01 ~]# 로 변경됨.


3. 필수 후속 조치: /etc/hosts 수정

호스트네임을 변경했다면, 서버 자신이 자신의 이름을 찾아갈 수 있도록 로컬 DNS 설정 파일인 /etc/hosts도 반드시 수정해야 합니다. 이를 누락하면 sudo 명령어 실행이 느려지거나 일부 애플리케이션 기동 시 에러가 발생할 수 있습니다.

파일 수정

vi /etc/hosts

수정 내용

기존 호스트네임이 적힌 부분을 새로운 이름으로 변경하거나 추가합니다.

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# 변경된 호스트네임 추가 (자신의 IP 또는 Loopback에 매핑)
127.0.0.1   web-server-01
Tip: 클러스터링(Cluster) 환경이나 WAS(WebSphere, JBoss) 환경에서는 127.0.0.1 대신 실제 서버의 공인 IP(또는 사설 IP)에 호스트네임을 매핑하는 것이 좋습니다.
Open Stream →
#IBM HTTPServer

[IBM HTTPServer] SSL/TLS 암호화 슈트(Cipher Suite) 확인 및 점검 방법 (DUMP_SSL_CIPHERS)

IBM HTTP Server(IHS)에서 현재 적용된 SSL/TLS 프로토콜 버전과 지원하는 암호화 슈트(Cipher Suite) 목록을 확인하는 방법을 정리합니다. apachectl의 진단 옵션을 통해 서버에 설정된 보안 수준을 점검할 수 있습니다.

0. 배경 지식 (Context)

보안 취약점 점검 시 "SSLv3나 RC4 같은 약한 암호화 알고리즘을 비활성화하라"는 권고를 자주 받습니다. 조치를 취하기 전에, 현재 웹 서버가 어떤 알고리즘을 허용하고 있는지 정확히 파악하는 것이 우선입니다.

Test Environment

  • OS: CentOS 7.2
  • Web Server: IBM HTTPServer v8.5.0.0

1. Cipher Suite 확인 명령어

IHS는 apachectl 실행 스크립트에 -t(문법 검사) 옵션과 함께 -D DUMP_SSL_CIPHERS 정의를 추가하여, 현재 설정된 SSL 구성을 출력하는 기능을 제공합니다.

명령어 실행

cd [IHS_HOME]/bin

# SSL Cipher 설정 덤프
./apachectl -t -D DUMP_SSL_CIPHERS

결과 출력 예시 (Default 상태)

별도의 보안 설정(Hardening)이 되어 있지 않다면, 아래와 같이 IHS 버전의 기본값(Default)들이 출력됩니다.

SSL default cipher lists:
SSL protocol SSLV2, FIPS off, defaults = (None)
SSL protocol SSLV3, FIPS off, defaults = TLS_RSA_WITH_AES_128_CBC_SHA(2F), ...
SSL protocol TLSv10, FIPS off, defaults = TLS_RSA_WITH_AES_128_CBC_SHA(2F), ...
SSL protocol TLSv11, FIPS off, defaults = TLS_RSA_WITH_AES_128_CBC_SHA(2F), ...
SSL protocol TLSv12, FIPS off, defaults = TLS_RSA_WITH_AES_128_GCM_SHA256(9C), ...
Syntax OK
해석 주의 (Analysis):
위 출력 결과에 SSLV3 항목이 보인다면, 현재 서버는 보안에 취약한 SSLv3 프로토콜 통신을 허용하고 있다는 뜻입니다. 보안 강화를 위해 비활성화가 필요합니다.

2. 외부 도구를 이용한 교차 검증 (Verification)

서버 내부 설정뿐만 아니라, 외부에서 실제로 접속을 시도하여 어떤 Cipher가 노출되는지 확인하는 것이 가장 정확합니다.

1) nmap 사용 (Linux)

nmap의 스크립트 엔진을 사용하여 지원하는 Cipher 목록을 조회합니다.

nmap --script ssl-enum-ciphers -p 443 [서버IP]

2) OpenSSL 사용

특정 프로토콜로 접속이 되는지 테스트합니다.

# SSLv3 접속 시도 (접속 실패해야 안전함)
openssl s_client -connect [서버IP]:443 -ssl3

3. 보안 설정 강화 (Next Step)

취약한 프로토콜과 Cipher를 확인했다면, httpd.conf 파일에서 이를 차단해야 합니다.

설정 예시 (httpd.conf)

IHS에서는 SSLCipherSpec 지시어를 사용하여 특정 Cipher를 허용하거나 차단합니다.

<VirtualHost *:443>
    SSLEnable
    
    # 1. 취약한 프로토콜 비활성화 (TLS 1.2만 허용 권장)
    SSLProtocolDisable SSLv2 SSLv3 TLSv10 TLSv11
    SSLProtocolEnable TLSv12

    # 2. 강력한 Cipher Suite만 허용 (예시)
    # 128비트 미만 차단, RC4/MD5 차단
    SSLCipherSpec TLS_RSA_WITH_AES_128_CBC_SHA
    SSLCipherSpec TLS_RSA_WITH_AES_256_CBC_SHA
    # 필요에 따라 추가...
</VirtualHost>

4. 참고 자료 (References)

Open Stream →
#JBoss

[JBoss EAP 6] 커스텀 기동/정지 스크립트 작성 가이드 (Config 분리 및 JVM 튜닝)

JBoss EAP 6 Standalone 모드의 운영 효율성을 높이기 위해, JVM 옵션과 환경 변수를 별도의 설정 파일(Config Shell)로 분리하고 이를 로드하여 서버를 제어(Start/Stop/Status)하는 커스텀 쉘 스크립트 작성법을 공유합니다.

Test Environment

  • OS: CentOS 7.2
  • Middleware: JBoss EAP 6.4

1. 스크립트 구조 및 전략

유지보수성과 확장성을 위해 스크립트를 두 개의 파일로 분리합니다.

  1. Config Script (config1.sh): JVM 옵션, 경로, IP, 포트 등 변수 정의.
  2. Control Script (jboss_ctl.sh): Config를 로드하여 실제 프로세스를 제어하는 로직.

2. 설정 스크립트 (config1.sh)

서버 인스턴스별 고유한 설정을 이곳에 정의합니다. JAVA_OPTS를 통해 메모리 및 GC 로그 설정을 상세하게 튜닝할 수 있습니다.

#!/bin/sh
DATE=`date +%Y%m%d%H%M%S`

##### 1. Basic Configuration #####
export JBOSS_HOME=/SW/was/JBoss
export SERVER_HOME=/SW/was/JBoss/TEST/TESTServer11
export LOG_PATH=/app/logs/was
export NODE_NAME=TESTServer11
export CONFIG_FILE=standalone-ha.xml

# Network & Port Offset
export SERVER_IP=10.252.16.25
export PORT_OFFSET=750
export MGMT_ADDR=$SERVER_IP

# Controller Port Calculation (Base 9999 + Offset)
let CONTROLLER_PORT=9999+$PORT_OFFSET
export CONTROLLER_PORT

# Admin User (Shutdown용)
export USER=admin

##### 2. JVM Options (Memory & GC) #####
# Heap Memory
export JAVA_OPTS="-server -Xms1024m -Xmx2048m -XX:MaxPermSize=256m"

# GC Logging
export JAVA_OPTS=" $JAVA_OPTS -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails "
export JAVA_OPTS=" $JAVA_OPTS -Xloggc:$LOG_PATH/log/gclog/gc_$DATE.log "

# GC Algorithm (ParallelGC)
export JAVA_OPTS=" $JAVA_OPTS -XX:+UseParallelGC -XX:+ExplicitGCInvokesConcurrent"

# Heap Dump on OOM
export JAVA_OPTS=" $JAVA_OPTS -XX:-HeapDumpOnOutOfMemoryError "
export JAVA_OPTS=" $JAVA_OPTS -XX:HeapDumpPath=$LOG_PATH/heap/$NODE_NAME "

##### 3. System Properties (-D options) #####
export JAVA_OPTS=" $JAVA_OPTS -Djava.net.preferIPv4Stack=true"
export JAVA_OPTS=" $JAVA_OPTS -Dorg.jboss.resolver.warning=true"
export JAVA_OPTS=" $JAVA_OPTS -Djava.awt.headless=true"
export JAVA_OPTS=" $JAVA_OPTS -DjvmRoute=$NODE_NAME"

# JBoss Path & Binding
export JAVA_OPTS=" $JAVA_OPTS -Djboss.server.base.dir=$SERVER_HOME"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.server.log.dir=$LOG_PATH/$NODE_NAME"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.socket.binding.port-offset=$PORT_OFFSET"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.node.name=$NODE_NAME"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.bind.address.management=$MGMT_ADDR"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.bind.address=$SERVER_IP"

# Clustering (Multicast)
export JAVA_OPTS=" $JAVA_OPTS -Djboss.default.jgroups.stack=tcp"
# export JAVA_OPTS=" $JAVA_OPTS -Djboss.default.multicast.address=230.1.0.1"

echo "Configuration Loaded: $NODE_NAME"

3. 제어 스크립트 (jboss_ctl.sh)

실제 기동 및 정지를 담당하는 메인 스크립트입니다. ./config/config1.sh를 로드하여 변수들을 가져옵니다.

#!/bin/sh

# Config 파일 로드 (경로 주의)
. ./config/config1.sh

start(){
    # 프로세스 중복 실행 방지
    PID=`ps -ef | grep java | grep "jboss.node.name=$NODE_NAME " | awk '{print $2}'`
    
    if [ "x$PID" != "x" ]; then
        echo "###############################################"
        echo "ERROR: JBoss SERVER ($NODE_NAME) is already RUNNING (PID=$PID)"
        echo "###############################################"
        exit 1
    fi

    echo "#######################"
    echo "   Starting JBoss EAP  "
    echo "#######################"
    
    # nohup으로 백그라운드 실행, 로그 리다이렉션
    nohup $JBOSS_HOME/bin/standalone.sh --server-config=$CONFIG_FILE >> $LOG_PATH/console.log 2>&1 &

    echo "Starting... Wait for checking status..."
    sleep 5
    status
}

stop(){
    echo "#######################"
    echo "    Stopping JBoss     "
    echo "#######################"
    
    # 보안을 위해 패스워드는 입력받도록 처리 (자동화 시 변수로 대체 가능)
    echo -n "Enter Controller Password: "
    read -s PASSWORD
    echo ""

    # CLI를 이용한 안전한 종료 (Graceful Shutdown)
    $JBOSS_HOME/bin/jboss-cli.sh --connect --controller=$SERVER_IP:$CONTROLLER_PORT --command=:shutdown --user=$USER --password=$PASSWORD
}

status() {
    # 포트 리슨 상태로 구동 여부 확인
    _up=`netstat -an | grep $CONTROLLER_PORT | grep LISTEN | wc -l`
    
    if [ "$_up" -ne 0 ]; then
        PID=`ps -ef | grep java | grep "jboss.node.name=$NODE_NAME " | awk '{print $2}'`
        echo "###############################################"
        echo " JBoss Server is RUNNING !! "
        echo " Node: $NODE_NAME (PID: $PID)"
        echo " Port: $CONTROLLER_PORT (Management)"
        echo "###############################################"
    else
        echo "##################################"
        echo " JBoss Server is STOPPED !! "
        echo " Node: $NODE_NAME "
        echo "##################################"
    fi
}

# 파라미터 처리
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  restart)
    stop
    sleep 5
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart}"
    exit 1
esac
exit 0

4. 사용 방법 및 주의사항

사용법

# 실행 권한 부여
chmod +x jboss_ctl.sh

# 기동
./jboss_ctl.sh start

# 상태 확인
./jboss_ctl.sh status

# 정지 (패스워드 입력 필요)
./jboss_ctl.sh stop
Tip: config1.sh 파일 내의 PORT_OFFSET 변수를 활용하면, 하나의 물리 서버에서 포트 충돌 없이 여러 개의 인스턴스를 띄울 수 있습니다. (예: 0, 100, 200...)
Open Stream →