Cloud-optimised Linux distributions remove the shell, the package manager and the writable root filesystem that a traditional hardening checklist assumes, so the old checklist either does not apply or quietly gets bypassed. Amazon Linux 2023 is still a general-purpose distribution, but Bottlerocket, Google's Container-Optimized OS (COS) and Talos Linux are built to run containers and little else, and each moves administration onto an API, a host container or cloud IAM. This guide explains how access and privilege work on each, which defaults are already strong, which settings you must change, and how to monitor and patch hosts you are meant to replace rather than repair. It is for platform, Kubernetes and cloud security engineers running EKS, ECS, GKE or self-managed clusters. For general Linux controls see the Linux Server Hardening Guide; this page covers what is different on these images.
Key takeaways
- Amazon Linux 2023 is not hardened for you. SELinux ships in permissive mode, kernel lockdown only engages with Secure Boot, and several KSPP options are opt-in on the kernel command line.
- On container-optimised OSs the control plane is the new root. Write access to Bottlerocket's
/run/api.sock, a Talosos:admincertificate or COS metadata SSH keys gives full control of the host. - Privileged containers undo the image's design. Host namespaces, runtime sockets, system mounts and privileged SELinux labels let a workload walk around dm-verity, read-only roots and enforcing SELinux.
- Patch by replacing, not by logging in. These images update as whole versions (A/B partitions, SquashFS images, versioned repositories), and Bottlerocket explicitly recommends periodic host replacement even with automatic updates.
- Logging must come from outside the host. With no shell and little persistent state, ship logs and runtime telemetry through DaemonSets or agents before you need them.
How identity and access work in cloud-optimised Linux
The four platforms take very different positions on who can log in and how.
| Platform | Interactive access | Configuration path | Root filesystem and integrity | Mandatory access control |
|---|---|---|---|---|
| Amazon Linux 2023 | SSH with EC2 key pairs or Systems Manager Session Manager; full shell and dnf | cloud-init user data (fails closed if remote content is unavailable), configuration management | Writable root; UEFI Secure Boot supported; /tmp is tmpfs | SELinux enabled, permissive by default |
| Bottlerocket | No SSH server or shell in the OS; control host container via SSM (on by default), admin host container with SSH (off by default) | Bottlerocket API over /run/api.sock, apiclient, TOML user data | Read-only root verified by dm-verity, A/B partitions, /etc on tmpfs, Secure Boot on new UEFI variants | SELinux enforcing, cannot be disabled; lockdown in integrity mode on most variants |
| Container-Optimized OS | SSH on port 22 only; no accessible accounts by default; keys from instance metadata or OS Login (IAM) | Instance metadata, cloud-init, GKE node configuration | Read-only root checksum verified by the kernel at each boot; /etc writable but reset on reboot | AppArmor and seccomp available; IMA and Audit in kernel |
| Talos Linux | No SSH, no shell, no passwords | Declarative machine configuration and gRPC API through talosctl, with certificate-based authentication | Immutable SquashFS image under 80 MB; small ephemeral partition | Follows KSPP recommendations; dynamic kernel modules disabled |
Sources: AWS AL2023 user guide, Bottlerocket SECURITY_FEATURES and README, Google Cloud COS security overview, Sidero Labs Talos documentation.
Admin roles and privileged access
Amazon Linux 2023
- Prefer Session Manager to SSH. It removes inbound port 22 and ties access to IAM; if SSH remains, note that AL2023 disables the
ssh-rsahost key algorithm, generates Ed25519 and ECDSA host keys, and expectsrsa-sha2-256orrsa-sha2-512signatures from RSA client keys. Re-enablingssh-rsaneeds the LEGACY crypto policy, which weakens every library on the host. See the Linux System-Wide Crypto Policies and FIPS Mode Guide. - Move SELinux to enforcing. Run in permissive long enough to collect AVC denials from your workload, fix labels or policy, then set enforcing in the image, ideally through cloud-init as AWS documents.
- Restrict sudo for
ec2-userin golden images; the default image grants it.
Bottlerocket
- The API socket:
/run/api.sockis owned by root and groupapi(GID 274) and labelledapi_socket_t. Write access grants full control of system configuration, including defining a superpowered host container and, on Kubernetes variants, static pods that bypass admission control. Block it from every orchestrator-managed container. - Host containers: keep the admin container disabled until needed (
apiclient set host-containers.admin.enabled=trueturns it on) and turn it off again afterwards. Inside it,sheltiegives a full root shell on the host, so treat enabling it as a privileged access event. Disabling the control container as well can leave no way to change settings on a running node. - SELinux labels: containers normally run as
container_t;control_tandsuper_tcan write to the API socket andsuper_tcan modify any host file. Block those labels in pod and task specifications.
Container-Optimized OS
- Use OS Login. Without it, anyone who can edit project or instance metadata can add an SSH key, and accounts get sudo. With OS Login, access is granted through IAM roles and can be audited centrally. Block project-wide SSH keys on node pools.
Talos Linux
- Roles live in client certificates. The organisation field of the certificate subject carries the role:
os:admin(all methods),os:operator(reader plus reboot, shutdown and etcd backup),os:reader(safe methods; can list but not read files) andos:etcd:backup(snapshot only). Issue named configs withtalosctl config new --roles=os:reader <name>, keepos:adminfor break-glass, and confirmmachine.features.rbac: trueon clusters created before RBAC became the default. - Protect the machine configuration. It holds cluster secrets and CA material; store it like a secret, not like a manifest.
Integrations, API tokens and service accounts
- Instance metadata credentials: every cloud node carries a role. On EC2, an AMI registered with
imds-support v2.0forces IMDSv2 (HttpTokens required, hop limit 2), and an account-level default can require IMDSv2 for new instances; check the AMI and launch template rather than assuming. Containers that can reach metadata can steal node credentials (ATT&CK T1552.005 Cloud Instance Metadata API). See the EC2 Instance Metadata Service Hardening Guide and the Cloud Instance Metadata Services Compared Guide. - Workload identity instead of node roles: on EKS use pod-level identity and on GKE Workload Identity, so pods do not inherit the node service account. See the EKS Identity Hardening Guide and the GKE Identity Hardening Guide.
- Container runtime sockets:
/run/containerd/containerd.sock,/run/docker.sockand Bottlerocket's/run/host-containerd/host-containerd.sockgrant full control of container execution. Build images with tools that do not need the socket. - User data is a secret store by accident. Bottlerocket TOML, cloud-init and Talos configurations often carry bootstrap tokens and keys; anyone with permission to read instance attributes can read them.
- Talos certificates: Talos API certificates are short-lived and rotate automatically, and Kubernetes keeps its own PKI. Long-lived
talosconfigfiles on laptops are the weak point: issue per-person configs and plan in advance how you will revoke a config if one leaks.
Logging and detection
| Signal | Amazon Linux 2023 | Bottlerocket | COS | Talos |
|---|---|---|---|---|
| Host access | SSM session logs, sshd in journal, CloudTrail StartSession | Control container SSM sessions; admin container enablement through API changes | OS Login and serial console events in Cloud Audit Logs | API access by certificate identity |
| Configuration change | auditd, configuration management drift | apiclient get settings compared with source; user data changes | Metadata changes in Cloud Audit Logs | Machine configuration changes applied through the API |
| Integrity | SELinux AVCs, file integrity monitoring | Unexpected reboot from dm-verity corruption | Boot failure on checksum mismatch; IMA | Image version and signature at upgrade |
| Runtime | auditd, eBPF agent | DaemonSet runtime sensor; logdog archives for support | DaemonSet sensor; Audit | DaemonSet sensor; talosctl logs and dmesg |
Alert on the events that undo the design: a privileged pod or task, a hostPath mount of /run, /etc or /local, host PID or network namespace use, an SELinux label other than container_t, Bottlerocket admin container enablement and new Talos os:admin configs. Container escape attempts (T1611 Escape to Host) and attacker-deployed containers (T1610 Deploy Container) are best caught by a runtime sensor plus admission logs. See the Container Runtime Security Guide.
Metrics
- Node age: share of nodes older than your replacement interval (for example 30 days).
- Version currency: share of nodes on the latest image or release version, and time from vendor release to fleet adoption.
- Privileged workloads: count of privileged containers, host namespace users and runtime socket mounts, each with an approved exception.
- Interactive access: admin container enablements, SSH sessions and
os:adminuses per month. - Enforcement: share of AL2023 hosts in SELinux enforcing mode with Secure Boot on.
Hardening baseline
Choosing a platform
| If you need | Consider | Trade-off |
|---|---|---|
| Traditional software, agents and packages on the host | Amazon Linux 2023 hardened to a benchmark | Largest attack surface; SELinux, lockdown and KSPP options are yours to set |
| EKS or ECS nodes with minimal host management | Bottlerocket | No host packages or shell; agents must run as containers; FIPS needs a FIPS variant |
| GKE or Compute Engine container hosts | Container-Optimized OS | Tied to Google Cloud; debugging through Toolbox |
| Self-managed Kubernetes on any cloud or bare metal | Talos Linux | All administration through the Talos API; teams must learn a new tool chain |
Small teams gain most from the container-optimised images because there is less to configure; large organisations with host agents, compliance scanners and legacy tooling often keep Amazon Linux for general workloads and adopt Bottlerocket or COS for cluster nodes first.
Baseline settings
- AL2023: SELinux enforcing; UEFI Secure Boot on supported instance types, which also engages lockdown; add
init_on_alloc=1 init_on_free=1 randomize_kstack_offset=onwhere the performance cost is acceptable; enforce module signing through lockdown becauseMODULE_SIG_FORCEis off; apply all updates of a new release, keepingdnf upgrade --securityfor exceptions; check for a CIS benchmark for your release. - Bottlerocket: deploy the Bottlerocket update operator (Kubernetes) or ECS updater; lockdown in integrity mode (not confidentiality, which breaks BPF and perf tools); admin container off; FIPS variant where required.
- COS: OS Login on, project-wide SSH keys blocked, automatic updates and GKE node auto-upgrade on, firewall left at its default of dropping inbound TCP and UDP except port 22.
- Talos: RBAC on, per-person
talosconfigfiles, restricted network access to the Talos API, machine configuration in a secret store. - All: Kubernetes Pod Security Admission at the restricted profile or an equivalent admission policy, default seccomp profile, no UID 0 containers where possible. See the Kubernetes Admission Control Guide.
Rollout
- Inventory host dependencies: agents, scanners, kernel modules and anything that needs a shell. Each must become a container, an API call or a reason to stay on AL2023.
- Build a pilot node group with the target image, baseline settings and admission policy in audit or warn mode.
- Run real workloads for a full release cycle, collecting SELinux denials, admission warnings and runtime alerts.
- Switch admission to enforce and move node groups in rings, using surge upgrades so that rollback is simply returning traffic to the previous node group.
- Set a replacement interval and automate it; for AL2023, pin
releaseverin images so every rebuild is deterministic. - Roll back by redeploying the previous image version, keeping the previous node group available until the new one is stable.
Framework mapping
| Framework | Reference | Applies to |
|---|---|---|
| NIST SP 800-53 Rev. 5 | CM-2, CM-7 Least Functionality, SI-7 and SI-7(6), SI-2, AC-6 | Minimal images, verified roots, version-based patching, least privilege for host access |
| NIST CSF 2.0 | PR.PS-01, PR.PS-02 | Configuration management and software maintenance through image replacement |
| CIS Controls v8.1 | 4.1 Secure Configuration Process; 7.3 Automated OS Patch Management | Image baselines and automated updates |
| MITRE ATT&CK | T1611 Escape to Host; T1610 Deploy Container; T1552.005 Cloud Instance Metadata API | Privileged workloads, rogue containers and node credential theft |
Common misconfigurations
- Treating AL2023 like Bottlerocket. Teams assume a modern AWS image is locked down and leave SELinux permissive and Secure Boot off, so none of the kernel protections that depend on them are active.
- Mounting the API or runtime socket "just for one tool". A logging or build DaemonSet with
/runmounted can reconfigure every node, define superpowered host containers and run static pods outside admission control. - Leaving the admin container on. Enabled once for troubleshooting and never disabled, it reintroduces SSH and a route to a root shell on every node launched from that user data.
- Metadata SSH keys on COS. Without OS Login, project-wide keys added years ago still work on every new node and grant sudo.
- A single shared
talosconfig. Oneos:adminfile passed between engineers and CI gives no attribution and no way to revoke one person. - Nodes that never die. Automatic updates fix the OS but a kernel compromise survives in place; without a replacement interval, a long-lived node is the place an attacker stays.
Practitioner checklist
- Choose one image per node role and record why; keep AL2023 only where host packages are genuinely needed.
- On AL2023, set SELinux enforcing and Secure Boot in the golden image and pin
releasever. - Require IMDSv2 for every node and give pods their own workload identity.
- Block
/run/api.sock, container runtime sockets,/etc,/runand/localmounts, host namespaces and privileged SELinux labels through admission policy. - Keep the Bottlerocket admin container disabled and alert when it is enabled.
- Use OS Login on COS and per-person, least-role certificates on Talos.
- Deploy the vendor update mechanism and a fixed node replacement interval.
- Ship host and runtime logs through DaemonSets to a central store and alert on privileged workload events.
- Remove secrets from user data and machine configurations, or encrypt and rotate them.
Standards and references
- Bottlerocket: Security Features
- Bottlerocket: Security Guidance
- AWS: Amazon Linux 2023 kernel hardening
- AWS: Setting SELinux modes for AL2023
- AWS: Configure instance metadata options for new instances
- Google Cloud: Container-Optimized OS security overview
- Sidero Labs: Talos Linux philosophy
- Sidero Labs: Talos role-based access control
Related NHI Mgmt Group resources: Amazon EKS Security Hardening Guide · GKE Security Hardening Guide · Container Security Guide · Kubernetes Security Guide