Win-acme Configuration with acme-dns Server

Connecting Windows ACME Client to ssl.anytrust.ch

This guide explains how to configure win-acme (Windows ACME client) to use your acme-dns server at ssl.anytrust.ch for automated certificate management on Windows servers.

Prerequisites

On Your acme-dns Server (ssl.anytrust.ch)

Ensure your acme-dns server is:

  • ✅ Running and accessible via HTTPS (port 443)
  • ✅ DNS service operational (port 53)
  • ✅ Registration enabled (or you have existing credentials)

Test accessibility from your Windows machine:

# Test API endpoint (run in PowerShell)
Invoke-WebRequest -Uri "https://ssl.anytrust.ch/health" -UseBasicParsing

# Test DNS resolution
nslookup ssl.anytrust.ch

Part 1: Win-acme Installation

1. Download and Install win-acme

  1. Download the correct version:

    • Visit: https://github.com/win-acme/win-acme/releases
    • Download: win-acme.v2.2.x.xxxx.x64.pluggable.zip (64-bit pluggable version)
    • CRITICAL: You MUST use the “pluggable” version - the trimmed version does NOT include DNS plugins!
    • DO NOT download the “trimmed” version as it lacks plugin support

  2. Extract to a permanent location:

    # Recommended installation path
    C:\Tools\win-acme\
       
    # Or use Program Files
    C:\Program Files\win-acme\
    
  3. Verify installation:

    cd C:\Tools\win-acme
    .\wacs.exe --version
    

2. Verify acme-dns Support

The acme-dns validation is built into win-acme since v2.1.x. Verify it’s available:

# Start win-acme with verbose output to see loaded plugins
.\wacs.exe --verbose

# Look for "acme-dns" in the validation plugins list
# You should see it listed as an available DNS validation method

# Alternative: Check available validations
.\wacs.exe --help

# Look for --validation acme-dns in the help output

Note: You won’t find specific acme-dns DLL files - the support is integrated into the core pluggable build. If you don’t see acme-dns as an option:

  • Ensure you downloaded the “pluggable” version, not “trimmed”
  • Check you have at least version 2.1.x or newer
  • Try running with administrator privileges

Part 2: Register with acme-dns

3. Register Your Domain with acme-dns

First, you need to register with your acme-dns server and get credentials:

Option A: Using PowerShell:

# Register with acme-dns
$response = Invoke-RestMethod -Method Post -Uri "https://ssl.anytrust.ch/register"

# Display credentials (SAVE THESE!)
$response | ConvertTo-Json

# Example output:
# {
#   "username": "6d4ca3ef-1c73-4911-8400-6f7b2c74cf3e",
#   "password": "hPqY6QYXG2mKvJbkoRwm8BVvdUwJ1FQ9T7WS5mm3",
#   "fulldomain": "6d4ca3ef-1c73-4911-8400-6f7b2c74cf3e.ssl.anytrust.ch",
#   "subdomain": "6d4ca3ef-1c73-4911-8400-6f7b2c74cf3e",
#   "allowfrom": []
# }

# Save to file for reference
$response | ConvertTo-Json | Out-File -FilePath "C:\Tools\win-acme\acme-dns-credentials.json"

Option B: Using curl (if available):

curl -X POST https://ssl.anytrust.ch/register

4. Create CNAME Record

Add a CNAME record in your domain’s DNS pointing to the acme-dns subdomain:

# In your domain's DNS (e.g., example.com)
_acme-challenge.example.com.  CNAME  6d4ca3ef-1c73-4911-8400-6f7b2c74cf3e.ssl.anytrust.ch.

# For wildcard certificates
_acme-challenge.example.com.  CNAME  6d4ca3ef-1c73-4911-8400-6f7b2c74cf3e.ssl.anytrust.ch.

Verify CNAME is working:

nslookup _acme-challenge.example.com
# Should resolve to: 6d4ca3ef-1c73-4911-8400-6f7b2c74cf3e.ssl.anytrust.ch

