Table of Contents
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
CA Handler for Microsoft Certification Authority Web Enrollment Service
This CA handler uses Microsoft's Certification Authority Web Enrollment Service for certificate enrollment. It also utilizes a modified version of the Python library magnuswatn/certsrv to communicate with the enrollment service.
Limitations
Be aware of the following limitations when using this handler:
- Authentication towards the Web Enrollment Service is limited to "basic," "NTLM," or "GSSAPI (Kerberos)." ClientAuth is not supported.
- Communication is limited to HTTPS.
- Revocation operations are not supported.
Preparation
- Microsoft Certification Authority Web Enrollment Service must be enabled and configured.
- You need a set of credentials with permission to access the service and enrollment templates.
- The authentication method (basic or NTLM) must be configured correctly.
- (Optional): If installing from RPM and using NTLM authentication, you need two additional Python modules: python3-requests-ntlm and python3-ntlm-auth. These are not part of the standard or EPEL repositories. You can find them in the A2C GitHub repository.
- (Optional): If installing from RPM and using GSSAPI authentication, you need two additional Python modules: python3-requests-gssapi and gssapi. These are also available in the A2C GitHub repository.
Verifying Service Access
Before configuring acme2certifier, verify access to the Web Enrollment Service:
- NTLM authentication:
curl -I --ntlm --user <user>:<password> -k https://<host>/certsrv/
- Basic authentication:
curl -I --user <user>:<password> -k https://<host>/certsrv/
- GSSAPI authentication:
export KRB5_CONFIG=<path>/krb5.conf
kinit <username>
curl --negotiate -u: <user>:<password> -k https://<host>/certsrv/
If the service is accessible, the response should return status code 200:
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 3686
Content-Type: text/html
Server: Microsoft-IIS/10.0
Set-Cookie: - removed - ; secure; path=/
X-Powered-By: ASP.NET
Extended Protection for Authentication (EPA) Configuration
When using GSSAPI (Kerberos) authentication, you may encounter issues if the Microsoft Certificate Services Web Enrollment Service has Extended Protection for Authentication (EPA) set to "Required". The current requests-gssapi library does not support EPA in "Required" mode, and the developers are working on implementing this feature.
Solution: Change the EPA setting from "Required" to "Accept" in the IIS configuration for the Certificate Services Web Enrollment Service.
To modify the EPA setting:
- Open Internet Information Services (IIS) Manager on the server hosting the Certificate Services Web Enrollment Service
- Navigate to the Default Web Site → CertSrv application
- Double-click on Authentication in the Features View
- Select Windows Authentication and click Advanced Settings
- In the Extended Protection dropdown, change from Required to Accept
- Click OK to apply the changes
- Restart the IIS service or the specific application pool
For detailed information about Extended Protection for Authentication, refer to the Microsoft documentation on Extended Protection for Authentication Overview.
Note: This configuration change maintains security while ensuring compatibility with the current requests-gssapi implementation. The EPA feature in "Accept" mode still provides protection against authentication relay attacks when supported by the client.
Installation
- Allow the MD4 algorithm in
openssl.cnf:
sudo sed -i "s/default = default_sect/\default = default_sect
legacy = legacy_sect/g" /etc/ssl/openssl.cnf && sudo sed -i "s/\[default_sect\]/\[default_sect\]
activate = 1
\[legacy_sect\]
activate = 1/g" /etc/ssl/openssl.cnf
- Install certsrv via pip (this module is already included in the Docker images):
pip install certsrv[ntlm]
- Modify the server configuration (
acme_srv/acme_srv.cfg) and add the following parameters:
[CAhandler]
handler_file: examples/ca_handler/mscertsrv_ca_handler.py
host: <hostname>
user: <username>
password: <password>
ca_bundle: <filename>
auth_method: <basic|ntlm|gssapi>
template: <name>
allowed_domainlist: ["example.com", "*.example2.com"]
krb5_config: <path_to_individual>/krb5.conf
Parameter Explanations
- host – The hostname of the system providing the Web Enrollment Service.
- host_variable (optional) – Name of the environment variable containing the host address (overridden if
hostis set inacme_srv.cfg). - user – Username for accessing the service.
- user_variable (optional) – Name of the environment variable containing the username (overridden if
useris set inacme_srv.cfg). - password – Password for authentication.
- password_variable (optional) – Name of the environment variable containing the password (overridden if
passwordis set inacme_srv.cfg). - ca_bundle – CA certificate bundle in PEM format, required for validating the server certificate.
- auth_method – Authentication method (
basic,ntlm, orgssapi). - krb5_config (optional) – Path to an individual
krb5.conffile. - template – Certificate template used for enrollment.
- allowed_domainlist (optional) – List of allowed domain names for enrollment (JSON format).
- enrollment_config_log (optional) – Log enrollment parameters (default:
False). - enrollment_config_log_skip_list (optional) – List of enrollment parameters to exclude from logs (JSON format).
Passing a Template from Client to Server
acme2certifier supports the the Automated Certificate Management Environment (ACME) Profiles Extension draft allowing an acme-client to specify a template parameter to be submitted to the CA server.
The list of supported profiles must be configured in acme_srv.cfg
[Order]
profiles: {"template1": "http://foo.bar/template1", "template2": "http://foo.bar/template2", "template3": "http://foo.bar/template3"}
Once enabled, a client can specify the template to be used as part of an order request. Below an example for lego:
docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego --tls-skip-verify -s https://<acme-srv> -a --email "lego@example.com" -d <fqdn> --http run --profile template2
The handler supports the header_info_list feature, allowing an ACME client to specify a template name during enrollment. To enable this feature, update acme_srv.cfg:
[Order]
header_info_list: ["HTTP_USER_AGENT"]
Example Usage
- acme.sh:
docker exec -i acme-sh acme.sh --server http://<acme-srv> --issue -d <fqdn> --standalone --useragent template=foo --debug 3 --output-insecure
- lego:
docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego --tls-skip-verify -s https://<acme-srv> -a --email "lego@example.com" --user-agent template=foo -d <fqdn> --http run
EAB Profiling
This handler supports EAB profiling to allow individual enrollment configurations per ACME account, as well as restrictions on CN and SANs in the CSR. To enable it, configure acme_srv.cfg as follows:
[EABhandler]
eab_handler_file: examples/eab_handler/kid_profile_handler.py
key_file: <profile_file>
eab_profiling: True
[CAhandler]
...
Example Key File
{
"keyid_00": {
"hmac": "V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw",
"cahandler": {
"template": ["WebServerModified", "WebServer"],
"allowed_domainlist": ["www.example.com", "www.example.org", "*.local"]
}
},
"keyid_01": {
"hmac": "YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg",
"cahandler": {
"template": "WebServerModified",
"allowed_domainlist": ["www.example.com", "www.example.org", "*.local"],
"unknown_key": "unknown_value"
}
},
"keyid_02": {
"hmac": "dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM",
"cahandler": {
"allowed_domainlist": ["www.example.com", "www.example.org"]
}
},
"keyid_03": {
"hmac": "YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr"
}
}
This setup ensures that individual accounts can have specific enrollment configurations and domain restrictions.