スマートフォンでの広告非表示で通信量削減を目指す

動機・目的

スマートフォンを使っていて、イラっとするのは、それほど広くない画面に広告がずらずらと表示されているときなのであります。 Wifi経由ではないとき、通信量は1ヶ月あたり○GBという契約になっています。 この画像データの通信に通信量にカウントされるのかと思うと腹が立つものです。というわけで、携帯回線経由の通信の際に広告を排除する、かつ、できれば、画像などを圧縮して通信量の削減をはかろうというコンセプトです。

手段

上記の目的を達成するために用いられる手段としてプロキシ導入があります。 かつてWindows上では、Proxomitronというプロキシを導入していたものです。

スマートフォン (Android)上で Proxy

FilterProxyというアプリケーションを使っていました。Android端末上で動作します。動作も軽快です。 広告ブロックぶりもよいです。

play.google.com

ただ

  • すべての通信がFilterProxy経由となるため、アプリケーションごとの通信量が把握しづらくなる点
  • 動作が軽快とはいえ、電池動作の端末でCPUパワーを使う点

が気になったので、サーバ上に処理を移すことを検討します。

サーバ上でプロキシ

VPSを契約していますので、そちらで動かそうということです。 下記のサイトを参考に、役割分担は以下のとおりです。

  • アクセス制限・認証 → Squid
  • 圧縮 → ziproxy
  • 広告フィルタ → privoxy

blog.asial.co.jp

実装

設計

クローラからのアクセスを嫌ってVPS経由のアクセスを制限しているサイトもありますので、最終的には自宅(プロバイダからはプライベートIPしか配布されない)内にある。Raspberry Piを経由させるようにします。

f:id:atauky:20160403045224p:plain

各Proxyの設定

Squid

インストールされていない場合は、$ sudo apt-get install squid3でインストールします。 設定変更後の再起動は、$ sudo service squid3 restart

$ grep -v -e '^\s*#' -e '^\s*$' /etc/squid3/squid.conf
acl docomospnet src 203.138.180.0/24
acl docomospnet src 203.138.181.0/24
acl docomospnet src 203.138.203.0/24
acl docomospnet src 1.66.96.0/21
acl docomospnet src 1.66.104.0/23
acl docomospnet src 1.72.0.0/21
acl docomospnet src 1.72.8.0/23
acl docomospnet src 1.72.10.0/24
acl docomospnet src 1.75.0.0/21
acl docomospnet src 1.75.8.0/22
acl docomospnet src 1.75.12.0/23
acl docomospnet src 1.75.14.0/24
acl docomospnet src 1.75.16.0/20
acl docomospnet src 1.75.152.0/21
acl docomospnet src 1.75.196.0/22
acl docomospnet src 1.75.208.0/21
acl docomospnet src 1.75.224.0/19
acl docomospnet src 1.78.0.0/19
acl docomospnet src 1.78.32.0/21
acl docomospnet src 1.78.40.0/22
acl docomospnet src 1.78.64.0/18
acl docomospnet src 1.78.96.0/22
acl docomospnet src 1.79.6.0/23
acl docomospnet src 1.79.8.0/21
acl docomospnet src 1.79.16.0/21
acl docomospnet src 1.79.24.0/22
acl docomospnet src 1.79.28.0/23
acl docomospnet src 1.79.30.0/24
acl docomospnet src 1.79.32.0/21
acl docomospnet src 1.79.66.0/23
acl docomospnet src 1.79.68.0/22
acl docomospnet src 1.79.72.0/21
acl docomospnet src 1.79.80.0/20
acl docomospnet src 1.79.96.0/21
acl docomospnet src 1.79.176.0/21
acl docomospnet src 49.96.0.0/18
acl docomospnet src 49.96.216.0/21
acl docomospnet src 49.96.224.0/21
acl docomospnet src 49.96.242.0/23
acl docomospnet src 49.96.244.0/23
acl docomospnet src 49.97.1.0/24
acl docomospnet src 49.97.2.0/23
acl docomospnet src 49.97.4.0/24
acl docomospnet src 49.97.16.0/22
acl docomospnet src 49.97.31.0/24
acl docomospnet src 49.97.32.0/23
acl docomospnet src 49.97.34.0/24
acl docomospnet src 49.97.39.0/24
acl docomospnet src 49.97.40.0/23
acl docomospnet src 49.97.42.0/24
acl docomospnet src 49.97.47.0/24
acl docomospnet src 49.97.48.0/23
acl docomospnet src 49.97.50.0/24
acl docomospnet src 49.97.55.0/24
acl docomospnet src 49.97.56.0/21
acl docomospnet src 49.97.64.0/20
acl docomospnet src 49.97.88.0/22
acl docomospnet src 49.97.92.0/22
acl docomospnet src 49.97.96.0/19
acl docomospnet src 49.98.7.0/24
acl docomospnet src 49.98.8.0/21
acl docomospnet src 49.98.16.0/23
acl docomospnet src 49.98.32.0/19
acl docomospnet src 49.98.64.0/18
acl docomospnet src 49.98.128.0/17
acl docomospnet src 49.104.0.0/18
acl docomospnet src 49.104.64.0/20
acl docomospnet src 49.104.80.0/21
acl docomospnet src 49.106.200.0/21
acl docomospnet src 49.106.208.0/20
acl docomospnet src 49.106.224.0/22
acl docomospnet src 49.106.228.0/23
acl docomospnet src 110.163.6.0/23
acl docomospnet src 110.163.8.0/22
acl docomospnet src 110.163.12.0/23
acl docomospnet src 110.163.216.0/21
acl docomospnet src 110.163.224.0/22
acl docomospnet src 183.74.0.0/21
acl docomospnet src 183.74.8.0/23
acl docomospnet src 183.74.192.0/20
acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localhost
http_access allow docomospnet # ←ポイント1
http_access deny all
http_port 8080
cache_peer localhost parent 3128 7 no-query # ←次のziproxyのポートへ
never_direct allow all
cache_dir ufs /var/spool/squid3 100 16 256 # ←一応キャッシュの設定
coredump_dir /var/spool/squid3
refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern -i (/cgi-bin/|\?) 0     0%      0
refresh_pattern (Release|Packages(.gz)*)$      0       20%     2880
refresh_pattern .               0       20%     4320
request_header_access X-Forwarded-For deny all  # ←ポイント2
request_header_access Via deny all # ←ポイント2
request_header_access Cache-Control deny all # ←ポイント2
forwarded_for off

