The System Crypto Policy, Proven To Govern The Handshake
One EL 10 setting that decides what OpenSSL, GnuTLS, NSS, OpenSSH and Java will negotiate, applied only when it differs and read back from both files that record it. The live test runs one TLS 1.2 handshake three times, under the configured policy, under FUTURE, and under the policy again, so the refusal in the middle is the policy's doing. Original role, live-tested on Rocky Linux 10.
Verification
Live-testedReally deployed to a container sandbox, proven idempotent (a second run changes nothing), verified against the role’s assertions, then torn down.
Conformance
- Static validation (yamllint · ansible-lint)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live-tested - applied, verified, destroyed
Last verified 2026-09-27 · podman 4.9.3 · ansible 2.21.4 · how we verify
Cite it in your README
badge · attributionPaste this beside the module in the repository that uses it. The badge is rendered from this artifact's verification record, so it reads live-tested because the record says so, and the link lands on this page.
[](https://www.iac-bazaar.com/catalog/ansible-crypto-policy?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
Ansible role 1.0.0, live-tested on IaC Bazaar: [The System Crypto Policy, Proven To Govern The Handshake](https://www.iac-bazaar.com/catalog/ansible-crypto-policy?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
```yaml
# The System Crypto Policy, Proven To Govern The Handshake: https://www.iac-bazaar.com/catalog/ansible-crypto-policy (download from your IaC Bazaar account)
```Preview:
Documentation
crypto-policy
One switch that every library on the host obeys. EL's crypto policies decide what OpenSSL, GnuTLS, NSS, OpenSSH, Java and Kerberos will negotiate, from one setting. The role sets it, refuses to believe it without reading it back, and proves the new policy reached a running daemon rather than only a file. The live test runs one handshake three times - under the configured policy, under FUTURE, and under the configured policy again - so the refusal in the middle is demonstrably the policy's doing and not the server's.
No download, and no version to pin. The crypto policies and their scripts are part of EL 10. What the role owns is which policy the host runs, and the proof that the host is really running it.
There is no file for this role to write. The policy is a system-wide switch,
and setting it regenerates every back-end under
/etc/crypto-policies/back-ends. So the role reads the current policy, sets it
only when it differs, and reads it back - and the live test asserts the generated
openssl back-end really carries the floor the policy implies.
The live test starts this host on the wrong policy on purpose. A role whose
whole effect is one conditional task converges with changed=0 against a machine
that already matches it, and a verify run after that reads the distribution's
defaults while appearing to confirm the role. The lane refuses a first converge
that changed nothing, and tests/pre-converge.yml answers the refusal by putting
the host on LEGACY first. What the receipt certifies is therefore a policy this
role moved, not a policy it agreed with.
A running process keeps the policy it read at start, and EL restarts exactly
three of them. update-crypto-policies --set runs
/usr/share/crypto-policies/reload-cmds.sh, which issues
try-reload-or-restart for bind and try-restart for ipsec and sshd, skipping
any of the three that is not already running. Nothing else is touched: httpd,
postfix, dovecot, a JVM, a database and anything of your own go on negotiating
under the policy they read when they started, while --show reports the new one.
That is the gap crypto_policy_restart_services exists to close, and it is empty
by default because sshd - the one everybody thinks of - is already covered.
Measured, because the tool's own note ("it is recommended to restart the system")
suggests it does nothing of the kind: a plain --set moved sshd's activation
forward by 9 seconds, --no-reload --set moved it by 0, and a plain --set
again by 6. crypto_policy_reload_services: false is that flag, for a host where
sshd dropping its sessions is your decision to schedule rather than a side effect
of a policy change.
The live test asserts the new policy reached a running daemon: sshd is installed and started before the converge, and its activation must be no earlier than the moment the policy file was written. A name in the restart list that systemd does not know fails the run - it used to be swallowed, which meant the role could report success having reached no running process at all.
Two of the obvious hardening choices stop dnf working on Rocky 10. Both
FUTURE and DEFAULT:OSPP raise OpenSSL's security level to 3, and the repository
mirrors present RSA-2048 certificates that a level-3 client refuses, so package
installs fail with Curl error (60) ... EE certificate key too weak. This role's
own live test failed on exactly that before the default was changed. Measured on
Rocky Linux 10 in this role's lane, one policy per row:
| policy | dnf makecache | a TLS 1.2 peer |
|---|---|---|
DEFAULT | works | accepted |
DEFAULT:NO-PQ | works | accepted |
DEFAULT:ECDHE-ONLY | works | refused, handshake failure |
DEFAULT:OSPP | fails | accepted |
FUTURE | fails | refused, protocol version |
The dnf column is a fact about the certificates this host's repositories serve,
not about the policy alone: a mirror with a 3072-bit key would be reachable under
either. Check your own repositories, internal ones included, before choosing a
level-3 policy - and note that --set succeeds in every row above, so nothing
warns you at the moment you make the change.
DEFAULT:NO-SHA1 does not work on EL 10. It is the line every RHEL 9
hardening guide gives, and NO-SHA1.pmod is not shipped here: the command exits
non-zero with Unknown policy, and the previous policy stays in force. The
subpolicies Rocky 10 does ship are AD-SUPPORT, AD-SUPPORT-LEGACY,
ECDHE-ONLY, NO-ENFORCE-EMS, NO-PQ, OSPP and TEST-PQ. The live test
asserts that refusal, so if a later release adds the module this role goes red
rather than going stale.
Setting the FIPS policy is not FIPS mode. update-crypto-policies --set FIPS selects the algorithm set; a host in FIPS mode needs fips-mode-setup --enable and a reboot, which this role does not do and does not claim.
License
Commercial - IaC Bazaar EULA. (c) IaC Bazaar.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Variables
- Test
Related modules
ansible-lynis
Lynis from EPEL on a systemd timer, with the units the package keeps only in its docs, your skipped tests in custom.prf, and a minimum hardening index below which the audit unit fails, so a falling score shows as a failed unit. The live test runs the audit, reads the index and the tests that ran, and finds the timer enabled. Original role, live-tested on Rocky Linux 10.
ansible-suricata
Suricata from EPEL watching the default-route interface as the suricata user, ET Open fetched at install and refreshed daily, plus a canary rule that proves the sensor is alive. A root-run check left root-owned logs and a daemon recording nothing; the role prevents it. The live test raises the canary alert while a second lookup is logged, not alerted. Original role, live-tested on Rocky Linux 10.
ansible-aide
AIDE from AppStream on EL 10: a watched tree, a baseline database built once, and the oneshot unit and timer the package does not ship. The live test passes on an unchanged host, FAILS when a file appears inside a watched path and names it, ignores one inside an excluded path, and passes again once the change is gone. Original role, live-tested on Rocky Linux 10.
ansible-389-ds
389 Directory Server from AppStream. A fresh instance listens on every interface and lets anonymous clients read the tree; this role binds both listeners to loopback and limits anonymous clients to the rootDSE. The live test adds a user who binds, sees a wrong password and an anonymous search refused, and reads the LDAPS certificate. Original role, live-tested on Rocky Linux 10.
ansible-krb5-kdc
An MIT Kerberos KDC: the realm created once with a stash, kadmind behind an ACL, a default policy that locks an account after five wrong passwords, every listener on loopback. The KDC starts on a broken config without a word, so the live test proves each setting by behaviour: the ticket lifetime, the refusals, the lockout. Original role, live-tested on Rocky Linux 10.
ansible-authelia
Authelia from the upstream release (sha256-verified) as a hardened system service on loopback with file users and sqlite; its secrets are generated once on the host and reach the service as AUTHELIA_*_FILE variables. The live test hashes a password with Authelia's hasher, logs in, sees a wrong password refused and an anonymous visitor sent to the portal. Original role, live-tested on Rocky 10.