それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

unboundによるDNSブロッキング

dns ブロッキングをunboundで実現する。

ともちゃ先輩が面白そうなことをやっていたので、ちょっと真似てみる。

とも ちゃ日記(Tomo cha) - 元大学生のOL日記-

ちまたで、kawangoが暴れているDNSブロッキングというネタがあり、元々実装を検討していたものについて、便乗してみました。 (略) 糞みたいな広告で通信料および、お金が擦り落とされるのが非常に腹正しく、何かする方法がないか考えていた。もちろん、部屋でゴロゴロとしてPCでネットを見ていても、広告があまりにもうざく、嫌気を指していたので、対処するべく実装に至った。 そのほか、 @kawango2525の頭の悪さに、こいつの関係するサイトもブロッキングする実装とした。

つまり、広告で余計なパケットを浪費させられるのは「意図しないプログラムの実行」なので止めていいよね。カワンゴもdnsで都合の悪いものは止めろと公言してるわけで、kawangoさんの会社のサービスもDNSで止めちゃえってこと。前からやってみようと思ってたけど、unbound入れるまともなOpenWRTルーターがなかったので延期にしていた。VPSDNSサービス立ち上げ選択肢もあったが、この場合一歩間違うとDNS amp の攻撃に使われちゃうし。x86 OpenWrt が無事に稼働しているし 設定をぶっ飛ばして初期化したのでついでに実装しておくことにした。*1

DNSによるブロッカーの仕組み

unboundの場合、次のようなホスト名の名前解決のルールを記入してあげると、該当のドメイン名は、ローカルに対する問合わせと処理され、「そのドメイン名にIPはなにもないぜ」という応答がクライアントに返されるようになる。

local-zone: "trafficgate.net." static

これは書式として次のようになっている。

# ゾーン=ローカル  " ドメイン名 + . "  static なにもなし
local-zone: "${domain_name}." static

この書式に従っってドメイン名を追記していけば、「なにもない」という応答を返せる。

書式が通りに実際に記入してためしてみて、実際に問い合わせた結果が空になることが確認できたら、ドメイン名を追加していけばいい。 ブロックしたいドメイン名の一覧をどこからか取得すればいいわけです。

ドメインリストがあれば、dns blocking をローカルでやることができる。

準備 unbound をいれる。

今回は、私は、openwrt に入れたルーターのunbound dnsを使って 実験することにしました。

opkg install unbound 

ubuntudebian なら

apt install unbound*

unboundの設定にサンプルを追加して試す。

わたしは、OpenWrt のunboundなので、次のようになっています。

unbound.conf

私の環境では、次のような include 関係になっています。include を重ねて管理していくのはどなたでも同じだと思います。

##
## 略
# 
include: /var/lib/unbound/unbound_srv.conf

unbound_srv.conf

include: /etc/unbound/280blocker-list.conf

280blocker-list.conf

## 適当なドメイン名で実在するものをテストで入れておく
local-zone: "trafficgate.net." static

設定を書いたら再起動してためします。

再起動

/etc/init.d/unbound restart
/etc/init.d/dnsmasq restart

わたしは、dnsmasq がフロント(0.0.0.0:53)で、実際に問い合わせる先にunbound(0.0.0.0:5300)を指定してるので両方を再起動しています。両方のキャッシュを削除し設定を反映させています。

確認

dig trafficgate.net @192.168.1.1
dig trafficgate.net @1.1.1.1

unbound(+dnsmasq)に問い合わせた結果と、public dns に問い合わせた結果が異なることを確認します。

無事にDNS問い合わせが、マスキングされて空っぽになっていたら、これでブロッキングに使えますね。

280blocker さんから ホスト名一覧を借りる。

ブロッキングしたいDNS一覧を探しておきます。

https://280blocker.net/files/280blocker_domain.txt

これを借りてきます。

curl -L https://280blocker.net/files/280blocker_domain.txt  \
 | sed -e "s/\r//"  \
 | grep -E '^[a-z0-9]'  \
 | awk '{print "local-zone: \""$1".\" static"}'  \
 | sort  | uniq

sed / awk / grep / sort /uniq をつかって整形します。

