# ============================================================================ # 06 — Setup Let's Encrypt SSL cho 3 domain qua win-acme # PREREQUISITE: # - DNS đã trỏ 3 domain về IP VPS (103.124.94.58) # - IIS sites đã bind với host header đúng # - Port 80 mở từ internet (cho HTTP-01 challenge) # ============================================================================ #Requires -RunAsAdministrator $ErrorActionPreference = 'Stop' $wacs = 'C:\Tools\win-acme\wacs.exe' $email = 'admin@ski-ump.com.vn' # TODO: đổi email contact if (-not (Test-Path $wacs)) { Write-Error "win-acme chưa cài. Chạy 01-install-prerequisites.ps1 trước." exit 1 } # --- CHECK DNS --------------------------------------------------------------- $domains = @('api.ski-ump.com.vn', 'ski-ump.com.vn', 'admin.ski-ump.com.vn') $vpsIp = '103.124.94.58' Write-Host "Checking DNS resolution (phải trỏ về $vpsIp) ..." -ForegroundColor Cyan $allOk = $true foreach ($d in $domains) { try { $resolved = (Resolve-DnsName $d -Type A -ErrorAction Stop | Where-Object { $_.Type -eq 'A' } | Select-Object -First 1).IPAddress if ($resolved -eq $vpsIp) { Write-Host " [OK] $d -> $resolved" -ForegroundColor Green } else { Write-Host " [FAIL] $d -> $resolved (expected $vpsIp)" -ForegroundColor Red $allOk = $false } } catch { Write-Host " [FAIL] $d -> DNS not resolvable" -ForegroundColor Red $allOk = $false } } if (-not $allOk) { Write-Host "" Write-Host "DNS chưa sẵn sàng. Cần cấu hình A record cho 3 domain về $vpsIp trước." -ForegroundColor Red Write-Host "Vào DNS provider (Cloudflare/GoDaddy/...) tạo:" -ForegroundColor Yellow Write-Host " api.ski-ump.com.vn A $vpsIp" Write-Host " ski-ump.com.vn A $vpsIp" Write-Host " admin.ski-ump.com.vn A $vpsIp" Write-Host " (plus) www.ski-ump.com.vn CNAME ski-ump.com.vn" Write-Host "" Write-Host "Đợi ~15 phút cho DNS propagation rồi chạy lại script này." exit 1 } # --- ISSUE CERTIFICATE ------------------------------------------------------- Write-Host "" Write-Host "Issuing Let's Encrypt cert cho 3 domain..." -ForegroundColor Cyan $sites = @( @{ Domain = 'api.ski-ump.com.vn'; IISSite = 'DYD.Api' }, @{ Domain = 'ski-ump.com.vn'; IISSite = 'DYD.User' }, @{ Domain = 'admin.ski-ump.com.vn'; IISSite = 'DYD.Admin' } ) foreach ($s in $sites) { Write-Host "" Write-Host "==========================================" -ForegroundColor Cyan Write-Host " SSL for $($s.Domain) -> $($s.IISSite)" -ForegroundColor Cyan Write-Host "==========================================" -ForegroundColor Cyan # Non-interactive mode & $wacs ` --target manual ` --host $s.Domain ` --installation iis ` --installationsiteid (Get-Website -Name $s.IISSite).Id ` --emailaddress $email ` --accepttos if ($LASTEXITCODE -ne 0) { Write-Host " [FAIL] Issue cert for $($s.Domain) (exit $LASTEXITCODE)" -ForegroundColor Red } else { Write-Host " [OK] Cert issued and bound to $($s.IISSite)" -ForegroundColor Green } } # --- FORCE HTTPS REDIRECT ---------------------------------------------------- Write-Host "" Write-Host "Adding HTTP→HTTPS redirect on all 3 sites..." -ForegroundColor Cyan # Trên mỗi site, URL Rewrite rule để 301 redirect HTTP → HTTPS # Có thể làm ở web.config nhưng cho API phải cẩn thận (stdout log) # Simplest: enable HTTPS only binding, remove HTTP binding foreach ($s in $sites) { # Không remove HTTP binding vì Let's Encrypt cần port 80 để renew # Dùng URL Rewrite trong web.config hoặc HSTS Write-Host " $($s.IISSite): HTTPS cert đã bound. (HTTP binding để Let's Encrypt renew)" -ForegroundColor Yellow } # --- VERIFY ------------------------------------------------------------------ Write-Host "" Write-Host "Verify bindings:" -ForegroundColor Cyan Get-WebBinding | Where-Object { $_.bindingInformation -match 'dyd' } | Format-Table protocol, bindingInformation -AutoSize Write-Host "" Write-Host "=========================================================" -ForegroundColor Green Write-Host " SSL setup done" -ForegroundColor Green Write-Host "=========================================================" -ForegroundColor Green Write-Host "" Write-Host "Test:" foreach ($s in $sites) { Write-Host " curl -I https://$($s.Domain)" } Write-Host "" Write-Host "Auto-renewal: win-acme tạo Scheduled Task tự động (daily check, renew 30 ngày trước expiry)."