On RHEL and its relatives, one setting decides which TLS, SSH, IPsec, Kerberos and DNSSEC algorithms every system library will accept, and most teams never look at it until an audit or an outage forces them to. System-wide crypto policies replace hundreds of per-application cipher strings with a single policy level, and FIPS mode goes further by forcing the kernel and core libraries onto validated, approved implementations. This guide explains how the two mechanisms fit together, who can change them, how they interact with keys, certificates and directory integrations, how to verify and monitor them, and how to roll out FIPS mode without rebuilding systems twice. It is written for Linux platform engineers, security architects and compliance owners running Red Hat Enterprise Linux, Fedora, CentOS Stream and rebuilds, with notes on Ubuntu. Background on algorithms and key sizes is in the Cryptography Basics Guide, and the wider RHEL baseline is in the Red Hat Enterprise Linux Security Hardening Guide; this page goes deeper on the crypto layer only.
Key takeaways
- A policy level is a floor for every library at once. DEFAULT already rejects TLS 1.1 and older, SHA-1 signatures and RSA or DH below 2048 bits for OpenSSL, GnuTLS, NSS, OpenSSH, libssh, Kerberos, Libreswan, BIND and OpenJDK.
- The FIPS policy is not FIPS mode. Red Hat states that switching to the FIPS policy does not guarantee FIPS 140 compliance; FIPS mode needs
fips=1on the kernel command line and the module self-tests that come with it. - Decide on FIPS before you install. RHEL 9 still allows a post-install switch with
fips-mode-setup --enablebut does not guarantee compliance; RHEL 10 removed the tool and supports FIPS mode only when it is enabled at installation. - FIPS mode is one way. Turning it off leaves an inconsistent system, and the only correct fix Red Hat documents is a reinstall, so test on disposable images first.
- Validated means a specific binary on a specific release. Module certificates cover particular RHEL minor releases, and FIPS 140-2 certificates move to the CMVP Historical list after 21 September 2026, so evidence must name the module and certificate number.
How identity and access work in Linux crypto policies and FIPS mode
Crypto policies decide how a host proves its identity and how it checks the identity of others: which certificate signatures it trusts, which SSH host key and user key types it accepts, which Kerberos encryption types it negotiates and which TLS groups it offers. The crypto-policies package holds the policy definitions; update-crypto-policies compiles the chosen policy into one configuration file per back-end under /etc/crypto-policies/back-ends/, and each library reads its file when an application starts. That is why a change needs a reboot, or at least a restart of every service, before it is real.
The four base levels
| Setting | LEGACY | DEFAULT | FIPS | FUTURE |
|---|---|---|---|---|
| TLS 1.1 and older | Off | Off | Off | Off |
| TLS 1.2 and 1.3 | On | On | On | On |
| IKEv1, 3DES, RC4, DSA | Off | Off | Off | Off |
| Minimum RSA and DH size | 2048 bits | 2048 bits | 2048 bits | 3072 bits |
| SHA-1 in signatures and certificates | Allowed | Off | Off | Off |
| CBC-mode ciphers | Allowed | Off for SSH | Off except Kerberos | Off except Kerberos |
| Symmetric ciphers under 256 bits | Allowed | Allowed | Allowed | Off |
| Intended use | Interoperability with RHEL 6 era systems, at a larger attack surface | Current threat model, the shipped default | Restricts to FIPS 140 approved algorithms; used by FIPS mode | Testing a likely future policy; may break public internet interoperability |
Source: Red Hat RHEL 9 Security hardening documentation. An algorithm allowed by a level is only usable where the application itself supports it.
Subpolicies and scopes
- Subpolicies: appended with a colon.
DEFAULT:SHA1re-enables SHA-1 signatures,LEGACY:AD-SUPPORTadds weaker settings for Active Directory interoperability,FIPS:OSPPadds Common Criteria restrictions (3072-bit minimum, fewer SSH algorithms and TLS groups), and from RHEL 9.7DEFAULT:PQenables hybrid ML-KEM key exchange and ML-DSA signatures. - Custom modules: files with upper-case names ending
.pmodin/etc/crypto-policies/policies/modules/, using directives such asmin_rsa_size,hash,cipher,key_exchange,protocol,sha1_in_certsandetm. - Scopes: a directive can target one protocol or back-end, for example
cipher@SSH,hash@{tls,ssh}or a negation such asoption@!ipsec. Scope names include TLS, SSH, IPsec, IKE, DNSSec and Kerberos, plus back-end names such asOpenSSH,libssh,NSSandjava-tls. - Full custom policy: a
.polfile in/etc/crypto-policies/policies/, usually copied from/usr/share/crypto-policies/policies/. Prefer a base level plus a module: it survives package updates to the base definitions.
What FIPS mode adds
FIPS mode is a kernel state. When /proc/sys/crypto/fips_enabled reads 1, the kernel crypto API and core libraries such as OpenSSL use only FIPS-approved implementations and run the self-tests FIPS 140-3 requires. The crypto policy follows the kernel flag and is set to FIPS. On RHEL 9, fips-mode-setup --enable sets the FIPS policy, installs the FIPS dracut module, adds fips=1 to the kernel command line and regenerates the initramfs. On RHEL 10 the tool is gone and fips=1 must be present when the installer starts, in an image builder blueprint (fips = true under [customizations]) or, for image mode, in a file under /usr/lib/bootc/kargs.d/.
Admin roles and privileged access
Changing the policy is a root action, and it silently changes the security of every service on the host. Treat it like a change to the firewall or PAM stack, not like a package update.
- Who can change it: root through
update-crypto-policies --set, the web console (Overview, Configuration, Crypto policy), and any automation with root on the host, such as the RHELcrypto_policiesAnsible system role (crypto_policies_policy,crypto_policies_reboot_ok). Restrict sudo rules so that operators cannot run the command ad hoc; see the sudo and sudoers Security Guide. - Who can bypass it: anyone who can write
/etc/ssh/sshd_config.d/, an application's own TLS settings, or the back-end symlinks in/etc/crypto-policies/back-ends/. Removing a symlink and replacing it with a hand-written file is possible but Red Hat does not support it. Monitor those paths as closely as the policy itself. - Where it should be set: in the build pipeline. A kickstart, image builder blueprint or Containerfile that sets the level and the FIPS flag gives you a reviewable record; a manual change on a running host does not.
- Privileged access to FIPS hosts: SSH sessions to FIPS hosts use only approved algorithms, so administrator clients and bastions must support them. Check which user and host key types the FIPS policy on your release accepts before the cut-over, and prefer ECDSA (P-256 or P-384) or RSA 3072 keys for administrators and automation where FIPS applies. See the SSH Key Management Guide.
Integrations, API tokens and service accounts
The most common breakages after a policy change are not web servers. They are the machine identities that were enrolled years ago with whatever algorithm was default at the time.
- Keys created before the switch: Red Hat says all cryptographic keys must be regenerated after moving to the FIPS policy, and that regeneration may be impossible in some cases, giving an existing IdM realm with user keys as the example. Inventory SSH host keys, TLS server keys, Kerberos keytabs and application keystores first. See the Linux Service Accounts and Keytab Management Guide.
- Host key rotation side effects: regenerating SSH host keys makes every client report a changed host identity, exactly what GitHub users saw when GitHub replaced its RSA host key in the GitHub RSA SSH host key exposure 2023. Publish new fingerprints, or use SSH certificates, before you rotate.
- Active Directory and Samba: Red Hat lists Samba (RC4 and DES) and Kerberos (SHA-1) among applications that are not FIPS 140-3 compliant in certain uses. AD trusts that still rely on RC4 need
AD-SUPPORTon LEGACY, which is a dated exception, not a fix.FIPS:OSPPalso causes AD and IdM integration problems and blocks connections to the Red Hat CDN. - Service-to-service TLS: on RHEL 9.2 and later in FIPS mode, TLS 1.2 connections must use Extended Master Secret, so legacy clients that support neither EMS nor TLS 1.3 cannot connect. ChaCha20 suites are not offered. Test every inbound partner, monitoring agent and API client against a FIPS host before the cut-over. See the mTLS Guide.
- Applications that ignore the policy: Go applications and GnuPG 2 do not follow the system-wide policy, and statically linked or vendored crypto libraries never will. Their API tokens, webhooks and agent connections need their own configuration and their own FIPS evidence. Red Hat also notes that Node.js
--enable-fipsand--force-fipsare unsupported and cause an error; rely on the system setting. - Containers: the host kernel must be in FIPS mode; Podman then enables FIPS mode in supported containers automatically.
fips-mode-setupdoes not work inside containers, and crypto libraries must come from the package manager, not copied in.
Logging and detection
A crypto policy is a configuration, so detection is mostly drift detection plus evidence that clients are actually negotiating what you expect.
| What to check | How | Expected result |
|---|---|---|
| Active policy | update-crypto-policies --show; compare /etc/crypto-policies/state/CURRENT.pol with the approved build | The approved level and modules, for example DEFAULT:NO-SHA1 or FIPS |
| Kernel FIPS flag | cat /proc/sys/crypto/fips_enabled; on RHEL 9 also fips-mode-setup --check | 1 on every host in a FIPS boundary |
| Active OpenSSL provider | openssl list -providers on a FIPS-booted host | The FIPS provider is loaded and active |
| Bypass files | File integrity monitoring and auditd watches on /etc/crypto-policies/, /etc/ssh/sshd_config.d/, /etc/ssh/ssh_config.d/ | No change outside an approved change window |
| Effective SSH algorithms | sshd -T and an external scan of offered key exchange and host key algorithms | No algorithm outside the policy |
| Effective TLS offer | External TLS scan of each listener | TLS 1.2 and 1.3 only; no SHA-1 certificates; EMS on FIPS hosts |
| Compliance scan | OpenSCAP with the SCAP Security Guide profile for your baseline | Crypto policy and FIPS rules pass |
Pair these with auditd rules on update-crypto-policies execution so that a change shows the user and session. Downgrade attempts against services (ATT&CK T1689 Downgrade Attack) appear as handshake failures once a policy is strict, so a spike in TLS or SSH negotiation errors after a change is either a broken client or a probe; both deserve a look. See the Linux Logging and auditd for Defenders Guide and the OpenSCAP and Linux Compliance Scanning Guide.
Metrics that show it is working
- Policy conformance: percentage of hosts whose active policy matches the approved level for their tier.
- FIPS coverage: percentage of hosts in the FIPS boundary reporting
fips_enabled = 1and running a release whose modules have an active certificate. - Exceptions: number of hosts on LEGACY or with
SHA1orAD-SUPPORTmodules, each with an owner and expiry date; the trend should fall. - Bypass count: services with application-level cipher overrides or modified back-end files.
- Weak key inventory: RSA keys under 2048 bits (3072 for FUTURE or OSPP tiers) and SHA-1 signed certificates still in use.
Hardening baseline
Choosing a level
| Situation | Choose | Trade-off |
|---|---|---|
| General servers, no regulatory FIPS requirement | DEFAULT, optionally DEFAULT:PQ on RHEL 9.7 and later once clients support hybrid key exchange | Best interoperability with a sound floor |
| Internet-facing services with modern clients only | FUTURE after testing, or DEFAULT plus a module that raises min_rsa_size | Older clients and some partners will fail to connect |
| US federal systems, FedRAMP, contracts that require validated modules | FIPS mode set at installation | Fewer algorithms (no ChaCha20, EMS required for TLS 1.2), rebuild to reverse, certificate tracking per release |
| Common Criteria evaluated configuration | FIPS:OSPP plus the cc-config guidance | Breaks AD and IdM integration and Red Hat CDN access; the subpolicy alone does not make a system compliant |
| A legacy system you cannot yet replace | DEFAULT plus a narrow scoped module, or LEGACY on an isolated host | Exposure to downgrade and weak signatures; must carry an expiry date |
Small estates can usually standardise on DEFAULT everywhere and FIPS for a clearly defined boundary. Large estates benefit from tiers (general, regulated, internet edge) each with one approved policy string held in the build pipeline and reported by configuration management.
Rollout in phases
- Inventory. List every listener and client with its protocol, key type, key size and signature algorithm, plus applications that ignore the policy (Go binaries, bundled runtimes, appliances).
- Pick the target per tier and write the policy string down, including any module. Record each exception with an owner and an expiry date.
- Test on disposable hosts. Build a pilot image with the target policy, run the application and its integrations, and scan the offered algorithms externally. For FIPS, build fresh from an image with
fips=1, never by converting the pilot in place. - Fix the identities before the cut-over. Reissue certificates signed with SHA-1, replace RSA 1024 and DSA keys, plan SSH host key and user key replacement, and confirm Kerberos encryption types with the directory team.
- Roll out in rings. Non-production, then a production canary, then the rest, each ring held for a full business cycle while you watch handshake errors and service health.
- Roll back safely. For crypto policies, rollback is
update-crypto-policies --setwith the previous string and a reboot. For FIPS mode there is no supported rollback: keep the previous non-FIPS image deployable until the FIPS ring is stable, and redeploy rather than disable. - Record evidence. For each FIPS host keep the release, the module names and certificate numbers from the Red Hat compliance page and the CMVP listing, and the output of the verification commands.
Ubuntu and other distributions
Ubuntu does not ship the RHEL crypto-policies framework; cipher choice is per application. Canonical provides FIPS through an Ubuntu Pro subscription, where a cryptographic core set including the kernel and OpenSSL is validated per LTS release and enabled with the Pro client (for example pro enable fips-updates). The same principles apply: enable it before workloads go on the host, check the certificate for the exact release, and treat the change as hard to reverse. See the Ubuntu Server Security Hardening Guide.
Framework mapping
| Framework | Reference | How this topic applies |
|---|---|---|
| NIST SP 800-53 Rev. 5 | SC-13 Cryptographic Protection; SC-8 and SC-8(1) Transmission Confidentiality and Integrity; SC-12 Key Establishment and Management; IA-7 Cryptographic Module Authentication; CM-2 and CM-6 | FIPS mode and approved algorithms for SC-13 and IA-7; the policy string as part of the baseline configuration |
| NIST CSF 2.0 | PR.DS-02 data in transit; PR.PS-01 configuration management | One governed setting for in-transit protection on every host |
| CIS Controls v8.1 | 3.10 Encrypt Sensitive Data in Transit; 4.1 Establish and Maintain a Secure Configuration Process | Policy level held in the secure configuration standard |
| ISO/IEC 27001:2022 Annex A | A.8.24 Use of cryptography; A.8.9 Configuration management | Documented cryptographic rules enforced at OS level |
| MITRE ATT&CK | T1689 Downgrade Attack; T1557 Adversary-in-the-Middle | Removing weak protocols and algorithms reduces the room for both |
Common misconfigurations
- Setting the FIPS policy and calling the host FIPS compliant. Without
fips=1the kernel and libraries do not run in FIPS mode; Red Hat says plainly that the policy alone does not guarantee compliance, and on RHEL 10 it is not sufficient to enable FIPS mode at all. - Switching to FIPS late. Enabling FIPS mode after workloads, keys and IdM enrolment exist leaves keys generated outside FIPS mode, which may be impossible to regenerate. Red Hat's advice, where install-time enablement is impossible, is to make it the first post-install step.
- LEGACY as a quick fix. One failing partner leads to
update-crypto-policies --set LEGACYon a whole fleet, re-enabling SHA-1 signatures and SSH CBC ciphers for every service. Use a scoped module for the one protocol that needs it, on the one host that needs it, with an expiry. - Changing the policy without restarting services. Libraries read their back-end files at start-up, so long-running daemons keep the old algorithms until reboot, and scans run straight after the change give false comfort.
- Trusting the policy for software that ignores it. Go services, GnuPG 2, vendored OpenSSL builds and third-party agents keep their own defaults; scan them externally and record them as separate items.
- Stale FIPS evidence. Citing a FIPS 140-2 certificate after 21 September 2026, or a certificate for a different minor release, will not satisfy an assessor. Red Hat ties compliance to the binary version, not the package name.
Practitioner checklist
- Record one approved policy string per server tier and set it in kickstart, image builder blueprints or Containerfiles, not by hand.
- Report
update-crypto-policies --showand/proc/sys/crypto/fips_enabledfrom every host into configuration management and alert on drift. - Decide on FIPS before installation; on RHEL 10, build FIPS hosts from an installer or image with
fips=1. - Inventory and replace SHA-1 certificates, RSA keys under 2048 bits and DSA keys before tightening the policy; plan SSH host key changes with published fingerprints.
- Express every exception as a scoped
.pmodmodule with an owner and expiry, never as fleet-wide LEGACY. - Watch
/etc/crypto-policies/and the SSH drop-in directories with file integrity monitoring and auditd. - Scan listeners externally after each change and after reboot to confirm the offered protocols, groups and signature algorithms.
- List applications that bypass the policy and give each its own configuration and evidence.
- Keep FIPS evidence per host: release, module names, certificate numbers and verification output, reviewed when you move minor releases.
Standards and references
- Red Hat: Using the system-wide cryptographic policies (RHEL 9 Security hardening)
- Red Hat: Switching RHEL to FIPS mode (RHEL 9)
- Red Hat: Switching RHEL to FIPS mode (RHEL 10)
- Red Hat: Compliance activities and government standards, FIPS 140
- crypto-policies project: crypto-policies(7) manual page
- NIST: Cryptographic Module Validation Program
- NIST: SP 800-53 Rev. 5
- Canonical: Ubuntu FIPS 140 certification
Related NHI Mgmt Group resources: FIPS 140-3 and Cryptographic Module Validation Guide · TLS Server Configuration Baseline Guide · OpenSSH Server Hardening Guide · Hybrid Post-Quantum TLS Key Exchange Guide