Files
AdGuardHome/internal/filtering/blocked.go
Eugene Burkov 47c9c946a3 Pull request: 4871 imp filtering
Merge in DNS/adguard-home from 4871-imp-filtering to master

Closes #4871.

Squashed commit of the following:

commit 618e7c558447703c114332708c94ef1b34362cf9
Merge: 41ff8ab7 11e4f091
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Sep 22 19:27:08 2022 +0300

    Merge branch 'master' into 4871-imp-filtering

commit 41ff8ab755a87170e7334dedcae00f01dcca238a
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Sep 22 19:26:11 2022 +0300

    filtering: imp code, log

commit e4ae1d1788406ffd7ef0fcc6df896a22b0c2db37
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Sep 22 14:11:07 2022 +0300

    filtering: move handlers into single func

commit f7a340b4c10980f512ae935a156f02b0133a1627
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Sep 21 19:21:09 2022 +0300

    all: imp code

commit e064bf4d3de0283e4bda2aaf5b9822bb8a08f4a6
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 20 20:12:16 2022 +0300

    all: imp name

commit e7eda3905762f0821e1be1ac3cf77e0ecbedeff4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 20 17:51:23 2022 +0300

    all: finally get rid of filtering

commit 188550d873e625cc2951583bb3a2eaad036745f5
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 20 17:36:03 2022 +0300

    filtering: merge refresh

commit e54ed9c7952b17e66b790c835269b28fbc26f9ca
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 20 17:16:23 2022 +0300

    filtering: merge filters

commit 32da31b754a319487d5f9d5e81e607d349b90180
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 20 14:48:13 2022 +0300

    filtering: imp docs

commit 43b0cafa7a27bb9b620c2ba50ccdddcf32cfcecc
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 20 14:38:04 2022 +0300

    all: imp code

commit 253a2ea6c92815d364546e34d631e406dd604644
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Sep 19 20:43:15 2022 +0300

    filtering: rm important flag

commit 1b87f08f946389d410f13412c7e486290d5e752d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Sep 19 17:05:40 2022 +0300

    all: move filtering to the package

commit daa13499f1dd4fe475c4b75769e34f1eb0915bdf
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Sep 19 15:13:55 2022 +0300

    all: finish merging

commit d6db75eb2e1f23528e9200ea51507eb793eefa3c
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Sep 16 18:18:14 2022 +0300

    all: continue merging

commit 45b4c484deb7198a469aa18d719bb9dbe81e5d22
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Sep 14 15:44:22 2022 +0300

    all: merge filtering types
2022-09-23 13:23:35 +03:00

496 lines
9.9 KiB
Go

