Posted at

Dnsmasq を使って特定のウェブサイトに OpenVPN 経由でアクセスできないようにする方法


はじめに

この記事では、OpenVPN に接続しているクライアント(PC、スマホなど)で、特定のサイトにアクセスできないようにする方法を紹介します。


TL;DR

Dnsmasq のインストール

$ sudo apt -y install dnsmasq

設定ファイルの編集


/etc/dnsmasq.conf

listen-address=127.0.0.1, 10.8.0.1


DNS の変更


/etc/openvpn/server.conf

- push "dhcp-option DNS 8.8.8.8"

+ push "dhcp-option DNS 10.8.0.1"

OpenVPN の再起動

$ sudo systemctl restart openvpn

ファイアウォールの変更と再起動

$ sudo ufw allow 53

$ sudo ufw reload

ブロックしたいサイトの追加


/etc/dnsmasq.d/main

address=/youtube.com/127.0.0.1


Dnsmasq の再起動

$ sudo systemctl restart dnsmasq

確認

$ curl -I https://www.youtube.com


モチベーション

なぜそんなことをするのかって? それはぼくが YouTube にハマりすぎて趣味の開発をする時間を確保できなくなってしまうからです。

YouTube 以外にも、Twitter や Facebook、Instagram、LINE、まとめサイトなど、気を散らすコンテンツは大量に潜んでいます。

それらのコンテンツは我々にこれでもかというくらい退屈させない時間を提供してくれますが、そのコンテンツの波に完全に身を任せてしまうともはや意志の力だけでは戻ることができません。

本当にやりたいことを実現するための時間を手に入れるためには、意志の力ではなく、コンテンツの波を提供するサイト自体を遮断するのが効果的です

そこで今回は、OpenVPN 経由でのアクセスにおいて、Dnsmasq を使って特定のドメイン(ぼくの場合は youtube.com)の接続先アドレスを書き換えることによって、アクセスできないようにする方法について紹介します。

特定のサイトにハマりすぎることがない人にとっては、この記事で紹介する内容はあまり役には立たないかもしれませんが、ぼくと同じようにある特定のサイトにハマってしまう人には役に立つと思います。


OpenVPN + Dnsmasq を使わない方法とその弱点

もし、OpenVPN を使わずに、もっと手軽に特定のサイトを遮断することをお望みならば、お使いの PC で /etc/hosts を編集することをおすすめします。

127.0.0.1 www.youtube.com

これだけで www.youtube.com にはアクセスできなくなります1

ただし、この方法には 2 つの弱点があります。


1. ワイルドカードが使えない

残念ながら /etc/hosts 内ではドメインに対してワイルドカード使えません。今でこそ YouTube Gaming は YouTube 本体に統合されましたが、昔は gaming.youtube.com でも YouTube と同じコンテンツを視聴することができました。

YouTube に限って言えばワイルドカードが使えないことに関してはあまりデメリットはないのかもしれませんが、複数のサイトをブロックしたいときに、それぞれのサイトでサブドメインで別のコンテンツが提供されるような場合はやはりワイルドカードが使いたくなることがあると思います。


2. スマホでは hosts ファイルをいじれない

これはあくまで PC の設定であり、スマホで /etc/hosts をいじることはできません。

なので、VPN 上の DNS で特定のサイトにアクセスできないようにしておいて、その DNS を使うように設定された VPN にスマホを接続することで、スマホでも特定のサイトにアクセスできないようにすることができます。

これは、ウェブブラウザからのアクセスに限らず、アプリ内でも効力を果たすのでとても役に立ちます。


環境構築と設定方法

OpenVPN + Dnsmasq の有用性について紹介したところで、ここからは具体的な設定方法について説明していきます。


OpenVPN の環境構築

こちらに関してはすでに過去のぼくが記事を書いているのでそちらを参考にしてみてください。

関連記事も参考になるかもしれません。


Dnsmasq の設定方法

この記事は Dnsmasq の設定方法を中心に説明します。


Dnsmasq のインストール

まずは Dnsmasq をインストールします。

$ sudo apt -y install dnsmasq


ローカル IP アドレスの調査

次に、ローカル IP アドレスを調べておきます。

$ ip a

いくつか表示されると思います。環境によって表示が変わると思うので説明が難しいのですが、inet という項目に IP アドレスが記載されているはずです。

複数ある inet の項目のうち、127.0.0.1 ではなく、グローバル IP アドレスでもないもの、つまりそのサーバに割り当てられているローカル IP アドレスを探してください。

以降の説明ではこのローカル IP アドレスを 10.8.0.1 として説明します。


dnsmasq.conf の編集

ローカル IP アドレスを調べたら、いくつかの設定ファイルを編集します。


/etc/dnsmasq.conf

listen-address=127.0.0.1, 10.8.0.1


/etc/dnsmasq.conf を見ると数百行に渡ってコメントアウトされた行があると思います。その行の中から listen-address を探し、コメントを外して上記のように記述してください。10.8.0.1 はご自身の環境に併せて変更してください。


