diff options
98 files changed, 232 insertions, 3282 deletions
diff --git a/appveyor.yml b/appveyor.yml index 36ab92a..9e5af8d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.1.10.{build} +version: 2.1.11.{build} image: Visual Studio 2019 platform: Any CPU shallow_clone: true diff --git a/build/create-artifacts.ps1 b/build/create-artifacts.ps1 index cb4a936..aa696b0 100644 --- a/build/create-artifacts.ps1 +++ b/build/create-artifacts.ps1 @@ -108,6 +108,7 @@ PluginRelease cloudflare plugin.validation.dns.cloudflare @( ) PluginRelease cloudflare plugin.validation.dns.digitalocean @( "DigitalOcean.API.dll", + "RestSharp.dll", "PKISharp.WACS.Plugins.ValidationPlugins.DigitalOcean.dll" ) diff --git a/dist/Scripts/ImportAzureADApplicationProxy.ps1 b/dist/Scripts/ImportAzureADApplicationProxy.ps1 new file mode 100644 index 0000000..bb484cc --- /dev/null +++ b/dist/Scripts/ImportAzureADApplicationProxy.ps1 @@ -0,0 +1,96 @@ +<#
+.SYNOPSIS
+Imports a cert from win-acme (WACS) renewal into Azure AD Application Proxy for all applications that are using it. You likely want to use a wildcard certificate for this purpose.
+
+.DESCRIPTION
+Note that this script is intended to be run via the install script plugin from win-acme (WACS) via the batch script wrapper. As such, we use positional parameters to avoid issues with using a dash in the cmd line.
+
+Proper information should be available here
+
+https://github.com/PKISharp/win-acme/wiki/Install-Script
+
+or more generally, here
+
+https://github.com/PKISharp/win-acme/wiki/Example-Scripts
+
+.PARAMETER PfxPath
+The absolute path to the pfx file that will be uploaded to Azure. Typically use '{CacheFile}'
+
+.PARAMETER CertPass
+The password for the pfx file. Typically use '{CachePassword}'
+
+.PARAMETER Username
+Username of account to login with Connect-AzureAD. This account must have the "Application administrator" role to allow it to change the proxy certificate.
+
+.PARAMETER Password
+Password for the azure account
+
+.EXAMPLE
+
+ImportAzureApplicationGateway.ps1 <PfxPath> <CertPass>
+
+.NOTES
+Wanted to use a service principal instead of an account for this, but since there is a bug with the cmdlets used, we can't. Instead a regular account must be specified.
+https://github.com/Azure/azure-docs-powershell-azuread/issues/200
+
+
+#>
+
+param(
+ [Parameter(Position=0,Mandatory=$false)][string]$PfxPath,
+ [Parameter(Position=1,Mandatory=$true)][string]$CertPass,
+ [Parameter(Position=2,Mandatory=$true)][string]$Username,
+ [Parameter(Position=3,Mandatory=$true)][string]$Password
+
+
+)
+
+# Convert the password for the certificate to a secure string
+$SecureCertPass = ConvertTo-SecureString -String $CertPass -AsPlainText -Force
+
+
+if (!(Get-Command "Set-AzureAdApplicationProxyApplicationCustomDomainCertificate" -erroraction SilentlyContinue)) {
+ Throw "Missing AzureAD module, install with 'Install-Module -name AzureAD -Scope AllUsers'"
+}
+
+# Connect to Azure
+$Pass = ConvertTo-SecureString -String $Password -AsPlainText -Force
+$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $Pass
+$null = Connect-AzureAD -Credential $Credential
+
+
+# It's easier, apparently, to search for the service principals that are tagged with WindowsAzureActiveDirectoryOnPremApp,
+# then match them to the Get-AzureADApplication output by AppId.
+# Get-AzureADApplication doesn't have any way to filter only for ones using the application proxy, and
+# Get-AzureADApplicationProxyApplication requires an ObjectId, there's no way to just list them all.
+$aadapServPrinc = Get-AzureADServicePrincipal -Top 100000 | where-object {$_.Tags -Contains "WindowsAzureActiveDirectoryOnPremApp"}
+
+# Now we get a list of all Azure AD Applications
+$aadapps = Get-AzureADApplication -All $true
+
+# The AppId between $aadapServPrinc and $aadapps is the same for each of the applications using Azure AD Application Proxy.
+# What we need to get is the ObjectId from $aadapps for each application that was in $aadapServPrinc
+$aadproxyapps = $aadapServPrinc | Foreach-Object { $aadapps -match $_.AppId}
+# Now $aadaproxyapps has just the Get-AzureADApplication objects for applications that use the Azure AD Application Proxy.
+
+"Found $($aadproxyapps.count) applications to update"
+
+# Get the matching objects from Get-AzureADApplicationProxyApplication and show the certificate being used
+#$aadproxyapps | Foreach-Object {
+# $proxyapp = Get-AzureADApplicationProxyApplication -ObjectId $_.ObjectId
+# Write-Host "Checking $($proxyapp.ExternalUrl)"
+# Write-Host "Existing certificate is: $($proxyapp.VerifiedCustomDomainCertificatesMetadata)"
+#
+#}
+
+# The documentation says "If you have one certificate that includes many of your applications, you only need to upload it with one application and it will also be assigned to the other relevant applications."
+# That does not seem to be the case. Updating the certificate for one application only updated that single application, the rest keep using the old certificate.
+# Perhaps it just takes a bit to update, but I thought it safer to just update all of them.
+
+$aadproxyapps | Foreach-Object {
+ "Updating certificate for $($_.DisplayName)"
+ Set-AzureADApplicationProxyApplicationCustomDomainCertificate -ObjectId $_.ObjectId -PfxFilePath $PfxPath -Password $SecureCertPass
+}
+
+
+Disconnect-AzureAD
\ No newline at end of file diff --git a/docs/Main.cs b/docs/Main.cs deleted file mode 100644 index 1b72039..0000000 --- a/docs/Main.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace docs -{ - internal class Program - { - public static void Main() { } - } -} diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 38ea930..0000000 --- a/docs/_config.yml +++ /dev/null @@ -1,3 +0,0 @@ -theme: jekyll-theme-merlot -show_downloads: true -google_analytics: UA-134924634-2 diff --git a/docs/_data/sitemap.yml b/docs/_data/sitemap.yml deleted file mode 100644 index dc9ac0f..0000000 --- a/docs/_data/sitemap.yml +++ /dev/null @@ -1,145 +0,0 @@ -main: -- title: Home - url: /win-acme -- title: Manual - url: /win-acme/manual/getting-started -- title: Reference - url: /win-acme/reference/cli -- title: Support - url: /win-acme/support - -manual: -- title: System requirements - url: /win-acme/manual/system-requirements - -- title: Getting started - url: /win-acme/manual/getting-started - -- title: Automatic renewal - url: /win-acme/manual/automatic-renewal - -- title: Renewal management - url: /win-acme/manual/renewal-management - -- title: Advanced usage - url: /win-acme/manual/advanced-use/ - subs: - - title: Examples - url: /win-acme/manual/advanced-use/examples/ - subs: - - title: Microsoft Exchange - url: /win-acme/manual/advanced-use/examples/exchange - - title: Apache - url: /win-acme/manual/advanced-use/examples/apache - - title: Remote Desktop Services - url: /win-acme/manual/advanced-use/examples/rds - - - title: Load balancing - url: /win-acme/manual/advanced-use/load-balancing - - title: Custom logging - url: /win-acme/manual/advanced-use/custom-logging - -- title: Validation problems - url: /win-acme/manual/validation-problems - -- title: Upgrading - url: /win-acme/manual/upgrading/ - subs: - - title: to v1.9.5 - url: /win-acme/manual/upgrading/to-v1.9.5 - - title: to v1.9.9 - url: /win-acme/manual/upgrading/to-v1.9.9 - - title: to v2.0.0 - url: /win-acme/manual/upgrading/to-v2.0.0 - - title: to v2.0.11 - url: /win-acme/manual/upgrading/to-v2.0.11 - - title: to v2.1.0 - url: /win-acme/manual/upgrading/to-v2.1.0 -reference: -- title: Command line arguments - url: /win-acme/reference/cli - -- title: Settings.json - url: /win-acme/reference/settings - -- title: Plugins - url: /win-acme/reference/plugins/ - subs: - - title: Target - url: /win-acme/reference/plugins/target/ - subs: - - title: IIS - url: /win-acme/reference/plugins/target/iis - - title: Manual - url: /win-acme/reference/plugins/target/manual - - title: CSR - url: /win-acme/reference/plugins/target/csr - - - title: Validation - url: /win-acme/reference/plugins/validation/ - subs: - - title: HTTP validation - url: /win-acme/reference/plugins/validation/http/ - subs: - - title: Self-hosting - url: /win-acme/reference/plugins/validation/http/selfhosting - - title: Filesystem - url: /win-acme/reference/plugins/validation/http/filesystem - - title: FTP(S) - url: /win-acme/reference/plugins/validation/http/ftps - - title: SFTP - url: /win-acme/reference/plugins/validation/http/sftp - - title: WebDav - url: /win-acme/reference/plugins/validation/http/webdav - - - title: DNS validation - url: /win-acme/reference/plugins/validation/dns/ - subs: - - title: acme-dns - url: /win-acme/reference/plugins/validation/dns/acme-dns - - title: Manual - url: /win-acme/reference/plugins/validation/dns/manual - - title: Script - url: /win-acme/reference/plugins/validation/dns/script - - title: Microsoft Azure DNS - url: /win-acme/reference/plugins/validation/dns/azure - - title: Amazon AWS Route53 - url: /win-acme/reference/plugins/validation/dns/route53 - - title: Cloudflare - url: /win-acme/reference/plugins/validation/dns/cloudflare - - title: Dreamhost - url: /win-acme/reference/plugins/validation/dns/dreamhost - - - title: TLS validation - url: /win-acme/reference/plugins/validation/tls-alpn/ - subs: - - title: Self-hosting - url: /win-acme/reference/plugins/validation/tls-alpn/selfhosting - - - title: CSR - url: /win-acme/reference/plugins/csr/ - subs: - - title: RSA - url: /win-acme/reference/plugins/csr/rsa - - title: EC - url: /win-acme/reference/plugins/csr/ec - - - title: Store - url: /win-acme/reference/plugins/store/ - subs: - - title: Certificate Store - url: /win-acme/reference/plugins/store/certificatestore - - title: Central Certificate Store (.pfx files) - url: /win-acme/reference/plugins/store/centralssl - - title: .pem files (Apache etc.) - url: /win-acme/reference/plugins/store/pemfiles - - - title: Installation - url: /win-acme/reference/plugins/installation/ - subs: - - title: IIS HTTPS bindings - url: /win-acme/reference/plugins/installation/iisweb - - title: IIS FTPS bindings - url: /win-acme/reference/plugins/installation/iisftp - - title: Script - url: /win-acme/reference/plugins/installation/script
\ No newline at end of file diff --git a/docs/_includes/csr-common.md b/docs/_includes/csr-common.md deleted file mode 100644 index a138677..0000000 --- a/docs/_includes/csr-common.md +++ /dev/null @@ -1,7 +0,0 @@ -## OCSP Must Staple -This extension can be added to the CSR with the command line option `--ocsp-must-staple` - -## Private key reuse - The option `--reuse-privatekey` can be used to keep using the same - private key across different renewals, which can be useful for example with - [DANE](https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities).
\ No newline at end of file diff --git a/docs/_includes/plugin-seperate.md b/docs/_includes/plugin-seperate.md deleted file mode 100644 index cffc536..0000000 --- a/docs/_includes/plugin-seperate.md +++ /dev/null @@ -1,14 +0,0 @@ -## Seperate download - -This plugin is offered as a separate download, which can be downloaded from the -[releases]({{ site.github.releases_url }}) page on GitHub has to be unpacked into -the main program folder to able to use. Note that after unpacking you will have to -unblock them for the .NET CRL to trust them. You can do that from the Windows File -Explorer by using the right mouse button and then checking the `Unblock` box on -the General tab. - - - -# Requires pluggable version - -This plugin requires to you use the `pluggable` version of the main executable.
\ No newline at end of file diff --git a/docs/_includes/sidebar.html b/docs/_includes/sidebar.html deleted file mode 100644 index 95e6dd9..0000000 --- a/docs/_includes/sidebar.html +++ /dev/null @@ -1,5 +0,0 @@ -<ul class="sidebar"> - {% for item in site.data.sitemap[page.sidebar] %} - {% include sidebarlevel.html item=item %} - {% endfor %} -</ul>
\ No newline at end of file diff --git a/docs/_includes/sidebarlevel.html b/docs/_includes/sidebarlevel.html deleted file mode 100644 index 2de2ebf..0000000 --- a/docs/_includes/sidebarlevel.html +++ /dev/null @@ -1,12 +0,0 @@ -{% assign z = '/win-acme' | append: page.url %} -{% assign x = include.item.url | append: '.html' %} -<li> - <a href="{{ include.item.url }}" {% if z==x or z==include.item.url %}style="color: #e83e8c;" {% endif %}>{{ include.item.title }}</a> - {% if include.item.subs %} - <ul class="sidebar"> - {% for sub in include.item.subs %} - {% include sidebarlevel.html item=sub %} - {% endfor %} - </ul> - {% endif %} -</li>
\ No newline at end of file diff --git a/docs/_includes/validation-http-common.md b/docs/_includes/validation-http-common.md deleted file mode 100644 index a0250e4..0000000 --- a/docs/_includes/validation-http-common.md +++ /dev/null @@ -1,58 +0,0 @@ -## Warmup - -Before allowing the ACME server to validate, the program will attempt to request -the validation file itself and note the result of that request in the log. A side -effect of this is that it forces the application to start in case it's application pool -or equivalent went to sleep, warming up the caches etc. This reduces the chance of -time-outs during validation. This used to be optional behaviour controlled by the -`--warmup` switch, but that is no longer in use. - -## web.config - -Optionally this plugin can place a `web.config` next to the validation file, to -help IIS properly serve the response. There are [many reasons](/win-acme/manual/validation-problems) -why IIS can fail to properly server the file. Some of them can be fixed this way. - -In interactive mode the program will ask you if you want to do this. In unattended mode you -can request it with the parameter `--manualtargetisiis` - -### Changing the template - -The web.config that will be copied lives in the root of the program directory with the -name `web_config.xml`. You can modify it to fit your needs, e.g. for MVC sites you might need: - -```XML -<configuration> - <system.webServer> - <staticContent> - <clear/> - <mimeMap fileExtension = ".*" mimeType="text/json" /> - </staticContent> - <handlers> - <clear /> - <add name="StaticFile" - path="*" - verb="*" - type="" - modules="StaticFileModule, - DefaultDocumentModule, - DirectoryListingModule" - scriptProcessor="" - resourceType="Either" - requireAccess="Read" - allowPathInfo="false" - preCondition="" - responseBufferLimit="4194304" /> - </handlers> - </system.webServer> -</configuration> -``` - -Or to disable URL Rewriting you might need to add this (in the beginning, right after `<clear />`). - -```XML -<rule name="LetsEncrypt Rule" stopProcessing="true"> - <match url="^\.well-known.*$" /> - <action type="None" /> -</rule> -```
\ No newline at end of file diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html deleted file mode 100644 index b6c6a86..0000000 --- a/docs/_layouts/default.html +++ /dev/null @@ -1,96 +0,0 @@ -<!DOCTYPE html> -<html lang="{{ site.lang | default: "en-US" }}"> -<head> - <meta charset='utf-8'> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=640"> - <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> - <script src="https://code.jquery.com/jquery-3.4.1.slim.js" integrity="sha256-BTlTdQO9/fascB1drekrDVkaKd9PkwBymMlHOiG+qLI=" crossorigin="anonymous"></script> - <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> - <link rel="stylesheet" href="{{ 'assets/template.css' | relative_url }}"> -</head> - -<body> - <header class="masthead"> - <div class="container h-25"> - <div class="row h-25"> - <div class="col-sm-2 my-auto"> - <div class="header-content mx-auto"> - <h3>WIN-ACME</h3> - </div> - </div> - <div class="col-sm-6 my-auto"> - <div class="header-content mx-auto"> - <span>A simple ACMEv2 client for Windows (for use with Let's Encrypt et al.)</span> - </div> - </div> - <div class="col-sm-2 my-auto"> - <div class="header-content mx-auto"> - <a href="{{ site.github.latest_release.assets[4].browser_download_url }}" class="btn btn-outline btn-xl js-scroll-trigger">Download {{ site.github.latest_release.name | strip | remove: 'v' }}</a> - </div> - </div> - </div> - </div> - </header> - - <nav class="navbar navbar-expand-sm bg-dark navbar-dark"> - <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar"> - <span class="navbar-toggler-icon"></span> - </button> - <div class="collapse navbar-collapse" id="collapsibleNavbar"> - <ul class="navbar-nav"> - {% for item in site.data.sitemap.main %} - <li class="nav-item"> - <a class="nav-link" href="{{ item.url }}">{{ item.title }}</a> - </li> - {% endfor %} - <li class="nav-item dropdown"> - <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Download</a> - <div class="dropdown-menu"> - <a class="dropdown-item" href="{{ site.github.latest_release.assets[4].browser_download_url }}">{{ site.github.latest_release.name | strip | remove: 'v' }} (64-bit, pluggable) <strong>(recommended)</strong></a> - <a class="dropdown-item" href="{{ site.github.latest_release.assets[5].browser_download_url }}">{{ site.github.latest_release.name | strip | remove: 'v' }} (64-bit, trimmed)</a> - <a class="dropdown-item" href="{{ site.github.latest_release.assets[6].browser_download_url }}">{{ site.github.latest_release.name | strip | remove: 'v' }} (32-bit, pluggable)</a> - <a class="dropdown-item" href="{{ site.github.latest_release.assets[7].browser_download_url }}">{{ site.github.latest_release.name | strip | remove: 'v' }} (32-bit, trimmed)</a> - <a class="dropdown-item" href="{{ site.github.releases_url }}">Release notes</a> - <a class="dropdown-item" href="{{ site.github.releases_url }}">Older versions</a> - </div> - </li> - </ul> - </div> - </nav> - - <div class="container py-3"> - <div class="row"> - {% if page.sidebar %} - <div class="col-sm-4"> - {% include sidebar.html %} - </div> - <div class="col-sm-8"> - {{ content }} - </div> - {% else %} - <div class="col"> - {{ content }} - </div> - {% endif %} - </div> - </div> - - <footer> - {% if site.github.is_project_page %} - <p>this project by Wouter Tinus can be found on <a href="https://github.com/PKISharp/win-acme/">GitHub</a></p> - {% endif %} - </footer> - - {% if site.google_analytics %} - <script> - (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ - (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), - m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) - })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - ga('create', '{{ site.google_analytics }}', 'auto'); - ga('send', 'pageview'); - </script> - {% endif %} -</body> -</html> diff --git a/docs/assets/bg-pattern.png b/docs/assets/bg-pattern.png Binary files differdeleted file mode 100644 index cfd7911..0000000 --- a/docs/assets/bg-pattern.png +++ /dev/null diff --git a/docs/assets/screenshot.png b/docs/assets/screenshot.png Binary files differdeleted file mode 100644 index b3eada9..0000000 --- a/docs/assets/screenshot.png +++ /dev/null diff --git a/docs/assets/template.css b/docs/assets/template.css deleted file mode 100644 index 6d6e9d5..0000000 --- a/docs/assets/template.css +++ /dev/null @@ -1,459 +0,0 @@ -/*! - * Start Bootstrap - New Age v5.0.6 (https://startbootstrap.com/template-overviews/new-age) - * Copyright 2013-2019 Start Bootstrap - * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-new-age/blob/master/LICENSE) - */ - -html, -body { - width: 100%; - height: 100%; -} - -body { - font-family: 'Muli', 'Helvetica', 'Arial', 'sans-serif'; -} - -a { - -webkit-transition: all .35s; - transition: all .35s; -} - -hr { - max-width: 100px; - margin: 25px auto 0; - border-width: 1px; - border-color: rgba(34, 34, 34, 0.1); -} - - hr.light { - border-color: white; - } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: 'Catamaran', 'Helvetica', 'Arial', 'sans-serif'; - font-weight: 200; - letter-spacing: 1px; -} - -p { - font-size: 16px; - line-height: 1.5; - margin-bottom: 20px; -} - -section { - padding: 100px 0; -} - - section h2 { - font-size: 50px; - } - -#mainNav { - border-color: rgba(34, 34, 34, 0.05); - background-color: white; - -webkit-transition: all .35s; - transition: all .35s; - font-family: 'Catamaran', 'Helvetica', 'Arial', 'sans-serif'; - font-weight: 200; - letter-spacing: 1px; -} - - #mainNav .navbar-brand { - color: #fdcc52; - font-family: 'Catamaran', 'Helvetica', 'Arial', 'sans-serif'; - font-weight: 200; - letter-spacing: 1px; - } - - #mainNav .navbar-brand:hover, #mainNav .navbar-brand:focus { - color: #fcbd20; - } - - #mainNav .navbar-toggler { - font-size: 12px; - padding: 8px 10px; - color: #222222; - } - - #mainNav .navbar-nav > li > a { - font-size: 11px; - font-family: 'Lato', 'Helvetica', 'Arial', 'sans-serif'; - letter-spacing: 2px; - text-transform: uppercase; - } - - #mainNav .navbar-nav > li > a.active { - color: #fdcc52 !important; - background-color: transparent; - } - - #mainNav .navbar-nav > li > a.active:hover { - background-color: transparent; - } - - #mainNav .navbar-nav > li > a, - #mainNav .navbar-nav > li > a:focus { - color: #222222; - } - - #mainNav .navbar-nav > li > a:hover, - #mainNav .navbar-nav > li > a:focus:hover { - color: #fdcc52; - } - -@media (min-width: 992px) { - #mainNav { - border-color: transparent; - background-color: transparent; - } - - #mainNav .navbar-brand { - color: fade(white, 70%); - } - - #mainNav .navbar-brand:hover, #mainNav .navbar-brand:focus { - color: white; - } - - #mainNav .navbar-nav > li > a, - #mainNav .navbar-nav > li > a:focus { - color: rgba(255, 255, 255, 0.7); - } - - #mainNav .navbar-nav > li > a:hover, - #mainNav .navbar-nav > li > a:focus:hover { - color: white; - } - - #mainNav.navbar-shrink { - border-color: rgba(34, 34, 34, 0.1); - background-color: white; - } - - #mainNav.navbar-shrink .navbar-brand { - color: #222222; - } - - #mainNav.navbar-shrink .navbar-brand:hover, #mainNav.navbar-shrink .navbar-brand:focus { - color: #fdcc52; - } - - #mainNav.navbar-shrink .navbar-nav > li > a, - #mainNav.navbar-shrink .navbar-nav > li > a:focus { - color: #222222; - } - - #mainNav.navbar-shrink .navbar-nav > li > a:hover, - #mainNav.navbar-shrink .navbar-nav > li > a:focus:hover { - color: #fdcc52; - } -} - -header.masthead { - position: relative; - width: 100%; - padding-top: 10px; - padding-bottom: 10px; - color: white; - background: url("bg-pattern.png"), #7b4397; - background: url("bg-pattern.png"), -webkit-gradient(linear, right top, left top, from(#7b4397), to(#dc2430)); - background: url("bg-pattern.png"), linear-gradient(to left, #7b4397, #dc2430); -} - - header.masthead .header-content { - text-align: center; - } - - header.masthead .header-content h1 { - font-size: 30px; - } - - header.masthead .device-container { - max-width: 325px; - margin-right: auto; - margin-left: auto; - } - - header.masthead .device-container .screen img { - border-radius: 3px; - } - -section.download { - position: relative; - padding: 150px 0; -} - - section.download h2 { - font-size: 50px; - margin-top: 0; - } - - section.download .badges .badge-link { - display: block; - margin-bottom: 25px; - } - - section.download .badges .badge-link:last-child { - margin-bottom: 0; - } - - section.download .badges .badge-link img { - height: 60px; - } - -@media (min-width: 768px) { - section.download .badges .badge-link { - display: inline-block; - margin-bottom: 0; - } -} - -@media (min-width: 768px) { - section.download h2 { - font-size: 70px; - } -} - -section.features .section-heading { - margin-bottom: 100px; -} - - section.features .section-heading h2 { - margin-top: 0; - } - - section.features .section-heading p { - margin-bottom: 0; - } - -section.features .device-container, -section.features .feature-item { - max-width: 325px; - margin: 0 auto; -} - -section.features .device-container { - margin-bottom: 100px; -} - -@media (min-width: 992px) { - section.features .device-container { - margin-bottom: 0; - } -} - -section.features .feature-item { - padding-top: 50px; - padding-bottom: 50px; - text-align: center; -} - - section.features .feature-item h3 { - font-size: 30px; - } - - section.features .feature-item i { - font-size: 80px; - display: block; - margin-bottom: 15px; - background: -webkit-gradient(linear, right top, left top, from(#7b4397), to(#dc2430)); - background: linear-gradient(to left, #7b4397, #dc2430); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - } - -section.cta { - position: relative; - padding: 250px 0; - background-image: url("../img/bg-cta.jpg"); - background-position: center; - background-size: cover; -} - - section.cta .cta-content { - position: relative; - z-index: 1; - } - - section.cta .cta-content h2 { - font-size: 50px; - max-width: 450px; - margin-top: 0; - margin-bottom: 25px; - color: white; - } - -@media (min-width: 768px) { - section.cta .cta-content h2 { - font-size: 80px; - } -} - -section.cta .overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); -} - -section.contact { - text-align: center; -} - - section.contact h2 { - margin-top: 0; - margin-bottom: 25px; - } - - section.contact h2 i { - color: #dd4b39; - } - - section.contact ul.list-social { - margin-bottom: 0; - } - - section.contact ul.list-social li a { - font-size: 40px; - line-height: 80px; - display: block; - width: 80px; - height: 80px; - color: white; - border-radius: 100%; - } - - section.contact ul.list-social li.social-twitter a { - background-color: #1da1f2; - } - - section.contact ul.list-social li.social-twitter a:hover { - background-color: #0d95e8; - } - - section.contact ul.list-social li.social-facebook a { - background-color: #3b5998; - } - - section.contact ul.list-social li.social-facebook a:hover { - background-color: #344e86; - } - - section.contact ul.list-social li.social-google-plus a { - background-color: #dd4b39; - } - - section.contact ul.list-social li.social-google-plus a:hover { - background-color: #d73925; - } - -footer { - padding: 25px 0; - text-align: center; - color: rgba(255, 255, 255, 0.3); - background-color: #222222; -} - - footer p { - font-size: 12px; - margin: 0; - } - - footer ul { - margin-bottom: 0; - } - - footer ul li a { - font-size: 12px; - color: rgba(255, 255, 255, 0.3); - } - - footer ul li a:hover, footer ul li a:focus, footer ul li a:active, footer ul li a.active { - text-decoration: none; - } - -.bg-primary { - background: #fdcc52; - background: -webkit-gradient(linear, left top, left bottom, from(#fdcc52), to(#fdc539)); - background: linear-gradient(#fdcc52, #fdc539); -} - -.text-primary { - color: #fdcc52; -} - -.no-gutter > [class*='col-'] { - padding-right: 0; - padding-left: 0; -} - -.btn-outline { - color: white; - border: 1px solid; - border-color: white; -} - - .btn-outline:hover, .btn-outline:focus, .btn-outline:active, .btn-outline.active { - color: white; - border-color: #fdcc52; - background-color: #fdcc52; - } - -.btn { - border-radius: 300px; - font-family: 'Lato', 'Helvetica', 'Arial', 'sans-serif'; - letter-spacing: 2px; - text-transform: uppercase; -} - -.btn-xl { - font-size: 11px; - padding: 15px 45px; -} - -/* Custom stuff starts here */ -img { - max-width: 100%; -} - -ul.sidebar { - font-size: small; - padding-inline-start: 20px; -} - -.h1, h1 { - font-size: 3rem -} - -.h2, h2 { - font-size: 2.5rem -} - -.h3, h3 { - font-size: 2rem -} - -.h4, h4 { - font-size: 1.5rem -} - -.h5, h5 { - font-size: 1rem -} - -.h6, h6 { - font-size: 1rem -} - -table { - margin-bottom: 1em; -}
\ No newline at end of file diff --git a/docs/assets/unblock-dll.png b/docs/assets/unblock-dll.png Binary files differdeleted file mode 100644 index c021861..0000000 --- a/docs/assets/unblock-dll.png +++ /dev/null diff --git a/docs/docs.csproj b/docs/docs.csproj deleted file mode 100644 index 046fbc7..0000000 --- a/docs/docs.csproj +++ /dev/null @@ -1,103 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProjectGuid>{F115D288-DF07-4424-BF08-594C2DB7C1BB}</ProjectGuid> - <OutputType>Exe</OutputType> - <RootNamespace>docs</RootNamespace> - <AssemblyName>docs</AssemblyName> - <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> - <FileAlignment>512</FileAlignment> - <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <Deterministic>true</Deterministic> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <ItemGroup> - <None Include="manual\advanced-use\custom-logging.md" /> - <None Include="manual\advanced-use\examples\apache.md" /> - <None Include="manual\advanced-use\examples\exchange.md" /> - <None Include="manual\advanced-use\examples\index.md" /> - <None Include="manual\advanced-use\examples\rds.md" /> - <None Include="manual\advanced-use\load-balancing.md" /> - <None Include="manual\advanced-use\index.md" /> - <None Include="manual\automatic-renewal.md" /> - <None Include="manual\index.md" /> - <None Include="manual\system-requirements.md" /> - <None Include="manual\upgrading\index.md" /> - <None Include="manual\upgrading\to-v1.9.5.md" /> - <None Include="manual\upgrading\to-v1.9.9.md" /> - <None Include="manual\upgrading\to-v2.0.0.md" /> - <None Include="index.md" /> - <None Include="manual\upgrading\to-v2.0.11.md" /> - <None Include="manual\upgrading\to-v2.1.0.md" /> - <None Include="reference\cli.md" /> - <None Include="reference\plugins\csr\ec.md" /> - <None Include="reference\plugins\csr\index.md" /> - <None Include="reference\plugins\csr\rsa.md" /> - <None Include="reference\plugins\development.md" /> - <None Include="reference\plugins\installation\iisftp.md" /> - <None Include="reference\plugins\installation\iisweb.md" /> - <None Include="reference\plugins\installation\index.md" /> - <None Include="reference\plugins\installation\script.md" /> - <None Include="reference\plugins\index.md" /> - <None Include="reference\plugins\store\centralssl.md" /> - <None Include="reference\plugins\store\certificatestore.md" /> - <None Include="reference\plugins\store\pemfiles.md" /> - <None Include="reference\plugins\store\index.md" /> - <None Include="reference\plugins\target\csr.md" /> - <None Include="reference\plugins\target\iis.md" /> - <None Include="reference\plugins\target\manual.md" /> - <None Include="reference\plugins\target\index.md" /> - <None Include="reference\plugins\validation\dns\acme-dns.md" /> - <None Include="reference\plugins\validation\dns\azure.md" /> - <None Include="reference\plugins\validation\dns\cloudflare.md" /> - <None Include="reference\plugins\validation\dns\dreamhost.md" /> - <None Include="reference\plugins\validation\dns\manual.md" /> - <None Include="reference\plugins\validation\dns\index.md" /> - <None Include="reference\plugins\validation\dns\route53.md" /> - <None Include="reference\plugins\validation\dns\script.md" /> - <None Include="reference\plugins\validation\http\filesystem.md" /> - <None Include="reference\plugins\validation\http\ftps.md" /> - <None Include="reference\plugins\validation\http\index.md" /> - <None Include="reference\plugins\validation\http\selfhosting.md" /> - <None Include="reference\plugins\validation\http\sftp.md" /> - <None Include="reference\plugins\validation\http\webdav.md" /> - <None Include="reference\plugins\validation\index.md" /> - <None Include="reference\index.md" /> - <None Include="reference\plugins\validation\tls-alpn\index.md" /> - <None Include="reference\plugins\validation\tls-alpn\selfhosting.md" /> - <None Include="reference\settings.md" /> - <None Include="support\index.md" /> - <None Include="_config.yml" /> - <None Include="_data\sitemap.yml" /> - <None Include="_includes\csr-common.md" /> - <None Include="_includes\plugin-seperate.md" /> - <None Include="_includes\validation-http-common.md" /> - </ItemGroup> - <ItemGroup> - <Content Include="assets\bg-pattern.png" /> - <Content Include="assets\screenshot.png" /> - <Content Include="assets\template.css" /> - <None Include="manual\getting-started.md" /> - <None Include="manual\renewal-management.md" /> - <None Include="manual\validation-problems.md" /> - <Content Include="assets\unblock-dll.png" /> - <Content Include="_includes\sidebar.html" /> - <Content Include="_includes\sidebarlevel.html" /> - <Content Include="_layouts\default.html" /> - </ItemGroup> - <ItemGroup> - <Compile Include="Main.cs" /> - </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> -</Project>
\ No newline at end of file diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index a06c8f1..0000000 --- a/docs/index.md +++ /dev/null @@ -1,38 +0,0 @@ -# win-acme -This is a ACMEv2 client for Windows that aims to be very simple to start with, -but powerful enough to grow into almost every scenario. - -- A very simple text interface to create and install certificates on a local IIS server -- A more advanced text interface for many other use cases, including [Apache](/win-acme/manual/advanced-use/examples/apache) and [Exchange](/win-acme/manual/advanced-use/examples/exchange) -- Automatically creates a scheduled task to renew certificates when needed -- Get certificates with - wildcards (`*.example.com`), - international names (`证书.example.com`), - [OCSP Must Staple](/win-acme/reference/plugins/csr/rsa) extension, optional - [re-use](/win-acme/reference/plugins/csr/rsa) of private keys, - [EC](/win-acme/reference/plugins/csr/ec) crypto or use your own - [CSR](/win-acme/reference/plugins/target/csr) -- Advanced toolkit for DNS, HTTP and TLS validation: - [SFTP](/win-acme/reference/plugins/validation/http/sftp)/[FTPS](/win-acme/reference/plugins/validation/http/ftps), - [acme-dns](/win-acme/reference/plugins/validation/dns/acme-dns), - [Azure](/win-acme/reference/plugins/validation/dns/azure), - [Route53](/win-acme/reference/plugins/validation/dns/route53), - [Cloudflare](/win-acme/reference/plugins/validation/dns/cloudflare) - and more... -- Completely unattended operation from the command line -- Other forms of automation through manipulation of `.json` files -- Write your own Powershell `.ps1` scripts to handle custom installation and validation -- Build your own plugins with C# and make the program do exactly what you want - - - -# Sponsors -- <img src="https://user-images.githubusercontent.com/11052380/72933908-fb465000-3d62-11ea-9b97-57b8a29fd783.png" alt="Insurance Technology Services" width="50px" /> [Insurance Technology Services](https://insurancetechnologyservices.com/) -- [e-shop LTD](https://www.e-shop.co.il/) -- The Proof Group @proofgroup -- [imagenia.fr](http://www.imagenia.fr/) - -# Getting started -Download the `.zip` file from the download menu, unpack it to a location on your hard disk -and run `wacs.exe`. If you require assistance please check the [manual](/win-acme/manual/getting-started) -first before looking for [support](/win-acme/support/). diff --git a/docs/manual/advanced-use/custom-logging.md b/docs/manual/advanced-use/custom-logging.md deleted file mode 100644 index 635a2fa..0000000 --- a/docs/manual/advanced-use/custom-logging.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -sidebar: manual ---- - -# Custom logging -The program users [Serilog](https://serilog.net/) for logging which is a powerful extensible library. - -## Levels -win-acme uses the following five log levels: - -- `Error` - Logs fatal or dangerous conditions -- `Warning` - Logs minor errors and suspicious conditions -- `Information` - General information about operations -- `Debug` - Additional information that can be useful for troubleshooting -- `Verbose` - Full logging for submitting bug reports - -You can change the log level by adding the following setting: - -`<add key="serilog:minimum-level" value="Verbose" />` - -## Included sinks -- The default sink logs to the console window to provide real time insights. -- The `event` sink writes to the Windows Event Viewer includes `Error`, `Warning` and selected `Information` messages. -- The `disk` sink writes rolling log files to `%programdata%\win-acme\log` - (that path can be changed in [settings.json](/win-acme/reference/settings)) - -## Custom sinks -There are many types of output channels called [sinks](https://github.com/serilog/serilog/wiki/Provided-Sinks) for all -kinds of different databases, file formats and services. - -### Example (Seq) - -- Download `Serilog.Sinks.PeriodicBatching.dll` and `Serilog.Sinks.Seq.dll` from NuGet. These files can be found -[here](https://www.nuget.org/packages/Serilog.Sinks.PeriodicBatching) and -[here](https://www.nuget.org/packages/Serilog.Sinks.Seq), respectively. -- Configure the sink in a file called `serilog.json` according to the specification [here](https://github.com/serilog/serilog-settings-configuration). - -### Example - -The follow piece of code in `serilog.json` adds the process ID to the output of the file log. - -```json -{ - "disk": { - "WriteTo": [ - { - "Name": "File", - "Args": { - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [PID:{ProcessId}] {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} -```
\ No newline at end of file diff --git a/docs/manual/advanced-use/examples/apache.md b/docs/manual/advanced-use/examples/apache.md deleted file mode 100644 index b72de7a..0000000 --- a/docs/manual/advanced-use/examples/apache.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -sidebar: manual ---- - -# Apache -To get the certificate in the correct format for Apache (i.e. `.pem` files), you have to active -the [PemFiles plugin](/win-acme/reference/plugins/store/pemfiles) for each of your renewals. -For **new** renewals this can be done either from the command line with `--store pemfiles` or -from the main menu with the `M` option, where it will be posed as a question ("How would you -like to store this certificate?"). - -Existing renewals that are set up without the PemFiles plugin (which unfortunately includes -those [imported](/win-acme/manual/upgrading/to-v2.0.0) from 1.9.x) cannot be modified with a -command line switch or settings change. You will have to re-create them one by one, or manually -modify the `.json` files on disk. - -## Getting the certificate in .pem format - -### Interactive -- Choose `M` in the main menu (create with full options) -- Choose "Manually input host names" as target -- Input the domain name(s) -- Choose or accept the friendly name -- Pick a validation method. Most common would be to save to a local path -- Pick your key type -- Now the critical part: at "How would you like to store this certificate?" pick `Write .pem files to folder (Apache, nginx, etc.)` -- And so on... - -### Unattended -`wacs.exe --target manual --host www.example.com --validation filesystem --webroot "C:\htdocs\www\example.com" --store pemfiles --pemfilespath C:\apache-certs` - -### Pro tip -If you don't want to have to specify the path for the `.pem` files each time, you can -edit `settings.json` in the program directory and set the `DefaultPemFilesPath` -option. - -## Configuring Apache -To use certificates obtained with the help of WACS with the Apache 2.4 server, you need -to make settings in `Apache24\conf\extra\httpd-vhosts.conf` file; you could also make -these changes in the `\Apache24\conf\extra\httpd-ssl.conf` file as well instead if -you so wish: - -``` -Define CERTROOT "C:/apache-certs" -Define SITEROOT "C:/htdocs/www" -.... -<VirtualHost *:443> - ServerName www.example.com - DocumentRoot "${SITEROOT}/example.com" -.... - SSLEngine on - SSLCertificateFile "${CERTROOT}/example.com-chain.pem" - SSLCertificateKeyFile "${CERTROOT}/example.com-key.pem" -</VirtualHost> -``` - -Obviously replace `example.com` with your actual domain name your siteroot to -where you're hosting your files. - -### Enable SSL -Do not forget to uncomment `LoadModule ssl_module modules/mod_ssl.so` in `Apache24\conf\httpd.conf` -file if it's not already uncommented. You also need to add `Listen 443` or `Listen 80 443`. - -### Not for XAMPP uses -You don't need the `/example.com` at the end after `"${SITEROOT}"` so it -should just read as: `DocumentRoot "${SITEROOT}"` for that one line or else -(at least according to my case), would result in an object not found 404 error -when you visit your domain page. - -Also, according to Apache standards, backslash means escaping characters so if you wanted to -use backslash as a way for defining directories, then you're supposed to use another one -so it looks like `C:\\XAMPP\\Apache\\somestuff` but apparently the developers have modded -it so that it doesn't really matter if you double slash or not or use forward slash instead -of a single back slash - they all work the same regardless, at least as of version -3.2.2 of XAMPP. - -## Addendum -If you want to use your own folder to store certificates, you can use this cmd script is -for copying (for example, with name `installcert.cmd`): - -``` -@echo off -if "%~1" == "" exit -if not exist "%2" md "%2" >nul -set certlist=%3-chain.pem,%3-key.pem -echo Script running... -for %%a in (%certlist%) do copy /y "%ProgramData%\win-acme\%1\%%a" "%2\" >nul && echo. [INFO] Install %%a to Certificate Store in %2... OK || echo. [WARN] Install certificate %%a fieled! -echo. [INFO] Restarting service... -C:\Apache24\bin\httpd.exe -k restart -echo. [INFO] Service restarted. -echo. [INFO] Script finished. -``` -This script is called with parameters: -`LEWSuriDirectory CertFolder DomainName` - -For example: -`wacs.exe --target manual --host www.example.com --webroot "C:\htdocs\www\example.com" --validation filesystem --script "installcert.cmd" --scriptparameters "acme-v02.api.letsencrypt.org C:\cert www.example.com"` - -Also you must specify a new path to the folder with certificates in your `httpd-vhosts.conf`.
\ No newline at end of file diff --git a/docs/manual/advanced-use/examples/exchange.md b/docs/manual/advanced-use/examples/exchange.md deleted file mode 100644 index 7bb444c..0000000 --- a/docs/manual/advanced-use/examples/exchange.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -sidebar: manual ---- - -# Microsoft Exchange -Choose the domains that you want to generate the certificate for. Note that Let's Encrypt only -issues certificates to public domains, that means no Active Directory server names or domain suffixes -that are only known inside of your intranet can be used. You can specify a maximum of 100 domains -in a certificate. - -Assumptions made in this example: - -- We want to generate the certificate for three domains - - mail.example.com - - webmail.example.com - - autodiscover.example.com -- mail.example.com will be the common name, hence we put it first -- OWA is running in the Default Web Site of IIS with Site Id `1`. -- We want to enable the certificate for SMTP and IMAP - -## Interactive -- Create certificate with full options -- Manually input host names -- [http-01] Self-host verification files -- Create or update https bindings in IIS -- Would you like to add another installer step? (y/n): Y -- Run a custom script -- Would you like to add another installer step? (y/n): N -- Choose site to create new bindings: Default Web Site (or where ever OWA is at) -- Enter the path to the script that you want to run after renewal: `./Scripts/ImportExchange.ps1` -- Enter the parameter format string for the script: `'{CertThumbprint}' 'IIS,SMTP,IMAP' 1 '{CacheFile}' '{CachePassword}' '{CertFriendlyName}'` - -## Unattended -- Without Central Certificate Store - `wacs.exe --target manual --host mail.example.com,webmail.example.com,autodiscover.example.com --certificatestore My --acl-fullcontrol "network service,administrators" --installation iis,script --installationsiteid 1 --script "./Scripts/ImportExchange.ps1" --scriptparameters "'{CertThumbprint}' 'IIS,SMTP,IMAP' 1 '{CacheFile}' '{CachePassword}' '{CertFriendlyName}'"` - -- With Central Certificate Store -`wacs.exe --target manual --host mail.example.com,webmail.example.com,autodiscover.example.com --store centralssl --centralsslstore "C:\Central SSL" --installation iis,script --installationsiteid 1 --script "./Scripts/ImportExchange.ps1" --scriptparameters "'{CertThumbprint}' 'IIS,SMTP,IMAP' 1 '{CacheFile}' '{CachePassword}' '{CertFriendlyName}'"` - -## Verification -To make sure all is working properly, I'd encourage you to use the -[Microsoft's Remote Connectivity Analyzer](https://testconnectivity.microsoft.com/). -The Autodiscover and ActiveSync Autodiscover tests are really useful for testing this out. -With Outlook 2016 requiring the use of [Autodiscover to connect to Exchange](http://blogs.technet.com/b/exchange/archive/2015/11/19/outlook-2016-what-exchange-admins-need-to-know.aspx), -verifying that this works properly is an important step is making sure your environment is setup correctly. - -## References -- [Assign certificates to Exchange services](https://technet.microsoft.com/en-us/library/dd351257%28v=exchg.160%29.aspx) -- [Import certificates into Exchange](https://technet.microsoft.com/en-us/library/bb124424(v=exchg.160).aspx) -- [Add MIME Type](https://support.microsoft.com/en-us/kb/326965) -- [Namespace planning in Exchange 2016](http://blogs.technet.com/b/exchange/archive/2015/10/06/namespace-planning-in-exchange-2016.aspx) -- [Exchange Server 2016 Client Access Namespace configuration](http://exchangeserverpro.com/exchange-server-2016-client-access-namespace-configuration/) -- [Install Exchange 2016 in your lab](https://supertekboy.com/2015/09/22/install-exchange-2016-in-your-lab-part-5/)
\ No newline at end of file diff --git a/docs/manual/advanced-use/examples/index.md b/docs/manual/advanced-use/examples/index.md deleted file mode 100644 index 949316d..0000000 --- a/docs/manual/advanced-use/examples/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -sidebar: manual ---- -# Examples -There are some [example scripts](https://github.com/PKISharp/win-acme/tree/master/dist/Scripts) -bundled with win-acme releases as a reference and inspiration for people looking to handle custom -[installation](/win-acme/reference/plugins/installation/script) or -[DNS validation](/win-acme/reference/plugins/validation/dns/script). - -The scripts are provided as-is. Caution is advised before running them on production systems.
\ No newline at end of file diff --git a/docs/manual/advanced-use/examples/rds.md b/docs/manual/advanced-use/examples/rds.md deleted file mode 100644 index 5eb51ae..0000000 --- a/docs/manual/advanced-use/examples/rds.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -sidebar: manual ---- - -# Remote Desktop Services -How to generate a Certificate for Microsoft Remote Desktop Servers - -## Running the client -Assuming you've a simple all in one Remote Desktop Server setup with the roles RD Gateway, RD Connection Broker -and RD Web Access, you have to import the certificate into the IIS site and additionally configure it for the -installed RD roles. For IIS the standard plugin is used, for the RD roles, the included `ImportRDSFull.ps1` is -used. - -## Configuration -In order for this script to work, the private key of the certificate needs to be marked as exportable. -Set `PrivateKeyExportable` in `settings.json` to `true`. - -The script accepts two parameters: CertThumbprint and RDCB. RDCB specifies the Remote Desktop Connection Broker -(RD Connection Broker) server for a Remote Desktop deployment. If you don't specify a value, the script uses the local -computer's fully qualified domain name (FQDN). - -## Unattended -- When specific domain names are configured in the IIS bindings, we can use them automatically -`wacs.exe --target iis --siteid 1 --certificatestore My --installation iis,script --script "Scripts\ImportRDSFull.ps1" --scriptparameters "{CertThumbprint}"` - -- When only blank/catch-all binding are configured in IIS, we have to be explicit about the domain name(s) that we want -`wacs.exe --target manual --hostname rds.example.com --certificatestore My --installation iis,script --installationsiteid 1 --script "Scripts\ImportRDSFull.ps1" --scriptparameters "{CertThumbprint}"`
\ No newline at end of file diff --git a/docs/manual/advanced-use/index.md b/docs/manual/advanced-use/index.md deleted file mode 100644 index c0de3c9..0000000 --- a/docs/manual/advanced-use/index.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -sidebar: manual ---- - -# Advanced use -The simple mode works well for the most common use case, but there are many -reasons to go for full options mode. For example: -- You don't use IIS -- You need to use [DNS validation](/win-acme/reference/plugins/validation/dns/) because - - You are requesting a wildcard certificate - - Port 80 is blocked on your network -- You are not running the program from your web server -- You are load balancing -- You need to run a script after each renewal, e.g. for [Exchange](/win-acme/manual/advanced-use/examples/exchange) -- etc. - -## Interactive -This describes the basic steps of an full options rewenal from the interactive menu. It touches -on concepts described [here](/win-acme/reference/plugins/), because this mode of operation -exposes more of the internal logic of the program to use to your advantage. Don't worry if -this seems overwhelming: most options have sensible defaults that you can select by just -pressing `<Enter>` in response to a question. - -- Choose `M` in the main menu to create a new certificate in full options mode -- Choose a [target plugin](/win-acme/reference/plugins/target/) that will be used - to determine for which domain(s) the certificate should be issued. -- Choose a [validation plugin](/win-acme/reference/plugins/validation/) to pick the - method that will be used to prove ownership of your domain(s) to the ACME server. -- Pick between RSA and EC private keys, which are both [plugins](/win-acme/reference/plugins/csr/) - used to generate a certificate signing request (CSR). -- One or more [store plugins](/win-acme/reference/plugins/store/) must be selected to save - the certificate. For Apache, nginx and others web servers the `PemFiles` plugin is commonly - chosen. -- One or more [installation plugins](/win-acme/reference/plugins/installation/) can be selected - to run after the certificate has been requested. The standard IIS option from simple mode - is of course available, but also the powerful [script installer](/win-acme/reference/plugins/installation/script). -- A registration with the ACME server is created, if it doesn't already exist. You will be - asked to agree to the terms of service and to provide an email address that the server - administrators can use to contact you. -- The program negotiates with ACME server to try and prove your ownership of the domain(s) that you want to - create the certificate for, using the method of your choice. Getting validation right is often the most tricky - part of getting an ACME certificate. If there are problems please check out some - [common issues](/win-acme/manual/validation-problems). -- After validating the domains, a certificate signing request is prepared according to - your specifications. -- The CSR is submitted to the ACME server and the signed response is saved according to your wishes. -- The program runs the requested installation steps. -- The program remembers all choices that you made while creating the certificate and applies them -for each subsequent [renewal](/win-acme/manual/automatic-renewal). - -## Unattended -By providing the right [command line arguments](/win-acme/reference/cli) at start up you can do -everything that is possible in interactive mode (and more) without having to jump through the menu's. -This is great way to make win-acme part of a larger automation workflow. - -### Examples -The `--target` switch, used to select a [target plugin](/win-acme/reference/plugins/target/), -triggers the unattended creation of new certificate. - -- `--target manual` - selects the [manual plugin](/win-acme/reference/plugins/target/manual). -- `--target iis` - selects the [iis plugin](/win-acme/reference/plugins/target/iis). - -Each plugin has their own inputs which it needs to generate the certificate, for example: - -```wacs.exe --target manual --host www.domain.com --webroot C:\sites\wwwroot``` -```wacs.exe --target iis --siteid 1 --excludebindings exclude.me``` - -There are some other parameters needed for first-time unattended use (e.g. on a clean server) -to create the Let's Encrypt registration automatically (```--emailaddress myaddress@example.com --accepttos```). -So a full command line to create a certificate for IIS site 1 on a clean server (except for -the 'exclude.me' binding) would look like this: - -```wacs.exe --target iis --siteid 1 --excludebindings exclude.me --emailaddress myaddress@example.com --accepttos``` - -#### More examples -Some application-specific examples are available [here](/win-acme/manual/advanced-use/examples).
\ No newline at end of file diff --git a/docs/manual/advanced-use/load-balancing.md b/docs/manual/advanced-use/load-balancing.md deleted file mode 100644 index 4121a54..0000000 --- a/docs/manual/advanced-use/load-balancing.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -sidebar: manual ---- - -# Load balancing -Some pointers on win-acme and load balancing. - -## Sharing certificates between servers -It really depends if you're using a separate appliance to offload HTTPS or if it's -handled by the servers in the pool themselves. In the latter case you should probably -use the [Central Certificate Store](https://blogs.msdn.microsoft.com/kaushal/2012/10/11/central-certificate-store-ccs-with-iis-8-windows-server-2012/) -feature of IIS. Instructions on how to configure win-acme to use it can be found -[here](/win-acme/reference/plugins/store/centralssl). - -## Scheduled task -- You can have a single server act as a renewal server running win-acme. That means it's a single - point of failure, but only a minor one, because certificates only need to be renewed once every - three months. -- To distribute the task of renewing, you should point the `ConfigurationPath` in the `settings.json` - of win-acme to somewhere on your SAN, so that any member of the pool can potentially renew the - certificates. -- You can configure the Scheduled Task on different machines at different times, e.g. one at 4:00 am, - the next at 5:00 am, etc. Then you can be sure that they will not run at the same time and the first - one that succeeds handles everything. -- If you're building an actual cluster, you can use a Clustered Task instead of a regular Scheduled Task. - -## Encryption -The encryption for the config files will have to be disabled via `settings.json` so that all machines -in the cluster can read the passwords. - -## Appliance -If you are using an appliance then you have to use their API and call into that from a `.bat`/`.ps1`/`.exe` -using an [installation script](/win-acme/reference/plugins/installation).
\ No newline at end of file diff --git a/docs/manual/automatic-renewal.md b/docs/manual/automatic-renewal.md deleted file mode 100644 index 16ae606..0000000 --- a/docs/manual/automatic-renewal.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -sidebar: manual ---- - -# Automatic renewal - -## Scheduled task -A single scheduled task is responsible to renew *all* certificates created by the program, -but will only do so when it's actually neccessary. The task is created by the program itself -after successfully creating the first certificate. The task runs every day and checks two -conditions to determine if it should renew: -- If the certificate is getting too old. This is based on the known history stored in the file. -- If the target (list of domains) has changed, e.g. an extra binding has been added to an IIS site. - -### Customization -The default renewal period of 55 days can be changed in [settings.json](/win-acme/reference/settings). -Other properties of the scheduled task can also be changed that way, or from the Task Scheduler itself, -as long as its name left unmodified. By default it runs at 9:00 am using the `SYSTEM` account. - -### Health checks -The health of the scheduled task is checked each time the program is run manually. It can also -be (re)created from the menu (`More options...` > `(Re)create scheduled task`). - -## Monitoring -The renewal process can be monitored from the Windows Event Viewer and log files -written to `%programdata%\win-acme\logs`. You can also set up email notifications -by configuring a mail server in [settings.json](/win-acme/reference/settings). -You can test these notifications from the menu (`More options...` > `Test email notification`). - -## Testing and troubleshooting -To test or troubleshoot the renewal process, renewals can be triggered manually from the menu or the -command line with the `--renew --force` switches. We recommend doing so while running with the -`--verbose` parameter to get maximum log visibility. When listing the details for a renewal, the -program will show any errors that have been recorded during previous runs.
\ No newline at end of file diff --git a/docs/manual/getting-started.md b/docs/manual/getting-started.md deleted file mode 100644 index 58687c6..0000000 --- a/docs/manual/getting-started.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -sidebar: manual ---- - -# Getting started - -## Installation -- Download the latest version of the program from this website. For most users the file -called `win-acme.v2.x.x.xx.x64.trimmed.zip` is recommended, but if you want to run on a -32 bit system you should get the `x86` version instead of the `x64` one, or if you want to -download or develop extra plugins, you should get the `pluggable` version instead of the -`trimmed` one. -- Unzip files to a non-temporary folder, so that the scheduled task will be able to run. -We recommend using `%programfiles%\win-acme`. -- Run `wacs.exe` (this requires administrator privileges). -- Follow the instructions on the screen to configure your first renewal. - -## Creating your first certificate -**Note:** simple mode is for users looking to install a non-wildcard certificate on their local IIS instance. -For any other scenario you should skip straight to the section on [advanced use](/win-acme/manual/advanced-use/). - -- Choose `N` in the main menu to create a new certificate in simple mode. -- Choose how you want to determine the domain name(s) that you want to include in the certificate. -This can be derived from the bindings of an IIS site, or you can input them manually. -- A registration is created with the ACME server, if no existing one can be found. You will be asked -to agree to its terms of service and to provide an email address that the administrators can use to contact you. -- The program negotiates with ACME server to try and prove your ownership of the domain(s) that you want to -create the certificate for. By default the [http validation](/win-acme/reference/plugins/validation/http/) -mode is picked, handled by our [self-hosting](/win-acme/reference/plugins/validation/http/selfhosting) plugin. -Getting validation right is often the most tricky part of getting an ACME certificate. If there are -problems please check out some [common issues](/win-acme/manual/validation-problems). -- After the proof has been provided, the program gets the new certificate from the ACME server and updates -or creates IIS bindings as required, according to the logic documented [here](/win-acme/reference/plugins/installation/iisweb). -- The program remembers all choices that you made while creating the certificate and applies them -for each subsequent [renewal](/win-acme/manual/automatic-renewal). diff --git a/docs/manual/index.md b/docs/manual/index.md deleted file mode 100644 index f159fec..0000000 --- a/docs/manual/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar: manual ---- - -# Manual - -Please pick a subject from the sidebar.
\ No newline at end of file diff --git a/docs/manual/renewal-management.md b/docs/manual/renewal-management.md deleted file mode 100644 index 4faad8b..0000000 --- a/docs/manual/renewal-management.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -sidebar: manual ---- - -# Renewal management -This program is primarily used to create certificates, but the nature of ACME encourages certificates to be -replaced regularly. We call a sequence of certificates, created with specific settings, a **renewal**. It's the -basic unit of work that you manage with the program. - -## Creation -- Creating a renewal can be done interactively from the main menu. The option `N` uses the easiest defaults for -IIS users and the option `M` offers full options, for example for Apache, Exchange, wildcard certificates, etc. -- Any certificate that can be created from the main menu, can also be created from the -[command line](/win-acme/reference/cli). -The command line even offers some options that the menu does not, check out the documentation -about [plugins](/win-acme/reference/plugins/) to read all about it. -- It's also possible to add `.json` files to the folder yourself, either manually or using some clever tooling or -scripting, to create a lighty coupled integration between your own management tools and win-acme. - -## Modification -Many users mistakenly try to modify their renewal by issuing commands like `--renew --webroot C:\NewRoot` -hoping that the configured webroot for their renewal will be changed. The reason this doesn't work is -because a renew cycle checks **all** renewals, each of which can use any of the hundreds of possible -combinations of [plugins](/win-acme/reference/plugins/), so it's complex to figure out what the -true intention of such a command should be. Therefore, modification and renewal are completely separate -functions. - -Modifying a renewal is essential the same as re-creating it, either from the command line or the main menu. -If it turns out that a newly configured certificate has the same friendly name as a previously created one, -then the older settings will be overwritten. In interactive mode the user is asked to confirm this. In -unattended mode the script or program calling win-acme is assumed to know the consequences of its actions. - -## Deleting/cancelling -To cancel a renewal means that the certificate will not be renewed anymore. The certificate, bindings -and other configuration that is already in place will **not** be touched, so it's completely safe to do -this without disturbing your production applications. Only you will have to set up a new renewal or -alternative certificate solution before the certificate reaches its natural expiration date. -- You can cancel a renewal from the main menu. The program will then delete the `.json` file from -disk and forget about it. -- You can cancel from the command line using the arguments `--cancel [--friendlyname xxx|-id xxx]`. -The effects are the same as above. -- You can delete the `.json` file yourself. The effects are the same as above. - -## Revocation -Revoking a certificate should only be done when the private key is believed to have been compromised, -not when simply replacing or cancelling it. Revocation can be done from the main menu with -(`Manage renewals` > `Revoke certificate`) -- You can revoke from the command line using the arguments `--revoke [--friendlyname xxx|-id xxx]`. -The effects are the same as above. - -## Internals -Renewals are stored in the `ConfigPath` which typically means `%ProgramData%\win-acme\acme-v02.api.letsencrypt.org`, -though that can be changed in [settings.json](/win-acme/reference/settings). Each file that fits the pattern -`*.renewal.json` is considered to be a renewal. - -### File names -The files are randomly named by the program, but you are free to rename them if that suits you. The only requirement -is that they must be unique, which is enforced by checking that the `"Id"` field in the JSON must match with the -name of file. You can specify your own identifier at creation time with the `--id` switch. - -### File content -The renewal files consist of three parts: -- Metadata, e.g. it's identifier, friendly name and the encrypted version of the password that is used for -the cached `.pfx` archive. -- Plugin configuration, e.g. everything that the [plugins](/win-acme/reference/plugins/) need to know -to do their jobs, according to the command line arguments and menu choices that were given at creation time. -- History, i.e. a record of each successful and failed attempt to get a certificate based on the file.
\ No newline at end of file diff --git a/docs/manual/system-requirements.md b/docs/manual/system-requirements.md deleted file mode 100644 index 586d99e..0000000 --- a/docs/manual/system-requirements.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -sidebar: manual ---- - -# System requirements -- Officially Microsoft only supports Windows Server 2012 R2 SP1 and higher -for .NET Core 3, but the program has been tested on Windows Server 2008 -as well. -- You may need to install [Microsoft Visual C++ 2015 Redistributable Update 3](https://www.microsoft.com/download/details.aspx?id=52685) -- If you run into the error about `api-ms-win-crt-runtime-l1-1-0.dll` you may need [KB2999226](https://support.microsoft.com/help/2999226/update-for-universal-c-runtime-in-windows) -- If you run into the error about `hostfxr.dll` you may need [KB2533623](https://support.microsoft.com/help/2533623/microsoft-security-advisory-insecure-library-loading-could-allow-remot) - -## Microsoft IIS -### Server Name Indication -Server Name Indication (SNI) is supported from IIS 8.0 (Windows Server 2012) and above. -This feature allows you to have multiple HTTPS certificates on the same IP address. -Without it, you can only configure a single certificate per IP address. - -#### Workarounds for IIS 7.x -If you want to have SSL for multiple sites with multiple domains with IIS 7.5 or -lower all bound to the same IP address your choices are: -- Create a single certificate for all sites. That only works if there are less than -100 domains in total (that's the maximum Let's Encrypt will currently support) -- If they are sub domains of the same root, a wildcard certificate can be an option. - -#### Configuring the IP address -When win-acme creates the binding for a new certificate, it will bind the wildcard (*) -IP address by default. In other words, incoming connections on all network interfaces -will handeled using the certificate. You can customize this with the `--sslipaddress` -switch from the command line, or manually after win-acme created the binding. On renewal, -the program will preserve whatever setting is configured in IIS. - -### Wildcard bindings -Wildcard bindings are only supported on IIS 10 (Windows Server 2016+). Wildcard -certificates can be created with older versions of IIS but their bindings will have -to be configured manually. - -### FTPS bindings -Updating FTPS binding is only supported for IIS 7.5 (Windows 2008 R2) and above. - -## Powershell -If you use Powershell (`.ps1`) script for custom installation or DNS validation steps, -please make sure to use a recent version of the Powershell runtime. Windows Server 2008 -ships with Powershell 2.0 which seems to have issues with starting from win-acme. - -## Microsoft Exchange -Please refer to [this page](https://docs.microsoft.com/en-us/exchange/plan-and-deploy/supportability-matrix?view=exchserver-2019) -to check compatibility between different versions of Exchange and the .NET Framework.
\ No newline at end of file diff --git a/docs/manual/upgrading/index.md b/docs/manual/upgrading/index.md deleted file mode 100644 index 1e618d8..0000000 --- a/docs/manual/upgrading/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -sidebar: manual ---- - -# Upgrading -When evolving win-acme, we strive for backwards compatibility and in-place upgrades. A typical upgrade can be -deleting everything from the program directory and extracting the new files. This can even be automated by -tools like [Scoop](https://github.com/lukesampson/scoop). - -There are some cases when you might want to be a little more careful. - -- When you made changes to the script(s) included with the distributed .zip-file, you will probably want to - preserve those. We do accept PR's for scripts, so if they are the type of changes which others might find - useful too, please feel free to submit them. -- If you made changes to `wacs.exe.config`, you will probably want to preserve those. If that is the case - please be careful to use the newly released file as the baseline and make the necessary changes there, - rather than keeping the old file around. This is because the file also contains configuration information - for the .NET CLR which has to match the build it's been generated for. - -## Testing -It's recommended to review and test all scheduled renewals after an upgrade. - -## Migrations -Some versions of win-acme have required or recommended migration steps, which are listed here. "v1.9.5" -in this case means that you can or should read this if you're migrating from a version below 1.9.5 -to version 1.9.5 or higher. - -- [v1.9.5](/win-acme/manual/upgrading/to-v1.9.5) -- [v1.9.9](/win-acme/manual/upgrading/to-v1.9.9) -- [v2.0.0](/win-acme/manual/upgrading/to-v2.0.0) -- [v2.1.0](/win-acme/manual/upgrading/to-v2.0.0)
\ No newline at end of file diff --git a/docs/manual/upgrading/to-v1.9.5.md b/docs/manual/upgrading/to-v1.9.5.md deleted file mode 100644 index 01b0e3b..0000000 --- a/docs/manual/upgrading/to-v1.9.5.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar: manual ---- - -# Migration from <=1.9.4 to v1.9.5 -Version 1.9.5 and later store information in system-wide folders and registry locations by -default, but still support reading configuration data from user specific locations. As such -it is backwards compatible with 1.9.4 and earlier. - -## Registry (optional) -- Export the key `HKEY_CURRENT_USER\Software\letsencrypt-win-simple` -- Delete the key -- Open the .reg file with your favorite text editor -- Replace `HKEY_CURRENT_USER` for `HKEY_LOCAL_MACHINE` and save it -- Import the .reg file - -## File system (optional) -Move the folder `%appdata%\letsencrypt-win-simple` to `%programdata%\letsencrypt-win-simple`. -Make sure the original is deleted, because the program prefers the old one over the new one. - -## Scheduled task (optional) -It should be changed to run as `SYSTEM`. Running under a specific user does not seem to work -if the task is running without a password specified.
\ No newline at end of file diff --git a/docs/manual/upgrading/to-v1.9.9.md b/docs/manual/upgrading/to-v1.9.9.md deleted file mode 100644 index 9db6640..0000000 --- a/docs/manual/upgrading/to-v1.9.9.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar: manual ---- - -# Migration from v1.9.5+ to v1.9.9 -This version introduced the ability to store information about renewals in a file instead of -the registry. This has several advantages including easier replication, backups, etc. - -By default this is only enable for new clean installs, but you can migrate manually if -you want to. This assumes you already followed the [v1.9.5](/win-acme/manual/upgrading/to-v1.9.5) -steps, or your initial install was on that version or higher. If not, -replace `HKEY_LOCAL_MACHINE` with `HKEY_CURRENT_USER` and `%programdata%` with `%appdata%`. - -- Start `regedit.exe` -- Go to `HKEY_LOCAL_MACHINE\SOFTWARE\letsencrypt-win-simple\` -- For each key there take the following steps: - - Find the matching folder in your `ConfigurationPath`, which defaults to `%programdata%\letsencrypt-win-simple` - - E.g. the key `https://acme-v01.api.letsencrypt.org/` matches with the folder `httpsacme-v01.api.letsencrypt.org` - - Create a new file named `Renewals` in the matching folder - - Copy the contents of the registry subkey `Renewals` to that file -- Delete or rename `HKEY_LOCAL_MACHINE\SOFTWARE\letsencrypt-win-simple\` to make sure the program doesn't find it anymore.
\ No newline at end of file diff --git a/docs/manual/upgrading/to-v2.0.0.md b/docs/manual/upgrading/to-v2.0.0.md deleted file mode 100644 index 40a74d8..0000000 --- a/docs/manual/upgrading/to-v2.0.0.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -sidebar: manual ---- - -# Migration from v1.9.9+ to v2.0.x -Version 2.0.0 is **not** an xcopy update. Many small but potentially **breaking** changes have been made. -See the [release notes](https://github.com/PKISharp/win-acme/releases/tag/v2.0.0.177) for details. This -guide explains how to import the renewals, but you might need to take other steps depending on how you -use the tool. - -## Pre-upgrade -When using an old version of LEWS or win-acme (1.9.7 or older), it's recommended to upgrade to the latest -1.9.x version and forcing a renewal of all certificates before attempting to upgrade to 2.0.0. The reason -for this is that new versions of the 1.9.x series automatically apply some compatibility steps, which may -not have been fully tested for the built-in converter to 2.0.0. - -## Importing renewals -Importing from 1.9.x is pretty easy. In the main menu select the option `More options...` and then -`Import renewals from LEWS/WACS 1.9.x`. The program will locate, convert and import the renewals -from the previous version. It will also disable the scheduled task for the old version and create -a new one for the new version. - -The same thing can be accomplished unattended with the `--import` switch. - -Note that the import process in versions before 2.1.4 will *not* create an account at the ACMEv2 server -for you, so you will have to set one up (by manually renewing once) before you will be able to renew with -the scheduled task. In any case it's a good idea to review the imported renewals and monitor the -progress of the first execution before declaring the conversion a success.
\ No newline at end of file diff --git a/docs/manual/upgrading/to-v2.0.11.md b/docs/manual/upgrading/to-v2.0.11.md deleted file mode 100644 index 86d3a72..0000000 --- a/docs/manual/upgrading/to-v2.0.11.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar: manual ---- - -# Migration from v1.9.x to v2.0.11 -The following does not apply to you. Please just follow the steps for the -[v1.9.x to v2.0.x](/win-acme/manual/upgrading/to-v2.0.0) migration. - -# Migration from v2.0.x to v2.0.11 -You will have to delete the files `Registration_v2` and `Signer_v2` from the ConfigurationPath, -which is `%programdata%\win-acme` by default. Then you will have to manually renew once to -create a new account with the ACME server. - -The reason for this is that v2.0.11 runs on .NET Framework 4.6.1 which required us to drop support -for the elliptic curve account signers.
\ No newline at end of file diff --git a/docs/manual/upgrading/to-v2.1.0.md b/docs/manual/upgrading/to-v2.1.0.md deleted file mode 100644 index ad69253..0000000 --- a/docs/manual/upgrading/to-v2.1.0.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -sidebar: manual ---- - -# Migration from v1.9.x to v2.1.x -You can follow the same instructions as listed for for -[v1.9.x to v2.0.x](/win-acme/manual/upgrading/to-v2.0.0) -with some notable exceptions. - -Releases `2.1.4` and above will also ensure that there is an account for the -ACMEv2 server, so that an initial manual renewal is no longer required. -For fully unattended upgrades, you will therefor have to specify -`--import --emailaddress you@example.com --accepttos` on the command line so -that the account can be created without additional user input. - -# Migration from v2.0.x to v2.1.0 -Version 2.1.0 is an xcopy update for "standard" users, but those who customized the program to fit their -needs with `settings.config`, custom plugins or custom Serilog configuration will have to re-apply some of -these modifications. - -- Custom plugins will have to be modified to conform to the new async interfaces of this version of win-acme. -Also they will have to be targeted to build for .NET Core 3.1. Note that this does not affect installation or -DNS scripts, only additional `.dll`s. -- settings.config has been replaced with [settings.json](/win-acme/reference/settings). The format is more -readable and nicely structured, but if you have some custom settings, you will have to re-apply them. -- If you are using custom settings for Serilog, you will have to migrate them to a new file called -`serilog.json`. More details are available [here](/win-acme/manual/advanced-use/custom-logging).
\ No newline at end of file diff --git a/docs/manual/validation-problems.md b/docs/manual/validation-problems.md deleted file mode 100644 index 37bee9a..0000000 --- a/docs/manual/validation-problems.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -sidebar: manual ---- - -# Validation problems -Validation is an important aspect of the ACME and Let's Encrypt, but there are many subtle ways -that it can fail. This page is meant for people who run into problems to help figure out what -the issue might be. - -## Testing -Run `wacs.exe` with the `--test` and `--verbose` parameters to watch your validation unfold in -'slow motion'. This will run against the Let's Encrypt staging server so you don't risk -running into any rate limits. If you want to test against the production endpoint, include the -parameter `--baseuri https://acme-v02.api.letsencrypt.org/` as well. - -## General validation issues - -### DNSSEC -ACME providers will typically validate your DNSSEC configuration. If there is anything suspicious -about it, your browser might not complain, but you will not be able to get a certificate. A useful -tool to check your (provider's) DNSSEC configuration from the perspective of a strict external -observer is the [Unbound DNS checker](https://unboundtest.com/). - -### CAA records -ACME providers will check for the existence and validity of a -[CAA record](https://support.dnsimple.com/articles/caa-record/) for your domain. You may have to add -a record like `example.com. CAA 0 issue "letsencrypt.org" to your DNS server in order to allow the -provider to issue certificates for your domain. - -### Protocols and cipher suites -Tools like [IISCrypto](https://www.nartac.com/Products/IISCrypto) are often used configure the -[cipher suites](http://letsencrypt.readthedocs.io/en/latest/ciphers.html) of Windows systems -according to the latest best practices. Changing these settings always brings some risk of -breaking compatibility between two parties though. Too restrictive cipher suites have been known -to hamper the ability to communicate with the ACME API endpoint and its validation servers. If -that happens try more conservative settings. Test if the [API endpoint](https://acme-v02.api.letsencrypt.org) -is accessible from a web browser on your server. - -## Let's Encrypt limitations -The following limitations apply to Let's Encrypt and may not be true for every ACME -service provider. - -### Domain count limit -Let's Encrypt does not support more than 100 domain names per certificate. - -### Non-public domains -Let's Encrypt can only be used to issue certificates for domains living on the -public internet. Interal domains or Active Directory host names are therefor not -possible to use. - -## HTTP validation issues - -### Firewall -HTTP validation happens on port 80, so it will have to open on your firewall(s). Let's Encrypt -doesn't disclose IP address range(s) for their validation servers, meaning port 80 will have -to be accessible from *any* origin, at least for the duration of the validation. - -### IPv6 configuration -Let's Encrypt will check IPv6 access to your site if `AAAA` records are configured. Many browsers -and networks don't use IPv6 yet or automatically fallback to IPv4 when an error occurs, so -it might not be immediately obvious that your site is unreachable on IPv6. You can test -it [here](http://ipv6-test.com/validate.php). - -### FileSystem plugin IIS issues -Note that it's recommended to use the default `SelfHosting` validation plugin in combination -with IIS. The `FileSystem` validation is great of other web servers such as -[Apache](/win-acme/manual/advanced-use/examples/apache), but using it in combination with IIS -leads to many potentials issues, described in the following sections. - -#### CMS modules -Your CMS might intercept the request and redirect the user to an (error) page. The solution -is to configure your CMS to allow unlimited access to the `/.well-known/acme-challenge/` -path. - -#### Problems with httpHanders -IIS might not be configured to serve static extensionless files. - -1. In IIS manager go to the `/.well-known/acme-challenge/` folder of the site (you may have to -create it). **Don't** do this at the root of the server or the website, because it might -break your application(s). -2. Choose Handler Mappings -> View Ordered List. -3. Move the StaticFile mapping above the ExtensionlessUrlHandler mappings. - - - -#### Anonymous authentication -Your website might require Windows authentication, client certificates or other -authentication methods. Enable anonymous authentication to the `/.well-known/acme-challenge/` -path to allow access from the ACME server. - -#### Require SSL -Your website might be configured to exclusively accept SSL traffic, while the validation -request comes in on port 80. Disable the "Require SSL" setting for the -`/.well-known/acme-challenge/` path to fix that. - -#### IP Address and Domain Restrictions -Your website might use IP Address and Domain Restrictions to provide extra security. -The ACME server will have to bypass though. Let's Encrypt does not publicize a list of -IP addresses that they can use for validation, so this features needs to be disabled -for the `/.well-known/acme-challenge/` path. - -#### URL Rewrite -If you are using [URL Rewrite](https://www.iis.net/downloads/microsoft/url-rewrite) the -validation request might get caught up in that, so you have to make exceptions for -the `/.well-known/acme-challenge/` path. For example like so: - -```XML -<rule name="LetsEncrypt Rule" stopProcessing="true"> - <match url="^\.well-known\acme-challenge\.*$" /> - <action type="None" /> -</rule> -``` - -## DNS validation issues - -### Name server synchronisation -Let's Encrypt may query all of your name servers, so they will have to be -in sync before submitting the challenge. The program will perform a pre-validation -'dry run' for a maximum of 5 times with 30 second intervals to allow the DNS -changed to be processed. diff --git a/docs/reference/cli.md b/docs/reference/cli.md deleted file mode 100644 index 8d418ec..0000000 --- a/docs/reference/cli.md +++ /dev/null @@ -1,421 +0,0 @@ ---- -sidebar: reference ---- - -# Command line arguments -Here are all the command line arguments the program accepts. - -#### Notes -- Make sure that you are familiar with the basics of [renewal management](/win-acme/manual/renewal-management) - before proceeding with unattended use. -- Arguments documented as such: `--foo [--bar baz|qux]` mean that `--foo` is only -applicable when `--bar` is set to `baz` or `qux`. - -## Main -``` - --baseuri - Address of the ACMEv2 server to use. The default endpoint - can be modified in settings.json. - - --import - Import scheduled renewals from version 1.9.x in unattended - mode. - - --importbaseuri - [--import] When importing scheduled renewals from version - 1.9.x, this argument can change the address of the ACMEv1 - server to import from. The default endpoint to import from - can be modified in settings.json. - - --test - Enables testing behaviours in the program which may help - with troubleshooting. By default this also switches the - --baseuri to the ACME test endpoint. The default endpoint - for test mode can be modified in settings.json. - - --verbose - Print additional log messages to console for - troubleshooting and bug reports. - - --help - Show information about all available command line options. - - --version - Show version information. - - --renew - Renew any certificates that are due. This argument is used - by the scheduled task. Note that it's not possible to - change certificate properties and renew at the same time. - - --force - Force renewal on all scheduled certificates when used - together with --renew. Otherwise just bypasses the - certificate cache on new certificate requests. - - --cancel - Cancel renewal specified by the --friendlyname or --id - arguments. - - --revoke - Revoke the most recently issued certificate for the renewal - specified by the --friendlyname or --id arguments. - - --list - List all created renewals in unattended mode. - - --id - [--target|--cancel|--renew|--revoke] Id of a new or existing - renewal, can be used to override the default when creating - a new renewal or to specify a specific renewal for other - commands. - - --friendlyname - [--target|--cancel|--renew|--revoke] Friendly name of a new or - existing renewal, can be used to override the default when - creating a new renewal or to specify a specific renewal - for other commands. In the latter case a pattern might be used. - You may use a `*` for a range of any characters and a `?` - for any single character. For example: the pattern `example.*` - will match `example.net` and `example.com` (but not `my.example.com`) - and the pattern `?.example.com` will match `a.example.com` and - `b.example.com` (but not `www.example.com`). Note that multiple patterns - can be combined by comma seperating them. - - --target - Specify which target plugin to run, bypassing the main - menu and triggering unattended mode. - - --validation - Specify which validation plugin to run. If none is - specified, SelfHosting validation will be chosen as the - default. - - --validationmode - Specify which validation mode to use. HTTP-01 is the - default. - - --csr - Specify which csr plugin to use. RSA is the default. - - --store - Specify which store plugin to use. CertificateStore is the - default. This may be a comma separated list. - - --installation - Specify which installation plugins to use. IIS is the - default. This may be a comma separated list. - - --closeonfinish - [--test] Close the application when complete, which - usually does not happen when test mode is active. Useful - to test unattended operation. - - --hidehttps - Hide sites that have existing https bindings from - interactive mode. - - --notaskscheduler - Do not create (or offer to update) the scheduled task. - - --usedefaulttaskuser - (Obsolete) Avoid the question about specifying the task - scheduler user, as such defaulting to the SYSTEM account. - - --accepttos - Accept the ACME terms of service. - - --emailaddress - Email address to use by ACME for renewal fail notices. - - --encrypt - Rewrites all renewal information using current - EncryptConfig setting - -``` -# CSR - -## Common -``` - --ocsp-must-staple - Enable OCSP Must Staple extension on certificate. - - --reuse-privatekey - Reuse the same private key for each renewal. - -``` -# Installation - -## IIS FTP plugin -``` [--installation iisftp] ``` -``` - --ftpsiteid - Site id to install certificate to. - -``` -## IIS Web plugin -``` [--installation iis] ``` -``` - --installationsiteid - Specify site to install new bindings to. Defaults to the - target if that is an IIS site. - - --sslport - Port number to use for newly created HTTPS bindings. - Defaults to 443. - - --sslipaddress - IP address to use for newly created HTTPS bindings. - Defaults to *. - -``` -## Script plugin -``` [--installation script] ``` -``` - --script - Path to script file to run after retrieving the - certificate. This may be a .exe or .bat. Refer to the Wiki - for instructions on how to run .ps1 files. - - --scriptparameters - Parameters for the script to run after retrieving the - certificate. Refer to the Wiki for further instructions. - -``` -# Store - -## Central Certificate Store plugin -``` [--store centralssl] ``` -``` - --centralsslstore - When using this setting, certificate files are stored to - the CCS and IIS bindings are configured to reflect that. - - --pfxpassword - Password to set for .pfx files exported to the IIS CSS. - -``` -## Certificate Store plugin -``` [--store certificatestore] ``` (default) -``` - --certificatestore - This setting can be used to save the certificate in a - specific store. By default it will go to 'WebHosting' - store on modern versions of Windows. - - --keepexisting - While renewing, do not remove the previous certificate. - - --acl-fullcontrol - List of additional principals (besides the owners of the - store) that should get full control permissions on the - private key of the certificate. - -``` -## PEM files plugin -``` [--store pemfiles] ``` -``` - --pemfilespath - .pem files are exported to this folder - -``` -# Target - -## CSR plugin -``` [--target csr] ``` -``` - --csrfile - Specify the location of a CSR file to make a certificate - for - - --pkfile - Specify the location of the private key corresponding to - the CSR - -``` -## IIS plugin -``` [--target iis] ``` -``` - --siteid - Identifiers of one or more sites to include. This may be a - comma seperated list. - - --host - Host name to filter. This parameter may be used to target - specific bindings. This may be a comma seperated list. - - --host-pattern - Pattern filter for host names. Can be used to dynamically - include bindings based on their match with the pattern. - You may use a `*` for a range of any characters and a `?` - for any single character. For example: the pattern - `example.*` will match `example.net` and `example.com` - (but not `my.example.com`) and the pattern `?.example.com` - will match `a.example.com` and `b.example.com` (but not - `www.example.com`). Note that multiple patterns can be - combined by comma seperating them. - - --host-regex - Regex pattern filter for host names. Some people, when - confronted with a problem, think "I know, I'll use regular - expressions." Now they have two problems. - - --commonname - Specify the common name of the certificate that should be - requested for the target. By default this will be the - first binding that is enumerated. - - --excludebindings - Exclude host names from the certificate. This may be a - comma separated list. - -``` -## Manual plugin -``` [--target manual] ``` -``` - --commonname - Specify the common name of the certificate. If not - provided the first host name will be used. - - --host - A host name to get a certificate for. This may be a comma - separated list. - -``` -# Validation - -## SelfHosting plugin -``` [--validationmode tls-alpn-01 --validation selfhosting] ``` (default) -``` - --validationport - Port to use for listening to validation requests. Note - that the ACME server will always send requests to port - 443. This option is only useful in combination with a port - forwarding. - -``` -## FileSystem plugin -``` [--validation filesystem] ``` -``` - --validationsiteid - Specify IIS site to use for handling validation requests. - This will be used to choose the web root path. - -``` -## Common HTTP validation options -``` [--validation filesystem|ftp|sftp|webdav] ``` -``` - --webroot - Root path of the site that will serve the HTTP validation - requests. - - --warmup - Not used (warmup is the new default). - - --manualtargetisiis - Copy default web.config to the .well-known directory. - -``` -## SelfHosting plugin -``` [--validation selfhosting] ``` (default) -``` - --validationport - Port to use for listening to validation requests. Note - that the ACME server will always send requests to port 80. - This option is only useful in combination with a port - forwarding. - -``` -## AcmeDns -``` [--validationmode dns-01 --validation acme-dns] ``` -``` - --acmednsserver - Root URI of the acme-dns service - -``` -## Script -``` [--validationmode dns-01 --validation script] ``` -``` - --dnsscript - Path to script that creates and deletes validation - records, depending on its parameters. If this parameter is - provided then --dnscreatescript and --dnsdeletescript are - ignored. - - --dnscreatescript - Path to script that creates the validation TXT record. - - --dnscreatescriptarguments - Default parameters passed to the script are create - {Identifier} {RecordName} {Token}, but that can be - customized using this argument. - - --dnsdeletescript - Path to script to remove TXT record. - - --dnsdeletescriptarguments - Default parameters passed to the script are delete - {Identifier} {RecordName} {Token}, but that can be - customized using this argument. - -``` -## Credentials -``` [--validation ftp|sftp|webdav] ``` -``` - --username - User name for WebDav/(s)ftp server - - --password - Password for WebDav/(s)ftp server - -``` -## Azure -``` [--validationmode dns-01 --validation azure] ``` -``` - --azureusemsi - Use Managed Service Identity for authentication. - - --azuretenantid - Tenant ID to login into Microsoft Azure. - - --azureclientid - Client ID to login into Microsoft Azure. - - --azuresecret - Secret to login into Microsoft Azure. - - --azuresubscriptionid - Subscription ID to login into Microsoft Azure DNS. - - --azureresourcegroupname - The name of the resource group within Microsoft Azure DNS. - -``` -## Cloudflare -``` [--validationmode dns-01 --validation cloudflare] ``` -``` - --cloudflareapitoken - API Token for Cloudflare. - -``` -## Dreamhost -``` [--validationmode dns-01 --validation dreamhost] ``` -``` - --apiKey - Dreamhost API key. - -``` -## Route53 -``` [--validationmode dns-01 --validation route53] ``` -``` - --route53IAMRole - AWS IAM role for the current EC2 instance to login into - Amazon Route 53. - - --route53AccessKeyId - Access key ID to login into Amazon Route 53. - - --route53SecretAccessKey - Secret access key to login into Amazon Route 53. - -```
\ No newline at end of file diff --git a/docs/reference/index.md b/docs/reference/index.md deleted file mode 100644 index 34dffb1..0000000 --- a/docs/reference/index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar: reference ---- - -# Reference diff --git a/docs/reference/plugins/csr/ec.md b/docs/reference/plugins/csr/ec.md deleted file mode 100644 index f410074..0000000 --- a/docs/reference/plugins/csr/ec.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -sidebar: reference ---- - -# Elliptic Curve -Generates ECDSA keys based on the `secp384r1` curve. The curve to use can be -configured in [settings.json](/win-acme/reference/settings) but currently only -SEC named curves are supported by this program. The ACME server provider may -also have limitations. - -{% include csr-common.md %} - -## Unattended -`--csr ec`
\ No newline at end of file diff --git a/docs/reference/plugins/csr/index.md b/docs/reference/plugins/csr/index.md deleted file mode 100644 index 236a730..0000000 --- a/docs/reference/plugins/csr/index.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -sidebar: reference ---- - -# CSR plugins - -CSR plugins are responsible for providing certificate requests that the ACME server can sign. -They determine key properties such as the private key, applications and extensions. When -a CSR is used as [target](/win-acme/reference/plugins/target/csr), no CSR plugin can be chosen -and the third party application is expected to take care of the private key and extensions instead. - -## Default - -The default is an [RSA](/win-acme/reference/plugins/csr/rsa) private key.
\ No newline at end of file diff --git a/docs/reference/plugins/csr/rsa.md b/docs/reference/plugins/csr/rsa.md deleted file mode 100644 index bc2e24f..0000000 --- a/docs/reference/plugins/csr/rsa.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -sidebar: reference ---- - -# RSA -Default plugin, generates 3072 bits RSA key pairs. The number of bits can be configured in -[settings.json](/win-acme/reference/settings) but may not be less than 2048. For -improved compatiblitity with Microsoft Exchange, RSA keys are automatically converted to the -`Microsoft RSA SChannel Cryptographic Provider`. - -{% include csr-common.md %} - -## Unattended -`[--csr rsa]`
\ No newline at end of file diff --git a/docs/reference/plugins/development.md b/docs/reference/plugins/development.md deleted file mode 100644 index 9cbb12c..0000000 --- a/docs/reference/plugins/development.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -sidebar: reference ----
\ No newline at end of file diff --git a/docs/reference/plugins/index.md b/docs/reference/plugins/index.md deleted file mode 100644 index 1b0e617..0000000 --- a/docs/reference/plugins/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -sidebar: reference ---- - -# Plugins - -Conceptually win-acme works by chaining together five components also known as plugins, which can be mixed and matched to support many use cases. - -- A [target plugin](/win-acme/reference/plugins/target/) provides information about (potential) certificates to create. -- A [validation plugin](/win-acme/reference/plugins/validation/) provides the ACME server with proof that you own the domain(s). -- A [CSR plugin](/win-acme/reference/plugins/csr/) determines the (type of) private key and extensions to use for the certificate. -- One or more [store plugins](/win-acme/reference/plugins/store/) place the certificate in a specific location and format. -- One or more [installation plugins](/win-acme/reference/plugins/installation/) make changes to your application(s) configuration.
\ No newline at end of file diff --git a/docs/reference/plugins/installation/iisftp.md b/docs/reference/plugins/installation/iisftp.md deleted file mode 100644 index 393179c..0000000 --- a/docs/reference/plugins/installation/iisftp.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -sidebar: reference ---- - -# IIS FTP -Create or update FTP site bindings in IIS, according to the following logic: - -- Any existing FTP sites linked to the previous certificate are updated to use the new certificate. -- The target FTP site will be updated to use the new certificate. - -## Unattended -`--installation iisftp [--ftpsiteid x]`
\ No newline at end of file diff --git a/docs/reference/plugins/installation/iisweb.md b/docs/reference/plugins/installation/iisweb.md deleted file mode 100644 index c9d2cef..0000000 --- a/docs/reference/plugins/installation/iisweb.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -sidebar: reference ---- - -# IIS Web -Create or update website bindings in IIS, according to the following logic: - -- Existing https bindings in *any* site linked to the previous certificate are updated to use the new certificate. -- Hosts names which are determined to not yet have been covered by any existing binding, will be processed further. - - All existing https bindings in *target* site whose hostnames match with the new certificate are updated - to use the new certificate. This happens even if they are using certificates issued by other authorities. - (Note that if you want to prevent this from happening, you can use the `--excludebindings` switch). - - If no existing https binding can be found, a new binding is created. - - It will create bindings on the specified installation site and fall back to the target site if there is none. - - It will use port `443` on IP `*` unless different values are specified with the `--sslport` and/or - `--sslipaddress` switches. - - New bindings will be created or updated for matching host headers with the most specific match. E.g. if you - generate a certificate for `a.b.c.com`, the order of preference for the binding creation/change will be: - 1. `a.b.c.com` - 2. `*.b.c.com` - 3. `*.c.com` - 4. `*.com` - 5. `*` (Default/empty binding) - - If the certificate contains a wildcard domain, the order of preference will be: - 1. `*.a.b.c.com` - 2. `x.a.b.c.com` - - In both cases, the first preferred option will be created from scratch if none of the later options - are available. - - In some cases the plugin will not be able to (safely) add a new binding on older versions of IIS, e.g. due to - lack of support for SNI and/or wildcard bindings. In that case the user will have to create them manually. - Renewals will still be automatic after this initial manual setup. - -## Unattended -`--installation iis [--installationsiteid x] [-sslport x] [--sslipaddress x]`
\ No newline at end of file diff --git a/docs/reference/plugins/installation/index.md b/docs/reference/plugins/installation/index.md deleted file mode 100644 index a031317..0000000 --- a/docs/reference/plugins/installation/index.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar: reference ---- - -# Installation plugins -Installation plugins are responsible for making the necessary changes to your -application(s) after successfully creating or renewing a certificate. Currently -there are three of these plugins. - -## Multiple -More than one plugin can run by choosing them in order of execution. In interactive -mode you will be asked, for unattended mode you can provide a comma seperated list, -e.g. `--installation certificatestore,pemfiles` - -## Default (simple mode) -In simple mode the default installation plugin is [IIS Web](/win-acme/reference/plugins/installation/iisweb). - -## Default (full options / unattended) -In full options and unattended modes there are **no** default installation steps, -which is equivalent to `--installation none`. You can to explicitly choose them -from the interface or using the `--installation` switch.
\ No newline at end of file diff --git a/docs/reference/plugins/installation/script.md b/docs/reference/plugins/installation/script.md deleted file mode 100644 index 561a52a..0000000 --- a/docs/reference/plugins/installation/script.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -sidebar: reference ---- - -# Script -Runs an external script or executable after a succesful renewal. This may be a `.bat`, `.ps1` or even `.exe`. -You provide the program with the path to the script and it will run automatically. - -## Parameters -The following variables can be provided from the program to the script as command line arguments. - -| Value | Replaced with | -|----------------|----------------| -| `{0}` or `{CertCommonName}` | Common name (primary domain name) | -| `{1}` or `{CachePassword}` | The .pfx password (generated randomly for each renewal) | -| `{2}` or `{CacheFile}` | Full path of the cached.pfx file | -| `{4}` or `{CertFriendlyName}` | Friendly name of the generated certificate | -| `{5}` or `{CertThumbprint}` | Thumbprint of the generated certificate | -| `{7}` or `{RenewalId}` | Id of the renewal | -| `{3}` or `{6}` or `{StorePath}` | Path or store name used by the (first) store plugin | -| `{StoreType}` | Name of the plugin (CentralSsl, CertificateStore or PemFiles) | - -## Example -If you need your scripts parameters to look something like this: - -`action=import file=C:\mydomain.pfx password=*****` - -Then your argument string should look like this: - -`action=import file={CacheFile} password={CachePassword}` - -## Unattended -`--installation script --script C:\script.bat [--scriptparameters x]` - -### Parameter escaping -If you need to put double quotes around your parameters from the command line, you have to escape them with a slash, for example: - -`--scriptparameters "action=import file=\"{CacheFile}\" password=\"{CachePassword}\""` - -For **Powershell** scripts, string parameters can also be delimited with single quotes, for example: - -`--scriptparameters "action=import file='{CacheFile}' password='{CachePassword}'"`
\ No newline at end of file diff --git a/docs/reference/plugins/store/centralssl.md b/docs/reference/plugins/store/centralssl.md deleted file mode 100644 index c7d2fdd..0000000 --- a/docs/reference/plugins/store/centralssl.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -sidebar: reference ---- - -# IIS Central Certificate Store (CSS) -Designed for the [Central Certificate Store](https://blogs.msdn.microsoft.com/kaushal/2012/10/11/central-certificate-store-ccs-with-iis-8-windows-server-2012/) -introduced in Windows 2012. Creates a separate copy of the `.pfx` file for each hostname and places -it in the path provided by the `--centralsslstore` parameter, or the `DefaultCentralSslStore` setting -in [settings.json](/win-acme/reference/settings). Using this store also triggers any created or -updated IIS bindings to get the `CentralSSL` flag. - -## Unattended -`--store centralssl [--centralsslstore C:\CentralSSL\] [--pfxpassword *****]`
\ No newline at end of file diff --git a/docs/reference/plugins/store/certificatestore.md b/docs/reference/plugins/store/certificatestore.md deleted file mode 100644 index 970d7af..0000000 --- a/docs/reference/plugins/store/certificatestore.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -sidebar: reference ---- - -# Windows Certificate Store -Default plugin, saves certificates to the Windows Certificate store. Which store is used is based on the following priorities: - -- Store configured for the specific renewal -- Global default is configured in [settings.json](/win-acme/reference/settings) -- `WebHosting` store (if it exists, i.e. Windows 2012+ with IIS) -- The machine-level `My` store (better known as Personal) - -## Keep existing -The `--keepexisting` switch can be used to prevent the program from deleting older -versions of the certificate from the store. - -## Private key ACL -The `--acl-fullcontrol` parameter can be used to grant principals other than the -defaults for a specific store full control access to the private key. - -## Unattended -`[--store certificatestore] [--certificatestore My] [--keepexisting] [--acl-fullcontrol "network service,administrators"]`
\ No newline at end of file diff --git a/docs/reference/plugins/store/index.md b/docs/reference/plugins/store/index.md deleted file mode 100644 index 17988a1..0000000 --- a/docs/reference/plugins/store/index.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar: reference ---- - -# Store plugins -Store plugins are responsible for storing issued certificates in their permanent -location(s). The program will cache the certificate in a `.pfx` file in its -CertificatePath (which defaults to `%programdata%\win-acme\[baseuri]certificates`) but -these files are protected by random passwords to prevent local non-administrators -from obtaining keys. Store plugins are responsible for making the certificates -accessible to the application(s) that need them. - -## Multiple -More than one plugin can run by choosing them in order of execution. In interactive -mode you will be asked, for unattended mode you can provide a comma seperated list, -e.g. `--store certificatestore,pemfiles` - -## Default -The default is the [Windows Certificate Store](/win-acme/reference/plugins/store/certificatestore). - -## None -To instruct the program not to use any store, for example when your installation -script handles it, you may specify `--store none`
\ No newline at end of file diff --git a/docs/reference/plugins/store/pemfiles.md b/docs/reference/plugins/store/pemfiles.md deleted file mode 100644 index 86fbfe4..0000000 --- a/docs/reference/plugins/store/pemfiles.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -sidebar: reference ---- - -# PemFiles -Designed for [Apache](/win-acme/manual/advanced-use/examples/apache), nginx and other web servers. -Exports a `.pem` file for the certificate and private key and places them in -the path provided by the `--pemfilespath` parameter, or the `DefaultPemFilesPath` -setting in [settings.json](/win-acme/reference/settings). - -## Unattended -`--store pemfiles [--pemfilespath C:\Certificates\]`
\ No newline at end of file diff --git a/docs/reference/plugins/target/csr.md b/docs/reference/plugins/target/csr.md deleted file mode 100644 index ddc716f..0000000 --- a/docs/reference/plugins/target/csr.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar: reference ---- - -# CSR -Use a certificate signing request generated by third party software. -When this target plugin is chosen, you will obviously not be able to select -a [CSR plugin](/win-acme/reference/plugins/csr/) as well, meaning that any -customization and key selection requirements should already be met. - -Note that it's possible though not required to provide the private key to -the program as well. If you do not provide the private key, the certificate -as stored by the [store plugins](/win-acme/reference/plugins/store/) will -have limited use. - -## Unattended -`--target csr --csrfile C:\csr.txt [--pkfile C:\key.txt]`
\ No newline at end of file diff --git a/docs/reference/plugins/target/iis.md b/docs/reference/plugins/target/iis.md deleted file mode 100644 index b93e3ea..0000000 --- a/docs/reference/plugins/target/iis.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -sidebar: reference ---- - -# IIS -Create target based on bindings configured in IIS. -- Automatically updates webroot path (useful for [FileSystem validation](/win-acme/reference/plugins/validation/http/filesystem)) - -# Filtering bindings -While it's possible to create a certificate for all bindings in all sites, typically you will want to select some -specific bindings to create a certificate for. There are several filters available, that in some cases can also be -combined with eachother. - -## Site filters -You can choose to limit the certificate to specific websites by specifying a site identifier, or a comma seperated list -of them. The magic value `s` will dynamically target all current and future websites created on the server. - -## Binding filters -You can filter bindings by host name by specifically typing them out. It's also be possible to filter hosts by a pattern -or by a regular expression. - -### Pattern -You may use a `*` for a range of any characters and a `?` for any single character. For example: the pattern `example.*` -will match `example.net` and `example.com` (but not `my.example.com`). The pattern `?.example.com` will match -`a.example.com` and `b.example.com` (but not `www.example.com`). Note that multiple patterns can be combined by -comma seperating them. - -### Regex -If a pattern is not powerful enough for you, there is the ultimate solution of applying a regular expression to the -problem. [regex101.com](https://regex101.com/) is a nice tool to help test your regular expression. - -## Unattended -- ##### Single binding -`--target iis --host example.com [--siteid 1]` -- ##### Multiple bindings -`--target iis --host example.com,www.example.com [--siteid 1,2,3] [--commonname common.example.com]` -- ##### All bindings of a site -`--target iis --siteid 1 [--commonname common.example.com] [--excludebindings exclude.example.com]` -- ##### All bindings of multiple sites -`--target iis --siteid 1,2,3 [--commonname common.example.com] [--excludebindings exclude.example.com]` -- ##### All bindings of all sites -`--target iis --siteid s [--commonname common.example.com] [--excludebindings exclude.example.com]` -- ##### Binding pattern -`--target iis --host-pattern *.example.??? [--siteid 1,2,3] [--commonname common.example.com] [--excludebindings exclude.example.com]` -- ##### Binging regex -`--target iis --host-regex [a-z]{3}\.example(\.com|\.net) [--siteid 1,2,3] [--commonname common.example.com] [--excludebindings exclude.example.com]`
\ No newline at end of file diff --git a/docs/reference/plugins/target/index.md b/docs/reference/plugins/target/index.md deleted file mode 100644 index af4e5ac..0000000 --- a/docs/reference/plugins/target/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -sidebar: reference ---- - -# Target plugins - -A target plugin is responsible for providing information about a (potential) certificate to the rest of the program. -Its primary purpose is to determine which host names should be included in the SAN list, but can also provide extra -information such as the preferred common name or bindings to exclude. - -## Default - -There is no default target plugin, it always has to be chosen by the user.
\ No newline at end of file diff --git a/docs/reference/plugins/target/manual.md b/docs/reference/plugins/target/manual.md deleted file mode 100644 index 4422c40..0000000 --- a/docs/reference/plugins/target/manual.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar: reference ---- - -# Manual -Manually input host names. The first name will be the common name of the certificate, the other will only be in the SAN list. - -## Unattended -`--target manual --host a.example.com,b.example.com`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/dns/acme-dns.md b/docs/reference/plugins/validation/dns/acme-dns.md deleted file mode 100644 index 18f7f6a..0000000 --- a/docs/reference/plugins/validation/dns/acme-dns.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar: reference ---- - -# acme-dns -Use an [acme-dns](https://github.com/joohoi/acme-dns) server to handle the validation records. -The plugin will ask you to choose an endpoint to use. For testing the `https://auth.acme-dns.io/` -endpoint is useful, but it is a security concern. As the readme of that project clearly states: - -> "You are encouraged to run your own acme-dns instance." - -It's possible to use basic authentication for your acme-dns service by specifying a url with -the format `https://user:password@acme-dns.example.com/` - -## Unattended -Not supported, unless there is a pre-existing acme-dns registration for all the domains. -The reason for this is that acme-dns requires you to create CNAME records. In the future this -might be scripted the same way we can script DNS validation itself, but so far there hasn't been -enough demand for that feature to make it worth developing.
\ No newline at end of file diff --git a/docs/reference/plugins/validation/dns/azure.md b/docs/reference/plugins/validation/dns/azure.md deleted file mode 100644 index 6518557..0000000 --- a/docs/reference/plugins/validation/dns/azure.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar: reference ---- - -# Azure DNS -Create the record in Azure DNS. - -{% include plugin-seperate.md %} - -## Setup -This assumes you already have your DNS managed in Azure; if not, you'll need to set that up first. If you are -using the Azure DNS option for validation, you'll need to get certain info from your Azure Tenant, and create -a service principal for win-acme to use (you'll only need to create on of these - it's basically an account that has authority to create DNS records). -There are two ways to authenticate with Azure: - -#### Create Azure AD Service Principal Account -Use the [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest) -to create an [Azure service principal](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest) - -You then need to give this Service Principal access to change DNS entries. In the Azure Portal: -* Go to `DNS Zones` > `sub.example.com` > `Access Control (IAM)` -* Click `Add` -* For Role, choose `DNS Zone Contributor` -* Assign access to `Azure AD user, group, or application` -* Select your Service Principal -* Click `Save` - -#### Use a Managed Service Identity -More information [here](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) - -### Configuring the plugin -During setup of the validation the program will ask several questions. -Here is to answer them with information from the Azure Portal. - -* `DNS Subscription ID`: DNS Zones > `sub.example.com` > `Subscription ID` -* `DNS Resource Group Name`: DNS zones > `sub.example.com` > `Resource Group`) - -Only when authenticating Service Principal Account: - -* `Directory/tenant id`: Azure Active Directory > Properties > `Directory ID`. -* `Application client id`: Azure Active Directory > App registrations > [Service Principal] > `Application ID`. -* `Application client secret`: The password that was generated when you created the Service Principal Account. - -### Resources -- [How to: Use Azure PowerShell to create a service principal with a certificate](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-authenticate-service-principal-powershell) -- [DNS SDK](https://docs.microsoft.com/en-us/azure/dns/dns-sdk) - -## Unattended -#### Service Principal Account -`--validationmode dns-01 --validation azure --azuretenantid x --azureclientid x --azuresecret *** --azuresubscriptionid x --azureresourcegroupname x` -#### Managaged Resource Identity -`--validationmode dns-01 --validation azure --azureusemsi --azuresubscriptionid x --azureresourcegroupname x`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/dns/cloudflare.md b/docs/reference/plugins/validation/dns/cloudflare.md deleted file mode 100644 index 7c934d9..0000000 --- a/docs/reference/plugins/validation/dns/cloudflare.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -sidebar: reference ---- - -# Cloudflare -Create the record in Cloudflare DNS. - -{% include plugin-seperate.md %} - -## Setup -This assumes you already have your DNS managed in Cloudflare; if not, you'll need to set that up first. If you are -using the Cloudflare DNS option for validation, you'll need to obtain a Cloudflare API Token (not Key) that is allowed -to read and write the DNS records of the zone your domain belongs to. - -### Create an appropriate API Token -1. Navigate here: https://dash.cloudflare.com/profile/api-tokens -2. Click *Create Token* -3. Choose a name -4. Under *Permissions*, select "Zone", "DNS", "Edit"; Click *Add More*, select "Zone", "Zone", "Read" -5. Under *Zone Resources*, select "Include", "All zones" (or "All zones from an account" and select the relevant account). - * Note that restricting access to the single target zone does not work, as we can not get the zone's id by its domain name then. You might be able to exclude other zones specifically. If this is a show stopper for you please open an issue to discuss how to proceed. -6. Finish creating the token, store it in a safe place or, better, paste it directly into win-acme. - -## Unattended -`--validationmode dns-01 --validation cloudflare --cloudflareapitoken ***` diff --git a/docs/reference/plugins/validation/dns/dreamhost.md b/docs/reference/plugins/validation/dns/dreamhost.md deleted file mode 100644 index 22c73be..0000000 --- a/docs/reference/plugins/validation/dns/dreamhost.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -sidebar: reference ---- - -# Dreamhost -Update record for [Dreamhost](https://www.dreamhost.com/) - -{% include plugin-seperate.md %} - -## Setup -Requires an API key - -## Unattended -`--validation dreamhost --validationmode dns-01 --apikey x`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/dns/index.md b/docs/reference/plugins/validation/dns/index.md deleted file mode 100644 index 84251f5..0000000 --- a/docs/reference/plugins/validation/dns/index.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar: reference ---- - -# DNS validation -DNS validation works as follows: -- For each domain, e.g. `sub.example.com`, the ACME server provides a -challenge consisting of an `x` and `y` value. The truth is actually a little -more complicated than that, but for the sake of this explanation it will suffice. -- The client has to make sure that when the ACME server requests the TXT -records for `_acme-challenge.sub.example.com`, -there should be at least one record called `x` with content `"y"`. -- There may be more than one validation lookup for the same token, e.g. from -different locations or different protocols (IPv4/IPv6). -- Let's Encrypt validates the DNSSEC chain. -- Let's Encrypt follows CNAME records and respects delegated autority. -- Let's Encrypt does *not* disclose the source locations of these lookups, which -effectively means that the DNS records have to be public, at least for the duration of -the validation.
\ No newline at end of file diff --git a/docs/reference/plugins/validation/dns/manual.md b/docs/reference/plugins/validation/dns/manual.md deleted file mode 100644 index 2ab0dcd..0000000 --- a/docs/reference/plugins/validation/dns/manual.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -sidebar: reference ---- - -# Manual -The client will show the record that is supposed to be created on screen and it will have -to be created manually by whatever means necessary. Obviously not good for unattended operation -but it is a good way to get started as a proof of concept, before investing in further -automation. - -## Unattended -Not supported (obviously)
\ No newline at end of file diff --git a/docs/reference/plugins/validation/dns/route53.md b/docs/reference/plugins/validation/dns/route53.md deleted file mode 100644 index ba59836..0000000 --- a/docs/reference/plugins/validation/dns/route53.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -sidebar: reference ---- - -# Route 53 -Create the record in Amazon Route53 - -{% include plugin-seperate.md %} - -## Setup -This requires either a user or an IAM role with the following permissions on the zone: -`route53:GetChange`, `route53:ListHostedZones` and `route53:ChangeResourceRecordSets` - -## Unattended -- User: -`--validation route53 --validationmode dns-01 --route53accesskeyid x --route53secretaccesskey ***` -- IAM role: -`--validation route53 --validationmode dns-01 --route53iamrole x`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/dns/script.md b/docs/reference/plugins/validation/dns/script.md deleted file mode 100644 index 467fb49..0000000 --- a/docs/reference/plugins/validation/dns/script.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -sidebar: reference ---- - -# Script -Run an external script or program to create or update the validation records. - -## Create -A script to create the DNS record must be provided. The arguments passed to the -script will be `create {Identifier} {RecordName} {Token}` by default, where the -following replacements are made by win-acme: - -| Value | Replaced with | -|----------------|----------------| -| `{Identifier}` | host name that's being validated, e.g. `sub.example.com` | -| `{RecordName}` | full name of the TXT record that is being expected, e.g. `_acme-challenge.sub.example.com` | -| `{Token}` | content of the TXT record, e.g. `DGyRejmCefe7v4NfDGDKfA` | - -The order and format of arguments may be customized by providing a diffent argument string. -For example if your script needs arguments like: - -`--host _acme-challenge.example.com --token DGyRejmCefe7v4NfDGDKfA` - -...your argument string should like like this: - -`--host {RecordName} --token {Token}` - -## Delete -Optionally, another script may be provided to delete the record after validation. The arguments passed to the -script will be `delete {Identifier} {RecordName} {Token}` by default. The order and format of arguments may be -customized by providing a diffent argument string, just like for the create script. You can also choose to use -the same script for create and delete, with each their own argument string. - -## Resources -A lot of good example scripts are available from the -[POSH-ACME](https://github.com/rmbolger/Posh-ACME/tree/master/Posh-ACME/DnsPlugins) -project. - -## Unattended -- ##### Create script only -`-validationmode dns-01 --validation script --dnscreatescript c:\create.ps1 [--dnscreatescriptarguments {args}]` -- ##### Create and delete scripts seperate -`-validationmode dns-01 --validation script --dnscreatescript c:\create.ps1 --dnsdeletescript c:\delete.ps1 [--dnscreatescriptarguments {args}] [--dnsdeletescriptarguments {args}]` -- ##### Create-delete script (integrated) -`-validationmode dns-01 --validation script --dnsscript c:\create-and-delete.ps1 [--dnscreatescriptarguments {args}] [--dnsdeletescriptarguments {args}]`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/http/filesystem.md b/docs/reference/plugins/validation/http/filesystem.md deleted file mode 100644 index 4ae8996..0000000 --- a/docs/reference/plugins/validation/http/filesystem.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar: reference ---- - -# Filesystem -This plugin saves the validation challenge to a local path, which may of course also be a network path. - -{% include validation-http-common.md %} - -## Unattended -`--validation filesystem [--validationsiteid x] [--webroot c:\httpdocs\]`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/http/ftps.md b/docs/reference/plugins/validation/http/ftps.md deleted file mode 100644 index 01369a4..0000000 --- a/docs/reference/plugins/validation/http/ftps.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar: reference ---- - -# FTP(S) -This plugin uploads the validation challenge to a (secure) FTP server. - -{% include validation-http-common.md %} - -## Unattended -`--validation ftp --webroot ftps://x/ --username admin --password ******`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/http/index.md b/docs/reference/plugins/validation/http/index.md deleted file mode 100644 index 25c8164..0000000 --- a/docs/reference/plugins/validation/http/index.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar: reference ---- - -# HTTP validation -HTTP validation works as follows: -- For each domain (e.g. `sub.example.com`), the ACME server sends a -challenge consisting of an `x` and `y` value. The truth is actually a little -more complicated than that, but for the sake of this explanation it will suffice. -- The client has to make sure that when the ACME server makes a request -to `http://sub.example.com/.well-known/acme-challenge/x`, the content of the HTTP -response will be `y` with some specific headers set as well. -- The validation request is *always* made to port 80, that cannot be changed. -- The ACME server **does** follow 301/302 redirects. -- There may be more than one validation request for the same token, e.g. from -different locations or different protocols (IPv4/IPv6). -- Let's Encrypt does **not** disclose the source locations of these requests, which -effectively means that the domain has to be accessible for the public, -at least for the duration of the validation.
\ No newline at end of file diff --git a/docs/reference/plugins/validation/http/selfhosting.md b/docs/reference/plugins/validation/http/selfhosting.md deleted file mode 100644 index a1b4c31..0000000 --- a/docs/reference/plugins/validation/http/selfhosting.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -sidebar: reference ---- - -# Self-hosting -This plugin launches a temporary built-in web listener that stores the validation -response in memory. It can share port 80 with IIS and other (Microsoft) software -so this doesn't interfere with regular traffic. Not all software supports this -port sharing feature though. If you get errors telling you that the listener -cannot be started, try to (temporarely) shut down other processes using the -port, or look for another validation method. - -## Non-default port -Even though Let's Encrypt will always send validation requests to port 80, -you may internally proxy, NAT or redirect that to another port. Using the -`--validationport` switch you can tell the plugin to listen to a specific port. - -## Firewall exemption -Obviously, whichever port is used will have to be accessible from outside, meaning -your firewall(s) will have to permit access. Unfortunately due to the use of the -port sharing mechanism, it's not possible to configure the Windows Firewall with -a rule for a specific application (i.e. `wacs.exe`), so you will have to open the -port to `System`. If you feel that is too generous, you could automate enabling/ -disabling this rule by running a script before and after `wacs.exe`. Make sure to -also add that script as steps in the scheduled task. - -## Unattended -`[--validation selfhosting] [--validationport 8080]`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/http/sftp.md b/docs/reference/plugins/validation/http/sftp.md deleted file mode 100644 index 62d59cc..0000000 --- a/docs/reference/plugins/validation/http/sftp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar: reference ---- - -# SFTP -This plugin uploads the validation challenge to a SSH FTP, also known as SFTP, server. - -{% include validation-http-common.md %} - -## Unattended -`--validation sftp --webroot ftps://x/ --username admin --password ******`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/http/webdav.md b/docs/reference/plugins/validation/http/webdav.md deleted file mode 100644 index 94bfeaf..0000000 --- a/docs/reference/plugins/validation/http/webdav.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar: reference ---- - -# SFTP -This plugin pushes the validation challenge to a WebDav path. - -{% include validation-http-common.md %} - -## Unattended -`--validation webdav --webroot ftps://x/ --username admin --password ******`
\ No newline at end of file diff --git a/docs/reference/plugins/validation/index.md b/docs/reference/plugins/validation/index.md deleted file mode 100644 index bfb133d..0000000 --- a/docs/reference/plugins/validation/index.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar: reference ---- - -# Validation plugins - -A validation plugin is responsible for providing the ACME server with proof that you own the identifiers -(host names) that you want to create a certificate for. The -[ACMEv2 protocol](https://tools.ietf.org/html/draft-ietf-acme-acme-18) defines different -challenge types, three of which are supported by win-acme, namely -[HTTP-01](/win-acme/reference/plugins/validation/http/), -[DNS-01](/win-acme/reference/plugins/validation/dns/) and -[TLS-ALPN-01](/win-acme/reference/plugins/validation/tls-alpn/). - -For wildcard identifiers, only DNS-01 validation is accepted by Let's Encrypt. - -Several other challenge types are not supported for various reasons: -- `TLS-SNI-01/-02` - deprecated and removed -- `PROOFOFPOSSESSION-01` - unknown - -## Default - -By default, the [self-hosting plugin](/win-acme/reference/plugins/validation/http/selfhosting) is used.
\ No newline at end of file diff --git a/docs/reference/plugins/validation/tls-alpn/index.md b/docs/reference/plugins/validation/tls-alpn/index.md deleted file mode 100644 index d1b6aa9..0000000 --- a/docs/reference/plugins/validation/tls-alpn/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -sidebar: reference ---- - -# TLS-ALPN validation -TLS-ALPN validation works as follows: -- For each domain (e.g. `sub.example.com`), the ACME server sends a -challenge consisting of an `x` and `y` value. The truth is actually a little -more complicated than that, but for the sake of this explanation it will suffice. -- The client has to make sure that when the ACME server sets up a TLS connection -to `sub.example.com`, a specifically crafted negotiation response with a -self-signed certificate containing the `y` value as extension is presented. -- The validation request is *always* made to port 443, that cannot be changed. -- There may be more than one validation connection for the same token, e.g. -for different IP addresses (in case of multiple A/AAAA records). -- Let's Encrypt does **not** disclose the source locations of these requests, which -effectively means that the domain has to be accessible for the public, -at least for the duration of the validation.
\ No newline at end of file diff --git a/docs/reference/plugins/validation/tls-alpn/selfhosting.md b/docs/reference/plugins/validation/tls-alpn/selfhosting.md deleted file mode 100644 index 836c591..0000000 --- a/docs/reference/plugins/validation/tls-alpn/selfhosting.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar: reference ---- - -# Self-hosting -This plugin launches a temporary built-in TCP listener that stores the -validation response in memory. There for share port 80 with IIS and -other (Microsoft) software so this doesn't interfere with regular traffic. -Not all software supports this port sharing feature though. If you get errors -telling you that the listener cannot be started, please look for another -validation method. - -## Non-default port -Even though Let's Encrypt will always try to open the validation connection -on port 443, you may internally NAT that to another port. Using the -`--validationport` switch you can tell the plugin to listen to a specific port. - -## Unattended -`--validationmode tls-alpn-01 --validation selfhosting [--validationport 4330]`
\ No newline at end of file diff --git a/docs/reference/settings.md b/docs/reference/settings.md deleted file mode 100644 index 96cbb51..0000000 --- a/docs/reference/settings.md +++ /dev/null @@ -1,329 +0,0 @@ ---- -sidebar: reference ---- - -# Settings.json -Some of the applications' settings can be modified in a file called `settings.json`. -If this file is not present when the program starts it will be automatically -created on first run, copied from `settings_default.json`. This allows you to -xcopy new releases without worrying about overwriting your previously customized -settings. - -## Client - -### `ClientNames` -Default: `[ "win-acme" ]` - -The name of the client, which comes back in the scheduled task and the -`ConfigurationPath`. If more than one value is provided the first one will -be used. - -### `ConfigurationPath` -Default: `null` - -Change the location where the program stores its (temporary) files. If not specified -this resolves to `%programdata%\{ClientName}\{BaseUri}`. Values should be JSON-encoded, -e.g. `"C:\\"` (note the double backslash). - -### `LogPath` -Default: `null` - -The path where log files for the past 31 days are stored. If not -specified or invalid, this defaults to `{ConfigurationPath}\Log`. - -## UI - -### `DateFormat` -Default: `"yyyy/M/d H:mm:ss"` - -A string that is used to format the date of the pfx file friendly -name. [Documentation](https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx) -for possibilities is available from Microsoft. - -### `PageSize` -Default: `50` - -The number of items to display per page in list views. - -### `TextEncoding` -Default: `"utf8"` - -Encoding to use for the console output. A list of possible values can be -found [here](https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding?view=netcore-3.0). -For certain languages `"unicode"` might give better results displaying the characters, -but note that this reduces compatibility with other programs processing the output. - -## ACME - -### `DefaultBaseUri` -Default: `"https://acme-v02.api.letsencrypt.org/"` - -Default ACMEv2 endpoint to use when none is specified with -the command line. - -### `DefaultBaseUriTest` -Default: `"https://acme-staging-v02.api.letsencrypt.org/"` - -Default ACMEv2 endpoint to use when none is specified with -the command line and the `--test` switch is activated. - -### `DefaultBaseUriImport` -Default: `"https://acme-v01.api.letsencrypt.org/"` - -Default ACMEv1 endpoint to import renewal settings from. - -### `PostAsGet` -Default: `true` - -Use [POST-as-GET] mode as defined in -[RFC8555](https://tools.ietf.org/html/rfc8555#section-6.3), -will be required by Let's Encrypt in production from November 2020, -and in test from November 2019. - -### `RetryCount` -Default: `5` - -Maximum numbers of times to refresh validation and order status, while -waiting for the ACME server to complete its tasks. - -### `RetryInterval` -Default: `5` - -Amount of time in seconds to wait for each retry. - -## Proxy - -### `Url` -Default: `"[System]"` - -Configures a proxy server to use for communication with the ACME server and -other HTTP requests done by the program. The default setting uses the -system proxy. Passing an empty string will try to bypass the system proxy. - -### `Username` -Default: `null` - -Username used to access the proxy server. - -### `Password` -Default: `null` - -Password used to access the proxy server. - -## Cache - -### `Path` -Default: `null` - -The path where certificates and request files are cached. If not specified or invalid, -this defaults to `{ConfigurationPath}\Certificates`. If you are using -[Central SSL](//win-acme/reference/plugins/store/centralssl), this can **not** -be set to the same path. Values should be JSON-encoded, e.g. `"C:\\"` -(note the double backslash). - -### `ReuseDays` -Default: `1` - -When renewing or re-creating a previously requested certificate that -has the exact same set of domain names, the program will used a cached -version for this many days, to prevent users from running into -[rate limits](https://letsencrypt.org/docs/rate-limits/) while experimenting. -Set this to a high value if you regularly re-request the same certificates, -e.g. for a Continuous Deployment scenario. - -### `DeleteStaleFiles` -Default: `false` - -Automatically delete files older than 120 days from the `CertificatePath` -folder. Running with default settings, these should only be long-expired -certificates, generated for abandoned renewals. However we do advise caution. - -## Scheduled task - -### `RenewalDays` -Default: `55` - -The number of days to renew a certificate after. Let's Encrypt certificates are -currently for a max of 90 days so it is advised to not increase the days much. -If you increase the days, please note that you will have less time to fix any -issues if the certificate doesn't renew correctly. - -### `StartBoundary` -Default: `"09:00:00"` (9:00 am) - -Configures start time for the scheduled task. - -### `ExecutionTimeLimit` -Default: `"02:00:00"` (2 hours) - -Configures time after which the scheduled task will be -terminated if it hangs for whatever reason. - -### `RandomDelay` -Default: `"00:00:00"` - -Configures random time to wait for starting the scheduled task. - -## Notifications - -### `SmtpServer` -Default: `null` - -SMTP server to use for sending email notifications. -Required to receive renewal failure notifications. - -### `SmtpPort` -Default: `25` - -SMTP server port number. - -### `SmtpUser` -Default: `null` - -User name for the SMTP server, in case of authenticated SMTP. - -### `SmtpPassword` -Default: `null` - -Password for the SMTP server, in case of authenticated SMTP. - -### `SmtpSecure` -Default: `false` - -Change to `true` to enable SMTPS. - -### `SmtpSenderName` -Default: `null` - -Display name to use as the sender of notification emails. -Defaults to the `ClientNames[0]` setting when empty. - -### `SenderAddress` -Default: `null` - -Email address to use as the sender of notification emails. -Required to receive renewal failure notifications. - -### `ReceiverAddresses` -Default: `[]` - -Email address to receive notification emails. Required to -receive renewal failure notifications. The correct format -for the receiver is `["example@example.com"]` for a single -address and `["example1@example.com", "example2@example.com"]` -for multiple addresses. - -### `EmailOnSuccess` -Default: `false` - -Send an email notification when a certificate has been successfully renewed, -as opposed to the default behavior that only send failure notifications. -Only works if at least `SmtpServer`, `SmtpSenderAddress`and `SmtpReceiverAddress` -have been configured. - -## Security - -### `RSAKeyBits` -Default: `3072` - -The key size to sign the certificate with. Minimum is 2048. - -### `ECCurve` -Default: `"secp384r1"` - -The curve to use for EC certificates. - -### `PrivateKeyExportable` -Default: `false` - -If set to `true`, it will be possible to export the generated certificates from -the certificate store, for example to move them to another server. - -### `EncryptConfig` -Default: `true` - -Uses Microsoft Data Protection API to encrypt sensitive parts of -the configuration, e.g. passwords. This may be disabled to share -the configuration across a cluster of machines. - -## Script - -### `Timeout` -Default: `600` - -Time in seconds to allow installation and DNS scripts to run before -terminating them forcefully. - -## Validation - -### `CleanupFolders` -Default: `true` - -If set to `true`, it will cleanup the folder structure and files it creates -under the site for authorization. - -### `PreValidateDns` -Default: `true` - -If set to `true`, it will wait until it can verify that the validation record -has been created and is available before beginning DNS validation. - -### `PreValidateDnsRetryCount` -Default: `5` - -Maximum numbers of times to retry DNS pre-validation, while -waiting for the name servers to start providing the expected answer. - -### `PreValidateDnsRetryInterval` -Default: `30` - -Amount of time in seconds to wait between each retry. - -### `DnsServers` -Default: `[ "8.8.8.8", "1.1.1.1", "8.8.4.4" ]` - -A list of servers to query during DNS prevalidation checks to verify whether -or not the validation record has been properly created and is visible for the -world. These servers will be used to located the actual authoritative name -servers for the domain. You can use the string `[System]` to have the -program query your servers default, but note that this can lead to -prevalidation failures when your Active Directory is hosting a private -version of the DNS zone for internal use. - -## Store - -### `DefaultCertificateStore` -Default: `null` - -The certificate store to save the certificates in. If left empty, certificates will -be installed either in the `WebHosting` store, or if that is not available, -the `My` store (better known as `Personal`). - -### `DefaultCentralSslStore` -Default: `null` - -When using `--store centralssl` this path is used by default, saving you the -effort from providing it manually. Filling this out makes the `--centralsslstore` -parameter unnecessary in most cases. Renewals created with the default path will -automatically change to any future default value, meaning this is also a good -practice for maintainability. Values should be JSON-encoded, e.g. `"C:\\"` -(note the double backslash). - -### `DefaultCentralSslPfxPassword` -Default: `null` - -When using `--store centralssl` this password is used by default for the pfx -files, saving you the effort from providing it manually. Filling this out makes -the `--pfxpassword` parameter unnecessary in most cases. Renewals created with -the default password will automatically change to any future default value, -meaning this is also a good practice for maintainability. - -### `DefaultPemFilesPath` -Default: `null` - -When using `--store pemfiles` this path is used by default, saving you the effort -from providing it manually. Filling this out makes the `--pemfilespath` parameter -unnecessary in most cases. Renewals created with the default path will automatically -change to any future default value, meaning this is also a good practice for -maintainability. Values should be JSON-encoded, e.g. `"C:\\"` -(note the double backslash).
\ No newline at end of file diff --git a/docs/support/index.md b/docs/support/index.md deleted file mode 100644 index d4fdb64..0000000 --- a/docs/support/index.md +++ /dev/null @@ -1,17 +0,0 @@ -# Community support -If you run into trouble please open an issue [here](https://github.com/PKISharp/win-acme/issues). -Please check to see if your issue is covered in the [manual](/win-acme/manual/) before you create a -new issue. Describe the exact steps you took and try to reproduce it while running with the `--verbose` -command line option set. Post your command line and the output from the console or log file to help -us diagnose the problem. - -# Professional support / sponsorship -Is your business relying on this program to secure customer websites and perhaps even critical -infrastructure? Then maybe it would be good for your peace of mind then to sponsor one of its -core developers, to gain guaranteed future support and good karma at the same time. I offer my -help quickly, discreetly and professionally via [Patreon](https://www.patreon.com/woutertinus). - -# Donations -Do you like the program and want to buy me a beer and discuss the future of the program in -private? My [Patreon](https://www.patreon.com/woutertinus) also has some affordable -"Thank you" tiers.
\ No newline at end of file diff --git a/src/main.lib/Clients/Acme/AcmeClient.cs b/src/main.lib/Clients/Acme/AcmeClient.cs index afe276f..f6ca381 100644 --- a/src/main.lib/Clients/Acme/AcmeClient.cs +++ b/src/main.lib/Clients/Acme/AcmeClient.cs @@ -83,7 +83,6 @@ namespace PKISharp.WACS.Clients.Acme {
signer = accountSigner.JwsTool();
}
-
var httpClient = _proxyService.GetHttpClient();
httpClient.BaseAddress = _settings.BaseUri;
var client = PrepareClient(httpClient, signer);
@@ -157,7 +156,7 @@ namespace PKISharp.WACS.Clients.Acme }
if (_client == null)
{
- throw new InvalidOperationException();
+ throw new InvalidOperationException("Failed to initialize AcmeProtocolClient");
}
return _client;
}
@@ -294,7 +293,7 @@ namespace PKISharp.WACS.Clients.Acme _log.Verbose("Writing terms of service to {path}", tosPath);
await File.WriteAllBytesAsync(tosPath, content);
_input.Show($"Terms of service", tosPath);
- if (_arguments.GetArguments<AccountArguments>().AcceptTos)
+ if (_arguments.GetArguments<AccountArguments>()?.AcceptTos ?? false)
{
return true;
}
@@ -655,4 +654,4 @@ namespace PKISharp.WACS.Clients.Acme Dispose(true);// TODO: uncomment the following line if the finalizer is overridden above.// GC.SuppressFinalize(this);
#endregion
}
-}
\ No newline at end of file +}
diff --git a/src/main.lib/Clients/Acme/ExternalAccountBinding.cs b/src/main.lib/Clients/Acme/ExternalAccountBinding.cs index 999d4e9..8049f64 100644 --- a/src/main.lib/Clients/Acme/ExternalAccountBinding.cs +++ b/src/main.lib/Clients/Acme/ExternalAccountBinding.cs @@ -55,7 +55,7 @@ namespace PKISharp.WACS.Clients.Acme return hmac.ComputeHash(input);
}
}
- throw new InvalidOperationException();
+ throw new InvalidOperationException($"Unsupported algorithm {Algorithm}");
}
}
}
diff --git a/src/main.lib/Clients/Acme/OrderManager.cs b/src/main.lib/Clients/Acme/OrderManager.cs index 51a30c3..c0ddaac 100644 --- a/src/main.lib/Clients/Acme/OrderManager.cs +++ b/src/main.lib/Clients/Acme/OrderManager.cs @@ -95,18 +95,30 @@ namespace PKISharp.WACS.Clients.Acme private async Task<OrderDetails?> CreateOrder(IEnumerable<string> identifiers, string cacheKey)
{
_log.Verbose("Creating order for hosts: {identifiers}", identifiers);
- var order = await _client.CreateOrder(identifiers);
- if (order.Payload.Error != null)
+ try
{
- _log.Error("Failed to create order {url}: {detail}", order.OrderUrl, order.Payload.Error.Detail);
- return null;
+ var order = await _client.CreateOrder(identifiers);
+ if (order.Payload.Error != null)
+ {
+ _log.Error("Failed to create order {url}: {detail}", order.OrderUrl, order.Payload.Error.Detail);
+ return null;
+ }
+ else
+ {
+ _log.Verbose("Order {url} created", order.OrderUrl);
+ SaveOrder(order, cacheKey);
+ }
+ return order;
+ }
+ catch (AcmeProtocolException ex)
+ {
+ _log.Error($"Failed to create order: {ex.ProblemDetail ?? ex.Message}");
}
- else
+ catch (Exception ex)
{
- _log.Verbose("Order {url} created", order.OrderUrl);
- SaveOrder(order, cacheKey);
+ _log.Error(ex, $"Failed to create order");
}
- return order;
+ return null;
}
/// <summary>
diff --git a/src/main.lib/Clients/EmailClient.cs b/src/main.lib/Clients/EmailClient.cs index 0f7f0a0..bbec75e 100644 --- a/src/main.lib/Clients/EmailClient.cs +++ b/src/main.lib/Clients/EmailClient.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; -using System.Reflection; using System.Threading.Tasks; namespace PKISharp.WACS.Clients @@ -32,7 +31,7 @@ namespace PKISharp.WACS.Clients private readonly string _version; private readonly IEnumerable<string> _receiverAddresses; - public EmailClient(ILogService log, ISettingsService settings) + public EmailClient(ILogService log, ISettingsService settings, VersionService version) { _log = log; _settings = settings; @@ -47,7 +46,7 @@ namespace PKISharp.WACS.Clients if (string.IsNullOrEmpty(_computerName)) { _computerName = Environment.MachineName; } - _version = Assembly.GetEntryAssembly().GetName().Version.ToString(); + _version = version.SoftwareVersion.ToString(); if (string.IsNullOrWhiteSpace(_senderName)) { diff --git a/src/main.lib/Plugins/TargetPlugins/IIS/IISOptionsFactory.cs b/src/main.lib/Plugins/TargetPlugins/IIS/IISOptionsFactory.cs index 206eb8f..8eebb99 100644 --- a/src/main.lib/Plugins/TargetPlugins/IIS/IISOptionsFactory.cs +++ b/src/main.lib/Plugins/TargetPlugins/IIS/IISOptionsFactory.cs @@ -585,7 +585,7 @@ namespace PKISharp.WACS.Plugins.TargetPlugins var identifiers = input.ParseCsv(); if (identifiers == null) { - throw new InvalidOperationException(); + throw new InvalidOperationException("No identifiers found"); } var ret = new List<long>(); diff --git a/src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs b/src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs index 222a7d2..ed747e1 100644 --- a/src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs +++ b/src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs @@ -92,10 +92,14 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns var zoneName = _domainParseService.GetRegisterableDomain(identifier); var nodeName = "@"; - if (recordName != zoneName) + if (recordName.Length > zoneName.Length) { // Offset by one to prevent trailing dot - nodeName = recordName.Substring(0, recordName.Length - zoneName.Length - 1); + var idx = recordName.Length - zoneName.Length - 1; + if (idx != 0) + { + nodeName = recordName.Substring(0, idx); + } } ret = ret.Replace("{ZoneName}", zoneName); ret = ret.Replace("{NodeName}", nodeName); diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs b/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs index c7e4c97..e4581b9 100644 --- a/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs +++ b/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs @@ -46,7 +46,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Http protected override Task<bool> IsEmpty(string path)
{
var x = new DirectoryInfo(path);
- return Task.FromResult(x.Exists && x.EnumerateFileSystemInfos().Any());
+ return Task.FromResult(x.Exists && !x.EnumerateFileSystemInfos().Any());
}
protected override async Task WriteFile(string path, string content)
diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystemOptionsFactory.cs b/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystemOptionsFactory.cs index 9a4e748..b32127c 100644 --- a/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystemOptionsFactory.cs +++ b/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystemOptionsFactory.cs @@ -29,15 +29,16 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Http { var args = _arguments.GetArguments<FileSystemArguments>(); var ret = new FileSystemOptions(BaseDefault(target)); - if (target.IIS && _iisClient.HasWebSites) + if (string.IsNullOrEmpty(ret.Path)) { - - if (args?.ValidationSiteId != null) + if (target.IIS && _iisClient.HasWebSites) { - // Throws exception when not found - var site = _iisClient.GetWebSite(args.ValidationSiteId.Value); - ret.Path = site.Path; - ret.SiteId = args.ValidationSiteId.Value; + if (args?.ValidationSiteId != null) + { + // Throws exception when not found + _iisClient.GetWebSite(args.ValidationSiteId.Value); + ret.SiteId = args.ValidationSiteId.Value; + } } } return ret; diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs b/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs index a45e9e2..11a5c45 100644 --- a/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs +++ b/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs @@ -160,7 +160,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins {
if (_path == null)
{
- throw new InvalidOperationException();
+ throw new InvalidOperationException("No path specified for HttpValidation");
}
var path = CombinePath(_path, challenge.HttpResourcePath);
WriteFile(path, challenge.HttpResourceValue);
@@ -180,7 +180,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins {
if (_path == null)
{
- throw new InvalidOperationException();
+ throw new InvalidOperationException("No path specified for HttpValidation");
}
if (_options.CopyWebConfig == true)
{
diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs b/src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs index 3681c8d..bb3d84a 100644 --- a/src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs +++ b/src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs @@ -34,7 +34,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Http { if (_listener == null) { - throw new InvalidOperationException(); + throw new InvalidOperationException("Listener not present"); } return _listener; } diff --git a/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs b/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs index f7cea99..b55906e 100644 --- a/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs +++ b/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs @@ -34,7 +34,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls { if (_listener == null) { - throw new InvalidOperationException(); + throw new InvalidOperationException("Listener not present"); } return _listener; } diff --git a/src/main.lib/RenewalManager.cs b/src/main.lib/RenewalManager.cs index e563d78..c435cfb 100644 --- a/src/main.lib/RenewalManager.cs +++ b/src/main.lib/RenewalManager.cs @@ -164,7 +164,7 @@ namespace PKISharp.WACS if (_args.Force) { runLevel |= RunLevel.IgnoreCache; - } + }
await ProcessRenewal(renewal, runLevel); } }, @@ -467,7 +467,12 @@ namespace PKISharp.WACS { try { - await ProcessRenewal(renewal, runLevel); + var success = await ProcessRenewal(renewal, runLevel);
+ if (!success)
+ {
+ // Make sure the ExitCode is set
+ _exceptionHandler.HandleException();
+ } } catch (Exception ex) { @@ -482,7 +487,7 @@ namespace PKISharp.WACS /// Process a single renewal /// </summary> /// <param name="renewal"></param> - internal async Task ProcessRenewal(Renewal renewal, RunLevel runLevel) + internal async Task<bool> ProcessRenewal(Renewal renewal, RunLevel runLevel) { var notification = _container.Resolve<NotificationService>(); try @@ -493,7 +498,8 @@ namespace PKISharp.WACS _renewalStore.Save(renewal, result); if (result.Success) { - await notification.NotifySuccess(renewal, _log.Lines); + await notification.NotifySuccess(renewal, _log.Lines);
+ return true; } else { @@ -505,7 +511,8 @@ namespace PKISharp.WACS { _exceptionHandler.HandleException(ex); await notification.NotifyFailure(runLevel, renewal, new List<string> { ex.Message }, _log.Lines); - } + }
+ return false; } /// <summary> diff --git a/src/main.lib/RenewalValidator.cs b/src/main.lib/RenewalValidator.cs index 9fee240..3a1b496 100644 --- a/src/main.lib/RenewalValidator.cs +++ b/src/main.lib/RenewalValidator.cs @@ -277,7 +277,7 @@ namespace PKISharp.WACS { if (context.ValidationPlugin == null) { - throw new InvalidOperationException(); + throw new InvalidOperationException("No validation plugin configured"); } var client = context.Scope.Resolve<AcmeClient>(); try @@ -372,7 +372,7 @@ namespace PKISharp.WACS { if (validationContext.Challenge == null) { - throw new InvalidOperationException(); + throw new InvalidOperationException("No challenge found"); } try { @@ -388,7 +388,7 @@ namespace PKISharp.WACS _log.Error("[{identifier}] {Error}", validationContext.Identifier, updatedChallenge.Error.ToString());
} - validationContext.AddErrorMessage("Validation failed", validationContext.Success == false); + validationContext.AddErrorMessage("Validation failed", validationContext.Success != true); return; } else @@ -402,7 +402,7 @@ namespace PKISharp.WACS { _log.Error("[{identifier}] Error submitting challenge answer", validationContext.Identifier); var message = _exceptionHandler.HandleException(ex); - validationContext.AddErrorMessage(message, validationContext.Success == false); + validationContext.AddErrorMessage(message, validationContext.Success != true); } } diff --git a/src/main.lib/Services/CertificateService.cs b/src/main.lib/Services/CertificateService.cs index ad2f0bf..2852548 100644 --- a/src/main.lib/Services/CertificateService.cs +++ b/src/main.lib/Services/CertificateService.cs @@ -235,7 +235,7 @@ namespace PKISharp.WACS.Services {
if (order.Details == null)
{
- throw new InvalidOperationException();
+ throw new InvalidOperationException("No order details found");
}
// What are we going to get?
diff --git a/src/main.lib/Services/ExceptionHandler.cs b/src/main.lib/Services/ExceptionHandler.cs index ca54ee9..0ab6cb7 100644 --- a/src/main.lib/Services/ExceptionHandler.cs +++ b/src/main.lib/Services/ExceptionHandler.cs @@ -74,8 +74,8 @@ namespace PKISharp.WACS.Services else if (!string.IsNullOrEmpty(message)) { _log.Error(message); - ExitCode = -1; } + ExitCode = -1; return outMessage; } diff --git a/src/main.lib/Services/ProxyService.cs b/src/main.lib/Services/ProxyService.cs index 17e45fd..6294835 100644 --- a/src/main.lib/Services/ProxyService.cs +++ b/src/main.lib/Services/ProxyService.cs @@ -12,12 +12,14 @@ namespace PKISharp.WACS.Services private readonly ILogService _log;
private IWebProxy? _proxy;
private readonly ISettingsService _settings;
+ private readonly VersionService _version;
public SslProtocols SslProtocols { get; set; } = SslProtocols.None;
- public ProxyService(ILogService log, ISettingsService settings)
+ public ProxyService(ILogService log, ISettingsService settings, VersionService version)
{
_log = log;
_settings = settings;
+ _version = version;
}
/// <summary>
@@ -44,7 +46,9 @@ namespace PKISharp.WACS.Services {
httpClientHandler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
}
- return new HttpClient(httpClientHandler);
+ var httpClient = new HttpClient(httpClientHandler);
+ httpClient.DefaultRequestHeaders.Add("User-Agent", $"win-acme/{_version.SoftwareVersion} (+https://github.com/win-acme/win-acme)");
+ return httpClient;
}
private class LoggingHttpClientHandler : HttpClientHandler
diff --git a/src/main.lib/Services/SettingsService.cs b/src/main.lib/Services/SettingsService.cs index e930c96..dec26aa 100644 --- a/src/main.lib/Services/SettingsService.cs +++ b/src/main.lib/Services/SettingsService.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using PKISharp.WACS.Extensions; -using PKISharp.WACS.Plugins.StorePlugins; using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/main.lib/Services/VersionService.cs b/src/main.lib/Services/VersionService.cs new file mode 100644 index 0000000..3383d12 --- /dev/null +++ b/src/main.lib/Services/VersionService.cs @@ -0,0 +1,31 @@ +using System; +using System.Reflection; + +namespace PKISharp.WACS.Services +{ + public class VersionService + { + public string Bitness => Environment.Is64BitProcess ? "64-bit" : "32-bit"; + + public string BuildType + { + get + { + var build = ""; +#if DEBUG + build += "DEBUG"; +#else + build += "RELEASE"; +#endif +#if PLUGGABLE + build += ", PLUGGABLE"; +#else + build += ", TRIMMED"; +#endif + return build; + } + } + + public Version SoftwareVersion => Assembly.GetEntryAssembly().GetName().Version; + } +} diff --git a/src/main.lib/Wacs.cs b/src/main.lib/Wacs.cs index be8faf9..36d3773 100644 --- a/src/main.lib/Wacs.cs +++ b/src/main.lib/Wacs.cs @@ -10,7 +10,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; using System.Threading.Tasks; namespace PKISharp.WACS.Host @@ -30,18 +29,27 @@ namespace PKISharp.WACS.Host private readonly ExceptionHandler _exceptionHandler; private readonly IUserRoleService _userRoleService; private readonly TaskSchedulerService _taskScheduler; + private readonly VersionService _versionService; - public Wacs(ILifetimeScope container) + public Wacs( + IContainer container, + IAutofacBuilder scopeBuilder, + ExceptionHandler exceptionHandler, + ILogService logService, + ISettingsService settingsService, + IUserRoleService userRoleService, + TaskSchedulerService taskSchedulerService, + VersionService versionService) { // Basic services _container = container; - _scopeBuilder = container.Resolve<IAutofacBuilder>(); - _exceptionHandler = container.Resolve<ExceptionHandler>(); - _log = _container.Resolve<ILogService>(); - _settings = _container.Resolve<ISettingsService>(); - _userRoleService = _container.Resolve<IUserRoleService>(); - _settings = _container.Resolve<ISettingsService>(); - _taskScheduler = _container.Resolve<TaskSchedulerService>(); + _scopeBuilder = scopeBuilder; + _exceptionHandler = exceptionHandler; + _log = logService; + _settings = settingsService; + _userRoleService = userRoleService; + _taskScheduler = taskSchedulerService; + _versionService = versionService; try { @@ -171,23 +179,11 @@ namespace PKISharp.WACS.Host /// </summary> private async Task ShowBanner() { - var build = ""; -#if DEBUG - build += "DEBUG"; -#else - build += "RELEASE"; -#endif -#if PLUGGABLE - build += ", PLUGGABLE"; -#else - build += ", TRIMMED"; -#endif - var version = Assembly.GetEntryAssembly().GetName().Version; var iis = _container.Resolve<IIISClient>().Version; Console.WriteLine(); _log.Information(LogType.Screen, "A simple Windows ACMEv2 client (WACS)"); - _log.Information(LogType.Screen, "Software version {version} ({build})", version, build); - _log.Information(LogType.Disk | LogType.Event, "Software version {version} ({build}) started", version, build); + _log.Information(LogType.Screen, "Software version {version} ({build}, {bitness})", _versionService.SoftwareVersion, _versionService.BuildType, _versionService.Bitness); + _log.Information(LogType.Disk | LogType.Event, "Software version {version} ({build}, {bitness}) started", _versionService.SoftwareVersion, _versionService.BuildType, _versionService.Bitness); if (_args != null) { _log.Information("ACME server {ACME}", _settings.BaseUri); @@ -378,7 +374,7 @@ namespace PKISharp.WACS.Host var acmeAccount = await acmeClient.GetAccount(); if (acmeAccount == null) { - throw new InvalidOperationException(); + throw new InvalidOperationException("Unable to initialize acmeAccount"); } _input.CreateSpace(); _input.Show("Account ID", acmeAccount.Payload.Id ?? "-"); diff --git a/src/main.test/Mock/MockContainer.cs b/src/main.test/Mock/MockContainer.cs index 76560ae..8c2076d 100644 --- a/src/main.test/Mock/MockContainer.cs +++ b/src/main.test/Mock/MockContainer.cs @@ -37,6 +37,7 @@ namespace PKISharp.WACS.UnitTests.Mock _ = builder.RegisterType<mock.MockRenewalStore>().As<real.IRenewalStore>().SingleInstance(); _ = builder.RegisterType<mock.MockSettingsService>().As<real.ISettingsService>().SingleInstance(); ; _ = builder.RegisterType<mock.UserRoleService>().As<real.IUserRoleService>().SingleInstance(); + _ = builder.RegisterType<real.VersionService>().SingleInstance(); _ = builder.RegisterType<real.ProxyService>().SingleInstance(); _ = builder.RegisterType<real.PasswordGenerator>().SingleInstance(); diff --git a/src/main.test/Tests/DnsValidationTests/When_resolving_name_servers.cs b/src/main.test/Tests/DnsValidationTests/When_resolving_name_servers.cs index b8d6427..3599ba3 100644 --- a/src/main.test/Tests/DnsValidationTests/When_resolving_name_servers.cs +++ b/src/main.test/Tests/DnsValidationTests/When_resolving_name_servers.cs @@ -16,7 +16,7 @@ namespace PKISharp.WACS.UnitTests.Tests.DnsValidationTests { var log = new LogService(true); var settings = new MockSettingsService(); - var proxy = new ProxyService(log, settings); + var proxy = new ProxyService(log, settings, new VersionService()); var domainParser = new DomainParseService(log, proxy, settings); _dnsClient = new LookupClientProvider(domainParser, log, settings); } diff --git a/src/main.test/Tests/InstallationPluginTests/MultipleInstallerTests.cs b/src/main.test/Tests/InstallationPluginTests/MultipleInstallerTests.cs index 8c8aa79..b05e95c 100644 --- a/src/main.test/Tests/InstallationPluginTests/MultipleInstallerTests.cs +++ b/src/main.test/Tests/InstallationPluginTests/MultipleInstallerTests.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using PKISharp.WACS.Clients.DNS; +using PKISharp.WACS.UnitTests.Mock; namespace PKISharp.WACS.UnitTests.Tests.InstallationPluginTests { @@ -40,13 +41,14 @@ namespace PKISharp.WACS.UnitTests.Tests.InstallationPluginTests var commandLine = "--installation iis"; var types = new List<Type>() { typeof(CertificateStore) }; var chosen = new List<IInstallationPluginOptionsFactory>(); - - + + var builder = new ContainerBuilder(); _ = builder.RegisterType<LookupClientProvider>(); _ = builder.RegisterType<ProxyService>(); _ = builder.RegisterType<DomainParseService>(); _ = builder.RegisterType<IISHelper>(); + _ = builder.RegisterType<VersionService>(); _ = builder.RegisterInstance(plugins). As<IPluginService>(). SingleInstance(); diff --git a/src/main/Program.cs b/src/main/Program.cs index 0c1a2ba..09892e3 100644 --- a/src/main/Program.cs +++ b/src/main/Program.cs @@ -31,7 +31,7 @@ namespace PKISharp.WACS.Host if (Environment.UserInteractive)
{
Console.WriteLine(" Press <Enter> to close");
- Console.ReadLine();
+ _ = Console.ReadLine();
} return; } @@ -42,9 +42,9 @@ namespace PKISharp.WACS.Host var original = Console.OutputEncoding; try - { - // Load instance of the main class and start the program - var wacs = new Wacs(container); + {
+ // Load instance of the main class and start the program
+ var wacs = container.Resolve<Wacs>(new TypedParameter(typeof(IContainer), container)); Environment.ExitCode = await wacs.Start(); } catch (Exception ex) @@ -107,6 +107,7 @@ namespace PKISharp.WACS.Host _ = builder.RegisterType<ProxyService>().SingleInstance(); _ = builder.RegisterType<PasswordGenerator>().SingleInstance(); _ = builder.RegisterType<RenewalStoreDisk>().As<IRenewalStore>().SingleInstance(); + _ = builder.RegisterType<VersionService>().SingleInstance(); pluginService.Configure(builder); @@ -132,6 +133,8 @@ namespace PKISharp.WACS.Host _ = builder.RegisterType<RenewalCreator>().SingleInstance(); _ = builder.Register(c => c.Resolve<IArgumentsService>().MainArguments).SingleInstance(); + _ = builder.RegisterType<Wacs>(); + return builder.Build(); } } |