Improve system resolver profile
This commit is contained in:
@@ -55,8 +55,10 @@ var defaultDeciders = []deciderFn{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dnsFromSystemResolverDeciders = []deciderFn{
|
var dnsFromSystemResolverDeciders = []deciderFn{
|
||||||
|
checkEndpointListsForSystemResolverDNSRequests,
|
||||||
checkConnectivityDomain,
|
checkConnectivityDomain,
|
||||||
checkBypassPrevention,
|
checkBypassPrevention,
|
||||||
|
checkFilterLists,
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecideOnConnection makes a decision about a connection.
|
// DecideOnConnection makes a decision about a connection.
|
||||||
@@ -214,6 +216,29 @@ func checkEndpointLists(ctx context.Context, conn *network.Connection, p *profil
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkEndpointListsForSystemResolverDNSRequests is a special version of
|
||||||
|
// checkEndpointLists that is only meant for DNS queries by the system
|
||||||
|
// resolver. It only checks the endpoint filter list of the local profile and
|
||||||
|
// does not include the global profile.
|
||||||
|
func checkEndpointListsForSystemResolverDNSRequests(ctx context.Context, conn *network.Connection, p *profile.LayeredProfile, _ packet.Packet) bool {
|
||||||
|
profileEndpoints := p.LocalProfile().GetEndpoints()
|
||||||
|
if profileEndpoints.IsSet() {
|
||||||
|
result, reason := profileEndpoints.Match(ctx, conn.Entity)
|
||||||
|
if endpoints.IsDecision(result) {
|
||||||
|
switch result {
|
||||||
|
case endpoints.Denied:
|
||||||
|
conn.DenyWithContext(reason.String(), profile.CfgOptionEndpointsKey, reason.Context())
|
||||||
|
return true
|
||||||
|
case endpoints.Permitted:
|
||||||
|
conn.AcceptWithContext(reason.String(), profile.CfgOptionEndpointsKey, reason.Context())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func checkConnectionType(ctx context.Context, conn *network.Connection, p *profile.LayeredProfile, _ packet.Packet) bool {
|
func checkConnectionType(ctx context.Context, conn *network.Connection, p *profile.LayeredProfile, _ packet.Packet) bool {
|
||||||
switch {
|
switch {
|
||||||
case conn.Type != network.IPConnection:
|
case conn.Type != network.IPConnection:
|
||||||
|
|||||||
@@ -301,6 +301,22 @@ func (profile *Profile) IsOutdated() bool {
|
|||||||
return profile.outdated.IsSet()
|
return profile.outdated.IsSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEndpoints returns the endpoint list of the profile.
|
||||||
|
func (profile *Profile) GetEndpoints() endpoints.Endpoints {
|
||||||
|
profile.RLock()
|
||||||
|
defer profile.RUnlock()
|
||||||
|
|
||||||
|
return profile.endpoints
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetServiceEndpoints returns the service endpoint list of the profile.
|
||||||
|
func (profile *Profile) GetServiceEndpoints() endpoints.Endpoints {
|
||||||
|
profile.RLock()
|
||||||
|
defer profile.RUnlock()
|
||||||
|
|
||||||
|
return profile.serviceEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
// AddEndpoint adds an endpoint to the endpoint list, saves the profile and reloads the configuration.
|
// AddEndpoint adds an endpoint to the endpoint list, saves the profile and reloads the configuration.
|
||||||
func (profile *Profile) AddEndpoint(newEntry string) {
|
func (profile *Profile) AddEndpoint(newEntry string) {
|
||||||
profile.addEndpointyEntry(CfgOptionEndpointsKey, newEntry)
|
profile.addEndpointyEntry(CfgOptionEndpointsKey, newEntry)
|
||||||
|
|||||||
@@ -85,19 +85,45 @@ func getSpecialProfile(profileID, linkedPath string) *Profile {
|
|||||||
return New(SourceLocal, SystemProfileID, linkedPath, nil)
|
return New(SourceLocal, SystemProfileID, linkedPath, nil)
|
||||||
|
|
||||||
case SystemResolverProfileID:
|
case SystemResolverProfileID:
|
||||||
return New(
|
systemResolverProfile := New(
|
||||||
SourceLocal,
|
SourceLocal,
|
||||||
SystemResolverProfileID,
|
SystemResolverProfileID,
|
||||||
linkedPath,
|
linkedPath,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
|
// Explicitly setting the default action to "permit" will improve the
|
||||||
|
// user experience for people who set the global default to "prompt".
|
||||||
|
// Resolved domain from the system resolver are checked again when
|
||||||
|
// attributed to a connection of a regular process. Otherwise, users
|
||||||
|
// would see two connection prompts for the same domain.
|
||||||
|
CfgOptionDefaultActionKey: "permit",
|
||||||
|
// Explicitly allow localhost and answers to multicast protocols that
|
||||||
|
// are commonly used by system resolvers.
|
||||||
|
// TODO: When the Portmaster gains the ability to attribute multicast
|
||||||
|
// responses to their requests, these rules can probably be removed
|
||||||
|
// again.
|
||||||
CfgOptionServiceEndpointsKey: []string{
|
CfgOptionServiceEndpointsKey: []string{
|
||||||
"+ Localhost", // Allow everything from localhost.
|
"+ Localhost", // Allow everything from localhost.
|
||||||
"+ LAN UDP/5353", // Allow inbound mDNS requests and multicast replies.
|
"+ LAN UDP/5353", // Allow inbound mDNS requests and multicast replies.
|
||||||
"+ LAN UDP/5355", // Allow inbound LLMNR requests and multicast replies.
|
"+ LAN UDP/5355", // Allow inbound LLMNR requests and multicast replies.
|
||||||
"+ LAN UDP/1900", // Allow inbound SSDP requests and multicast replies.
|
"+ LAN UDP/1900", // Allow inbound SSDP requests and multicast replies.
|
||||||
},
|
},
|
||||||
|
// Explicitly disable all filter lists, as these will be checked later
|
||||||
|
// with the attributed connection. As this is the system resolver, this
|
||||||
|
// list can instead be used as a global enforcement of filter lists, if
|
||||||
|
// the system resolver is used. Users who want to
|
||||||
|
CfgOptionFilterListsKey: []string{},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
// Add description to tell users about the quirks of this profile.
|
||||||
|
systemResolverProfile.Description = `The System DNS Client is a system service that requires special handling. For regular network connections, the configured settings will apply as usual, but DNS requests coming from the System DNS Client are handled in a special way, as they could actually be coming from any other application on the system.
|
||||||
|
|
||||||
|
In order to respect the app settings of the actual application, DNS requests from the System DNS Client are only subject to the following settings:
|
||||||
|
|
||||||
|
- Outgoing Rules (without global rules)
|
||||||
|
- Block Bypassing
|
||||||
|
- Filter Lists
|
||||||
|
`
|
||||||
|
return systemResolverProfile
|
||||||
|
|
||||||
case PortmasterProfileID:
|
case PortmasterProfileID:
|
||||||
profile := New(SourceLocal, PortmasterProfileID, linkedPath, nil)
|
profile := New(SourceLocal, PortmasterProfileID, linkedPath, nil)
|
||||||
@@ -155,7 +181,7 @@ func specialProfileNeedsReset(profile *Profile) bool {
|
|||||||
|
|
||||||
switch profile.ID {
|
switch profile.ID {
|
||||||
case SystemResolverProfileID:
|
case SystemResolverProfileID:
|
||||||
return canBeUpgraded(profile, "18.5.2021")
|
return canBeUpgraded(profile, "1.6.2021")
|
||||||
default:
|
default:
|
||||||
// Not a special profile or no upgrade available yet.
|
// Not a special profile or no upgrade available yet.
|
||||||
return false
|
return false
|
||||||
@@ -175,7 +201,7 @@ func canBeUpgraded(profile *Profile, upgradeDate string) bool {
|
|||||||
log.Infof("profile: upgrading special profile %s", profile.ScopedID())
|
log.Infof("profile: upgrading special profile %s", profile.ScopedID())
|
||||||
|
|
||||||
notifications.NotifyInfo(
|
notifications.NotifyInfo(
|
||||||
"profiles:upgraded-special-profile-"+profile.ID,
|
"profiles:upgraded-special-profile:"+profile.ID,
|
||||||
profile.Name+" Settings Upgraded",
|
profile.Name+" Settings Upgraded",
|
||||||
// TODO: Remove disclaimer.
|
// TODO: Remove disclaimer.
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
|
|||||||
Reference in New Issue
Block a user