diff --git a/salt/fleet/event_gen-packages.sls b/salt/fleet/event_gen-packages.sls index 11a3d9a0a..72c02be45 100644 --- a/salt/fleet/event_gen-packages.sls +++ b/salt/fleet/event_gen-packages.sls @@ -2,12 +2,19 @@ {% set ENROLLSECRET = salt['pillar.get']('secrets:fleet_enroll-secret') %} {% set CURRENTPACKAGEVERSION = salt['pillar.get']('static:fleet_packages-version') %} {% set VERSION = salt['pillar.get']('static:soversion') %} +{% set CUSTOM_FLEET_HOSTNAME = salt['pillar.get']('static:fleet_custom_hostname', None) %} + +{% if CUSTOM_FLEET_HOSTNAME != None %} + {% set HOSTNAME = {{ CUSTOM_FLEET_HOSTNAME }} %} +{% else %} + {% set HOSTNAME = {{ grains.host }} %} +{% endif %} so/fleet: event.send: - data: action: 'genpackages' - hostname: {{ grains.host }} + package-hostname: {{ HOSTNAME }} role: {{ grains.role }} mainip: {{ grains.host }} enroll-secret: {{ ENROLLSECRET }} diff --git a/salt/fleet/event_update-custom-hostname.sls b/salt/fleet/event_update-custom-hostname.sls new file mode 100644 index 000000000..9278862ed --- /dev/null +++ b/salt/fleet/event_update-custom-hostname.sls @@ -0,0 +1,9 @@ +{% set CUSTOM_FLEET_HOSTNAME = salt['pillar.get']('static:fleet_custom_hostname', None) %} + +so/fleet: + event.send: + - data: + action: 'update_custom_hostname' + custom_hostname: {{ CUSTOM_FLEET_HOSTNAME }} + role: {{ grains.role }} + \ No newline at end of file diff --git a/salt/reactor/fleet.sls b/salt/reactor/fleet.sls index 2e929c59e..c7bade3ab 100644 --- a/salt/reactor/fleet.sls +++ b/salt/reactor/fleet.sls @@ -9,10 +9,6 @@ import subprocess def run(): MINIONID = data['id'] ACTION = data['data']['action'] - HOSTNAME = data['data']['hostname'] - ROLE = data['data']['role'] - ESECRET = data['data']['enroll-secret'] - MAINIP = data['data']['mainip'] STATICFILE = '/opt/so/saltstack/pillar/static.sls' SECRETSFILE = '/opt/so/saltstack/pillar/secrets.sls' @@ -21,6 +17,11 @@ def run(): if ACTION == 'enablefleet': logging.info('so/fleet enablefleet reactor') + ESECRET = data['data']['enroll-secret'] + MAINIP = data['data']['mainip'] + ROLE = data['data']['role'] + HOSTNAME = data['data']['hostname'] + # Enable Fleet for line in fileinput.input(STATICFILE, inplace=True): if ROLE == 'so-fleet': @@ -48,8 +49,10 @@ def run(): logging.info('so/fleet genpackages reactor') PACKAGEVERSION = data['data']['current-package-version'] + PACKAGEHOSTNAME = data['data']['package-hostname'] MASTER = data['data']['master'] VERSION = data['data']['version'] + ESECRET = data['data']['enroll-secret'] # Increment the package version by 1 PACKAGEVERSION += 1 @@ -57,7 +60,7 @@ def run(): # Run Docker container that will build the packages gen_packages = subprocess.run(["docker", "run","--rm", "--mount", "type=bind,source=/opt/so/saltstack/salt/fleet/packages,target=/output", \ "--mount", "type=bind,source=/etc/ssl/certs/intca.crt,target=/var/launcher/launcher.crt", f"{ MASTER }:5000/soshybridhunter/so-fleet-launcher:{ VERSION }", \ - f"{ESECRET}", f"{HOSTNAME}:8090", f"{PACKAGEVERSION}.1.1"], stdout=subprocess.PIPE, encoding='ascii') + f"{ESECRET}", f"{PACKAGEHOSTNAME}:8090", f"{PACKAGEVERSION}.1.1"], stdout=subprocess.PIPE, encoding='ascii') # Update the 'packages-built' timestamp on the webpage (stored in the static pillar) for line in fileinput.input(STATICFILE, inplace=True): @@ -70,6 +73,16 @@ def run(): print(line) # Copy over newly-built packages - copy_packages = subprocess.run(["salt-call", "state.apply","fleet"], stdout=subprocess.PIPE, encoding='ascii') + copy_packages = subprocess.run(["salt-call", "state.apply","fleet"], stdout=subprocess.PIPE, encoding='ascii') + + if ACTION == 'update_custom_hostname': + logging.info('so/fleet update_custom_hostname reactor') + + CUSTOMHOSTNAME = data['data']['custom_hostname'] + + # Update the Fleet host in the static pillar + for line in fileinput.input(STATICFILE, inplace=True): + line = re.sub(r'fleet_custom_hostname: \S*', f"fleet_custom_hostname: {CUSTOMHOSTNAME}", line.rstrip()) + print(line) return {} diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls index ca6417dec..897ab84d0 100644 --- a/salt/ssl/init.sls +++ b/salt/ssl/init.sls @@ -5,6 +5,7 @@ {% set global_ca_server = [] %} {% set MAININT = salt['pillar.get']('host:mainint') %} {% set MAINIP = salt['grains.get']('ip_interfaces').get(MAININT)[0] %} +{% set CUSTOM_FLEET_HOSTNAME = salt['pillar.get']('static:fleet_custom_hostname', None) %} {% if grains.id.split('_')|last in ['master', 'eval', 'standalone'] %} {% set trusttheca_text = salt['mine.get'](grains.id, 'x509.get_pem_entries')[grains.id]['/etc/pki/ca.crt']|replace('\n', '') %} @@ -201,6 +202,7 @@ chownfilebeatp8: - signing_policy: masterssl - public_key: /etc/pki/masterssl.key - CN: {{ HOSTNAME }} + - subjectAltName: DNS:{{ HOSTNAME }}, IP:{{ MAINIP }} {% if CUSTOM_FLEET_HOSTNAME != None %},DNS:{{ CUSTOM_FLEET_HOSTNAME }} {% endif %} - days_remaining: 0 - days_valid: 820 - backup: True @@ -223,7 +225,7 @@ chownfilebeatp8: x509.certificate_managed: - signing_private_key: /etc/pki/fleet.key - CN: {{ HOSTNAME }} - - subjectAltName: DNS:{{ HOSTNAME }}, IP:{{ MAINIP }} + - subjectAltName: DNS:{{ HOSTNAME }}, IP:{{ MAINIP }} {% if CUSTOM_FLEET_HOSTNAME != None %},DNS:{{ CUSTOM_FLEET_HOSTNAME }} {% endif %} - days_remaining: 0 - days_valid: 820 - backup: True diff --git a/setup/so-functions b/setup/so-functions index f3e738678..96190b60c 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -287,6 +287,10 @@ collect_adminuser_inputs() { done } +collect_fleet_custom_hostname_inputs{ + whiptail_fleet_custom_hostname +} + collect_fleetuser_inputs() { # Get a username & password for the Fleet admin user local valid_user=no diff --git a/setup/so-setup b/setup/so-setup index c583c4260..7f55c1e46 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -288,6 +288,7 @@ fi if [ "$install_type" == 'FLEET' ]; then collect_fleetuser_inputs + collect_fleet_custom_hostname_inputs else FLEETNODEUSER=$WEBUSER FLEETNODEPASSWD1=$WEBPASSWD1 @@ -495,6 +496,12 @@ fi set_progress_str 73 "$(print_salt_state_apply 'redis')" salt-call state.apply -l info redis >> $setup_log 2>&1 + + if [[ $is_fleet_standalone && $FLEETCUSTOMHOSTNAME != '' ]]; then + set_progress_str 73 "$(print_salt_state_apply 'fleet.event_update-custom-hostname')" + pillar_override="{"static":{"fleet_custom_hostname":"$FLEETCUSTOMHOSTNAME"}}" + salt-call state.apply -l info fleet.event_update-custom-hostname pillar=$pillar_override >> $setup_log 2>&1 + fi set_progress_str 74 "$(print_salt_state_apply 'so-fleet-setup')" so-fleet-setup $FLEETNODEUSER $FLEETNODEPASSWD1 >> $setup_log 2>&1 diff --git a/setup/so-whiptail b/setup/so-whiptail index fc2429ad2..dd6d1edac 100755 --- a/setup/so-whiptail +++ b/setup/so-whiptail @@ -270,6 +270,19 @@ whiptail_create_web_user_password2() { } +whiptail_fleet_custom_hostname() { + + [ -n "$TESTING" ] && return + + FLEETCUSTOMHOSTNAME=$(whiptail --title "Security Onion Install" --inputbox \ + "What FQDN should osquery clients use for connections to this Fleet node? Leave blank if the local system hostname will be used." 10 60 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus +} + + + whiptail_requirements_error() { local requirement_needed=$1