・ポイント1

docomoのspmodeからのアクセスを許可するため、アクセスリストに「docomospnet」というグループを作りました。 アクセスリストに設定するサブネット情報は下記から取得しています。 リストに変更が入ることがあるのでので、自動で設定できるようにするともっと楽かもしれませんが、今は時々確認して手動で更新です。

www.nttdocomo.co.jp

・ポイント2

プロキシからのアクセスとわからなくするための設定です。

ziproxy

インストールされていなければ$ sudo apt-get install ziproxyでインストールします。 設定変更後の再起動は、$ sudo service ziproxy restartです。

設定ファイルの内容は以下のとおり。

$ grep -v -e '^\s*#' -e '^\s*$' /etc/ziproxy/ziproxy.conf
Port = 3128 # ziproxyが動作するポート番号
Address = "xxx.xxx.xxx.xxx"  # Raspberry Piに設定されたIPアドレス
ErrorLog = "/var/log/ziproxy/error.log"
AccessLog = "/var/log/ziproxy/access.log"
NextProxy="xxx.xxx.xxx.xxx." # 次のProxy:上記と同じ
NextPort=8118  # 次のProxy:Privoxyが動作しているポート番号
TransparentProxy = true 
UseContentLength = false
ImageQuality = {30,25,25,20}

Privoxy

インストールされていなければ$ sudo apt-get install privoxyでインストールします。 設定変更後の再起動は、$ sudo service ziproxy restartです。

設定ファイルの内容は以下のとおり。 追加する広告ブロック用の設定をmycustom.actionにすべて入れておいて、user.actionと分割しておきます。

$ grep -v -e '^\s*#' -e '^\s*$' /etc/privoxy/config
user-manual /usr/share/doc/privoxy/user-manual
confdir /etc/privoxy
logdir /var/log/privoxy
actionsfile match-all.action # Actions that are applied to all sites and maybe overruled later on.
actionsfile default.action   # Main actions file
actionsfile user.action      # User customizations
actionsfile mycustom.action  # 追加したアクションファイル
filterfile default.filter
filterfile user.filter      # User customizations
logfile logfile
listen-address  xxx.xxx.xxx.xxx:8118
toggle  1
enable-remote-toggle  0
enable-remote-http-toggle  0
enable-edit-actions 0
enforce-blocks 0
buffer-limit 4096
enable-proxy-authentication-forwarding 0
forwarded-connect-retries  0
accept-intercepted-requests 0
allow-cgi-request-crunching 0
split-large-forms 0
keep-alive-timeout 5
tolerate-pipelining 1
socket-timeout 300

mycustom.action ファイルの中身は下記のサイトを参考に設定しました。

d.hatena.ne.jp

トンネリング

ziproxyの3128番ポートでトンネリングできるようにします。 無通信による切断を避けるため、下記のサイトを参考にautosshを用います。

qiita.com

インストールは、$ sudo apt-get install autosshでできました。 Raspberry Pi側から下記のコマンドを入力します。

$ autossh -M 0 -o Compression=yes -NR 3128:(VPSのIPアドレス):3128 -l (VPSのユーザ名) -p (VPSのsshポート番号)

事前にパスワードなしでSSHできるようにしておいてください。

orebibou.com

あとこちらにならって、sshのセッションが切れないようにクライアント側(Raspberry Pi側)に設定をしておきます。

rcmdnk.github.io

~/.ssh/config

ServerAliveInterval 60
ServerAliveCountMax 3

Android側の設定

Androidのバージョンや機種によって設定画面に違いがあると思いますが、APNの設定プロキシの設定を追加します。

f:id:atauky:20160403052139p:plain