diff --git a/bash/containers/falcon-container-sensor-pull/README.md b/bash/containers/falcon-container-sensor-pull/README.md index e6953b1..61070c3 100644 --- a/bash/containers/falcon-container-sensor-pull/README.md +++ b/bash/containers/falcon-container-sensor-pull/README.md @@ -10,6 +10,7 @@ Please refer to the [Deprecation](DEPRECATION.md) document for more information - [Table of Contents](#table-of-contents) - [Multi-Architecture Support :rocket:](#multi-architecture-support-rocket) +- [Unified Falcon Sensor Image Support](#unified-falcon-sensor-image-support) - [Security recommendations](#security-recommendations) - [Prerequisites](#prerequisites) - [Auto-Discovery of Falcon Cloud Region](#auto-discovery-of-falcon-cloud-region) @@ -35,6 +36,16 @@ Refer to the [examples](#examples) section for more information on how to use th > [!NOTE] > While we do support copying the multi-arch image to a different registry using Podman, Docker, or Skopeo, we recommend using Skopeo for this purpose. Skopeo is a tool specifically designed for copying container images between registries and supports multi-arch images. +## Unified Falcon Sensor Image Support + +Starting with Falcon sensor for Linux version 7.31 and above, CrowdStrike has introduced a new unified Falcon sensor that utilizes a single container image as opposed to the regional based sensors. + + +For additional context and information, please see the [Tech Alert](https://supportportal.crowdstrike.com/s/article/Tech-Alert-60-day-notice-Unified-installer-image-for-Falcon-sensor-for-Linux). + +> [!IMPORTANT] +> **Backward Compatibility**: Existing users of the `falcon-sensor` type will now automatically receive the new unified sensor. If you need to maintain the traditional regional sensor for any reason, simply change `-t falcon-sensor` to `-t falcon-sensor-regional` in your commands. No other changes to your scripts or workflows are required. + ## Security recommendations ### Use cURL version 7.55.0 or later @@ -55,7 +66,7 @@ To check your version of cURL, run the following command: `curl --version` > [!IMPORTANT] > The following API scopes are the minimum required to retrieve the images. If you need to perform other operations post-retrieval, please refer to the CrowdStrike documentation to identify any additional scopes that may be required. -- **falcon-sensor | falcon-container | falcon-kac | falcon-imageanalyzer | falcon-jobcontroller | falcon-registryassessmentexecutor** +- **falcon-sensor | falcon-sensor-regional | falcon-container | falcon-kac | falcon-imageanalyzer | falcon-jobcontroller | falcon-registryassessmentexecutor** - `Sensor Download (read)` - `Falcon Images Download (read)` - **kpagent** @@ -100,6 +111,7 @@ Optional Flags: ----------------------- falcon-container falcon-sensor + falcon-sensor-regional falcon-kac falcon-snapshot falcon-imageanalyzer @@ -138,7 +150,7 @@ Help Options: | `-c`, `--copy ` | `$COPY` | `None` (Optional) | Registry you want to copy the sensor image to. Example: `myregistry.com/mynamespace`.
*\*By default, the image name and tag are appended. Use `--copy-omit-image-name` and/or `--copy-custom-tag` to change that behavior.* | | `-v`, `--version ` | `$SENSOR_VERSION` | `None` (Optional) | Specify sensor version to retrieve from the registry | | `-p`, `--platform ` | `$SENSOR_PLATFORM` | `None` (Optional) | Specify sensor platform to retrieve from the registry | -| `-t`, `--type ` | `$SENSOR_TYPE` | `falcon-container` (Optional) | Specify which sensor to download [`falcon-container`, `falcon-sensor`, `falcon-kac`, `falcon-snapshot`, `falcon-imageanalyzer`, `kpagent`, `fcs`, `falcon-jobcontroller`, `falcon-registryassessmentexecutor`] ([see more details below](#sensor-types)) | +| `-t`, `--type ` | `$SENSOR_TYPE` | `falcon-container` (Optional) | Specify which sensor to download [`falcon-container`, `falcon-sensor`, `falcon-sensor-regional`, `falcon-kac`, `falcon-snapshot`, `falcon-imageanalyzer`, `kpagent`, `fcs`, `falcon-jobcontroller`, `falcon-registryassessmentexecutor`] ([see more details below](#sensor-types)) | | `--runtime` | `$CONTAINER_TOOL` | `docker` (Optional) | Use a different container runtime [docker, podman, skopeo]. **Default is Docker**. | | `--dump-credentials` | `$CREDS` | `False` (Optional) | Print registry credentials to stdout to copy/paste into container tools | | `--get-image-path` | N/A | `None` | Get the full image path including the registry, repository, and latest tag for the specified `SENSOR_TYPE`. | @@ -165,7 +177,8 @@ The following sensor types are available to download: | Sensor Image Name | Description | | :---------------------------------- | :---------------------------------------------------- | -| `falcon-sensor` | The Falcon sensor for Linux as a DaemonSet deployment | +| `falcon-sensor` | The Falcon sensor for Linux as a DaemonSet deployment (unified - version 7.31+) | +| `falcon-sensor-regional` | The Falcon sensor for Linux as a DaemonSet deployment w/ regions (traditional) | | `falcon-container` **(default)** | The Falcon Container sensor for Linux | | `falcon-kac` | The Falcon Kubernetes Admission Controller | | `falcon-snapshot` | The Falcon Snapshot scanner | @@ -188,9 +201,9 @@ The following example will attempt to autodiscover the region and download the l --type falcon-kac ``` -#### Example getting the full image path for the Falcon DaemonSet sensor +#### Example getting the full image path for the Falcon DaemonSet sensor (unified) -The following example will print the image repository path with the latest image tag of the Falcon DaemonSet sensor. +The following example will print the image repository path with the latest image tag of the Falcon DaemonSet sensor using the new unified sensor. ```shell ./falcon-container-sensor-pull.sh \ @@ -200,19 +213,47 @@ The following example will print the image repository path with the latest image --get-image-path ``` -#### Example downloading the Falcon DaemonSet sensor +Example output: `registry.crowdstrike.com/falcon-sensor/release/falcon-sensor:7.31.0-15501-1` + +#### Example getting the full image path for the Falcon DaemonSet sensor (regional) -The following example will download the latest version of the Falcon DaemonSet sensor container image and copy it to another registry. +The following example will print the image repository path with the latest image tag of the Falcon DaemonSet sensor using the traditional regional sensor. + +```shell +./falcon-container-sensor-pull.sh \ +--client-id \ +--client-secret \ +--type falcon-sensor-regional \ +--get-image-path +``` + +Example output: `registry.crowdstrike.com/falcon-sensor/us-1/release/falcon-sensor:7.29.0-15501-1.falcon-linux.Release.US-1` + +#### Example downloading the Falcon DaemonSet sensor (unified) + +The following example will download the latest version of the Falcon DaemonSet sensor container image using the unified sensor and copy it to another registry. ```shell ./falcon-container-sensor-pull.sh \ --client-id \ --client-secret \ ---region us-2 \ --type falcon-sensor \ --copy myregistry.com/mynamespace ``` +#### Example downloading the Falcon DaemonSet sensor (regional) + +The following example will download the latest version of the Falcon DaemonSet sensor container image using the regional sensor and copy it to another registry. + +```shell +./falcon-container-sensor-pull.sh \ +--client-id \ +--client-secret \ +--region us-2 \ +--type falcon-sensor-regional \ +--copy myregistry.com/mynamespace +``` + #### Example generating a pull token for K8s The following example will generate a pull token for the Falcon Container sensor for use in Kubernetes. diff --git a/bash/containers/falcon-container-sensor-pull/falcon-container-sensor-pull.sh b/bash/containers/falcon-container-sensor-pull/falcon-container-sensor-pull.sh index 039a90c..ff7995b 100755 --- a/bash/containers/falcon-container-sensor-pull/falcon-container-sensor-pull.sh +++ b/bash/containers/falcon-container-sensor-pull/falcon-container-sensor-pull.sh @@ -30,6 +30,7 @@ Optional Flags: ----------------------- falcon-container falcon-sensor + falcon-sensor-regional falcon-kac falcon-snapshot falcon-imageanalyzer @@ -443,7 +444,7 @@ detect_container_tool() { display_api_scopes() { local sensor_type=$1 case "${sensor_type}" in - falcon-sensor | falcon-container | falcon-kac | falcon-imageanalyzer | falcon-jobcontroller | falcon-registryassessmentexecutor) + falcon-sensor | falcon-sensor-regional | falcon-container | falcon-kac | falcon-imageanalyzer | falcon-jobcontroller | falcon-registryassessmentexecutor) echo "Sensor Download [read], Falcon Images Download [read]" ;; kpagent) @@ -461,6 +462,68 @@ display_api_scopes() { esac } +# Smart version matching function +match_sensor_version() { + local requested_version="$1" + local all_tags + local matched_tags + local version_pattern + + # Get all available tags by properly parsing JSON output from list_tags + all_tags=$(list_tags | awk ' + /^[[:space:]]*"[0-9]/ { + # Extract quoted tag (lines starting with version numbers), remove surrounding quotes and whitespace + gsub(/^[[:space:]]*"/, "") + gsub(/"[[:space:]]*,?[[:space:]]*$/, "") + if (length($0) > 0) print $0 + } + ') + + if [ -z "$requested_version" ]; then + # If no version specified, get the latest version + if [ -n "$all_tags" ]; then + echo "$all_tags" | sort -V | tail -1 + return 0 + else + return 1 + fi + fi + + # First try: exact version match (e.g., 6.35.0 matches 6.35.0-*) + version_pattern="^${requested_version}[.-]" + matched_tags=$(echo "$all_tags" | grep -E "$version_pattern") + + if [ -n "$matched_tags" ]; then + echo "$matched_tags" | sort -V | tail -1 + return 0 + fi + + # Second try: partial version match (e.g., 6.35 matches 6.35.* versions) + # Count dots in requested version to determine specificity + dot_count=$(echo "$requested_version" | tr -cd '.' | wc -c) + + if [ "$dot_count" -eq 1 ]; then + # For major.minor (e.g., 6.35), match 6.35.* versions + version_pattern="^${requested_version}\.[0-9]" + matched_tags=$(echo "$all_tags" | grep -E "$version_pattern") + elif [ "$dot_count" -eq 0 ]; then + # For major only (e.g., 6), match 6.* versions + version_pattern="^${requested_version}\.[0-9]" + matched_tags=$(echo "$all_tags" | grep -E "$version_pattern") + else + # For more specific versions, try prefix matching + matched_tags=$(echo "$all_tags" | grep "^${requested_version}") + fi + + if [ -n "$matched_tags" ]; then + echo "$matched_tags" | sort -V | tail -1 + return 0 + fi + + # No matches found - fail explicitly + return 1 +} + # shellcheck disable=SC2086 FALCON_CLOUD=$(echo ${FALCON_CLOUD:-'us-1'} | tr '[:upper:]' '[:lower:]') @@ -489,12 +552,13 @@ fi # Check if SENSOR_TYPE is set to a valid value case "${SENSOR_TYPE}" in - falcon-container | falcon-sensor | falcon-kac | falcon-snapshot | falcon-imageanalyzer | kpagent | fcs | falcon-jobcontroller | falcon-registryassessmentexecutor) ;; + falcon-container | falcon-sensor | falcon-sensor-regional | falcon-kac | falcon-snapshot | falcon-imageanalyzer | kpagent | fcs | falcon-jobcontroller | falcon-registryassessmentexecutor) ;; *) die """ Unrecognized sensor type: ${SENSOR_TYPE} Valid values are: falcon-container falcon-sensor + falcon-sensor-regional falcon-kac falcon-snapshot falcon-imageanalyzer @@ -504,6 +568,11 @@ case "${SENSOR_TYPE}" in falcon-registryassessmentexecutor""" ;; esac +# Add deprecation warning for falcon-sensor-regional +if [ "${SENSOR_TYPE}" = "falcon-sensor-regional" ]; then + echo "WARNING: Use 'falcon-sensor' for the new unified sensor image as the regional sensor images will eventually be EOL." +fi + #Check all mandatory variables set VARIABLES="FALCON_CLIENT_ID FALCON_CLIENT_SECRET" { @@ -536,7 +605,7 @@ cs_falcon_oauth_token=$( region_hint=$(grep -i ^x-cs-region: "$response_headers" | head -n 1 | tr '[:upper:]' '[:lower:]' | tr -d '\r' | sed 's/^x-cs-region: //g') rm "${response_headers}" -if [ "x${FALCON_CLOUD}" != "x${region_hint}" ] && [ "${region_hint}" != "" ]; then +if [ "${FALCON_CLOUD}" != "${region_hint}" ] && [ -n "${region_hint}" ]; then if [ -z "${region_hint}" ]; then die "Unable to obtain region hint from CrowdStrike Falcon OAuth API, Please provide FALCON_CLOUD environment variable as an override." fi @@ -544,8 +613,20 @@ if [ "x${FALCON_CLOUD}" != "x${region_hint}" ] && [ "${region_hint}" != "" ]; th fi registry_opts=$( - # Account for govcloud api mismatch - if [ "${FALCON_CLOUD}" = "us-gov-1" ]; then + # Handle unified falcon-sensor format (no region) + if [ "${SENSOR_TYPE}" = "falcon-sensor" ]; then + echo "falcon-sensor" + # Handle falcon-sensor-regional with traditional regional paths + elif [ "${SENSOR_TYPE}" = "falcon-sensor-regional" ]; then + if [ "${FALCON_CLOUD}" = "us-gov-1" ]; then + echo "falcon-sensor/gov1" + elif [ "${FALCON_CLOUD}" = "us-gov-2" ]; then + echo "falcon-sensor/gov2" + else + echo "falcon-sensor/$FALCON_CLOUD" + fi + # Account for govcloud api mismatch for other sensor types + elif [ "${FALCON_CLOUD}" = "us-gov-1" ]; then echo "$SENSOR_TYPE/gov1" elif [ "${FALCON_CLOUD}" = "us-gov-2" ]; then echo "$SENSOR_TYPE/gov2" @@ -738,7 +819,22 @@ if [ "${ERROR}" = "true" ]; then fi #Get latest sensor version -LATESTSENSOR=$(list_tags | awk -v RS=" " '{print}' | grep -i "$SENSOR_VERSION" | grep -o "[0-9a-zA-Z_\.\-]*" | tail -1) +set +e # Temporarily disable exit-on-error for version matching +LATESTSENSOR=$(match_sensor_version "$SENSOR_VERSION") +set -e # Re-enable exit-on-error + +# Check if version matching was successful +if [ -z "$LATESTSENSOR" ]; then + die "No sensor version found matching: ${SENSOR_VERSION} + +Available versions can be listed with: $0 --list-tags -t ${SENSOR_TYPE} + +Tips for version matching: + - Use exact version: -v 7.31.0 + - Use partial version: -v 7.31 (matches latest 7.31.x) + - Use major version: -v 7 (matches latest 7.x.x) + - Omit -v flag to get the latest available version" +fi #Construct full image path FULLIMAGEPATH="${REPOSITORY}:${LATESTSENSOR}"