Summary: WebSphere Liberty(Open Liberty) ํ๊ฒฝ์์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด ์กฐ์ ๊ฐ๋ฅํ ์ฃผ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฆฌํ ๋ฌธ์์ ๋๋ค. JVM ํ ์ค์ ๋ถํฐ Connection Pool, Executor, ๊ทธ๋ฆฌ๊ณ ์ ํด ์์ ๊ด๋ฆฌ๊น์ง
server.xml๋ฐjvm.options๋ฅผ ํตํ ํ๋ ํฌ์ธํธ๋ฅผ ๋ค๋ฃน๋๋ค.
WebSphere Liberty๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์๊ฐ ํ๋(Self-tuning) ๊ธฐ๋ฅ์ ๊ฐ์ถ๊ณ ์์ผ๋, ์ด์ ํ๊ฒฝ์ ํน์ฑ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํฌ๋ก๋ ํจํด์ ๋ฐ๋ผ ๋ช ์์ ์ธ ์ค์ ๋ณ๊ฒฝ์ด ํ์ํ ์ ์์ต๋๋ค. ๋ณธ ๋ฌธ์๋ IBM Documentation์ ๊ธฐ๋ฐ์ผ๋ก ์ฑ๋ฅ์ ์ง์ ์ ์ธ ์ํฅ์ ์ฃผ๋ ํต์ฌ ์์ฑ๋ค์ ์ ๋ฆฌํ์ต๋๋ค.
1. JVM Tuning
๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ด๋ฉฐ ์ค์ํ ๋จ๊ณ์
๋๋ค. ${server.config.dir}/jvm.options ํ์ผ์ ์ฌ์ฉํ์ฌ ์ค์ ํฉ๋๋ค.
- ๊ฐ๋ฐ ํ๊ฒฝ: ๋น ๋ฅธ ์๋ฒ ์์์ ์ํด ์ต์ ํ(Min Heap)์ ์๊ฒ, ์ต๋ ํ(Max Heap)์ ํ์ํ ๋งํผ ์ค์ .
- ์ด์ ํ๊ฒฝ: ๋ฐํ์ ์ค ํ ํฌ๊ธฐ ์กฐ์ (Expansion/Contraction)์ ๋ฐ๋ฅธ ์ค๋ฒํค๋๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํด ์ต์ ํ๊ณผ ์ต๋ ํ์ ๋์ผํ ๊ฐ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
2. Transport Channel Service Tuning
ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ, HTTP I/O ์ฒ๋ฆฌ, ์ค๋ ๋ ํ ๋ฐ ์ฐ๊ฒฐ ํ ๊ด๋ฆฌ๋ฅผ ๋ด๋นํ๋ ์์ญ์
๋๋ค. server.xml์์ ์ค์ ํฉ๋๋ค.
HTTP Options
SSL ํธ๋์ ฐ์ดํฌ ๋น์ฉ์ด ๋๊ฑฐ๋ ์ฒ๋ฆฌ๋์ด ์ค์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ ์ง์์ ์ฐ๊ฒฐ(Persistent Connection) ์ค์ ์ ์ต์ ํํด์ผ ํฉ๋๋ค.
maxKeepAliveRequests: ๋จ์ผ HTTP ์ฐ๊ฒฐ์์ ํ์ฉ๋๋ ์ต๋ ์์ฒญ ์์ ๋๋ค.-1๋ก ์ค์ ์ ๋ฌด์ ํ์ ์๋ฏธํ๋ฉฐ, ์ฐ๊ฒฐ ๋งบ๋ ๋น์ฉ์ ์ ๊ฐํ ์ ์์ต๋๋ค.
<httpOptions maxKeepAliveRequests="-1" />
Connection Manager
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ํ(Connection Pool) ์ฑ๋ฅ์ ๊ฒฐ์ ์ง๋ ํต์ฌ ์์ฑ์ ๋๋ค.
maxPoolSize: ์ต๋ ์ค์ ์ฐ๊ฒฐ ์ (Default: 50). ๋ชจ๋ ์ค๋ ๋๊ฐ DB ์ฐ๊ฒฐ์ ํ์๋ก ํ๋ค๋ฉดcoreThreads์ 1:1 ๋งคํ์ ๊ณ ๋ คํ์ญ์์ค.purgePolicy: Stale Connection ๋ฐ๊ฒฌ ์ ์ฒ๋ฆฌ ์ ์ฑ . ๊ธฐ๋ณธ๊ฐ์EntirePool์ด๋,FailingConnectionOnly๋ก ์ค์ ํ์ฌ ์คํจํ ์ฐ๊ฒฐ๋ง ์ ๊ฑฐํ๋ ๊ฒ์ด ํจ์จ์ ์ ๋๋ค.numConnectionsPerThreadLocal: ์คํ ์ค๋ ๋๋ณ๋ก DB ์ฐ๊ฒฐ์ ์บ์ฑํ์ฌ ๋ฝ ๊ฒฝํฉ(Contention)์ ์ค์ ๋๋ค. ๋ฉํฐ ์ฝ์ด ์์คํ ์์ ์ฑ๋ฅ ํฅ์์ ์ ๋ฆฌํฉ๋๋ค.
<connectionManager id="defaultConnectionManager"
maxPoolSize="40"
purgePolicy="FailingConnectionOnly"
numConnectionsPerThreadLocal="1" />
Note:
numConnectionsPerThreadLocal์ฌ์ฉ ์,maxPoolSize๋ (์ ํ๋ฆฌ์ผ์ด์ ์ค๋ ๋ ์ × ์ค๋ ๋๋น ์ฐ๊ฒฐ ์) ์ด์์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
3. Data Source Optimization
DB ์ฟผ๋ฆฌ ์ฑ๋ฅ ๋ฐ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ์์ค์ ์กฐ์ ํฉ๋๋ค.
Statement Cache
PreparedStatement ์บ์ฑ์ ํตํด ํ์ฑ ๋น์ฉ์ ์ค์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉํ๋ ๊ณ ์ ํ SQL ๋ฌธ์ฅ ์๋ณด๋ค ํฌ๊ฒ ์ค์ ํด์ผ ํฉ๋๋ค.
<dataSource ... statementCacheSize="60" > ... </dataSource>
Isolation Level
๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ๊ณผ ๋์์ฑ(Concurrency)์ ํธ๋ ์ด๋์คํ ๊ด๊ณ์
๋๋ค. isolationLevel ์์ฑ์ผ๋ก ์กฐ์ ํฉ๋๋ค.
TRANSACTION_READ_UNCOMMITTED: ์ฑ๋ฅ ์ต์, ๋ฌด๊ฒฐ์ฑ ์ต์ (Dirty Read ๋ฐ์).TRANSACTION_READ_COMMITTED: Dirty Read ๋ฐฉ์ง.TRANSACTION_REPEATABLE_READ: Dirty/Non-repeatable Read ๋ฐฉ์ง.TRANSACTION_SERIALIZABLE: ์ฑ๋ฅ ์ต์ , ๋ฌด๊ฒฐ์ฑ ์ต์ (์์ ํ ์ง๋ ฌํ).
4. Executor (Thread Pool) Tuning
Liberty์ Executor๋ ์ํฌ๋ก๋์ ๋ฐ๋ผ ์ค๋ ๋๋ฅผ ๋์ ์ผ๋ก ์กฐ์ ํ๋ ์๊ฐ ํ๋ ๋ก์ง์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ๊ธฐ๋ณธ ์์น: ํน๋ณํ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ์ค์ ์ ๋ณ๊ฒฝํ์ง ์๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
- ์์ธ ์ํฉ: ๊ต์ฐฉ ์ํ(Deadlock) ํด๊ฒฐ ๋ก์ง์ด ๊ณผ๋ํ๊ฒ ์๋ํ๊ฑฐ๋, ์์คํ
์์ ํ๊ณ๋ก ์ค๋ ๋ ์๋ฅผ ์ ํํด์ผ ํ ๊ฒฝ์ฐ
coreThreads๋ฐmaxThreads๋ฅผ ๋ช ์ํฉ๋๋ค.
5. Reducing Overhead & Startup Time
๋ถํ์ํ CPU ์ฌ์ดํด์ ์ค์ด๊ณ ๊ธฐ๋ ์๊ฐ์ ๋จ์ถํ๊ธฐ ์ํ ์ค์ ์ ๋๋ค.
Servlet Response Time
WebContainer๊ฐ ์ ์ ๋ฆฌ์์ค ์ฒ๋ฆฌ๋ฅผ ์ํด META-INF ๋๋ ํ ๋ฆฌ๋ฅผ ์ค์บํ๋ ๊ณผ์ ์ ์๋ตํฉ๋๋ค.
<webContainer skipMetaInfResourcesProcessing="true"/>
Idle Server CPU
์ด์ ํ๊ฒฝ์์๋ ๋น๋ฒํ ์ ํ๋ฆฌ์ผ์ด์ /๊ตฌ์ฑ ํ์ผ ๋ณ๊ฒฝ ๊ฐ์ง๊ฐ ๋ถํ์ํ๋ฏ๋ก, ๋ชจ๋ํฐ๋ง ์ฃผ๊ธฐ๋ฅผ ๋นํ์ฑํํ๊ฑฐ๋ ๋๋ฆฝ๋๋ค.
<!-- ์์ ๋นํ์ฑํ (๊ถ์ฅ) -->
<applicationMonitor dropinsEnabled="false" updateTrigger="disabled"/>
<config updateTrigger="disabled"/>
<!-- ํน์ MBean ํธ๋ฆฌ๊ฑฐ๋ก ๋ณ๊ฒฝ ๋ฐ ํด๋ง ์ฃผ๊ธฐ ์ํ -->
<applicationMonitor updateTrigger="mbean" pollingRate="60s"/>
<config updateTrigger="mbean" monitorInterval="60s"/>
CDI 1.2 Scanning
CDI 1.2 ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ์์นด์ด๋ธ๋ฅผ ์ค์บํฉ๋๋ค. ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ธฐ๋ ์๋ ์ ํ์ ์ฃผ์์ธ์ด ๋๋ฏ๋ก, ์์์ ์ค์บ(Implicit Bean Archives)์ ๋นํ์ฑํํฉ๋๋ค.
<cdi12 enableImplicitBeanArchives="false"/>
Next Step: ์ ์ค์ ๋ค์ ์ํฌ๋ก๋์ ํน์ฑ์ ๋ฐ๋ผ ํจ๊ณผ๊ฐ ๋ค๋ฆ ๋๋ค. ์ด์ ํ๊ฒฝ ์ ์ฉ ์ , ๋ถํ ํ ์คํธ๋ฅผ ํตํด ๊ฐ ํ๋ผ๋ฏธํฐ ๋ณ๊ฒฝ์ ๋ฐ๋ฅธ ์ฒ๋ฆฌ๋(Throughput)๊ณผ ์๋ต ์๊ฐ ๋ณํ๋ฅผ ์ธก์ ํ์๊ธฐ ๋ฐ๋๋๋ค.
[WebSphere] Liberty Cluster: End-to-End ๊ตฌ์ถ ๋ฐ ๊ตฌ์ฑ ๊ฐ์ด๋
Summary: WebSphere Liberty Profile(WLP)์ Collective ๋ฐ Cluster ๊ธฐ๋ฅ์ ํ์ฉํ ์ธํ๋ผ ๊ตฌ์ถ ๊ฐ์ด๋์ ๋๋ค. Controller ๊ตฌ์ฑ๋ถํฐ Member ์กฐ์ธ, ํด๋ฌ์คํฐ๋ง ์ค์ ๋ฐ ํธ๋ฌ๋ธ์ํ ๊น์ง์ ์ ์ฒด ๊ณผ์ ์ ๋ค๋ฃน๋๋ค.
WebSphere Application Server Liberty Profile(WLP)์ ๊ฒฝ๋ํ๋ ๊ตฌ์กฐ์ ํ์ฅ์ฑ ๋๋ถ์ ์ฑํ๋ฅ ์ด ๋์์ง๊ณ ์์ต๋๋ค. ๋ณธ ํฌ์คํธ๋ WLP Collective์ Clustering ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ํ์ฅ ๊ฐ๋ฅํ ํ ํด๋ก์ง๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋จ๊ณ๋ณ๋ก ์ ๋ฆฌํ ์์ง๋์ด๋ง ๋ ธํธ์ ๋๋ค.
์ด ์๋ฆฌ์ฆ๋ ๋ค์ ์์๋ก ์งํ๋ฉ๋๋ค.
- How to Create and Configure WebSphere Liberty Cluster End-to-End (Current)
- How to Deploy Application in WebSphere Liberty Cluster
- How to Setup Front-End Web Server for WebSphere Liberty Cluster
1. Topology Architecture
์ด ๊ฐ์ด๋์์๋ Collective Controller 1๋์ Collective/Cluster Member 2๋๋ก ๊ตฌ์ฑ๋ ํ ํด๋ก์ง๋ฅผ ๊ตฌํํฉ๋๋ค. ํ๋ก ํธ์๋์๋ IBM HTTP Server(IHS)๊ฐ ๋ฐฐ์น๋๋ฉฐ ๋ณ๋์ ๋ฐฐํฌ ์๋ฒ๊ฐ ์กด์ฌํ๋ ๊ตฌ์กฐ์ ๋๋ค.
2. Prerequisites & WLP Installation
๋ณธ ๊ฐ์ด๋๋ WLP 17.0.2 ๋ฐ CentOS Linux 7.3 ํ๊ฒฝ์ ๊ธฐ์ค์ผ๋ก ์์ฑ๋์์ต๋๋ค. ์ค์น ์ ์ง์๋๋ Java ๋ฒ์ ์ด ์ค์น๋์ด ์๋์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
Check System Environment
$> cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
$> ./java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build pxa6480sr4fp5-20170421_01(SR4 FP5))
IBM J9 VM (build 2.8, JRE 1.8.0 Linux amd64-64 Compressed References 20170419_344392)
Base Installation (Machine: 02)
๋จผ์ Controller๊ฐ ๋ ๋จธ์ (Machine: 02)์ WLP๋ฅผ ์ค์นํ๊ณ ํ์ํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ค, ์ด๋ฅผ ํจํค์งํ์ฌ Member ์๋ฒ๋ค(Machine: 03, 04)๋ก ๋ฐฐํฌํ๋ ์ ๋ต์ ์ฌ์ฉํฉ๋๋ค.
# Create directory
$> sudo mkdir -p /opt/ibm
# Change ownership
$> sudo chown -R wasadmin:wasgrp /opt/ibm
# Install WLP
$> java -jar wlp-17.0.0.2-all.jar --acceptLicense /opt/ibm
# Verify version
$> cd /opt/ibm/wlp/bin
$> ./productInfo version
Product name: WebSphere Application Server
Product version: 17.0.0.2
Install Required Features
Collective, Cluster, SSL, JMX Connector ๋ฑ์ ํ์ ๊ธฐ๋ฅ์ ์ค์นํฉ๋๋ค.
$> ./installUtility install collectiveController-1.0 collectiveMember-1.0 clusterMember-1.0 websocket-1.1 restConnector-2.0 ssl-1.0 localConnector-1.0 adminCenter-1.0
Package and Distribute
์ค์น๋ ํ๊ฒฝ์ wlp_install.jar๋ก ํจํค์งํ์ฌ ๋ค๋ฅธ ๋
ธ๋์ ๋ณต์ ํฉ๋๋ค.
# Create defaultServer for packaging context
$> ./server create
# Package server including all binaries
$> ./server package defaultServer --archive=/tmp/wlp_install.jar --include=all
Server defaultServer package complete in /tmp/wlp_install.jar.
์์ฑ๋ wlp_install.jar๋ฅผ Machine 03, 04๋ก ์ ์กํ ํ ๋์ผํ๊ฒ ์ค์น๋ฅผ ์งํํฉ๋๋ค.
# On Machine 03 & 04
$> sudo mkdir -p /opt/ibm
$> chown -R wasadmin:wasgrp /opt/ibm
$> java -jar wlp_install.jar --acceptLicense /opt/ibm
3. Setup Collective Controller (Machine: 02)
Controller ์๋ฒ(wlpCntlr)๋ฅผ ์์ฑํ๊ณ ๊ตฌ์ฑ์ ์ด๊ธฐํํฉ๋๋ค.
# Create server
$> ./server create wlpCntlr
# Initialize Collective Controller
$> ./collective create wlpCntlr --keystorePassword=<password> --createConfigFile=/opt/ibm/wlp/usr/servers/wlpCntlr/wlpcntlr_include.xml
์ ๋ช
๋ น์ด๋ฅผ ์ํํ๋ฉด ์ธ์ฆ์ ์์ฑ ๋ฐ wlpcntlr_include.xml ์ค์ ํ์ผ์ด ์์ฑ๋ฉ๋๋ค. ์ดํ server.xml๊ณผ include ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ ํฉ๋๋ค.
Configuration: server.xml (Controller)
<server description="CollectiveController">
<featureManager>
<feature>adminCenter-1.0</feature>
<feature>websocket-1.1</feature>
<feature>restConnector-1.0</feature>
<feature>localConnector-1.0</feature>
</featureManager>
<!-- Include generated config -->
<include location="${server.config.dir}/wlpcntlr_include.xml" />
<httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443" host="*" />
</server>
Configuration: wlpcntlr_include.xml
์๋ ์์ฑ๋ ํ์ผ์์ quickStartSecurity ๋ถ๋ถ์ ๋ณธ์ธ์ ๊ณ์ ์ ๋ณด๋ก ์์ ํฉ๋๋ค.
<quickStartSecurity userName="wasadmin" userPassword="{xor}EncryptedPassword..." />
Firewall Configuration
CentOS ๋ฐฉํ๋ฒฝ์์ 9080, 9443 ํฌํธ๋ฅผ ํ์ฉํด์ผ ํฉ๋๋ค.
$> sudo firewall-cmd --zone=public --permanent --add-port=9443/tcp
$> sudo firewall-cmd --zone=public --permanent --add-port=9080/tcp
$> sudo firewall-cmd --reload
Start Controller
$> ./server start wlpCntlr
๋ก๊ทธ(messages.log)์์ CWWKX6011I: The collective controller is ready ๋ฉ์์ง๋ฅผ ํ์ธํฉ๋๋ค. Admin Center(https://hostname:9443/adminCenter/) ์ ์๋ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.
4. Setup Collective & Cluster Members
Machine 03๊ณผ 04์์ ๋ฉค๋ฒ ์๋ฒ๋ฅผ ์์ฑํ๊ณ Controller์ Join ์ํต๋๋ค.
Create & Join Member (Machine: 03)
# Create Server
$> ./server create wlpSrv01
# Join Collective
$> ./collective join wlpSrv01 \
--host=waslibctlr01 \
--port=9443 \
--user=wasadmin \
--password=<password> \
--keystorePassword=<password> \
--createConfigFile=/opt/ibm/wlp/usr/servers/wlpSrv01/wlpsrv01_include.xml
SSL Handshake ๊ณผ์ ์์ ์ธ์ฆ์๋ฅผ ์ ๋ขฐํ๊ฒ ๋๋ ํ๋กฌํํธ์ y๋ฅผ ์
๋ ฅํฉ๋๋ค.
Configuration: server.xml (Member)
Member ์๋ฒ์ server.xml์ Cluster ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ณ , Controller๊ฐ ๋ฐฐํฌ ๊ด๋ฆฌ๋ฅผ ํ ์ ์๋๋ก remoteFileAccess๋ฅผ ์ค์ ํฉ๋๋ค.
<server description="Cluster Member">
<featureManager>
<feature>webProfile-7.0</feature>
<feature>restConnector-1.0</feature>
<feature>localConnector-1.0</feature>
<!-- Added for Clustering -->
<feature>clusterMember-1.0</feature>
</featureManager>
<include location="${server.config.dir}/wlpsrv01_include.xml" />
<!-- Define Cluster Name -->
<clusterMember name="wlpCluster"/>
<httpEndpoint id="defaultHttpEndpoint" httpPort="9081" httpsPort="9444" host="*" />
<!-- Write Access for Controller -->
<remoteFileAccess>
<writeDir>${server.config.dir}</writeDir>
</remoteFileAccess>
</server>
Machine: 04 (wlpSrv02)์ ๋ํด์๋ ์ ๊ณผ์ ์ ๋์ผํ๊ฒ ๋ฐ๋ณตํฉ๋๋ค.
Security Considerations (LTPA)
ํด๋ฌ์คํฐ ํ๊ฒฝ์์ ์ธ์
๊ณต์ ๋ฐ ๋ณด์์ ์ํด ๋ชจ๋ ๋ฉค๋ฒ๋ ๋์ผํ LTPA ํค๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ํ ์๋ฒ์์ ์์ฑ๋ ltpa.keys ํ์ผ์ ๋ค๋ฅธ ๋ฉค๋ฒ ์๋ฒ๋ค์ ๋์ผํ ๊ฒฝ๋ก(${server.ouput.dir}/resources/security/)๋ก ๋ณต์ฌํฉ๋๋ค.
5. Start Members & Verification
๊ฐ ๋ ธ๋์์ ๋ฉค๋ฒ ์๋ฒ๋ฅผ ์์ํฉ๋๋ค.
$> ./server start wlpSrv01 # On Machine 03
$> ./server start wlpSrv02 # On Machine 04
๋ก๊ทธ ํ์ผ์์ ๋ค์ ๋ฉ์์ง๋ค์ ํ์ธํ์ฌ ์ ์ ๊ตฌ๋์ ๊ฒ์ฆํฉ๋๋ค.
CWWKX8112I: Collective Repository์ ํธ์คํธ ์ ๋ณด ๊ฒ์ ์ฑ๊ณต.CWWKX7400I: ClusterMember MBean ํ์ฑํ (ํด๋ฌ์คํฐ ์กฐ์ธ ์ฑ๊ณต).
6. Troubleshooting Notes
์ค์ ๊ณผ์ ์์ ์์ฃผ ๋ฐ์ํ๋ ์ค๋ฅ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋๋ค.
-
CWWKX0229E (401 Unauthorized / 403 Forbidden)
collective join์ ์ธ์ฆ ์คํจ.quickStartSecurity์ ๊ณ์ ์ ๋ณด๊ฐ ์ผ์นํ๋์ง ํ์ธํ์ญ์์ค. 403 ์๋ฌ์ ๊ฒฝ์ฐ ํด๋น ์ฌ์ฉ์๊ฐadministrator-role์ ๊ฐ์ง๊ณ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. -
CWWKS9582E (SSL unresolved)
IIOP ๋ณด์ ์ค์ ์ SSL ์ฐธ์กฐ ์ค๋ฅ.server.xml์ SSL ๊ตฌ์ฑ ๋ฐ KeyStore ์ ์๊ฐ ๋ช ํํ์ง ํ์ธํ์ญ์์ค. -
CWWKO0221E / CWWKS9580E (Port in use)
ํ ํธ์คํธ์ ์ฌ๋ฌ ์ธ์คํด์ค๋ฅผ ๋์ธ ๊ฒฝ์ฐ JMS ํฌํธ(7276)๋ IIOP ํฌํธ(2809) ์ถฉ๋์ด ๋ฐ์ํ ์ ์์ต๋๋ค.wasJmsEndpoint๋ฐiiopEndpoint์ค์ ์ ํตํด ํฌํธ๋ฅผ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
Next Step: ํด๋ฌ์คํฐ ๊ตฌ์ฑ์ด ์๋ฃ๋์์ต๋๋ค. ๋ค์ ํฌ์คํธ์์๋ ์ด ํด๋ฌ์คํฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฃน๋๋ค.
[Tomcat] ์ฃผ์ ์ค์ ํ์ผ(server.xml, web.xml) ์๋ฒฝ ๋ถ์ ๋ฐ ํ์ ํ๋ ํฌ์ธํธ
Apache Tomcat์ ๋์์ ์ ์ดํ๋ ํต์ฌ ์ค์ ํ์ผ๋ค์ ๋ชจ๋
/conf๋๋ ํ ๋ฆฌ์ ์์นํฉ๋๋ค. ๊ฐ์ฅ ์ค์ํserver.xml(ํฌํธ, ์ปค๋ฅํฐ)๊ณผweb.xml(์ธ์ , MIME)์ ์ญํ ๊ณผ ์์ฃผ ์ฌ์ฉํ๋ ์ค์ ๋ณ๊ฒฝ ๊ฐ์ด๋๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
1. ์ค์ ํ์ผ ๊ฐ์ (Configuration Overview)
Tomcat ์ค์น ๊ฒฝ๋ก ๋ด conf ๋๋ ํ ๋ฆฌ์๋ ๋ค์๊ณผ ๊ฐ์ ์ฃผ์ XML ํ์ผ๋ค์ด ์กด์ฌํฉ๋๋ค.
| ํ์ผ๋ช | ์ฃผ์ ์ญํ ๋ฐ ์ค๋ช |
|---|---|
| server.xml |
Tomcat์ ๋ฉ์ธ ์ค์ ํ์ผ์
๋๋ค. - HTTP/AJP ํฌํธ ์ค์ - ๊ฐ์ ํธ์คํธ(Host) ๋ฐ Context ์ค์ - ์ฐ๋ ๋ ํ(Thread Pool) ๊ด๋ฆฌ |
| web.xml |
๋ชจ๋ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๊ธฐ๋ณธ ์์ฑ์ ์ ์ํฉ๋๋ค. - ์ธ์ ํ์์์(Session Timeout) ์ค์ - MIME ํ์ ์ ์, ๊ธฐ๋ณธ ์๋ธ๋ฆฟ ๋งคํ |
| context.xml |
์น ์ ํ๋ฆฌ์ผ์ด์
์ Context ์ค์ ์ ๋ด๋นํฉ๋๋ค. - JNDI ๋ฆฌ์์ค(DB Connection Pool) ์ค์ ์ ์ฃผ๋ก ์ฌ์ฉ |
| tomcat-users.xml | Tomcat Manager/Admin ํ์ด์ง ์ ๊ทผ ๊ณ์ ์ ๊ด๋ฆฌํฉ๋๋ค. |
2. server.xml ์ฃผ์ ์ค์ ๊ฐ์ด๋
์์ง๋์ด๊ฐ ๊ฐ์ฅ ๋น๋ฒํ๊ฒ ์์ ํ๋ ํ์ผ์ ๋๋ค. ํฌํธ ์ถฉ๋ ํด๊ฒฐ์ด๋ ์ธ์ฝ๋ฉ ์ฒ๋ฆฌ๋ฅผ ์ํด ํ์์ ์ผ๋ก ํ์ธํด์ผ ํฉ๋๋ค.
1) HTTP ํฌํธ ๋ณ๊ฒฝ ๋ฐ ์ธ์ฝ๋ฉ ์ค์
๊ธฐ๋ณธ 8080 ํฌํธ๋ฅผ 80์ผ๋ก ๋ณ๊ฒฝํ๊ฑฐ๋, ํ๊ธ ๊นจ์ง ๋ฐฉ์ง๋ฅผ ์ํด URIEncoding์ ์ค์ ํฉ๋๋ค.
<!-- ๊ธฐ๋ณธ ์ค์ -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- ํ๋ ์ค์ ์์ -->
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" />
URIEncoding="UTF-8" ์์ฑ์ด ๋๋ฝ๋์์ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค.
2) AJP ํฌํธ ์ค์ (์น ์๋ฒ ์ฐ๋ ์)
Apache HTTP Server์ ์ฐ๋ํ ๋ ์ฌ์ฉํ๋ AJP ํ๋กํ ์ฝ ํฌํธ์ ๋๋ค. ์ฌ์ฉํ์ง ์๋๋ค๋ฉด ์ฃผ์ ์ฒ๋ฆฌํ์ฌ ๋ณด์์ ๊ฐํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
<!-- ๊ธฐ๋ณธ๊ฐ 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
3. web.xml ์ฃผ์ ์ค์ ๊ฐ์ด๋
๋ชจ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ฉ๋๋ ์ ์ญ(Global) ์ค์ ์ ๋ด๋นํฉ๋๋ค.
1) ์ธ์ ํ์์์ (Session Timeout)
์ฌ์ฉ์ ์ธ์ ๋ง๋ฃ ์๊ฐ์ ์ค์ ํฉ๋๋ค. (๋จ์: ๋ถ)
<session-config>
<session-timeout>30</session-timeout>
</session-config>
2) ๋๋ ํ ๋ฆฌ ๋ฆฌ์คํ ๋นํ์ฑํ (๋ณด์)
ํน์ ๋๋ ํ ๋ฆฌ ์ ๊ทผ ์ ํ์ผ ๋ชฉ๋ก์ด ๋
ธ์ถ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด listings ๊ฐ์ false๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value> <!-- true๋ฉด ํ์ผ ๋ชฉ๋ก ๋
ธ์ถ๋จ -->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
4. tomcat-users.xml (Manager App)
http://localhost:8080/manager ํ์ด์ง์ ์ ์ํ์ฌ GUI๋ก ์ ํ๋ฆฌ์ผ์ด์
์ ๋ฐฐํฌํ๊ฑฐ๋ ์ค์งํ๋ ค๋ฉด ๊ณ์ ์ค์ ์ด ํ์ํฉ๋๋ค.
<tomcat-users>
<!-- ์ญํ ์ ์ -->
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<!-- ์ฌ์ฉ์ ์ ์ -->
<user username="admin" password="password" roles="manager-gui,admin-gui"/>
</tomcat-users>
Next Step:
์ค์ ํ์ผ ์์ ํ์๋ ๋ฐ๋์ Tomcat์ ์ฌ๊ธฐ๋ํด์ผ ์ ์ฉ๋ฉ๋๋ค. ๋ค์ ๋จ๊ณ์์๋ ์ค์ ์ด์ ํ๊ฒฝ์์ ์ฑ๋ฅ์ ์ต์ ํํ๊ธฐ ์ํ JVM ๋ฉ๋ชจ๋ฆฌ ์ค์ (Heap Size)๊ณผ GC ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
[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
./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/IHS] ์๋ฒ ์ฑ๋ฅ ํ๋์ ํต์ฌ: MaxRequestWorkers ๊ณ์ฐ๋ฒ ๋ฐ MPM ์ค์ ์๋ฒฝ ๊ฐ์ด๋
"์ฌ์ฉ์๊ฐ ๋ชฐ๋ฆฌ๋ฉด ์๋ฒ๊ฐ ์๋ต์ด ์์ด์." ์ด๋ฐ ๋ฌธ์ ์ 90%๋ ๋์ ์ ์์ ์ฒ๋ฆฌ ์ค์ ์ธ MPM(Multi-Processing Module) ํ๋์ผ๋ก ํด๊ฒฐ๋ฉ๋๋ค. ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ ํ๊ณ ๋ด์์ ์ต๋ ์ฑ๋ฅ์ ๋์ด๋ด๋
MaxRequestWorkers์ค์ ๋ฒ๊ณผServerLimit์ ๊ด๊ณ๋ฅผ ๋จ๊ณ๋ณ๋ก ์ ๋ฆฌํฉ๋๋ค.
0. ํ๋์ ํต์ฌ ๊ณต์ (The Formula)
ํ๋์ '๊ฐ'์ผ๋ก ํ๋ ๊ฒ์ด ์๋๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ผ๋ก ์ธํ ์ค์(Swap) ๋ฐ์์ ๋ง๋ ๊ฒ์ด ์ต์ฐ์ ๋ชฉํ์ด๋ฉฐ, ์ด๋ ์ ํํ ๊ณ์ฐ์์ ์์๋ฉ๋๋ค.
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 - ๊ฒฐ๋ก : ์์์ ์ ๋ฒ๋ฆฌ๊ณ 225๋ฅผ
MaxRequestWorkers๊ฐ์ผ๋ก ์ ์ ํฉ๋๋ค.
2. ๋ณด์ด์ง ์๋ ๋ฒฝ: Limit ์ง์์ด์ ์ดํด
MaxRequestWorkers ๊ฐ๋ง ๋์ธ๋ค๊ณ ๋์ด ์๋๋๋ค. ์ด ๊ฐ์ ์์ ์ ํ(Hard Limit) ์ค์ ์ธ ServerLimit๊ณผ ThreadLimit ์์์๋ง ์ ํจํฉ๋๋ค.
- ๊ท์น:
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>
apachectl -t ๋๋ httpd -t ๋ช
๋ น์ด๋ก ๋ฌธ๋ฒ ์ค๋ฅ๊ฐ ์๋์ง ํ์ธํ๊ณ ์ฌ๊ธฐ๋ํด์ผ ํฉ๋๋ค.
[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 ๋ฑ์ ํ๋ก์ ํธ ์์ฑ ๋ช
๋ น์ด๋ฅผ ์คํํด ๋ณด์ญ์์ค.
[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 ๋ชจ๋์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
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 ๋ฑ ๋ณด์ ํค๋ ์ ์ฉ์ ๊ฒํ ํด ๋ณด์ญ์์ค.
[JBoss EAP 7] ๋ฐ์ดํฐ์์ค ํจ์ค์๋ ์ํธํ ์๋ฒฝ ๊ฐ์ด๋: Password Vault ๊ตฌ์ฑ ๋ฐ ์ ์ฉ (Windows/Linux)
JBoss EAP 7.x ํ๊ฒฝ์์ ํ๋ฌธ์ผ๋ก ์ ์ฅ๋๋ ๋ฐ์ดํฐ์์ค ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณดํธํ๊ธฐ ์ํด Password Vault๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํฉ๋๋ค. Windows์ Linux ํ๊ฒฝ, ๊ทธ๋ฆฌ๊ณ Standalone๊ณผ Domain ๋ชจ๋ ๊ฐ๊ฐ์ ๋ํ ์ค์ ๋ฒ์ ํฌ๊ดํ๋ฉฐ, KeyStore ์์ฑ๋ถํฐ
VAULT๋ฌธ์์ด ์ ์ฉ๊น์ง์ ์ ์ฒด ํ๋ก์ธ์ค๋ฅผ ๋ค๋ฃน๋๋ค.
1. ํ๋ก์ธ์ค ๊ฐ์ (Process Overview)
Vault ๊ตฌ์ฑ์ ํฌ๊ฒ 4๋จ๊ณ๋ก ์งํ๋ฉ๋๋ค.
- KeyStore ์์ฑ: ์ํธํ ํค๋ฅผ ์ ์ฅํ ๋ฌผ๋ฆฌ์ ํ์ผ(.keystore) ์์ฑ
- Vault ์ด๊ธฐํ ๋ฐ ์ํธํ: ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํํ๊ณ JBoss ์ค์ ์ ํ์ํ ํ๋ผ๋ฏธํฐ ์์ฑ
- JBoss Vault ์ค์ : ์์ฑ๋ KeyStore์ JBoss๋ฅผ ์ฐ๋ (
standalone.xml๋๋host.xml) - ๋ฐ์ดํฐ์์ค ์ ์ฉ: ํ๋ฌธ ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํ๋ ๋ฌธ์์ด(
${VAULT::...})๋ก ๊ต์ฒด
2. KeyStore ์์ฑ (Generate KeyStore)
Java์ keytool์ ์ฌ์ฉํ์ฌ JCEKS ํ์์ ํค์คํ ์ด๋ฅผ ์์ฑํฉ๋๋ค.
Windows ํ๊ฒฝ
keytool.exe -genseckey ^
-alias "vault" ^
-storetype "jceks" ^
-keyalg "AES" ^
-keysize "128" ^
-storepass "passw0rd" ^
-keypass "passw0rd" ^
-validity "7300" ^
-keystore "D:\app\was\JBoss\vault\vault.keystore"
Linux ํ๊ฒฝ
./keytool -genseckey \
-alias "vault" \
-storetype "jceks" \
-keyalg "AES" \
-keysize "128" \
-storepass "passw0rd" \
-keypass "passw0rd" \
-validity "7300" \
-keystore "/app/was/JBoss/vault/vault.keystore"
3. ๋น๋ฐ๋ฒํธ ์ํธํ ์คํ (Vault Tool)
JBoss `bin` ๋๋ ํ ๋ฆฌ์ ์๋ vault ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ DB ํจ์ค์๋๋ฅผ ์ํธํํฉ๋๋ค.
Windows (vault.bat)
vault.bat --keystore "D:\app\was\JBoss\vault\vault.keystore" ^
--keystore-password "passw0rd" ^
--alias "vault" ^
--vault-block "vb" ^
--attribute "dbpw" ^
--sec-attr "RealDBPassword!" ^
--enc-dir "D:\app\was\JBoss\vault" ^
--iteration "44" ^
--salt "JBo72ssv"
Linux (vault.sh)
./vault.sh --keystore "/app/was/JBoss/vault/vault.keystore" \
--keystore-password "passw0rd" \
--alias "vault" \
--vault-block "vb" \
--attribute "dbpw" \
--sec-attr "RealDBPassword!" \
--enc-dir "/app/was/JBoss/vault" \
--iteration "44" \
--salt "JBo72ssv"
๋ช ๋ น์ด ์คํ ๊ฒฐ๊ณผ์์ ์๋ ๋ ๊ฐ์ง ๊ฐ์ ๋ฐ๋์ ๊ธฐ๋กํด ๋์ด์ผ ํฉ๋๋ค.
1. Vault Configuration:
KEYSTORE_PASSWORD ๊ฐ (์: MASK-1234abcd...)2. Vault Block: ์ค์ ์ฌ์ฉ๋ ์ํธํ ๋ฌธ์์ด (์:
${VAULT::vb::dbpw::1})
4. JBoss Vault ๊ตฌ์ฑ ๋ฑ๋ก (Configuration)
JBoss๊ฐ ์์์ ๋ง๋ KeyStore๋ฅผ ์ธ์ํ ์ ์๋๋ก ์ค์ ํฉ๋๋ค. XML์ ์ง์ ์์ ํ๊ฑฐ๋ CLI๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Standalone Mode (standalone.xml)
<vault> ์น์
์ ์ถ๊ฐํฉ๋๋ค. (์ผ๋ฐ์ ์ผ๋ก <extensions> ๋ค์ชฝ)
<vault>
<vault-option name="KEYSTORE_URL" value="D:\app\was\JBoss\vault\vault.keystore"/>
<vault-option name="KEYSTORE_PASSWORD" value="MASK-xxxx"/> <!-- Vault ์คํ ๊ฒฐ๊ณผ๊ฐ -->
<vault-option name="KEYSTORE_ALIAS" value="vault"/>
<vault-option name="SALT" value="JBo72ssv"/>
<vault-option name="ITERATION_COUNT" value="44"/>
<vault-option name="ENC_FILE_DIR" value="D:\app\was\JBoss\vault\"/>
</vault>
Domain Mode (host.xml ๊ถ์ฅ)
๋๋ฉ์ธ ๋ชจ๋์์๋ ๋ฌผ๋ฆฌ์ ํ์ผ ๊ฒฝ๋ก(KeyStore ์์น)๊ฐ ์๋ฒ๋ง๋ค ๋ค๋ฅผ ์ ์์ผ๋ฏ๋ก, ๊ฐ ์๋ฒ์ host.xml์ ์ค์ ์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค.
<!-- host.xml์ <management> ๋๋ <vault> ์์ญ -->
<vault>
<vault-option name="KEYSTORE_URL" value="/app/was/JBoss/vault/vault.keystore"/>
<vault-option name="KEYSTORE_PASSWORD" value="MASK-xxxx"/>
<vault-option name="KEYSTORE_ALIAS" value="vault"/>
<vault-option name="SALT" value="JBo72ssv"/>
<vault-option name="ITERATION_COUNT" value="44"/>
<vault-option name="ENC_FILE_DIR" value="/app/was/JBoss/vault/"/>
</vault>
5. ๋ฐ์ดํฐ์์ค ๋น๋ฐ๋ฒํธ ์ ์ฉ
๋ง์ง๋ง์ผ๋ก ๋ฐ์ดํฐ์์ค ์ค์ ํ์ผ(standalone.xml ๋๋ domain.xml)์์ ํ๋ฌธ ๋น๋ฐ๋ฒํธ๋ฅผ Vault ๋ฌธ์์ด๋ก ๊ต์ฒดํฉ๋๋ค.
<datasource jndi-name="java:jboss/datasources/ExampleDS" ...>
...
<security>
<user-name>dbuser</user-name>
<!-- ์ํธํ๋ ๋ฌธ์์ด ์ ์ฉ -->
<password>${VAULT::vb::dbpw::1}</password>
</security>
</datasource>
Next Step:
์ค์ ์ด ์๋ฃ๋์๋ค๋ฉด JBoss๋ฅผ ์ฌ๊ธฐ๋ํ๊ณ ๊ด๋ฆฌ ์ฝ์์์ Test Connection์ ์ํํ์ฌ DB ์ฐ๊ฒฐ์ด ์ ์์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋์ง ํ์ธํ์ญ์์ค.
[JBoss EAP 6] ๋๋ฉ์ธ ๋ชจ๋ ๋ณด์ ๊ฐํ: Vault๋ฅผ ์ด์ฉํ Datasource ํจ์ค์๋ ์ํธํ ๋ฐ ๋ฌด์ค๋จ ์ ์ฉ ์ ๋ต
JBoss EAP 6.4 ๋๋ฉ์ธ ๋ชจ๋(Domain Mode)์์ ํ๋ฌธ์ผ๋ก ์ ์ฅ๋ ๋ฐ์ดํฐ์์ค ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณดํธํ๊ธฐ ์ํด Vault๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํฉ๋๋ค.
host.xml๊ณผdomain.xml์ ์ค์ ๋ถ๋ฆฌ ์์น์ ์ดํดํ๊ณ , ์ด์คํ๋ ํ๊ฒฝ์์ ์๋น์ค ์ค๋จ ์์ด ์ ์ฉํ๋ ์์ฐจ์ ๋ฐฐํฌ ์ ๋ต์ ๋ค๋ฃน๋๋ค.
0. ๋ฐฐ๊ฒฝ ๋ฐ ์ํคํ ์ฒ (Context)
๋ณด์ ๊ฐ์ฌ ์๊ฑด ์ถฉ์กฑ์ ์ํด DB ํจ์ค์๋ ์ํธํ๋ ํ์์ ๋๋ค. ๋๋ฉ์ธ ๋ชจ๋์์๋ ๋ค์๊ณผ ๊ฐ์ ์ค์ ๋ถ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค.
- host.xml: ๋ฌผ๋ฆฌ์ ์ธ Keystore ํ์ผ์ ์์น์ ์ํธํ ํค ํด๋ ์ค์ (Vault ์ ์ธ)
- domain.xml: ์ค์ ์ํธํ๋ ๋ฌธ์์ด์ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ์์ค ์ค์ (Vault ์ฐธ์กฐ)
1. Vault ํ๊ฒฝ ์ค๋น (Keystore ์์ฑ)
์ํธํ ํค๋ฅผ ์ ์ฅํ Java Keystore๋ฅผ ์์ฑํฉ๋๋ค. JDK์ keytool์ ์ฌ์ฉํฉ๋๋ค.
# Keystore ์์ฑ (์๊ณ ๋ฆฌ์ฆ: DESede ๋๋ AES)
keytool -genkey -alias vault -keyalg DESede -keystore vault.keystore -keysize 168 -storepass [ํค์คํ ์ด_๋น๋ฐ๋ฒํธ] -validity 3650
vault.keystore ํ์ผ์ ๋ง์คํฐ(Master)์ ์ฌ๋ ์ด๋ธ(Slave) ์๋ฒ ๋ชจ๋ ๋์ผํ ๊ฒฝ๋ก(์: EAP_HOME/vault/)์ ๋ณต์ฌํด ๋์ด์ผ ํฉ๋๋ค.
2. Vault ์ด๊ธฐํ ๋ฐ ๋น๋ฐ๋ฒํธ ์ํธํ
JBoss์์ ์ ๊ณตํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ Vault๋ฅผ ์ด๊ธฐํํ๊ณ , ์ค์ DB ํจ์ค์๋๋ฅผ ์ํธํ๋ ๋ฌธ์์ด๋ก ๋ณํํฉ๋๋ค.
๋ํํ ๋ชจ๋ ์คํ (Interactive)
$JBOSS_HOME/bin/vault.sh
์ ๋ช ๋ น ์คํ ํ ์ต์ 0 (Store a secured attribute)์ ์ ํํ์ฌ ์งํํ๊ฑฐ๋, ์๋์ ๊ฐ์ด CLI ํ๋ผ๋ฏธํฐ๋ก ํ ๋ฒ์ ์คํํ ์๋ ์์ต๋๋ค.
# CLI ํ๋ผ๋ฏธํฐ ์์
$JBOSS_HOME/bin/vault.sh \
--keystore vault.keystore \
--keystore-password [ํค์คํ ์ด_๋น๋ฐ๋ฒํธ] \
--alias vault \
--vault-block ds_vault \
--attribute db_password \
--sec-attr [์ค์ _DB_๋น๋ฐ๋ฒํธ] \
--enc-dir /path/to/vault/ \
--iteration 120 \
--salt 1234abcd
๊ฒฐ๊ณผ ํ์ธ: ์ถ๋ ฅ๋๋ VAULT::ds_vault::db_password::1 ํํ์ ๋ฌธ์์ด๊ณผ, ํ๋ฉด์ ํ์๋๋ XML ์ค์ ๋ธ๋ก์ ๋ณต์ฌํด ๋ก๋๋ค.
3. host.xml ์ค์ (Vault ์ ์ธ)
๋ฌผ๋ฆฌ์ ์ธ ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ธ์ํด์ผ ํ๋ ๋ชจ๋ ํธ์คํธ ์ปจํธ๋กค๋ฌ(Master, Slave)์ host.xml ํ์ผ์ ์์ ํฉ๋๋ค.
<!-- host.xml์ <management> ์น์
๋ด, ๋๋ <vault> ์น์
-->
<vault>
<vault-option name="KEYSTORE_URL" value="/path/to/vault/vault.keystore"/>
<vault-option name="KEYSTORE_PASSWORD" value="MASK-..."/> <!-- ๋ง์คํน๋ ๋น๋ฐ๋ฒํธ -->
<vault-option name="KEYSTORE_ALIAS" value="vault"/>
<vault-option name="SALT" value="1234abcd"/>
<vault-option name="ITERATION_COUNT" value="120"/>
<vault-option name="ENC_FILE_DIR" value="/path/to/vault/" />
</vault>
4. domain.xml ์ค์ (Datasource ์ ์ฉ)
์ด์ ๋๋ฉ์ธ ์ปจํธ๋กค๋ฌ์ domain.xml์์ ๋ฐ์ดํฐ์์ค ๋น๋ฐ๋ฒํธ ๋ถ๋ถ์ ์์์ ์์ฑํ Vault ๋ฌธ์์ด๋ก ๋์ฒดํฉ๋๋ค.
<datasource ...>
<security>
<user-name>dbuser</user-name>
<password>${VAULT::ds_vault::db_password::1}</password>
</security>
</datasource>
5. ์ด์ ํ๊ฒฝ ์ ์ฉ ์ ๋ต (Deployment Strategy)
์ด์คํ(HA)๋ ์ด์ ํ๊ฒฝ์์ ์๋น์ค ์ค๋จ์ ๋ฐฉ์งํ๊ธฐ ์ํด, host.xml ์ค์ ๊ณผ domain.xml ์ค์ ์ ๋ถ๋ฆฌํ์ฌ ์ ์ฉํ๋ ์ ๋ต์ด ํ์ํฉ๋๋ค.
Scenario A: ๋ฌด์ค๋จ ์์ฐจ ์ ์ฉ (Rolling Update)
Host Controller(HC) ์ค์ ์ธ host.xml์ ์ฌ๊ธฐ๋์ด ํ์ํ์ง๋ง, domain.xml ๋ณ๊ฒฝ์ ๋ฆฌ๋ก๋(Reload)๋ก ๋ฐ์๋ ์ ์์์ ์ด์ฉํฉ๋๋ค.
- Slave ์๋ฒ(Server2) ์์
:
- Slave HC ์ค์ง
- Slave
host.xml์ Vault ์ค์ ์ถ๊ฐ ๋ฐvault.keystoreํ์ผ ๋ฐฐํฌ - Slave HC ์ฌ๊ธฐ๋ (์ด๋ Server2 ์ธ์คํด์ค๋ค๋ ์ฌ๊ธฐ๋๋จ)
- Master ์๋ฒ(Server1) ์์
:
- Master HC ์ค์ง (๋๋ฉ์ธ ์ปจํธ๋กค๋ฌ ์ค์ง)
- Master
host.xml์ Vault ์ค์ ์ถ๊ฐ ๋ฐvault.keystoreํ์ผ ๋ฐฐํฌ - Master HC ์ฌ๊ธฐ๋
- Datasource ๋ณ๊ฒฝ:
- Master๊ฐ ๊ธฐ๋๋ ์ํ์์
domain.xml์ ๋ฐ์ดํฐ์์ค ํจ์ค์๋๋ฅผ${VAULT::...}๋ก ๋ณ๊ฒฝ - JBoss CLI ๋๋ ์ฝ์์์ Datasource Disable/Enable ์ํ (๋๋ reload)
- Master๊ฐ ๊ธฐ๋๋ ์ํ์์
Scenario B: ์ ์ฒด ์ค๋จ ํ ์ ์ฉ (Cold Restart)
๊ฐ์ฅ ์์ ํ๊ณ ํ์คํ ๋ฐฉ๋ฒ์ ๋๋ค. ์ ์ง๋ณด์ ์๊ฐ(Maintenance Window)์ด ํ๋ณด๋์์ ๋ ๊ถ์ฅํฉ๋๋ค.
- ๋ชจ๋ JBoss ํ๋ก์ธ์ค(Master/Slave) ์ข ๋ฃ
- ๋ชจ๋ ์๋ฒ์
host.xml์์ ๋ฐ ํค์คํ ์ด ๋ฐฐํฌ - Master ์๋ฒ์
domain.xml์์ - Master ๊ธฐ๋ → Slave ๊ธฐ๋ ์์๋ก ์ ์ฒด ์ฌ์์
6. ๊ฒ์ฆ (Verification)
- ์๋ฒ ๊ธฐ๋ ๋ก๊ทธ(server.log)์ Vault ๊ด๋ จ ์๋ฌ(
PBOX000...)๊ฐ ์๋์ง ํ์ธํฉ๋๋ค. - ๊ด๋ฆฌ ์ฝ์์์ Datasource์ Test Connection์ ์ํํ์ฌ DB ์ฐ๊ฒฐ์ด ์ ์์ ์ธ์ง ํ์ธํฉ๋๋ค.
[WebSphere Liberty] securityUtility๋ก SSL ์ธ์ฆ์ ์์ฑ ๋ฐ AES ํจ์ค์๋ ์ํธํ ์ค์ ๊ฐ์ด๋
WebSphere Liberty์
securityUtility๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒด ์๋ช ๋(Self-Signed) SSL ์ธ์ฆ์๋ฅผ ์์ฑํ๊ณ , ๋ณด์์ฑ์ ๋์ด๊ธฐ ์ํด Keystore ๋น๋ฐ๋ฒํธ๋ฅผ AES๋ก ์ํธํํ์ฌ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํฉ๋๋ค.
0. ๋ฐฐ๊ฒฝ ๋ฐ ์๋๋ฆฌ์ค (Context)
Liberty ์๋ฒ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ๋ฐ ํธ์๋ฅผ ์ํด SSL ์ค์ ์ ์๋ํํ์ง๋ง, ์ด์ ํ๊ฒฝ์์๋ ๋ช
์์ ์ธ ์ธ์ฆ์ ๊ด๋ฆฌ์ ๋น๋ฐ๋ฒํธ ๋ณด์์ด ํ์์ ์
๋๋ค. securityUtility๋ฅผ ์ฌ์ฉํ๋ฉด ์ธ์ฆ์ ์์ฑ๊ณผ ๋น๋ฐ๋ฒํธ ์ํธํ(Encoding)๋ฅผ ๋์์ ์ํํ ์ ์์ต๋๋ค.
Test Environment
- Middleware: WebSphere Liberty Profile (WLP)
- Server Name: s11, s12
1. SSL ์ธ์ฆ์ ์์ฑ ๋ฐ ์ํธํ (Create Certificate)
securityUtility createSSLCertificate ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ํค์คํ ์ด(PKCS12)๋ฅผ ์์ฑํฉ๋๋ค. ์ด๋ --passwordEncoding=aes ์ต์
์ ์ฌ์ฉํ์ฌ ์ค์ ํ์ผ์ ๋ค์ด๊ฐ ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํํฉ๋๋ค.
๋ช ๋ น์ด ๊ตฌ๋ฌธ
# ๊ตฌ๋ฌธ: securityUtility createSSLCertificate --server=[์๋ฒ๋ช
] --password=[ํคํจ์ค์๋] --validity=[์ ํจ๊ธฐ๊ฐ์ผ์] --passwordEncoding=aes --passwordKey=[์ํธํํค]
cd $WLP_HOME/bin
./securityUtility createSSLCertificate --server=s11 --password=passw0rd --validity=7300 --passwordEncoding=aes --passwordKey=passw0rd
์คํ ๊ฒฐ๊ณผ
ํค ์ ์ฅ์ /sw/was/WebSphere/wlp/usr/servers/s11/resources/security/key.p12์(๋ฅผ) ์์ฑํ๋ ์ค์
๋๋ค.
์๋ฒ s11์ ๋ํ SSL ์ธ์ฆ์๋ฅผ ์์ฑํ์ต๋๋ค.
์ด ์ธ์ฆ์๋ CN=testwas11,OU=s11์(๋ฅผ) ์ฌ์ฉํ์ฌ SubjectDN์ผ๋ก ์์ฑ๋์์ต๋๋ค.
usr/servers/[์๋ฒ๋ช
]/resources/security/ ๊ฒฝ๋ก์ ์ ์ฅ๋ฉ๋๋ค.
2. ์๋ฒ ์ค์ ์ ์ฉ (server.xml)
์์์ ์์ฑ๋ ์ธ์ฆ์๋ฅผ ์๋ฒ๊ฐ ์ฌ์ฉํ๋๋ก server.xml์ ์์ ํฉ๋๋ค. ์ด๋ ๋น๋ฐ๋ฒํธ ๋ถ๋ถ์ {aes}... ๋ก ์์ํ๋ ์ํธํ๋ ๋ฌธ์์ด์ ์
๋ ฅํด์ผ ํฉ๋๋ค.
<server description="SSL Server">
<!-- 1. SSL ๊ธฐ๋ฅ ํ์ฑํ -->
<featureManager>
<feature>transportSecurity-1.0</feature>
</featureManager>
<!-- 2. Keystore ์ ์ (๋น๋ฐ๋ฒํธ๋ ์ํธํ๋ ๊ฐ ์ฌ์ฉ) -->
<keyStore id="defaultKeyStore"
location="key.p12"
password="{aes}AJS+VEek/Fgo/zp46z8cuIUMTbnMM7sJVmPPbT49n4s6" />
</server>
3. ์ํธํ ํค ๋ฑ๋ก (bootstrap.properties)
server.xml์ ์ ํ {aes} ๋น๋ฐ๋ฒํธ๋ฅผ ์๋ฒ๊ฐ ๋ณตํธํํ๋ ค๋ฉด, ์ํธํํ ๋ ์ฌ์ฉํ๋ Key๋ฅผ ์๋ฒ์ ์๋ ค์ฃผ์ด์ผ ํฉ๋๋ค. ์ด ์ค์ ์ bootstrap.properties ํ์ผ์ ์ ์ฅํฉ๋๋ค.
- ํ์ผ ์์น:
usr/servers/[์๋ฒ๋ช ]/bootstrap.properties
# securityUtility ์คํ ์ --passwordKey ์ต์
์ ๋ฃ์๋ ๊ฐ
wlp.password.encryption.key=passw0rd
CWWKS1704E: ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณตํธํํ ์ ์์ต๋๋ค. ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
4. ์ธ์ฆ์ ๊ฒ์ฆ (Verification)
์์ฑ๋ ํค์คํ ์ด ํ์ผ์ด ์ ์์ ์ธ์ง, ์ ํจ๊ธฐ๊ฐ์ ๋ง๋์ง ํ์ธํ๊ธฐ ์ํด JDK์ ํฌํจ๋ keytool ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๊ฒ์ฆ ๋ช ๋ น์ด
# keytool -list -v -keystore [ํ์ผ๊ฒฝ๋ก] -storetype PKCS12 -storepass [๋น๋ฐ๋ฒํธ]
./keytool -list -v -keystore /sw/was/WebSphere/wlp/usr/servers/s12/resources/security/key.p12 -storetype PKCS12 -storepass passw0rd
์ถ๋ ฅ ๊ฒฐ๊ณผ ๋ถ์
ํค ์ ์ฅ์ ์ ํ: PKCS12
ํค ์ ์ฅ์ ์ ๊ณต์: SUN
๋ณ์นญ ์ด๋ฆ: default
์์ฑ ๋ ์ง: 2024. 6. 12.
ํญ๋ชฉ ์ ํ: PrivateKeyEntry
์ธ์ฆ์ ์ฒด์ธ ๊ธธ์ด: 2
# ์ ํจ๊ธฐ๊ฐ ํ์ธ
์ ํฉํ ์์ ๋ ์ง: Wed Jun 12 16:47:57 KST 2024
์ข
๋ฃ ๋ ์ง: Tue Jun 07 16:47:57 KST 2044 (์ฝ 20๋
)
# ์์ ์ ๋ฐ ์๋ช
์๊ณ ๋ฆฌ์ฆ ํ์ธ
์์ ์: CN=testwas11, OU=s12, O=ibm, C=us
์๋ช
์๊ณ ๋ฆฌ์ฆ ์ด๋ฆ: SHA256withRSA
์ฃผ์ฒด ๊ณต์ฉ ํค ์๊ณ ๋ฆฌ์ฆ: 2048๋นํธ RSA ํค
Next Step:
์์ฒด ์๋ช
์ธ์ฆ์(Self-Signed)๋ ๋ธ๋ผ์ฐ์ ์์ ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํ๋ฏ๋ก, ์ด์ ํ๊ฒฝ์์๋ CSR์ ์์ฑํ์ฌ ๊ณต์ธ ์ธ์ฆ๊ธฐ๊ด(CA)์ ์๋ช
์ ๋ฐ์ ํ keytool -import ๋ช
๋ น์ด๋ก ๊ต์ฒดํด์ผ ํฉ๋๋ค.