feat: update list config and code to use "allow/deny" language

This commit is contained in:
ThinkChaos 2024-04-08 13:09:51 -04:00
parent 3515483795
commit bcd1381e18
26 changed files with 262 additions and 232 deletions

View File

@ -20,10 +20,10 @@ Blocky is a DNS proxy and ad-blocker for the local network written in Go with fo
## 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.)
- Periodical reload of external black and white lists
- Definition of allow/denylists per client group (Kids, Smart home devices, etc.)
- Periodical reload of external allow/denylists
- Regex support
- Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)

View File

@ -39,7 +39,7 @@ var _ = Describe("root command", func() {
" default:",
" - 1.1.1.1",
"blocking:",
" blackLists:",
" denylists:",
" ads:",
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
" clientGroupsBlock:",

View File

@ -8,8 +8,8 @@ import (
// Blocking configuration for query blocking
type Blocking struct {
BlackLists map[string][]BytesSource `yaml:"blackLists"`
WhiteLists map[string][]BytesSource `yaml:"whiteLists"`
Denylists map[string][]BytesSource `yaml:"denylists"`
Allowlists map[string][]BytesSource `yaml:"allowlists"`
ClientGroupsBlock map[string][]string `yaml:"clientGroupsBlock"`
BlockType string `yaml:"blockType" default:"ZEROIP"`
BlockTTL Duration `yaml:"blockTTL" default:"6h"`
@ -17,19 +17,23 @@ type Blocking struct {
// Deprecated options
Deprecated struct {
DownloadTimeout *Duration `yaml:"downloadTimeout"`
DownloadAttempts *uint `yaml:"downloadAttempts"`
DownloadCooldown *Duration `yaml:"downloadCooldown"`
RefreshPeriod *Duration `yaml:"refreshPeriod"`
FailStartOnListError *bool `yaml:"failStartOnListError"`
ProcessingConcurrency *uint `yaml:"processingConcurrency"`
StartStrategy *InitStrategy `yaml:"startStrategy"`
MaxErrorsPerFile *int `yaml:"maxErrorsPerFile"`
BlackLists *map[string][]BytesSource `yaml:"blackLists"`
WhiteLists *map[string][]BytesSource `yaml:"whiteLists"`
DownloadTimeout *Duration `yaml:"downloadTimeout"`
DownloadAttempts *uint `yaml:"downloadAttempts"`
DownloadCooldown *Duration `yaml:"downloadCooldown"`
RefreshPeriod *Duration `yaml:"refreshPeriod"`
FailStartOnListError *bool `yaml:"failStartOnListError"`
ProcessingConcurrency *uint `yaml:"processingConcurrency"`
StartStrategy *InitStrategy `yaml:"startStrategy"`
MaxErrorsPerFile *int `yaml:"maxErrorsPerFile"`
} `yaml:",inline"`
}
func (c *Blocking) migrate(logger *logrus.Entry) bool {
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)),
"downloadAttempts": Move(To("loading.downloads.attempts", &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:")
log.WithIndent(logger, " ", c.Loading.LogConfig)
logger.Info("blacklist:")
logger.Info("denylists:")
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) {
c.logListGroups(logger, c.WhiteLists)
c.logListGroups(logger, c.Allowlists)
})
}

View File

@ -17,7 +17,7 @@ var _ = Describe("BlockingConfig", func() {
cfg = Blocking{
BlockType: "ZEROIP",
BlockTTL: Duration(time.Minute),
BlackLists: map[string][]BytesSource{
Denylists: map[string][]BytesSource{
"gr1": NewBytesSources("/a/file/path"),
},
ClientGroupsBlock: map[string][]string{
@ -60,4 +60,30 @@ var _ = Describe("BlockingConfig", func() {
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))
})
})
})

View File

@ -988,8 +988,8 @@ func defaultTestFileConfig(config *Config) {
Expect(config.Conditional.Mapping.Upstreams["multiple.resolvers"]).Should(HaveLen(2))
Expect(config.ClientLookup.Upstream.Host).Should(Equal("192.168.178.1"))
Expect(config.ClientLookup.SingleNameOrder).Should(Equal([]uint{2, 1}))
Expect(config.Blocking.BlackLists).Should(HaveLen(2))
Expect(config.Blocking.WhiteLists).Should(HaveLen(1))
Expect(config.Blocking.Denylists).Should(HaveLen(2))
Expect(config.Blocking.Allowlists).Should(HaveLen(1))
Expect(config.Blocking.ClientGroupsBlock).Should(HaveLen(2))
Expect(config.Blocking.BlockTTL).Should(Equal(Duration(time.Minute)))
Expect(config.Blocking.Loading.RefreshPeriod).Should(Equal(Duration(2 * time.Hour)))
@ -1029,7 +1029,7 @@ func writeConfigYml(tmpDir *helpertest.TmpFolder) *helpertest.TmpFile {
"fqdnOnly:",
" enable: true",
"blocking:",
" blackLists:",
" denylists:",
" ads:",
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
" - 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",
" special:",
" - https://hosts-file.net/ad_servers.txt",
" whiteLists:",
" allowlists:",
" ads:",
" - whitelist.txt",
" - allowlist.txt",
" clientGroupsBlock:",
" default:",
" - ads",
@ -1119,7 +1119,7 @@ func writeConfigDir(tmpDir *helpertest.TmpFolder) {
tmpDir.CreateStringFile("config2.yaml",
"blocking:",
" blackLists:",
" denylists:",
" ads:",
" - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
" - 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",
" special:",
" - https://hosts-file.net/ad_servers.txt",
" whiteLists:",
" allowlists:",
" ads:",
" - whitelist.txt",
" - allowlist.txt",
" clientGroupsBlock:",
" default:",
" - ads",

View File

@ -33,7 +33,6 @@ To print runtime configuration / statistics, you can send `SIGUSR1` signal to ru
INFO server: MEM NumGC = 1533
INFO server: RUN NumCPU = 4
INFO server: RUN NumGoroutine = 18
```
!!! hint
@ -49,7 +48,7 @@ automatically.
Some links/ideas for lists:
### Blacklists
### Denylists
* [https://github.com/StevenBlack/hosts](https://github.com/StevenBlack/hosts)
* [https://github.com/nickspaargaren/no-google](https://github.com/nickspaargaren/no-google)
@ -60,11 +59,11 @@ Some links/ideas for lists:
!!! 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
@ -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
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.

View File

@ -8,10 +8,10 @@ info:
## 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.)
- Periodical reload of external black and white lists
- Definition of allow/denylists per client group (Kids, Smart home devices, etc.)
- Periodical reload of external allow/denylists
- Regex support
- Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)

View File

@ -429,7 +429,7 @@
"datasource": {
"uid": "${DS_PROMETHEUS}"
},
"description": "Number of blacklist entries",
"description": "Number of denylist entries",
"fieldConfig": {
"defaults": {
"mappings": [
@ -487,7 +487,7 @@
"uid": "${DS_PROMETHEUS}"
},
"exemplar": true,
"expr": "sum(blocky_blacklist_cache) / sum(up{job=~\"$job\"})",
"expr": "sum(blocky_denylist_cache) / sum(up{job=~\"$job\"})",
"format": "table",
"instant": false,
"interval": "",
@ -495,7 +495,7 @@
"refId": "A"
}
],
"title": "Blacklist entries total",
"title": "Denylist entries total",
"transparent": true,
"type": "stat"
},
@ -1683,7 +1683,7 @@
"uid": "${DS_PROMETHEUS}"
},
"exemplar": false,
"expr": "topk(1, blocky_blacklist_cache) by (group)",
"expr": "topk(1, blocky_denylist_cache) by (group)",
"format": "time_series",
"instant": true,
"interval": "",
@ -1691,7 +1691,7 @@
"refId": "A"
}
],
"title": "Blacklist by group",
"title": "Denylist by group",
"transparent": true,
"type": "piechart"
},
@ -1978,4 +1978,4 @@
"uid": "JvOqE4gRk",
"version": 1,
"weekStart": ""
}
}

View File

@ -243,7 +243,7 @@
]
}
],
"title": "Blocked by Blacklist",
"title": "Blocked by Denylist",
"type": "piechart"
},
{

View File

@ -243,7 +243,7 @@
]
}
],
"title": "Blocked by Blacklist",
"title": "Blocked by Denylist",
"type": "piechart"
},
{

View File

@ -62,10 +62,10 @@ conditional:
fritz.box: 192.168.178.1
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:
# definition of blacklist groups. Can be external link (http/https) or local file
blackLists:
# definition of denylist groups. Can be external link (http/https) or local file
denylists:
ads:
- https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
@ -77,14 +77,16 @@ blocking:
*.example.com
special:
- 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
whiteLists:
# definition of allowlist groups.
# 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:
- whitelist.txt
- allowlist.txt
- |
# inline definition with YAML literal block scalar style
# hosts format
whitelistdomain.com
allowlistdomain.com
# this is a regex
/^banners?[_.-]/
# definition: which groups should be applied for which client
@ -242,7 +244,7 @@ minTlsServeVersion: 1.3
#certFile: server.crt
#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:
- tcp+udp:1.1.1.1
- https://1.1.1.1/dns-query

View File

@ -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.
## Blocking and whitelisting
## Blocking and allowlisting
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.
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.
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.
@ -421,7 +421,7 @@ The supported list formats are:
```yaml
blocking:
blackLists:
denylists:
ads:
- https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
@ -436,25 +436,24 @@ The supported list formats are:
/^banners?[_.-]/
special:
- https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
whiteLists:
allowlists:
ads:
- whitelist.txt
- allowlist.txt
- /path/to/file.txt
- |
# 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.
!!! warning
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.
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.
!!! 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
@ -833,7 +832,7 @@ These settings apply only to the resolver under which they are nested.
```yaml
blocking:
loading:
# only applies to white/blacklists
# only applies to allow/denylists
hostsFile:
loading:

View File

@ -8,10 +8,10 @@ Blocky is a DNS proxy and ad-blocker for the local network written in Go with fo
## 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.)
* Periodical reload of external black and white lists
* Definition of allow/denylists per client group (Kids, Smart home devices, etc.)
* Periodical reload of external allow/denylists
* Regex support
* Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)

View File

@ -20,7 +20,7 @@ upstream:
- tcp-tls:fdns1.dismail.de:853
- https://dns.digitale-gesellschaft.ch/dns-query
blocking:
blackLists:
denylists:
ads:
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
clientGroupsBlock:
@ -95,8 +95,8 @@ docker-compose up -d
### Advanced setup
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
path like '/app/whitelists/whitelist.txt' in the config file.
allowlists directories are mounted as volume. You can create own black or allowlists in these directories and define the
path like '/app/allowlists/allowlist.txt' in the config file.
!!! example
@ -118,9 +118,9 @@ services:
- ./config.yml:/app/config.yml
# write query logs in this volume
- queryLogs:/logs
# put your custom white and blacklists in these directories
- ./blacklists:/app/blacklists/
- ./whitelists:/app/whitelists/
# put your custom allow/denylists in these directories
- ./denylists:/app/denylists/
- ./allowlists:/app/allowlists/
volumes:
queryLogs:

View File

@ -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 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 lists refresh` reloads all white and blacklists
- `./blocky lists refresh` reloads all allow/denylists
!!! tip

View File

@ -10,7 +10,7 @@ Following metrics will be exported:
| 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_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) |

View File

@ -24,7 +24,7 @@ var _ = Describe("External lists and query blocking", func() {
Expect(err).Should(Succeed())
})
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() {
BeforeEach(func(ctx context.Context) {
blocky, err = createBlockyContainer(ctx, e2eNet,
@ -37,7 +37,7 @@ var _ = Describe("External lists and query blocking", func() {
"blocking:",
" loading:",
" strategy: blocking",
" blackLists:",
" denylists:",
" ads:",
" - http://wrong.domain.url/list.txt",
" clientGroupsBlock:",
@ -72,7 +72,7 @@ var _ = Describe("External lists and query blocking", func() {
"blocking:",
" loading:",
" strategy: failOnError",
" blackLists:",
" denylists:",
" ads:",
" - http://wrong.domain.url/list.txt",
" clientGroupsBlock:",
@ -96,8 +96,8 @@ var _ = Describe("External lists and query blocking", func() {
})
})
})
Describe("Query blocking against external blacklists", func() {
When("external blacklists are defined and available", func() {
Describe("Query blocking against external denylists", func() {
When("external denylists are defined and available", func() {
BeforeEach(func(ctx context.Context) {
_, err = createHTTPServerContainer(ctx, "httpserver", e2eNet, "list.txt", "blockeddomain.com")
Expect(err).Should(Succeed())
@ -110,7 +110,7 @@ var _ = Describe("External lists and query blocking", func() {
" default:",
" - moka",
"blocking:",
" blackLists:",
" denylists:",
" ads:",
" - http://httpserver:8080/list.txt",
" clientGroupsBlock:",

View File

@ -49,7 +49,7 @@ var _ = Describe("Metrics functional tests", func() {
" default:",
" - moka1",
"blocking:",
" blackLists:",
" denylists:",
" group1:",
" - http://httpserver1:8080/list1.txt",
" 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) {
Eventually(fetchBlockyMetrics).WithArguments(ctx, metricsURL).
Should(ContainElements(
"blocky_blacklist_cache{group=\"group1\"} 1",
"blocky_blacklist_cache{group=\"group2\"} 3",
"blocky_denylist_cache{group=\"group1\"} 1",
"blocky_denylist_cache{group=\"group2\"} 3",
))
})
})

View File

@ -24,8 +24,8 @@ const (
)
// ListCacheType represents the type of cached list ENUM(
// blacklist // is a list with blocked domains
// whitelist // is a list with whitelisted domains / IPs
// denylist // is a list with blocked domains
// allowlist // is a list with allowlisted domains / IPs
// )
type ListCacheType int

View File

@ -20,7 +20,7 @@ func BenchmarkRefresh(b *testing.B) {
RefreshPeriod: config.Duration(-1),
}
downloader := NewDownloader(config.Downloader{}, nil)
cache, _ := NewListCache(context.Background(), ListCacheTypeBlacklist, cfg, lists, downloader)
cache, _ := NewListCache(context.Background(), ListCacheTypeDenylist, cfg, lists, downloader)
b.ReportAllocs()

View File

@ -12,21 +12,21 @@ import (
)
const (
// ListCacheTypeBlacklist is a ListCacheType of type Blacklist.
// ListCacheTypeDenylist is a ListCacheType of type Denylist.
// is a list with blocked domains
ListCacheTypeBlacklist ListCacheType = iota
// ListCacheTypeWhitelist is a ListCacheType of type Whitelist.
// is a list with whitelisted domains / IPs
ListCacheTypeWhitelist
ListCacheTypeDenylist ListCacheType = iota
// ListCacheTypeAllowlist is a ListCacheType of type Allowlist.
// is a list with allowlisted domains / IPs
ListCacheTypeAllowlist
)
var ErrInvalidListCacheType = fmt.Errorf("not a valid ListCacheType, try [%s]", strings.Join(_ListCacheTypeNames, ", "))
const _ListCacheTypeName = "blacklistwhitelist"
const _ListCacheTypeName = "denylistallowlist"
var _ListCacheTypeNames = []string{
_ListCacheTypeName[0:9],
_ListCacheTypeName[9:18],
_ListCacheTypeName[0:8],
_ListCacheTypeName[8:17],
}
// ListCacheTypeNames returns a list of possible string values of ListCacheType.
@ -37,8 +37,8 @@ func ListCacheTypeNames() []string {
}
var _ListCacheTypeMap = map[ListCacheType]string{
ListCacheTypeBlacklist: _ListCacheTypeName[0:9],
ListCacheTypeWhitelist: _ListCacheTypeName[9:18],
ListCacheTypeDenylist: _ListCacheTypeName[0:8],
ListCacheTypeAllowlist: _ListCacheTypeName[8:17],
}
// String implements the Stringer interface.
@ -57,8 +57,8 @@ func (x ListCacheType) IsValid() bool {
}
var _ListCacheTypeValue = map[string]ListCacheType{
_ListCacheTypeName[0:9]: ListCacheTypeBlacklist,
_ListCacheTypeName[9:18]: ListCacheTypeWhitelist,
_ListCacheTypeName[0:8]: ListCacheTypeDenylist,
_ListCacheTypeName[8:17]: ListCacheTypeAllowlist,
}
// ParseListCacheType attempts to convert a string to a ListCacheType.

View File

@ -46,7 +46,7 @@ var _ = Describe("ListCache", func() {
ctx, cancelFn = context.WithCancel(context.Background())
DeferCleanup(cancelFn)
listCacheType = ListCacheTypeBlacklist
listCacheType = ListCacheTypeDenylist
sutConfig, err = config.WithDefaults[config.SourceLoading]()
Expect(err).Should(Succeed())
@ -306,7 +306,7 @@ var _ = Describe("ListCache", 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(sut.groupedCache.ElementCount("gr1")).Should(Equal(lines1 + lines2 + lines3))
@ -408,7 +408,7 @@ var _ = Describe("ListCache", 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())
sut.LogConfig(logger)
@ -432,7 +432,7 @@ var _ = Describe("ListCache", 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())
})
})

View File

@ -28,14 +28,14 @@ func registerApplicationEventListeners() {
}
func versionNumberGauge() *prometheus.GaugeVec {
blacklistCnt := prometheus.NewGaugeVec(
denylistCnt := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "blocky_build_info",
Help: "Version number and build info",
}, []string{"version", "build_time"},
)
return blacklistCnt
return denylistCnt
}
func registerBlockingEventListeners() {
@ -51,23 +51,23 @@ func registerBlockingEventListeners() {
}
})
blacklistCnt := blacklistGauge()
denylistCnt := denylistGauge()
whitelistCnt := whitelistGauge()
allowlistCnt := allowlistGauge()
lastListGroupRefresh := lastListGroupRefresh()
RegisterMetric(blacklistCnt)
RegisterMetric(whitelistCnt)
RegisterMetric(denylistCnt)
RegisterMetric(allowlistCnt)
RegisterMetric(lastListGroupRefresh)
subscribe(evt.BlockingCacheGroupChanged, func(listType lists.ListCacheType, groupName string, cnt int) {
lastListGroupRefresh.Set(float64(time.Now().Unix()))
switch listType {
case lists.ListCacheTypeBlacklist:
blacklistCnt.WithLabelValues(groupName).Set(float64(cnt))
case lists.ListCacheTypeWhitelist:
whitelistCnt.WithLabelValues(groupName).Set(float64(cnt))
case lists.ListCacheTypeDenylist:
denylistCnt.WithLabelValues(groupName).Set(float64(cnt))
case lists.ListCacheTypeAllowlist:
allowlistCnt.WithLabelValues(groupName).Set(float64(cnt))
}
})
}
@ -82,26 +82,26 @@ func enabledGauge() prometheus.Gauge {
return enabledGauge
}
func blacklistGauge() *prometheus.GaugeVec {
blacklistCnt := prometheus.NewGaugeVec(
func denylistGauge() *prometheus.GaugeVec {
denylistCnt := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "blocky_blacklist_cache",
Help: "Number of entries in the blacklist cache",
Name: "blocky_denylist_cache",
Help: "Number of entries in the denylist cache",
}, []string{"group"},
)
return blacklistCnt
return denylistCnt
}
func whitelistGauge() *prometheus.GaugeVec {
whitelistCnt := prometheus.NewGaugeVec(
func allowlistGauge() *prometheus.GaugeVec {
allowlistCnt := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "blocky_whitelist_cache",
Help: "Number of entries in the whitelist cache",
Name: "blocky_allowlist_cache",
Help: "Number of entries in the allowlist cache",
}, []string{"group"},
)
return whitelistCnt
return allowlistCnt
}
func lastListGroupRefresh() prometheus.Gauge {

View File

@ -79,16 +79,16 @@ type status struct {
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 {
configurable[*config.Blocking]
NextResolver
typed
blacklistMatcher *lists.ListCache
whitelistMatcher *lists.ListCache
denylistMatcher *lists.ListCache
allowlistMatcher *lists.ListCache
blockHandler blockHandler
whitelistOnlyGroups map[string]bool
allowlistOnlyGroups map[string]bool
status *status
clientGroupsBlock map[string][]string
redisClient *redis.Client
@ -125,11 +125,11 @@ func NewBlockingResolver(ctx context.Context,
downloader := lists.NewDownloader(cfg.Loading.Downloads, bootstrap.NewHTTPTransport())
blacklistMatcher, blErr := lists.NewListCache(ctx, lists.ListCacheTypeBlacklist,
cfg.Loading, cfg.BlackLists, downloader)
whitelistMatcher, wlErr := lists.NewListCache(ctx, lists.ListCacheTypeWhitelist,
cfg.Loading, cfg.WhiteLists, downloader)
whitelistOnlyGroups := determineWhitelistOnlyGroups(&cfg)
denylistMatcher, blErr := lists.NewListCache(ctx, lists.ListCacheTypeDenylist,
cfg.Loading, cfg.Denylists, downloader)
allowlistMatcher, wlErr := lists.NewListCache(ctx, lists.ListCacheTypeAllowlist,
cfg.Loading, cfg.Allowlists, downloader)
allowlistOnlyGroups := determineAllowlistOnlyGroups(&cfg)
err = multierror.Append(err, blErr, wlErr).ErrorOrNil()
if err != nil {
@ -141,9 +141,9 @@ func NewBlockingResolver(ctx context.Context,
typed: withType("blocking"),
blockHandler: blockHandler,
blacklistMatcher: blacklistMatcher,
whitelistMatcher: whitelistMatcher,
whitelistOnlyGroups: whitelistOnlyGroups,
denylistMatcher: denylistMatcher,
allowlistMatcher: allowlistMatcher,
allowlistOnlyGroups: allowlistOnlyGroups,
status: &status{
enabled: true,
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 {
var err *multierror.Error
err = multierror.Append(err, r.blacklistMatcher.Refresh())
err = multierror.Append(err, r.whitelistMatcher.Refresh())
err = multierror.Append(err, r.denylistMatcher.Refresh())
err = multierror.Append(err, r.allowlistMatcher.Refresh())
return err.ErrorOrNil()
}
func (r *BlockingResolver) retrieveAllBlockingGroups() []string {
result := maps.Keys(r.cfg.BlackLists)
result := maps.Keys(r.cfg.Denylists)
result = append(result, "default")
slices.Sort(result)
@ -217,7 +217,7 @@ func (r *BlockingResolver) retrieveAllBlockingGroups() []string {
return result
}
// EnableBlocking enables the blocking against the blacklists
// EnableBlocking enables the blocking against the denylists
func (r *BlockingResolver) EnableBlocking(ctx context.Context) {
r.internalEnableBlocking()
@ -310,13 +310,13 @@ func (r *BlockingResolver) BlockingStatus() api.BlockingStatus {
}
}
// returns groups, which have only whitelist entries
func determineWhitelistOnlyGroups(cfg *config.Blocking) (result map[string]bool) {
result = make(map[string]bool, len(cfg.WhiteLists))
// returns groups, which have only allowlist entries
func determineAllowlistOnlyGroups(cfg *config.Blocking) (result map[string]bool) {
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 _, found := cfg.BlackLists[g]; !found {
if _, found := cfg.Denylists[g]; !found {
result[g] = true
}
}
@ -343,16 +343,16 @@ func (r *BlockingResolver) handleBlocked(logger *logrus.Entry,
func (r *BlockingResolver) LogConfig(logger *logrus.Entry) {
r.cfg.LogConfig(logger)
logger.Info("blacklist cache entries:")
log.WithIndent(logger, " ", r.blacklistMatcher.LogConfig)
logger.Info("denylist cache entries:")
log.WithIndent(logger, " ", r.denylistMatcher.LogConfig)
logger.Info("whitelist cache entries:")
log.WithIndent(logger, " ", r.whitelistMatcher.LogConfig)
logger.Info("allowlist cache entries:")
log.WithIndent(logger, " ", r.allowlistMatcher.LogConfig)
}
func (r *BlockingResolver) hasWhiteListOnlyAllowed(groupsToCheck []string) bool {
func (r *BlockingResolver) hasAllowlistOnlyAllowed(groupsToCheck []string) bool {
for _, group := range groupsToCheck {
if _, found := r.whitelistOnlyGroups[group]; found {
if _, found := r.allowlistOnlyGroups[group]; found {
return true
}
}
@ -360,31 +360,31 @@ func (r *BlockingResolver) hasWhiteListOnlyAllowed(groupsToCheck []string) bool
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,
) (bool, *model.Response, error) {
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 {
domain := util.ExtractDomain(question)
logger := logger.WithField("domain", domain)
if groups := r.matches(groupsToCheck, r.whitelistMatcher, domain); len(groups) > 0 {
logger.WithField("groups", groups).Debugf("domain is whitelisted")
if groups := r.matches(groupsToCheck, r.allowlistMatcher, domain); len(groups) > 0 {
logger.WithField("groups", groups).Debugf("domain is allowlisted")
resp, err := r.next.Resolve(ctx, request)
return true, resp, err
}
if whitelistOnlyAllowed {
resp, err := r.handleBlocked(logger, request, question, "BLOCKED (WHITELIST ONLY)")
if allowlistOnlyAllowed {
resp, err := r.handleBlocked(logger, request, question, "BLOCKED (ALLOWLIST ONLY)")
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, ",")))
return true, resp, err
@ -394,13 +394,13 @@ func (r *BlockingResolver) handleBlacklist(ctx context.Context, groupsToCheck []
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) {
ctx, logger := r.log(ctx)
groupsToCheck := r.groupsToCheckForClient(request)
if len(groupsToCheck) > 0 {
handled, resp, err := r.handleBlacklist(ctx, groupsToCheck, request, logger)
handled, resp, err := r.handleDenylist(ctx, groupsToCheck, request, logger)
if handled {
return resp, err
}
@ -414,9 +414,9 @@ func (r *BlockingResolver) Resolve(ctx context.Context, request *model.Request)
if len(entryToCheck) > 0 {
logger := logger.WithField("response_entry", entryToCheck)
if groups := r.matches(groupsToCheck, r.whitelistMatcher, entryToCheck); len(groups) > 0 {
logger.WithField("groups", groups).Debugf("%s is whitelisted", tName)
} else if groups := r.matches(groupsToCheck, r.blacklistMatcher, entryToCheck); len(groups) > 0 {
if groups := r.matches(groupsToCheck, r.allowlistMatcher, entryToCheck); len(groups) > 0 {
logger.WithField("groups", groups).Debugf("%s is allowlisted", tName)
} 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,
strings.Join(groups, ",")))
}

View File

@ -97,7 +97,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
sutConfig = config.Blocking{
BlockType: "ZEROIP",
BlockTTL: config.Duration(time.Minute),
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"gr1": config.NewBytesSources(group1File.Path),
"gr2": config.NewBytesSources(group2File.Path),
},
@ -125,7 +125,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
sutConfig = config.Blocking{
BlockType: "ZEROIP",
BlockTTL: config.Duration(time.Minute),
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"gr1": config.NewBytesSources(group1File.Path),
"gr2": config.NewBytesSources(group2File.Path),
},
@ -164,7 +164,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
sutConfig = config.Blocking{
BlockType: "ZEROIP",
BlockTTL: config.Duration(time.Minute),
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"gr1": {config.TextBytesSource("/regex/")},
},
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() {
Eventually(sut.Resolve).
WithContext(ctx).
@ -196,7 +196,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
BeforeEach(func() {
sutConfig = config.Blocking{
BlockTTL: config.Duration(6 * time.Hour),
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"gr1": config.NewBytesSources(group1File.Path),
"gr2": config.NewBytesSources(group2File.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() {
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"))).
Should(
SatisfyAll(
@ -227,7 +227,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
SatisfyAll(
@ -238,7 +238,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
SatisfyAll(
@ -249,7 +249,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
SatisfyAll(
@ -260,7 +260,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
SatisfyAll(
@ -271,18 +271,18 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
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"))).
Should(HaveReturnCode(dns.RcodeNameError))
})
})
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"))).
Should(
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() {
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"))).
Should(
SatisfyAll(
@ -307,7 +307,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
// was delegated to next resolver
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"))).
Should(
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() {
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"))).
Should(
SatisfyAll(
@ -333,7 +333,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
SatisfyAll(
@ -402,7 +402,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
BeforeEach(func() {
sutConfig = config.Blocking{
BlockTTL: config.Duration(time.Minute),
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
},
ClientGroupsBlock: map[string][]string{
@ -428,7 +428,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
BeforeEach(func() {
sutConfig = config.Blocking{
BlockType: "ZEROIP",
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
},
ClientGroupsBlock: map[string][]string{
@ -473,7 +473,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
BeforeEach(func() {
sutConfig = config.Blocking{
BlockTTL: config.Duration(6 * time.Hour),
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
},
ClientGroupsBlock: map[string][]string{
@ -511,7 +511,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
When("BlockType is custom IP only for ipv4", func() {
BeforeEach(func() {
sutConfig = config.Blocking{
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
},
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() {
BeforeEach(func() {
// return defined IP as response
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"))).
Should(
SatisfyAll(
@ -561,7 +561,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
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() {
// reconfigure mock, to return CNAMEs
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.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"))).
Should(
SatisfyAll(
@ -598,14 +598,14 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
})
})
Describe("Whitelisting", func() {
When("Requested domain is on black and white list", func() {
Describe("Allowlisting", func() {
When("Requested domain is on black and allowlist", func() {
BeforeEach(func() {
sutConfig = config.Blocking{
BlockType: "ZEROIP",
BlockTTL: config.Duration(time.Minute),
BlackLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
WhiteLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
Denylists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
Allowlists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
ClientGroupsBlock: map[string][]string{
"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() {
sutConfig = config.Blocking{
BlockType: "zeroIP",
BlockTTL: config.Duration(60 * time.Second),
WhiteLists: map[string][]config.BytesSource{
Allowlists: map[string][]config.BytesSource{
"gr1": config.NewBytesSources(group1File.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() {
By("querying domain on the whitelist", func() {
It("should block everything else except domains on the allowlist with default group", func() {
By("querying domain on the allowlist", func() {
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "unknown"))).
Should(
SatisfyAll(
@ -656,7 +656,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
SatisfyAll(
@ -664,15 +664,15 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
HaveTTL(BeNumerically("==", 60)),
HaveResponseType(ResponseTypeBLOCKED),
HaveReturnCode(dns.RcodeSuccess),
HaveReason("BLOCKED (WHITELIST ONLY)"),
HaveReason("BLOCKED (ALLOWLIST ONLY)"),
))
Expect(m.Calls).Should(HaveLen(1))
})
})
It("should block everything else except domains on the white list "+
"if multiple white list only groups are defined", func() {
By("querying domain on the whitelist", func() {
It("should block everything else except domains on the allowlist "+
"if multiple allowlist only groups are defined", func() {
By("querying domain on the allowlist", func() {
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "one-client"))).
Should(
SatisfyAll(
@ -685,7 +685,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
SatisfyAll(
@ -693,14 +693,14 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
HaveTTL(BeNumerically("==", 60)),
HaveResponseType(ResponseTypeBLOCKED),
HaveReturnCode(dns.RcodeSuccess),
HaveReason("BLOCKED (WHITELIST ONLY)"),
HaveReason("BLOCKED (ALLOWLIST ONLY)"),
))
Expect(m.Calls).Should(HaveLen(1))
})
})
It("should block everything else except domains on the white list "+
"if multiple white list only groups are defined", func() {
By("querying domain on the whitelist group 1", func() {
It("should block everything else except domains on the allowlist "+
"if multiple allowlist only groups are defined", func() {
By("querying domain on the allowlist group 1", func() {
Expect(sut.Resolve(ctx, newRequestWithClient("domain1.com.", A, "1.2.1.2", "all-client"))).
Should(
SatisfyAll(
@ -713,7 +713,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
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"))).
Should(
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() {
sutConfig = config.Blocking{
BlockType: "ZEROIP",
BlockTTL: config.Duration(time.Minute),
BlackLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
WhiteLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(defaultGroupFile.Path)},
Denylists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
Allowlists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(defaultGroupFile.Path)},
ClientGroupsBlock: map[string][]string{
"default": {"gr1"},
},
}
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"))).
Should(
SatisfyAll(
@ -756,9 +756,9 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
Describe("Delegate request to next resolver", func() {
BeforeEach(func() {
sutConfig = config.Blocking{
BlockType: "ZEROIP",
BlockTTL: config.Duration(time.Minute),
BlackLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
BlockType: "ZEROIP",
BlockTTL: config.Duration(time.Minute),
Denylists: map[string][]config.BytesSource{"gr1": config.NewBytesSources(group1File.Path)},
ClientGroupsBlock: map[string][]string{
"default": {"gr1"},
},
@ -768,7 +768,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
// was delegated to next resolver
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() {
Expect(sut.Resolve(ctx, newRequestWithClient("example.com.", A, "1.2.1.2", "unknown"))).
Should(
@ -801,7 +801,7 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
Describe("Control status via API", func() {
BeforeEach(func() {
sutConfig = config.Blocking{
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"defaultGroup": config.NewBytesSources(defaultGroupFile.Path),
"group1": config.NewBytesSources(group1File.Path),
},
@ -1124,8 +1124,8 @@ var _ = Describe("BlockingResolver", Label("blockingResolver"), func() {
When("strategy is failOnError", func() {
It("should fail if lists can't be downloaded", func() {
_, err := NewBlockingResolver(ctx, config.Blocking{
BlackLists: map[string][]config.BytesSource{"gr1": config.NewBytesSources("wrongPath")},
WhiteLists: map[string][]config.BytesSource{"whitelist": config.NewBytesSources("wrongPath")},
Denylists: map[string][]config.BytesSource{"gr1": config.NewBytesSources("wrongPath")},
Allowlists: map[string][]config.BytesSource{"allowlist": config.NewBytesSources("wrongPath")},
Loading: config.SourceLoading{
Init: config.Init{Strategy: config.InitStrategyFailOnError},
},

View File

@ -117,7 +117,7 @@ var _ = BeforeSuite(func() {
},
},
Blocking: config.Blocking{
BlackLists: map[string][]config.BytesSource{
Denylists: map[string][]config.BytesSource{
"ads": config.NewBytesSources(
doubleclickFile.Path,
bildFile.Path,
@ -125,13 +125,13 @@ var _ = BeforeSuite(func() {
),
"youtube": config.NewBytesSources(youtubeFile.Path),
},
WhiteLists: map[string][]config.BytesSource{
Allowlists: map[string][]config.BytesSource{
"ads": config.NewBytesSources(heiseFile.Path),
"whitelist": config.NewBytesSources(heiseFile.Path),
"allowlist": config.NewBytesSources(heiseFile.Path),
},
ClientGroupsBlock: map[string][]string{
"default": {"ads"},
"clWhitelistOnly": {"whitelist"},
"clAllowlistOnly": {"allowlist"},
"clAdsAndYoutube": {"ads", "youtube"},
"clYoutubeOnly": {"youtube"},
},
@ -263,7 +263,7 @@ var _ = Describe("Running DNS server", 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))).
Should(
SatisfyAll(
@ -272,8 +272,8 @@ var _ = Describe("Running DNS server", func() {
))
})
})
Context("domain is on white and blacklist default group", func() {
It("Query with should not be blocked, domain is on white and blacklist", func() {
Context("domain is on allow/denylist default group", func() {
It("Query with should not be blocked, domain is on allow/denylist", func() {
Expect(requestServer(util.NewMsgWithQuestion("heise.de.", A))).
Should(
SatisfyAll(
@ -282,9 +282,9 @@ var _ = Describe("Running DNS server", func() {
))
})
})
Context("domain is on client specific white list", func() {
It("Query with should not be blocked, domain is on client's white list", func() {
mockClientName.Store("clWhitelistOnly")
Context("domain is on client specific allowlist", func() {
It("Query with should not be blocked, domain is on client's allowlist", func() {
mockClientName.Store("clAllowlistOnly")
Expect(requestServer(util.NewMsgWithQuestion("heise.de.", A))).
Should(
SatisfyAll(
@ -293,9 +293,9 @@ var _ = Describe("Running DNS server", func() {
))
})
})
Context("block client whitelist only", func() {
It("Query with should be blocked, client has only whitelist, domain is not on client's white list", func() {
mockClientName.Store("clWhitelistOnly")
Context("block client allowlist only", func() {
It("Query with should be blocked, client has only allowlist, domain is not on client's allowlist", func() {
mockClientName.Store("clAllowlistOnly")
Expect(requestServer(util.NewMsgWithQuestion("google.de.", A))).
Should(
SatisfyAll(