package filtering
import (
"encoding/json"
"net/http"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/urlfilter/rules"
"golang.org/x/exp/slices"
)
// svc represents a single blocked service.
type svc struct {
name string
rules []string
}
// servicesData contains raw blocked service data.
//
// Keep in sync with:
// - client/src/helpers/constants.js
// - client/src/components/ui/Icons.js
var servicesData = []svc{{
name: "whatsapp",
rules: []string{
"||wa.me^",
"||whatsapp.com^",
"||whatsapp.net^",
},
}, {
name: "facebook",
rules: []string{
"||facebook.com^",
"||facebook.net^",
"||fbcdn.net^",
"||accountkit.com^",
"||fb.me^",
"||fb.com^",
"||fb.gg^",
"||fbsbx.com^",
"||fbwat.ch^",
"||messenger.com^",
"||facebookcorewwwi.onion^",
"||fbcdn.com^",
"||fb.watch^",
},
}, {
name: "twitter",
rules: []string{
"||t.co^",
"||twimg.com^",
"||twitter.com^",
"||twttr.com^",
},
}, {
name: "youtube",
rules: []string{
"||googlevideo.com^",
"||wide-youtube.l.google.com^",
"||youtu.be^",
"||youtube",
"||youtube-nocookie.com^",
"||youtube.com^",
"||youtubei.googleapis.com^",
"||youtubekids.com^",
"||ytimg.com^",
},
}, {
name: "twitch",
rules: []string{
"||jtvnw.net^",
"||ttvnw.net^",
"||twitch.tv^",
"||twitchcdn.net^",
},
}, {
name: "netflix",
rules: []string{
"||nflxext.com^",
"||netflix.com^",
"||nflximg.net^",
"||nflxvideo.net^",
"||nflxso.net^",
},
}, {
name: "instagram",
rules: []string{"||instagram.com^", "||cdninstagram.com^"},
}, {
name: "snapchat",
rules: []string{
"||snapchat.com^",
"||sc-cdn.net^",
"||snap-dev.net^",
"||snapkit.co",
"||snapads.com^",
"||impala-media-production.s3.amazonaws.com^",
},
}, {
name: "discord",
rules: []string{
"||discord.gg^",
"||discordapp.net^",
"||discordapp.com^",
"||discord.com^",
"||discord.gift",
"||discord.media^",
},
}, {
name: "ok",
rules: []string{"||ok.ru^"},
}, {
name: "skype",
rules: []string{
"||edge-skype-com.s-0001.s-msedge.net^",
"||skype-edf.akadns.net^",
"||skype.com^",
"||skypeassets.com^",
"||skypedata.akadns.net^",
},
}, {
name: "vk",
rules: []string{
"||userapi.com^",
"||vk-cdn.net^",
"||vk.com^",
"||vkuservideo.net^",
},
}, {
name: "origin",
rules: []string{
"||accounts.ea.com^",
"||origin.com^",
"||signin.ea.com^",
},
}, {
name: "steam",
rules: []string{
"||steam.com^",
"||steampowered.com^",
"||steamcommunity.com^",
"||steamstatic.com^",
"||steamstore-a.akamaihd.net^",
"||steamcdn-a.akamaihd.net^",
},
}, {
name: "epic_games",
rules: []string{"||epicgames.com^", "||easyanticheat.net^", "||easy.ac^", "||eac-cdn.com^"},
}, {
name: "reddit",
rules: []string{"||reddit.com^", "||redditstatic.com^", "||redditmedia.com^", "||redd.it^"},
}, {
name: "mail_ru",
rules: []string{"||mail.ru^"},
}, {
name: "cloudflare",
rules: []string{
"||1.1.1.1^",
"||argotunnel.com^",
"||cloudflare-dns.com^",
"||cloudflare-ipfs.com^",
"||cloudflare-quic.com^",
"||cloudflare.cn^",
"||cloudflare.com^",
"||cloudflare.net^",
"||cloudflareaccess.com^",
"||cloudflareapps.com^",
"||cloudflarebolt.com^",
"||cloudflareclient.com^",
"||cloudflareinsights.com^",
"||cloudflareresolve.com^",
"||cloudflarestatus.com^",
"||cloudflarestream.com^",
"||cloudflarewarp.com^",
"||dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion^",
"||one.one^",
"||pages.dev^",
"||trycloudflare.com^",
"||videodelivery.net^",
"||warp.plus^",
"||workers.dev^",
},
}, {
name: "amazon",
rules: []string{
"||amazon.com^",
"||media-amazon.com^",
"||primevideo.com^",
"||amazontrust.com^",
"||images-amazon.com^",
"||ssl-images-amazon.com^",
"||amazonpay.com^",
"||amazonpay.in^",
"||amazon-adsystem.com^",
"||a2z.com^",
"||amazon.ae^",
"||amazon.ca^",
"||amazon.cn^",
"||amazon.de^",
"||amazon.es^",
"||amazon.fr^",
"||amazon.in^",
"||amazon.it^",
"||amazon.nl^",
"||amazon.com.au^",
"||amazon.com.br^",
"||amazon.co.jp^",
"||amazon.com.mx^",
"||amazon.com.tr^",
"||amazon.co.uk^",
"||createspace.com^",
"||aws",
},
}, {
name: "ebay",
rules: []string{
"||ebay.com^",
"||ebayimg.com^",
"||ebaystatic.com^",
"||ebaycdn.net^",
"||ebayinc.com^",
"||ebay.at^",
"||ebay.be^",
"||ebay.ca^",
"||ebay.ch^",
"||ebay.cn^",
"||ebay.de^",
"||ebay.es^",
"||ebay.fr^",
"||ebay.ie^",
"||ebay.in^",
"||ebay.it^",
"||ebay.ph^",
"||ebay.pl^",
"||ebay.nl^",
"||ebay.com.au^",
"||ebay.com.cn^",
"||ebay.com.hk^",
"||ebay.com.my^",
"||ebay.com.sg^",
"||ebay.co.uk^",
},
}, {
name: "tiktok",
rules: []string{
"||amemv.com^",
"||bdurl.com^",
"||bytecdn.cn^",
"||bytedance.map.fastly.net^",
"||bytedapm.com^",
"||byteimg.com^",
"||byteoversea.com^",
"||douyin.com^",
"||douyincdn.com^",
"||douyinpic.com^",
"||douyinstatic.com^",
"||douyinvod.com^",
"||ixigua.com^",
"||ixiguavideo.com^",
"||muscdn.com^",
"||musical.ly^",
"||pstatp.com^",
"||snssdk.com^",
"||tiktok.com^",
"||tiktokcdn.com^",
"||tiktokv.com^",
"||toutiao.com^",
"||toutiaocloud.com^",
"||toutiaocloud.net^",
"||toutiaovod.com^",
},
}, {
name: "vimeo",
rules: []string{
"*vod-adaptive.akamaized.net^",
"||vimeo.com^",
"||vimeocdn.com^",
},
}, {
name: "pinterest",
rules: []string{
"||pinimg.com^",
"||pinterest.*^",
},
}, {
name: "imgur",
rules: []string{"||imgur.com^"},
}, {
name: "dailymotion",
rules: []string{
"||dailymotion.com^",
"||dm-event.net^",
"||dmcdn.net^",
},
}, {
name: "qq",
rules: []string{
// Block qq.com and subdomains excluding WeChat's domains.
"||qq.com^$denyallow=wx.qq.com|weixin.qq.com",
"||qqzaixian.com^",
"||qq-video.cdn-go.cn^",
"||url.cn^",
},
}, {
name: "wechat",
rules: []string{
"||wechat.com^",
"||weixin.qq.com.cn^",
"||weixin.qq.com^",
"||weixinbridge.com^",
"||wx.qq.com^",
},
}, {
name: "viber",
rules: []string{"||viber.com^"},
}, {
name: "weibo",
rules: []string{
"||weibo.cn^",
"||weibo.com^",
"||weibocdn.com^",
},
}, {
name: "9gag",
rules: []string{
"||9cache.com^",
"||9gag.com^",
},
}, {
name: "telegram",
rules: []string{
"||t.me^",
"||telegram.me^",
"||telegram.org^",
},
}, {
name: "disneyplus",
rules: []string{
"||disney-plus.net^",
"||disney.playback.edge.bamgrid.com^",
"||disneynow.com^",
"||disneyplus.com^",
"||hotstar.com^",
"||media.dssott.com^",
"||star.playback.edge.bamgrid.com^",
"||starplus.com^",
},
}, {
name: "hulu",
rules: []string{"||hulu.com^"},
}, {
name: "spotify",
rules: []string{
"/_spotify-connect._tcp.local/",
"||spotify.com^",
"||scdn.co^",
"||spotify.com.edgesuite.net^",
"||spotify.map.fastly.net^",
"||spotify.map.fastlylb.net^",
"||spotifycdn.net^",
"||audio-ak-spotify-com.akamaized.net^",
"||audio4-ak-spotify-com.akamaized.net^",
"||heads-ak-spotify-com.akamaized.net^",
"||heads4-ak-spotify-com.akamaized.net^",
},
}, {
name: "tinder",
rules: []string{
"||gotinder.com^",
"||tinder.com^",
"||tindersparks.com^",
},
}, {
name: "bilibili",
rules: []string{
"||b23.tv^",
"||biliapi.net^",
"||bilibili.com^",
"||bilicdn1.com^",
"||bilicdn2.com^",
"||biligame.com^",
"||bilivideo.cn^",
"||bilivideo.com^",
"||dreamcast.hk^",
"||hdslb.com^",
},
}}
// serviceRules maps a service ID to its filtering rules.
var serviceRules map[string][]*rules.NetworkRule
// serviceIDs contains service IDs sorted alphabetically.
var serviceIDs []string
// initBlockedServices initializes package-level blocked service data.
func initBlockedServices() {
l := len(servicesData)
serviceIDs = make([]string, l)
serviceRules = make(map[string][]*rules.NetworkRule, l)
for i, s := range servicesData {
netRules := make([]*rules.NetworkRule, 0, len(s.rules))
for _, text := range s.rules {
rule, err := rules.NewNetworkRule(text, BlockedSvcsListID)
if err != nil {
log.Error("parsing blocked service %q rule %q: %s", s.name, text, err)
continue
}
netRules = append(netRules, rule)
}
serviceIDs[i] = s.name
serviceRules[s.name] = netRules
}
slices.Sort(serviceIDs)
log.Debug("filtering: initialized %d services", l)
}
// BlockedSvcKnown - return TRUE if a blocked service name is known
func BlockedSvcKnown(s string) (ok bool) {
_, ok = serviceRules[s]
return ok
}
// ApplyBlockedServices - set blocked services settings for this DNS request
func (d *DNSFilter) ApplyBlockedServices(setts *Settings, list []string) {
setts.ServicesRules = []ServiceEntry{}
if list == nil {
d.confLock.RLock()
defer d.confLock.RUnlock()
list = d.Config.BlockedServices
}
for _, name := range list {
rules, ok := serviceRules[name]
if !ok {
log.Error("unknown service name: %s", name)
continue
}
setts.ServicesRules = append(setts.ServicesRules, ServiceEntry{
Name: name,
Rules: rules,
})
}
}
func (d *DNSFilter) handleBlockedServicesAvailableServices(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
err := json.NewEncoder(w).Encode(serviceIDs)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "encoding available services: %s", err)
return
}
}
func (d *DNSFilter) handleBlockedServicesList(w http.ResponseWriter, r *http.Request) {
d.confLock.RLock()
list := d.Config.BlockedServices
d.confLock.RUnlock()
w.Header().Set("Content-Type", "application/json")
err := json.NewEncoder(w).Encode(list)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "encoding services: %s", err)
return
}
}
func (d *DNSFilter) handleBlockedServicesSet(w http.ResponseWriter, r *http.Request) {
list := []string{}
err := json.NewDecoder(r.Body).Decode(&list)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "json.Decode: %s", err)
return
}
d.confLock.Lock()
d.Config.BlockedServices = list
d.confLock.Unlock()
log.Debug("Updated blocked services list: %d", len(list))
d.ConfigModified()
}