はじめに
この記事では、OpenVPN に接続しているクライアント(PC、スマホなど)で、特定のサイトにアクセスできないようにする方法を紹介します。
TL;DR
Dnsmasq のインストール
$ sudo apt -y install dnsmasq
設定ファイルの編集
listen-address=127.0.0.1, 10.8.0.1
DNS の変更
- 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
ブロックしたいサイトの追加
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 アドレスを調べたら、いくつかの設定ファイルを編集します。
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
という設定ファイルに以下のような記述があるかと思います。
push "dhcp-option DNS 8.8.8.8"
これは VPN に接続してきた端末(PC やスマホなど)が使用する DNS を指定するものです。8.8.8.8
は Google Public DNS なので、これを使う代わりに Dnsmasq を通すように書き換えましょう。
- 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
とします。
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だと思います。
それでは、みなさんも無限のコンテンツに邪魔されない最高の時間をお楽しみください。