본문 바로가기

카테고리 없음

신뢰저장소에 Forward Proxy 인증서 추가

💥이슈 사항

- 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 배포 실행