From 5a0b1dead10a556d475cdafade995ed7924ab154 Mon Sep 17 00:00:00 2001 From: Angel Cancino Date: Thu, 18 Mar 2021 17:16:20 -0500 Subject: [PATCH] Added support for installing on Windows the Splunk UF only --- roles/splunk/defaults/main.yml | 2 + roles/splunk/handlers/main.yml | 6 + roles/splunk/tasks/check_splunk.yml | 42 +++++- roles/splunk/tasks/check_splunk_status.yml | 8 +- .../splunk/tasks/configure_authentication.yml | 14 +- .../tasks/configure_deploymentclient.yml | 14 +- .../splunk/tasks/configure_splunk_secret.yml | 17 ++- roles/splunk/tasks/configure_user-seed.yml | 24 +++- roles/splunk/tasks/install_splunk.yml | 48 ++++++- roles/splunk/tasks/main.yml | 123 +++++++++++------- roles/splunk/tasks/post_install.yml | 54 +++++--- roles/splunk/tasks/splunk_stop.yml | 9 +- 12 files changed, 273 insertions(+), 88 deletions(-) diff --git a/roles/splunk/defaults/main.yml b/roles/splunk/defaults/main.yml index e3dfb3e9..cfd5a968 100644 --- a/roles/splunk/defaults/main.yml +++ b/roles/splunk/defaults/main.yml @@ -9,8 +9,10 @@ splunk_package_url: auto_determined # This gets set by main.yml but we have to d splunk_package_path: ~/ splunk_package_url_full: https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=linux&version=8.1.2&product=splunk&filename=splunk-8.1.2-545206cc9f70-Linux-x86_64.tgz&wget=true splunk_package_url_uf: https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=linux&version=8.1.2&product=universalforwarder&filename=splunkforwarder-8.1.2-545206cc9f70-Linux-x86_64.tgz&wget=true +splunk_package_winurl_uf: https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=windows&version=8.1.2&product=universalforwarder&filename=splunkforwarder-8.1.2-545206cc9f70-x64-release.msi&wget=true splunk_install_type: undefined # There are two ways to configure this. The easiest way is to nest hosts under either a "full" group or a "uf" group in your inventory and main.yml will handle it for you. Or, you can also set the value via a group_vars or host_vars file. splunk_install_path: /opt # Base directory on the operating system to which splunk should be installed +splunk_install_winpath: C:\Program Files # Base directory on the operating system to which splunk should be installed splunk_nix_user: splunk splunk_nix_group: splunk splunk_uri_lm: undefined diff --git a/roles/splunk/handlers/main.yml b/roles/splunk/handlers/main.yml index f6e08fb3..e4beb317 100644 --- a/roles/splunk/handlers/main.yml +++ b/roles/splunk/handlers/main.yml @@ -77,6 +77,12 @@ state: restarted become: true +- name: restart windows splunk + win_service: + name: "{{ splunk_service }}" + state: restarted + ignore_errors: True + - name: restart redhat auditd service command: service auditd condrestart become: true diff --git a/roles/splunk/tasks/check_splunk.yml b/roles/splunk/tasks/check_splunk.yml index 05ca0c12..9cd8397a 100644 --- a/roles/splunk/tasks/check_splunk.yml +++ b/roles/splunk/tasks/check_splunk.yml @@ -1,15 +1,23 @@ --- -- name: Check if Splunk is installed +- name: Linux - Check if Splunk is installed stat: path: "{{ splunk_home }}/bin/splunk" follow: true register: splunkd_path become: true + when: ansible_system == "Linux" + +- name: Windows - Check if Splunk is installed + win_stat: + path: "{{ splunk_home }}\\bin\\splunk.exe" + follow: true + register: splunkd_path + when: ansible_system == "Win32NT" # If installed, check version, if version is good, don't install but continue - name: Install Splunk if not installed include_tasks: install_splunk.yml - when: splunkd_path.stat.exists == false + when: not splunkd_path.stat.exists # Configure the license for both fresh and old installs - name: Configure license @@ -18,16 +26,28 @@ - name: Execute this block only if splunk is already installed block: - - name: Run splunk version command to check currently installed version + - name: Linux - Run splunk version command to check currently installed version command: "{{ splunk_home }}/bin/splunk version --answer-yes --auto-ports --no-prompt --accept-license" register: current_version become: true become_user: "{{ splunk_nix_user }}" changed_when: false + when: ansible_system == "Linux" + + - name: Windows - Run splunk version command to check currently installed version + win_command: | + "{{ splunk_home }}\\bin\\splunk.exe" version --answer-yes --auto-ports --no-prompt --accept-license + register: current_version + changed_when: false + when: ansible_system == "Win32NT" + + - name: Save current version in variable + set_fact: + splunk_current_version: "{{ current_version.stdout | regex_search('(\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?)') }}" - name: "Checkpoint: Version" ########################## debug: - msg: "The value of splunk_version is: {{ splunk_version }} and the current_version is: {{ current_version.stdout }}" + msg: "The value of splunk_version is: {{ splunk_v }} and the current_version is: {{ splunk_current_version }}" - name: Execute this block only if the current version does not match the expected version block: @@ -40,11 +60,19 @@ - name: Stop Splunk if not at expected version and splunk is currently running include_tasks: splunk_stop.yml - when: splunk_status.rc == 0 + when: + ( + splunk_status.rc is defined and + splunk_status.rc == 0 + ) or + ( + win_splunk_status.stderr_lines is defined and + win_splunk_status.stderr_lines | length == 0 + ) - name: Upgrade Splunk if not at expected version include_tasks: upgrade_splunk.yml # Conditional for version mismatch block - when: current_version.stdout != splunk_version + when: current_version.stdout != splunk_v # Conditional for this block - when: splunkd_path.stat.exists == true + when: splunkd_path.stat.exists diff --git a/roles/splunk/tasks/check_splunk_status.yml b/roles/splunk/tasks/check_splunk_status.yml index cf5d75a3..c4adc7f4 100644 --- a/roles/splunk/tasks/check_splunk_status.yml +++ b/roles/splunk/tasks/check_splunk_status.yml @@ -1,8 +1,14 @@ --- -- name: Check if Splunk is currently running or stopped +- name: Linux - Check if Splunk is currently running or stopped command: "{{ splunk_home }}/bin/splunk status" register: splunk_status become: true become_user: "{{ splunk_nix_user }}" failed_when: false changed_when: false + when: ansible_system == "Linux" + +- name: Windows - Get information about Splunk service + win_shell: (Get-Process -Name splunkd).Name + register: win_splunk_status + when: ansible_system == "Win32NT" diff --git a/roles/splunk/tasks/configure_authentication.yml b/roles/splunk/tasks/configure_authentication.yml index bdb97bbe..a2548627 100644 --- a/roles/splunk/tasks/configure_authentication.yml +++ b/roles/splunk/tasks/configure_authentication.yml @@ -1,5 +1,5 @@ --- -- name: Install authentication.conf for admins +- name: Linux - Install authentication.conf for admins template: src: "{{ splunk_authenticationconf }}" dest: "{{ splunk_home }}/etc/system/local/authentication.conf" @@ -9,4 +9,16 @@ when: - splunk_authenticationconf is defined - ad_bind_password != 'undefined' + - ansible_system == "Linux" notify: restart splunk + +- name: Windows - Install authentication.conf for admins + win_template: + src: "{{ splunk_authenticationconf }}" + dest: "{{ splunk_home }}\\etc\\system\\local\\authentication.conf" + owner: "{{ splunk_nix_user }}" + when: + - splunk_authenticationconf is defined + - ad_bind_password != 'undefined' + - ansible_system == "Win32NT" + notify: restart windows splunk diff --git a/roles/splunk/tasks/configure_deploymentclient.yml b/roles/splunk/tasks/configure_deploymentclient.yml index b99ad01a..0115e9ac 100644 --- a/roles/splunk/tasks/configure_deploymentclient.yml +++ b/roles/splunk/tasks/configure_deploymentclient.yml @@ -1,5 +1,5 @@ --- -- name: Create deploymentclient.conf config +- name: Linux - Create deploymentclient.conf config template: src: deploymentclient.conf.j2 dest: "{{ splunk_home }}/etc/system/local/deploymentclient.conf" @@ -10,3 +10,15 @@ when: - clientName != 'undefined' - splunk_uri_ds != 'undefined' + - ansible_system == "Linux" + +- name: Windows - Create deploymentclient.conf config + win_template: + src: deploymentclient.conf.j2 + dest: "{{ splunk_home }}\\etc\\system\\local\\deploymentclient.conf" + owner: "{{ splunk_nix_user }}" + notify: restart windows splunk + when: + - clientName != 'undefined' + - splunk_uri_ds != 'undefined' + - ansible_system == "Win32NT" diff --git a/roles/splunk/tasks/configure_splunk_secret.yml b/roles/splunk/tasks/configure_splunk_secret.yml index 4c8d0f67..200bb679 100644 --- a/roles/splunk/tasks/configure_splunk_secret.yml +++ b/roles/splunk/tasks/configure_splunk_secret.yml @@ -1,4 +1,5 @@ -- name: Install splunk.secret +--- +- name: Linux - Install splunk.secret copy: src: "{{ splunk_secret_file }}" dest: "{{ splunk_home }}/etc/auth/splunk.secret" @@ -7,4 +8,16 @@ mode: 0644 become: true notify: restart splunk - when: splunk_configure_secret + when: + - splunk_configure_secret + - ansible_system == "Linux" + +- name: Windows - Install splunk.secret + win_copy: + src: "{{ splunk_secret_file }}" + dest: "{{ splunk_home }}\\etc\\auth\\splunk.secret" + owner: "{{ splunk_nix_user }}" + notify: restart windows splunk + when: + - splunk_configure_secret + - ansible_system == "Win32NT" diff --git a/roles/splunk/tasks/configure_user-seed.yml b/roles/splunk/tasks/configure_user-seed.yml index 52a837a2..e6a86478 100644 --- a/roles/splunk/tasks/configure_user-seed.yml +++ b/roles/splunk/tasks/configure_user-seed.yml @@ -1,14 +1,21 @@ --- - name: Execute this block only when splunk_admin_password has been configured block: - - name: "Check for existing {{ splunk_home }}/etc/passwd" + - name: "Linux - Check for existing {{ splunk_home }}/etc/passwd" stat: path: "{{ splunk_home }}/etc/passwd" register: splunk_etc_passwd become: true become_user: "{{ splunk_nix_user }}" + when: ansible_system == "Linux" - - name: Create user-seed.conf file with splunk_admin_username and splunk_admin_password + - name: "Windows - Check for existing {{ splunk_home }}/etc/passwd" + win_stat: + path: "{{ splunk_home }}\\etc\\passwd" + register: splunk_etc_passwd + when: ansible_system == "Win32NT" + + - name: Linux - Create user-seed.conf file with splunk_admin_username and splunk_admin_password template: src: user-seed.conf.j2 dest: "{{ splunk_home }}/etc/system/local/user-seed.conf" @@ -16,6 +23,17 @@ group: "{{ splunk_nix_group }}" mode: 0644 become: true - when: not splunk_etc_passwd.stat.exists + when: + - not splunk_etc_passwd.stat.exists + - ansible_system == "Linux" + + - name: Windows - Create user-seed.conf file with splunk_admin_username and splunk_admin_password + win_template: + src: user-seed.conf.j2 + dest: "{{ splunk_home }}\\etc\\system\\local\\user-seed.conf" + owner: "{{ splunk_nix_user }}" + when: + - not splunk_etc_passwd.stat.exists + - ansible_system == "Win32NT" when: - splunk_admin_password != 'undefined' diff --git a/roles/splunk/tasks/install_splunk.yml b/roles/splunk/tasks/install_splunk.yml index bc8d769c..64c41b39 100644 --- a/roles/splunk/tasks/install_splunk.yml +++ b/roles/splunk/tasks/install_splunk.yml @@ -1,4 +1,27 @@ --- +- name: Windows - Save Splunk UF package name in variable + set_fact: + splunk_file: splunkforwarder-{{ splunk_package_winurl_uf | regex_search('(\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?)') }}.msi + when: ansible_system == "Win32NT" + +- name: Windows - Download Splunk UF package + get_url: + url: "{{ splunk_package_url }}" + dest: /tmp/{{ splunk_file }} + delegate_to: localhost + register: download_result + retries: 3 + delay: 10 + until: download_result is success + run_once: true + when: ansible_system == "Win32NT" + +- name: Windows - Copy Splunk UF package to managed nodes + win_copy: + src: /tmp/{{ splunk_file }} + dest: C:\\Windows\\Temp + when: ansible_system == "Win32NT" + # This task should be used for fresh installations of Splunk, refer to upgrade_splunk.yml for upgrades - name: Block for non-root splunk user setup block: @@ -7,8 +30,9 @@ name: "{{ splunk_nix_group }}" state: present become: true + when: ansible_system == "Linux" - - name: Add nix splunk user + - name: Linux - Add nix splunk user user: name: "{{ splunk_nix_user }}" groups: "{{ splunk_nix_group }}" @@ -17,20 +41,39 @@ state: present shell: /bin/bash become: true + when: ansible_system == "Linux" + + - name: Windows - Add nix splunk user + win_user: + name: "{{ splunk_nix_user }}" + password: "{{ splunk_admin_password }}" + state: present + when: ansible_system == "Win32NT" - name: Allow splunk user to read /var/log include_tasks: configure_facl.yml + when: ansible_system == "Linux" - name: Configure .bash_profile and .bashrc for splunk user include_tasks: configure_bash.yml + when: ansible_system == "Linux" + + when: splunk_nix_user not in ["root","administrator"] - when: splunk_nix_user != 'root' +- name: Windows - Install Latest Splunk Forwarder + win_package: + path: C:\\Windows\\Temp\\{{ splunk_file }} + arguments: AGREETOLICENSE=Yes SET_ADMIN_USER=0 LOGON_USERNAME="{{ ansible_hostname }}\{{ splunk_nix_user }}" LOGON_PASSWORD="{{ splunk_admin_password }}" SPLUNKUSERNAME="{{ splunk_admin_username }}" SPLUNKPASSWORD="{{ splunk_admin_password }}" /quiet + state: present + when: ansible_system == "Win32NT" - name: Configure OS to disable THP and increase ulimits for splunk process include_tasks: configure_os.yml + when: ansible_system == "Linux" - name: Include download and unarchive task include_tasks: download_and_unarchive.yml + when: ansible_system == "Linux" - name: Include configure splunk.secret task to standardize splunk.secret include_tasks: configure_splunk_secret.yml @@ -58,3 +101,4 @@ - name: Enable boot start include_tasks: configure_splunk_boot.yml + when: ansible_system == "Linux" diff --git a/roles/splunk/tasks/main.yml b/roles/splunk/tasks/main.yml index e45ac5da..188bd9a4 100644 --- a/roles/splunk/tasks/main.yml +++ b/roles/splunk/tasks/main.yml @@ -1,4 +1,9 @@ --- +- name: Gather essential facts + setup: + gather_subset: min + when: ansible_system is not defined + - block: - name: Configure vars for full package tags: always @@ -15,77 +20,97 @@ follow: true register: systemd_boot_full become: true - when: "'full' in group_names" + when: + - "'full' in group_names" + - ansible_system == "Linux" - block: - - name: Configure vars for uf package + - name: Configure cross platform vars for uf package tags: always set_fact: - splunk_home: "{{ splunk_install_path }}/splunkforwarder" - splunk_package_url: "{{ splunk_package_url_uf }}" splunk_product: "Splunk Universal Forwarder" splunk_install_type: uf changed_when: false + - name: Linux - Configure vars for uf package + tags: always + set_fact: + splunk_home: "{{ splunk_install_path }}/splunkforwarder" + splunk_package_url: "{{ splunk_package_url_uf }}" + changed_when: false + when: ansible_system == "Linux" + + - name: Windows - Configure vars for uf package + tags: always + set_fact: + splunk_home: "{{ splunk_install_winpath }}\\SplunkUniversalForwarder" + splunk_package_url: "{{ splunk_package_winurl_uf }}" + splunk_service: SplunkForwarder + changed_when: false + when: ansible_system == "Win32NT" + - name: Check if current boot-start configuration is systemd stat: path: /etc/systemd/system/SplunkForwarder.service follow: true register: systemd_boot_uf become: true + when: ansible_system == "Linux" when: "'uf' in group_names" -- name: Set systemd_boot var to true if systemd is being used for splunk - set_fact: - systemd_boot: true - when: (systemd_boot_uf.stat is defined and systemd_boot_uf.stat.exists) or (systemd_boot_full.stat is defined and systemd_boot_full.stat.exists) +- block: + - name: Set systemd_boot var to true if systemd is being used for splunk + set_fact: + systemd_boot: true + when: (systemd_boot_uf.stat is defined and systemd_boot_uf.stat.exists) or (systemd_boot_full.stat is defined and systemd_boot_full.stat.exists) -- name: Check if current boot-start method is init.d - stat: - path: /etc/init.d/splunk - follow: true - register: initd_boot - become: true + - name: Check if current boot-start method is init.d + stat: + path: /etc/init.d/splunk + follow: true + register: initd_boot + become: true -- name: Check if Splunk is installed when no boot-start config has been found - stat: - path: "{{ splunk_home }}/bin/splunk" - follow: true - register: splunkd_found - become: true + - name: Check if Splunk is installed when no boot-start config has been found + stat: + path: "{{ splunk_home }}/bin/splunk" + follow: true + register: splunkd_found + become: true -- name: Fail the play if the currently configured boot-start method does match the expected state or boot-start is not enabled - fail: - msg: - - "ERROR: Misconfiguration detected! Unable to proceed as handlers will fail in the play later." - - "Either splunk boot-start is not enabled on this host, or its current boot-start method does not matched the expected value of splunk_use_initd." - - "To correct this: Either run configure_splunk_boot.yml or update the value of splunk_use_initd in your group_vars." - when: - - splunkd_found.stat.exists - - (systemd_boot and splunk_use_initd) or (initd_boot.stat.exists and not splunk_use_initd) or (not systemd_boot and not initd_boot.stat.exists) - - not deployment_task == "configure_splunk_boot.yml" + - name: Fail the play if the currently configured boot-start method does match the expected state or boot-start is not enabled + fail: + msg: + - "ERROR: Misconfiguration detected! Unable to proceed as handlers will fail in the play later." + - "Either splunk boot-start is not enabled on this host, or its current boot-start method does not matched the expected value of splunk_use_initd." + - "To correct this: Either run configure_splunk_boot.yml or update the value of splunk_use_initd in your group_vars." + when: + - splunkd_found.stat.exists + - (systemd_boot and splunk_use_initd) or (initd_boot.stat.exists and not splunk_use_initd) or (not systemd_boot and not initd_boot.stat.exists) + - not deployment_task == "configure_splunk_boot.yml" -- name: Configure var for splunk init.d service handler - tags: always - set_fact: - splunk_service: splunk - when: splunk_use_initd + - name: Configure var for splunk init.d service handler + tags: always + set_fact: + splunk_service: splunk + when: splunk_use_initd -- name: Configure var for splunk systemd service handler - tags: always - set_fact: - splunk_service: Splunkd - when: - - not splunk_use_initd - - "'full' in group_names" + - name: Configure var for splunk systemd service handler + tags: always + set_fact: + splunk_service: Splunkd + when: + - not splunk_use_initd + - "'full' in group_names" -- name: Configure var for splunkforwarder systemd service handler - tags: always - set_fact: - splunk_service: SplunkForwarder - when: - - not splunk_use_initd - - "'uf' in group_names" + - name: Configure var for splunkforwarder systemd service handler + tags: always + set_fact: + splunk_service: SplunkForwarder + when: + - not splunk_use_initd + - "'uf' in group_names" + when: ansible_system == "Linux" - name: Send Slack messages include_tasks: slack_messenger.yml diff --git a/roles/splunk/tasks/post_install.yml b/roles/splunk/tasks/post_install.yml index 8c52a021..3a1d9469 100644 --- a/roles/splunk/tasks/post_install.yml +++ b/roles/splunk/tasks/post_install.yml @@ -1,32 +1,44 @@ --- -- name: Touch .ui_login file to disable first-time login prompt +- name: Linux - Touch .ui_login file to disable first-time login prompt file: dest: "{{ splunk_home }}/etc/.ui_login" state: touch become: true become_user: "{{ splunk_nix_user }}" - when: "'full' in group_names" + when: + - ansible_system == "Linux" + - "'full' in group_names" -- name: "Ensure correct ownership for {{ splunk_home }}/etc" - file: - path: "{{ splunk_home }}/etc" - owner: "{{ splunk_nix_user }}" - group: "{{ splunk_nix_group }}" - recurse: true - become: true +- name: Windows - Touch .ui_login file to disable first-time login prompt + win_file: + path: "{{ splunk_home }}\\etc\\.ui_login" + state: touch + when: + - ansible_system == "Win32NT" + - "'full' in group_names" + +- block: + - name: "Ensure correct ownership for {{ splunk_home }}/etc" + file: + path: "{{ splunk_home }}/etc" + owner: "{{ splunk_nix_user }}" + group: "{{ splunk_nix_group }}" + recurse: true + become: true -- name: Configure cron job to cleanup crash logs older than 7 days - include_tasks: add_crashlog_script.yml - when: add_crashlog_script + - name: Configure cron job to cleanup crash logs older than 7 days + include_tasks: add_crashlog_script.yml + when: add_crashlog_script -- name: Configure cron job to cleanup diags older than 30 days - include_tasks: add_diag_script.yml - when: add_diag_script + - name: Configure cron job to cleanup diags older than 30 days + include_tasks: add_diag_script.yml + when: add_diag_script -- name: Install pstack shell script for troubleshooting purposes - include_tasks: add_pstack_script.yml - when: add_pstack_script + - name: Install pstack shell script for troubleshooting purposes + include_tasks: add_pstack_script.yml + when: add_pstack_script -- name: Install additional utilities and troubleshooting tools - include_tasks: install_utilities.yml - when: install_utilities + - name: Install additional utilities and troubleshooting tools + include_tasks: install_utilities.yml + when: install_utilities + when: ansible_system == "Linux" \ No newline at end of file diff --git a/roles/splunk/tasks/splunk_stop.yml b/roles/splunk/tasks/splunk_stop.yml index 06f07252..c7bdb36f 100644 --- a/roles/splunk/tasks/splunk_stop.yml +++ b/roles/splunk/tasks/splunk_stop.yml @@ -1,6 +1,13 @@ --- -- name: Stop splunk +- name: Linux - Stop splunk service: name: "{{ splunk_service }}" state: stopped become: true + when: ansible_system == "Linux" + +- name: Windows - Stop splunk + win_service: + name: "{{ splunk_service }}" + state: stopped + when: ansible_system == "Win32NT"