Quick Install Script for Vulnerability Management (InsightVM) in InsightGovCloud
Copy link

Copy and paste this code block into a new file and follow the Linux installation instructions in Deploy Vulnerability Management (InsightVM) in InsightGovCloud.

ℹ️

Tip for copying code blocks

Hover your cursor over a code block to make the Copy code button appear. Click this button to copy the entire code block to your clipboard.

Folder highlights Script content details the unattended Linux installation for Vulnerability Management (InsightVM) InsightGovCloud, including password policy checks and FIPS mode configuration steps. # !/bin/bash set -euo pipefail # # FedRamp Linux Quick Start Script (v0.98) # - Security: downloads SHA-512 checksum and verifies installer before execution. # - Collects required user inputs and enforces a basic password policy (min 8 chars, mixed case, digit, special) # - Ease of use: uses unattended install with direct cli call (not response.vars) # - Performance: polling loop for log markers # - Compatibility: avoids "bash -lc" login shell behavior; uses "bash -c". # - Checks for Federal or FIPS = false # # - Verbose + colorized checks for existing install and FedRAMP/FIPS log markers # - Existing install guard verifies: RNG (advisory), process running, log markers, CustomEnvironment.properties; exits success if compliant, fails otherwise # - Uses /tmp for downloads (installer + checksum) # --- Colors --- C_RESET="\033[0m" C_BOLD="\033[1m" C_BLUE="\033[1;34m" C_GRAY="\033[90m" C_GREEN="\033[32m" C_YELLOW="\033[33m" C_RED="\033[31m" ok() { echo -e "${C_GREEN}[SUCCESS]${C_RESET} $*"; } warn() { echo -e "${C_YELLOW}[WARNING]${C_RESET} $*"; } fail() { echo -e "${C_RED}[ERROR]${C_RESET} $*"; } info() { echo -e "${C_BLUE}[INFO]${C_RESET} $*"; } print_step() { echo -e "\n${C_BLUE}${C_BOLD}==> $1${C_RESET}" } run_cmd() { echo -e "${C_GRAY}$ $*${C_RESET}" bash -c "$@" } have() { command -v "$1" >/dev/null 2>&1; } # --- Password complexity --- pw_error() { echo -e "${C_RED}Password policy error:${C_RESET} $1" >&2; } check_password_complexity() { local password="$1" local username="${2:-}" local min_len=8 info "Password policy: >=${min_len} chars, upper/lower/digit/special, no whitespace, no username substring" if (( ${#password} < min_len )); then pw_error "Password must be at least ${min_len} characters." return 1 fi if grep -qE '[[:space:]]' <<<"$password"; then pw_error "Password must not contain whitespace." return 1 fi if ! grep -qE '[A-Z]' <<<"$password"; then pw_error "Password must contain at least one uppercase letter." return 1 fi if ! grep -qE '[a-z]' <<<"$password"; then pw_error "Password must contain at least one lowercase letter." return 1 fi if ! grep -qE '[0-9]' <<<"$password"; then pw_error "Password must contain at least one digit." return 1 fi if ! grep -qE '[^A-Za-z0-9]' <<<"$password"; then pw_error "Password must contain at least one special character." return 1 fi if [[ -n "$username" ]]; then shopt -s nocasematch if [[ "$password" == *"$username"* ]]; then shopt -u nocasematch pw_error "Password must not contain the username." return 1 fi shopt -u nocasematch fi ok "Password meets complexity requirements." return 0 } # --- RNG helpers --- rng_service_candidates=("rngd" "rng-tools" "rng-tools-debian") find_rng_service() { for s in "${rng_service_candidates[@]}"; do if systemctl list-unit-files --type=service 2>/dev/null | awk '{print $1}' | grep -qx "${s}.service"; then echo "${s}.service" return 0 fi done if have rngd; then echo "rngd.service" return 0 fi return 1 } # --- SELinux helpers --- selinux_is_enabled() { if have selinuxenabled; then selinuxenabled && return 0 || return 1 fi if have getenforce; then [[ "$(getenforce 2>/dev/null || echo Disabled)" != "Disabled" ]] && return 0 || return 1 fi return 1 } # --- Process check (existing install) --- # Must match cases like: # root 4495 ... SCREEN -d -m -S nexposeconsole /opt/rapid7/nexpose/nsc/nsc.sh nexpose_process_is_running() { pgrep -fa "/opt/rapid7/nexpose/nsc/nsc\.sh" >/dev/null 2>&1 } get_nexpose_process_line() { # Return one representative line if present, formatted without the leading username # e.g. "4495 SCREEN -d -m -S nexposeconsole /opt/rapid7/nexpose/nsc/nsc.sh" pgrep -fa "/opt/rapid7/nexpose/nsc/nsc\.sh" 2>/dev/null | head -n 1 | awk '{ $1=$1; print }' || true } # --- Existing install detection (quiet) --- nexpose_is_installed_quiet() { [[ -d /opt/rapid7/nexpose/nsc ]] || return 1 [[ -f /opt/rapid7/nexpose/nsc/nsc.sh ]] || return 1 return 0 } verify_existing_installation() { print_step "Existing install detected. Verifying FedRAMP/FIPS compliance..." ok "Existing install detected. Verifying FedRAMP/FIPS compliance..." local LOG="/opt/rapid7/nexpose/nsc/logs/nsc.log" local CUSTOM_ENV="/opt/rapid7/nexpose/nsc/CustomEnvironment.properties" local MARK_FED_TRUE="Console is a Federal instance = true" local MARK_FIPS_TRUE="Console FIPS Mode switched on = true" local MARK_FED_FALSE="Console is a Federal instance = false" local MARK_FIPS_FALSE="Console FIPS Mode switched on = false" local log_ok=0 local env_ok=0 local rng_ok=0 local proc_ok=0 # Process (required) - print first on success if nexpose_process_is_running; then local pline pline="$(get_nexpose_process_line)" if [[ -n "$pline" ]]; then ok "Process running: ${pline}" else ok "Process running: /opt/rapid7/nexpose/nsc/nsc.sh" fi proc_ok=1 fi # RNG (advisory) if RNG_SVC="$(find_rng_service 2>/dev/null)"; then if systemctl is-active --quiet "$RNG_SVC"; then ok "RNG active: $RNG_SVC" rng_ok=1 else warn "RNG installed but inactive: $RNG_SVC" fi else warn "No RNG service detected." fi # Logs if [[ -f "$LOG" ]]; then if sudo grep -qF "$MARK_FED_FALSE" "$LOG" || sudo grep -qF "$MARK_FIPS_FALSE" "$LOG"; then fail "Detected explicit non-compliant log markers (false)." fail "Searched for false markers:" fail " - $MARK_FED_FALSE" fail " - $MARK_FIPS_FALSE" echo -e "${C_GRAY}" sudo grep -nE "Console is a Federal instance = |Console FIPS Mode switched on = " "$LOG" | tail -n 100 || true echo -e "${C_RESET}" # Continue to final failure summary below else if sudo grep -qF "$MARK_FED_TRUE" "$LOG" && sudo grep -qF "$MARK_FIPS_TRUE" "$LOG"; then ok "Log markers verified (Federal=true, FIPS=true). Sample:" log_ok=1 else fail "FedRAMP/FIPS log verification failed." fail "Search of logs did not find):" if sudo grep -qF "$MARK_FED_TRUE" "$LOG"; then fail " - ${MARK_FED_TRUE}. (Found)" else fail " - ${MARK_FED_TRUE}. (Not found)" fi if sudo grep -qF "$MARK_FIPS_TRUE" "$LOG"; then fail " - ${MARK_FIPS_TRUE}. (Found)" else fail " - ${MARK_FIPS_TRUE}. (Not found)" fi fi fi else fail "Log file not found." fi # CustomEnvironment.properties if [[ -f "$CUSTOM_ENV" ]]; then local miss=0 if ! grep -q "^com\.rapid7\.federal=true" "$CUSTOM_ENV"; then fail "Missing/incorrect property: com.rapid7.federal=true" miss=1 fi if ! grep -q "^fipsMode=1" "$CUSTOM_ENV"; then fail "Missing/incorrect property: fipsMode=1" miss=1 fi if (( miss == 0 )); then env_ok=1 fi else fail "CustomEnvironment.properties not found." fi # Process requirement failure detail if (( proc_ok != 1 )); then fail "Process check failed: could not find running nsc.sh process." info "Matching processes (if any):" echo -e "${C_GRAY}" ps -ef | grep -E "/opt/rapid7/nexpose/nsc/nsc\.sh|nexposeconsole|nsc\.sh" | grep -v grep || true echo -e "${C_RESET}" fi if (( log_ok == 1 && env_ok == 1 && proc_ok == 1 )); then ok "Existing installation is Federal + FIPS compliant. No changes made. Exiting." if (( rng_ok != 1 )); then warn "RNG not active; FIPS mode may not operate correctly." fi exit 0 fi fail "Existing installation detected but not compliant. Aborting to avoid overwriting." warn "Next Steps:" warn " - Check that RNG is installed and running" warn " - Ensure FIPS and Federal instance is configured in: ${CUSTOM_ENV}" warn " - Make above checks, restart daemon, and re-run this script." warn " - Logs: ${LOG}" exit 1 } # --- Existing installation guard (quiet; no pre-check output) --- if nexpose_is_installed_quiet; then verify_existing_installation fi # --- Collect user variables for unattended install --- print_step "Collecting user variables for installer..." read -rp "Enter company name: " NX_NAME read -rp "Enter first name: " FIRST read -rp "Enter last name: " LAST read -rp "Enter console admin username: " NX_USERNAME while true; do read -rsp "Enter console admin password: " NX_PASSWORD echo read -rsp "Re-enter console admin password: " NX_PASSWORD2 echo if [[ "$NX_PASSWORD" != "$NX_PASSWORD2" ]]; then fail "Passwords do not match. Try again." continue fi if ! check_password_complexity "$NX_PASSWORD" "$NX_USERNAME"; then fail "Password does not meet complexity requirements. Try again." continue fi ok "Password accepted." break done # --- Package manager detection --- PKG="unknown" if have dnf; then PKG="dnf" elif have apt-get; then PKG="apt" elif have yum; then PKG="dnf" fi if [[ "$PKG" == "unknown" ]]; then fail "Unsupported distro. Need dnf or apt-get." exit 1 fi ok "Detected package manager: $PKG" # --- Update and install prerequisites --- print_step "Updating system packages..." if [[ "$PKG" == "dnf" ]]; then run_cmd "sudo dnf -y update" elif [[ "$PKG" == "apt" ]]; then run_cmd "sudo apt-get update -y" fi ok "System update complete." print_step "Installing prerequisite packages (RNG, SELinux tools when available, curl)..." if [[ "$PKG" == "dnf" ]]; then run_cmd "sudo dnf -y install rng-tools policycoreutils policycoreutils-python-utils curl" elif [[ "$PKG" == "apt" ]]; then run_cmd "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y curl" run_cmd "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y policycoreutils || true" run_cmd "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y rng-tools5 || sudo DEBIAN_FRONTEND=noninteractive apt-get install -y rng-tools || true" fi ok "Prerequisites installed." print_step "Enabling and starting RNG daemon..." if RNG_SVC="$(find_rng_service 2>/dev/null)"; then run_cmd "sudo systemctl enable --now ${RNG_SVC}" if systemctl is-active --quiet "$RNG_SVC"; then ok "RNG active: $RNG_SVC" else warn "RNG installed but not active yet: $RNG_SVC" fi else warn "Could not detect rng daemon. FIPS mode may be impacted. Install will continue." fi # --- Directory setup --- print_step "Creating /opt/rapid7/nexpose directory..." run_cmd "sudo install -d -m 755 /opt/rapid7/nexpose" run_cmd "sudo chown -R root:root /opt/rapid7" ok "Directory prepared: /opt/rapid7/nexpose" # --- SELinux pre-config (only if SELinux is enabled) --- if selinux_is_enabled && have semanage; then print_step "SELinux detected: labeling Rapid7 directories and opening TCP 3780..." run_cmd "sudo semanage fcontext -a -t usr_t '/opt/rapid7(/.*)?' || true" run_cmd "sudo semanage fcontext -a -t bin_t '/opt/rapid7/nexpose(/.*)?' || true" run_cmd "sudo semanage fcontext -a -t var_log_t '/opt/rapid7/nexpose/nsc/logs(/.*)?' || true" run_cmd "sudo semanage port -a -t http_port_t -p tcp 3780 2>/dev/null || sudo semanage port -m -t http_port_t -p tcp 3780 || true" print_step "Applying SELinux labels..." run_cmd "sudo restorecon -RF /opt/rapid7 || true" ok "SELinux configuration applied (best-effort)." else warn "SELinux not enabled/detected or semanage missing. Skipping SELinux steps." fi # --- Download installer and verify checksum (in /tmp) --- INSTALLER="/tmp/Rapid7Setup-Linux64.bin" CHECKSUM_FILE="/tmp/Rapid7Setup-Linux64.bin.sha512sum" print_step "Downloading Rapid7 Vulnerability Management (InsightVM) installer and checksum to /tmp..." run_cmd "sudo curl -fL https://download2.rapid7.com/download/InsightVM/Rapid7Setup-Linux64.bin -o '${INSTALLER}'" run_cmd "sudo curl -fL https://download2.rapid7.com/download/InsightVM/Rapid7Setup-Linux64.bin.sha512sum -o '${CHECKSUM_FILE}'" ok "Downloads complete." print_step "Verifying installer checksum..." run_cmd "cd /tmp && sha512sum -c Rapid7Setup-Linux64.bin.sha512sum" ok "Checksum verification successful." run_cmd "sudo chmod +x '${INSTALLER}'" ok "Installer marked executable." # --- Run installer with -V args (no response.vars), avoid $Boolean expansion under set -u --- print_step "Running Vulnerability Management (InsightVM) installer..." warn "Password is supplied via command-line arguments; it may be visible to other processes via ps during install." INSTALL_CMD=( sudo "$INSTALLER" -q -overwrite "-Vfirstname=$FIRST" "-Vlastname=$LAST" "-Vcompany=$NX_NAME" "-Vusername=$NX_USERNAME" "-Vpassword1=$NX_PASSWORD" "-Vpassword2=$NX_PASSWORD" '-Vsys.component.typical$Boolean=true' '-Vsys.component.engine$Boolean=false' '-VcommunicationDirectionChoice$Integer=1' '-VrequirePasswordChange$Boolean=true' '-VinitService$Boolean=true' ) echo -e "${C_GRAY}$ sudo $INSTALLER -q -overwrite -Vfirstname=... -Vlastname=... -Vcompany=... -Vusername=... -Vpassword1=REDACTED -Vpassword2=REDACTED ...${C_RESET}" if "${INSTALL_CMD[@]}"; then ok "Installer completed successfully." else fail "Installer returned a non-zero exit code." exit 1 fi # --- FIPS & FedRAMP configuration --- print_step "Enabling InsightGovCloud and FIPS mode..." run_cmd "sudo bash -c \"cat > /opt/rapid7/nexpose/nsc/CustomEnvironment.properties <<'EOF' fipsMode=1 com.rapid7.federal=true EOF \"" ok "CustomEnvironment.properties written." # Re-apply labels if SELinux is present if selinux_is_enabled; then print_step "Re-applying SELinux labels..." run_cmd "sudo restorecon -RF /opt/rapid7/nexpose || true" ok "SELinux labels re-applied." else warn "SELinux not enabled; skipping restorecon." fi # --- Start console service --- print_step "Reloading systemd and enabling Nexpose Console..." run_cmd "sudo systemctl daemon-reload || true" run_cmd "sudo systemctl enable --now nexposeconsole.service || true" # --- Verify console successfully starts with FIPS/Federal --- print_step "Verifying FIPS/Federal mode in logs (polling)..." LOG="/opt/rapid7/nexpose/nsc/logs/nsc.log" MAX_WAIT_SECONDS=180 POLL_INTERVAL=10 ELAPSED=0 MARK_FED_TRUE="Console is a Federal instance = true" MARK_FIPS_TRUE="Console FIPS Mode switched on = true" MARK_FED_FALSE="Console is a Federal instance = false" MARK_FIPS_FALSE="Console FIPS Mode switched on = false" while (( ELAPSED < MAX_WAIT_SECONDS )); do if [[ -f "$LOG" ]]; then if sudo grep -qF "$MARK_FED_FALSE" "$LOG" || sudo grep -qF "$MARK_FIPS_FALSE" "$LOG"; then fail "Detected explicit false markers in log. Aborting." echo -e "${C_GRAY}" sudo grep -nE "Console is a Federal instance = |Console FIPS Mode switched on = " "$LOG" | tail -n 100 || true echo -e "${C_RESET}" exit 1 fi if sudo grep -qF "$MARK_FED_TRUE" "$LOG" && sudo grep -qF "$MARK_FIPS_TRUE" "$LOG"; then ok "Verified: Federal + FIPS active." exit 0 fi fi sleep "$POLL_INTERVAL" ELAPSED=$((ELAPSED + POLL_INTERVAL)) done fail "Did not detect both Federal=true and FIPS=true within ${MAX_WAIT_SECONDS}s." warn "Suggested checks:" warn " - sudo systemctl status nexposeconsole.service" warn " - sudo tail -n 200 $LOG" exit 1