これで完成です。

定期的に更新出来るように、スクリプトにまとめておきます。

スクリプトに更新して再起動する手順を手っ取り早くまとめておいて、あとはcron に登録しておきました。280blockerさんによると、毎月1度の取得で十分だそうです。

unboundのdnsブロッキングリストを更新する。 · GitHub

#!/usr/bin/env sh

## @since 2020-05-15 
## @last 2021-01-05 
## @author takuya
## unbound にブロッキング
## ブロッキングするURLを定期的に更新する

function update_domain_lists(){
  update280blocker
  updateYoutubeAdblocker
}
function geneate_conf(){

  URL=$1
  OUTPUT=$2
  curl -sL $URL \
    | sed -e "s/\r//"   \
    | grep -E '^[a-z0-9]' \
    | awk '{print "local-zone: \""$1".\" static"}' \
    | sort \
    | uniq \
    > $OUTPUT
}

function checkHTTPStatusIs200(){
  URL=$1
  RET=$(curl -IL -s -o /dev/null -w '%{http_code}' $URL)

  [[ $RET == 200 ]];

}
function update280blocker () {

  URL=https://280blocker.net/files/280blocker_domain_$(date +%Y%m).txt
  ## mirror
  ## URL=https://raw.githubusercontent.com/junkurihara/280blocker_domain-mirror/master/280blocker_domain.txt
  OUTPUT=/etc/unbound/280blocker-list.conf
  if ! checkHTTPStatusIs200 $URL ; then
    echo failed;
    return 1
  fi
  ##
  geneate_conf $URL $OUTPUT
}

function updateYoutubeAdblocker () {

  URL=https://raw.githubusercontent.com/anudeepND/youtubeadsblacklist/master/domainlist.txt
  OUTPUT=/etc/unbound/youtube-ad.conf
  ##
  if ! checkHTTPStatusIs200 $URL ; then
    echo failed;
    return 1
  fi
  ##
  geneate_conf $URL $OUTPUT
}

function restart_unbund(){
  [ -e /etc/init.d/unbound ] &&
  /etc/init.d/unbound restart
}
function restart_dnsmasq(){
  [ -e /etc/init.d/dnsmasq ] &&
  /etc/init.d/dnsmasq restart 2>&1 > /dev/null
}
function main(){
  update_domain_lists &&
  restart_unbund &&
  restart_dnsmasq
}



main


DNSブロッキングってすごく強力

ためしてみてわかったのですが、DNSブロッキングは強烈に強力です。

DNSTLS化したりHTTPS化してコンテンツの書き換えを防止したいというセキュリティ上の欲求の要請がよくわかります。

強烈に強力なので、これを監視に使いたいという欲求もよくわかります。

インターネット・イコール・DNSと言っても過言ではないので、こんな強力すぎるものをkawango と政府に握られるのはとても恐ろしやと思いますね。中国怖いです。はい。

DNSだけは死守しないと死にますね。8.8.8.8 / google public dnsや 1.1.1.1 / cloudflare dns がコンテンツフィルタリングしないとも限らないので、ちゃんとroot . から問い合わせる unboundを自宅に一つ持っておくべきだと思います。安易な8.8.8.8、ダメゼッタイ。

関連資料

unboundでrootから引くdnsサーバを作り、DNSフィルタリングに備える - それマグで!
ついに牙を向いたPublic DNS - それマグで!
我々のDNS問い合わせは監視されている。 - それマグで!

参考資料

Adguard HomeでVPSに広告ブロックDNSを立てました | 280blocker

とも ちゃ日記(Tomo cha) - 元大学生のOL日記-

https://blog.unko.pro/adblock-by-resolver/

2021-01-05

280blocker さんに迷惑をかけないように書き直し。

*1: ローカルネットのdebian/ubuntuのサーバーで色々と試してたりしますが、実運用に使うにはPPPoE持ってるルータに入れないと回線断やら再起動やら常時起動を考えると別サーバー運用にするのは煩雑だし。DHCP割り振りも考えると、キャッシュDNSの仕組み上、ルーターに持たせるのが楽なんですよ。