Giter Club home page Giter Club logo

Comments (15)

rmbolger avatar rmbolger commented on August 14, 2024

Hey @fthobe, thanks for the suggestion. However, this functionality already exists in the Set-RDSHCertificate function except under the hood it uses the native Get-CimInstance/Set-CimInstance functions instead of shell'ing out to the wmic utility (which is now deprecated)

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

I lower my head in a humble manor and request a change in documentation:
Change "Remote Desktop Session Host" to "Remote Desktop Session Host / Remote Desktop Listener" :D

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

Stupid question, you just answered
Just out of curiosity, what would be the appropriate current way to request thumbprints then?

from posh-acme.deploy.

rmbolger avatar rmbolger commented on August 14, 2024

It's not your fault you didn't realize. Microsoft has been confusing people with the naming in this tech since they renamed from Terminal Services and then split out the functionality between the old remote administration mode which can be used out of the box with no extra roles or licensing installed and the full fledged Remote Desktop Services role which has a whole wizard based cert management workflow if I recall correctly.

You can tell they're even internally confused because in that same documentation site, there's another entirely different page explaining how to configure the same cert and they don't mention "Remote Desktop Listener" even once.
https://learn.microsoft.com/en-us/troubleshoot/windows-server/remote/custom-server-authentication-certificate-for-tls

There's also no "Listener" mentioned on the page describing the services associated with the Remote Desktop Services role here. https://learn.microsoft.com/en-us/windows-server/remote/remote-desktop-services/rds-roles

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

@rmbolger so how does renewal behave? I just install posh-acme and posh-acme.deploy and follow the procedure described in https://www.dvolve.net/blog/2019/12/using-lets-encrypt-for-active-directory-domain-controller-certificates/ with my custom flavor of FQDN identification and add RDP session host and all should work renewal included given that I schedule the task?

from posh-acme.deploy.

rmbolger avatar rmbolger commented on August 14, 2024

More or less, yes.

You would generally run Set-RDSHCertificate with either the output of Submit-Renewal or an explicit call to Get-PACertificate. So if we modify the renewal script example, I'd probably go with something like this:

if ($newCert = Submit-Renewal -Verbose) {
    $newCert | Set-RDSHCertificate
    $oldCert | Remove-Item
    Restart-Service ADWS
}

So instead of just calling Submit-Renewal and ignoring the cert object output, we save it to a variable and then use that with the Set-RDSHCertificate function before deleting the old cert.

Alternatively, this is effectively the same code.

if (Submit-Renewal -Verbose) {
    Get-PACertificate | Set-RDSHCertificate
    $oldCert | Remove-Item
    Restart-Service ADWS
}

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

So technically the first script creates the cert, stores into personal and sets for RDP and the second renews it, correct?

# Cloud Flare requires a simple API token, securing the string to keep it safe
$token = ConvertTo-SecureString '[INSERT API KEY]' -AsPlainText -Force
$pArgs = @{CFToken=$token}

# The default certificate password is "poshacme", but we prefer some extra security. At this point you could also just use the CF token. 
$CertPass = '$token'

# To get the correct hostname independent of features installed, use System.Net.Dns (does not work on linux).
$certName = @([System.Net.Dns]::GetHostEntry([string]"localhost").HostName)

# This notification email is contacted if the certificate is close to expiration date.
$notifyEmail = '[[email protected]]'

# Constructs all Cert Params for a successful request.
$certParams = @{
    Domain = $certName
    PfxPass = $CertPass
    DnsPlugin = 'Cloudflare'
    PluginArgs = $pArgs
    AcceptTOS = $true
    Install = $true
    Contact = $notifyEmail  # optional
    Verbose = $true         # optional
}

New-PACertificate @certParams 

# Sets the certificate also for RDP Host Listener
Set-PAOrder $certName
Get-PACertificate $certName | Set-RDSHCertificate -Verbose
Start-Transcript $env:LOCALAPPDATA\cert-renewal.log -Append
$hostname = @([System.Net.Dns]::GetHostEntry([string]"localhost").HostName)
$oldCert = Get-ChildItem Cert:\LocalMachine\My |
    Where-Object { $_.Subject -eq "CN=$hostname" } |
    Sort-Object -Descending NotAfter |
    Select-Object -First 1
if (Submit-Renewal -Verbose) {
    Get-PACertificate | Set-RDSHCertificate
    $oldCert | Remove-Item
    Restart-Service ADWS
}
Stop-Transcript

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

When adding additional services do I just invoke the whole line substituting "Set-RDSHCertificate" or just add another "| Set-Someotherservice" at the end of the line?

    Get-PACertificate | Set-RDSHCertificate

from posh-acme.deploy.

rmbolger avatar rmbolger commented on August 14, 2024

Those functions don't have a passthru option that would send the original object back out to the pipeline (though that's an interesting idea). So you'd need another complete line.

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

Those functions don't have a passthru option that would send the original object back out to the pipeline (though that's an interesting idea). So you'd need another complete line.

So the script above looks fine but I need multiple get PA to add services, correct?

from posh-acme.deploy.

rmbolger avatar rmbolger commented on August 14, 2024

Yes. Or you could use the model where you assign the output of Submit-Renewal to a variable and use that variable instead of Get-PACertificate.

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

Yes. Or you could use the model where you assign the output of Submit-Renewal to a variable and use that variable instead of Get-PACertificate.

You make it sound so easily while I have no idea whatsoever how that would look like 😅

