Merge pull request #187 from safing/feature/config-wording-update

Config wording update
This commit is contained in:
Patrick Pacher 2020-11-04 15:31:05 +01:00 committed by GitHub
commit 24d21341fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 147 additions and 114 deletions

View file

@ -35,7 +35,7 @@ func registerConfig() error {
ReleaseLevel: config.ReleaseLevelStable, ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: defaultDevMode, DefaultValue: defaultDevMode,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: 127, config.DisplayOrderAnnotation: 512,
config.CategoryAnnotation: "Development", config.CategoryAnnotation: "Development",
}, },
}) })
@ -52,8 +52,8 @@ func registerConfig() error {
ReleaseLevel: config.ReleaseLevelStable, ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: true, // TODO: turn off by default on unsupported systems DefaultValue: true, // TODO: turn off by default on unsupported systems
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: 32, config.DisplayOrderAnnotation: -15,
config.CategoryAnnotation: "General", config.CategoryAnnotation: "User Interface",
}, },
}) })
if err != nil { if err != nil {

View file

@ -18,7 +18,7 @@ var (
askTimeout config.IntOption askTimeout config.IntOption
CfgOptionPermanentVerdictsKey = "filter/permanentVerdicts" CfgOptionPermanentVerdictsKey = "filter/permanentVerdicts"
cfgOptionPermanentVerdictsOrder = 128 cfgOptionPermanentVerdictsOrder = 96
permanentVerdicts config.BoolOption permanentVerdicts config.BoolOption
devMode config.BoolOption devMode config.BoolOption
@ -29,7 +29,7 @@ func registerConfig() error {
err := config.Register(&config.Option{ err := config.Register(&config.Option{
Name: "Permanent Verdicts", Name: "Permanent Verdicts",
Key: CfgOptionPermanentVerdictsKey, Key: CfgOptionPermanentVerdictsKey,
Description: "With permanent verdicts, control of a connection is fully handed back to the OS after the initial decision. This brings a great performance increase, but makes it impossible to change the decision of a link later on.", Description: "The Portmaster's system integration intercepts every single packet. Usually the first packet is enough for the Portmaster to set the verdict for a connection - ie. to allow or deny it. Making these verdicts permanent means that the Portmaster will tell the system integration that is does not want to see any more packets of that single connection. This brings a major performance increase.",
OptType: config.OptTypeBool, OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelDeveloper, ExpertiseLevel: config.ExpertiseLevelDeveloper,
ReleaseLevel: config.ReleaseLevelExperimental, ReleaseLevel: config.ReleaseLevelExperimental,
@ -50,7 +50,6 @@ func registerConfig() error {
Description: `In addition to showing prompt notifications in the Portmaster App, also send them to the Desktop. This requires the Portmaster Notifier to be running. Requires Desktop Notifications to be enabled.`, Description: `In addition to showing prompt notifications in the Portmaster App, also send them to the Desktop. This requires the Portmaster Notifier to be running. Requires Desktop Notifications to be enabled.`,
OptType: config.OptTypeBool, OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelUser, ExpertiseLevel: config.ExpertiseLevelUser,
ReleaseLevel: config.ReleaseLevelExperimental,
DefaultValue: true, DefaultValue: true,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: cfgOptionAskWithSystemNotificationsOrder, config.DisplayOrderAnnotation: cfgOptionAskWithSystemNotificationsOrder,
@ -68,11 +67,10 @@ func registerConfig() error {
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Prompt Timeout", Name: "Prompt Timeout",
Key: CfgOptionAskTimeoutKey, Key: CfgOptionAskTimeoutKey,
Description: "How long the Portmaster will wait for a reply to a prompt notification. Please note that Desktop Notifications might not respect this or have it's own limits.", Description: "How long the Portmaster will wait for a reply to a prompt notification. Please note that Desktop Notifications might not respect this or have their own limits.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelUser, ExpertiseLevel: config.ExpertiseLevelUser,
ReleaseLevel: config.ReleaseLevelExperimental, DefaultValue: 20,
DefaultValue: 60,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: cfgOptionAskTimeoutOrder, config.DisplayOrderAnnotation: cfgOptionAskTimeoutOrder,
config.UnitAnnotation: "seconds", config.UnitAnnotation: "seconds",

View file

@ -115,7 +115,18 @@ func filterDNSResponse(conn *network.Connection, rrCache *resolver.RRCache) *res
if len(rrCache.FilteredEntries) > 0 { if len(rrCache.FilteredEntries) > 0 {
rrCache.Filtered = true rrCache.Filtered = true
if validIPs == 0 { if validIPs == 0 {
conn.Block("no addresses returned for this domain are permitted", interveningOptionKey) switch interveningOptionKey {
case profile.CfgOptionBlockScopeInternetKey:
conn.Block("Internet access blocked", interveningOptionKey)
case profile.CfgOptionBlockScopeLANKey:
conn.Block("LAN access blocked", interveningOptionKey)
case profile.CfgOptionBlockScopeLocalKey:
conn.Block("Localhost access blocked", interveningOptionKey)
case profile.CfgOptionRemoveOutOfScopeDNSKey:
conn.Block("DNS global/private split-view violation", interveningOptionKey)
default:
conn.Block("DNS response only contained to-be-blocked IPs", interveningOptionKey)
}
// If all entries are filtered, this could mean that these are broken/bogus resource records. // If all entries are filtered, this could mean that these are broken/bogus resource records.
if rrCache.Expired() { if rrCache.Expired() {

View file

@ -16,12 +16,12 @@ func registerConfiguration() error {
err := config.Register(&config.Option{ err := config.Register(&config.Option{
Name: "Process Detection", Name: "Process Detection",
Key: CfgOptionEnableProcessDetectionKey, Key: CfgOptionEnableProcessDetectionKey,
Description: "This option enables the attribution of network traffic to processes. This should be always enabled, and effectively disables app profiles if disabled.", Description: "This option enables the attribution of network traffic to processes. This should always be enabled, and effectively disables app profiles if disabled.",
OptType: config.OptTypeBool, OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelDeveloper, ExpertiseLevel: config.ExpertiseLevelDeveloper,
DefaultValue: true, DefaultValue: true,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: 144, config.DisplayOrderAnnotation: 528,
config.CategoryAnnotation: "Development", config.CategoryAnnotation: "Development",
}, },
}) })

View file

@ -13,13 +13,18 @@ var (
cfgIntOptions = make(map[string]config.IntOption) cfgIntOptions = make(map[string]config.IntOption)
cfgBoolOptions = make(map[string]config.BoolOption) cfgBoolOptions = make(map[string]config.BoolOption)
// General
// Enable Filter Order = 0 // Enable Filter Order = 0
CfgOptionDefaultActionKey = "filter/defaultAction" CfgOptionDefaultActionKey = "filter/defaultAction"
cfgOptionDefaultAction config.StringOption cfgOptionDefaultAction config.StringOption
cfgOptionDefaultActionOrder = 1 cfgOptionDefaultActionOrder = 1
// Prompt Timeout Order = 2 // Prompt Desktop Notifications Order = 2
// Prompt Timeout Order = 3
// Network Scopes
CfgOptionBlockScopeInternetKey = "filter/blockInternet" CfgOptionBlockScopeInternetKey = "filter/blockInternet"
cfgOptionBlockScopeInternet config.IntOption // security level option cfgOptionBlockScopeInternet config.IntOption // security level option
@ -33,6 +38,8 @@ var (
cfgOptionBlockScopeLocal config.IntOption // security level option cfgOptionBlockScopeLocal config.IntOption // security level option
cfgOptionBlockScopeLocalOrder = 18 cfgOptionBlockScopeLocalOrder = 18
// Connection Types
CfgOptionBlockP2PKey = "filter/blockP2P" CfgOptionBlockP2PKey = "filter/blockP2P"
cfgOptionBlockP2P config.IntOption // security level option cfgOptionBlockP2P config.IntOption // security level option
cfgOptionBlockP2POrder = 19 cfgOptionBlockP2POrder = 19
@ -41,6 +48,8 @@ var (
cfgOptionBlockInbound config.IntOption // security level option cfgOptionBlockInbound config.IntOption // security level option
cfgOptionBlockInboundOrder = 20 cfgOptionBlockInboundOrder = 20
// Rules
CfgOptionEndpointsKey = "filter/endpoints" CfgOptionEndpointsKey = "filter/endpoints"
cfgOptionEndpoints config.StringArrayOption cfgOptionEndpoints config.StringArrayOption
cfgOptionEndpointsOrder = 32 cfgOptionEndpointsOrder = 32
@ -49,43 +58,47 @@ var (
cfgOptionServiceEndpoints config.StringArrayOption cfgOptionServiceEndpoints config.StringArrayOption
cfgOptionServiceEndpointsOrder = 33 cfgOptionServiceEndpointsOrder = 33
CfgOptionPreventBypassingKey = "filter/preventBypassing"
cfgOptionPreventBypassing config.IntOption // security level option
cfgOptionPreventBypassingOrder = 48
CfgOptionFilterListsKey = "filter/lists" CfgOptionFilterListsKey = "filter/lists"
cfgOptionFilterLists config.StringArrayOption cfgOptionFilterLists config.StringArrayOption
cfgOptionFilterListsOrder = 64 cfgOptionFilterListsOrder = 34
CfgOptionFilterSubDomainsKey = "filter/includeSubdomains" CfgOptionFilterSubDomainsKey = "filter/includeSubdomains"
cfgOptionFilterSubDomains config.IntOption // security level option cfgOptionFilterSubDomains config.IntOption // security level option
cfgOptionFilterSubDomainsOrder = 65 cfgOptionFilterSubDomainsOrder = 35
// DNS Filtering
CfgOptionFilterCNAMEKey = "filter/includeCNAMEs" CfgOptionFilterCNAMEKey = "filter/includeCNAMEs"
cfgOptionFilterCNAME config.IntOption // security level option cfgOptionFilterCNAME config.IntOption // security level option
cfgOptionFilterCNAMEOrder = 66 cfgOptionFilterCNAMEOrder = 48
CfgOptionDisableAutoPermitKey = "filter/disableAutoPermit"
cfgOptionDisableAutoPermit config.IntOption // security level option
cfgOptionDisableAutoPermitOrder = 80
CfgOptionRemoveOutOfScopeDNSKey = "filter/removeOutOfScopeDNS" CfgOptionRemoveOutOfScopeDNSKey = "filter/removeOutOfScopeDNS"
cfgOptionRemoveOutOfScopeDNS config.IntOption // security level option cfgOptionRemoveOutOfScopeDNS config.IntOption // security level option
cfgOptionRemoveOutOfScopeDNSOrder = 112 cfgOptionRemoveOutOfScopeDNSOrder = 49
CfgOptionRemoveBlockedDNSKey = "filter/removeBlockedDNS" CfgOptionRemoveBlockedDNSKey = "filter/removeBlockedDNS"
cfgOptionRemoveBlockedDNS config.IntOption // security level option cfgOptionRemoveBlockedDNS config.IntOption // security level option
cfgOptionRemoveBlockedDNSOrder = 113 cfgOptionRemoveBlockedDNSOrder = 50
CfgOptionDomainHeuristicsKey = "filter/domainHeuristics" CfgOptionDomainHeuristicsKey = "filter/domainHeuristics"
cfgOptionDomainHeuristics config.IntOption // security level option cfgOptionDomainHeuristics config.IntOption // security level option
cfgOptionDomainHeuristicsOrder = 114 cfgOptionDomainHeuristicsOrder = 51
// Permanent Verdicts Order = 128 // Advanced
CfgOptionPreventBypassingKey = "filter/preventBypassing"
cfgOptionPreventBypassing config.IntOption // security level option
cfgOptionPreventBypassingOrder = 64
CfgOptionDisableAutoPermitKey = "filter/disableAutoPermit"
cfgOptionDisableAutoPermit config.IntOption // security level option
cfgOptionDisableAutoPermitOrder = 65
// Permanent Verdicts Order = 96
CfgOptionUseSPNKey = "spn/useSPN" CfgOptionUseSPNKey = "spn/useSPN"
cfgOptionUseSPN config.BoolOption cfgOptionUseSPN config.BoolOption
cfgOptionUseSPNOrder = 128 cfgOptionUseSPNOrder = 129
) )
func registerConfiguration() error { func registerConfiguration() error {
@ -94,10 +107,9 @@ func registerConfiguration() error {
// ask - ask mode: if not verdict is found, the user is consulted // ask - ask mode: if not verdict is found, the user is consulted
// block - allowlist mode: everything is blocked unless permitted // block - allowlist mode: everything is blocked unless permitted
err := config.Register(&config.Option{ err := config.Register(&config.Option{
Name: "Default Action", Name: "Default Action",
Key: CfgOptionDefaultActionKey, Key: CfgOptionDefaultActionKey,
// TODO: Discuss "when nothing else" Description: `The default action when nothing else permits or blocks an outgoing connection. Incoming connections are always blocked by default.`,
Description: `The default action when nothing else permits or blocks an outgoing connection. Inbound connections are always blocked by default.`,
OptType: config.OptTypeString, OptType: config.OptTypeString,
DefaultValue: "permit", DefaultValue: "permit",
Annotations: config.Annotations{ Annotations: config.Annotations{
@ -111,16 +123,16 @@ func registerConfiguration() error {
Value: "permit", Value: "permit",
Description: "Permit all connections", Description: "Permit all connections",
}, },
{
Name: "Prompt",
Value: "ask",
Description: "Always ask for a decision",
},
{ {
Name: "Block", Name: "Block",
Value: "block", Value: "block",
Description: "Block all connections", Description: "Block all connections",
}, },
{
Name: "Prompt",
Value: "ask",
Description: "Prompt for decisions",
},
}, },
}) })
if err != nil { if err != nil {
@ -131,10 +143,10 @@ func registerConfiguration() error {
// Disable Auto Permit // Disable Auto Permit
err = config.Register(&config.Option{ err = config.Register(&config.Option{
// TODO: Discuss // TODO: Check how to best handle negation here.
Name: "Disable Auto Permit", Name: "Disable Auto Permit",
Key: CfgOptionDisableAutoPermitKey, Key: CfgOptionDisableAutoPermitKey,
Description: `Auto Permit searches for a relation between an app and the destination of a connection - if there is a correlation, the connection will be permitted. This setting is negated in order to provide a streamlined user experience, where "higher settings" provide more protection.`, Description: `Auto Permit searches for a relation between an app and the destination of a connection - if there is a correlation, the connection will be permitted.`,
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ReleaseLevel: config.ReleaseLevelBeta, ReleaseLevel: config.ReleaseLevelBeta,
DefaultValue: status.SecurityLevelsAll, DefaultValue: status.SecurityLevelsAll,
@ -181,7 +193,7 @@ Examples:
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Outgoing Rules", Name: "Outgoing Rules",
Key: CfgOptionEndpointsKey, Key: CfgOptionEndpointsKey,
Description: "Rules that apply to outgoing network connections. Network Scope restrictions still apply.", Description: "Rules that apply to outgoing network connections. Cannot overrule Network Scopes and Connection Types (see above).",
Help: filterListHelp, Help: filterListHelp,
OptType: config.OptTypeStringArray, OptType: config.OptTypeStringArray,
DefaultValue: []string{}, DefaultValue: []string{},
@ -201,12 +213,13 @@ Examples:
// Service Endpoint Filter List // Service Endpoint Filter List
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Incoming Rules", Name: "Incoming Rules",
Key: CfgOptionServiceEndpointsKey, Key: CfgOptionServiceEndpointsKey,
Description: "Rules that apply to incoming network connections. Network Scope restrictions and the incoming permission still apply. Also note that the default action for incoming connections is to always block.", Description: "Rules that apply to incoming network connections. Cannot overrule Network Scopes and Connection Types (see above). Also note that the default action for incoming connections is to always block.",
Help: filterListHelp, Help: filterListHelp,
OptType: config.OptTypeStringArray, OptType: config.OptTypeStringArray,
DefaultValue: []string{"+ Localhost"}, DefaultValue: []string{"+ Localhost"},
ExpertiseLevel: config.ExpertiseLevelExpert,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.StackableAnnotation: true, config.StackableAnnotation: true,
config.DisplayHintAnnotation: endpoints.DisplayHintEndpointList, config.DisplayHintAnnotation: endpoints.DisplayHintEndpointList,
@ -260,16 +273,16 @@ Examples:
// Include CNAMEs // Include CNAMEs
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Check Domain Aliases", Name: "Block Domain Aliases",
Key: CfgOptionFilterCNAMEKey, Key: CfgOptionFilterCNAMEKey,
Description: "In addition to checking a domain against rules and filter lists, also check it's resolved CNAMEs.", Description: "Block a domain if a resolved CNAME (alias) is blocked by a rule or filter list.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
DefaultValue: status.SecurityLevelsAll, DefaultValue: status.SecurityLevelsAll,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelExpert,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionFilterCNAMEOrder, config.DisplayOrderAnnotation: cfgOptionFilterCNAMEOrder,
config.CategoryAnnotation: "DNS", config.CategoryAnnotation: "DNS Filtering",
}, },
PossibleValues: status.SecurityLevelValues, PossibleValues: status.SecurityLevelValues,
}) })
@ -281,16 +294,16 @@ Examples:
// Include subdomains // Include subdomains
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Check Subdomains", Name: "Block Subdomains of Filter List Entries",
Key: CfgOptionFilterSubDomainsKey, Key: CfgOptionFilterSubDomainsKey,
Description: "Also block a domain if any parent domain is blocked by a filter list", Description: "Additionally block all subdomains of entries in selected filter lists.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
DefaultValue: status.SecurityLevelsAll, DefaultValue: status.SecurityLevelsAll,
PossibleValues: status.SecurityLevelValues, PossibleValues: status.SecurityLevelValues,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionFilterSubDomainsOrder, config.DisplayOrderAnnotation: cfgOptionFilterSubDomainsOrder,
config.CategoryAnnotation: "DNS", config.CategoryAnnotation: "Rules",
}, },
}) })
if err != nil { if err != nil {
@ -303,7 +316,7 @@ Examples:
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Block Device-Local Connections", Name: "Block Device-Local Connections",
Key: CfgOptionBlockScopeLocalKey, Key: CfgOptionBlockScopeLocalKey,
Description: "Block all internal connections on your own device, ie. localhost.", Description: "Block all internal connections on your own device, ie. localhost. Is stronger than Rules (see below).",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelExpert,
DefaultValue: status.SecurityLevelOff, DefaultValue: status.SecurityLevelOff,
@ -311,7 +324,7 @@ Examples:
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionBlockScopeLocalOrder, config.DisplayOrderAnnotation: cfgOptionBlockScopeLocalOrder,
config.CategoryAnnotation: "Scopes & Types", config.CategoryAnnotation: "Network Scope",
}, },
}) })
if err != nil { if err != nil {
@ -324,14 +337,14 @@ Examples:
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Block LAN", Name: "Block LAN",
Key: CfgOptionBlockScopeLANKey, Key: CfgOptionBlockScopeLANKey,
Description: "Block all connections from and to the Local Area Network.", Description: "Block all connections from and to the Local Area Network. Is stronger than Rules (see below).",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
DefaultValue: status.SecurityLevelsHighAndExtreme, DefaultValue: status.SecurityLevelsHighAndExtreme,
PossibleValues: status.AllSecurityLevelValues, PossibleValues: status.AllSecurityLevelValues,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionBlockScopeLANOrder, config.DisplayOrderAnnotation: cfgOptionBlockScopeLANOrder,
config.CategoryAnnotation: "Scopes & Types", config.CategoryAnnotation: "Network Scope",
}, },
}) })
if err != nil { if err != nil {
@ -342,16 +355,16 @@ Examples:
// Block Scope Internet // Block Scope Internet
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Block Internet", Name: "Block Internet Access",
Key: CfgOptionBlockScopeInternetKey, Key: CfgOptionBlockScopeInternetKey,
Description: "Block connections from and to the Internet.", Description: "Block connections from and to the Internet. Is stronger than Rules (see below).",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
DefaultValue: status.SecurityLevelOff, DefaultValue: status.SecurityLevelOff,
PossibleValues: status.AllSecurityLevelValues, PossibleValues: status.AllSecurityLevelValues,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionBlockScopeInternetOrder, config.DisplayOrderAnnotation: cfgOptionBlockScopeInternetOrder,
config.CategoryAnnotation: "Scopes & Types", config.CategoryAnnotation: "Network Scope",
}, },
}) })
if err != nil { if err != nil {
@ -364,14 +377,14 @@ Examples:
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Block P2P/Direct Connections", Name: "Block P2P/Direct Connections",
Key: CfgOptionBlockP2PKey, Key: CfgOptionBlockP2PKey,
Description: "These are connections that are established directly to an IP address or peer on the Internet without resolving a domain name via DNS first.", Description: "These are connections that are established directly to an IP address or peer on the Internet without resolving a domain name via DNS first. Is stronger than Rules (see below).",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
DefaultValue: status.SecurityLevelExtreme, DefaultValue: status.SecurityLevelExtreme,
PossibleValues: status.SecurityLevelValues, PossibleValues: status.SecurityLevelValues,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionBlockP2POrder, config.DisplayOrderAnnotation: cfgOptionBlockP2POrder,
config.CategoryAnnotation: "Scopes & Types", config.CategoryAnnotation: "Connection Types",
}, },
}) })
if err != nil { if err != nil {
@ -384,14 +397,14 @@ Examples:
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Block Incoming Connections", Name: "Block Incoming Connections",
Key: CfgOptionBlockInboundKey, Key: CfgOptionBlockInboundKey,
Description: "Connections initiated towards your device from the LAN or Internet. This will usually only be the case if you are running a network service or are using peer to peer software.", Description: "Connections initiated towards your device from the LAN or Internet. This will usually only be the case if you are running a network service or are using peer to peer software. Is stronger than Rules (see below).",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
DefaultValue: status.SecurityLevelsHighAndExtreme, DefaultValue: status.SecurityLevelsHighAndExtreme,
PossibleValues: status.SecurityLevelValues, PossibleValues: status.SecurityLevelValues,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionBlockInboundOrder, config.DisplayOrderAnnotation: cfgOptionBlockInboundOrder,
config.CategoryAnnotation: "Scopes & Types", config.CategoryAnnotation: "Connection Types",
}, },
}) })
if err != nil { if err != nil {
@ -402,17 +415,17 @@ Examples:
// Filter Out-of-Scope DNS Records // Filter Out-of-Scope DNS Records
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Enforce global/private split-view", Name: "Enforce Global/Private Split-View",
Key: CfgOptionRemoveOutOfScopeDNSKey, Key: CfgOptionRemoveOutOfScopeDNSKey,
Description: "Remove private IP addresses from public DNS responses.", Description: "Reject private IP addresses (RFC1918 et al.) from public DNS responses.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelDeveloper,
DefaultValue: status.SecurityLevelsAll, DefaultValue: status.SecurityLevelsAll,
PossibleValues: status.SecurityLevelValues, PossibleValues: status.SecurityLevelValues,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionRemoveOutOfScopeDNSOrder, config.DisplayOrderAnnotation: cfgOptionRemoveOutOfScopeDNSOrder,
config.CategoryAnnotation: "DNS", config.CategoryAnnotation: "DNS Filtering",
}, },
}) })
if err != nil { if err != nil {
@ -423,17 +436,17 @@ Examples:
// Filter DNS Records that would be blocked // Filter DNS Records that would be blocked
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Remove blocked records", Name: "Reject Blocked IPs",
Key: CfgOptionRemoveBlockedDNSKey, Key: CfgOptionRemoveBlockedDNSKey,
Description: "Remove blocked IP addresses from DNS responses.", Description: "Reject blocked IP addresses directly from the DNS response instead of handing them over to the app and blocking a resulting connection.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelDeveloper,
DefaultValue: status.SecurityLevelsAll, DefaultValue: status.SecurityLevelsAll,
PossibleValues: status.SecurityLevelValues, PossibleValues: status.SecurityLevelValues,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionRemoveBlockedDNSOrder, config.DisplayOrderAnnotation: cfgOptionRemoveBlockedDNSOrder,
config.CategoryAnnotation: "DNS", config.CategoryAnnotation: "DNS Filtering",
}, },
}) })
if err != nil { if err != nil {
@ -444,9 +457,9 @@ Examples:
// Domain heuristics // Domain heuristics
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Domain Heuristics", Name: "Enable Domain Heuristics",
Key: CfgOptionDomainHeuristicsKey, Key: CfgOptionDomainHeuristicsKey,
Description: "Domain Heuristics checks for suspicious domain names and blocks them. This option currently targets domain names generated by malware and DNS data exfiltration channels.", Description: "Checks for suspicious domain names and blocks them. This option currently targets domain names generated by malware and DNS data exfiltration channels.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelExpert,
DefaultValue: status.SecurityLevelsAll, DefaultValue: status.SecurityLevelsAll,
@ -454,7 +467,7 @@ Examples:
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
config.DisplayOrderAnnotation: cfgOptionDomainHeuristicsOrder, config.DisplayOrderAnnotation: cfgOptionDomainHeuristicsOrder,
config.CategoryAnnotation: "DNS", config.CategoryAnnotation: "DNS Filtering",
}, },
}) })
if err != nil { if err != nil {
@ -464,9 +477,10 @@ Examples:
// Bypass prevention // Bypass prevention
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Prevent Bypassing", Name: "Block Bypassing",
Key: CfgOptionPreventBypassingKey, Key: CfgOptionPreventBypassingKey,
Description: `Prevent apps from bypassing the privacy filter: Description: `Prevent apps from bypassing the privacy filter.
Current Features:
- Disable Firefox' internal DNS-over-HTTPs resolver`, - Disable Firefox' internal DNS-over-HTTPs resolver`,
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelUser, ExpertiseLevel: config.ExpertiseLevelUser,
@ -489,9 +503,8 @@ Examples:
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Use SPN", Name: "Use SPN",
Key: CfgOptionUseSPNKey, Key: CfgOptionUseSPNKey,
Description: "Route connection through the Safing Privacy Network. If it is unavailable for any reason, connections will be blocked.", Description: "Route connections through the Safing Privacy Network. If it is disabled or unavailable for any reason, connections will be blocked.",
OptType: config.OptTypeBool, OptType: config.OptTypeBool,
ReleaseLevel: config.ReleaseLevelExperimental,
DefaultValue: true, DefaultValue: true,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: cfgOptionUseSPNOrder, config.DisplayOrderAnnotation: cfgOptionUseSPNOrder,

View file

@ -82,8 +82,12 @@ func prepConfig() error {
Name: "DNS Servers", Name: "DNS Servers",
Key: CfgOptionNameServersKey, Key: CfgOptionNameServersKey,
Description: "DNS Servers to use for resolving DNS requests.", Description: "DNS Servers to use for resolving DNS requests.",
Help: strings.ReplaceAll(`DNS Servers are configured in a URL format. This allows you to specify special settings for a resolver. If you just want to use a resolver at IP 10.2.3.4, please enter: "dns://10.2.3.4" Help: strings.ReplaceAll(`DNS Servers are used in the order as entered. The first one will be used as the primary DNS Server. Only if it fails, will the other servers be used as a fallback - in their respective order. If all fail, or if no DNS Server is configured here, the Portmaster will use the one configured in your system or network.
The format is: "protocol://ip:port?parameter=value&parameter=value"
Additionally, if it is more likely that the DNS Server of your system or network has a (better) answer to a request, they will be asked first. This will be the case for special local domains and domain spaces announced on the current network.
DNS Servers are configured in a URL format. This allows you to specify special settings for a resolver. If you just want to use a resolver at IP 10.2.3.4, please enter: "dns://10.2.3.4"
The format is: "protocol://ip:port?parameter=value&parameter=value"
- Protocol - Protocol
- "dot": DNS-over-TLS (recommended) - "dot": DNS-over-TLS (recommended)
@ -152,7 +156,7 @@ The format is: "protocol://ip:port?parameter=value&parameter=value"
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Retry Timeout", Name: "Retry Timeout",
Key: CfgOptionNameserverRetryRateKey, Key: CfgOptionNameserverRetryRateKey,
Description: "Timeout between retries when a resolver fails.", Description: "Timeout between retries when a DNS server fails.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelExpert,
ReleaseLevel: config.ReleaseLevelStable, ReleaseLevel: config.ReleaseLevelStable,
@ -169,9 +173,9 @@ The format is: "protocol://ip:port?parameter=value&parameter=value"
nameserverRetryRate = config.Concurrent.GetAsInt(CfgOptionNameserverRetryRateKey, 600) nameserverRetryRate = config.Concurrent.GetAsInt(CfgOptionNameserverRetryRateKey, 600)
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Ignore system resolvers", Name: "Ignore System/Network Servers",
Key: CfgOptionNoAssignedNameserversKey, Key: CfgOptionNoAssignedNameserversKey,
Description: "Ignore resolvers that were acquired from the operating system.", Description: "Ignore DNS servers configured in your system or network.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelExpert,
ReleaseLevel: config.ReleaseLevelStable, ReleaseLevel: config.ReleaseLevelStable,
@ -209,7 +213,7 @@ The format is: "protocol://ip:port?parameter=value&parameter=value"
noMulticastDNS = status.SecurityLevelOption(CfgOptionNoMulticastDNSKey) noMulticastDNS = status.SecurityLevelOption(CfgOptionNoMulticastDNSKey)
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Enforce secure DNS", Name: "Enforce Secure DNS",
Key: CfgOptionNoInsecureProtocolsKey, Key: CfgOptionNoInsecureProtocolsKey,
Description: "Never resolve using insecure protocols, ie. plain DNS.", Description: "Never resolve using insecure protocols, ie. plain DNS.",
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
@ -229,14 +233,17 @@ The format is: "protocol://ip:port?parameter=value&parameter=value"
noInsecureProtocols = status.SecurityLevelOption(CfgOptionNoInsecureProtocolsKey) noInsecureProtocols = status.SecurityLevelOption(CfgOptionNoInsecureProtocolsKey)
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Block unofficial TLDs", Name: "Block Unofficial TLDs",
Key: CfgOptionDontResolveSpecialDomainsKey, Key: CfgOptionDontResolveSpecialDomainsKey,
Description: fmt.Sprintf("Block %s.", formatScopeList(specialServiceDomains)), Description: fmt.Sprintf(
"Block %s. Unofficial domains may pose a security risk. This does not affect .onion domains in the Tor Browser.",
formatScopeList(specialServiceDomains),
),
OptType: config.OptTypeInt, OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelExpert,
ReleaseLevel: config.ReleaseLevelStable, ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: status.SecurityLevelsAll, DefaultValue: status.SecurityLevelsAll,
PossibleValues: status.SecurityLevelValues, PossibleValues: status.AllSecurityLevelValues,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: cfgOptionDontResolveSpecialDomainsOrder, config.DisplayOrderAnnotation: cfgOptionDontResolveSpecialDomainsOrder,
config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel,
@ -254,7 +261,7 @@ The format is: "protocol://ip:port?parameter=value&parameter=value"
func formatScopeList(list []string) string { func formatScopeList(list []string) string {
formatted := make([]string, 0, len(list)) formatted := make([]string, 0, len(list))
for _, domain := range list { for _, domain := range list {
formatted = append(formatted, strings.Trim(domain, ".")) formatted = append(formatted, strings.TrimRight(domain, "."))
} }
return strings.Join(formatted, ", ") return strings.Join(formatted, ", ")
} }

View file

@ -204,28 +204,32 @@ func getSystemResolvers() (resolvers []*Resolver) {
return resolvers return resolvers
} }
const missingResolversErrorID = "missing-resolvers"
func loadResolvers() { func loadResolvers() {
// TODO: what happens when a lot of processes want to reload at once? we do not need to run this multiple times in a short time frame. // TODO: what happens when a lot of processes want to reload at once? we do not need to run this multiple times in a short time frame.
resolversLock.Lock() resolversLock.Lock()
defer resolversLock.Unlock() defer resolversLock.Unlock()
// Resolve module error about missing resolvers.
module.Resolve(missingResolversErrorID)
newResolvers := append( newResolvers := append(
getConfiguredResolvers(configuredNameServers()), getConfiguredResolvers(configuredNameServers()),
getSystemResolvers()..., getSystemResolvers()...,
) )
if len(newResolvers) == 0 { if len(newResolvers) == 0 {
msg := "no (valid) dns servers found in (user) configuration or system, falling back to defaults" msg := "no (valid) dns servers found in configuration or system, falling back to defaults"
log.Warningf("resolver: %s", msg) log.Warningf("resolver: %s", msg)
module.Warning("no-valid-user-resolvers", msg) module.Warning(missingResolversErrorID, msg)
// load defaults directly, overriding config system // load defaults directly, overriding config system
newResolvers = getConfiguredResolvers(defaultNameServers) newResolvers = getConfiguredResolvers(defaultNameServers)
if len(newResolvers) == 0 { if len(newResolvers) == 0 {
msg = "no (valid) dns servers found in configuration or system" msg = "no (valid) dns servers found in configuration or system"
log.Criticalf("resolver: %s", msg) log.Criticalf("resolver: %s", msg)
module.Error("no-valid-default-resolvers", msg) module.Error(missingResolversErrorID, msg)
return
} }
} }

View file

@ -14,11 +14,11 @@ const (
var ( var (
releaseChannel config.StringOption releaseChannel config.StringOption
devMode config.BoolOption devMode config.BoolOption
disableUpdates config.BoolOption enableUpdates config.BoolOption
previousReleaseChannel string previousReleaseChannel string
updatesCurrentlyDisabled bool updatesCurrentlyEnabled bool
previousDevMode bool previousDevMode bool
) )
func registerConfig() error { func registerConfig() error {
@ -42,9 +42,9 @@ func registerConfig() error {
}, },
}, },
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: 1, config.DisplayOrderAnnotation: -4,
config.DisplayHintAnnotation: config.DisplayHintOneOf, config.DisplayHintAnnotation: config.DisplayHintOneOf,
config.CategoryAnnotation: "Expertise & Release", config.CategoryAnnotation: "Updates",
}, },
}) })
if err != nil { if err != nil {
@ -52,17 +52,17 @@ func registerConfig() error {
} }
err = config.Register(&config.Option{ err = config.Register(&config.Option{
Name: "Disable Updates", Name: "Automatic Updates",
Key: disableUpdatesKey, Key: enableUpdatesKey,
Description: "Disable automatic updates. This affects all kinds of updates, including intelligence feeds and broadcast notifications.", Description: "Enable automatic checking, downloading and applying of updates. This affects all kinds of updates, including intelligence feeds and broadcast notifications.",
OptType: config.OptTypeBool, OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelExpert, ExpertiseLevel: config.ExpertiseLevelExpert,
ReleaseLevel: config.ReleaseLevelStable, ReleaseLevel: config.ReleaseLevelStable,
RequiresRestart: false, RequiresRestart: false,
DefaultValue: false, DefaultValue: true,
Annotations: config.Annotations{ Annotations: config.Annotations{
config.DisplayOrderAnnotation: 64, config.DisplayOrderAnnotation: -12,
config.CategoryAnnotation: "General", config.CategoryAnnotation: "Updates",
}, },
}) })
if err != nil { if err != nil {
@ -76,8 +76,8 @@ func initConfig() {
releaseChannel = config.GetAsString(releaseChannelKey, releaseChannelStable) releaseChannel = config.GetAsString(releaseChannelKey, releaseChannelStable)
previousReleaseChannel = releaseChannel() previousReleaseChannel = releaseChannel()
disableUpdates = config.GetAsBool(disableUpdatesKey, false) enableUpdates = config.GetAsBool(enableUpdatesKey, true)
updatesCurrentlyDisabled = disableUpdates() updatesCurrentlyEnabled = enableUpdates()
devMode = config.GetAsBool(cfgDevModeKey, false) devMode = config.GetAsBool(cfgDevModeKey, false)
previousDevMode = devMode() previousDevMode = devMode()
@ -99,10 +99,10 @@ func updateRegistryConfig(_ context.Context, _ interface{}) error {
changed = true changed = true
} }
if disableUpdates() != updatesCurrentlyDisabled { if enableUpdates() != updatesCurrentlyEnabled {
updatesCurrentlyDisabled = disableUpdates() updatesCurrentlyEnabled = enableUpdates()
changed = true changed = true
forceUpdate = !updatesCurrentlyDisabled forceUpdate = updatesCurrentlyEnabled
} }
if changed { if changed {
@ -113,7 +113,7 @@ func updateRegistryConfig(_ context.Context, _ interface{}) error {
module.Resolve(updateFailed) module.Resolve(updateFailed)
_ = TriggerUpdate() _ = TriggerUpdate()
log.Infof("updates: automatic updates enabled again.") log.Infof("updates: automatic updates enabled again.")
} else if updatesCurrentlyDisabled { } else if !updatesCurrentlyEnabled {
module.Warning(updateFailed, "Automatic updates are disabled! This also affects security updates and threat intelligence.") module.Warning(updateFailed, "Automatic updates are disabled! This also affects security updates and threat intelligence.")
log.Warningf("updates: automatic updates are now disabled.") log.Warningf("updates: automatic updates are now disabled.")
} }

View file

@ -20,7 +20,7 @@ const (
releaseChannelStable = "stable" releaseChannelStable = "stable"
releaseChannelBeta = "beta" releaseChannelBeta = "beta"
disableUpdatesKey = "core/disableUpdates" enableUpdatesKey = "core/automaticUpdates"
// ModuleName is the name of the update module // ModuleName is the name of the update module
// and can be used when declaring module dependencies. // and can be used when declaring module dependencies.
@ -245,7 +245,7 @@ func DisableUpdateSchedule() error {
} }
func checkForUpdates(ctx context.Context) (err error) { func checkForUpdates(ctx context.Context) (err error) {
if updatesCurrentlyDisabled { if !updatesCurrentlyEnabled {
log.Debugf("updates: automatic updates are disabled") log.Debugf("updates: automatic updates are disabled")
return nil return nil
} }