package main import ( "context" "errors" "flag" "fmt" "log" "net/http" "os" "time" "crowdsec-dashy/internal/config" "crowdsec-dashy/internal/crowdsec" "crowdsec-dashy/internal/router" webfiles "crowdsec-dashy/web" ) func main() { // ---------------------------------------------------------------- // CLI flags // ---------------------------------------------------------------- pwhash := flag.String("pwhash", "", "hash a password for use as ui_password in app_config.conf") flag.Parse() if *pwhash != "" { hash, err := config.HashPassword(*pwhash) if err != nil { log.Fatalf("hash password: %v", err) } fmt.Println(hash) os.Exit(0) } // ---------------------------------------------------------------- // Configuration // ---------------------------------------------------------------- cfg, err := config.Load() if err != nil { var firstRun *config.FirstRunError if errors.As(err, &firstRun) { log.Println(firstRun.Error()) os.Exit(0) } log.Fatalf("configuration error: %v", err) } // ---------------------------------------------------------------- // CrowdSec LAPI — authenticate at startup // ---------------------------------------------------------------- lapi := crowdsec.NewLAPIClient(cfg.CrowdSecAPIURL, cfg.CrowdSecAPILogin, cfg.CrowdSecAPIPassword) log.Printf("connecting to CrowdSec LAPI at %s ...", cfg.CrowdSecAPIURL) ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) if err := lapi.Login(ctx); err != nil { cancel() log.Fatalf("failed to authenticate with CrowdSec LAPI: %v\n"+ "Check crowdsec_api_login / crowdsec_api_password in %s\n"+ "Register the machine first: cscli machines add %s -a", err, config.ConfigFile(), cfg.CrowdSecAPILogin) } cancel() log.Println("authenticated with CrowdSec LAPI") // CLI availability if cfg.CscliAvailable() { log.Printf("cscli available at %s", cfg.CscliPath) } else { log.Printf("[WARN] cscli not found at %s — bouncer/machine/hub/metrics features disabled", cfg.CscliPath) } // ---------------------------------------------------------------- // Build router // ---------------------------------------------------------------- handler, err := router.New(cfg, lapi, webfiles.FS) if err != nil { log.Fatalf("failed to initialise router: %v", err) } // ---------------------------------------------------------------- // HTTP server // ---------------------------------------------------------------- srv := &http.Server{ Addr: cfg.Port, Handler: handler, ReadTimeout: 10 * time.Second, WriteTimeout: 60 * time.Second, // longer for hub operations IdleTimeout: 120 * time.Second, } log.Printf("CrowdSec UI listening on %s", srv.Addr) log.Printf("UI credentials: %s / [redacted]", cfg.UIUsername) if err := srv.ListenAndServe(); err != nil { log.Fatalf("server error: %v", err) } }