Part 3: Configure win-acme

5. Create acme-dns Configuration File (Optional)

Win-acme can store acme-dns credentials automatically, but you can also pre-configure them:

Automatic Storage: Win-acme stores credentials in C:\ProgramData\win-acme\acmedns.json

Manual Pre-configuration: If you want to pre-register domains:

# The configuration is stored automatically after first use
# Location: C:\ProgramData\win-acme\acmedns.json

# If you want to view or edit existing registrations:
Get-Content "C:\ProgramData\win-acme\acmedns.json" | ConvertFrom-Json

# Format is:
# {
#   "example.com": {
#     "BaseUri": "https://ssl.anytrust.ch",
#     "Registration": {
#       "username": "uuid-here",
#       "password": "password-here",
#       "fulldomain": "uuid.ssl.anytrust.ch",
#       "subdomain": "uuid",
#       "allowfrom": []
#     }
#   }
# }

6. Run win-acme Interactive Mode

Start win-acme in interactive mode to create a new certificate:

cd C:\Tools\win-acme
.\wacs.exe

Follow these steps in the interactive menu:

Main Menu:
N: Create certificate (default settings)
M: Create certificate (full options)

Choose: N

Select source:
1: Manual input
2: IIS (if available)

Choose: 1

Enter host: example.com

Select validation:
1: [http-01] ...
2: [dns-01] acme-dns
3: [dns-01] Script
...

Choose: 2 (acme-dns)

