Skip to content

Latest commit

 

History

History
217 lines (164 loc) · 8.28 KB

File metadata and controls

217 lines (164 loc) · 8.28 KB

Azure Linux OS Guard on Azure Kubernetes Service

Azure Linux OS Guard is a hardened, immutable OS profile for Azure Kubernetes Service node pools that combines dm-verity-protected read-only /usr, Unified Kernel Image (UKI) Secure Boot, a vTPM, FIPS-mode cryptography, and Integrity Policy Enforcement (IPE) to deliver a supply-chain-hardened runtime for your cluster nodes. This repository contains ready-to-run companion code for the blog post "Azure Linux OS Guard on Azure Kubernetes Service": a minimal Bicep template that deploys an OS Guard-enabled AKS cluster and a set of shell scripts that reproduce the inspection and demo steps described in the post.

Note: IPE is in audit mode (ipe.enforce=0) during Public Preview. Policy violations are logged via the kernel audit subsystem but are not blocked. None of the scripts below will prevent execution of untrusted binaries.

Table of contents


Prerequisites

Requirement Notes
Azure CLI installed and logged in az login
kubectl installed Used by all scripts
Azure subscription with the AzureLinuxOSGuardPreview feature flag registered See commands below

Register the preview feature

az feature register \
  --namespace Microsoft.ContainerService \
  --name AzureLinuxOSGuardPreview

# Wait until RegistrationState is "Registered" (may take a few minutes)
az feature show \
  --namespace Microsoft.ContainerService \
  --name AzureLinuxOSGuardPreview \
  --query properties.state -o tsv

# Refresh the provider registration
az provider register -n Microsoft.ContainerService

Quickstart

1 — Deploy the cluster

# Create a resource group
az group create --name rg-osguard-demo --location eastus

# Deploy the Bicep template
az deployment group create \
  --resource-group rg-osguard-demo \
  --template-file deploy/main.bicep \
  --parameters deploy/main.parameters.bicepparam

2 — Connect to the cluster

export RESOURCE_GROUP=rg-osguard-demo
export CLUSTER_NAME=aks-osguard-demo

az aks get-credentials \
  --resource-group "$RESOURCE_GROUP" \
  --name "$CLUSTER_NAME"

3 — Run the scripts

Run these in order to reproduce the blog walkthrough:

# Inspect Secure Boot, TPM2, UKI, and dm-verity partition layout
RESOURCE_GROUP=rg-osguard-demo CLUSTER_NAME=aks-osguard-demo bash scripts/inspect-node.sh

# Check IPE audit events (all)
RESOURCE_GROUP=rg-osguard-demo CLUSTER_NAME=aks-osguard-demo bash scripts/check-ipe-audit.sh

# Filter IPE audit events for a specific binary
RESOURCE_GROUP=rg-osguard-demo CLUSTER_NAME=aks-osguard-demo \
  bash scripts/check-ipe-audit.sh --path /opt/nvim-linux-x86_64/bin/nvim

# Run the full dm-verity + IPE demo (write protection + binary download + audit log)
RESOURCE_GROUP=rg-osguard-demo CLUSTER_NAME=aks-osguard-demo bash scripts/demo-immutability.sh

Expected output

inspect-node.sh — confirms Secure Boot, vTPM, and dm-verity on /usr:

========================================================
  bootctl status
========================================================
...
     Secure Boot: enabled (user)
    TPM2 Support: yes
   Measured UKI: yes
...

========================================================
  bootctl list
========================================================
...
options: ... ipe.enforce=0 rd.systemd.verity=1 usrhash=63e91b6a... \
         systemd.verity_usr_data=UUID=ff6feab9-... \
         systemd.verity_usr_hash=UUID=c3de2e26-... \
         systemd.verity_usr_options=,root-hash-signature=/boot/usr.hash.sig ...

Key fields: ipe.enforce=0 (IPE is in audit mode), usrhash (dm-verity root hash), systemd.verity_usr_data/_hash (the two partitions that feed dm-verity).

========================================================
  lsblk
========================================================
NAME          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda             8:0    0   128G  0 disk
...
├─sda3          8:3    0   1.1G  0 part
│ └─usr       253:0    0   1.1G  1 crypt /usr   ← dm-verity device
└─sda4          8:4    0   128M  0 part         ← dm-verity hash tree

========================================================
  mount | grep usr
========================================================
/dev/mapper/usr on /usr type ext4 (ro,relatime)

check-ipe-audit.sh — streams IPE audit events from the node journal:

========================================================
  IPE Audit Events
  IPE is in AUDIT mode (enforcing=0) during Public Preview.
  Violations are logged but NOT blocked.
========================================================

<node> audit[36039]: IPE_ACCESS ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=0 pid=36039 comm="bash" path="/opt/nvim-linux-x86_64/bin/nvim" dev="sda5" ino=917575 rule="DEFAULT op=EXECUTE action=DENY"
<node> audit[36039]: IPE_ACCESS ipe_op=EXECUTE ipe_hook=MMAP enforcing=0 pid=36039 comm="nvim" path="/opt/nvim-linux-x86_64/bin/nvim" dev="sda5" ino=917575 rule="DEFAULT op=EXECUTE action=DENY"
...

Summary: 14 policy violation(s) logged (IPE currently in AUDIT mode — not enforced)

demo-immutability.sh — end-to-end dm-verity write protection + IPE audit demo:

========================================================
  STEP 1: Write protection on /usr
========================================================

✅ PASS: /usr is read-only (dm-verity protected)
   Error captured: bash: /usr/hello.txt: Read-only file system

========================================================
  STEP 2: Download and run an untrusted binary from /opt
========================================================

--> Downloading Neovim ...
--> Extracting to /opt ...
--> Running /opt/nvim-linux-x86_64/bin/nvim --version ...

NVIM v0.xy.z
...
✅ Binary executed successfully (IPE in audit mode — would be blocked at GA)

========================================================
  STEP 3: IPE audit log for the nvim execution
========================================================

<node> audit[36039]: IPE_ACCESS ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=0 ... path="/opt/nvim-linux-x86_64/bin/nvim" rule="DEFAULT op=EXECUTE action=DENY"
...
⚠️  IPE logged this execution as a policy violation.
    In enforce mode, this would be blocked.

Repository structure

az-spoony-bard/
├── README.md
├── deploy/
│   ├── main.bicep                  # AKS cluster with OS Guard node pool (AVM wrapper)
│   └── main.parameters.bicepparam  # Deployment parameters
└── scripts/
    ├── inspect-node.sh             # Secure Boot / dm-verity inspection
    ├── check-ipe-audit.sh          # IPE audit log viewer
    └── demo-immutability.sh        # End-to-end dm-verity + IPE demo

Key concepts

Concept What the scripts show
Secure Boot + UKI bootctl status confirms Secure Boot: enabled and Measured UKI: yes
dm-verity on /usr mount | grep usr shows /usr is read-only via dm-0; write attempts fail
IPE (Integrity Policy Enforcement) Kernel logs every execution of an untrusted binary as IPE_ACCESS … enforcing=0
vTPM bootctl status shows TPM2 Support: yes; UKI measurements are extended into PCRs

For conceptual background on all of the above, see the blog post.


🔗 Links