104 lines
3.2 KiB
Go
104 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"crowdsec-dashy/internal/config"
|
|
"crowdsec-dashy/internal/crowdsec"
|
|
"crowdsec-dashy/internal/geoip"
|
|
"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)
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
// GeoIP auto-updater
|
|
// ----------------------------------------------------------------
|
|
geoUpdater := geoip.New(cfg.IPInfoToken, cfg.IPInfoDBFile, cfg.IPInfoDBPath, cfg.IPInfoRefreshDays)
|
|
go geoUpdater.Start(context.Background())
|
|
|
|
// ----------------------------------------------------------------
|
|
// Build router
|
|
// ----------------------------------------------------------------
|
|
handler, err := router.New(cfg, lapi, webfiles.FS, geoUpdater)
|
|
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)
|
|
}
|
|
}
|