Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 42 additions & 7 deletions parts/common/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -1148,23 +1148,58 @@
}
},
{
"name": "cni-plugins",
"name": "containernetworking-plugins",
"downloadLocation": "/opt/cni/downloads",
"downloadURIs": {
"windows": {
"default": {
"versionsV2": []
}
},
"default": {
"current": {
"ubuntu": {
"r2004": {
"versionsV2": [
{
"renovateTag": "<DO_NOT_UPDATE>",
"latestVersion": "1.6.2"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've been on 1.6.2 this whole time? :D

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. Paul confirmed it's intended.

"renovateTag": "name=containernetworking-plugins, repository=production, os=ubuntu, release=20.04",
"latestVersion": "1.9.0-ubuntu20.04u1"
}
],
"downloadURL": "https://packages.aks.azure.com/cni-plugins/v${version}/binaries/cni-plugins-linux-${CPU_ARCH}-v${version}.tgz"
]
},
"r2204": {
"versionsV2": [
{
"renovateTag": "name=containernetworking-plugins, repository=production, os=ubuntu, release=22.04",
"latestVersion": "1.9.0-ubuntu22.04u1"
}
]
},
"r2404": {
"versionsV2": [
{
"renovateTag": "name=containernetworking-plugins, repository=production, os=ubuntu, release=24.04",
"latestVersion": "1.9.0-ubuntu24.04u1"
}
]
}
},
"azurelinux": {
"v3.0": {
"versionsV2": [
{
"renovateTag": "RPM_registry=https://packages.microsoft.com/azurelinux/3.0/prod/cloud-native/x86_64/repodata, name=containernetworking-plugins, os=azurelinux, release=3.0",
"latestVersion": "1.9.0-1.azl3"
}
]
}
},
"azurelinuxkata": {
"v3.0": {
"versionsV2": [
{
"renovateTag": "RPM_registry=https://packages.microsoft.com/azurelinux/3.0/prod/cloud-native/x86_64/repodata, name=containernetworking-plugins, os=azurelinux, release=3.0",
"latestVersion": "1.9.0-1.azl3"
}
]
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ installCriCtlPackage() {
stub
}

installCNI() {
retrycmd_get_tarball 120 5 "${CNI_DOWNLOADS_DIR}/refcni.tar.gz" "https://${PACKAGE_DOWNLOAD_BASE_URL}/cni-plugins/v1.6.2/binaries/cni-plugins-linux-amd64-v1.6.2.tgz" || exit $ERR_CNI_DOWNLOAD_TIMEOUT
extract_tarball "${CNI_DOWNLOADS_DIR}/refcni.tar.gz" "$CNI_BIN_DIR"
Comment on lines +97 to +98
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The installCNI function downloads and extracts a CNI plugin tarball from https://${PACKAGE_DOWNLOAD_BASE_URL}/cni-plugins/... without any checksum or signature verification. If an attacker can compromise the download host, DNS, or TLS path, they can replace the tarball with a malicious one and obtain root-level code execution via the installed CNI binaries. Add robust integrity checking (e.g., verify a pinned hash or signature before extraction) or move to a package distribution mechanism that performs signature validation.

Copilot uses AI. Check for mistakes.
}


installStandaloneContainerd() {
stub
}
Expand Down
58 changes: 0 additions & 58 deletions parts/linux/cloud-init/artifacts/cse_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ installNetworkPlugin() {
if [ "${NETWORK_PLUGIN}" = "azure" ]; then
installAzureCNI
fi
installCNI #reference plugins. Mostly for kubenet but loopback plugin is used by containerd until containerd 2
rm -rf $CNI_DOWNLOADS_DIR &
}

# downloadCredentialProvider is always called during build time by install-dependencies.sh.
Expand Down Expand Up @@ -384,62 +382,6 @@ setupCNIDirs() {
}


# Reference CNI plugins is used by kubenet and the loopback plugin used by containerd 1.0 (dependency gone in 2.0)
# The version used to be deteremined by RP/toggle but are now just hadcoded in vhd as they rarely change and require a node image upgrade anyways
# Latest VHD should have the untar, older should have the tgz. And who knows will have neither.
installCNI() {
# Old versions of VHDs will not have components.json. If it does not exist, we will fall back to the hardcoded download for CNI.
# Network Isolated Cluster / Bring Your Own ACR will not work with a vhd that requres a hardcoded CNI download.
if [ ! -f "$COMPONENTS_FILEPATH" ] || ! jq '.Packages[] | select(.name == "cni-plugins")' < $COMPONENTS_FILEPATH > /dev/null; then
echo "WARNING: no cni-plugins components present falling back to hard coded download of 1.4.1. This should error eventually"
# could we fail if not Ubuntu2204Gen2ContainerdPrivateKubePkg vhd? Are there others?
# definitely not handling arm here.
retrycmd_get_tarball 120 5 "${CNI_DOWNLOADS_DIR}/refcni.tar.gz" "https://${PACKAGE_DOWNLOAD_BASE_URL}/cni-plugins/v1.4.1/binaries/cni-plugins-linux-amd64-v1.4.1.tgz" || exit $ERR_CNI_DOWNLOAD_TIMEOUT
extract_tarball "${CNI_DOWNLOADS_DIR}/refcni.tar.gz" "$CNI_BIN_DIR"
return
fi

#always just use what is listed in components.json so we don't have to sync.
cniPackage=$(jq ".Packages" "$COMPONENTS_FILEPATH" | jq ".[] | select(.name == \"cni-plugins\")") || exit $ERR_CNI_VERSION_INVALID

#CNI doesn't really care about this but wanted to reuse updatePackageVersions which requires it.
os=${UBUNTU_OS_NAME}
if [ -z "$UBUNTU_RELEASE" ]; then
os=${OS}
os_version="current"
fi
os_version="${UBUNTU_RELEASE}"
if isMarinerOrAzureLinux "${OS}" && [ "${IS_KATA}" = "true" ]; then
os=${MARINER_KATA_OS_NAME}
fi
PACKAGE_VERSIONS=()
updatePackageVersions "${cniPackage}" "${os}" "${os_version}"

#should change to ne
# shellcheck disable=SC3010
if [[ ${#PACKAGE_VERSIONS[@]} -gt 1 ]]; then
echo "WARNING: containerd package versions array has more than one element. Installing the last element in the array."
exit $ERR_CONTAINERD_VERSION_INVALID
fi
packageVersion=${PACKAGE_VERSIONS[0]}

# Is there a ${arch} variable I can use instead of the iff
if [ "$(isARM64)" -eq 1 ]; then
CNI_DIR_TMP="cni-plugins-linux-arm64-v${packageVersion}"
else
CNI_DIR_TMP="cni-plugins-linux-amd64-v${packageVersion}"
fi

if [ -d "$CNI_DOWNLOADS_DIR/${CNI_DIR_TMP}" ]; then
#not clear to me when this would ever happen. assume its related to the line above Latest VHD should have the untar, older should have the tgz.
mv ${CNI_DOWNLOADS_DIR}/${CNI_DIR_TMP}/* $CNI_BIN_DIR
else
echo "CNI tarball should already be unzipped by components.json"
exit $ERR_CNI_VERSION_INVALID
fi

chown -R root:root $CNI_BIN_DIR
}

installAzureCNI() {
CNI_TGZ_TMP=${VNET_CNI_PLUGINS_URL##*/} # Use bash builtin ## to remove all chars ("*") up to the final "/"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ installCriCtlPackage() {
stub
}

installCNI() {
#This is an old version because dalec needs to be updated for osguard/flatcar
# https://github.com/Azure/dalec-build-defs/blob/main/specs/containernetworking-plugins/containernetworking-plugins-1.9.0.yaml
retrycmd_get_tarball 120 5 "${CNI_DOWNLOADS_DIR}/refcni.tar.gz" "https://${PACKAGE_DOWNLOAD_BASE_URL}/cni-plugins/v1.6.2/binaries/cni-plugins-linux-amd64-v1.6.2.tgz" || exit $ERR_CNI_DOWNLOAD_TIMEOUT
extract_tarball "${CNI_DOWNLOADS_DIR}/refcni.tar.gz" "$CNI_BIN_DIR"
Comment on lines +18 to +19
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The installCNI function downloads and extracts a CNI plugin tarball from https://${PACKAGE_DOWNLOAD_BASE_URL}/cni-plugins/... without any checksum or signature verification. If an attacker can compromise the download endpoint, DNS, or TLS path, they can substitute a malicious tarball and gain code execution on the node as root via the CNI binaries. Add strong integrity verification (for example, pinning to a known hash or verified signature before extraction) or source the plugins from a package channel that enforces signature checks.

Copilot uses AI. Check for mistakes.
}


# CSE+VHD can dictate the containerd version, users don't care as long as it works
installStandaloneContainerd() {
local desiredVersion="${1:-}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,48 @@ installDeps() {
fi
}

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "determined" is misspelled as "deteremined"

Suggested change
# The version used to be determined by RP/toggle but is now just hardcoded in the VHD as it rarely changes and requires a node image upgrade anyway
# Latest VHD should have the untar, older should have the tgz. And who knows will have neither.

Copilot uses AI. Check for mistakes.
# Reference CNI plugins is used by kubenet and the loopback plugin used by containerd 1.0 (dependency gone in 2.0)
# The version used to be determined by RP/toggle but is now just hardcoded in the VHD as it rarely changes and requires a node image upgrade anyway
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't have references to RP/ "toggles" if we can help it

# Latest VHD should have the untar, older should have the tgz. And who knows will have neither.
installCNI() {
echo "installing mariner containernetworking-plugins"
# Old versions of VHDs will not have components.json. If it does not exist, we will fall back to the hardcoded download for CNI.
# Network Isolated Cluster / Bring Your Own ACR will not work with a vhd that requires a hardcoded CNI download.
if [ ! -f "$COMPONENTS_FILEPATH" ] || ! jq '.Packages[] | select(.name == "containernetworking-plugins")' < $COMPONENTS_FILEPATH > /dev/null; then
# For older VHDs which do not have containernetworking-plugins in components.json, it should have the older cni-plugins tgz extracted and installed at VHD build time.
# We will just use what is already installed on the VHD.
echo "components.json not found or containernetworking-plugins not found in components.json, assuming older VHD with cni-plugins already installed."
return
fi

#always just use what is listed in components.json so we don't have to sync.
cniPackage=$(jq ".Packages" "$COMPONENTS_FILEPATH" | jq ".[] | select(.name == \"containernetworking-plugins\")") || exit $ERR_CNI_VERSION_INVALID

os=${OS}
os_version="${OS_VERSION}"
PACKAGE_VERSIONS=()
updatePackageVersions "${cniPackage}" "${os}" "${os_version}"

if [ ${#PACKAGE_VERSIONS[@]} -eq 0 ]; then
echo "no containernetworking-plugins versions for ${os} ${os_version}"
return
fi
# shellcheck disable=SC3010
if [ ${#PACKAGE_VERSIONS[@]} -gt 1 ]; then
echo "WARNING: containernetworking-plugins package versions array has more than one element."
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as Ubuntu: The error message says "WARNING" but the code exits fatally. This should say "ERROR" or handle the multiple versions gracefully.

Suggested change
echo "WARNING: containernetworking-plugins package versions array has more than one element."
echo "ERROR: containernetworking-plugins package versions array has more than one element."

Copilot uses AI. Check for mistakes.
exit $ERR_CNI_VERSION_INVALID
fi
packageVersion=${PACKAGE_VERSIONS[0]}

# - between name and version unlike apt which uses =
packageName="containernetworking-plugins-${packageVersion}"
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error in comment: "vesion" should be "version"

Copilot uses AI. Check for mistakes.
echo "Installing ${packageName} with dnf"
dnf_install 30 1 600 ${packageName} || exit $ERR_CNI_VERSION_INVALID

mv /usr/bin/containernetworking-plugins/* $CNI_BIN_DIR
chown -R root:root $CNI_BIN_DIR
}

installKataDeps() {
if [ "$OS_VERSION" != "1.0" ]; then
if ! dnf_install 30 1 600 kata-packages-host; then
Expand Down Expand Up @@ -152,7 +194,7 @@ downloadGPUDrivers() {
echo "No CUDA package found for kernel ${KERNEL_VERSION} (vm_sku=${VM_SKU})"
exit $ERR_MISSING_CUDA_PACKAGE
fi

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace-only change that removes trailing whitespace. While this is good hygiene, it's unrelated to the main PR purpose of changing CNI plugin installation.

Copilot uses AI. Check for mistakes.
echo "Installing: ${CUDA_PACKAGE}"
dnf_install 30 1 600 ${CUDA_PACKAGE} || exit $ERR_APT_INSTALL_TIMEOUT
}
Expand Down
43 changes: 43 additions & 0 deletions parts/linux/cloud-init/artifacts/ubuntu/cse_install_ubuntu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,49 @@ installDeps() {
fi
}

# Reference CNI plugins is used by kubenet and the loopback plugin used by containerd 1.0 (dependency gone in 2.0)
# The version used to be deteremined by RP/toggle but are now just hardcoded in vhd as they rarely change and require a node image upgrade anyways
# Latest VHD should have the untar, older should have the tgz. And who knows will have neither.
installCNI() {
echo "installing ubuntu containernetworking-plugins"
# Old versions of VHDs will not have components.json. If it does not exist, we will fall back to the hardcoded download for CNI.
# Network Isolated Cluster / Bring Your Own ACR will not work with a vhd that requires a hardcoded CNI download.
if [ ! -f "$COMPONENTS_FILEPATH" ] || ! jq '.Packages[] | select(.name == "containernetworking-plugins")' < $COMPONENTS_FILEPATH > /dev/null; then
# For older VHDs which do not have containernetworking-plugins in components.json, it should have the older cni-plugins tgz extracted and installed at VHD build time.
# We will just use what is already installed on the VHD.
echo "components.json not found or containernetworking-plugins not found in components.json, assuming older VHD with cni-plugins already installed."
return
fi

#always just use what is listed in components.json so we don't have to sync.
cniPackage=$(jq ".Packages" "$COMPONENTS_FILEPATH" | jq ".[] | select(.name == \"containernetworking-plugins\")") || exit $ERR_CNI_VERSION_INVALID

os=${OS}
os_version=${UBUNTU_RELEASE}
PACKAGE_VERSIONS=()
updatePackageVersions "${cniPackage}" "${os}" "${os_version}"
if [ ${#PACKAGE_VERSIONS[@]} -eq 0 ]; then
echo "no containernetworking-plugins versions for ${os} ${os_version}"
return
fi

# Ensure exactly one containernetworking-plugins package version is present; multiple versions are not supported.
# shellcheck disable=SC3010
if [ ${#PACKAGE_VERSIONS[@]} -gt 1 ]; then
echo "WARNING: containernetworking-plugins package versions array has more than one element."
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message says "WARNING: containernetworking-plugins package versions array has more than one element" but this is actually a fatal error that exits with ERR_CNI_VERSION_INVALID. The message should say "ERROR" instead of "WARNING" to accurately reflect the severity, or alternatively, the code should gracefully handle multiple versions (e.g., by selecting the first or last version) if this is truly just a warning scenario.

Suggested change
echo "WARNING: containernetworking-plugins package versions array has more than one element."
echo "ERROR: containernetworking-plugins package versions array has more than one element."

Copilot uses AI. Check for mistakes.
exit $ERR_CNI_VERSION_INVALID
fi
packageVersion=${PACKAGE_VERSIONS[0]}

packageName="containernetworking-plugins=${packageVersion}"
echo "Installing ${packageName} with apt-get"
apt_get_install 20 30 120 ${packageName} || exit $ERR_CNI_VERSION_INVALID

mv /usr/bin/containernetworking-plugins/* $CNI_BIN_DIR

chown -R root:root $CNI_BIN_DIR
}

updateAptWithMicrosoftPkg() {
retrycmd_silent 120 5 25 curl https://packages.microsoft.com/config/ubuntu/${UBUNTU_RELEASE}/prod.list > /tmp/microsoft-prod.list || exit $ERR_MOBY_APT_LIST_TIMEOUT
retrycmd_if_failure 10 5 10 cp /tmp/microsoft-prod.list /etc/apt/sources.list.d/ || exit $ERR_MOBY_APT_LIST_TIMEOUT
Expand Down
Loading
Loading