CrowdStrike / ansible_collection_falcon

Comprehensive toolkit for streamlining your interactions with the CrowdStrike Falcon platform.
https://galaxy.ansible.com/ui/repo/published/crowdstrike/falcon/
GNU General Public License v3.0
97 stars 61 forks source link

falcon_install deletes RPM before installing it when run against localhost #578

Open nhinds opened 4 days ago

nhinds commented 4 days ago

When running version 4.7.1 of the crowdstrike.falcon.falcon_install role against a localhost inventory, the RPM gets deleted before it is installed.

It seems like #569 changed the defaults so that location the RPM is downloaded to on the controller (falcon_api_sensor_download_path) and the location the RPM is copied to on the Linux target machine (falcon_install_tmp_dir) are both /tmp/falcon-sensor. When run against an inventory of localhost (i.e. when using Ansible to install Falcon on the current machine), this results in:

  1. "Download Falcon Sensor Installation Package (local)" downloads the RPM to /tmp/falcon-sensor/falcon-sensor-*.rpm
  2. "Copy Sensor Installation Package to remote host (non-windows)" is a no-op, as /tmp/falcon-sensor/falcon-sensor-*.rpm is copied to itself
  3. "Remove Downloaded Sensor Installation directory (local)" deletes /tmp/falcon-sensor/falcon-sensor-*.rpm
  4. "Install Falcon Sensor Package (Linux)" fails to install the RPM, as it has been deleted
TASK [crowdstrike.falcon.falcon_install : ansible.builtin.include_tasks] ******* 
included: /tmp/ansible/ansible_collections/crowdstrike/falcon/roles/falcon_install/tasks/preinstall.yml for localhost 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate Required API URL Is Defined] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate CrowdStrike API Client ID Is Defined] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate CrowdStrike API Client Secret Is Defined] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate CrowdStrike Falcon Sensor version decrement is correctly set] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate CID is defined (non-api)] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Configure Python Interpreter for older Linux OSes] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Default Operating System configuration] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Determine Operating System Architecture (Linux)] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Determine if Endpoint Operating System Is RHEL, CentOS, or Oracle Linux] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Determine if Endpoint Operating System Is SLES] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Determine if Target OS Is Amazon Linux] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Determine if Target OS Is MacOS] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Endpoint Operating System Detected Is Microsoft Windows] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Ensure Temporary Install Directory Exists (non-Windows)] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Ensure Temporary Install Directory Exists (Windows)] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate Temporary install directory (Windows)] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Verify Falcon is not already installed (macOS)] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Override falcon_sensor_version_decrement when falcon_sensor_update_policy_name or falcon_sensor_version set] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Override falcon_sensor_version when set] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : ansible.builtin.include_tasks] ******* 
included: /tmp/ansible/ansible_collections/crowdstrike/falcon/roles/falcon_install/tasks/auth.yml for localhost 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Authenticate to CrowdStrike API] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Detect Target CID Based on Credentials] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Set CID received from API] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : ansible.builtin.include_tasks] ******* 
included: /tmp/ansible/ansible_collections/crowdstrike/falcon/roles/falcon_install/tasks/api.yml for localhost 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Build Sensor Update Policy API Query] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Search for Sensor Update Policy] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate Sensor Update Policy request] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate Sensor Update Policy request for aarch64 architectures] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Get the Falcon Sensor version from Update Policy] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Get the Falcon Sensor version from Update Policy for aarch64 architecture] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Override falcon_sensor_version with version from Sensor Update Policy] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Build API Sensor Query] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Get list of filtered Falcon sensors] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Validate Sensor request] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Ensure download path exists (local)] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Download Falcon Sensor Installation Package (local)] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Copy Sensor Installation Package to remote host (non-windows)] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Copy Sensor Installation Package to remote host (windows)] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Remove Downloaded Sensor Installation directory (local)] *** 
ok: [localhost] => (item=/tmp/falcon-sensor/falcon-sensor-7.19.0-17219.amzn2023.x86_64.rpm) 
ok: [localhost] => (item=/tmp/falcon-sensor/falcon-sensor-7.19.0-17219.amzn2023.x86_64.rpm.lock) 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Set full file download path (non-windows)] *** 
ok: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Set full file download path (windows)] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : ansible.builtin.include_tasks] ******* 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : ansible.builtin.include_tasks] ******* 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : ansible.builtin.include_tasks] ******* 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : ansible.builtin.include_tasks] ******* 
included: /tmp/ansible/ansible_collections/crowdstrike/falcon/roles/falcon_install/tasks/install.yml for localhost 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Set default sensor name] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Transfer CrowdStrike Falcon RPM GPG key files] *** 
ok: [localhost] => (item=falcon-sensor.gpg) 
ok: [localhost] => (item=falcon-sensor1.gpg) 
ok: [localhost] => (item=falcon-sensor2.gpg) 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Import CrowdStrike Falcon RPM GPG key from files] *** 
ok: [localhost] => (item=falcon-sensor.gpg) 
ok: [localhost] => (item=falcon-sensor1.gpg) 
ok: [localhost] => (item=falcon-sensor2.gpg) 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Import CrowdStrike Falcon APT GPG key from file] *** 
skipping: [localhost] 

