diff --git a/main.go b/main.go index 7ecabfe..a7309fb 100644 --- a/main.go +++ b/main.go @@ -41,42 +41,33 @@ var ( // ------------------------------------- -func loadOrCreateHostKey(path string) (ssh.Signer, error) { - if _, err := os.Stat(path); err == nil { - b, err := os.ReadFile(path) - if err != nil { - return nil, err - } - return ssh.ParsePrivateKey(b) - } - _, priv, err := ed25519.GenerateKey(rand.Reader) - if err != nil { - return nil, err - } - pkcs8, err := x509.MarshalPKCS8PrivateKey(priv) - if err != nil { - return nil, err - } - block := &pem.Block{Type: "PRIVATE KEY", Bytes: pkcs8} - pemBytes := pem.EncodeToMemory(block) - if err := os.WriteFile(path, pemBytes, 0o600); err != nil { - return nil, err - } - return ssh.ParsePrivateKey(pemBytes) -} +// ---------- SFTP Server ---------- + +// startSFTPServer démarre un serveur SFTP sur le port 2222 +// avec authentification par IP-allowlist et user/pass. +// Le dossier racine SFTP est défini par `base`. +// Les clés hôte sont générées ou chargées depuis le disque. +// Les IP autorisées peuvent se connecter sans mot de passe. +// Les autres doivent utiliser le login et mot de passe définis. +// Le serveur écoute sur le port 2222 et gère les connexions SFTP. +// Il utilise les clés hôte ed25519 et RSA pour la compatibilité. +// Les connexions TCP ont un keep-alive agressif pour éviter les coupures NAT. +// Les erreurs de connexion sont loguées, mais le serveur continue à accepter les connexions. +// Les requêtes SFTP sont traitées avec un serveur SFTP minimaliste. +// Les erreurs de traitement des requêtes sont loguées. +// Le serveur est conçu pour être lancé dans un goroutine séparé. +// Il vérifie que le dossier racine existe et est un répertoire valide. +// Les clés hôte sont stockées dans le même répertoire que le serveur SFTP. +// Le serveur utilise le protocole SSH pour établir les connexions SFTP. +// Il gère les canaux de session et les requêtes de sous-système SFTP. +// Les connexions sont acceptées en boucle infinie, avec des logs pour chaque connexion réussie ou échouée. +// Les erreurs de handshake SSH sont loguées et la connexion est fermée. +// Les canaux SFTP sont acceptés et traités pour servir les requêtes SFTP. +// Le serveur SFTP est initialisé avec des gestionnaires par défaut pour les opérations de fichier. +// Les erreurs lors de l'initialisation ou du traitement des requêtes SFTP sont loguées. +// Le serveur continue à accepter les connexions même après des erreurs, garantissant une disponibilité maximale. +// Il est recommandé de lancer cette fonction dans un goroutine séparé pour ne pas bloquer l'exécution principale du programme. -func ipAllowed(addr string) bool { - host, _, err := net.SplitHostPort(addr) - if err != nil { - host = addr - } - for _, allow := range AllowedIPs { - if host == allow { - return true - } - } - return false -} func startSFTPServer(base string) { // --- helpers locaux pour charger/générer les clés hôte --- @@ -243,24 +234,20 @@ func startSFTPServer(base string) { func startHTTP() { bd := db.InitDB() - app := gin.Default() - - api := app.Group("/api/v1") - routes.AddRoutes(api, bd) - utils.CreateDefaultFolder(bd) - - app.Static("/static", "./web") - app.NoRoute(func(c *gin.Context) { - if strings.HasPrefix(c.Request.URL.Path, "/api/") { - c.JSON(404, gin.H{"error": "Not found"}) - return + app := gin.Default() + api := app.Group("/api/v1") + routes.AddRoutes(api, bd) + utils.CreateDefaultFolder(bd) + app.Static("/static", "./web") + app.NoRoute(func(c *gin.Context) { + if strings.HasPrefix(c.Request.URL.Path, "/api/") { + c.JSON(404, gin.H{"error": "Not found"}) + return } - c.File("./web/index.html") - }) - - log.Println("[HTTP] Serveur Gin sur http://0.0.0.0:8080") - _ = app.Run(":8080") -} + c.File("./web/index.html") }) + log.Println("[HTTP] Serveur Gin sur http://localhost:8080") + app.Run(":8080") + } func main() { // SFTP sur 2222 (root = ./upload)