Strong Crypto Settings - How best to define/apply?

What is the recommended means to enforce strong cryptographic settings on FCOS? For example, if I want to remove weak ciphers for SSH key exchange etc do I need to faff around with defining these explicitly in fcct as drop-in type configs or is there a better way to define ‘strong’? I see in upstream Fedora there seems to be something going on with update-crypto-policies but I can’t find anything that explains the FCOS position on this - now and future? Thanks for any insights you can provide.

Hi, this is a great question. We don’t have any high level fcct “sugar” for this, though I think that’d be a good enhancement.

So today the answer is inded to use fcct/Ignition to replace /etc/crypto-policies/config with the contents you want, and also add a systemd unit to run update-crypto-policies.

crypto-policies was discussed in We currently don’t ship update-crypto-policies as it requires Python.

It’s a pain right now, but one way to set the policy on FCOS is in your Ignition config, change the symlinks in /etc/crypto-policies/back-ends and the contents of /etc/crypto-policies/state/current.

We could have sugar for that, or alternatively try to rewrite update-crypto-policies in a compiled language.

1 Like

Filed about this.

Another approach I mentioned there which I’ve just tested is:

(host)$ podman run --privileged -v /etc/crypto-policies:/etc/crypto-policies -ti --rm /bin/bash
(cnt)$ dnf install -y crypto-policies-scripts
(cnt)$ update-crypto-policies --no-reload --set FUTURE

But see caveats in ticket.

1 Like

Thanks @jlebon. Both responses were useful to me in building understanding here. I’ve gone with the fcct solution but I think this too may ultimately prove brittle subject to version changes.

The fcct snippet that worked for me for the first solution is:

    # FCOS is delivered without upstream Fedora's update-crypto-policies because
    # of the python dependency.  So, instead we overwrite the file indicating the
    # security profile to apply, and re-write all the symbolic links for current
    # security settings to point to defined crypto policy, e.g. DEFAULT, FUTURE etc.
    - path: /etc/crypto-policies/state/current
      overwrite: true
      mode: 0644
        inline: {cluster_crypto_policy}
    - path: /etc/crypto-policies/back-ends/bind.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/bind.txt
    - path: /etc/crypto-policies/back-ends/gnutls.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/gnutls.txt
    - path: /etc/crypto-policies/back-ends/java.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/java.txt
    - path: /etc/crypto-policies/back-ends/krb5.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/krb5.txt
    - path: /etc/crypto-policies/back-ends/libreswan.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/libreswan.txt
    - path: /etc/crypto-policies/back-ends/libssh.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/libssh.txt
    - path: /etc/crypto-policies/back-ends/nss.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/nss.txt
    - path: /etc/crypto-policies/back-ends/openssh.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/openssh.txt
    - path: /etc/crypto-policies/back-ends/opensshserver.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/opensshserver.txt
    - path: /etc/crypto-policies/back-ends/opensslcnf.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/opensslcnf.txt
    - path: /etc/crypto-policies/back-ends/openssl.config
      overwrite: true
      target: /usr/share/crypto-policies/{cluster_crypto_policy}/openssl.txt

Hey @fifofonix, what version of FCOS are you using? You’re using absolute symlinks which was broken at one point and only recently fixed in testing (not yet in stable).

My testing was with FCOS testing stream with an fcct 1.1.0 definition. Thanks for the warning on this as re-creation of our production stacks right now (based on stable) would presumably fail - until next stable release is made.

1 Like

Yep. Next stable release should be out next week. The workaround is to use relative symlinks if you need something now.

This was solved by input from @jlebon and others but I wanted to re-summarize and add a little more:

  • Summary: The recommended way to modify crypto policy is to apply one of the pre-defined policy levels (e.g. NEXT, FUTURE) and if necessary apply one of the pre-defined policy modification modules to refine to your needs (e.g. NEXT:NO-SHA1). Or, if that doesn’t work define your own policy modification module and apply that (e.g. NEXT:ACME).
  • Detail: To apply the crypto policy in the absence of the python scripts (see discussion) @jlebon detailed a means (with some caveats) using a privileged podman container. This can be wrapped into a oneshot systemd ignition file, referencing your policy level preference and modifications.
  • Caution 1: FUTURE is probably too strict for the time being, without some fine tuning of the openssl SECLEVEL, since it will prevent auto-OS updates being applied without other modifications due to the need for all intermediate CAs to be using keys in excess of 2048 bits. NEXT on the other hand is a good move eliminating some legacy TLS protocols whilst allowing auto-OS updates by zincati/Cincinatti.
  • Caution 2: If you are going to apply a policy modification, e.g. (NEXT:NO-SHA1) one of the existing ones, or your own, note that you cannot use the alternate implementation method suggested in the answers which defines links to pre-defined crypto settings. The python scripts do something else that is not encompassed by that answer when applying a modification module - a dynamic regen of a larger policy document?
  • Background: Good presentation on crypto settings and illustrating how to use policy modification policies to fine tune them.

This is an example of an ignition that works although the systemd could be made a lot better I’m sure. It reboots the machine post application of policy changes without reference to other system state. It might be better with a ConditionFirstBoot if you don’t have other rebooting going on.

    - path: /etc/crypto-policies/policies/modules/ACME.pmod
      mode: 0644
        inline: |
          hash = -SHA1
          sign = -RSA-PSS-SHA1 -RSA-SHA1 -ECDSA-SHA1
          sha1_in_certs = 0
          ssh_cipher = -AES-256-CBC -AES-128-CBC
    - name: set-crypto-policy.service
      enabled: true
      contents: |
        Description=Enable NEXT:ACME
        # ConditionFirstBoot=true

        # Verify current policy state and if not NEXT:ACME make it so...
        ExecStart=/bin/sh -c ' \
            if [[ "$(cat /etc/crypto-policies/state/current)" != "NEXT:ACME" ]]; then \
                /bin/podman run --privileged -v /etc/crypto-policies:/etc/crypto-policies -ti \
                   --rm /bin/bash -c \
                    "dnf install -y crypto-policies-scripts && update-crypto-policies \
                       --no-reload --set NEXT:ACME"; \
                reboot; \

1 Like

@dustymabe and @jlebon please let me know how we can improve upon the solution above to come up with a non-persistent SELINUX change that does not then subsequently impact upgrades.

AFAIU what you’re doing above doesn’t touch the SELinux policy. Is it possible you’re doing something else or maybe ran a one off command somewhere?

You’re right of course. This is crypto policy relate and not SELinux related. I figured out where the real SELinux was in my configuration and I’ll be documenting that in another item on this board tomorrow.