TASK [crowdstrike.falcon.falcon_install : CrowdStrike Falcon | Install Falcon Sensor Package (Linux)] *** 
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: OSError: Could not open: /tmp/falcon-sensor/falcon-sensor-7.19.0-17219.amzn2023.x86_64.rpm 
fatal: [localhost]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-tmp-1732752470.8024106-27795-254568391292512/AnsiballZ_dnf.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-tmp-1732752470.8024106-27795-254568391292512/AnsiballZ_dnf.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-tmp-1732752470.8024106-27795-254568391292512/AnsiballZ_dnf.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible.modules.dnf', init_globals=dict(_module_fqn='ansible.modules.dnf', _modlib_path=modlib_path),\n  File \"/usr/lib64/python3.9/runpy.py\", line 225, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib64/python3.9/runpy.py\", line 97, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib64/python3.9/runpy.py\", line 87, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_ansible.legacy.dnf_payload_5ixu3dln/ansible_ansible.legacy.dnf_payload.zip/ansible/modules/dnf.py\", line 1481, in <module>\n  File \"/tmp/ansible_ansible.legacy.dnf_payload_5ixu3dln/ansible_ansible.legacy.dnf_payload.zip/ansible/modules/dnf.py\", line 1470, in main\n  File \"/tmp/ansible_ansible.legacy.dnf_payload_5ixu3dln/ansible_ansible.legacy.dnf_payload.zip/ansible/modules/dnf.py\", line 1443, in run\n  File \"/tmp/ansible_ansible.legacy.dnf_payload_5ixu3dln/ansible_ansible.legacy.dnf_payload.zip/ansible/modules/dnf.py\", line 1088, in ensure\n  File \"/tmp/ansible_ansible.legacy.dnf_payload_5ixu3dln/ansible_ansible.legacy.dnf_payload.zip/ansible/modules/dnf.py\", line 988, in _install_remote_rpms\n  File \"/usr/lib/python3.9/site-packages/dnf/base.py\", line 1341, in add_remote_rpms\n    raise IOError(_(\"Could not open: {}\").format(' '.join(pkgs_error)))\nOSError: Could not open: /tmp/falcon-sensor/falcon-sensor-7.19.0-17219.amzn2023.x86_64.rpm\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1} 

PLAY RECAP ********************************************************************* 
localhost                  : ok=38   changed=5    unreachable=0    failed=1    skipped=28   rescued=0    ignored=0 

Overriding falcon_api_sensor_download_path so it is different than falcon_install_tmp_dir (e.g. falcon_api_sensor_download_path: "/tmp/falcon-sensor-download") allows the installation to succeed.

carlosmmatos commented 2 days ago

@nhinds thanks for opening up this issue! You are absolutely correct and that was an oversight on our part.

Glad you found a workaround, you could also set falcon_api_sensor_download_cleanup: false as well to prevent the deletion.

I think we need to consider moving the deletion operation towards the end of the role after the sensor actually get's installed, whether remote or locally to prevent this situation. Will look into a PR next week.