Enter acme-dns server URL: https://ssl.anytrust.ch
(Press Enter if you've already registered this domain)

If this is the first time:
- The tool will register with acme-dns
- You'll be shown the CNAME record to create
- Create the CNAME in your DNS before continuing

Select how to store the certificate:
1: Windows Certificate Store
2: PEM files
3: PFX file

Choose based on your needs

Select installation method:
1: None
2: IIS (if applicable)
3: Script

Choose based on your application

7. Alternative: Command-Line Configuration

For automated deployment, use command-line parameters:

# Single domain certificate
.\wacs.exe --source manual --host example.com `
    --validation acme-dns `
    --acmednsserver https://ssl.anytrust.ch `
    --store pemfiles --pemfilespath "C:\Certificates\example.com" `
    --accepttos

# Wildcard certificate
.\wacs.exe --source manual --host "*.example.com" `
    --validation acme-dns `
    --acmednsserver https://ssl.anytrust.ch `
    --store certificatestore `
    --accepttos

# With IIS binding
.\wacs.exe --source iis --siteid 1 `
    --validation acme-dns `
    --acmednsserver https://ssl.anytrust.ch `
    --installation iis `
    --accepttos

Part 4: Advanced Configuration

8. Configure for IIS Integration

If using IIS, win-acme can automatically bind certificates:

# Interactive mode - choose IIS installation
.\wacs.exe

# Command line for IIS site
.\wacs.exe --source iis --siteid 1 `
    --validation acme-dns `
    --acmednsserver https://ssl.anytrust.ch `
    --installation iis `
    --accepttos

9. Set Up Scheduled Renewal

Win-acme automatically creates a scheduled task for renewal:

# View scheduled task
Get-ScheduledTask | Where-Object {$_.TaskName -like "*win-acme*"}

# Manual renewal check
.\wacs.exe --renew --baseuri https://acme-v02.api.letsencrypt.org/

# Force renewal
.\wacs.exe --renew --force

10. Multiple Domains Configuration

For multiple domains, create separate acme-dns registrations:

# Register each domain with acme-dns
$domains = @("example.com", "app.example.com", "api.example.com")

foreach ($domain in $domains) {
    # Register with acme-dns
    $response = Invoke-RestMethod -Method Post -Uri "https://ssl.anytrust.ch/register"
    
    # Save credentials
    $config = @{
        $domain = @{
            "username" = $response.username
            "password" = $response.password
            "fulldomain" = $response.fulldomain
            "subdomain" = $response.subdomain
            "allowfrom" = @()
            "baseurl" = "https://ssl.anytrust.ch"
        }
    }
    
    # Save to file
    $config | ConvertTo-Json -Depth 3 | Out-File "C:\ProgramData\win-acme\acmednsjson\$domain.json"
    
    # Output CNAME record needed
    Write-Host "Add CNAME: _acme-challenge.$domain -> $($response.fulldomain)"
}

Part 5: Testing and Validation

11. Test Certificate Acquisition

# Test mode (staging environment)
.\wacs.exe --test --source manual --host example.com `
    --validation acme-dns `
    --acmednsserver https://ssl.anytrust.ch `
    --store pemfiles --pemfilespath "C:\Certificates\test"

# Check acme-dns logs on server
# SSH to ssl.anytrust.ch and run:
# sudo journalctl -u acme-dns -f

12. Verify Certificate Installation

# Check certificate in store
Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*example.com*"}

# Check PEM files
Get-ChildItem -Path "C:\Certificates\example.com"

# Test HTTPS binding (if using IIS)
Start-Process "https://example.com"

Part 6: Troubleshooting

Common Issues and Solutions

Issue 1: Connection to acme-dns Failed

# Test connectivity
Test-NetConnection ssl.anytrust.ch -Port 443
Test-NetConnection ssl.anytrust.ch -Port 53

# Check TLS/SSL
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri "https://ssl.anytrust.ch/health"

Issue 2: DNS Validation Failed

# Verify CNAME record
nslookup _acme-challenge.example.com

# Test TXT record update
$updateData = @{
    txt = "test-validation-string"
} | ConvertTo-Json

$username = "your-username"
$password = "your-password"
$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${username}:${password}"))

Invoke-RestMethod -Method Post `
    -Uri "https://ssl.anytrust.ch/update" `
    -Headers @{Authorization = "Basic $auth"} `
    -Body $updateData `
    -ContentType "application/json"

# Verify TXT record
nslookup -type=TXT your-subdomain.ssl.anytrust.ch ssl.anytrust.ch

Issue 3: Certificate Not Binding to IIS

# Manual IIS binding
Import-Module WebAdministration

# List sites
Get-IISSite

# Add HTTPS binding
New-IISSiteBinding -Name "Default Web Site" -BindingInformation "*:443:" -Protocol https

# Bind certificate
$cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "example.com"}
$binding = Get-WebBinding -Name "Default Web Site" -Protocol https
$binding.AddSslCertificate($cert.Thumbprint, "My")

Enable Logging

# Enable debug logging in win-acme
.\wacs.exe --verbose

# Check win-acme logs
Get-Content "C:\ProgramData\win-acme\httpsacme-v02.api.letsencrypt.org\Log.txt" -Tail 50

Part 7: Automation Scripts

PowerShell Script for Bulk Certificate Management

# BulkCertificateSetup.ps1
param(
    [Parameter(Mandatory=$true)]
    [string[]]$Domains,
    
    [string]$AcmeDnsServer = "https://ssl.anytrust.ch",
    [string]$WacsPath = "C:\Tools\win-acme\wacs.exe"
)

foreach ($domain in $Domains) {
    Write-Host "Processing domain: $domain" -ForegroundColor Green
    
    # Register with acme-dns
    $registration = Invoke-RestMethod -Method Post -Uri "$AcmeDnsServer/register"
    
    # Save credentials
    $configPath = "C:\ProgramData\win-acme\acmednsjson\$domain.json"
    $config = @{
        $domain = @{
            username = $registration.username
            password = $registration.password
            fulldomain = $registration.fulldomain
            subdomain = $registration.subdomain
            allowfrom = @()
            baseurl = $AcmeDnsServer
        }
    }
    $config | ConvertTo-Json -Depth 3 | Out-File $configPath
    
    Write-Host "IMPORTANT: Add this CNAME record to your DNS:" -ForegroundColor Yellow
    Write-Host "_acme-challenge.$domain CNAME $($registration.fulldomain)" -ForegroundColor Cyan
    
    # Wait for DNS propagation
    Write-Host "Waiting for DNS propagation (press Enter when ready)..."
    Read-Host
    
    # Request certificate
    & $WacsPath --source manual --host $domain `
        --validation acme-dns `
        --acmednsserver $AcmeDnsServer `
        --store certificatestore `
        --accepttos
}

