feat: add resilient updates and access controls
Container-Image veröffentlichen / container (push) Has been cancelled
Container-Image veröffentlichen / container (push) Has been cancelled
This commit is contained in:
1 parent
a000152423
commit
f02ec9977c
41 files changed
+3277
-151
No files matched your search
@@ -1,8 +1,10 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -27,6 +29,9 @@ type Config struct {
|
||||
HCloudBaseURL string
|
||||
Mode string
|
||||
ShutdownTimeout time.Duration
|
||||
UpdateAPIURL string
|
||||
UpdateAgentSock string
|
||||
UpdateInterval time.Duration
|
||||
}
|
||||
|
||||
func Load() (Config, error) {
|
||||
@@ -51,6 +56,14 @@ func Load() (Config, error) {
|
||||
}
|
||||
|
||||
keyFile := value("APP_MASTER_KEY_FILE", "/secrets/master_key")
|
||||
updateInterval, err := duration("APP_SOFTWARE_UPDATE_CHECK_INTERVAL", 6*time.Hour)
|
||||
if err != nil || updateInterval < 15*time.Minute || updateInterval > 7*24*time.Hour {
|
||||
return Config{}, fmt.Errorf("APP_SOFTWARE_UPDATE_CHECK_INTERVAL must be between 15m and 168h")
|
||||
}
|
||||
updateAPIURL := value("APP_SOFTWARE_UPDATE_API_URL", "https://git.j-mahler.de/api/v1/repos/admin/hetzner-api-dyndns-records-webinterface/releases/latest")
|
||||
if err := validateUpdateURL(updateAPIURL); err != nil {
|
||||
return Config{}, fmt.Errorf("APP_SOFTWARE_UPDATE_API_URL: %w", err)
|
||||
}
|
||||
|
||||
cookieSecure := mode == "https"
|
||||
if raw := os.Getenv("APP_COOKIE_SECURE"); raw != "" {
|
||||
@@ -71,9 +84,28 @@ func Load() (Config, error) {
|
||||
HCloudBaseURL: strings.TrimRight(value("APP_HCLOUD_BASE_URL", "https://api.hetzner.cloud/v1"), "/"),
|
||||
Mode: mode,
|
||||
ShutdownTimeout: shutdownTimeout,
|
||||
UpdateAPIURL: updateAPIURL,
|
||||
UpdateAgentSock: value("APP_SOFTWARE_UPDATE_AGENT_SOCKET", "/run/domain-control-update/agent.sock"),
|
||||
UpdateInterval: updateInterval,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func validateUpdateURL(raw string) error {
|
||||
parsed, err := url.Parse(raw)
|
||||
if err != nil || parsed.Host == "" || parsed.User != nil || (parsed.Scheme != "https" && parsed.Scheme != "http") {
|
||||
return errors.New("must be an absolute HTTPS URL without embedded credentials")
|
||||
}
|
||||
if parsed.Scheme == "https" {
|
||||
return nil
|
||||
}
|
||||
host := parsed.Hostname()
|
||||
address := net.ParseIP(host)
|
||||
if host == "localhost" || (address != nil && address.IsLoopback()) {
|
||||
return nil
|
||||
}
|
||||
return errors.New("HTTP is allowed only for loopback test endpoints")
|
||||
}
|
||||
|
||||
func value(name, fallback string) string {
|
||||
if v := strings.TrimSpace(os.Getenv(name)); v != "" {
|
||||
return v
|
||||
|
||||
Reference in new issue
Block a user