Open abdealipython opened 1 week ago
Sounds like EAB account credentials to link your ACME account to a system account within your CA. Why do you have multiple accounts and which CA are you using?
Thank you for the response.
Yes, the EAB is linked to my account. There is only one account, and we are using Sectigo CA. However, currently in the account, there are many HMAC keys and KIDs. We are creating these separate keys because we want to manage certificate requests by department, such as for private or public certificates.
What commands are you using to create the accounts? Or are you just calling New-PACertificate
directly? The confirmations make it sound like the module is trying to overwrite the first account with the subsequent accounts.
EAB/HMAC keys are generally only needed once during account creation. But you should be able to create as many different local accounts as you want and switch between them with no confirmations. You probably want to explicitly include the -ID
parameter in your New-PAAccount
calls to name the accounts according to your departments.
When we are creating the account for the first time, there is no issue; it will create the certificate for the private CA and user email address.
Import-Module -Name Posh-ACME
Set-PAServer -DirectoryUrl https://acme.account
New-PAAccount -AcceptTOS -Contact '{{ requestor_email }}' -ExtAcctKID '{{ HMACKID }}' -ExtAcctHMACKey '{{ HMACKEY }}' -Debug
$domain = '{{ domain }}'
New-PACertificate $domain -Verbose -Plugin WebRoot -Plugin
Now, the user has requested a new email address and public certificate for different departments. We need to use the same server https://acme.account
, but we need to map a different EAB for the public certificate and the different departments. When we try to create a new PA account, it creates the old one (which is for the private CA and email address used earlier).
I am using the same command again:
Import-Module -Name Posh-ACME
Set-PAServer -DirectoryUrl https://acme.account
New-PAAccount -AcceptTOS -Contact '{{ requestor_email }}' -ExtAcctKID '{{ HMACKID }}' -ExtAcctHMACKey '{{ HMACKEY }}' -Debug
but this is asking for confirmation of many things.
I can change the account using the ID, but when we are creating a new local account for the departments, it is asking me for a prompt regarding the existing account.
> Set-PAAccount -ID 19455645645646545a824a3c600000000
> Get-PAAccount
id status contact alg KeyLength
-- ------ ------- --- ---------
19455645645646545a824a3c600000000... valid {mailto:abdealipython@example.com} ES256 ec-256
> $domain = 'testabdaccountiis.example.com'
> New-PACertificate $domain -Verbose -Plugin WebRoot -PluginArgs @{ WRPath = '{{ D:\inetpub\wwwroot\websites\testabdaccountiis }}' }
VERBOSE: Updating directory info from https://acme.account
VERBOSE: Using ACME Server https://acme.account
VERBOSE: Using account 19455645645646545a824a3c600000000
VERBOSE: Order name not specified, using 'testabdaccountiis.example.com'
VERBOSE: Creating a new order 'testabdaccountiis.example.com' for testabdaccountiis.example.com
VERBOSE: Finalizing the order.
VERBOSE: Creating new certificate request with key length 2048.
VERBOSE: Creating new private key for the certificate request.
VERBOSE: Downloading signed certificate
VERBOSE: Updating cert expiration and renewal window
VERBOSE: Successfully created certificate.
Subject NotAfter KeyLength Thumbprint AllSANs
------- -------- --------- ---------- -------
C=IN,ST=GJ,O=OV,OU=IT,CN=testabdaccountiis.example.com 11/14/2024 2:41:29 AM 2048 dfgdfgdfgdfgdfgdgdgfdgf4D8AD20E {testabdaccountiis.example.com}
Do we have an alternative solution to achieve different EABs with the same account without receiving any prompts? If yes, could you please provide the command or link?
Part of the problem is the use of the -Debug
switch. Until PowerShell 7 (I think), that will cause confirmation prompts every time the module makes a Write-Debug call. If you still want to see the debug output but without the confirmations remove the switch and run $DebugPreference = 'Continue'
prior to the rest of the commands.
The New-PAAccount
command specifically may also still prompt for confirmation if the new account you're creating has the same KeyLength and Contact values as an existing valid account. You can avoid that duplication confirmation with -Force
.
I'd still also probably use an -ID <department>
flag on the new account calls as well just so you don't need to keep a record of generated ID values to departments when switching back and forth. The only caveat is the ID values can only contain alphanumeric characters and -
,.
,_
,!
because they get used as a folder name on disk.
Thank you for your insight. I am using the Force flag to create accounts forcibly, which is working fine. but, we are getting some challenges with revocation, so we implemented a loop to check each entry one by one and revoke the matched certificate using Ansible.
Import-Module -Name Posh-ACME -Force Set-PAServer -DirectoryUrl '{{ acme_directory }}' New-PAAccount -AcceptTOS -Contact '{{ requestor_email }}' -ExtAcctKID '{{ HMACKID }}' -ExtAcctHMACKey '{{ HMACKEY }}' -Force $domain = '{{ common_name }}' New-PACertificate $domain -Verbose -Plugin WebRoot -PluginArgs @{ WRPath = '{{ dir_details }}' }
Once the certificate is created and stored in the Posh-ACME profile, I retrieve the PFX file path and import the certificate into IIS, matching the certificate thumbprint using an Ansible module. This process is working well, and my website is secured without issues. but, when renewing a specific certificate, old backup (.bak) files are created. Currently, I'm checking the certificate serial number and its expiration, but the old entry still appears on the website. (Note: I have restarted the IIS services and rebooted the testing server, but the entry is still present, which means the new certificate is not attached.)
retrieve the PFX file path and import the certificate into IIS
What's the actual process you're using to import the cert into IIS?
We are creating the certificate using Posh ACME, and once the certificate is stored locally, we pick the value from Ansible and bind the IIS certificate using ansible.builtin.win_certificate_store and ansible.builtin.win_iis_webbinding. Also, we create a task scheduler entry for certificate renewal.
But when the certificate is renewed at the endpoint, I can see that the thumbprint and order values have changed. But when checking the IIS website, it still shows the old entries instead of the new one.
Code:-
name: 'Create Website with custom log location, format W3C, and roll over every hour' ansible.builtin.win_iis_website: name: "{{ add_iis_site_role_site_name }}_site" state: 'started' hostname: "{{ common_name }}" physical_path: "{{ add_iis_site_role_app_directory }}" parameters: "logfile.directory:{{ add_iis_site_role_log_directory }}|logfile.period:Hourly|logFile.logFormat:W3C" application_pool: "{{ add_iis_site_role_app_pool }}" ssl_flags: 0
name: 'Import cert into IIS cert store' ansible.builtin.win_certificate_store: path: "{{ cert_pfx_full_chain }}" #this value we are picking the CN get-pacertificate and fetching thumbprint value file_type: pkcs12 password: "{{ ansible_acme_pfx_pass }}" store_location: LocalMachine key_storage: 'machine' state: 'present' register: add_iis_site_role_cert_import become_method: runas become_user: "{{ ansible_dev }}"
name: 'Add port 443 binding using the certificate' ansible.builtin.win_iis_webbinding: name: "{{ add_iis_site_role_site_name }}_site" protocol: 'https' port: 443 host_header: "{{ common_name }}" ssl_flags: 0 certificate_hash: "{{ cert_thumbprint | trim }}" #this value we are picking the CN get-pacertificate and fetching thumbprint value state: 'present'
Unfortunately, I'm not really familiar with Ansible. Are there any logs that show it's trying to update the binding and failing or might the re-binding just not be happening because the site and binding already exist?
If you're not forced to stick with Ansible for those things, there's a Set-IISCertificate function in the Posh-ACME.Deploy companion module that might help as well.
Let’s leave Ansible aside for now. Suppose we are manually creating the IIS site, generating the certificate using Posh-ACME, and binding the certificate manually to the specified site. In this case, the IIS site will be accessible securely. But if we execute the submit-renewal command using Task Scheduler, do we need to modify the IIS settings again and bind the new HTTPS certificate manually?
Yes, the renewed cert is distinct from the old cert. IIS must be explicitly told to use it.
Suppose I am trying your method to do IIS binding with Posh-ACME.Deploy module then how to handle this way if the certificate is already bind then how to do force ?
Error:-
Submit-Renewal certificate.example.com | Set-IISCertificate -SiteName "certificate_site" WARNING: Order 'certificate.example.com' is not recommended for renewal yet. Use -Force to override.
PS C:\Windows\system32> Submit-Renewal certificate.example.com -force | Set-IISCertificate -SiteName "certificate_site" New-IISSiteBinding : At least one other site is using the same HTTPS binding and the binding is configured with a different certificate. Use the -Force switch to reuse this HTTPS binding and reassign the other site(s) to use the new certificate. At C:\Users\test\Documents\WindowsPowerShell\Modules\Posh-ACME.Deploy\2.0.0\Public\Set-IISCertificate.ps1:150 char:17
+ CategoryInfo : InvalidOperation: (:) [New-IISSiteBinding], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.IIS.Powershell.Commands.NewIISSiteBindingCommand
The Set-IISCertificateNew
function will only run if Submit-Renewal
actually returns a certificate. The warning you're seeing is from Submit-Renewal basically telling you that nothing was renewed (and thus nothing was returned for Set-IISCertificate
to process).
If you want to force the renewal early, you'd add that -Force
flag to the Submit-Renewal command only like this:
Submit-Renewal certificate.example.com -Force | Set-IISCertificate -SiteName "certificate_site"
Be careful with this though because you don't want to run into rate limits and get stuck for a while. It might be worth switching to the Staging server first if you think it's going to run a lot.
I have tried switching to another staging server and ran the same command with the -Force option. The certificate is being renewed and issued, but it is not assigned to the specific IIS site I provided in the command. I am getting the following error. It would be great if you could provide some insights
Error:- Submit-Renewal testingposhacmeiis.example.com-force | Set-IISCertificate -SiteName "testingposhacmeiis_site" New-IISSiteBinding : At least one other site is using the same HTTPS binding and the binding is configured with a different certificate. Use the -Force switch to reuse this HTTPS binding and reassign the other site(s) to use the new certificate. At C:\Program Files\WindowsPowerShell\Modules\Posh-ACME.Deploy\2.0.0\Public\Set-IISCertificate.ps1:150 char:17
+ CategoryInfo : InvalidOperation: (:) [New-IISSiteBinding], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.IIS.Powershell.Commands.NewIISSiteBindingCommand
This approach will help us. If we are handling the Posh-ACME.Deploy module, we can achieve this with more automation and bind the certificate using a PowerShell script. but, at the very least, this approach should work if we can bind the old certificate with the renewed certificate.
The error is from the New-IISSiteBinding
command that Set-IISCertificate
is using under the hood. I haven't run into it before but it sounds like you have multiple sites configured for the same old cert? It may also be confused because you haven't specified a host header but your ansible equivalent did. So you could also try adding -HostHeader "{{ common_name }}"
to your Set-IISCertificate
command and see if that gets rid of the error.
The -Force
it's suggesting would be for the underlying command. But in order to use it, the Set-IISCertificate
function would need to be updated to support passing it through.
When developing scripted renewal and deployment with more complex orchestration I would recommend that your renewal and deployment are not tightly bound.
Consider renewing and storing in a keyvault or secrets store, then periodically (and on first deployment) your app deployment can pull the latest cert directly from there. The app will then always get the most recently renewed cert.
Keep in mind that IIS https bindings should ideally be: Hostname set to your domain (not blank), IP set to * or All Unassigned (not a specific IP, to avoid cert binding conflicts), SNI enabled. Your certificate is expected to be in the local machine store under either My/Personal or Web Hosting. Watch out for trying to create bindings against "my" if your cert is actually stored in "webhosting".
Based on https://docs.ansible.com/ansible/latest/collections/community/windows/win_iis_webbinding_module.html#ansible-collections-community-windows-win-iis-webbinding-module in your above configuration example you are not enabling SNI, here is one of there examples, modified to use any IP
- name: Add a HTTPS binding with host header and SNI enabled
community.windows.win_iis_webbinding:
name: Default Web Site
protocol: https
port: 443
ip: '*'
host_header: test.com
ssl_flags: 1
certificate_hash: D1A3AF8988FD32D1A3AF8988FD323792DA73F4C
state: present
You should raise any bugs with the ansible project https://github.com/ansible-collections/community.windows/issues however be aware that community modules like this generally have no official support.
I am issuing the certificate using Posh-ACME, but we have two different HMAC keys and IDs, so we need to use them each time.
The first time when I issue the certificate with a new PA account, it works fine. However, when I create a new PA account, I get many prompts asking for confirmation of the PA account details. In the end, a new PA account is created with a new HMAC and KeyID. My question is: how can we avoid these prompts asking for confirmation? Or if there is any other way to create the new PA account with a new HMAC key, it would be greatly appreciated. Thank you for your help!
If we need to create a new certificate with a new HMAC and Key, how should we proceed without disrupting the existing certificate?