bitbucket.org/Aishee/synsec@v0.0.0-20210414005726-236fc01a153d/wizard.sh (about)

     1  #!/usr/bin/env bash
     2  
     3  set -o pipefail
     4  #set -x
     5  
     6  
     7  RED='\033[0;31m'
     8  BLUE='\033[0;34m'
     9  GREEN='\033[0;32m'
    10  YELLOW='\033[1;33m'
    11  ORANGE='\033[0;33m'
    12  NC='\033[0m'
    13  
    14  SILENT="false"
    15  DOCKER_MODE="false"
    16  
    17  SYNSEC_RUN_DIR="/var/run"
    18  SYNSEC_LIB_DIR="/var/lib/synsec"
    19  SYNSEC_USR_DIR="/usr/local/lib/synsec"
    20  SYNSEC_DATA_DIR="${SYNSEC_LIB_DIR}/data"
    21  SYNSEC_DB_PATH="${SYNSEC_DATA_DIR}/synsec.db"
    22  SYNSEC_PATH="/etc/synsec"
    23  SYNSEC_CONFIG_PATH="${SYNSEC_PATH}"
    24  SYNSEC_LOG_FILE="/var/log/synsec.log"
    25  LAPI_LOG_FILE="/var/log/synsec_api.log"
    26  
    27  
    28  SYNSEC_BIN="./cmd/synsec/synsec"
    29  CCSCLI_BIN="./cmd/synsec-cli/ccscli"
    30  
    31  CLIENT_SECRETS="local_api_credentials.yaml"
    32  LAPI_SECRETS="online_api_credentials.yaml"
    33  
    34  BIN_INSTALL_PATH="/usr/local/bin"
    35  SYNSEC_BIN_INSTALLED="${BIN_INSTALL_PATH}/synsec"
    36  
    37  if [[ -f "/usr/bin/ccscli" ]] ; then
    38      CCSCLI_BIN_INSTALLED="/usr/bin/ccscli"
    39  else
    40      CCSCLI_BIN_INSTALLED="${BIN_INSTALL_PATH}/ccscli"
    41  fi
    42  
    43  ACQUIS_PATH="${SYNSEC_CONFIG_PATH}"
    44  TMP_ACQUIS_FILE="tmp-acquis.yaml"
    45  ACQUIS_TARGET="${ACQUIS_PATH}/acquis.yaml"
    46  
    47  PID_DIR="${SYNSEC_RUN_DIR}"
    48  SYSTEMD_PATH_FILE="/etc/systemd/system/synsec.service"
    49  
    50  PATTERNS_FOLDER="config/patterns"
    51  PATTERNS_PATH="${SYNSEC_CONFIG_PATH}/patterns/"
    52  
    53  ACTION=""
    54  
    55  DEBUG_MODE="false"
    56  FORCE_MODE="false"
    57  
    58  SUPPORTED_SERVICES='apache2
    59  httpd
    60  nginx
    61  sshd
    62  mysql
    63  telnet
    64  smb
    65  '
    66  
    67  BACKUP_DIR=$(mktemp -d)
    68  rm -rf $BACKUP_DIR
    69  
    70  log_info() {
    71      msg=$1
    72      date=$(date +%x:%X)
    73      echo -e "${BLUE}INFO${NC}[${date}] synsec_wizard: ${msg}"
    74  }
    75  
    76  log_fatal() {
    77      msg=$1
    78      date=$(date +%x:%X)
    79      echo -e "${RED}FATA${NC}[${date}] synsec_wizard: ${msg}" 1>&2
    80      exit 1
    81  }
    82  
    83  log_warn() {
    84      msg=$1
    85      date=$(date +%x:%X)
    86      echo -e "${ORANGE}WARN${NC}[${date}] synsec_wizard: ${msg}"
    87  }
    88  
    89  log_err() {
    90      msg=$1
    91      date=$(date +%x:%X)
    92      echo -e "${RED}ERR${NC}[${date}] synsec_wizard: ${msg}" 1>&2
    93  }
    94  
    95  log_dbg() {
    96      if [[ ${DEBUG_MODE} == "true" ]]; then
    97          msg=$1
    98          date=$(date +%x:%X)
    99          echo -e "[${date}][${YELLOW}DBG${NC}] synsec_wizard: ${msg}" 1>&2
   100      fi
   101  }
   102  
   103  detect_services () {
   104      DETECTED_SERVICES=()
   105      HMENU=()
   106      #list systemd services
   107      SYSTEMD_SERVICES=`systemctl  --state=enabled list-unit-files '*.service' | cut -d ' ' -f1`
   108      #raw ps
   109      PSAX=`ps ax -o comm=`
   110      for SVC in ${SUPPORTED_SERVICES} ; do
   111          log_dbg "Checking if service '${SVC}' is running (ps+systemd)"
   112          for SRC in "${SYSTEMD_SERVICES}" "${PSAX}" ; do
   113              echo ${SRC} | grep ${SVC} >/dev/null
   114              if [ $? -eq 0 ]; then
   115                  #on centos, apache2 is named httpd
   116                  if [[ ${SVC} == "httpd" ]] ; then
   117                      SVC="apache2";
   118                  fi
   119                  DETECTED_SERVICES+=(${SVC})
   120                  HMENU+=(${SVC} "on")
   121                  log_dbg "Found '${SVC}' running"
   122                  break;
   123              fi;
   124          done;
   125      done;
   126      if [[ ${OSTYPE} == "linux-gnu" ]]; then
   127          DETECTED_SERVICES+=("linux")
   128          HMENU+=("linux" "on")
   129      else
   130          log_info "NOT A LINUX"
   131      fi;
   132  
   133      if [[ ${SILENT} == "false" ]]; then
   134          #we put whiptail results in an array, notice the dark magic fd redirection
   135          DETECTED_SERVICES=($(whiptail --separate-output --noitem --ok-button Continue --title "Services to monitor" --checklist "Detected services, uncheck to ignore. Ignored services won't be monitored." 18 70 10 ${HMENU[@]} 3>&1 1>&2 2>&3))
   136          if [ $? -eq 1 ]; then
   137              log_err "user bailed out at services selection"
   138              exit 1;
   139          fi;
   140          log_dbg "Detected services (interactive) : ${DETECTED_SERVICES[@]}"
   141      else
   142          log_dbg "Detected services (unattended) : ${DETECTED_SERVICES[@]}"
   143      fi;
   144  }
   145  
   146  declare -A log_input_tags
   147  log_input_tags[apache2]='type: apache2'
   148  log_input_tags[nginx]='type: nginx'
   149  log_input_tags[sshd]='type: syslog'
   150  log_input_tags[rsyslog]='type: syslog'
   151  log_input_tags[telnet]='type: telnet'
   152  log_input_tags[mysql]='type: mysql'
   153  log_input_tags[smb]='type: smb'
   154  log_input_tags[linux]="type: syslog"
   155  
   156  declare -A log_locations
   157  log_locations[apache2]='/var/log/apache2/*.log,/var/log/*httpd*.log,/var/log/httpd/*log'
   158  log_locations[nginx]='/var/log/nginx/*.log'
   159  log_locations[sshd]='/var/log/auth.log,/var/log/sshd.log,/var/log/secure'
   160  log_locations[rsyslog]='/var/log/syslog'
   161  log_locations[telnet]='/var/log/telnetd*.log'
   162  log_locations[mysql]='/var/log/mysql/error.log'
   163  log_locations[smb]='/var/log/samba*.log'
   164  log_locations[linux]='/var/log/syslog,/var/log/kern.log,/var/log/messages'
   165  
   166  #$1 is service name, such those in SUPPORTED_SERVICES
   167  find_logs_for() {
   168      ret=""
   169      x=${1}
   170      #we have trailing and starting quotes because of whiptail
   171      SVC="${x%\"}"
   172      SVC="${SVC#\"}"
   173      DETECTED_LOGFILES=()
   174      HMENU=()
   175      #log_info "Searching logs for ${SVC} : ${log_locations[${SVC}]}"
   176  
   177      #split the line into an array with ',' separator
   178      OIFS=${IFS}
   179      IFS=',' read -r -a a <<< "${log_locations[${SVC}]},"
   180      IFS=${OIFS}
   181      #readarray -td, a <<<"${log_locations[${SVC}]},"; unset 'a[-1]';
   182      for poss_path in "${a[@]}"; do
   183          #Split /var/log/nginx/*.log into '/var/log/nginx' and '*.log' so we can use find
   184  	    path=${poss_path%/*}
   185  	    fname=${poss_path##*/}
   186  	    candidates=`find "${path}" -type f -mtime -5 -ctime -5 -name "$fname"`
   187  	    #We have some candidates, add them
   188  	    for final_file in ${candidates} ; do
   189  	        log_dbg "Found logs file for '${SVC}': ${final_file}"
   190  	        DETECTED_LOGFILES+=(${final_file})
   191              HMENU+=(${final_file} "on")
   192  	    done;
   193      done;
   194  
   195      if [[ ${SILENT} == "false" ]]; then
   196          DETECTED_LOGFILES=($(whiptail --separate-output  --noitem --ok-button Continue --title "Log files to process for ${SVC}" --checklist "Detected logfiles for ${SVC}, uncheck to ignore" 18 70 10 ${HMENU[@]} 3>&1 1>&2 2>&3))
   197          if [ $? -eq 1 ]; then
   198              log_err "user bailed out at log file selection"
   199              exit 1;
   200          fi;
   201      fi
   202  }
   203  
   204  in_array() {
   205      str=$1
   206      shift
   207      array=("$@")
   208      for element in "${array[@]}"; do
   209          if [[ ${str} == *${element}* ]]; then
   210              return 0
   211          fi
   212      done
   213      return 1
   214  }
   215  
   216  install_collection() {
   217      HMENU=()
   218      readarray -t AVAILABLE_COLLECTION < <(${CCSCLI_BIN_INSTALLED} collections list -o raw -a)
   219      COLLECTION_TO_INSTALL=()
   220      for collect_info in "${AVAILABLE_COLLECTION[@]}"; do
   221          collection="$(echo ${collect_info} | cut -d " " -f1)"
   222          description="$(echo ${collect_info} | cut -d " " -f2-)"
   223          in_array $collection "${DETECTED_SERVICES[@]}"
   224          if [[ $? == 0 ]]; then
   225              HMENU+=("${collection}" "${description}" "ON")
   226              #in case we're not in interactive mode, assume defaults
   227              COLLECTION_TO_INSTALL+=(${collection})
   228          else
   229              if [[ ${collection} == "linux" ]]; then
   230                  HMENU+=("${collection}" "${description}" "ON")
   231                  #in case we're not in interactive mode, assume defaults
   232                  COLLECTION_TO_INSTALL+=(${collection})
   233              else
   234                  HMENU+=("${collection}" "${description}" "OFF")
   235              fi
   236          fi
   237      done
   238  
   239      if [[ ${SILENT} == "false" ]]; then
   240          COLLECTION_TO_INSTALL=($(whiptail --separate-output --ok-button Continue --title "Synsec collections" --checklist "Available collections in synsec, try to pick one that fits your profile. Collections contains parsers and scenarios to protect your system." 20 120 10 "${HMENU[@]}" 3>&1 1>&2 2>&3))
   241          if [ $? -eq 1 ]; then
   242              log_err "user bailed out at collection selection"
   243              exit 1;
   244          fi;
   245      fi;
   246  
   247      for collection in "${COLLECTION_TO_INSTALL[@]}"; do
   248          log_info "Installing collection '${collection}'"
   249          ${CCSCLI_BIN_INSTALLED} collections install "${collection}" > /dev/null 2>&1 || log_err "fail to install collection ${collection}"
   250      done
   251  
   252      ${CCSCLI_BIN_INSTALLED} parsers install "breakteam/whitelists" > /dev/null 2>&1 || log_err "fail to install collection synsec/whitelists"
   253      if [[ ${SILENT} == "false" ]]; then
   254          whiptail --msgbox "Out of safety, I installed a parser called 'breakteam/whitelists'. This one will prevent private IP adresses from being banned, feel free to remove it any time." 20 50
   255      fi
   256  
   257      if [[ ${SILENT} == "false" ]]; then
   258          whiptail --msgbox "SynSec alone will not block any IP address. If you want to block them, you must use a bouncer. You can find them on https://hub.synsec.net/browse/#bouncers" 20 50
   259      fi
   260  }
   261  
   262  #$1 is the service name, $... is the list of candidate logs (from find_logs_for)
   263  genyaml() {
   264      local service="${1}"
   265      shift
   266      local files=("${@}")
   267  
   268      echo "#Generated acquisition file - wizard.sh (service: ${service}) / files : ${files[@]}" >> ${TMP_ACQUIS_FILE}
   269  
   270      echo "filenames:"  >> ${TMP_ACQUIS_FILE}
   271      for fd in ${files[@]}; do
   272  	echo "  - ${fd}"  >> ${TMP_ACQUIS_FILE}
   273      done
   274      echo "labels:"  >> ${TMP_ACQUIS_FILE}
   275      echo "  "${log_input_tags[${service}]}  >> ${TMP_ACQUIS_FILE}
   276      echo "---"  >> ${TMP_ACQUIS_FILE}
   277      log_dbg "tmp acquisition file generated to: ${TMP_ACQUIS_FILE}"
   278  }
   279  
   280  genacquisition() {
   281      log_dbg "Found following services : "${DETECTED_SERVICES[@]}
   282      for PSVG in ${DETECTED_SERVICES[@]} ; do
   283          find_logs_for ${PSVG}
   284          if [[ ${#DETECTED_LOGFILES[@]} -gt 0 ]] ; then
   285              log_info "service '${PSVG}': ${DETECTED_LOGFILES[*]}"
   286              genyaml ${PSVG} ${DETECTED_LOGFILES[@]}
   287          fi;
   288      done
   289  }
   290  
   291  detect_cs_install () {
   292      if [[ -f "$SYNSEC_BIN_INSTALLED" ]]; then
   293          log_warn "Synsec is already installed !"
   294          echo ""
   295          echo "We recommand to upgrade : sudo ./wizard.sh --upgrade "
   296          echo "If you want to install it anyway, please use '--force'."
   297          echo ""
   298          echo "Run : sudo ./wizard.sh -i --force"
   299          if [[ ${FORCE_MODE} == "false" ]]; then
   300              exit 1
   301          fi
   302      fi
   303  }
   304  
   305  check_cs_version () {
   306      CURRENT_CS_VERSION=$(synsec -version 2>&1 | grep version | grep -Eio 'v[0-9]+.[0-9]+.[0-9]+' | cut -c 2-)
   307      NEW_CS_VERSION=$($SYNSEC_BIN -version 2>&1 | grep version | grep -Eio 'v[0-9]+.[0-9]+.[0-9]+' | cut -c 2-)
   308      CURRENT_MAJOR_VERSION=$(echo $CURRENT_CS_VERSION | cut -d'.' -f1)
   309      CURRENT_MINOR_VERSION=$(echo $CURRENT_CS_VERSION | cut -d'.' -f2)
   310      CURRENT_PATCH_VERSION=$(echo $CURRENT_CS_VERSION | cut -d'.' -f3)
   311      NEW_MAJOR_VERSION=$(echo $NEW_CS_VERSION | cut -d'.' -f1)
   312      NEW_MINOR_VERSION=$(echo $NEW_CS_VERSION | cut -d'.' -f2)
   313      NEW_PATCH_VERSION=$(echo $NEW_CS_VERSION | cut -d'.' -f3)
   314  
   315      if [[ $NEW_MAJOR_VERSION -gt $CURRENT_MAJOR_VERSION ]]; then
   316          if [[ ${FORCE_MODE} == "false" ]]; then
   317              log_warn "new version ($NEW_CS_VERSION) is a major, you need to follow documentation to upgrade !"
   318              echo ""
   319              echo "Please follow : https://docs.synsec.net/Synsec/v1/migration/"
   320              exit 1
   321          fi
   322      elif [[ $NEW_MINOR_VERSION -gt $CURRENT_MINOR_VERSION ]] ; then
   323          log_warn "new version ($NEW_CS_VERSION) is a minor upgrade !"
   324          if [[ $ACTION != "upgrade" ]] ; then
   325              if [[ ${FORCE_MODE} == "false" ]]; then
   326                  echo ""
   327                  echo "We recommand to upgrade with : sudo ./wizard.sh --upgrade "
   328                  echo "If you want to $ACTION anyway, please use '--force'."
   329                  echo ""
   330                  echo "Run : sudo ./wizard.sh --$ACTION --force"
   331                  exit 1
   332              fi
   333          fi
   334      elif [[ $NEW_PATCH_VERSION -gt $CURRENT_PATCH_VERSION ]] ; then
   335          log_warn "new version ($NEW_CS_VERSION) is a patch !"
   336          if [[ $ACTION != "binupgrade" ]] ; then
   337              if [[ ${FORCE_MODE} == "false" ]]; then
   338                  echo ""
   339                  echo "We recommand to upgrade binaries only : sudo ./wizard.sh --binupgrade "
   340                  echo "If you want to $ACTION anyway, please use '--force'."
   341                  echo ""
   342                  echo "Run : sudo ./wizard.sh --$ACTION --force"
   343                  exit 1
   344              fi
   345          fi
   346      elif [[ $NEW_MINOR_VERSION -eq $CURRENT_MINOR_VERSION ]]; then
   347          log_warn "new version ($NEW_CS_VERSION) is same as current version ($CURRENT_CS_VERSION) !"
   348          if [[ ${FORCE_MODE} == "false" ]]; then
   349              echo ""
   350              echo "We recommand to $ACTION only if it's an higher version. "
   351              echo "If it's an RC version (vX.X.X-rc) you can upgrade it using '--force'."
   352              echo ""
   353              echo "Run : sudo ./wizard.sh --$ACTION --force"
   354              exit 1
   355          fi
   356      fi
   357  }
   358  
   359  #install synsec and ccscli
   360  install_synsec() {
   361      mkdir -p "${SYNSEC_DATA_DIR}"
   362      (cd config && find patterns -type f -exec install -Dm 644 "{}" "${SYNSEC_CONFIG_PATH}/{}" \; && cd ../) || exit
   363      mkdir -p "${SYNSEC_CONFIG_PATH}/scenarios" || exit
   364      mkdir -p "${SYNSEC_CONFIG_PATH}/postoverflows" || exit
   365      mkdir -p "${SYNSEC_CONFIG_PATH}/collections" || exit
   366      mkdir -p "${SYNSEC_CONFIG_PATH}/patterns" || exit
   367  
   368      #tmp
   369      mkdir -p /tmp/data
   370      mkdir -p /etc/synsec/hub/
   371      install -v -m 600 -D "./config/${CLIENT_SECRETS}" "${SYNSEC_CONFIG_PATH}" 1> /dev/null || exit
   372      install -v -m 600 -D "./config/${LAPI_SECRETS}" "${SYNSEC_CONFIG_PATH}" 1> /dev/null || exit
   373  
   374      ## end tmp
   375  
   376      install -v -m 644 -D ./config/config.yaml "${SYNSEC_CONFIG_PATH}" 1> /dev/null || exit
   377      install -v -m 644 -D ./config/dev.yaml "${SYNSEC_CONFIG_PATH}" 1> /dev/null || exit
   378      install -v -m 644 -D ./config/user.yaml "${SYNSEC_CONFIG_PATH}" 1> /dev/null || exit
   379      install -v -m 644 -D ./config/acquis.yaml "${SYNSEC_CONFIG_PATH}" 1> /dev/null || exit
   380      install -v -m 644 -D ./config/profiles.yaml "${SYNSEC_CONFIG_PATH}" 1> /dev/null || exit
   381      install -v -m 644 -D ./config/simulation.yaml "${SYNSEC_CONFIG_PATH}" 1> /dev/null || exit
   382  
   383      mkdir -p ${PID_DIR} || exit
   384      PID=${PID_DIR} DATA=${SYNSEC_DATA_DIR} CFG=${SYNSEC_CONFIG_PATH} envsubst '$CFG $PID $DATA' < ./config/user.yaml > ${SYNSEC_CONFIG_PATH}"/user.yaml" || log_fatal "unable to generate user configuration file"
   385      if [[ ${DOCKER_MODE} == "false" ]]; then
   386          CFG=${SYNSEC_CONFIG_PATH} PID=${PID_DIR} BIN=${SYNSEC_BIN_INSTALLED} envsubst '$CFG $PID $BIN' < ./config/synsec.service > "${SYSTEMD_PATH_FILE}" || log_fatal "unable to synsec systemd file"
   387      fi
   388      install_bins
   389  
   390      if [[ ${DOCKER_MODE} == "false" ]]; then
   391  	    systemctl daemon-reload
   392      fi
   393  }
   394  
   395  update_bins() {
   396      log_info "Only upgrading binaries"
   397      delete_bins
   398      install_bins
   399      log_info "Upgrade finished"
   400      systemctl restart synsec || log_fatal "unable to restart synsec with systemctl"
   401  }
   402  
   403  update_full() {
   404  
   405      if [[ ! -f "$SYNSEC_BIN" ]]; then
   406          log_err "Synsec binary '$SYNSEC_BIN' not found. Please build it with 'make build'" && exit
   407      fi
   408      if [[ ! -f "$CCSCLI_BIN" ]]; then
   409          log_err "Cscli binary '$CCSCLI_BIN' not found. Please build it with 'make build'" && exit
   410      fi
   411  
   412      log_info "Backing up existing configuration"
   413      ${CCSCLI_BIN_INSTALLED} config backup ${BACKUP_DIR}
   414      log_info "Saving default database content if exist"
   415      if [[ -f "/var/lib/synsec/data/synsec.db" ]]; then
   416          cp /var/lib/synsec/data/synsec.db ${BACKUP_DIR}/synsec.db
   417      fi
   418      log_info "Cleanup existing synsec configuration"
   419      uninstall_synsec
   420      log_info "Installing synsec"
   421      install_synsec
   422      log_info "Restoring configuration"
   423      ${CCSCLI_BIN_INSTALLED} hub update
   424      ${CCSCLI_BIN_INSTALLED} config restore ${BACKUP_DIR}
   425      log_info "Restoring saved database if exist"
   426      if [[ -f "${BACKUP_DIR}/synsec.db" ]]; then
   427          cp ${BACKUP_DIR}/synsec.db /var/lib/synsec/data/synsec.db
   428      fi
   429      log_info "Finished, restarting"
   430      systemctl restart synsec || log_fatal "Failed to restart synsec"
   431  }
   432  
   433  install_bins() {
   434      log_dbg "Installing synsec binaries"
   435      install -v -m 755 -D "${SYNSEC_BIN}" "${SYNSEC_BIN_INSTALLED}" 1> /dev/null || exit
   436      install -v -m 755 -D "${CCSCLI_BIN}" "${CCSCLI_BIN_INSTALLED}" 1> /dev/null || exit
   437      symlink_bins
   438  }
   439  
   440  symlink_bins() {
   441      if grep -q "${BIN_INSTALL_PATH}" <<< $PATH; then
   442          log_dbg "${BIN_INSTALL_PATH} found in PATH"
   443      else
   444          ln -s "${CCSCLI_BIN_INSTALLED}" /usr/bin/ccscli
   445          ln -s "${SYNSEC_BIN_INSTALLED}" /usr/bin/synsec
   446      fi
   447  }
   448  
   449  delete_bins() {
   450      log_info "Removing synsec binaries"
   451      rm -f ${SYNSEC_BIN_INSTALLED}
   452      rm -f ${CCSCLI_BIN_INSTALLED}
   453  }
   454  
   455  check_running_bouncers() {
   456      #when uninstalling, check if user still has bouncers
   457      BOUNCERS_COUNT=$(${CCSCLI_BIN} bouncers list -o=json | jq '. | length')
   458      if [[ ${BOUNCERS_COUNT} -gt 0 ]] ; then
   459          if [[ ${FORCE_MODE} == "false" ]]; then
   460              echo "WARNING : You have at least one bouncer registered (ccscli bouncers list)."
   461              echo "WARNING : Uninstalling synsec with a running bouncer will let it in an unpredictable state."
   462              echo "WARNING : If you want to uninstall synsec, you should first uninstall the bouncers."
   463              echo "Specify --force to bypass this restriction."
   464              exit 1
   465          fi;
   466      fi
   467  }
   468  
   469  # uninstall synsec and ccscli
   470  uninstall_synsec() {
   471      systemctl stop synsec.service 1>/dev/null
   472      systemctl disable -q synsec.service 1>/dev/null
   473      ${CCSCLI_BIN} dashboard remove -f -y >/dev/null
   474      delete_bins
   475  
   476      # tmp
   477      rm -rf /tmp/data/
   478      ## end tmp
   479  
   480      find /etc/synsec -maxdepth 1 -mindepth 1 | grep -v "bouncer" | xargs rm -rf || echo ""
   481      rm -f ${SYNSEC_LOG_FILE} || echo ""
   482      rm -f ${LAPI_LOG_FILE} || echo ""
   483      rm -f ${SYNSEC_DB_PATH} || echo ""
   484      rm -rf ${SYNSEC_LIB_DIR} || echo ""
   485      rm -rf ${SYNSEC_USR_DIR} || echo ""
   486      rm -f ${SYSTEMD_PATH_FILE} || echo ""
   487      log_info "synsec successfully uninstalled"
   488  }
   489  
   490  
   491  function show_link {
   492      echo ""
   493      echo "Useful links to start with Synsec:"
   494      echo ""
   495      echo "  - Documentation : https://docs.synsec.net/Synsec/v1/getting_started/synsec-tour/"
   496      echo "  - Synsec Hub  : https://hub.synsec.net/ "
   497      echo "  - Open issues   : https://bitbucket.org/Aishee/synsec/issues"
   498      echo ""
   499      echo "Useful commands to start with Synsec:"
   500      echo ""
   501      echo "  - sudo ccscli metrics             : https://docs.synsec.net/Synsec/v1/ccscli/ccscli_metrics/"
   502      echo "  - sudo ccscli decisions list      : https://docs.synsec.net/Synsec/v1/ccscli/ccscli_decisions_list/"
   503      echo "  - sudo ccscli alerts list         : https://docs.synsec.net/Synsec/v1/ccscli/ccscli_alerts_list/"
   504      echo "  - sudo ccscli hub list            : https://docs.synsec.net/Synsec/v1/ccscli/ccscli_hub_list/"
   505      echo ""
   506  }
   507  
   508  main() {
   509      if [ "$1" == "install" ] || [ "$1" == "configure" ]; then
   510          if [ "${SILENT}" == "false" ]; then
   511              which whiptail > /dev/null
   512              if [ $? -ne 0 ]; then
   513                  log_fatal "whiptail binary is needed to use the wizard in interactive mode, exiting ..."
   514              fi
   515          fi
   516          which envsubst > /dev/null
   517          if [ $? -ne 0 ]; then
   518              log_fatal "envsubst binary is needed to use do a full install with the wizard, exiting ..."
   519          fi
   520      fi
   521  
   522      if [[ "$1" == "binupgrade" ]];
   523      then
   524          if ! [ $(id -u) = 0 ]; then
   525              log_err "Please run the wizard as root or with sudo"
   526              exit 1
   527          fi
   528          check_cs_version
   529          update_bins
   530          return
   531      fi
   532  
   533      if [[ "$1" == "upgrade" ]];
   534      then
   535          if ! [ $(id -u) = 0 ]; then
   536              log_err "Please run the wizard as root or with sudo"
   537              exit 1
   538          fi
   539          check_cs_version
   540          update_full
   541          return
   542      fi
   543  
   544      if [[ "$1" == "configure" ]];
   545      then
   546          if ! [ $(id -u) = 0 ]; then
   547              log_err "Please run the wizard as root or with sudo"
   548              exit 1
   549          fi
   550          detect_services
   551          ${CCSCLI_BIN_INSTALLED} hub update
   552          install_collection
   553          genacquisition
   554          mv "${TMP_ACQUIS_FILE}" "${ACQUIS_TARGET}"
   555  
   556          return
   557      fi
   558  
   559      if [[ "$1" == "noop" ]];
   560      then
   561          return
   562      fi
   563  
   564      if [[ "$1" == "uninstall" ]];
   565      then
   566          if ! [ $(id -u) = 0 ]; then
   567              log_err "Please run the wizard as root or with sudo"
   568              exit 1
   569          fi
   570          check_running_bouncers
   571          uninstall_synsec
   572          return
   573      fi
   574  
   575      if [[ "$1" == "bininstall" ]];
   576      then
   577          if ! [ $(id -u) = 0 ]; then
   578              log_err "Please run the wizard as root or with sudo"
   579              exit 1
   580          fi
   581          log_info "checking existing synsec install"
   582          detect_cs_install
   583          log_info "installing synsec"
   584          install_synsec
   585  
   586          show_link
   587          return
   588      fi
   589  
   590      if [[ "$1" == "install" ]];
   591      then
   592          if ! [ $(id -u) = 0 ]; then
   593              log_err "Please run the wizard as root or with sudo"
   594              exit 1
   595          fi
   596          log_info "checking if synsec is installed"
   597          detect_cs_install
   598          ## Do make build before installing (as non--root) in order to have the binary and then install synsec as root
   599          log_info "installing synsec"
   600          install_synsec
   601          log_dbg "configuring ${CCSCLI_BIN_INSTALLED}"
   602          ${CCSCLI_BIN_INSTALLED} hub update > /dev/null 2>&1 || (log_err "fail to update synsec hub. exiting" && exit 1)
   603  
   604          # detect running services
   605          detect_services
   606          if ! [ ${#DETECTED_SERVICES[@]} -gt 0 ] ; then
   607              log_err "No detected or selected services, stopping."
   608              exit 1
   609          fi;
   610  
   611          # Generate acquisition file and move it to the right folder
   612          genacquisition
   613          mv "${TMP_ACQUIS_FILE}" "${ACQUIS_TARGET}"
   614          log_info "acquisition file path: ${ACQUIS_TARGET}"
   615          # Install collections according to detected services
   616          log_dbg "Installing needed collections ..."
   617          install_collection
   618  
   619          # install patterns/ folder
   620          log_dbg "Installing patterns"
   621          mkdir -p "${PATTERNS_PATH}"
   622          cp "./${PATTERNS_FOLDER}/"* "${PATTERNS_PATH}/"
   623  
   624  
   625          # api register
   626          ${CCSCLI_BIN_INSTALLED} machines add --force "$(cat /etc/machine-id)" -a -f "${SYNSEC_CONFIG_PATH}/${CLIENT_SECRETS}" || log_fatal "unable to add machine to the local API"
   627          log_dbg "Synsec LAPI registered"
   628  
   629          ${CCSCLI_BIN_INSTALLED} capi register || log_fatal "unable to register to the Central API"
   630          log_dbg "Synsec CAPI registered"
   631  
   632          systemctl enable -q synsec >/dev/null || log_fatal "unable to enable synsec"
   633          systemctl start synsec >/dev/null || log_fatal "unable to start synsec"
   634          log_info "enabling and starting synsec daemon"
   635          show_link
   636          return
   637      fi
   638  
   639      if [[ "$1" == "detect" ]];
   640      then
   641          rm -f "${TMP_ACQUIS_FILE}"
   642          detect_services
   643          if [[ ${DETECTED_SERVICES} == "" ]] ; then
   644              log_err "No detected or selected services, stopping."
   645              exit
   646          fi;
   647          log_info "Found ${#DETECTED_SERVICES[@]} supported services running:"
   648          genacquisition
   649          cat "${TMP_ACQUIS_FILE}"
   650          rm "${TMP_ACQUIS_FILE}"
   651          return
   652      fi
   653  
   654  }
   655  
   656  usage() {
   657        echo "Usage:"
   658        echo "    ./wizard.sh -h                               Display this help message."
   659        echo "    ./wizard.sh -d|--detect                      Detect running services and associated logs file"
   660        echo "    ./wizard.sh -i|--install                     Assisted installation of synsec/ccscli and collections"
   661        echo "    ./wizard.sh --bininstall                     Install binaries and empty config, no wizard."
   662        echo "    ./wizard.sh --uninstall                      Uninstall synsec/ccscli"
   663        echo "    ./wizard.sh --binupgrade                     Upgrade synsec/ccscli binaries"
   664        echo "    ./wizard.sh --upgrade                        Perform a full upgrade and try to migrate configs"
   665        echo "    ./wizard.sh --unattended                     Install in unattended mode, no question will be asked and defaults will be followed"
   666        echo "    ./wizard.sh --docker-mode                    Will install synsec without systemd and generate random machine-id"
   667        echo "    ./wizard.sh -n|--noop                        Do nothing"
   668  
   669        exit 0
   670  }
   671  
   672  if [[ $# -eq 0 ]]; then
   673  usage
   674  fi
   675  
   676  while [[ $# -gt 0 ]]
   677  do
   678      key="${1}"
   679      case ${key} in
   680      --uninstall)
   681          ACTION="uninstall"
   682          shift #past argument
   683          ;;
   684      --binupgrade)
   685          ACTION="binupgrade"
   686          shift #past argument
   687          ;;
   688      --upgrade)
   689          ACTION="upgrade"
   690          shift #past argument
   691          ;;
   692      -i|--install)
   693          ACTION="install"
   694          shift # past argument
   695          ;;
   696      --bininstall)
   697          ACTION="bininstall"
   698          shift # past argument
   699          ;;
   700      --docker-mode)
   701          DOCKER_MODE="true"
   702          ACTION="bininstall"
   703          shift # past argument
   704          ;;
   705      -c|--configure)
   706          ACTION="configure"
   707          shift # past argument
   708          ;;
   709      -d|--detect)
   710          ACTION="detect"
   711          shift # past argument
   712          ;;
   713      -n|--noop)
   714          ACTION="noop"
   715          shift # past argument
   716          ;;
   717      --unattended)
   718          SILENT="true"
   719          ACTION="install"
   720          shift
   721          ;;
   722      -f|--force)
   723          FORCE_MODE="true"
   724          shift
   725          ;;
   726      -v|--verbose)
   727          DEBUG_MODE="true"
   728          shift
   729          ;;
   730      -h|--help)
   731          usage
   732          exit 0
   733          ;;
   734      *)    # unknown option
   735          log_err "Unknown argument ${key}."
   736          usage
   737          exit 1
   738          ;;
   739      esac
   740  done
   741  
   742  main ${ACTION}