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.

1 Like

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 python3 getting pulled in by crypto-policies · Issue #280 · coreos/fedora-coreos-tracker · GitHub. 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 Make it easier to change crypto policy · Issue #607 · coreos/fedora-coreos-tracker · GitHub 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 registry.fedoraproject.org/fedora:32 /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
      contents:
        inline: {cluster_crypto_policy}
  links:
    - 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
      contents:
        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: |
        [Unit]
        Description=Enable NEXT:ACME
        # ConditionFirstBoot=true
        Wants=network-online.target

        [Service]
        Type=oneshot
        # 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 registry.fedoraproject.org/fedora:32 /bin/bash -c \
                    "dnf install -y crypto-policies-scripts && update-crypto-policies \
                       --no-reload --set NEXT:ACME"; \
                reboot; \
            fi'

        [Install]
        WantedBy=multi-user.target
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.

So ‘solution’ above hard codes the fedora version (my bad) and once applied effectively pins the security policy meaning it does not benefit from future system wide recommended changes. This should be easily fixable with a uname based lookup but @dustymabe or @jlebon is there a recommended systemd unit template for tasks that should be executed on FCOS major (or minor) version tick?

I don’t think we have that. I would look at VERSION_ID=34 from /etc/os-release.

Things have moved on in Fedora land in terms of crypto policies available since this thread originated with new base policy names available as described here:

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. FUTURE, FIPS) and if necessary apply one of the pre-defined policy modification modules to refine to your needs (e.g. FUTURE:NO-SHA1). Or, if that doesn’t work define your own policy modification module and apply that (e.g. FUTURE: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 re-applies base policy and applies policy modifications on the boot subsequent to any OS update initiating a further reboot.

In this iteration:

  • Base policy changed from CURRENT to FUTURE (NEXT seems still to be a functional option but no longer seems documented). Applied policy modification is ACME so we pivot from CURRENT to FUTURE:ACME
  • Fedora container image label required to apply policy modifications is referenced dynamically using Fedora major version number.
  • Systemd unit now re-runs whenever the unit systemd-update-done is active. The goal of this is to have the unit run on the boot following a FCOS upgrade. This is required because otherwise the modified policy would be forever pinned and not benefit from evolving best standards in future OS versions.
  • This seems to work but it will also trigger if for example a new package is layered via rpm-ostree. However, it probably needs re-working to use a ‘stamp file’ that captures the last uname -r for which the unit has run to make it properly transactional (I think if a reboot were triggered midway through this unit’s execution then it would not re-trigger automatically).
  • The given policy modification file still contains cipher as a policy modification although this is deprecated in fedora 35 and will need to be replaced by something like cipher@ssh for each backend where customization is desired. I have yet to find documentation on this and am still figuring it out.
  • I am not at all confident on systemd units so welcome any improvement feedback.
variant: fcos
version: 1.3.0
storage:
  files:
    - path: /etc/crypto-policies/policies/modules/ACME.pmod
      mode: 0644
      contents:
        inline: |
          # This is an ACME extension to default NO-SHA1 mod to further remove
          # the CBC tls_ciphers thereby improving SSH.
          hash = -SHA1
          sign = -RSA-PSS-SHA1 -RSA-SHA1 -ECDSA-SHA1
          sha1_in_certs = 0
          cipher = -AES-256-CBC -AES-128-CBC
          #cipher@ssh = -AES-256-CBC -AES-128-CBC
          #cipher@openssh-server = -AES-256-CBC -AES-128-CBC
systemd:
  units:
    - name: acme-set-crypto-policy.service
      enabled: true
      contents: |
        [Unit]
        Description=Enable FUTURE:ACME crypto settings
        BindsTo=systemd-update-done.service
        Requires=network-online.target
        After=systemd-update-done.service network-online.target

        [Service]
        Type=oneshot
        # Alternative to BindsTo+After:
        # ExecCondition=/usr/bin/systemctl is-active --quiet systemd-update-done.service
        ExecStartPre=/bin/sleep 10
        # Alternatively:
        # FEDORA_VERSION=$(cat /etc/os-release | grep VERSION_ID | cut -d\= -f2)
        ExecStart=/bin/sh -c 'FEDORA_VERSION=$(uname -r | sed -r "s/^.*fc([0-9][0-9]).*/\1/"); \
                if ( /bin/podman run --privileged -v /etc/crypto-policies:/etc/crypto-policies -i \
                          --rm registry.fedoraproject.org/fedora:$FEDORA_VERSION /bin/bash -c \
                              "dnf install -y crypto-policies-scripts && update-crypto-policies \
                                  --no-reload --set FUTURE:ACME" ); then \
                    reboot; \
                else \
                    exit 1; \
                fi'
        RemainAfterExit=yes

        [Install]
        WantedBy=multi-user.target
1 Like

Comparison matrix of different crypto policies here showing clearly that FUTURE is beyond FIPS in terms of crypto policy settings. Obviously, FUTURE also more likely to cause issues, e.g. presently with layering of packages from fedora mirrors since these do not yet adhere to implied required crypto standards (experienced when layering open-vm-tools for example).