OpenVPN 設定ファイルの編集

OpenVPNのインストールとセットアップからインターネット接続までのガイドブック」の通りに環境構築をされた場合は、/etc/openvpn/server.conf という設定ファイルに以下のような記述があるかと思います。


/etc/openvpn/server.conf

push "dhcp-option DNS 8.8.8.8"


これは VPN に接続してきた端末(PC やスマホなど)が使用する DNS を指定するものです。8.8.8.8 は Google Public DNS なので、これを使う代わりに Dnsmasq を通すように書き換えましょう。


/etc/openvpn/server.conf

- push "dhcp-option DNS 8.8.8.8"

+ push "dhcp-option DNS 10.8.0.1"

設定を変更したら OpenVPN を再起動しましょう。

$ sudo systemctl restart openvpn

うまくいかない場合は「OpenVPNのインストールとセットアップからインターネット接続までのガイドブック」の「OpenVPN サーバが起動できない場合」あたりも参考にしてみてください。


ファイアウォールの編集

せっかく Dnsmasq を通すようにしても、DNS のポートが空いていなければどのサイトの名前解決もできなくなってしまいます。なのでファイアウォールで 53 番ポートを開放します。

$ sudo ufw allow 53

開放したらファイアウォールをリロードします。

$ sudo ufw reload

53 番ポートが開放されていることを確認したい場合は以下のようにします。

$ sudo ufw status


ブロックしたいサイトを設定する

いよいよお待ちかねのサイトブロックの設定です。

/etc/dnsmasq.d/ のディレクトリ以下に配置したファイルは Dnsmasq の設定ファイルとしてロードされます。ファイル名はなんでも良いです。ここでは main とします。


/etc/dnsmasq.d/main

address=/youtube.com/127.0.0.1


address=/<ブロックしたいサイトのドメイン>/127.0.0.1 という形式で記述します。複数ある場合は次の行に同じように記述すれば良いです。


Dnsmasq の再起動

最後に Dnsmasq を再起動することを忘れずに。

$ sudo systemctl restart dnsmasq

問題なければデーモンが起動しているはずです。

$ systemctl status dnsmasq


確認

この状態で、まずは curl を実行してみましょう。

$ curl -I https://www.youtube.com

以下のように表示されてサイトにアクセスできないようになっていれば OK です。

curl: (35) gnutls_handshake() failed: The TLS connection was non-properly terminated.

ただ、まだこの段階では VPN サーバ上でアクセスできないことが確認できただけです。クライアント側でも同様に上記のコマンドを実行するか、ブラウザでアクセスしてみてください。もし設定が正しければアクセスできないようになっているはずです!


エラーハンドリング

もしうまくいかないのであれば問題を切り分けて考えてみましょう。


OpenVPN に接続できない

そもそも OpenVPN に接続できない場合は OpenVPN の設定が間違っている可能性が高いです。「OpenVPNのインストールとセットアップからインターネット接続までのガイドブック」の「注意ポイント」が参考になるかもしれません。


ブロックしたサイトにアクセスできてしまう

VPN サーバ上ではアクセスできないようになっていたが、クライアント側では依然としてアクセスできてしまう場合は、クライアントで使用する DNS が正しく設定できていない可能性があります。

クライアント側で dig コマンドを実行してみます。

$ dig www.youtube.com

SERVER と表示されている部分が、先ほど設定した VPN サーバのローカル IP アドレスになっていない場合は OpenVPN の設定が正しくできていないか、再起動を忘れている可能性が高いです。

;; SERVER: 10.8.0.1#53(10.8.0.1) # <- こうなっていれば正しい

;; SERVER: 8.8.8.8#53(8.8.8.8) # <- これだとたぶんうまくいかない


どのサイトにもアクセスできない

同じく VPN サーバ上ではアクセスできないようになっていたが、クライアントではどのサイトにもアクセスできない(dig コマンドも応答が返ってこない)場合は DNS のポートが閉じていることを疑います。

VPN サーバ側でファイアウォールの設定をもう一度確認してみましょう。

$ sudo ufw status

53 番ポートが開放されていなければ開放してください。再起動も忘れずに実行してください。


さいごに

多少めんどくさくはありますが、これで特定のサイトをブロックすることができました。

ぼくの場合は SSH 鍵がローカルになく2、設定を変更するためにはわざわざウェブのコンソールにログインしないといけないため、ちょうど良い抑止力になっています。

最悪、ウェブのコンソールからはアクセスできるので、思い切って VPN サーバ用の SSH 鍵を捨ててしまうのもあり3だと思います。

それでは、みなさんも無限のコンテンツに邪魔されない最高の時間をお楽しみください。





  1. 正確には「アクセスできない」ではなくて、www.youtube.com の接続先が自分に向くと言ったほうが正しいのですが、以降も便宜上は「アクセスできない」と表現することにします。 



  2. 厳密にはあるが、だいぶ前から Permission denied になったまま放置している。 



  3. 念のため言っておくと、パスワード認証にするという意味ではないです。