# 보안 설정 가이드 > **버전**: 1.0.0 > **최종 수정**: 2026-05-25 > **참고 기준**: NIST SP 800-53, 행안부 정보보안 관리체계 --- ## 1. 개요 CI/CD 파이프라인에서 취급하는 민감 정보: | 종류 | 예시 | 보관 방법 | |------|------|----------| | SSH 키 | 배포 서버 SSH 개인키 | Jenkins Credentials (SSH Key) | | 서비스 계정 토큰 | ITSM API Token | Jenkins Credentials (Secret Text) | | DB 접속 정보 | SonarQube DB Password | Jenkins Credentials (Username+Password) | | 배포 서버 정보 | 서버 IP/포트 | Jenkins Credentials / Config File | **절대 금지 사항**: - Jenkinsfile 또는 스크립트에 민감 정보 하드코딩 - Git 저장소에 자격증명 커밋 - 빌드 로그에 비밀번호/토큰 출력 --- ## 2. Jenkins Credentials 관리 ### 2-1. Credentials 종류 및 용도 | Credential ID | 종류 | 용도 | |--------------|------|------| | `git-credentials` | Username+Password (또는 SSH Key) | Git 소스 체크아웃 | | `ssh-{서버명}` | SSH Username+Private Key | 배포 서버 SSH 접속 | | `itsm-api-token` | Secret Text | GUARDiA ITSM API 호출 | | `sonar-token` | Secret Text | SonarQube 분석 | | `deploy-key-prd` | SSH Username+Private Key | 운영 서버 배포 전용 | ### 2-2. SSH Credentials 등록 Jenkins 관리 → Credentials → System → Global credentials → Add Credentials: ``` Kind: SSH Username with private key Scope: Global ID: ssh-app-server-01 Description: APP-SERVER-01 배포 SSH Key Username: deploy Private Key: [Enter directly] → 개인키 내용 붙여넣기 Passphrase: (있는 경우 입력) ``` ### 2-3. Secret Text 등록 (API Token) ``` Kind: Secret text Scope: Global ID: itsm-api-token Description: GUARDiA ITSM API Token Secret: <토큰값> ``` ### 2-4. Jenkinsfile에서 Credentials 사용 ```groovy // SSH Key 사용 withCredentials([sshUserPrivateKey( credentialsId: 'ssh-app-server-01', keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER' )]) { sh "ssh -i ${SSH_KEY} ${SSH_USER}@${TARGET_HOST} 'systemctl status tomcat'" } // Secret Text 사용 withCredentials([string( credentialsId: 'itsm-api-token', variable: 'ITSM_TOKEN' )]) { sh "curl -H 'Authorization: Bearer ${ITSM_TOKEN}' ${ITSM_URL}/api/health" } // Username+Password 사용 withCredentials([usernamePassword( credentialsId: 'sonar-credentials', usernameVariable: 'SONAR_USER', passwordVariable: 'SONAR_PASS' )]) { sh "mvn sonar:sonar -Dsonar.login=${SONAR_USER} -Dsonar.password=${SONAR_PASS}" } ``` --- ## 3. RBAC (역할 기반 접근 제어) ### 3-1. Role Strategy Plugin 설정 Jenkins 관리 → Security → Authorization → Role-Based Strategy #### Global Roles | Role | 권한 | 대상 | |------|------|------| | `admin` | 전체 | Jenkins 관리자 | | `pm` | Job Read/Build, View | PM/프로젝트 관리자 | | `developer` | Job Read/Build (dev 한정), View | 개발자 | | `viewer` | Job Read, View | 감사/보안 담당 | #### Project Roles (정규식 매핑) | Role | 대상 Job 패턴 | 권한 | |------|-------------|------| | `dev-deployer` | `.*-dev$` | Build, Cancel, Read | | `prd-deployer` | `.*-prd$` | Build, Cancel, Read | | `rollback-only` | `.*-rollback$` | Build, Read | ### 3-2. 운영 배포 2인 승인 규칙 `main`, `hotfix/*` 브랜치 배포는 반드시 2명이 승인: ```groovy stage('Production Approval') { steps { script { def approvers = [] def required = 2 timeout(time: 60, unit: 'MINUTES') { for (int i = 0; i < required; i++) { def approval = input( message: "운영 배포 ${i+1}/${required}차 승인", ok: "승인", submitterParameter: "APPROVER_${i+1}" ) approvers << approval echo "승인자 ${i+1}: ${approval}" } } env.APPROVERS = approvers.join(', ') } } } ``` --- ## 4. 네트워크 보안 ### 4-1. Jenkins 접근 IP 제한 ```nginx # Nginx에서 허용 IP 제한 location / { allow 10.0.0.0/8; # 내부망 allow 192.168.0.0/16; # 내부망 deny all; proxy_pass http://jenkins; } ``` ```bash # firewalld에서 특정 IP만 허용 sudo firewall-cmd --permanent --add-rich-rule=' rule family="ipv4" source address="10.0.0.0/8" port protocol="tcp" port="8080" accept' sudo firewall-cmd --reload ``` ### 4-2. 배포 서버 SSH 보안 ```bash # 배포 서버 /etc/ssh/sshd_config 설정 # Jenkins 전용 deploy 계정만 허용 AllowUsers deploy jenkins-agent PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys # deploy 계정 SSH sudo 제한 (특정 명령만) # /etc/sudoers.d/jenkins-deploy deploy ALL=(root) NOPASSWD: /bin/systemctl restart tomcat9, \ /bin/systemctl restart nginx, \ /opt/jeus/bin/stopServer, \ /opt/jeus/bin/startServer ``` --- ## 5. 빌드 로그 보안 ### 5-1. 민감 정보 마스킹 `Mask Passwords` 플러그인 사용: ```groovy options { maskPasswords() } ``` Jenkins 관리 → System → Mask Passwords: - Global Passwords에 패턴 등록: `PASSWORD`, `TOKEN`, `SECRET`, `KEY` ### 5-2. 로그 보존 정책 ```groovy options { buildDiscarder(logRotator( numToKeepStr: '30', // 30개 빌드 보관 artifactNumToKeepStr: '10', // 아티팩트 10개 보관 daysToKeepStr: '90' // 90일 이전 자동 삭제 )) } ``` --- ## 6. 아티팩트 보안 ### 6-1. 아티팩트 체크섬 검증 ```bash # 빌드 후 SHA256 체크섬 생성 sha256sum target/*.jar > target/checksums.sha256 # 배포 전 검증 sha256sum -c checksums.sha256 ``` ### 6-2. 아티팩트 접근 제한 ```bash # 아티팩트 디렉터리 권한 설정 sudo mkdir -p /opt/artifacts sudo chown jenkins:jenkins /opt/artifacts sudo chmod 750 /opt/artifacts ``` --- ## 7. 감사 로그 (Audit Trail) `Audit Trail Plugin` 설치 후: Jenkins 관리 → System → Audit Trail: - Log Location: `/var/log/jenkins/audit.log` - Log File Size: 100 MB - Log File Count: 30 기록 항목: - 로그인/로그아웃 - 자격증명 접근 - 잡 빌드 시작/중단 - 설정 변경 --- ## 8. Jenkins 보안 설정 체크리스트 | 항목 | 상태 | 비고 | |------|------|------| | CSRF Protection 활성화 | ✓ | 기본 활성화 | | 익명 사용자 접근 차단 | ✓ | Authorization: Role-Based | | 빌드 에이전트 인증 | ✓ | SSH or JNLP with secret | | Credentials 암호화 | ✓ | Jenkins master key 사용 | | 보안 업데이트 정기 적용 | 주 1회 | 매주 일요일 자동 업데이트 확인 | | 사용하지 않는 플러그인 제거 | ✓ | 분기별 점검 | | HTTPS 적용 | 내부망 선택 | 외부 연동 시 필수 | | 빌드 로그 민감정보 마스킹 | ✓ | Mask Passwords Plugin | | 운영 배포 2인 승인 | ✓ | input() step | | 감사 로그 활성화 | ✓ | Audit Trail Plugin |