서버 인증서가 예고 없이 만료되면 사용자와 고객에게 다양한 문제가 발생합니다. 사이트와의 보안 연결이 실패하거나, 인증 오류가 나타나거나, 브라우저에서 성가신 경고 알림이 표시될 수 있습니다. 이 글에서는 원격 사이트의 SSL/TLS 인증서 만료 날짜를 확인하는 방법과, 도메인 내 서버·PC의 로컬 인증서 저장소에서 곧 만료되는 인증서 목록을 추출하는 방법을 소개합니다.
PowerShell로 웹사이트 SSL 인증서 만료 날짜 확인하기
많은 웹 프로젝트가 HTTPS 구현을 위해 무료 Let's Encrypt SSL 인증서를 사용합니다. 이 인증서는 90일 유효 기간으로 발급되며 정기적인 갱신이 필요합니다. 일반적으로 호스팅이나 서버 측에서 특수 스크립트나 봇(Windows의 WACS, Linux의 Certbot 등)이 Let's Encrypt 인증서를 자동 갱신해 주지만, 때때로 자동 갱신에 실패하는 경우가 있습니다.
그래서 웹사이트의 SSL 인증서 만료 날짜를 점검하고, 만료가 임박했을 때 알림을 받을 수 있는 자체 스크립트를 만들어 두면 유용합니다. PowerShell로 이를 구현할 수 있으며, HttpWeb 요청을 통해 웹사이트의 인증서를 조회하는 방식이므로 원격 웹 서버에 관리자 권한이 필요하지 않습니다.
아래 PowerShell 스크립트에서는 인증서 만료 날짜를 확인할 웹사이트 목록과, 알림을 표시하기 시작할 남은 유효 기간($minCertAge)을 지정해야 합니다. 예시로는 80일을 입력했습니다.
$minCertAge = 80
$timeoutMs = 10000
$sites = @(
"https://testsite1.com/",
"https://testsite2.com/",
"https://woshub.com/"
)
# 인증서 유효성 검사 비활성화
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
foreach ($site in $sites)
{
Write-Host Check $site -f Green
$req = [Net.HttpWebRequest]::Create($site)
$req.Timeout = $timeoutMs
try {$req.GetResponse() |Out-Null} catch {Write-Host URL check error $site`: $_ -f Red}
$expDate = $req.ServicePoint.Certificate.GetExpirationDateString()
$certExpDate = [datetime]::ParseExact($expDate, "dd/MM/yyyy HH:mm:ss", $null)
[int]$certExpiresIn = ($certExpDate - $(get-date)).Days
$certName = $req.ServicePoint.Certificate.GetName()
$certThumbprint = $req.ServicePoint.Certificate.GetCertHashString()
$certEffectiveDate = $req.ServicePoint.Certificate.GetEffectiveDateString()
$certIssuer = $req.ServicePoint.Certificate.GetIssuerName()
if ($certExpiresIn -gt $minCertAge)
{Write-Host The $site certificate expires in $certExpiresIn days [$certExpDate] -f Green}
else
{
$message= "The $site certificate expires in $certExpiresIn days"
$messagetitle= "Renew certificate"
Write-Host $message [$certExpDate]. Details:`n`nCert name: $certName`Cert thumbprint: $certThumbprint`nCert effective date: $certEffectiveDate`nCert issuer: $certIssuer -f Red
# 팝업 알림 표시 및 관리자에게 이메일 전송
#ShowNotification $messagetitle $message
# Send-MailMessage -From powershell@woshub.com -To admin@woshub.com -Subject $messagetitle -body $message -SmtpServer gwsmtp.woshub.com -Encoding UTF8
}
write-host "________________" `n
}
이 스크립트는 목록에 포함된 모든 웹사이트의 SSL 인증서를 점검하고, 만료가 임박한 인증서가 발견되면 해당 항목을 강조하여 알려줍니다.
SSL 인증서 만료가 임박했다는 사실을 관리자에게 알리려면 팝업 알림을 추가할 수 있습니다. 스크립트에서 "ShowNotification $messagetitle $message" 줄의 주석을 해제하고 아래 함수를 함께 추가하세요.
Function ShowNotification ($MsgTitle, $MsgText) {
Add-Type -AssemblyName System.Windows.Forms
$global:balmsg = New-Object System.Windows.Forms.NotifyIcon
$path = (Get-Process -id $pid).Path
$balmsg.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balmsg.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Warning
$balmsg.BalloonTipText = $MsgText
$balmsg.BalloonTipTitle = $MsgTitle
$balmsg.Visible = $true
$balmsg.ShowBalloonTip(10000)
}
Send-MailMessage cmdlet을 사용하면 이메일 알림도 보낼 수 있습니다. 이렇게 하면 만료되었거나 곧 만료될 인증서가 발견될 때마다 이메일과 팝업 메시지로 알림을 받게 됩니다.
마지막으로 작업 스케줄러(Task Scheduler)에 주 1~2회 실행되는 자동 작업을 등록하여, HTTPS 웹사이트 인증서 만료 날짜를 주기적으로 점검하도록 설정하세요. (Register-ScheduledTask cmdlet을 사용하면 PS1 스크립트 파일을 실행하는 작업을 손쉽게 생성할 수 있습니다.)
원격으로 Windows 인증서 저장소의 만료 인증서 확인하는 방법
도메인 서버에서 암호화 서비스가 사용하는 인증서(RDP/RDS, Exchange, SharePoint, LDAPS 인증서 등)나 사용자 PC의 인증서 만료 날짜도 점검해야 할 수 있습니다.
로컬 컴퓨터에서는 다음 명령으로 인증서 목록을 가져올 수 있습니다.
Get-ChildItem -Path cert
PowerShell 3.0부터는 전용 -ExpiringInDays 매개변수를 제공합니다.
Get-ChildItem -Path cert: -Recurse -ExpiringInDays 30
PowerShell 2.0 환경이라면 동일한 작업을 다음과 같이 수행할 수 있습니다.
Get-ChildItem -Path cert: -Recurse | where { $_.notafter -le (get-date).AddDays(30) -AND $_.notafter -gt (get-date)} | select thumbprint, subject
자체 발급 인증서만 점검하려면 루트 폴더의 Cert: 대신 Cert:\LocalMachine\My 컨테이너를 사용하세요. 이렇게 하면 Windows 신뢰할 수 있는 루트 인증서나 상용 인증서까지 불필요하게 검사하는 것을 피할 수 있습니다.
도메인의 모든 서버에서 향후 30일 이내에 만료될 인증서를 찾으려면 아래 PowerShell 스크립트를 사용하세요.
$servers= (Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(operatingSystem=Windows Server*) (!serviceprincipalname=*MSClusterVirtualServer*) (!(userAccountControl:1.2.840.113556.1.4.803:=2)))").Name
$result=@()
foreach ($server in $servers)
{
$ErrorActionPreference="SilentlyContinue"
$getcert=Invoke-Command -ComputerName $server { Get-ChildItem -Path Cert:\LocalMachine\My -Recurse -ExpiringInDays 30}
foreach ($cert in $getcert) {
$result+=New-Object -TypeName PSObject -Property ([ordered]@{
'Server'=$server;
'Certificate'=$cert.Issuer;
'Expires'=$cert.NotAfter
})
}
}
Write-Output $result
스크립트를 실행하면 곧 만료될 서버 인증서 목록을 얻을 수 있으며, 인증서가 실제로 만료되기 전에 미리 갱신할 충분한 시간을 확보할 수 있습니다.