Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #185 from safing/feature/bind-and-rate-limit
Browse files Browse the repository at this point in the history
Bind to adv. IPs, concurrent connecting, rate limiting
  • Loading branch information
dhaavi committed Oct 5, 2023
2 parents c7ef5cd + dcfd6bc commit 62861c7
Show file tree
Hide file tree
Showing 23 changed files with 786 additions and 136 deletions.
143 changes: 77 additions & 66 deletions cabin/config-public.go
Expand Up @@ -96,12 +96,13 @@ var (

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,
DefaultValue: publicCfgOptionNameDefault,
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,
},
Expand All @@ -112,12 +113,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionGroupDefault,
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,
},
Expand All @@ -128,12 +130,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionContactAddressDefault,
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,
},
Expand All @@ -144,12 +147,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionContactServiceDefault,
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,
},
Expand All @@ -160,12 +164,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionHostersDefault,
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,
},
Expand All @@ -176,12 +181,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionDatacenterDefault,
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,
},
Expand All @@ -192,12 +198,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionIPv4Default,
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,
},
Expand All @@ -208,12 +215,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionIPv6Default,
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,
},
Expand Down Expand Up @@ -253,12 +261,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionEntryDefault,
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,
Expand All @@ -270,12 +279,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionExitDefault,
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,
Expand All @@ -287,12 +297,13 @@ func prepPublicHubConfig() error {
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,
DefaultValue: publicCfgOptionAllowUnencryptedDefault,
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,
},
Expand Down
26 changes: 26 additions & 0 deletions captain/config.go
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/safing/portbase/config"
"github.com/safing/portmaster/profile"
"github.com/safing/portmaster/profile/endpoints"
"github.com/safing/spn/conf"
"github.com/safing/spn/navigator"
)

Expand Down Expand Up @@ -44,6 +45,12 @@ var (
cfgOptionSpecialAccessCode config.StringOption //nolint:unused // Linter, you drunk?
cfgOptionSpecialAccessCodeOrder = 160

// IPv6 must be global and accessible.
cfgOptionBindToAdvertisedKey = "spn/publicHub/bindToAdvertised"
cfgOptionBindToAdvertised config.BoolOption
cfgOptionBindToAdvertisedDefault = false
cfgOptionBindToAdvertisedOrder = 161

// Config options for use.
cfgOptionRoutingAlgorithm config.StringOption
)
Expand Down Expand Up @@ -163,6 +170,25 @@ This setting mainly exists for when you need to simulate your presence in anothe
}
cfgOptionSpecialAccessCode = config.Concurrent.GetAsString(cfgOptionSpecialAccessCodeKey, "")

if conf.PublicHub() {
err = config.Register(&config.Option{
Name: "Connect From Advertised IPs Only",
Key: cfgOptionBindToAdvertisedKey,
Description: "Only connect from (bind to) the advertised IP addresses.",
OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelExpert,
DefaultValue: cfgOptionBindToAdvertisedDefault,
RequiresRestart: true,
Annotations: config.Annotations{
config.DisplayOrderAnnotation: cfgOptionBindToAdvertisedOrder,
},
})
if err != nil {
return err
}
cfgOptionBindToAdvertised = config.GetAsBool(cfgOptionBindToAdvertisedKey, cfgOptionBindToAdvertisedDefault)
}

// Config options for use.
cfgOptionRoutingAlgorithm = config.Concurrent.GetAsString(profile.CfgOptionRoutingAlgorithmKey, navigator.DefaultRoutingProfileID)

Expand Down
3 changes: 3 additions & 0 deletions captain/public.go
Expand Up @@ -68,6 +68,9 @@ func loadPublicIdentity() (err error) {
publicIdentity.Hub.Info.IPv4 != nil,
publicIdentity.Hub.Info.IPv6 != nil,
)
if cfgOptionBindToAdvertised() {
conf.SetConnectAddr(publicIdentity.Hub.Info.IPv4, publicIdentity.Hub.Info.IPv6)
}

// Set Home Hub before updating the hub on the map, as this would trigger a
// recalculation without a Home Hub.
Expand Down
59 changes: 58 additions & 1 deletion conf/networks.go
@@ -1,6 +1,11 @@
package conf

import "github.com/tevino/abool"
import (
"net"
"sync"

"github.com/tevino/abool"
)

var (
hubHasV4 = abool.New()
Expand All @@ -22,3 +27,55 @@ func HubHasIPv4() bool {
func HubHasIPv6() bool {
return hubHasV6.IsSet()
}

var (
connectIPv4 net.IP
connectIPv6 net.IP
connectIPLock sync.Mutex
)

// SetConnectAddr sets the preferred connect (bind) addresses.
func SetConnectAddr(ip4, ip6 net.IP) {
connectIPLock.Lock()
defer connectIPLock.Unlock()

connectIPv4 = ip4
connectIPv6 = ip6
}

// GetConnectAddr returns an address with the preferred connect (bind)
// addresses for the given dial network.
// The dial network must have a suffix specify the IP version.
func GetConnectAddr(dialNetwork string) net.Addr {
connectIPLock.Lock()
defer connectIPLock.Unlock()

switch dialNetwork {
case "ip4":
if connectIPv4 != nil {
return &net.IPAddr{IP: connectIPv4}
}
case "ip6":
if connectIPv6 != nil {
return &net.IPAddr{IP: connectIPv6}
}
case "tcp4":
if connectIPv4 != nil {
return &net.TCPAddr{IP: connectIPv4}
}
case "tcp6":
if connectIPv6 != nil {
return &net.TCPAddr{IP: connectIPv6}
}
case "udp4":
if connectIPv4 != nil {
return &net.UDPAddr{IP: connectIPv4}
}
case "udp6":
if connectIPv6 != nil {
return &net.UDPAddr{IP: connectIPv6}
}
}

return nil
}

0 comments on commit 62861c7

Please sign in to comment.