Skip to content
Merged
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
57 changes: 49 additions & 8 deletions bash/containers/falcon-container-sensor-pull/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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**
Expand Down Expand Up @@ -100,6 +111,7 @@ Optional Flags:
-----------------------
falcon-container
falcon-sensor
falcon-sensor-regional
falcon-kac
falcon-snapshot
falcon-imageanalyzer
Expand Down Expand Up @@ -138,7 +150,7 @@ Help Options:
| `-c`, `--copy <REGISTRY/NAMESPACE>` | `$COPY` | `None` (Optional) | Registry you want to copy the sensor image to. Example: `myregistry.com/mynamespace`. <br> *\*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>` | `$SENSOR_VERSION` | `None` (Optional) | Specify sensor version to retrieve from the registry |
| `-p`, `--platform <SENSOR_PLATFORM>` | `$SENSOR_PLATFORM` | `None` (Optional) | Specify sensor platform to retrieve from the registry |
| `-t`, `--type <SENSOR_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>` | `$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`. |
Expand All @@ -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 |
Expand All @@ -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 \
Expand All @@ -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 <FALCON_CLIENT_ID> \
--client-secret <FALCON_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 <FALCON_CLIENT_ID> \
--client-secret <FALCON_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 <FALCON_CLIENT_ID> \
--client-secret <FALCON_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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Optional Flags:
-----------------------
falcon-container
falcon-sensor
falcon-sensor-regional
falcon-kac
falcon-snapshot
falcon-imageanalyzer
Expand Down Expand Up @@ -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)
Expand All @@ -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:]')

Expand Down Expand Up @@ -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
Expand All @@ -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"
{
Expand Down Expand Up @@ -536,16 +605,28 @@ 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
FALCON_CLOUD="${region_hint}"
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"
Expand Down Expand Up @@ -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}"
Expand Down