💥이슈 사항
- Forward proxy 의 인증서는 사설인증서이며, 윈도우 (Win-root) 경로엔 존재하지만
개발툴(gradle, jdk, python, docker, npm)이 참조하는 신뢰저장소 파일엔 Forward proxy 인증서가 없어 인증서 검증 우회 옵션을 하지 않으면 서비스가 되지 않은 이슈
- 사용자별 사용하는 툴, 언어 버전, 설치 경로 등을 한정할 수 없음
🙋♀️ 프로그램별 신뢰저장소 경로, 파일 형식
프로그램 | 설명 | 신뢰저장소 파일(형식) |
jdk | jdk{버전}/lib/security/cacerts | cacerts (jks) |
maven | maven이 사용하는 jdk버전 하위의 cacerts 파일 | cacerts (jks) |
gradle | gradle이 사용하는 jdk버전 하위의 cacerts 파일 | cacerts (jks) |
python | certifi 패키지의 cacert.pem | cacert.pem |
conda | cert.pem | |
node/npm | OS에 따라 다르며 Node.js 내장 인증서를 사용 | cert.pem |
git | cert.pem | |
curl | cert.pem | |
docker | cacert.crt |
💛 해결방안
1. 프로그램 별 win-root 경로 설정하기
2. 프로그램 별 참조하는 신뢰 인증서 파일 변경
-
(1) jks 형식파일 ( jdk )
가.
.\keytool.exe -import -file 'D:Forwardproxy.crt' -keystore 'D:\jdk-24\lib\security\cacerts' -storepass "chageit" |
나. 신뢰저장소 파일 대체
# 1. 대체할 파일 경로 지정 $sourceFile = "D:\cacerts_new" # 2. 시스템에 연결된 모든 드라이브 확인 # ❗개발자가 사용하는 모든 jdk 버전, gradle, maven jdk 버전에 적용시키기 위함 $drives = Get-PSDrive -PSProvider FileSystem | Where-Object { Test-Path "$($_.Root)" } # 3. 각 드라이브에서 cacerts 파일 찾고 대체 foreach ($drive in $drives) { Write-Host "Scanning drive: $($drive.Root)" $targetFiles = Get-ChildItem -Path $drive.Root -Recurse -Filter "cacerts" -ErrorAction SilentlyContinue foreach ($file in $targetFiles) { try { # 기존 cacerts 파일 백업 Copy-Item -Path $file.FullName -Destination "$($file.FullName).bak" -Force # cacerts 파일 덮어쓰기 Copy-Item -Path $sourceFile -Destination $file.FullName -Force Write-Host " Replaced: $($file.FullName)" } catch { Write-Host " Failed to replace: $($file.FullName) - $_" } } } |
# ================================================ # 모든 JDK의 cacerts에 인증서가 없으면 자동 삽입 # ================================================ # 📄 설정 $certPath = "D:\Forward.crt" $alias = "corp-forward-proxy" $storepass = "changeit" # 인증서 파일 확인 if (!(Test-Path $certPath)) { Write-Host "❌ 인증서 파일이 존재하지 않습니다: $certPath" exit 1 } # 드라이브 전체 검색 (C, D) $drives = @("D:\") # 결과 저장용 $patched = @() $skipped = @() $notfound = @() foreach ($drive in $drives) { Write-Host "`n🔍 드라이브 검색 중: $drive" # cacerts 경로 찾기 $matches = Get-ChildItem -Path $drive -Filter "cacerts" -Recurse -ErrorAction SilentlyContinue -Force -File | Where-Object { $_.FullName -match "\\lib\\security\\cacerts$" } foreach ($cacerts in $matches) { # 정확한 JDK base 경로 계산 $securityDir = Split-Path $cacertsPath -Parent # ...\lib\security $libDir = Split-Path $securityDir -Parent # ...\lib $jdkBase = Split-Path $libDir -Parent # ...\jdk-xx $keytoolPath = Join-Path $jdkBase "bin\keytool.exe" # ...\jdk-xx\bin\keytool.exe if (!(Test-Path $keytoolPath)) { Write-Host "⚠️ keytool 없음 (건너뜀): $keytoolPath" $notfound += $cacertsPath continue } Write-Host "🧩 발견: $cacertsPath" # 인증서 중복 확인 $result = & "$keytoolPath" -list -keystore "$cacertsPath" -storepass $storepass -alias $alias 2>&1 if ($result -match "trustedCertEntry") { Write-Host "⏭️ 이미 존재함 (건너뜀): $alias" $skipped += $cacertsPath continue } # 인증서 삽입 & "$keytoolPath" -importcert -trustcacerts -keystore "$cacertsPath" -storepass $storepass ` -file "$certPath" -alias $alias -noprompt if ($LASTEXITCODE -eq 0) { Write-Host "✅ 인증서 추가 완료: $cacertsPath" $patched += $cacertsPath } else { Write-Host "❌ 인증서 추가 실패: $cacertsPath" } } } # 결과 출력 Write-Host "`n================== 결과 요약 ==================" Write-Host "✅ 인증서가 추가된 cacerts 수: $($patched.Count)" Write-Host "⏭️ 이미 추가되어 건너뜀: $($skipped.Count)" Write-Host "⚠️ keytool 찾지 못한 cacerts: $($notfound.Count)" Write-Host "================================================" |
다. 스크립트 배포
(2) pem 형식 파일(npm,python,curl 등등)
가. . 신뢰저장소 파일에 추가
# ▶ 경로 설정 $certToAdd = "D:\forward.crt" # ▶ 인증서 파일 존재 확인 if (!(Test-Path $certToAdd)) { Write-Host "❌ 인증서 파일이 존재하지 않습니다: $certToAdd" exit 1 } # ▶ 추가 대상 파일명 리스트 $pemFileNames = @("cacert.pem", "cert.pem") # ▶ 전체 드라이브 스캔 대상 (C:과 D: 위주) $drives = @("C:\", "D:\") # ▶ 결과 저장용 $patchedFiles = @() $alreadyPatched = @() # ▶ 내용 준비 $certContent = Get-Content -Path $certToAdd -Raw foreach ($drive in $drives) { foreach ($pemFile in $pemFileNames) { Write-Host "🔍 $drive 드라이브에서 $pemFile 검색 중..." # cacert.pem 또는 cert.pem 찾기 $pemFiles = Get-ChildItem -Path $drive -Filter $pemFile -Recurse -ErrorAction SilentlyContinue -Force -File foreach ($pem in $pemFiles) { try { $backupPath = "$($pem.FullName).bak" Copy-Item $pem.FullName $backupPath -Force # 인증서가 이미 포함돼 있는지 확인 if (Select-String -Path $pem.FullName -Pattern ($certContent.Substring(0, 50)) -Quiet) { $alreadyPatched += $pem.FullName Write-Host "⚠️ 이미 인증서가 포함됨 (건너뜀): $($pem.FullName)" continue } # 줄바꿈 + 인증서 추가 Add-Content -Path $pem.FullName -Value "`r`n$certContent" $patchedFiles += $pem.FullName Write-Host "✅ 인증서 추가됨: $($pem.FullName)" } catch { Write-Host "❌ 처리 실패: $($pem.FullName) - $_" } } } } # ▶ 결과 출력 Write-Host "`n==== 처리 결과 ====" Write-Host "🔧 인증서가 추가된 파일 수: $($patchedFiles.Count)" Write-Host "⚠️ 이미 포함된 파일 수: $($alreadyPatched.Count)" |
다. 스크립트 배포
- GPO + PS1 배포 실행