wip: migrate to mono-repo. SPN has already been moved to spn/
This commit is contained in:
392
spn/cabin/config-public.go
Normal file
392
spn/cabin/config-public.go
Normal file
@@ -0,0 +1,392 @@
|
||||
package cabin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/safing/portbase/config"
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
"github.com/safing/portmaster/service/profile/endpoints"
|
||||
"github.com/safing/portmaster/spn/hub"
|
||||
)
|
||||
|
||||
// Configuration Keys.
|
||||
var (
|
||||
// Name of the node.
|
||||
publicCfgOptionNameKey = "spn/publicHub/name"
|
||||
publicCfgOptionName config.StringOption
|
||||
publicCfgOptionNameDefault = ""
|
||||
publicCfgOptionNameOrder = 512
|
||||
|
||||
// Person or organisation, who is in control of the node (should be same for all nodes of this person or organisation).
|
||||
publicCfgOptionGroupKey = "spn/publicHub/group"
|
||||
publicCfgOptionGroup config.StringOption
|
||||
publicCfgOptionGroupDefault = ""
|
||||
publicCfgOptionGroupOrder = 513
|
||||
|
||||
// Contact possibility (recommended, but optional).
|
||||
publicCfgOptionContactAddressKey = "spn/publicHub/contactAddress"
|
||||
publicCfgOptionContactAddress config.StringOption
|
||||
publicCfgOptionContactAddressDefault = ""
|
||||
publicCfgOptionContactAddressOrder = 514
|
||||
|
||||
// Type of service of the contact address, if not email.
|
||||
publicCfgOptionContactServiceKey = "spn/publicHub/contactService"
|
||||
publicCfgOptionContactService config.StringOption
|
||||
publicCfgOptionContactServiceDefault = ""
|
||||
publicCfgOptionContactServiceOrder = 515
|
||||
|
||||
// Hosters - supply chain (reseller, hosting provider, datacenter operator, ...).
|
||||
publicCfgOptionHostersKey = "spn/publicHub/hosters"
|
||||
publicCfgOptionHosters config.StringArrayOption
|
||||
publicCfgOptionHostersDefault = []string{}
|
||||
publicCfgOptionHostersOrder = 516
|
||||
|
||||
// Datacenter
|
||||
// Format: CC-COMPANY-INTERNALCODE
|
||||
// Eg: DE-Hetzner-FSN1-DC5
|
||||
//.
|
||||
publicCfgOptionDatacenterKey = "spn/publicHub/datacenter"
|
||||
publicCfgOptionDatacenter config.StringOption
|
||||
publicCfgOptionDatacenterDefault = ""
|
||||
publicCfgOptionDatacenterOrder = 517
|
||||
|
||||
// Network Location and Access.
|
||||
|
||||
// IPv4 must be global and accessible.
|
||||
publicCfgOptionIPv4Key = "spn/publicHub/ip4"
|
||||
publicCfgOptionIPv4 config.StringOption
|
||||
publicCfgOptionIPv4Default = ""
|
||||
publicCfgOptionIPv4Order = 518
|
||||
|
||||
// IPv6 must be global and accessible.
|
||||
publicCfgOptionIPv6Key = "spn/publicHub/ip6"
|
||||
publicCfgOptionIPv6 config.StringOption
|
||||
publicCfgOptionIPv6Default = ""
|
||||
publicCfgOptionIPv6Order = 519
|
||||
|
||||
// Transports.
|
||||
publicCfgOptionTransportsKey = "spn/publicHub/transports"
|
||||
publicCfgOptionTransports config.StringArrayOption
|
||||
publicCfgOptionTransportsDefault = []string{
|
||||
"tcp:17",
|
||||
}
|
||||
publicCfgOptionTransportsOrder = 520
|
||||
|
||||
// Entry Policy.
|
||||
publicCfgOptionEntryKey = "spn/publicHub/entry"
|
||||
publicCfgOptionEntry config.StringArrayOption
|
||||
publicCfgOptionEntryDefault = []string{}
|
||||
publicCfgOptionEntryOrder = 521
|
||||
|
||||
// Exit Policy.
|
||||
publicCfgOptionExitKey = "spn/publicHub/exit"
|
||||
publicCfgOptionExit config.StringArrayOption
|
||||
publicCfgOptionExitDefault = []string{"- * TCP/25"}
|
||||
publicCfgOptionExitOrder = 522
|
||||
|
||||
// Allow Unencrypted.
|
||||
publicCfgOptionAllowUnencryptedKey = "spn/publicHub/allowUnencrypted"
|
||||
publicCfgOptionAllowUnencrypted config.BoolOption
|
||||
publicCfgOptionAllowUnencryptedDefault = false
|
||||
publicCfgOptionAllowUnencryptedOrder = 523
|
||||
)
|
||||
|
||||
func prepPublicHubConfig() error {
|
||||
err := config.Register(&config.Option{
|
||||
Name: "Name",
|
||||
Key: publicCfgOptionNameKey,
|
||||
Description: "Human readable name of the Hub.",
|
||||
OptType: config.OptTypeString,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionNameDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionNameOrder,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionName = config.GetAsString(publicCfgOptionNameKey, publicCfgOptionNameDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Group",
|
||||
Key: publicCfgOptionGroupKey,
|
||||
Description: "Name of the hub group this Hub belongs to.",
|
||||
OptType: config.OptTypeString,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionGroupDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionGroupOrder,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionGroup = config.GetAsString(publicCfgOptionGroupKey, publicCfgOptionGroupDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Contact Address",
|
||||
Key: publicCfgOptionContactAddressKey,
|
||||
Description: "Contact address where the Hub operator can be reached.",
|
||||
OptType: config.OptTypeString,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionContactAddressDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionContactAddressOrder,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionContactAddress = config.GetAsString(publicCfgOptionContactAddressKey, publicCfgOptionContactAddressDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Contact Service",
|
||||
Key: publicCfgOptionContactServiceKey,
|
||||
Description: "Name of the service the contact address corresponds to, if not email.",
|
||||
OptType: config.OptTypeString,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionContactServiceDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionContactServiceOrder,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionContactService = config.GetAsString(publicCfgOptionContactServiceKey, publicCfgOptionContactServiceDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Hosters",
|
||||
Key: publicCfgOptionHostersKey,
|
||||
Description: "List of all involved entities and organisations that are involved in hosting this Hub.",
|
||||
OptType: config.OptTypeStringArray,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionHostersDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionHostersOrder,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionHosters = config.GetAsStringArray(publicCfgOptionHostersKey, publicCfgOptionHostersDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Datacenter",
|
||||
Key: publicCfgOptionDatacenterKey,
|
||||
Description: "Identifier of the datacenter this Hub is hosted in.",
|
||||
OptType: config.OptTypeString,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionDatacenterDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionDatacenterOrder,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionDatacenter = config.GetAsString(publicCfgOptionDatacenterKey, publicCfgOptionDatacenterDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "IPv4",
|
||||
Key: publicCfgOptionIPv4Key,
|
||||
Description: "IPv4 address of this Hub. Must be globally reachable.",
|
||||
OptType: config.OptTypeString,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionIPv4Default,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionIPv4Order,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionIPv4 = config.GetAsString(publicCfgOptionIPv4Key, publicCfgOptionIPv4Default)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "IPv6",
|
||||
Key: publicCfgOptionIPv6Key,
|
||||
Description: "IPv6 address of this Hub. Must be globally reachable.",
|
||||
OptType: config.OptTypeString,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionIPv6Default,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionIPv6Order,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionIPv6 = config.GetAsString(publicCfgOptionIPv6Key, publicCfgOptionIPv6Default)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Transports",
|
||||
Key: publicCfgOptionTransportsKey,
|
||||
Description: "List of transports this Hub supports.",
|
||||
OptType: config.OptTypeStringArray,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionTransportsDefault,
|
||||
ValidationFunc: func(value any) error {
|
||||
if transports, ok := value.([]string); ok {
|
||||
for i, transport := range transports {
|
||||
if _, err := hub.ParseTransport(transport); err != nil {
|
||||
return fmt.Errorf("failed to parse transport #%d: %w", i, err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("not a []string, but %T", value)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionTransportsOrder,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionTransports = config.GetAsStringArray(publicCfgOptionTransportsKey, publicCfgOptionTransportsDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Entry",
|
||||
Key: publicCfgOptionEntryKey,
|
||||
Description: "Define an entry policy. The format is the same for the endpoint lists. Default is permit.",
|
||||
OptType: config.OptTypeStringArray,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionEntryDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionEntryOrder,
|
||||
config.DisplayHintAnnotation: endpoints.DisplayHintEndpointList,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionEntry = config.GetAsStringArray(publicCfgOptionEntryKey, publicCfgOptionEntryDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Exit",
|
||||
Key: publicCfgOptionExitKey,
|
||||
Description: "Define an exit policy. The format is the same for the endpoint lists. Default is permit.",
|
||||
OptType: config.OptTypeStringArray,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionExitDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionExitOrder,
|
||||
config.DisplayHintAnnotation: endpoints.DisplayHintEndpointList,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionExit = config.GetAsStringArray(publicCfgOptionExitKey, publicCfgOptionExitDefault)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Allow Unencrypted Connections",
|
||||
Key: publicCfgOptionAllowUnencryptedKey,
|
||||
Description: "Advertise that this Hub is available for handling unencrypted connections, as detected by clients.",
|
||||
OptType: config.OptTypeBool,
|
||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
||||
RequiresRestart: true,
|
||||
DefaultValue: publicCfgOptionAllowUnencryptedDefault,
|
||||
Annotations: config.Annotations{
|
||||
config.DisplayOrderAnnotation: publicCfgOptionAllowUnencryptedOrder,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
publicCfgOptionAllowUnencrypted = config.GetAsBool(publicCfgOptionAllowUnencryptedKey, publicCfgOptionAllowUnencryptedDefault)
|
||||
|
||||
// update defaults from system
|
||||
setDynamicPublicDefaults()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPublicHubInfo() *hub.Announcement {
|
||||
// get configuration
|
||||
info := &hub.Announcement{
|
||||
Name: publicCfgOptionName(),
|
||||
Group: publicCfgOptionGroup(),
|
||||
ContactAddress: publicCfgOptionContactAddress(),
|
||||
ContactService: publicCfgOptionContactService(),
|
||||
Hosters: publicCfgOptionHosters(),
|
||||
Datacenter: publicCfgOptionDatacenter(),
|
||||
Transports: publicCfgOptionTransports(),
|
||||
Entry: publicCfgOptionEntry(),
|
||||
Exit: publicCfgOptionExit(),
|
||||
Flags: []string{},
|
||||
}
|
||||
|
||||
if publicCfgOptionAllowUnencrypted() {
|
||||
info.Flags = append(info.Flags, hub.FlagAllowUnencrypted)
|
||||
}
|
||||
|
||||
ip4 := publicCfgOptionIPv4()
|
||||
if ip4 != "" {
|
||||
ip := net.ParseIP(ip4)
|
||||
if ip == nil {
|
||||
log.Warningf("spn/cabin: invalid %s config: %s", publicCfgOptionIPv4Key, ip4)
|
||||
} else {
|
||||
info.IPv4 = ip
|
||||
}
|
||||
}
|
||||
|
||||
ip6 := publicCfgOptionIPv6()
|
||||
if ip6 != "" {
|
||||
ip := net.ParseIP(ip6)
|
||||
if ip == nil {
|
||||
log.Warningf("spn/cabin: invalid %s config: %s", publicCfgOptionIPv6Key, ip6)
|
||||
} else {
|
||||
info.IPv6 = ip
|
||||
}
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
func setDynamicPublicDefaults() {
|
||||
// name
|
||||
hostname, err := os.Hostname()
|
||||
if err == nil {
|
||||
err := config.SetDefaultConfigOption(publicCfgOptionNameKey, hostname)
|
||||
if err != nil {
|
||||
log.Warningf("spn/cabin: failed to set %s default to %s", publicCfgOptionNameKey, hostname)
|
||||
}
|
||||
}
|
||||
|
||||
// IPs
|
||||
v4IPs, v6IPs, err := netenv.GetAssignedGlobalAddresses()
|
||||
if err != nil {
|
||||
log.Warningf("spn/cabin: failed to get assigned addresses: %s", err)
|
||||
return
|
||||
}
|
||||
if len(v4IPs) == 1 {
|
||||
err = config.SetDefaultConfigOption(publicCfgOptionIPv4Key, v4IPs[0].String())
|
||||
if err != nil {
|
||||
log.Warningf("spn/cabin: failed to set %s default to %s", publicCfgOptionIPv4Key, v4IPs[0].String())
|
||||
}
|
||||
}
|
||||
if len(v6IPs) == 1 {
|
||||
err = config.SetDefaultConfigOption(publicCfgOptionIPv6Key, v6IPs[0].String())
|
||||
if err != nil {
|
||||
log.Warningf("spn/cabin: failed to set %s default to %s", publicCfgOptionIPv6Key, v6IPs[0].String())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user