feat: HA-Cluster v1.2.x — Split-Brain, TOTP, Enterprise-FW, Drift-Fix, VIP-Recovery
- keepalived: pg_role='standby' hat Vorrang vor role für BACKUP-Bestimmung - keepalived-master.sh: gecrasht Dienste beim MASTER-Übergang starten (nicht nur reload) - confighash: ip_addresses per Interface-Name hashen statt per FK (Cross-Node-Drift-Fix) - TOTP/2FA: RFC 6238 — Setup-Flow, QR-Code, Admin-Disable; two-step Login - Firewall-UI: Enterprise-Design — auto-Beschreibung, icon-only Actions, zero-hit Indikator - fe80-Filter: Link-local IPv6 aus NTP/DNS Listen-Dropdowns entfernen - VIP-Dashboard, Dual-Path VRRP, GW-Tracking (Migrations 0033/0034) - Forward Proxy + DNS erweiterte Einstellungen (Migrations 0031/0032) - unbound-control: edgeguard in unbound-Gruppe via postinst Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,12 +4,19 @@ import "time"
|
||||
|
||||
// ClusterSettings ist die Singleton-Tabelle (id=1) für VIP/VRRP-
|
||||
// und Replikations-Konfiguration. Angelegt in Migration 0029.
|
||||
// hb_* = zweite VRRP-Instanz für Split-Brain-Schutz (0033).
|
||||
// gw_check_ip = Gateway-IP für vrrp_script chk_gateway (0033).
|
||||
type ClusterSettings struct {
|
||||
ID int `gorm:"column:id;primaryKey" json:"id"`
|
||||
VIPAddress *string `gorm:"column:vip_address" json:"vip_address,omitempty"`
|
||||
VIPInterface *string `gorm:"column:vip_interface" json:"vip_interface,omitempty"`
|
||||
VIPAuthPass *string `gorm:"column:vip_auth_pass" json:"vip_auth_pass,omitempty"`
|
||||
VRRPRouterID int `gorm:"column:vrrp_router_id" json:"vrrp_router_id"`
|
||||
HBInterface *string `gorm:"column:hb_interface" json:"hb_interface,omitempty"`
|
||||
HBSrcIP *string `gorm:"column:hb_src_ip" json:"hb_src_ip,omitempty"`
|
||||
HBPeerIP *string `gorm:"column:hb_peer_ip" json:"hb_peer_ip,omitempty"`
|
||||
HBRouterID int `gorm:"column:hb_router_id" json:"hb_router_id"`
|
||||
GWCheckIP *string `gorm:"column:gw_check_ip" json:"gw_check_ip,omitempty"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
@@ -40,16 +40,20 @@ func (DNSRecord) TableName() string { return "dns_records" }
|
||||
// Optionen. Default kommt aus der Migration (alle Werte sinnvoll
|
||||
// für die typische LAN-Resolver-Rolle).
|
||||
type DNSSettings struct {
|
||||
ID int64 `gorm:"primaryKey" json:"id"`
|
||||
ListenAddresses string `gorm:"column:listen_addresses" json:"listen_addresses"`
|
||||
ListenPort int `gorm:"column:listen_port" json:"listen_port"`
|
||||
UpstreamForwards string `gorm:"column:upstream_forwards" json:"upstream_forwards"`
|
||||
AccessACL string `gorm:"column:access_acl" json:"access_acl"`
|
||||
DNSSEC bool `gorm:"column:dnssec" json:"dnssec"`
|
||||
QNameMinimisation bool `gorm:"column:qname_minimisation" json:"qname_minimisation"`
|
||||
CacheMinTTL int `gorm:"column:cache_min_ttl" json:"cache_min_ttl"`
|
||||
CacheMaxTTL int `gorm:"column:cache_max_ttl" json:"cache_max_ttl"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
ID int64 `gorm:"primaryKey" json:"id"`
|
||||
ListenAddresses string `gorm:"column:listen_addresses" json:"listen_addresses"`
|
||||
ListenPort int `gorm:"column:listen_port" json:"listen_port"`
|
||||
UpstreamForwards string `gorm:"column:upstream_forwards" json:"upstream_forwards"`
|
||||
AccessACL string `gorm:"column:access_acl" json:"access_acl"`
|
||||
DNSSEC bool `gorm:"column:dnssec" json:"dnssec"`
|
||||
QNameMinimisation bool `gorm:"column:qname_minimisation" json:"qname_minimisation"`
|
||||
CacheMinTTL int `gorm:"column:cache_min_ttl" json:"cache_min_ttl"`
|
||||
CacheMaxTTL int `gorm:"column:cache_max_ttl" json:"cache_max_ttl"`
|
||||
Prefetch bool `gorm:"column:prefetch" json:"prefetch"`
|
||||
ServeExpired bool `gorm:"column:serve_expired" json:"serve_expired"`
|
||||
MsgCacheSizeMB int `gorm:"column:msg_cache_size_mb" json:"msg_cache_size_mb"`
|
||||
RRSetCacheSizeMB int `gorm:"column:rrset_cache_size_mb" json:"rrset_cache_size_mb"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
func (DNSSettings) TableName() string { return "dns_settings" }
|
||||
|
||||
19
internal/models/forward_proxy_settings.go
Normal file
19
internal/models/forward_proxy_settings.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type ForwardProxySettings struct {
|
||||
ID int `gorm:"primaryKey" json:"id"`
|
||||
ListenAddresses string `gorm:"column:listen_addresses" json:"listen_addresses"`
|
||||
ListenPort int `gorm:"column:listen_port" json:"listen_port"`
|
||||
CacheMemMB int `gorm:"column:cache_mem_mb" json:"cache_mem_mb"`
|
||||
CacheDirMB int `gorm:"column:cache_dir_mb" json:"cache_dir_mb"`
|
||||
MaxObjSizeMB int `gorm:"column:max_obj_size_mb" json:"max_obj_size_mb"`
|
||||
ConnectTimeout int `gorm:"column:connect_timeout" json:"connect_timeout"`
|
||||
ReadTimeout int `gorm:"column:read_timeout" json:"read_timeout"`
|
||||
RequestTimeout int `gorm:"column:request_timeout" json:"request_timeout"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
func (ForwardProxySettings) TableName() string { return "forward_proxy_settings" }
|
||||
Reference in New Issue
Block a user