opnsense-portal/cmd/vpnportal/check.go
Carsten Abele 0fc2d8808b feat(auth): konfigurierbare TLS-Mindestversion fuer den Verzeichnisdienst
Domain Controller auf Windows Server 2012 R2 koennen TLS 1.2 per Registry
deaktiviert haben. ad.min_tls_version (Default 1.2) erlaubt es, fuer solche
Altsysteme auf 1.0/1.1 herunterzugehen; das Portal warnt dann bei jedem Start.

Die Zertifikatspruefung bleibt in jedem Fall aktiv — fuer LDAP gibt es
weiterhin keine Insecure-Option. Im Legacy-Modus kommen lediglich die
CBC-SHA256-Suiten hinzu, die Go als unsicher einstuft; RC4, 3DES und Suiten
ohne Forward Secrecy werden nie angeboten.

README dokumentiert zusaetzlich die beiden anderen 2012-R2-Stolpersteine:
SHA-1-signierte DC-Zertifikate (seit Go 1.24 nicht mehr umgehbar) und
RSA-Schluesselaustausch (nur ueber GODEBUG=tlsrsakex=1).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBHF4R9EAejDJUMdwr6C68
2026-08-14 13:18:24 +02:00

81 lines
2.3 KiB
Go

package main
import (
"context"
"fmt"
"io"
"time"
"git.ravensburg.dev/cabele/opnsense-portal/internal/auth"
"git.ravensburg.dev/cabele/opnsense-portal/internal/check"
"git.ravensburg.dev/cabele/opnsense-portal/internal/config"
"git.ravensburg.dev/cabele/opnsense-portal/internal/opnsense"
)
func runCheck(args []string, stdout, stderr io.Writer) int {
fs, path := configFlags("check", stderr)
testAuth := fs.String("test-auth", "",
"Suche und Gruppenprüfung für einen konkreten Benutzer durchspielen (ohne Passwort)")
if err := fs.Parse(args); err != nil {
return 2
}
cfg, err := config.Load(*path, nil)
if err != nil {
// Ohne lesbare Konfiguration lässt sich nichts weiter prüfen.
fmt.Fprintf(stdout, "✗ Konfiguration\n %v\n", err)
return 1
}
fw, ad, err := buildBackends(cfg)
if err != nil {
fmt.Fprintf(stdout, "✗ Initialisierung\n %v\n", err)
return 1
}
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
c := &check.Checker{Cfg: cfg, ConfigPath: *path, FW: fw, Dir: ad}
report := c.Run(ctx, *testAuth)
report.WriteTo(stdout)
if !report.OK() {
fmt.Fprintln(stdout, "\nEs sind Fehler aufgetreten. Das Portal würde nicht korrekt arbeiten.")
return 1
}
fmt.Fprintln(stdout, "\nAlle Prüfungen bestanden.")
return 0
}
// buildBackends erzeugt Firewall- und Verzeichnis-Client aus der Konfiguration.
// Wird von serve und check gemeinsam genutzt.
func buildBackends(cfg *config.Config) (*opnsense.Client, *auth.AD, error) {
fw, err := opnsense.New(opnsense.Options{
BaseURL: cfg.OPNsense.URL,
APIKey: cfg.OPNsense.APIKey,
APISecret: cfg.OPNsense.APISecret,
CAFile: cfg.OPNsense.CAFile,
InsecureSkipVerify: cfg.OPNsense.InsecureSkipVerify,
Timeout: 20 * time.Second,
})
if err != nil {
return nil, nil, err
}
ad, err := auth.NewAD(auth.Options{
Servers: cfg.AD.Servers,
Port: cfg.AD.Port,
TLSMode: cfg.AD.TLSMode,
BaseDN: cfg.EffectiveBaseDN(),
BindUser: cfg.AD.BindUser,
BindPassword: cfg.AD.BindPassword,
VPNGroup: cfg.AD.VPNGroup,
CAFile: cfg.AD.CAFile,
MinTLSVersion: auth.ParseTLSVersion(cfg.AD.MinTLSVersion),
Timeout: time.Duration(cfg.AD.Timeout),
})
if err != nil {
return nil, nil, err
}
return fw, ad, nil
}