docs(DOC): Jenkins 보안 강화 — Java 21 업그레이드, CSP 활성화, 분산 빌드 설정
- Java 17 → 21 업그레이드 (17은 2026-03-31 지원 종료) - CSP(Content Security Policy) JVM 옵션 추가 - Built-in Node executor 0으로 변경, local-agent 분산 빌드 구성 - 운영 매뉴얼 3개 파일 업데이트 (01, 04, 11) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -156,7 +156,7 @@
|
||||
| Prometheus | 2.51.0 | 9090 | - (localhost only) |
|
||||
| Grafana | - | 3100 | monitor.sam.it.kr |
|
||||
| node_exporter | 1.8.2 | 9100 | - |
|
||||
| Java | OpenJDK 17.0.18 | - | Jenkins 런타임 |
|
||||
| Java | OpenJDK 21.0.10 | - | Jenkins 런타임 |
|
||||
| Certbot | - | - | SSL 자동 갱신 |
|
||||
| fail2ban | - | - | SSH 보호 |
|
||||
|
||||
@@ -180,6 +180,8 @@
|
||||
| Nginx 사이트 | /etc/nginx/sites-available/{ci,git,monitor}.sam.it.kr |
|
||||
| Jenkins 홈 | /var/lib/jenkins/ |
|
||||
| Jenkins JVM 설정 | /etc/systemd/system/jenkins.service.d/override.conf |
|
||||
| Jenkins Agent | /var/lib/jenkins-agent/ (workspace, agent.jar) |
|
||||
| Jenkins Agent 서비스 | /etc/systemd/system/jenkins-agent.service |
|
||||
| Jenkins 환경파일 | /var/lib/jenkins/env-files/react/.env.{develop,stage,main} |
|
||||
| Gitea 설정 | /etc/gitea/app.ini |
|
||||
| Gitea 저장소 | /var/lib/gitea/data/repositories/ |
|
||||
|
||||
@@ -20,14 +20,17 @@ sudo systemctl status jenkins
|
||||
| 파일 | 용도 |
|
||||
|------|------|
|
||||
| /var/lib/jenkins/ | Jenkins 홈 (jobs, plugins, credentials) |
|
||||
| /etc/systemd/system/jenkins.service.d/override.conf | JVM 메모리 설정 |
|
||||
| /etc/systemd/system/jenkins.service.d/override.conf | JVM 옵션 (메모리, CSP) |
|
||||
| /var/lib/jenkins/env-files/ | 배포 환경변수 (.env 파일) |
|
||||
| /var/lib/jenkins-agent/ | Agent 워크스페이스 (빌드 실행 격리) |
|
||||
| /etc/systemd/system/jenkins-agent.service | Agent systemd 서비스 |
|
||||
|
||||
**JVM 메모리 설정:**
|
||||
**JVM 설정:**
|
||||
|
||||
```bash
|
||||
# /etc/systemd/system/jenkins.service.d/override.conf
|
||||
# Environment="JAVA_OPTS=-Xmx2048m -Xms512m -Djava.awt.headless=true"
|
||||
# - 메모리: -Xmx2048m -Xms512m
|
||||
# - CSP: DirectoryBrowserSupport.CSP (workspace 브라우저 보안)
|
||||
|
||||
# 변경 후 적용
|
||||
sudo systemctl daemon-reload
|
||||
@@ -75,16 +78,46 @@ sudo journalctl -u jenkins --since "2 hours ago" --no-pager
|
||||
|
||||
플러그인 업데이트 후 Jenkins 재시작이 필요한 경우: `sudo systemctl restart jenkins`
|
||||
|
||||
### Build Agent (분산 빌드)
|
||||
|
||||
Built-in Node의 executor는 0으로 설정되어 있으며, 빌드는 로컬 Agent(`local-agent`)에서 실행된다.
|
||||
|
||||
| 항목 | 값 |
|
||||
|------|-----|
|
||||
| Agent 이름 | local-agent |
|
||||
| Workspace | /var/lib/jenkins-agent/ |
|
||||
| Executor 수 | 2 |
|
||||
| 라벨 | build |
|
||||
| 연결 방식 | WebSocket (Inbound) |
|
||||
|
||||
**서비스 제어:**
|
||||
|
||||
```bash
|
||||
sudo systemctl start jenkins-agent
|
||||
sudo systemctl stop jenkins-agent
|
||||
sudo systemctl restart jenkins-agent
|
||||
sudo systemctl status jenkins-agent
|
||||
|
||||
# Agent 로그
|
||||
sudo journalctl -u jenkins-agent -f
|
||||
```
|
||||
|
||||
> **참고**: Jenkins 마스터 재시작 시 Agent가 자동 재연결된다. Agent가 연결 실패하면 `sudo systemctl restart jenkins-agent`로 수동 재시작.
|
||||
|
||||
### Workspace 정리
|
||||
|
||||
```bash
|
||||
# 용량 확인
|
||||
sudo du -sh /var/lib/jenkins/workspace/*
|
||||
# Agent workspace 용량 확인
|
||||
sudo du -sh /var/lib/jenkins-agent/workspace/*
|
||||
|
||||
# 특정 workspace 삭제
|
||||
sudo rm -rf /var/lib/jenkins/workspace/<JOB_NAME>
|
||||
sudo rm -rf /var/lib/jenkins-agent/workspace/<JOB_NAME>
|
||||
|
||||
# 전체 workspace 정리 (빌드 중이 아닌지 확인 후)
|
||||
sudo rm -rf /var/lib/jenkins-agent/workspace/*
|
||||
|
||||
# 레거시 Built-in workspace (이전 빌드 잔존 시)
|
||||
sudo du -sh /var/lib/jenkins/workspace/*
|
||||
sudo rm -rf /var/lib/jenkins/workspace/*
|
||||
|
||||
# 임시 파일 정리
|
||||
|
||||
@@ -580,7 +580,7 @@ stage-api.sam.it.kr은 api.sam.it.kr과 동일 구조 (소켓: php8.4-fpm-api-st
|
||||
|------|------|--------|
|
||||
| ① | OS 기본 셋팅 (UFW, 스왑, 타임존) | - |
|
||||
| ② | MySQL 8.4 | ① |
|
||||
| ③ | Java 17 (Jenkins 런타임) | ① |
|
||||
| ③ | Java 21 (Jenkins 런타임) | ① |
|
||||
| ④ | Gitea | ② |
|
||||
| ⑤ | 개발서버 post-receive hook 설정 | ④ |
|
||||
| ⑥ | Jenkins | ③ |
|
||||
@@ -626,13 +626,19 @@ GRANT ALL PRIVILEGES ON *.* TO 'hskwon'@'localhost' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
### ③ Java 17
|
||||
### ③ Java 21
|
||||
|
||||
```bash
|
||||
sudo apt install -y openjdk-17-jre-headless
|
||||
sudo apt install -y openjdk-21-jre-headless
|
||||
java -version
|
||||
# openjdk version "21.0.x" 확인
|
||||
|
||||
# 여러 버전 설치 시 기본 Java 전환
|
||||
sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java
|
||||
```
|
||||
|
||||
> **참고**: Java 17은 2026-03-31 Jenkins 지원 종료. Java 21 사용 필수.
|
||||
|
||||
### ④ Gitea
|
||||
|
||||
```bash
|
||||
@@ -746,11 +752,11 @@ done
|
||||
|
||||
| 저장소 | hook 대상 브랜치 | 동작 |
|
||||
|--------|-----------------|------|
|
||||
| sam-react-prod | stage, develop | CI/CD Gitea에 push |
|
||||
| sam-api | stage | CI/CD Gitea에 push |
|
||||
| sam-react-prod | main, develop | CI/CD Gitea에 push |
|
||||
| sam-api | main | CI/CD Gitea에 push |
|
||||
| sam-manage | main | CI/CD Gitea에 push (2026-02-24 추가) |
|
||||
| sam-sales | main | CI/CD Gitea에 push |
|
||||
| sam-landing | main | CI/CD Gitea에 push |
|
||||
| sam-manage | ❌ 없음 | main만 사용, 배포관리자 수동 push |
|
||||
|
||||
### ⑥ Jenkins
|
||||
|
||||
@@ -765,11 +771,11 @@ echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.gpg]" \
|
||||
sudo apt update
|
||||
sudo apt install -y jenkins
|
||||
|
||||
# JVM 메모리 제한
|
||||
# JVM 옵션 (메모리 + CSP)
|
||||
sudo mkdir -p /etc/systemd/system/jenkins.service.d
|
||||
sudo tee /etc/systemd/system/jenkins.service.d/override.conf > /dev/null << 'EOF'
|
||||
[Service]
|
||||
Environment="JAVA_OPTS=-Xmx2048m -Xms512m -Djava.awt.headless=true"
|
||||
Environment="JAVA_OPTS=-Xmx2048m -Xms512m -Djava.awt.headless=true -Dhudson.model.DirectoryBrowserSupport.CSP=\"default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:;\""
|
||||
EOF
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
@@ -810,6 +816,64 @@ sudo -u jenkins ssh-keyscan -H 114.203.209.83 >> /var/lib/jenkins/.ssh/known_hos
|
||||
- `deploy-ssh-key`: SSH 키 (hskwon@운영/개발 서버 공용)
|
||||
- `gitea-api-token`: Gitea API 토큰
|
||||
|
||||
**분산 빌드 설정 (Built-in Node 보안 격리):**
|
||||
|
||||
```bash
|
||||
# 1. Built-in Node executor를 0으로 변경 (Jenkins 정지 상태에서)
|
||||
sudo systemctl stop jenkins
|
||||
sudo sed -i 's|<numExecutors>2</numExecutors>|<numExecutors>0</numExecutors>|' /var/lib/jenkins/config.xml
|
||||
# Agent 포트 활성화 (0 = 랜덤 포트)
|
||||
sudo sed -i 's|<slaveAgentPort>-1</slaveAgentPort>|<slaveAgentPort>0</slaveAgentPort>|' /var/lib/jenkins/config.xml
|
||||
|
||||
# 2. Agent workspace 디렉토리
|
||||
sudo mkdir -p /var/lib/jenkins-agent/workspace
|
||||
sudo chown -R jenkins:jenkins /var/lib/jenkins-agent
|
||||
|
||||
# 3. Agent 노드 설정
|
||||
sudo mkdir -p /var/lib/jenkins/nodes/local-agent
|
||||
# config.xml 생성 (JNLP WebSocket, executor 2, label: build)
|
||||
sudo chown -R jenkins:jenkins /var/lib/jenkins/nodes/local-agent
|
||||
|
||||
# 4. Jenkins 시작 → Agent secret 확인 (UI 또는 Groovy 스크립트)
|
||||
sudo systemctl start jenkins
|
||||
|
||||
# 5. Agent jar 다운로드
|
||||
sudo curl -sL http://localhost:8080/jnlpJars/agent.jar -o /var/lib/jenkins-agent/agent.jar
|
||||
sudo chown jenkins:jenkins /var/lib/jenkins-agent/agent.jar
|
||||
|
||||
# 6. Agent systemd 서비스
|
||||
sudo tee /etc/systemd/system/jenkins-agent.service > /dev/null << 'AGENTEOF'
|
||||
[Unit]
|
||||
Description=Jenkins Build Agent
|
||||
After=network.target jenkins.service
|
||||
Wants=jenkins.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=jenkins
|
||||
Group=jenkins
|
||||
WorkingDirectory=/var/lib/jenkins-agent
|
||||
ExecStart=/usr/bin/java -jar /var/lib/jenkins-agent/agent.jar \
|
||||
-url http://localhost:8080/ \
|
||||
-secret <AGENT_SECRET> \
|
||||
-name local-agent \
|
||||
-workDir /var/lib/jenkins-agent \
|
||||
-webSocket
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
AGENTEOF
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable jenkins-agent
|
||||
sudo systemctl start jenkins-agent
|
||||
```
|
||||
|
||||
> **참고**: Agent secret은 Jenkins UI > Manage Jenkins > Nodes > local-agent에서 확인하거나,
|
||||
> init.groovy.d 스크립트로 추출 가능.
|
||||
|
||||
### ⑦ Nginx + SSL (CI/CD)
|
||||
|
||||
**리버스 프록시 설정:**
|
||||
|
||||
Reference in New Issue
Block a user