From 87a90583feced8c806f5f77263d3fb4a4de60a70 Mon Sep 17 00:00:00 2001 From: AlteredCoder <64792091+AlteredCoder@users.noreply.github.com> Date: Thu, 16 Jul 2020 15:48:46 +0200 Subject: [PATCH] Fix#80 (#133) * fix #80 Co-authored-by: AlteredCoder Co-authored-by: Thibault bui Koechlin --- cmd/crowdsec-cli/backup-restore.go | 73 ++++++++++++++++++++++++++++-- pkg/outputs/ouputs.go | 2 + wizard.sh | 28 +++++++++--- 3 files changed, 93 insertions(+), 10 deletions(-) diff --git a/cmd/crowdsec-cli/backup-restore.go b/cmd/crowdsec-cli/backup-restore.go index c9d1536a0..32dfb5c53 100644 --- a/cmd/crowdsec-cli/backup-restore.go +++ b/cmd/crowdsec-cli/backup-restore.go @@ -168,10 +168,8 @@ func restoreFromDirectory(source string) error { destinationFile := fmt.Sprintf("%s%s", stagedir, tfile.Name()) if err = copyFile(sourceFile, destinationFile); err != nil { return fmt.Errorf("failed copy %s %s to %s : %s", itype, sourceFile, destinationFile, err) - } else { - log.Infof("restored %s to %s", sourceFile, destinationFile) } - + log.Infof("restored %s to %s", sourceFile, destinationFile) } } } @@ -195,6 +193,39 @@ func restoreFromDirectory(source string) error { } log.Infof("Restore acquis to %s", yamlAcquisFile) + /* Restore plugins configuration */ + var pluginsConfigFile []string + walkErr := filepath.Walk(fmt.Sprintf("%s/plugins/backend/", source), func(path string, info os.FileInfo, err error) error { + if err != nil { + return fmt.Errorf("walk error : %s", err) + } + fi, err := os.Stat(path) + if err != nil { + return fmt.Errorf("unable to stats file '%s' : %s", path, err) + } + mode := fi.Mode() + if mode.IsRegular() { + pluginsConfigFile = append(pluginsConfigFile, path) + } + return nil + }) + if walkErr != nil { + return fmt.Errorf("error while listing folder '%s' : %s", fmt.Sprintf("%s/plugins/backend/", source), walkErr) + } + + if err := os.MkdirAll(outputCTX.Config.BackendFolder, os.ModePerm); err != nil { + return fmt.Errorf("error while creating backup folder dir %s : %s", outputCTX.Config.BackendFolder, err) + } + + for _, file := range pluginsConfigFile { + _, filename := path.Split(file) + backupFile := fmt.Sprintf("%s/%s", outputCTX.Config.BackendFolder, filename) + log.Printf("Restoring '%s' to '%s'", file, backupFile) + if err := copyFile(file, backupFile); err != nil { + return fmt.Errorf("error while copying '%s' to '%s' : %s", file, backupFile, err) + } + } + return nil } @@ -367,6 +398,40 @@ func backupToDirectory(target string) error { return fmt.Errorf("unable to write credentials to %s : %s", apiCredsDumped, err) } log.Infof("Saved configuration to %s", target) + + /* Backup plugins configuration */ + var pluginsConfigFile []string + walkErr := filepath.Walk(outputCTX.Config.BackendFolder, func(path string, info os.FileInfo, err error) error { + if err != nil { + return fmt.Errorf("walk error : %s", err) + } + fi, err := os.Stat(path) + if err != nil { + return fmt.Errorf("unable to stats file '%s' : %s", path, err) + } + mode := fi.Mode() + if mode.IsRegular() { + pluginsConfigFile = append(pluginsConfigFile, path) + } + return nil + }) + if walkErr != nil { + return fmt.Errorf("error while listing folder '%s' : %s", outputCTX.Config.BackendFolder, walkErr) + } + + targetDir := fmt.Sprintf("%s/plugins/backend/", target) + if err := os.MkdirAll(targetDir, os.ModePerm); err != nil { + return fmt.Errorf("error while creating backup folder dir %s : %s", targetDir, err) + } + + for _, file := range pluginsConfigFile { + _, filename := path.Split(file) + backupFile := fmt.Sprintf("%s/plugins/backend/%s", target, filename) + if err := copyFile(file, backupFile); err != nil { + return fmt.Errorf("unable to copy file '%s' to '%s' : %s", file, backupFile, err) + } + } + return nil } @@ -396,7 +461,7 @@ cscli backup restore ./my-backup`, - Backup of API credentials -- Backup of acqusition configuration +- Backup of acquisition configuration `, Example: `cscli backup save ./my-backup`, diff --git a/pkg/outputs/ouputs.go b/pkg/outputs/ouputs.go index e51cc289c..40ed67055 100644 --- a/pkg/outputs/ouputs.go +++ b/pkg/outputs/ouputs.go @@ -35,6 +35,7 @@ type OutputFactory struct { type Output struct { API *cwapi.ApiCtx bManager *cwplugin.BackendManager + Config *OutputFactory } /* @@ -351,5 +352,6 @@ func NewOutput(config *OutputFactory) (*Output, error) { if err != nil { return nil, errors.Wrap(err, "failed to load backend plugin") } + output.Config = config return &output, nil } diff --git a/wizard.sh b/wizard.sh index e814ace9d..55a76a74c 100755 --- a/wizard.sh +++ b/wizard.sh @@ -266,6 +266,23 @@ genacquisition() { done } +delete_plugins(){ + rm -rf "${CROWDSEC_PLUGIN_DIR}" + rm -rf "${CROWDSEC_BACKEND_FOLDER}" +} + +install_plugins() { + install_plugins_bin + mkdir -p "${CROWDSEC_BACKEND_FOLDER}" || exit + cp -r ./config/plugins/backend/* "${CROWDSEC_BACKEND_FOLDER}" || exit +} + +install_plugins_bin() { + mkdir -p "${CROWDSEC_PLUGIN_BACKEND_DIR}" || exit + (cd ./plugins && find . -type f -name "*.so" -exec install -Dm 644 {} "${CROWDSEC_PLUGIN_DIR}/{}" \; && cd ../) || exit +} + + #install crowdsec and cscli install_crowdsec() { mkdir -p "${CROWDSEC_DATA_DIR}" @@ -275,14 +292,8 @@ install_crowdsec() { mkdir -p "${CROWDSEC_CONFIG_PATH}/postoverflows" || exit mkdir -p "${CROWDSEC_CONFIG_PATH}/collections" || exit mkdir -p "${CROWDSEC_CONFIG_PATH}/patterns" || exit - - mkdir -p "${CROWDSEC_BACKEND_FOLDER}" || exit - mkdir -p "${CROWDSEC_PLUGIN_BACKEND_DIR}" || exit mkdir -p "${CSCLI_FOLDER}" || exit - (cd ./plugins && find . -type f -name "*.so" -exec install -Dm 644 {} "${CROWDSEC_PLUGIN_DIR}/{}" \; && cd ../) || exit - cp -r ./config/plugins/backend/* "${CROWDSEC_BACKEND_FOLDER}" || exit - install -v -m 755 -D ./config/prod.yaml "${CROWDSEC_CONFIG_PATH}" || exit install -v -m 755 -D ./config/dev.yaml "${CROWDSEC_CONFIG_PATH}" || exit install -v -m 755 -D ./config/acquis.yaml "${CROWDSEC_CONFIG_PATH}" || exit @@ -293,6 +304,7 @@ install_crowdsec() { PID=${PID_DIR} DATA=${CROWDSEC_DATA_DIR} CFG=${CROWDSEC_CONFIG_PATH} envsubst '$CFG $PID $DATA' < ./config/user.yaml > ${CROWDSEC_CONFIG_PATH}"/user.yaml" CFG=${CROWDSEC_CONFIG_PATH} PID=${PID_DIR} BIN=${CROWDSEC_BIN_INSTALLED} envsubst '$CFG $PID $BIN' < ./config/crowdsec.service > "${SYSTEMD_PATH_FILE}" install_bins + install_plugins systemctl daemon-reload } @@ -300,10 +312,12 @@ update_bins() { log_info "Only upgrading binaries" delete_bins install_bins + install_plugins_bin log_info "Upgrade finished" systemctl restart crowdsec } + update_full() { if [[ ! -f "$CROWDSEC_BIN" ]]; then @@ -334,6 +348,7 @@ install_bins() { log_info "Installing crowdsec binaries" install -v -m 755 -D "${CROWDSEC_BIN}" "${CROWDSEC_BIN_INSTALLED}" || exit install -v -m 755 -D "${CSCLI_BIN}" "${CSCLI_BIN_INSTALLED}" || exit + install_plugins_bin || exit } delete_bins() { @@ -347,6 +362,7 @@ uninstall_crowdsec() { systemctl stop crowdsec.service ${CSCLI_BIN} dashboard stop --remove delete_bins + delete_plugins rm -rf ${CROWDSEC_PATH} || echo "" rm -f ${CROWDSEC_LOG_FILE} || echo "" rm -f ${CROWDSEC_DB_PATH} || echo ""