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}