From 8c6d46d71651065df2abd77560b25d493b6f8cc9 Mon Sep 17 00:00:00 2001 From: Carlos Matos Date: Sun, 13 Apr 2025 15:49:09 -0400 Subject: [PATCH] feat(uninstall bash): add maintenance token functionality Closes #423 This PR adds the ability to either pass a maintenance token or allow the API to retrieve it for you (assuming you have the proper scope and pass in the API creds). --- bash/install/README.md | 30 ++++++++++----- bash/install/falcon-linux-uninstall.sh | 52 +++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/bash/install/README.md b/bash/install/README.md index 5c50d7b2..22d70b0d 100644 --- a/bash/install/README.md +++ b/bash/install/README.md @@ -33,18 +33,25 @@ API clients are granted one or more API scopes. Scopes allow access to specific Ensure the following API scopes are enabled: - **Sensor Download** [read] -- (optional) **Installation Tokens** [read] - > This scope allows the installation script to retrieve a provisioning token from the API, but only if installation tokens are required in your environment. -- (optional) **Sensor update policies** [read] - > Use this scope when configuring the `FALCON_SENSOR_UPDATE_POLICY_NAME` environment variable. -- (optional) **Hosts** [write] - > Use this scope when configuring the `FALCON_REMOVE_HOST` environment variable for the uninstall script. + > Required for downloading the Falcon Sensor installation package. + +- **Installation Tokens** [read] + > Required if your environment enforces installation tokens for Falcon Sensor installation. + +- **Sensor update policies** [read] + > Required when using the `FALCON_SENSOR_UPDATE_POLICY_NAME` environment variable to specify a sensor update policy. + +- **Sensor update policies** [write] + > Required if you want the uninstall script to automatically retrieve a maintenance token from the API. + > Not needed if you directly provide the maintenance token via the `FALCON_MAINTENANCE_TOKEN` environment variable. + > Maintenance tokens are required to uninstall sensors that have uninstall protection enabled. + +- **Hosts** [write] + > Required when using the `FALCON_REMOVE_HOST=true` environment variable with the uninstall script. > > :warning: > It is recommended to use Host Retention Policies in the Falcon console instead. - - ## Configuration ### Setting up Authentication @@ -250,7 +257,7 @@ Usage: falcon-linux-uninstall.sh [-h|--help] Uninstalls the CrowdStrike Falcon Sensor from Linux operating systems. Version: 1.7.4 -The script recognizes the following environmental variables: +This script recognizes the following environmental variables: Authentication: - FALCON_CLIENT_ID (default: unset) @@ -269,6 +276,11 @@ Authentication: Accepted values are ['us-1', 'us-2', 'eu-1', 'us-gov-1']. Other Options: + - FALCON_MAINTENANCE_TOKEN (default: unset) + Sensor uninstall maintenance token used to unlock sensor uninstallation. + If not provided but FALCON_CLIENT_ID and FALCON_CLIENT_SECRET are set, + the script will try to retrieve the token from the API. + - FALCON_REMOVE_HOST (default: unset) Determines whether the host should be removed from the Falcon console after uninstalling the sensor. Requires API Authentication. diff --git a/bash/install/falcon-linux-uninstall.sh b/bash/install/falcon-linux-uninstall.sh index b30426c8..2c21531f 100755 --- a/bash/install/falcon-linux-uninstall.sh +++ b/bash/install/falcon-linux-uninstall.sh @@ -27,6 +27,11 @@ Authentication: Accepted values are ['us-1', 'us-2', 'eu-1', 'us-gov-1']. Other Options: + - FALCON_MAINTENANCE_TOKEN (default: unset) + Sensor uninstall maintenance token used to unlock sensor uninstallation. + If not provided but FALCON_CLIENT_ID and FALCON_CLIENT_SECRET are set, + the script will try to retrieve the token from the API. + - FALCON_REMOVE_HOST (default: unset) Determines whether the host should be removed from the Falcon console after uninstalling the sensor. Requires API Authentication. @@ -68,6 +73,17 @@ main() { # Check if Falcon sensor is installed cs_sensor_installed + + # Handle maintenance token + cs_maintenance_token="" + if [ -n "$FALCON_MAINTENANCE_TOKEN" ]; then + cs_maintenance_token="$FALCON_MAINTENANCE_TOKEN" + elif [ -n "$FALCON_CLIENT_ID" ] && [ -n "$FALCON_CLIENT_SECRET" ] && [ -n "$aid" ]; then + get_oauth_token + get_maintenance_token + echo "Retrieved maintenance token via API" + fi + echo -n 'Removing Falcon Sensor ... ' cs_sensor_remove echo '[ Ok ]' @@ -126,6 +142,14 @@ cs_sensor_remove() { fi } + # Handle maintenance protection + if [ -n "$cs_maintenance_token" ]; then + # shellcheck disable=SC2086 + if ! /opt/CrowdStrike/falconctl -s -f --maintenance-token=${cs_maintenance_token} >/dev/null 2>&1; then + die "Failed to apply maintenance token. Uninstallation may fail." + fi + fi + # Check for package manager lock prior to uninstallation check_package_manager_lock @@ -159,12 +183,36 @@ cs_sensor_installed() { if ! test -f /opt/CrowdStrike/falconctl; then echo "Falcon sensor is already uninstalled." && exit 0 fi - # Get AID if FALCON_REMOVE_HOST is set to true and sensor is installed - if [ "${FALCON_REMOVE_HOST}" = "true" ]; then + # Get AID if FALCON_REMOVE_HOST is set to true or if we need to get a maintenance token + if [ "${FALCON_REMOVE_HOST}" = "true" ] || [ -n "$FALCON_CLIENT_ID" ] && [ -n "$FALCON_CLIENT_SECRET" ] && [ -z "$FALCON_MAINTENANCE_TOKEN" ]; then get_aid fi } +get_maintenance_token() { + if [ -z "$aid" ]; then + die "Unable to find AID. Cannot retrieve maintenance token." + fi + + echo "Retrieving maintenance token from the CrowdStrike Falcon API..." + + payload="{\"device_id\": \"$aid\", \"audit_message\": \"CrowdStrike Falcon Uninstall Bash Script\"}" + url="https://$(cs_cloud)/policy/combined/reveal-uninstall-token/v1" + + response=$(curl_command -X "POST" -H "Content-Type: application/json" -d "$payload" "$url") + + handle_curl_error $? + + if echo "$response" | grep -q "\"uninstall_token\""; then + cs_maintenance_token=$(echo "$response" | json_value "uninstall_token" 1 | sed 's/ *$//g' | sed 's/^ *//g') + if [ -z "$cs_maintenance_token" ]; then + die "Retrieved empty maintenance token from API." + fi + else + die "Failed to retrieve maintenance token. Response: $response" + fi +} + old_curl=$( if ! command -v curl >/dev/null 2>&1; then die "The 'curl' command is missing. Please install it before continuing. Aborting..."