mirror of https://github.com/0xERR0R/blocky.git
feat: update list config and code to use "allow/deny" language
This commit is contained in:
parent
3515483795
commit
bcd1381e18
|
@ -20,10 +20,10 @@ Blocky is a DNS proxy and ad-blocker for the local network written in Go with fo
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Blocking** - Blocking of DNS queries with external lists (Ad-block, malware) and whitelisting
|
- **Blocking** - Blocking of DNS queries with external lists (Ad-block, malware) and allowlisting
|
||||||
|
|
||||||
- Definition of black and white lists per client group (Kids, Smart home devices, etc.)
|
- Definition of allow/denylists per client group (Kids, Smart home devices, etc.)
|
||||||
- Periodical reload of external black and white lists
|
- Periodical reload of external allow/denylists
|
||||||
- Regex support
|
- Regex support
|
||||||
- Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)
|
- Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ var _ = Describe("root command", func() {
|
||||||
" default:",
|
" default:",
|
||||||
" - 1.1.1.1",
|
" - 1.1.1.1",
|
||||||
"blocking:",
|
"blocking:",
|
||||||
" blackLists:",
|
" denylists:",
|
||||||
" ads:",
|
" ads:",
|
||||||
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
|
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
|
||||||
" clientGroupsBlock:",
|
" clientGroupsBlock:",
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
|
|
||||||
// Blocking configuration for query blocking
|
// Blocking configuration for query blocking
|
||||||
type Blocking struct {
|
type Blocking struct {
|
||||||
BlackLists map[string][]BytesSource `yaml:"blackLists"`
|
Denylists map[string][]BytesSource `yaml:"denylists"`
|
||||||
WhiteLists map[string][]BytesSource `yaml:"whiteLists"`
|
Allowlists map[string][]BytesSource `yaml:"allowlists"`
|
||||||
ClientGroupsBlock map[string][]string `yaml:"clientGroupsBlock"`
|
ClientGroupsBlock map[string][]string `yaml:"clientGroupsBlock"`
|
||||||
BlockType string `yaml:"blockType" default:"ZEROIP"`
|
BlockType string `yaml:"blockType" default:"ZEROIP"`
|
||||||
BlockTTL Duration `yaml:"blockTTL" default:"6h"`
|
BlockTTL Duration `yaml:"blockTTL" default:"6h"`
|
||||||
|
@ -17,19 +17,23 @@ type Blocking struct {
|
||||||
|
|
||||||
// Deprecated options
|
// Deprecated options
|
||||||
Deprecated struct {
|
Deprecated struct {
|
||||||
DownloadTimeout *Duration `yaml:"downloadTimeout"`
|
BlackLists *map[string][]BytesSource `yaml:"blackLists"`
|
||||||
DownloadAttempts *uint `yaml:"downloadAttempts"`
|
WhiteLists *map[string][]BytesSource `yaml:"whiteLists"`
|
||||||
DownloadCooldown *Duration `yaml:"downloadCooldown"`
|
DownloadTimeout *Duration `yaml:"downloadTimeout"`
|
||||||
RefreshPeriod *Duration `yaml:"refreshPeriod"`
|
DownloadAttempts *uint `yaml:"downloadAttempts"`
|
||||||
FailStartOnListError *bool `yaml:"failStartOnListError"`
|
DownloadCooldown *Duration `yaml:"downloadCooldown"`
|
||||||
ProcessingConcurrency *uint `yaml:"processingConcurrency"`
|
RefreshPeriod *Duration `yaml:"refreshPeriod"`
|
||||||
StartStrategy *InitStrategy `yaml:"startStrategy"`
|
FailStartOnListError *bool `yaml:"failStartOnListError"`
|
||||||
MaxErrorsPerFile *int `yaml:"maxErrorsPerFile"`
|
ProcessingConcurrency *uint `yaml:"processingConcurrency"`
|
||||||
|
StartStrategy *InitStrategy `yaml:"startStrategy"`
|
||||||
|
MaxErrorsPerFile *int `yaml:"maxErrorsPerFile"`
|
||||||
} `yaml:",inline"`
|
} `yaml:",inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Blocking) migrate(logger *logrus.Entry) bool {
|
func (c *Blocking) migrate(logger *logrus.Entry) bool {
|
||||||
return Migrate(logger, "blocking", c.Deprecated, map[string]Migrator{
|
return Migrate(logger, "blocking", c.Deprecated, map[string]Migrator{
|
||||||
|
"blackLists": Move(To("denylists", c)),
|
||||||
|
"whiteLists": Move(To("allowlists", c)),
|
||||||
"downloadTimeout": Move(To("loading.downloads.timeout", &c.Loading.Downloads)),
|
"downloadTimeout": Move(To("loading.downloads.timeout", &c.Loading.Downloads)),
|
||||||
"downloadAttempts": Move(To("loading.downloads.attempts", &c.Loading.Downloads)),
|
"downloadAttempts": Move(To("loading.downloads.attempts", &c.Loading.Downloads)),
|
||||||
"downloadCooldown": Move(To("loading.downloads.cooldown", &c.Loading.Downloads)),
|
"downloadCooldown": Move(To("loading.downloads.cooldown", &c.Loading.Downloads)),
|
||||||
|
@ -67,14 +71,14 @@ func (c *Blocking) LogConfig(logger *logrus.Entry) {
|
||||||
logger.Info("loading:")
|
logger.Info("loading:")
|
||||||
log.WithIndent(logger, " ", c.Loading.LogConfig)
|
log.WithIndent(logger, " ", c.Loading.LogConfig)
|
||||||
|
|
||||||
logger.Info("blacklist:")
|
logger.Info("denylists:")
|
||||||
log.WithIndent(logger, " ", func(logger *logrus.Entry) {
|
log.WithIndent(logger, " ", func(logger *logrus.Entry) {
|
||||||
c.logListGroups(logger, c.BlackLists)
|
c.logListGroups(logger, c.Denylists)
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.Info("whitelist:")
|
logger.Info("allowlists:")
|
||||||
log.WithIndent(logger, " ", func(logger *logrus.Entry) {
|
log.WithIndent(logger, " ", func(logger *logrus.Entry) {
|
||||||
c.logListGroups(logger, c.WhiteLists)
|
c.logListGroups(logger, c.Allowlists)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ var _ = Describe("BlockingConfig", func() {
|
||||||
cfg = Blocking{
|
cfg = Blocking{
|
||||||
BlockType: "ZEROIP",
|
BlockType: "ZEROIP",
|
||||||
BlockTTL: Duration(time.Minute),
|
BlockTTL: Duration(time.Minute),
|
||||||
BlackLists: map[string][]BytesSource{
|
Denylists: map[string][]BytesSource{
|
||||||
"gr1": NewBytesSources("/a/file/path"),
|
"gr1": NewBytesSources("/a/file/path"),
|
||||||
},
|
},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
|
@ -60,4 +60,30 @@ var _ = Describe("BlockingConfig", func() {
|
||||||
Expect(hook.Messages).Should(ContainElement(Equal("blockType = ZEROIP")))
|
Expect(hook.Messages).Should(ContainElement(Equal("blockType = ZEROIP")))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Describe("migrate", func() {
|
||||||
|
It("should copy values", func() {
|
||||||
|
cfg, err := WithDefaults[Blocking]()
|
||||||
|
Expect(err).Should(Succeed())
|
||||||
|
|
||||||
|
cfg.Deprecated.BlackLists = &map[string][]BytesSource{
|
||||||
|
"deny-group": NewBytesSources("/deny.txt"),
|
||||||
|
}
|
||||||
|
cfg.Deprecated.WhiteLists = &map[string][]BytesSource{
|
||||||
|
"allow-group": NewBytesSources("/allow.txt"),
|
||||||
|
}
|
||||||
|
|
||||||
|
migrated := cfg.migrate(logger)
|
||||||
|
Expect(migrated).Should(BeTrue())
|
||||||
|
|
||||||
|
Expect(hook.Calls).ShouldNot(BeEmpty())
|
||||||
|
Expect(hook.Messages).Should(ContainElements(
|
||||||
|
ContainSubstring("blocking.allowlists"),
|
||||||
|
ContainSubstring("blocking.denylists"),
|
||||||
|
))
|
||||||
|
|
||||||
|
Expect(cfg.Allowlists).Should(Equal(*cfg.Deprecated.WhiteLists))
|
||||||
|
Expect(cfg.Denylists).Should(Equal(*cfg.Deprecated.BlackLists))
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -988,8 +988,8 @@ func defaultTestFileConfig(config *Config) {
|
||||||
Expect(config.Conditional.Mapping.Upstreams["multiple.resolvers"]).Should(HaveLen(2))
|
Expect(config.Conditional.Mapping.Upstreams["multiple.resolvers"]).Should(HaveLen(2))
|
||||||
Expect(config.ClientLookup.Upstream.Host).Should(Equal("192.168.178.1"))
|
Expect(config.ClientLookup.Upstream.Host).Should(Equal("192.168.178.1"))
|
||||||
Expect(config.ClientLookup.SingleNameOrder).Should(Equal([]uint{2, 1}))
|
Expect(config.ClientLookup.SingleNameOrder).Should(Equal([]uint{2, 1}))
|
||||||
Expect(config.Blocking.BlackLists).Should(HaveLen(2))
|
Expect(config.Blocking.Denylists).Should(HaveLen(2))
|
||||||
Expect(config.Blocking.WhiteLists).Should(HaveLen(1))
|
Expect(config.Blocking.Allowlists).Should(HaveLen(1))
|
||||||
Expect(config.Blocking.ClientGroupsBlock).Should(HaveLen(2))
|
Expect(config.Blocking.ClientGroupsBlock).Should(HaveLen(2))
|
||||||
Expect(config.Blocking.BlockTTL).Should(Equal(Duration(time.Minute)))
|
Expect(config.Blocking.BlockTTL).Should(Equal(Duration(time.Minute)))
|
||||||
Expect(config.Blocking.Loading.RefreshPeriod).Should(Equal(Duration(2 * time.Hour)))
|
Expect(config.Blocking.Loading.RefreshPeriod).Should(Equal(Duration(2 * time.Hour)))
|
||||||
|
@ -1029,7 +1029,7 @@ func writeConfigYml(tmpDir *helpertest.TmpFolder) *helpertest.TmpFile {
|
||||||
"fqdnOnly:",
|
"fqdnOnly:",
|
||||||
" enable: true",
|
" enable: true",
|
||||||
"blocking:",
|
"blocking:",
|
||||||
" blackLists:",
|
" denylists:",
|
||||||
" ads:",
|
" ads:",
|
||||||
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
|
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
|
||||||
" - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
|
" - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
|
||||||
|
@ -1039,9 +1039,9 @@ func writeConfigYml(tmpDir *helpertest.TmpFolder) *helpertest.TmpFile {
|
||||||
" - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
|
" - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
|
||||||
" special:",
|
" special:",
|
||||||
" - https://hosts-file.net/ad_servers.txt",
|
" - https://hosts-file.net/ad_servers.txt",
|
||||||
" whiteLists:",
|
" allowlists:",
|
||||||
" ads:",
|
" ads:",
|
||||||
" - whitelist.txt",
|
" - allowlist.txt",
|
||||||
" clientGroupsBlock:",
|
" clientGroupsBlock:",
|
||||||
" default:",
|
" default:",
|
||||||
" - ads",
|
" - ads",
|
||||||
|
@ -1119,7 +1119,7 @@ func writeConfigDir(tmpDir *helpertest.TmpFolder) {
|
||||||
|
|
||||||
tmpDir.CreateStringFile("config2.yaml",
|
tmpDir.CreateStringFile("config2.yaml",
|
||||||
"blocking:",
|
"blocking:",
|
||||||
" blackLists:",
|
" denylists:",
|
||||||
" ads:",
|
" ads:",
|
||||||
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
|
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
|
||||||
" - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
|
" - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
|
||||||
|
@ -1129,9 +1129,9 @@ func writeConfigDir(tmpDir *helpertest.TmpFolder) {
|
||||||
" - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
|
" - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
|
||||||
" special:",
|
" special:",
|
||||||
" - https://hosts-file.net/ad_servers.txt",
|
" - https://hosts-file.net/ad_servers.txt",
|
||||||
" whiteLists:",
|
" allowlists:",
|
||||||
" ads:",
|
" ads:",
|
||||||
" - whitelist.txt",
|
" - allowlist.txt",
|
||||||
" clientGroupsBlock:",
|
" clientGroupsBlock:",
|
||||||
" default:",
|
" default:",
|
||||||
" - ads",
|
" - ads",
|
||||||
|
|
|
@ -33,7 +33,6 @@ To print runtime configuration / statistics, you can send `SIGUSR1` signal to ru
|
||||||
INFO server: MEM NumGC = 1533
|
INFO server: MEM NumGC = 1533
|
||||||
INFO server: RUN NumCPU = 4
|
INFO server: RUN NumCPU = 4
|
||||||
INFO server: RUN NumGoroutine = 18
|
INFO server: RUN NumGoroutine = 18
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! hint
|
!!! hint
|
||||||
|
@ -49,7 +48,7 @@ automatically.
|
||||||
|
|
||||||
Some links/ideas for lists:
|
Some links/ideas for lists:
|
||||||
|
|
||||||
### Blacklists
|
### Denylists
|
||||||
|
|
||||||
* [https://github.com/StevenBlack/hosts](https://github.com/StevenBlack/hosts)
|
* [https://github.com/StevenBlack/hosts](https://github.com/StevenBlack/hosts)
|
||||||
* [https://github.com/nickspaargaren/no-google](https://github.com/nickspaargaren/no-google)
|
* [https://github.com/nickspaargaren/no-google](https://github.com/nickspaargaren/no-google)
|
||||||
|
@ -60,11 +59,11 @@ Some links/ideas for lists:
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
|
|
||||||
Use only blacklists from the sources you trust!
|
Use only denylists from the sources you trust!
|
||||||
|
|
||||||
### Whitelists
|
### Allowlists
|
||||||
|
|
||||||
* [https://github.com/anudeepND/whitelist](https://github.com/anudeepND/whitelist)
|
* [https://github.com/anudeepND/whitelist](https://github.com/anudeepND/allowlist)
|
||||||
|
|
||||||
## List of public DNS servers
|
## List of public DNS servers
|
||||||
|
|
||||||
|
@ -74,7 +73,7 @@ Some links/ideas for lists:
|
||||||
|
|
||||||
Please read the description before using the DNS server as upstream. Some of them provide already an ad-blocker, some
|
Please read the description before using the DNS server as upstream. Some of them provide already an ad-blocker, some
|
||||||
filters other content. If you use external DNS server with included ad-blocker, you can't choose which domains should be
|
filters other content. If you use external DNS server with included ad-blocker, you can't choose which domains should be
|
||||||
blocked, and you can't use whitelisting.
|
blocked, and you can't use allowlisting.
|
||||||
|
|
||||||
This is only a small excerpt of all free available DNS servers and should only be understood as an idee.
|
This is only a small excerpt of all free available DNS servers and should only be understood as an idee.
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@ info:
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Blocking** - Blocking of DNS queries with external lists (Ad-block, malware) and whitelisting
|
- **Blocking** - Blocking of DNS queries with external lists (Ad-block, malware) and allowlisting
|
||||||
|
|
||||||
- Definition of black and white lists per client group (Kids, Smart home devices, etc.)
|
- Definition of allow/denylists per client group (Kids, Smart home devices, etc.)
|
||||||
- Periodical reload of external black and white lists
|
- Periodical reload of external allow/denylists
|
||||||
- Regex support
|
- Regex support
|
||||||
- Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)
|
- Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)
|
||||||
|
|
||||||
|
|
|
@ -429,7 +429,7 @@
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"uid": "${DS_PROMETHEUS}"
|
"uid": "${DS_PROMETHEUS}"
|
||||||
},
|
},
|
||||||
"description": "Number of blacklist entries",
|
"description": "Number of denylist entries",
|
||||||
"fieldConfig": {
|
"fieldConfig": {
|
||||||
"defaults": {
|
"defaults": {
|
||||||
"mappings": [
|
"mappings": [
|
||||||
|
@ -487,7 +487,7 @@
|
||||||
"uid": "${DS_PROMETHEUS}"
|
"uid": "${DS_PROMETHEUS}"
|
||||||
},
|
},
|
||||||
"exemplar": true,
|
"exemplar": true,
|
||||||
"expr": "sum(blocky_blacklist_cache) / sum(up{job=~\"$job\"})",
|
"expr": "sum(blocky_denylist_cache) / sum(up{job=~\"$job\"})",
|
||||||
"format": "table",
|
"format": "table",
|
||||||
"instant": false,
|
"instant": false,
|
||||||
"interval": "",
|
"interval": "",
|
||||||
|
@ -495,7 +495,7 @@
|
||||||
"refId": "A"
|
"refId": "A"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "Blacklist entries total",
|
"title": "Denylist entries total",
|
||||||
"transparent": true,
|
"transparent": true,
|
||||||
"type": "stat"
|
"type": "stat"
|
||||||
},
|
},
|
||||||
|
@ -1683,7 +1683,7 @@
|
||||||
"uid": "${DS_PROMETHEUS}"
|
"uid": "${DS_PROMETHEUS}"
|
||||||
},
|
},
|
||||||
"exemplar": false,
|
"exemplar": false,
|
||||||
"expr": "topk(1, blocky_blacklist_cache) by (group)",
|
"expr": "topk(1, blocky_denylist_cache) by (group)",
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
"instant": true,
|
"instant": true,
|
||||||
"interval": "",
|
"interval": "",
|
||||||
|
@ -1691,7 +1691,7 @@
|
||||||
"refId": "A"
|
"refId": "A"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "Blacklist by group",
|
"title": "Denylist by group",
|
||||||
"transparent": true,
|
"transparent": true,
|
||||||
"type": "piechart"
|
"type": "piechart"
|
||||||
},
|
},
|
||||||
|
@ -1978,4 +1978,4 @@
|
||||||
"uid": "JvOqE4gRk",
|
"uid": "JvOqE4gRk",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"weekStart": ""
|
"weekStart": ""
|
||||||
}
|
}
|
|
@ -243,7 +243,7 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "Blocked by Blacklist",
|
"title": "Blocked by Denylist",
|
||||||
"type": "piechart"
|
"type": "piechart"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -243,7 +243,7 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "Blocked by Blacklist",
|
"title": "Blocked by Denylist",
|
||||||
"type": "piechart"
|
"type": "piechart"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,10 +62,10 @@ conditional:
|
||||||
fritz.box: 192.168.178.1
|
fritz.box: 192.168.178.1
|
||||||
lan.net: 192.168.178.1,192.168.178.2
|
lan.net: 192.168.178.1,192.168.178.2
|
||||||
|
|
||||||
# optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.)
|
# optional: use allow/denylists to block queries (for example ads, trackers, adult pages etc.)
|
||||||
blocking:
|
blocking:
|
||||||
# definition of blacklist groups. Can be external link (http/https) or local file
|
# definition of denylist groups. Can be external link (http/https) or local file
|
||||||
blackLists:
|
denylists:
|
||||||
ads:
|
ads:
|
||||||
- https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
|
- https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
|
||||||
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
||||||
|
@ -77,14 +77,16 @@ blocking:
|
||||||
*.example.com
|
*.example.com
|
||||||
special:
|
special:
|
||||||
- https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
|
- https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
|
||||||
# definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked
|
# definition of allowlist groups.
|
||||||
whiteLists:
|
# Note: if the same group has both allow/denylists, allowlists take precedence. Meaning if a domain is both blocked and allowed, it will be allowed.
|
||||||
|
# If a group has only allowlist entries, only domains from this list are allowed, and all others be blocked.
|
||||||
|
allowlists:
|
||||||
ads:
|
ads:
|
||||||
- whitelist.txt
|
- allowlist.txt
|
||||||
- |
|
- |
|
||||||
# inline definition with YAML literal block scalar style
|
# inline definition with YAML literal block scalar style
|
||||||
# hosts format
|
# hosts format
|
||||||
whitelistdomain.com
|
allowlistdomain.com
|
||||||
# this is a regex
|
# this is a regex
|
||||||
/^banners?[_.-]/
|
/^banners?[_.-]/
|
||||||
# definition: which groups should be applied for which client
|
# definition: which groups should be applied for which client
|
||||||
|
@ -242,7 +244,7 @@ minTlsServeVersion: 1.3
|
||||||
#certFile: server.crt
|
#certFile: server.crt
|
||||||
#keyFile: server.key
|
#keyFile: server.key
|
||||||
|
|
||||||
# optional: use these DNS servers to resolve blacklist urls and upstream DNS servers. It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries.
|
# optional: use these DNS servers to resolve denylist urls and upstream DNS servers. It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries.
|
||||||
bootstrapDns:
|
bootstrapDns:
|
||||||
- tcp+udp:1.1.1.1
|
- tcp+udp:1.1.1.1
|
||||||
- https://1.1.1.1/dns-query
|
- https://1.1.1.1/dns-query
|
||||||
|
|
|
@ -395,16 +395,16 @@ contains a map of client name and multiple IP addresses.
|
||||||
|
|
||||||
Use `192.168.178.1` for rDNS lookup. Take second name if present, if not take first name. IP address `192.168.178.29` is mapped to `laptop` as client name.
|
Use `192.168.178.1` for rDNS lookup. Take second name if present, if not take first name. IP address `192.168.178.29` is mapped to `laptop` as client name.
|
||||||
|
|
||||||
## Blocking and whitelisting
|
## Blocking and allowlisting
|
||||||
|
|
||||||
Blocky can use lists of domains and IPs to block (e.g. advertisement, malware,
|
Blocky can use lists of domains and IPs to block (e.g. advertisement, malware,
|
||||||
trackers, adult sites). You can group several list sources together and define the blocking behavior per client.
|
trackers, adult sites). You can group several list sources together and define the blocking behavior per client.
|
||||||
Blocking uses the [DNS sinkhole](https://en.wikipedia.org/wiki/DNS_sinkhole) approach. For each DNS query, the domain name from
|
Blocking uses the [DNS sinkhole](https://en.wikipedia.org/wiki/DNS_sinkhole) approach. For each DNS query, the domain name from
|
||||||
the request, IP address from the response, and any CNAME records will be checked to determine whether to block the query or not.
|
the request, IP address from the response, and any CNAME records will be checked to determine whether to block the query or not.
|
||||||
|
|
||||||
To avoid over-blocking, you can use whitelists.
|
To avoid over-blocking, you can use allowlists.
|
||||||
|
|
||||||
### Definition black and whitelists
|
### Definition allow/denylists
|
||||||
|
|
||||||
Lists are defined in groups. This allows using different sets of lists for different clients.
|
Lists are defined in groups. This allows using different sets of lists for different clients.
|
||||||
|
|
||||||
|
@ -421,7 +421,7 @@ The supported list formats are:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
blocking:
|
blocking:
|
||||||
blackLists:
|
denylists:
|
||||||
ads:
|
ads:
|
||||||
- https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
|
- https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
|
||||||
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
||||||
|
@ -436,25 +436,24 @@ The supported list formats are:
|
||||||
/^banners?[_.-]/
|
/^banners?[_.-]/
|
||||||
special:
|
special:
|
||||||
- https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
|
- https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
|
||||||
whiteLists:
|
allowlists:
|
||||||
ads:
|
ads:
|
||||||
- whitelist.txt
|
- allowlist.txt
|
||||||
- /path/to/file.txt
|
- /path/to/file.txt
|
||||||
- |
|
- |
|
||||||
# inline definition with YAML literal block scalar style
|
# inline definition with YAML literal block scalar style
|
||||||
whitelistdomain.com
|
allowlistdomain.com
|
||||||
```
|
```
|
||||||
|
|
||||||
In this example you can see 2 groups: **ads** and **special** with one list. The **ads** group includes 2 inline lists.
|
In this example you can see 2 groups: **ads** and **special** with one list. The **ads** group includes 2 inline lists.
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
|
|
||||||
If the same group has black and whitelists, whitelists will be used to disable particular blacklist entries.
|
If the same group has **both** allow/denylists, allowlists take precedence. Meaning if a domain is both blocked and allowed, it will be allowed.
|
||||||
If a group has **only** whitelist entries -> this means only domains from this list are allowed, all other domains will
|
If a group has **only allowlist** entries, only domains from this list are allowed, and all others be blocked.
|
||||||
be blocked.
|
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
You must also define client group mapping, otherwise you black and whitelist definition will have no effect.
|
You must also define a client group mapping, otherwise the allow/denylist definitions will have no effect.
|
||||||
|
|
||||||
#### Wildcard support
|
#### Wildcard support
|
||||||
|
|
||||||
|
@ -833,7 +832,7 @@ These settings apply only to the resolver under which they are nested.
|
||||||
```yaml
|
```yaml
|
||||||
blocking:
|
blocking:
|
||||||
loading:
|
loading:
|
||||||
# only applies to white/blacklists
|
# only applies to allow/denylists
|
||||||
|
|
||||||
hostsFile:
|
hostsFile:
|
||||||
loading:
|
loading:
|
||||||
|
|
|
@ -8,10 +8,10 @@ Blocky is a DNS proxy and ad-blocker for the local network written in Go with fo
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Blocking** - :no_entry: Blocking of DNS queries with external lists (Ad-block, malware) and whitelisting
|
- **Blocking** - :no_entry: Blocking of DNS queries with external lists (Ad-block, malware) and allowlisting
|
||||||
|
|
||||||
* Definition of black and white lists per client group (Kids, Smart home devices, etc.)
|
* Definition of allow/denylists per client group (Kids, Smart home devices, etc.)
|
||||||
* Periodical reload of external black and white lists
|
* Periodical reload of external allow/denylists
|
||||||
* Regex support
|
* Regex support
|
||||||
* Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)
|
* Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ upstream:
|
||||||
- tcp-tls:fdns1.dismail.de:853
|
- tcp-tls:fdns1.dismail.de:853
|
||||||
- https://dns.digitale-gesellschaft.ch/dns-query
|
- https://dns.digitale-gesellschaft.ch/dns-query
|
||||||
blocking:
|
blocking:
|
||||||
blackLists:
|
denylists:
|
||||||
ads:
|
ads:
|
||||||
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
||||||
clientGroupsBlock:
|
clientGroupsBlock:
|
||||||
|
@ -95,8 +95,8 @@ docker-compose up -d
|
||||||
### Advanced setup
|
### Advanced setup
|
||||||
|
|
||||||
Following example shows, how to run blocky in a docker container and store query logs on a SAMBA share. Local black and
|
Following example shows, how to run blocky in a docker container and store query logs on a SAMBA share. Local black and
|
||||||
whitelists directories are mounted as volume. You can create own black or whitelists in these directories and define the
|
allowlists directories are mounted as volume. You can create own black or allowlists in these directories and define the
|
||||||
path like '/app/whitelists/whitelist.txt' in the config file.
|
path like '/app/allowlists/allowlist.txt' in the config file.
|
||||||
|
|
||||||
!!! example
|
!!! example
|
||||||
|
|
||||||
|
@ -118,9 +118,9 @@ services:
|
||||||
- ./config.yml:/app/config.yml
|
- ./config.yml:/app/config.yml
|
||||||
# write query logs in this volume
|
# write query logs in this volume
|
||||||
- queryLogs:/logs
|
- queryLogs:/logs
|
||||||
# put your custom white and blacklists in these directories
|
# put your custom allow/denylists in these directories
|
||||||
- ./blacklists:/app/blacklists/
|
- ./denylists:/app/denylists/
|
||||||
- ./whitelists:/app/whitelists/
|
- ./allowlists:/app/allowlists/
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
queryLogs:
|
queryLogs:
|
||||||
|
|
|
@ -27,7 +27,7 @@ To run the CLI, please ensure, that blocky DNS server is running, then execute `
|
||||||
- `./blocky blocking status` to print current status of blocking
|
- `./blocky blocking status` to print current status of blocking
|
||||||
- `./blocky query <domain>` execute DNS query (A) (simple replacement for dig, useful for debug purposes)
|
- `./blocky query <domain>` execute DNS query (A) (simple replacement for dig, useful for debug purposes)
|
||||||
- `./blocky query <domain> --type <queryType>` execute DNS query with passed query type (A, AAAA, MX, ...)
|
- `./blocky query <domain> --type <queryType>` execute DNS query with passed query type (A, AAAA, MX, ...)
|
||||||
- `./blocky lists refresh` reloads all white and blacklists
|
- `./blocky lists refresh` reloads all allow/denylists
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ Following metrics will be exported:
|
||||||
|
|
||||||
| name | Description |
|
| name | Description |
|
||||||
| ------------------------------------------------ | -------------------------------------------------------- |
|
| ------------------------------------------------ | -------------------------------------------------------- |
|
||||||
| blocky_blacklist_cache / blocky_whitelist_cache | Number of entries in blacklist/whitelist cache, partitioned by group |
|
| blocky_denylist_cache / blocky_allowlist_cache | Number of entries in denylist/allowlist cache, partitioned by group |
|
||||||
| blocky_error_total | Number of total queries that ended in error for any reason |
|
| blocky_error_total | Number of total queries that ended in error for any reason |
|
||||||
| blocky_query_total | Number of total queries, partitioned by client and DNS request type (A, AAAA, PTR, etc) |
|
| blocky_query_total | Number of total queries, partitioned by client and DNS request type (A, AAAA, PTR, etc) |
|
||||||
| blocky_request_duration_ms_bucket | Request duration histogram, partitioned by response type (Blocked, cached, etc) |
|
| blocky_request_duration_ms_bucket | Request duration histogram, partitioned by response type (Blocked, cached, etc) |
|
||||||
|
|
|
@ -24,7 +24,7 @@ var _ = Describe("External lists and query blocking", func() {
|
||||||
Expect(err).Should(Succeed())
|
Expect(err).Should(Succeed())
|
||||||
})
|
})
|
||||||
Describe("List download on startup", func() {
|
Describe("List download on startup", func() {
|
||||||
When("external blacklist ist not available", func() {
|
When("external denylist ist not available", func() {
|
||||||
Context("loading.strategy = blocking", func() {
|
Context("loading.strategy = blocking", func() {
|
||||||
BeforeEach(func(ctx context.Context) {
|
BeforeEach(func(ctx context.Context) {
|
||||||
blocky, err = createBlockyContainer(ctx, e2eNet,
|
blocky, err = createBlockyContainer(ctx, e2eNet,
|
||||||
|
@ -37,7 +37,7 @@ var _ = Describe("External lists and query blocking", func() {
|
||||||
"blocking:",
|
"blocking:",
|
||||||
" loading:",
|
" loading:",
|
||||||
" strategy: blocking",
|
" strategy: blocking",
|
||||||
" blackLists:",
|
" denylists:",
|
||||||
" ads:",
|
" ads:",
|
||||||
" - http://wrong.domain.url/list.txt",
|
" - http://wrong.domain.url/list.txt",
|
||||||
" clientGroupsBlock:",
|
" clientGroupsBlock:",
|
||||||
|
@ -72,7 +72,7 @@ var _ = Describe("External lists and query blocking", func() {
|
||||||
"blocking:",
|
"blocking:",
|
||||||
" loading:",
|
" loading:",
|
||||||
" strategy: failOnError",
|
" strategy: failOnError",
|
||||||
" blackLists:",
|
" denylists:",
|
||||||
" ads:",
|
" ads:",
|
||||||
" - http://wrong.domain.url/list.txt",
|
" - http://wrong.domain.url/list.txt",
|
||||||
" clientGroupsBlock:",
|
" clientGroupsBlock:",
|
||||||
|
@ -96,8 +96,8 @@ var _ = Describe("External lists and query blocking", func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Describe("Query blocking against external blacklists", func() {
|
Describe("Query blocking against external denylists", func() {
|
||||||
When("external blacklists are defined and available", func() {
|
When("external denylists are defined and available", func() {
|
||||||
BeforeEach(func(ctx context.Context) {
|
BeforeEach(func(ctx context.Context) {
|
||||||
_, err = createHTTPServerContainer(ctx, "httpserver", e2eNet, "list.txt", "blockeddomain.com")
|
_, err = createHTTPServerContainer(ctx, "httpserver", e2eNet, "list.txt", "blockeddomain.com")
|
||||||
Expect(err).Should(Succeed())
|
Expect(err).Should(Succeed())
|
||||||
|
@ -110,7 +110,7 @@ var _ = Describe("External lists and query blocking", func() {
|
||||||
" default:",
|
" default:",
|
||||||
" - moka",
|
" - moka",
|
||||||
"blocking:",
|
"blocking:",
|
||||||
" blackLists:",
|
" denylists:",
|
||||||
" ads:",
|
" ads:",
|
||||||
" - http://httpserver:8080/list.txt",
|
" - http://httpserver:8080/list.txt",
|
||||||
" clientGroupsBlock:",
|
" clientGroupsBlock:",
|
||||||
|
|
|
@ -49,7 +49,7 @@ var _ = Describe("Metrics functional tests", func() {
|
||||||
" default:",
|
" default:",
|
||||||
" - moka1",
|
" - moka1",
|
||||||
"blocking:",
|
"blocking:",
|
||||||
" blackLists:",
|
" denylists:",
|
||||||
" group1:",
|
" group1:",
|
||||||
" - http://httpserver1:8080/list1.txt",
|
" - http://httpserver1:8080/list1.txt",
|
||||||
" group2:",
|
" group2:",
|
||||||
|
@ -129,8 +129,8 @@ var _ = Describe("Metrics functional tests", func() {
|
||||||
It("Should expose list cache sizes per group as metrics", func(ctx context.Context) {
|
It("Should expose list cache sizes per group as metrics", func(ctx context.Context) {
|
||||||
Eventually(fetchBlockyMetrics).WithArguments(ctx, metricsURL).
|
Eventually(fetchBlockyMetrics).WithArguments(ctx, metricsURL).
|
||||||
Should(ContainElements(
|
Should(ContainElements(
|
||||||
"blocky_blacklist_cache{group=\"group1\"} 1",
|
"blocky_denylist_cache{group=\"group1\"} 1",
|
||||||
"blocky_blacklist_cache{group=\"group2\"} 3",
|
"blocky_denylist_cache{group=\"group2\"} 3",
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,8 +24,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListCacheType represents the type of cached list ENUM(
|
// ListCacheType represents the type of cached list ENUM(
|
||||||
// blacklist // is a list with blocked domains
|
// denylist // is a list with blocked domains
|
||||||
// whitelist // is a list with whitelisted domains / IPs
|
// allowlist // is a list with allowlisted domains / IPs
|
||||||
// )
|
// )
|
||||||
type ListCacheType int
|
type ListCacheType int
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ func BenchmarkRefresh(b *testing.B) {
|
||||||
RefreshPeriod: config.Duration(-1),
|
RefreshPeriod: config.Duration(-1),
|
||||||
}
|
}
|
||||||
downloader := NewDownloader(config.Downloader{}, nil)
|
downloader := NewDownloader(config.Downloader{}, nil)
|
||||||
cache, _ := NewListCache(context.Background(), ListCacheTypeBlacklist, cfg, lists, downloader)
|
cache, _ := NewListCache(context.Background(), ListCacheTypeDenylist, cfg, lists, downloader)
|
||||||
|
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
|
|
@ -12,21 +12,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ListCacheTypeBlacklist is a ListCacheType of type Blacklist.
|
// ListCacheTypeDenylist is a ListCacheType of type Denylist.
|
||||||
// is a list with blocked domains
|
// is a list with blocked domains
|
||||||
ListCacheTypeBlacklist ListCacheType = iota
|
ListCacheTypeDenylist ListCacheType = iota
|
||||||
// ListCacheTypeWhitelist is a ListCacheType of type Whitelist.
|
// ListCacheTypeAllowlist is a ListCacheType of type Allowlist.
|
||||||
// is a list with whitelisted domains / IPs
|
// is a list with allowlisted domains / IPs
|
||||||
ListCacheTypeWhitelist
|
ListCacheTypeAllowlist
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrInvalidListCacheType = fmt.Errorf("not a valid ListCacheType, try [%s]", strings.Join(_ListCacheTypeNames, ", "))
|
var ErrInvalidListCacheType = fmt.Errorf("not a valid ListCacheType, try [%s]", strings.Join(_ListCacheTypeNames, ", "))
|
||||||
|
|
||||||
const _ListCacheTypeName = "blacklistwhitelist"
|
const _ListCacheTypeName = "denylistallowlist"
|
||||||
|
|
||||||
var _ListCacheTypeNames = []string{
|
var _ListCacheTypeNames = []string{
|
||||||
_ListCacheTypeName[0:9],
|
_ListCacheTypeName[0:8],
|
||||||
_ListCacheTypeName[9:18],
|
_ListCacheTypeName[8:17],
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListCacheTypeNames returns a list of possible string values of ListCacheType.
|
// ListCacheTypeNames returns a list of possible string values of ListCacheType.
|
||||||
|
@ -37,8 +37,8 @@ func ListCacheTypeNames() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ListCacheTypeMap = map[ListCacheType]string{
|
var _ListCacheTypeMap = map[ListCacheType]string{
|
||||||
ListCacheTypeBlacklist: _ListCacheTypeName[0:9],
|
ListCacheTypeDenylist: _ListCacheTypeName[0:8],
|
||||||
ListCacheTypeWhitelist: _ListCacheTypeName[9:18],
|
ListCacheTypeAllowlist: _ListCacheTypeName[8:17],
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the Stringer interface.
|
// String implements the Stringer interface.
|
||||||
|
@ -57,8 +57,8 @@ func (x ListCacheType) IsValid() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ListCacheTypeValue = map[string]ListCacheType{
|
var _ListCacheTypeValue = map[string]ListCacheType{
|
||||||
_ListCacheTypeName[0:9]: ListCacheTypeBlacklist,
|
_ListCacheTypeName[0:8]: ListCacheTypeDenylist,
|
||||||
_ListCacheTypeName[9:18]: ListCacheTypeWhitelist,
|
_ListCacheTypeName[8:17]: ListCacheTypeAllowlist,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseListCacheType attempts to convert a string to a ListCacheType.
|
// ParseListCacheType attempts to convert a string to a ListCacheType.
|
||||||
|
|
|
@ -46,7 +46,7 @@ var _ = Describe("ListCache", func() {
|
||||||
ctx, cancelFn = context.WithCancel(context.Background())
|
ctx, cancelFn = context.WithCancel(context.Background())
|
||||||
DeferCleanup(cancelFn)
|
DeferCleanup(cancelFn)
|
||||||
|
|
||||||
listCacheType = ListCacheTypeBlacklist
|
listCacheType = ListCacheTypeDenylist
|
||||||
|
|
||||||
sutConfig, err = config.WithDefaults[config.SourceLoading]()
|
sutConfig, err = config.WithDefaults[config.SourceLoading]()
|
||||||
Expect(err).Should(Succeed())
|
Expect(err).Should(Succeed())
|
||||||
|
@ -306,7 +306,7 @@ var _ = Describe("ListCache", func() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
It("should match", func() {
|
It("should match", func() {
|
||||||
sut, err = NewListCache(ctx, ListCacheTypeBlacklist, sutConfig, lists, downloader)
|
sut, err = NewListCache(ctx, ListCacheTypeDenylist, sutConfig, lists, downloader)
|
||||||
Expect(err).Should(Succeed())
|
Expect(err).Should(Succeed())
|
||||||
|
|
||||||
Expect(sut.groupedCache.ElementCount("gr1")).Should(Equal(lines1 + lines2 + lines3))
|
Expect(sut.groupedCache.ElementCount("gr1")).Should(Equal(lines1 + lines2 + lines3))
|
||||||
|
@ -408,7 +408,7 @@ var _ = Describe("ListCache", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should print list configuration", func() {
|
It("should print list configuration", func() {
|
||||||
sut, err = NewListCache(ctx, ListCacheTypeBlacklist, sutConfig, lists, downloader)
|
sut, err = NewListCache(ctx, ListCacheTypeDenylist, sutConfig, lists, downloader)
|
||||||
Expect(err).Should(Succeed())
|
Expect(err).Should(Succeed())
|
||||||
|
|
||||||
sut.LogConfig(logger)
|
sut.LogConfig(logger)
|
||||||
|
@ -432,7 +432,7 @@ var _ = Describe("ListCache", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should never return an error", func() {
|
It("should never return an error", func() {
|
||||||
_, err := NewListCache(ctx, ListCacheTypeBlacklist, sutConfig, lists, downloader)
|
_, err := NewListCache(ctx, ListCacheTypeDenylist, sutConfig, lists, downloader)
|
||||||
Expect(err).Should(Succeed())
|
Expect(err).Should(Succeed())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -28,14 +28,14 @@ func registerApplicationEventListeners() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func versionNumberGauge() *prometheus.GaugeVec {
|
func versionNumberGauge() *prometheus.GaugeVec {
|
||||||
blacklistCnt := prometheus.NewGaugeVec(
|
denylistCnt := prometheus.NewGaugeVec(
|
||||||
prometheus.GaugeOpts{
|
prometheus.GaugeOpts{
|
||||||
Name: "blocky_build_info",
|
Name: "blocky_build_info",
|
||||||
Help: "Version number and build info",
|
Help: "Version number and build info",
|
||||||
}, []string{"version", "build_time"},
|
}, []string{"version", "build_time"},
|
||||||
)
|
)
|
||||||
|
|
||||||
return blacklistCnt
|
return denylistCnt
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerBlockingEventListeners() {
|
func registerBlockingEventListeners() {
|
||||||
|
@ -51,23 +51,23 @@ func registerBlockingEventListeners() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
blacklistCnt := blacklistGauge()
|
denylistCnt := denylistGauge()
|
||||||
|
|
||||||
whitelistCnt := whitelistGauge()
|
allowlistCnt := allowlistGauge()
|
||||||
|
|
||||||
lastListGroupRefresh := lastListGroupRefresh()
|
lastListGroupRefresh := lastListGroupRefresh()
|
||||||
|
|
||||||
RegisterMetric(blacklistCnt)
|
RegisterMetric(denylistCnt)
|
||||||
RegisterMetric(whitelistCnt)
|
RegisterMetric(allowlistCnt)
|
||||||
RegisterMetric(lastListGroupRefresh)
|
RegisterMetric(lastListGroupRefresh)
|
||||||
|
|
||||||
subscribe(evt.BlockingCacheGroupChanged, func(listType lists.ListCacheType, groupName string, cnt int) {
|
subscribe(evt.BlockingCacheGroupChanged, func(listType lists.ListCacheType, groupName string, cnt int) {
|
||||||
lastListGroupRefresh.Set(float64(time.Now().Unix()))
|
lastListGroupRefresh.Set(float64(time.Now().Unix()))
|
||||||
switch listType {
|
switch listType {
|
||||||
case lists.ListCacheTypeBlacklist:
|
case lists.ListCacheTypeDenylist:
|
||||||
blacklistCnt.WithLabelValues(groupName).Set(float64(cnt))
|
denylistCnt.WithLabelValues(groupName).Set(float64(cnt))
|
||||||
case lists.ListCacheTypeWhitelist:
|
case lists.ListCacheTypeAllowlist:
|
||||||
whitelistCnt.WithLabelValues(groupName).Set(float64(cnt))
|
allowlistCnt.WithLabelValues(groupName).Set(float64(cnt))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -82,26 +82,26 @@ func enabledGauge() prometheus.Gauge {
|
||||||
return enabledGauge
|
return enabledGauge
|
||||||
}
|
}
|
||||||
|
|
||||||
func blacklistGauge() *prometheus.GaugeVec {
|
func denylistGauge() *prometheus.GaugeVec {
|
||||||
blacklistCnt := prometheus.NewGaugeVec(
|
denylistCnt := prometheus.NewGaugeVec(
|
||||||
prometheus.GaugeOpts{
|
prometheus.GaugeOpts{
|
||||||
Name: "blocky_blacklist_cache",
|
Name: "blocky_denylist_cache",
|
||||||
Help: "Number of entries in the blacklist cache",
|
Help: "Number of entries in the denylist cache",
|
||||||
}, []string{"group"},
|
}, []string{"group"},
|
||||||
)
|
)
|
||||||
|
|
||||||
return blacklistCnt
|
return denylistCnt
|
||||||
}
|
}
|
||||||
|
|
||||||
func whitelistGauge() *prometheus.GaugeVec {
|
func allowlistGauge() *prometheus.GaugeVec {
|
||||||
whitelistCnt := prometheus.NewGaugeVec(
|
allowlistCnt := prometheus.NewGaugeVec(
|
||||||
prometheus.GaugeOpts{
|
prometheus.GaugeOpts{
|
||||||
Name: "blocky_whitelist_cache",
|
Name: "blocky_allowlist_cache",
|
||||||
Help: "Number of entries in the whitelist cache",
|
Help: "Number of entries in the allowlist cache",
|
||||||
}, []string{"group"},
|
}, []string{"group"},
|
||||||
)
|
)
|
||||||
|
|
||||||
return whitelistCnt
|
return allowlistCnt
|
||||||
}
|
}
|
||||||
|
|
||||||
func lastListGroupRefresh() prometheus.Gauge {
|
func lastListGroupRefresh() prometheus.Gauge {
|
||||||
|
|
|
@ -79,16 +79,16 @@ type status struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockingResolver checks request's question (domain name) against black and white lists
|
// BlockingResolver checks request's question (domain name) against allow/denylists
|
||||||
type BlockingResolver struct {
|
type BlockingResolver struct {
|
||||||
configurable[*config.Blocking]
|
configurable[*config.Blocking]
|
||||||
NextResolver
|
NextResolver
|
||||||
typed
|
typed
|
||||||
|
|
||||||
blacklistMatcher *lists.ListCache
|
denylistMatcher *lists.ListCache
|
||||||
whitelistMatcher *lists.ListCache
|
allowlistMatcher *lists.ListCache
|
||||||
blockHandler blockHandler
|
blockHandler blockHandler
|
||||||
whitelistOnlyGroups map[string]bool
|
allowlistOnlyGroups map[string]bool
|
||||||
status *status
|
status *status
|
||||||
clientGroupsBlock map[string][]string
|
clientGroupsBlock map[string][]string
|
||||||
redisClient *redis.Client
|
redisClient *redis.Client
|
||||||
|
@ -125,11 +125,11 @@ func NewBlockingResolver(ctx context.Context,
|
||||||
|
|
||||||
downloader := lists.NewDownloader(cfg.Loading.Downloads, bootstrap.NewHTTPTransport())
|
downloader := lists.NewDownloader(cfg.Loading.Downloads, bootstrap.NewHTTPTransport())
|
||||||
|
|
||||||
blacklistMatcher, blErr := lists.NewListCache(ctx, lists.ListCacheTypeBlacklist,
|
denylistMatcher, blErr := lists.NewListCache(ctx, lists.ListCacheTypeDenylist,
|
||||||
cfg.Loading, cfg.BlackLists, downloader)
|
cfg.Loading, cfg.Denylists, downloader)
|
||||||
whitelistMatcher, wlErr := lists.NewListCache(ctx, lists.ListCacheTypeWhitelist,
|
allowlistMatcher, wlErr := lists.NewListCache(ctx, lists.ListCacheTypeAllowlist,
|
||||||
cfg.Loading, cfg.WhiteLists, downloader)
|
cfg.Loading, cfg.Allowlists, downloader)
|
||||||
whitelistOnlyGroups := determineWhitelistOnlyGroups(&cfg)
|
allowlistOnlyGroups := determineAllowlistOnlyGroups(&cfg)
|
||||||
|
|
||||||
err = multierror.Append(err, blErr, wlErr).ErrorOrNil()
|
err = multierror.Append(err, blErr, wlErr).ErrorOrNil()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -141,9 +141,9 @@ func NewBlockingResolver(ctx context.Context,
|
||||||
typed: withType("blocking"),
|
typed: withType("blocking"),
|
||||||
|
|
||||||
blockHandler: blockHandler,
|
blockHandler: blockHandler,
|
||||||
blacklistMatcher: blacklistMatcher,
|
denylistMatcher: denylistMatcher,
|
||||||
whitelistMatcher: whitelistMatcher,
|
allowlistMatcher: allowlistMatcher,
|
||||||
whitelistOnlyGroups: whitelistOnlyGroups,
|
allowlistOnlyGroups: allowlistOnlyGroups,
|
||||||
status: &status{
|
status: &status{
|
||||||
enabled: true,
|
enabled: true,
|
||||||
enableTimer: time.NewTimer(0),
|
enableTimer: time.NewTimer(0),
|
||||||
|
@ -198,18 +198,18 @@ func (r *BlockingResolver) redisSubscriber(ctx context.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshLists triggers the refresh of all black and white lists in the cache
|
// RefreshLists triggers the refresh of all allow/denylists in the cache
|
||||||
func (r *BlockingResolver) RefreshLists() error {
|
func (r *BlockingResolver) RefreshLists() error {
|
||||||
var err *multierror.Error
|
var err *multierror.Error
|
||||||
|
|
||||||
err = multierror.Append(err, r.blacklistMatcher.Refresh())
|
err = multierror.Append(err, r.denylistMatcher.Refresh())
|
||||||
err = multierror.Append(err, r.whitelistMatcher.Refresh())
|
err = multierror.Append(err, r.allowlistMatcher.Refresh())
|
||||||
|
|
||||||
return err.ErrorOrNil()
|
return err.ErrorOrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *BlockingResolver) retrieveAllBlockingGroups() []string {
|
func (r *BlockingResolver) retrieveAllBlockingGroups() []string {
|
||||||
result := maps.Keys(r.cfg.BlackLists)
|
result := maps.Keys(r.cfg.Denylists)
|
||||||
|
|
||||||
result = append(result, "default")
|
result = append(result, "default")
|
||||||
slices.Sort(result)
|
slices.Sort(result)
|
||||||
|
@ -217,7 +217,7 @@ func (r *BlockingResolver) retrieveAllBlockingGroups() []string {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableBlocking enables the blocking against the blacklists
|
// EnableBlocking enables the blocking against the denylists
|
||||||
func (r *BlockingResolver) EnableBlocking(ctx context.Context) {
|
func (r *BlockingResolver) EnableBlocking(ctx context.Context) {
|
||||||
r.internalEnableBlocking()
|
r.internalEnableBlocking()
|
||||||
|
|
||||||
|
@ -310,13 +310,13 @@ func (r *BlockingResolver) BlockingStatus() api.BlockingStatus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns groups, which have only whitelist entries
|
// returns groups, which have only allowlist entries
|
||||||
func determineWhitelistOnlyGroups(cfg *config.Blocking) (result map[string]bool) {
|
func determineAllowlistOnlyGroups(cfg *config.Blocking) (result map[string]bool) {
|
||||||
result = make(map[string]bool, len(cfg.WhiteLists))
|
result = make(map[string]bool, len(cfg.Allowlists))
|
||||||
|
|
||||||
for g, links := range cfg.WhiteLists {
|
for g, links := range cfg.Allowlists {
|
||||||
if len(links) > 0 {
|
if len(links) > 0 {
|
||||||
if _, found := cfg.BlackLists[g]; !found {
|
if _, found := cfg.Denylists[g]; !found {
|
||||||
result[g] = true
|
result[g] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,16 +343,16 @@ func (r *BlockingResolver) handleBlocked(logger *logrus.Entry,
|
||||||
func (r *BlockingResolver) LogConfig(logger *logrus.Entry) {
|
func (r *BlockingResolver) LogConfig(logger *logrus.Entry) {
|
||||||
r.cfg.LogConfig(logger)
|
r.cfg.LogConfig(logger)
|
||||||
|
|
||||||
logger.Info("blacklist cache entries:")
|
logger.Info("denylist cache entries:")
|
||||||
log.WithIndent(logger, " ", r.blacklistMatcher.LogConfig)
|
log.WithIndent(logger, " ", r.denylistMatcher.LogConfig)
|
||||||
|
|
||||||
logger.Info("whitelist cache entries:")
|
logger.Info("allowlist cache entries:")
|
||||||
log.WithIndent(logger, " ", r.whitelistMatcher.LogConfig)
|
log.WithIndent(logger, " ", r.allowlistMatcher.LogConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *BlockingResolver) hasWhiteListOnlyAllowed(groupsToCheck []string) bool {
|
func (r *BlockingResolver) hasAllowlistOnlyAllowed(groupsToCheck []string) bool {
|
||||||
for _, group := range groupsToCheck {
|
for _, group := range groupsToCheck {
|
||||||
if _, found := r.whitelistOnlyGroups[group]; found {
|
if _, found := r.allowlistOnlyGroups[group]; found {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,31 +360,31 @@ func (r *BlockingResolver) hasWhiteListOnlyAllowed(groupsToCheck []string) bool
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *BlockingResolver) handleBlacklist(ctx context.Context, groupsToCheck []string,
|
func (r *BlockingResolver) handleDenylist(ctx context.Context, groupsToCheck []string,
|
||||||
request *model.Request, logger *logrus.Entry,
|
request *model.Request, logger *logrus.Entry,
|
||||||
) (bool, *model.Response, error) {
|
) (bool, *model.Response, error) {
|
||||||
logger.WithField("groupsToCheck", strings.Join(groupsToCheck, "; ")).Debug("checking groups for request")
|
logger.WithField("groupsToCheck", strings.Join(groupsToCheck, "; ")).Debug("checking groups for request")
|
||||||
whitelistOnlyAllowed := r.hasWhiteListOnlyAllowed(groupsToCheck)
|
allowlistOnlyAllowed := r.hasAllowlistOnlyAllowed(groupsToCheck)
|
||||||
|
|
||||||
for _, question := range request.Req.Question {
|
for _, question := range request.Req.Question {
|
||||||
domain := util.ExtractDomain(question)
|
domain := util.ExtractDomain(question)
|
||||||
logger := logger.WithField("domain", domain)
|
logger := logger.WithField("domain", domain)
|
||||||
|
|
||||||
if groups := r.matches(groupsToCheck, r.whitelistMatcher, domain); len(groups) > 0 {
|
if groups := r.matches(groupsToCheck, r.allowlistMatcher, domain); len(groups) > 0 {
|
||||||
logger.WithField("groups", groups).Debugf("domain is whitelisted")
|
logger.WithField("groups", groups).Debugf("domain is allowlisted")
|
||||||
|
|
||||||
resp, err := r.next.Resolve(ctx, request)
|
resp, err := r.next.Resolve(ctx, request)
|
||||||
|
|
||||||
return true, resp, err
|
return true, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if whitelistOnlyAllowed {
|
if allowlistOnlyAllowed {
|
||||||
resp, err := r.handleBlocked(logger, request, question, "BLOCKED (WHITELIST ONLY)")
|
resp, err := r.handleBlocked(logger, request, question, "BLOCKED (ALLOWLIST ONLY)")
|
||||||
|
|
||||||
return true, resp, err
|
return true, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if groups := r.matches(groupsToCheck, r.blacklistMatcher, domain); len(groups) > 0 {
|
if groups := r.matches(groupsToCheck, r.denylistMatcher, domain); len(groups) > 0 {
|
||||||
resp, err := r.handleBlocked(logger, request, question, fmt.Sprintf("BLOCKED (%s)", strings.Join(groups, ",")))
|
resp, err := r.handleBlocked(logger, request, question, fmt.Sprintf("BLOCKED (%s)", strings.Join(groups, ",")))
|
||||||
|
|
||||||
return true, resp, err
|
return true, resp, err
|
||||||
|
@ -394,13 +394,13 @@ func (r *BlockingResolver) handleBlacklist(ctx context.Context, groupsToCheck []
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve checks the query against the blacklist and delegates to next resolver if domain is not blocked
|
// Resolve checks the query against the denylist and delegates to next resolver if domain is not blocked
|
||||||
func (r *BlockingResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error) {
|
func (r *BlockingResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error) {
|
||||||
ctx, logger := r.log(ctx)
|
ctx, logger := r.log(ctx)
|
||||||
groupsToCheck := r.groupsToCheckForClient(request)
|
groupsToCheck := r.groupsToCheckForClient(request)
|
||||||
|
|
||||||
if len(groupsToCheck) > 0 {
|
if len(groupsToCheck) > 0 {
|
||||||
handled, resp, err := r.handleBlacklist(ctx, groupsToCheck, request, logger)
|
handled, resp, err := r.handleDenylist(ctx, groupsToCheck, request, logger)
|
||||||
if handled {
|
if handled {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
@ -414,9 +414,9 @@ func (r *BlockingResolver) Resolve(ctx context.Context, request *model.Request)
|
||||||
if len(entryToCheck) > 0 {
|
if len(entryToCheck) > 0 {
|
||||||
logger := logger.WithField("response_entry", entryToCheck)
|
logger := logger.WithField("response_entry", entryToCheck)
|
||||||
|
|
||||||
if groups := r.matches(groupsToCheck, r.whitelistMatcher, entryToCheck); len(groups) > 0 {
|
if groups := r.matches(groupsToCheck, r.allowlistMatcher, entryToCheck); len(groups) > 0 {
|
||||||
logger.WithField("groups", groups).Debugf("%s is whitelisted", tName)
|
logger.WithField("groups", groups).Debugf("%s is allowlisted", tName)
|
||||||
} else if groups := r.matches(groupsToCheck, r.blacklistMatcher, entryToCheck); len(groups) > 0 {
|
} else if groups := r.matches(groupsToCheck, r.denylistMatcher, entryToCheck); len(groups) > 0 {
|
||||||
return r.handleBlocked(logger, request, request.Req.Question[0], fmt.Sprintf("BLOCKED %s (%s)", tName,
|
return r.handleBlocked(logger, request, request.Req.Question[0], fmt.Sprintf("BLOCKED %s (%s)", tName,
|
||||||
strings.Join(groups, ",")))
|
strings.Join(groups, ",")))
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockType: "ZEROIP",
|
BlockType: "ZEROIP",
|
||||||
BlockTTL: config.Duration(time.Minute),
|
BlockTTL: config.Duration(time.Minute),
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"gr1": config.NewBytesSources(group1File.Path),
|
"gr1": config.NewBytesSources(group1File.Path),
|
||||||
"gr2": config.NewBytesSources(group2File.Path),
|
"gr2": config.NewBytesSources(group2File.Path),
|
||||||
},
|
},
|
||||||
|
@ -125,7 +125,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockType: "ZEROIP",
|
BlockType: "ZEROIP",
|
||||||
BlockTTL: config.Duration(time.Minute),
|
BlockTTL: config.Duration(time.Minute),
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"gr1": config.NewBytesSources(group1File.Path),
|
"gr1": config.NewBytesSources(group1File.Path),
|
||||||
"gr2": config.NewBytesSources(group2File.Path),
|
"gr2": config.NewBytesSources(group2File.Path),
|
||||||
},
|
},
|
||||||
|
@ -164,7 +164,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockType: "ZEROIP",
|
BlockType: "ZEROIP",
|
||||||
BlockTTL: config.Duration(time.Minute),
|
BlockTTL: config.Duration(time.Minute),
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"gr1": {config.TextBytesSource("/regex/")},
|
"gr1": {config.TextBytesSource("/regex/")},
|
||||||
},
|
},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
|
@ -176,7 +176,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
When("Domain is on the black list", func() {
|
When("Domain is on the denylist", func() {
|
||||||
It("should block request", func() {
|
It("should block request", func() {
|
||||||
Eventually(sut.Resolve).
|
Eventually(sut.Resolve).
|
||||||
WithContext(ctx).
|
WithContext(ctx).
|
||||||
|
@ -196,7 +196,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockTTL: config.Duration(6 * time.Hour),
|
BlockTTL: config.Duration(6 * time.Hour),
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"gr1": config.NewBytesSources(group1File.Path),
|
"gr1": config.NewBytesSources(group1File.Path),
|
||||||
"gr2": config.NewBytesSources(group2File.Path),
|
"gr2": config.NewBytesSources(group2File.Path),
|
||||||
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
||||||
|
@ -216,7 +216,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
When("client name is defined in client groups block", func() {
|
When("client name is defined in client groups block", func() {
|
||||||
It("should block the A query if domain is on the black list (single)", func() {
|
It("should block the A query if domain is on the denylist (single)", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "client1"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "client1"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -227,7 +227,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
HaveReturnCode(dns.RcodeSuccess),
|
HaveReturnCode(dns.RcodeSuccess),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
It("should block the A query if domain is on the black list (multipart 1)", func() {
|
It("should block the A query if domain is on the denylist (multipart 1)", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "client2"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "client2"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -238,7 +238,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
HaveReturnCode(dns.RcodeSuccess),
|
HaveReturnCode(dns.RcodeSuccess),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
It("should block the A query if domain is on the black list (multipart 2)", func() {
|
It("should block the A query if domain is on the denylist (multipart 2)", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "client3"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "client3"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -249,7 +249,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
HaveReturnCode(dns.RcodeSuccess),
|
HaveReturnCode(dns.RcodeSuccess),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
It("should block the A query if domain is on the black list (merged)", func() {
|
It("should block the A query if domain is on the denylist (merged)", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("blocked2.com.", A, "1.2.1.2", "client3"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("blocked2.com.", A, "1.2.1.2", "client3"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -260,7 +260,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
HaveReturnCode(dns.RcodeSuccess),
|
HaveReturnCode(dns.RcodeSuccess),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
It("should block the AAAA query if domain is on the black list", func() {
|
It("should block the AAAA query if domain is on the denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", AAAA, "1.2.1.2", "client1"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", AAAA, "1.2.1.2", "client1"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -271,18 +271,18 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
HaveReturnCode(dns.RcodeSuccess),
|
HaveReturnCode(dns.RcodeSuccess),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
It("should block the HTTPS query if domain is on the black list", func() {
|
It("should block the HTTPS query if domain is on the denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", HTTPS, "1.2.1.2", "client1"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", HTTPS, "1.2.1.2", "client1"))).
|
||||||
Should(HaveReturnCode(dns.RcodeNameError))
|
Should(HaveReturnCode(dns.RcodeNameError))
|
||||||
})
|
})
|
||||||
It("should block the MX query if domain is on the black list", func() {
|
It("should block the MX query if domain is on the denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", MX, "1.2.1.2", "client1"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", MX, "1.2.1.2", "client1"))).
|
||||||
Should(HaveReturnCode(dns.RcodeNameError))
|
Should(HaveReturnCode(dns.RcodeNameError))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
When("Client ip is defined in client groups block", func() {
|
When("Client ip is defined in client groups block", func() {
|
||||||
It("should block the query if domain is on the black list", func() {
|
It("should block the query if domain is on the denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "192.168.178.55", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "192.168.178.55", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -295,7 +295,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
When("Client CIDR (10.43.8.64 - 10.43.8.79) is defined in client groups block", func() {
|
When("Client CIDR (10.43.8.64 - 10.43.8.79) is defined in client groups block", func() {
|
||||||
It("should not block the query for 10.43.8.63 if domain is on the black list", func() {
|
It("should not block the query for 10.43.8.63 if domain is on the denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "10.43.8.63", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "10.43.8.63", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -307,7 +307,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
// was delegated to next resolver
|
// was delegated to next resolver
|
||||||
m.AssertExpectations(GinkgoT())
|
m.AssertExpectations(GinkgoT())
|
||||||
})
|
})
|
||||||
It("should not block the query for 10.43.8.80 if domain is on the black list", func() {
|
It("should not block the query for 10.43.8.80 if domain is on the denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "10.43.8.80", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "10.43.8.80", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -322,7 +322,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
When("Client CIDR (10.43.8.64 - 10.43.8.79) is defined in client groups block", func() {
|
When("Client CIDR (10.43.8.64 - 10.43.8.79) is defined in client groups block", func() {
|
||||||
It("should block the query for 10.43.8.64 if domain is on the black list", func() {
|
It("should block the query for 10.43.8.64 if domain is on the denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "10.43.8.64", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "10.43.8.64", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -333,7 +333,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
HaveReturnCode(dns.RcodeSuccess),
|
HaveReturnCode(dns.RcodeSuccess),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
It("should block the query for 10.43.8.79 if domain is on the black list", func() {
|
It("should block the query for 10.43.8.79 if domain is on the denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "10.43.8.79", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "10.43.8.79", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -402,7 +402,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockTTL: config.Duration(time.Minute),
|
BlockTTL: config.Duration(time.Minute),
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
||||||
},
|
},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
|
@ -428,7 +428,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockType: "ZEROIP",
|
BlockType: "ZEROIP",
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
||||||
},
|
},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
|
@ -473,7 +473,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockTTL: config.Duration(6 * time.Hour),
|
BlockTTL: config.Duration(6 * time.Hour),
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
||||||
},
|
},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
|
@ -511,7 +511,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
When("BlockType is custom IP only for ipv4", func() {
|
When("BlockType is custom IP only for ipv4", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
||||||
},
|
},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
|
@ -535,13 +535,13 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
When("Blacklist contains IP", func() {
|
When("Denylist contains IP", func() {
|
||||||
When("IP4", func() {
|
When("IP4", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
// return defined IP as response
|
// return defined IP as response
|
||||||
mockAnswer, _ = util.NewMsgWithAnswer("example.com.", 300, A, "123.145.123.145")
|
mockAnswer, _ = util.NewMsgWithAnswer("example.com.", 300, A, "123.145.123.145")
|
||||||
})
|
})
|
||||||
It("should block query, if lookup result contains blacklisted IP", func() {
|
It("should block query, if lookup result contains denylisted IP", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -561,7 +561,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
AAAA, "2001:0db8:85a3:08d3::0370:7344",
|
AAAA, "2001:0db8:85a3:08d3::0370:7344",
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
It("should block query, if lookup result contains blacklisted IP", func() {
|
It("should block query, if lookup result contains denylisted IP", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", AAAA, "1.2.1.2", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", AAAA, "1.2.1.2", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -575,7 +575,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
When("blacklist contains domain which is CNAME in response", func() {
|
When("denylist contains domain which is CNAME in response", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
// reconfigure mock, to return CNAMEs
|
// reconfigure mock, to return CNAMEs
|
||||||
rr1, _ := dns.NewRR("example.com 300 IN CNAME domain.com")
|
rr1, _ := dns.NewRR("example.com 300 IN CNAME domain.com")
|
||||||
|
@ -584,7 +584,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
mockAnswer = new(dns.Msg)
|
mockAnswer = new(dns.Msg)
|
||||||
mockAnswer.Answer = []dns.RR{rr1, rr2, rr3}
|
mockAnswer.Answer = []dns.RR{rr1, rr2, rr3}
|
||||||
})
|
})
|
||||||
It("should block the query, if response contains a CNAME with domain on a blacklist", func() {
|
It("should block the query, if response contains a CNAME with domain on a denylist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -598,14 +598,14 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("Whitelisting", func() {
|
Describe("Allowlisting", func() {
|
||||||
When("Requested domain is on black and white list", func() {
|
When("Requested domain is on black and allowlist", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockType: "ZEROIP",
|
BlockType: "ZEROIP",
|
||||||
BlockTTL: config.Duration(time.Minute),
|
BlockTTL: config.Duration(time.Minute),
|
||||||
BlackLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
|
Denylists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
|
||||||
WhiteLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
|
Allowlists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
"default": {"gr1"},
|
"default": {"gr1"},
|
||||||
},
|
},
|
||||||
|
@ -625,12 +625,12 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
When("Only whitelist is defined", func() {
|
When("Only allowlist is defined", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockType: "zeroIP",
|
BlockType: "zeroIP",
|
||||||
BlockTTL: config.Duration(60 * time.Second),
|
BlockTTL: config.Duration(60 * time.Second),
|
||||||
WhiteLists: map[string][]config.BytesSource{
|
Allowlists: map[string][]config.BytesSource{
|
||||||
"gr1": config.NewBytesSources(group1File.Path),
|
"gr1": config.NewBytesSources(group1File.Path),
|
||||||
"gr2": config.NewBytesSources(group2File.Path),
|
"gr2": config.NewBytesSources(group2File.Path),
|
||||||
},
|
},
|
||||||
|
@ -642,8 +642,8 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
It("should block everything else except domains on the white list with default group", func() {
|
It("should block everything else except domains on the allowlist with default group", func() {
|
||||||
By("querying domain on the whitelist", func() {
|
By("querying domain on the allowlist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -656,7 +656,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
m.AssertExpectations(GinkgoT())
|
m.AssertExpectations(GinkgoT())
|
||||||
})
|
})
|
||||||
|
|
||||||
By("querying another domain, which is not on the whitelist", func() {
|
By("querying another domain, which is not on the allowlist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("google.com.", A, "1.2.1.2", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("google.com.", A, "1.2.1.2", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -664,15 +664,15 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
HaveTTL(BeNumerically("==", 60)),
|
HaveTTL(BeNumerically("==", 60)),
|
||||||
HaveResponseType(ResponseTypeBLOCKED),
|
HaveResponseType(ResponseTypeBLOCKED),
|
||||||
HaveReturnCode(dns.RcodeSuccess),
|
HaveReturnCode(dns.RcodeSuccess),
|
||||||
HaveReason("BLOCKED (WHITELIST ONLY)"),
|
HaveReason("BLOCKED (ALLOWLIST ONLY)"),
|
||||||
))
|
))
|
||||||
|
|
||||||
Expect(m.Calls).Should(HaveLen(1))
|
Expect(m.Calls).Should(HaveLen(1))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
It("should block everything else except domains on the white list "+
|
It("should block everything else except domains on the allowlist "+
|
||||||
"if multiple white list only groups are defined", func() {
|
"if multiple allowlist only groups are defined", func() {
|
||||||
By("querying domain on the whitelist", func() {
|
By("querying domain on the allowlist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "one-client"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "one-client"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -685,7 +685,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
m.AssertExpectations(GinkgoT())
|
m.AssertExpectations(GinkgoT())
|
||||||
})
|
})
|
||||||
|
|
||||||
By("querying another domain, which is not on the whitelist", func() {
|
By("querying another domain, which is not on the allowlist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("blocked2.com.", A, "1.2.1.2", "one-client"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("blocked2.com.", A, "1.2.1.2", "one-client"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -693,14 +693,14 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
HaveTTL(BeNumerically("==", 60)),
|
HaveTTL(BeNumerically("==", 60)),
|
||||||
HaveResponseType(ResponseTypeBLOCKED),
|
HaveResponseType(ResponseTypeBLOCKED),
|
||||||
HaveReturnCode(dns.RcodeSuccess),
|
HaveReturnCode(dns.RcodeSuccess),
|
||||||
HaveReason("BLOCKED (WHITELIST ONLY)"),
|
HaveReason("BLOCKED (ALLOWLIST ONLY)"),
|
||||||
))
|
))
|
||||||
Expect(m.Calls).Should(HaveLen(1))
|
Expect(m.Calls).Should(HaveLen(1))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
It("should block everything else except domains on the white list "+
|
It("should block everything else except domains on the allowlist "+
|
||||||
"if multiple white list only groups are defined", func() {
|
"if multiple allowlist only groups are defined", func() {
|
||||||
By("querying domain on the whitelist group 1", func() {
|
By("querying domain on the allowlist group 1", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "all-client"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "all-client"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -713,7 +713,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
m.AssertExpectations(GinkgoT())
|
m.AssertExpectations(GinkgoT())
|
||||||
})
|
})
|
||||||
|
|
||||||
By("querying another domain, which is in the whitelist group 1", func() {
|
By("querying another domain, which is in the allowlist group 1", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("blocked2.com.", A, "1.2.1.2", "all-client"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("blocked2.com.", A, "1.2.1.2", "all-client"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -726,20 +726,20 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
When("IP address is on black and white list", func() {
|
When("IP address is on black and allowlist", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockType: "ZEROIP",
|
BlockType: "ZEROIP",
|
||||||
BlockTTL: config.Duration(time.Minute),
|
BlockTTL: config.Duration(time.Minute),
|
||||||
BlackLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
|
Denylists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
|
||||||
WhiteLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(defaultGroupFile.Path)},
|
Allowlists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(defaultGroupFile.Path)},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
"default": {"gr1"},
|
"default": {"gr1"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
mockAnswer, _ = util.NewMsgWithAnswer("example.com.", 300, A, "123.145.123.145")
|
mockAnswer, _ = util.NewMsgWithAnswer("example.com.", 300, A, "123.145.123.145")
|
||||||
})
|
})
|
||||||
It("should not block if DNS answer contains IP from the white list", func() {
|
It("should not block if DNS answer contains IP from the allowlist", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -756,9 +756,9 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
Describe("Delegate request to next resolver", func() {
|
Describe("Delegate request to next resolver", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlockType: "ZEROIP",
|
BlockType: "ZEROIP",
|
||||||
BlockTTL: config.Duration(time.Minute),
|
BlockTTL: config.Duration(time.Minute),
|
||||||
BlackLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
|
Denylists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
"default": {"gr1"},
|
"default": {"gr1"},
|
||||||
},
|
},
|
||||||
|
@ -768,7 +768,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
// was delegated to next resolver
|
// was delegated to next resolver
|
||||||
m.AssertExpectations(GinkgoT())
|
m.AssertExpectations(GinkgoT())
|
||||||
})
|
})
|
||||||
When("domain is not on the black list", func() {
|
When("domain is not on the denylist", func() {
|
||||||
It("should delegate to next resolver", func() {
|
It("should delegate to next resolver", func() {
|
||||||
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
|
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
|
||||||
Should(
|
Should(
|
||||||
|
@ -801,7 +801,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
Describe("Control status via API", func() {
|
Describe("Control status via API", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sutConfig = config.Blocking{
|
sutConfig = config.Blocking{
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
|
||||||
"group1": config.NewBytesSources(group1File.Path),
|
"group1": config.NewBytesSources(group1File.Path),
|
||||||
},
|
},
|
||||||
|
@ -1124,8 +1124,8 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
|
||||||
When("strategy is failOnError", func() {
|
When("strategy is failOnError", func() {
|
||||||
It("should fail if lists can't be downloaded", func() {
|
It("should fail if lists can't be downloaded", func() {
|
||||||
_, err := NewBlockingResolver(ctx, config.Blocking{
|
_, err := NewBlockingResolver(ctx, config.Blocking{
|
||||||
BlackLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources("wrongPath")},
|
Denylists: map[string][]config.BytesSource{"gr1": config.NewBytesSources("wrongPath")},
|
||||||
WhiteLists: map[string][]config.BytesSource{"whitelist": config.NewBytesSources("wrongPath")},
|
Allowlists: map[string][]config.BytesSource{"allowlist": config.NewBytesSources("wrongPath")},
|
||||||
Loading: config.SourceLoading{
|
Loading: config.SourceLoading{
|
||||||
Init: config.Init{Strategy: config.InitStrategyFailOnError},
|
Init: config.Init{Strategy: config.InitStrategyFailOnError},
|
||||||
},
|
},
|
||||||
|
|
|
@ -117,7 +117,7 @@ var _ = BeforeSuite(func() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Blocking: config.Blocking{
|
Blocking: config.Blocking{
|
||||||
BlackLists: map[string][]config.BytesSource{
|
Denylists: map[string][]config.BytesSource{
|
||||||
"ads": config.NewBytesSources(
|
"ads": config.NewBytesSources(
|
||||||
doubleclickFile.Path,
|
doubleclickFile.Path,
|
||||||
bildFile.Path,
|
bildFile.Path,
|
||||||
|
@ -125,13 +125,13 @@ var _ = BeforeSuite(func() {
|
||||||
),
|
),
|
||||||
"youtube": config.NewBytesSources(youtubeFile.Path),
|
"youtube": config.NewBytesSources(youtubeFile.Path),
|
||||||
},
|
},
|
||||||
WhiteLists: map[string][]config.BytesSource{
|
Allowlists: map[string][]config.BytesSource{
|
||||||
"ads": config.NewBytesSources(heiseFile.Path),
|
"ads": config.NewBytesSources(heiseFile.Path),
|
||||||
"whitelist": config.NewBytesSources(heiseFile.Path),
|
"allowlist": config.NewBytesSources(heiseFile.Path),
|
||||||
},
|
},
|
||||||
ClientGroupsBlock: map[string][]string{
|
ClientGroupsBlock: map[string][]string{
|
||||||
"default": {"ads"},
|
"default": {"ads"},
|
||||||
"clWhitelistOnly": {"whitelist"},
|
"clAllowlistOnly": {"allowlist"},
|
||||||
"clAdsAndYoutube": {"ads", "youtube"},
|
"clAdsAndYoutube": {"ads", "youtube"},
|
||||||
"clYoutubeOnly": {"youtube"},
|
"clYoutubeOnly": {"youtube"},
|
||||||
},
|
},
|
||||||
|
@ -263,7 +263,7 @@ var _ = Describe("Running DNS server", func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("no blocking default group with sub domain", func() {
|
Context("no blocking default group with sub domain", func() {
|
||||||
It("Query with should not be blocked, sub domain is not in blacklist", func() {
|
It("Query with should not be blocked, sub domain is not in denylist", func() {
|
||||||
Expect(requestServer(util.NewMsgWithQuestion("bild.de.", A))).
|
Expect(requestServer(util.NewMsgWithQuestion("bild.de.", A))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -272,8 +272,8 @@ var _ = Describe("Running DNS server", func() {
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("domain is on white and blacklist default group", func() {
|
Context("domain is on allow/denylist default group", func() {
|
||||||
It("Query with should not be blocked, domain is on white and blacklist", func() {
|
It("Query with should not be blocked, domain is on allow/denylist", func() {
|
||||||
Expect(requestServer(util.NewMsgWithQuestion("heise.de.", A))).
|
Expect(requestServer(util.NewMsgWithQuestion("heise.de.", A))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -282,9 +282,9 @@ var _ = Describe("Running DNS server", func() {
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("domain is on client specific white list", func() {
|
Context("domain is on client specific allowlist", func() {
|
||||||
It("Query with should not be blocked, domain is on client's white list", func() {
|
It("Query with should not be blocked, domain is on client's allowlist", func() {
|
||||||
mockClientName.Store("clWhitelistOnly")
|
mockClientName.Store("clAllowlistOnly")
|
||||||
Expect(requestServer(util.NewMsgWithQuestion("heise.de.", A))).
|
Expect(requestServer(util.NewMsgWithQuestion("heise.de.", A))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
@ -293,9 +293,9 @@ var _ = Describe("Running DNS server", func() {
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("block client whitelist only", func() {
|
Context("block client allowlist only", func() {
|
||||||
It("Query with should be blocked, client has only whitelist, domain is not on client's white list", func() {
|
It("Query with should be blocked, client has only allowlist, domain is not on client's allowlist", func() {
|
||||||
mockClientName.Store("clWhitelistOnly")
|
mockClientName.Store("clAllowlistOnly")
|
||||||
Expect(requestServer(util.NewMsgWithQuestion("google.de.", A))).
|
Expect(requestServer(util.NewMsgWithQuestion("google.de.", A))).
|
||||||
Should(
|
Should(
|
||||||
SatisfyAll(
|
SatisfyAll(
|
||||||
|
|
Loading…
Reference in New Issue