Renewal Check Script

# CheckRenewals.ps1
$wacsPath = "C:\Tools\win-acme\wacs.exe"

# Check all renewals
& $wacsPath --list

# Renew all due certificates
& $wacsPath --renew

# Send notification (optional)
$renewals = & $wacsPath --list | Select-String "Renewal due"
if ($renewals) {
    Send-MailMessage -To "admin@example.com" `
        -From "certificates@example.com" `
        -Subject "Certificate Renewals Processed" `
        -Body $renewals `
        -SmtpServer "smtp.example.com"
}

Part 8: Best Practices

Security Considerations

  1. Protect Credentials:

    # Set ACL on credentials file
    $acl = Get-Acl "C:\ProgramData\win-acme\acmednsjson"
    $acl.SetAccessRuleProtection($true, $false)
    $adminRule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators", "FullControl", "Allow")
    $systemRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM", "FullControl", "Allow")
    $acl.SetAccessRule($adminRule)
    $acl.SetAccessRule($systemRule)
    Set-Acl "C:\ProgramData\win-acme\acmednsjson" $acl
    
  2. Use Staging for Testing:

    # Always test with staging first
    .\wacs.exe --test --baseuri https://acme-staging-v02.api.letsencrypt.org/
    
  3. Monitor Certificate Expiry:

    # Certificate expiry check script
    Get-ChildItem -Path Cert:\LocalMachine\My | 
       Where-Object {$_.NotAfter -lt (Get-Date).AddDays(30)} |
       Select-Object Subject, NotAfter
    

Production Deployment Checklist

  • [ ] acme-dns server accessible from Windows server
  • [ ] CNAME records created for all domains
  • [ ] win-acme installed with acme-dns plugin
  • [ ] Credentials stored securely in acmednsjson
  • [ ] Test certificates obtained from staging
  • [ ] Production certificates successfully issued
  • [ ] Automatic renewal scheduled task created
  • [ ] IIS bindings configured (if applicable)
  • [ ] Monitoring and alerting configured
  • [ ] Documentation updated with domain mappings

Quick Reference

Key File Locations

# win-acme installation
C:\Tools\win-acme\

# Configuration files
C:\ProgramData\win-acme\

# acme-dns credentials
C:\ProgramData\win-acme\acmednsjson\

# Certificates (default)
C:\ProgramData\win-acme\certificates\

# Logs
C:\ProgramData\win-acme\httpsacme-v02.api.letsencrypt.org\Log.txt

Essential Commands

# New certificate
.\wacs.exe

# List certificates
.\wacs.exe --list

# Renew all
.\wacs.exe --renew

# Force renewal
.\wacs.exe --renew --force

# Test mode
.\wacs.exe --test

# Cancel renewal
.\wacs.exe --cancel

# Verbose logging
.\wacs.exe --verbose

acme-dns API Commands

# Register new account
Invoke-RestMethod -Method Post -Uri "https://ssl.anytrust.ch/register"

# Update TXT record (with auth)
Invoke-RestMethod -Method Post -Uri "https://ssl.anytrust.ch/update" `
    -Headers @{Authorization = "Basic [base64-encoded-credentials]"} `
    -Body '{"txt":"validation-string"}' `
    -ContentType "application/json"

# Health check
Invoke-WebRequest -Uri "https://ssl.anytrust.ch/health"

This completes the comprehensive guide for using win-acme with your acme-dns server at ssl.anytrust.ch!