from posh-acme.deploy.

rmbolger avatar rmbolger commented on August 14, 2024

In my comment before you posted your script, it's the first example code block.

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

Hey @rmbolger Sorry for always dragging issues for months but I switched company and the amount of work I found was staggering.

I think I nailed it now, but when I manually run the task from the schedule to check the log, nothing happens.
Script A contains the minified ps script while script b contains the written out version.

Some additional questions from somebody who's not very experienced in PS:

  1. In the minified version you changed Where-Object to ?, does that always work? what are conditions?
  2. Idem with "Sort-Object -Descending" > "sort -d", "Remove-Item" > "ri"
  3. Are you using any handy tool to minify?

Thanks, you helped me a lot and I really appreciate it. I am going to publish a couple of scripts I wrote to publish LE certs across various systems over the next weeks and you were a big help on all of this.

Script A: Initial Request and Scheduling of renewal

 # run in .\PsExec64.exe -i -h -s powershell.exe
# Install Posh-Acme and Posh-Acme Deploy with all dependencies
Install-Module -Name Posh-ACME -Scope AllUsers -Force -SkipPublisherCheck
Install-Module -Name Posh-ACME.Deploy -Scope AllUsers -Force -SkipPublisherCheck

# Cloud Flare requires a simple API token, securing the string to keep it safe
$token = ConvertTo-SecureString 'token' -AsPlainText -Force
$pArgs = @{CFToken=$token}

# The default certificate password is "poshacme", but we prefer some extra security. At this point you could also just use the CF token. 
$CertPass = '$token'

# To get the correct hostname independent of features installed, use System.Net.Dns (does not work on linux).
$certName = ([System.Net.Dns]::GetHostEntry([string]"localhost").HostName)

# This notification email is contacted if the certificate is close to expiration date.
$notifyEmail = '[email protected]'

# Constructs all Cert Params for a successful request.
$certParams = @{
    Domain = $certName
    PfxPass = $CertPass
    DnsPlugin = 'Cloudflare'
    PluginArgs = $pArgs
    AcceptTOS = $true
    Install = $true
    Contact = $notifyEmail  # optional
    Verbose = $true         # optional
}

New-PACertificate @certParams 

# Sets the certificate also for RDP Host Listener
Set-PAOrder $certName
Get-PACertificate $certName | Set-RDSHCertificate -Verbose

# Sets the scheduler to check and renew certificate when due
$taskname = "Renew SSL Server Certificate"
$taskdesc = "Renews the Let's Encrypt certificate installed on this server."
$actionArg = '-C "Start-Transcript $env:LOCALAPPDATA\cert-renewal.log -Append; $name=([System.Net.Dns]::GetHostEntry([string]"localhost").HostName); $oldCert=gci Cert:\LocalMachine\My | ?{ $_.Subject -eq \"CN=$name\" } | sort -d NotAfter | select -f 1; if (Submit-Renewal -Verbose) { Get-PACertificate | Set-RDSHCertificate; $oldCert | ri; Restart-Service ADWS } Stop-Transcript; exit $LASTEXITCODE"'
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $actionArg
$trigger =  New-ScheduledTaskTrigger -Daily -At 2am -RandomDelay (New-TimeSpan -Minutes 30)
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 30)
Register-ScheduledTask $taskname -Action $action -Trigger $trigger -User 'System' -Settings $settings -Desc $taskdesc 

Script B Renewal written out without Task Scheduler

Start-Transcript $env:LOCALAPPDATA\cert-renewal.log -Append $name=([System.Net.Dns]::GetHostEntry([string]"localhost").HostName)
$oldCert=gci Cert:\LocalMachine\My |
	Where-Object { $_.Subject -eq \"CN=$name\" } |
	Sort-Object -Descending NotAfter |
	Select-Object -First 1
if (Submit-Renewal -Verbose) { 
	Get-PACertificate | Set-RDSHCertificate
	$oldCert | ri; Restart-Service ADWS 
}
Stop-Transcript

from posh-acme.deploy.

fthobe avatar fthobe commented on August 14, 2024

Hey @rmbolger

I also struggle a little with a nonce error, Am I understanding correctly that posh-acme.deploy just falls back to generating a new one?

**********************
Windows PowerShell transcript start
Start time: 20240808004658
Username: GMSERVICE\SYSTEM
RunAs User: GMSERVICE\SYSTEM
Configuration Name: 
Machine: MI-DEV-PS (Microsoft Windows NT 10.0.20348.0)
Host Application: powershell.exe
Process ID: 5540
PSVersion: 5.1.20348.2582
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.20348.2582
BuildVersion: 10.0.20348.2582
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
Transcript started, output file is C:\Windows\system32\config\systemprofile\AppData\Local\cert-renewal.log
PS>TerminatingError(Invoke-WebRequest): "{
  "type": "urn:ietf:params:acme:error:badNonce",
  "detail": "JWS has an invalid anti-replay nonce: \"Cb9-D9qJCtold24rWJytkwMfpT0aSbw-ohnEayo0PLMQaW-w_bk\"",
  "status": 400
}"
VERBOSE: Nonce rejected by ACME server. Retrying with updated nonce.
VERBOSE: Checking for updated renewal window via ARI
WARNING: Order 'mi-dev-ps.gmservice.app' is not recommended for renewal yet. Use -Force to override.
**********************
Windows PowerShell transcript end
End time: 20240808004659
**********************

from posh-acme.deploy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.