Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
31
Help us understand the problem. What is going on with this article?

More than 3 years have passed since last update.

@mascii

Raspberry PiをHTTP/HTTPSプロキシサーバーにしてみた

プロキシサーバーとは、主にHTTP/HTTPS通信を"代理"(Proxy)するサーバーのことを言います。
PCやスマホ、ゲーム機のネットワーク設定で、プロキシを設定することでHTTP/HTTPSの通信ログを取得したり、ドメイン名などを指定して特定のWebサイトやサービスをブロックすることができます。

今回の記事ではSquidというソフトを利用し、題目通りRaspberry PiをHTTP/HTTPSプロキシサーバーとして機能させ、Nintendo Switchにプロキシの設定をしてHTTP/HTTPS通信ログをみてみる実験をしてみます。

illust-proxy.png

動作環境(確認済み)

  • Raspberry Pi 3 Model B
    • Raspbian Stretch Lite 2017-11-29
      • イメージをMicroSDに書き込んだ後、MicroSDのルートディレクトリにsshという名前で空のファイルを作成
      • 家庭用無線LANルーターに有線LAN接続

設定

初期設定

あなたのお家に眠るラズパイを救出したいのスライドなどを参考に、有線LAN接続を用いてPCからSSH接続できる状態にしておいてください。
sshまたはssh.txtという名前のファイルをPC上でMicroSDに保存しておく必要があることに気をつけてください。
必要であればテキストエディタとして、Vimなどをインストールしてください。

Squidのインストール

sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install squid -y

Squidの設定

サイボウズさんの技術ブログの記事1を参考にSquidの設定をしました:

/etc/squid/squid.conf
# ローカルネットワークの定義
acl localnet src 10.0.0.0/8     # RFC1918 possible internal network
acl localnet src 172.16.0.0/12  # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
# acl localnet src fc00::/7 # RFC 4193 local private network range
# acl localnet src fe80::/10# RFC 4291 link-local (directly plugged) machines

# SSL接続時に 443 ポート以外の CONNECT を拒否
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny CONNECT !SSL_ports

# 接続先として指定されているポート以外を拒否
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
http_access deny !Safe_ports

# キャッシュの設定( manager を定義してないので無効な値)
http_access allow localhost manager
http_access deny manager

# ローカルネットワークからのアクセスを許可
http_access allow localnet

# 自身からのアクセスを許可
http_access allow localhost

# ここまで一致しなかった場合は拒否
http_access deny all

# Squid が使用するポート
http_port 3128

# core 出力場所の設定
coredump_dir /var/spool/squid

# キャッシュの設定
# refresh_pattern ^ftp:     1440    20%     10080
# refresh_pattern ^gopher:  1440    0%1440
# refresh_pattern -i (/cgi-bin/|\?) 0     0%0
# refresh_pattern .   0 20%     4320

# QueryStringの記録
strip_query_terms off

# Apache風の形式でログを記録
logformat combined %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
access_log /var/log/squid/access.log combined

IPv6のローカルネットワークの定義があるとSquidがうまく動かなかったので、コメントアウトしました。

http通信に関しては、URLの ? 以降のクエリー文字列も取得できるので、クエリー文字列取得のための設定をしました2

標準では以下のように、1517980020.712 1150 192.168.10.3 TCP_TUNNEL/200 4531 CONNECT accounts.nintendo.com:443 - HIER_DIRECT/54.175.219.211 - のように、Unix時間から始まるログが記録されるので、下記のログのようなApache風のログを出力するための設定をしました3

192.168.10.3 - - [09/Feb/2018:16:47:38 +0900] "CONNECT accounts.nintendo.com:443 HTTP/1.1" 200 4531 "-" "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1aca
e821d897; SDK 4.4.0.0; Add-on 4.4.0.0)" TCP_TUNNEL:HIER_DIRECT

設定を反映するには、以下のコマンドでSquidを再起動します:

sudo systemctl restart squid

Timezoneの設定

Squidのアクセスログの時刻をJST(UTC+9)で出力させるため、以下のコマンドを実行します:

sudo timedatectl set-timezone Asia/Tokyo

logrotateの設定

Squidをaptでインストールすると、 /etc/logrotate.d/ にSquidのアクセスログに関するログローテーションの定義ファイルが入ります。
この定義ファイルがあると、深夜3時台に1日分のログファイルがリネームされ、過去2日分だけログが保存されるようになります。
少しの間だけプロキシサーバーを立てて試してみるのには不要でしたので、以下の定義ファイルの内容をすべて # でコメントアウトしてみました。
(x86マシンなどでプロキシサーバーの長期運用を考えている際には、適切なログローテーションの運用が必要ですので、注意してください)

/etc/logrotate.d/squid
#
#   Logrotate fragment for squid.
#
/var/log/squid/*.log {
    daily
    compress
    delaycompress
    rotate 2
    missingok
    nocreate
    sharedscripts
    prerotate
        test ! -x /usr/sbin/sarg-reports || /usr/sbin/sarg-reports daily
    endscript
    postrotate
        test ! -e /var/run/squid.pid || test ! -x /usr/sbin/squid || /usr/sbin/squid -k rotate
    endscript
}

logrotateについては、サービスの再起動なしで設定が反映されます。

IPアドレスの固定設定

Nintendo SwitchはZeroconfに対応していないようなので、Raspberry PiのIPアドレスは固定しておくと良いです。
IPアドレスを固定するには、dhcpcdで設定するか、ルーター(DHCP)で設定します。

dhcpcdで設定

/etc/dhcpcd.conf に設定を追記してRaspberry Piを再起動することで、IPアドレスを固定できます。
参照: Raspberry Pi 2 (Raspbian: jessie) でIPアドレスを固定する

ルーター(DHCP)で設定

ルーターのDHCP機能を利用している方が大半だと思いますが、MACアドレスを指定してDHCPで割り当てられるIPアドレスを固定することができます。

aterm-dhcp.png

Raspberry PiのMACアドレス、割り当てられているIPアドレスを調べるには、ip addr コマンドを実行します(eth0が有線LAN、wlan0が無線LANです)

pi@raspberrypi:~ $ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.10/24 brd 192.168.10.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2405:6581:9b20:1200:4504:c156:f42e:b053/64 scope global mngtmpaddr noprefixroute dynamic 
       valid_lft 2591961sec preferred_lft 604761sec
    inet6 fe80::12d6:b296:64dd:10e3/64 scope link 
       valid_lft forever preferred_lft forever
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether b8:27:eb:xx:xx:xx brd ff:ff:ff:ff:ff:ff

アクセスログを見てみる

lessコマンドを使ってアクセスログをみることができます:

sudo less /var/log/squid/access.log

アクセスログを開いている際、大文字Gを入力で、最終行までジャンプできます。

アクセスログをリアルタイムで見たい場合はtailコマンドを使います:

sudo tail -f /var/log/squid/access.log

Nintendo Switchにプロキシを設定してみる

このスクリーンショットのように、接続先単位でプロキシを設定できます
switch-proxy.jpg

Nintendo SwitchのHTTP/HTTPS通信ログを見てみる

1日放置してみた

Nintendo みまもり Switchを設定したNintendo Switchを、30時間ほど放置してみたところ、145行ほどのログが出力されていました。この記事にログを貼り付けると長くなってしまうのでGistに置きました:
https://gist.github.com/mascii/73334b6994c699fd30c065e59bc7efac

SwitchのOSは、ほぼHTTPSで通信していることがわかりました。
api-lp1.pctl.srv.nintendo.netはブラウザで開いてみると、みまもり Switchのアプリのダウンロードリンクだけあるページが表示されるので、これはみまもり Switch関連の通信だと推測します。6時間に1回みまもり Switch関連の通信があると思われます。
他にも、ニンテンドーeショップやゲームニュース関連の通信が6時間に1回程度あるものと思われます。

niconicoアプリ

ニンテンドーeショップから無料でダウンロードできるniconicoアプリで、ニコニコ動画を観てみたところ、以下のようなHTTPのログが残っていました:

192.168.10.3 - - [10/Feb/2018:15:10:53 +0900] "GET http://flapi.nicovideo.jp/api/getflv?v=1182590816&device=nicoswitch&eco=1 HTTP/1.1" 200 1058 "-" "NicoSwitchAgent/2.00 (handheld)" TCP_MISS:HIER_DIRECT

クエリー文字列までログに残すようにしていたので、組曲『ニコニコ動画』を観たことがバレバレでした。SwitchのOSのログがほぼHTTPSだったので、ちょっと残念。

まとめ

組み込み機器やゲーム機がHTTP/HTTPSでいつどんな通信しているか、プロキシサーバーを立てて見てみることはやはり面白かったです。
ただ、Raspberry PiではストレージがmicroSD(ログの書き込みなどによる故障の確率が高い)であったり、Gigabit Ethernetに非対応だったりするので、長期運用や速度は望めなさそうです。

小規模オフィスでプロキシによるアクセス制御(SNSやオンラインストレージの使用制限など)や、アクセスログの収集が必要になった際に、Raspberry Piを試験的なプロキシサーバーとしてみるような使い方もできると思います。x86マシンにCentOSとSquidをインストールし、logrotateやfluentdの設定をしっかりやって...などの前段階の調査に良さそうです。

また、DHCP環境だと端末に割り当てられるIPアドレスが頻繁に変わることがあるので、「いつ、IPアドレスがどのWebサーバーにアクセスしたか」だけでなく、「いつ、どの端末がどのWebサーバーにアクセスしたか」までログに残す必要がある場合は、DHCPのログも必要になると思われます。家庭用ルーターだとDHCPのログをSyslogでログサーバーに転送するといった機能はないので、Node.jsを用いてルーターの管理画面にあるDHCPのログをHTTPでスクレイピングするような仕組みを作ると良いと思います。
aterm-dchp-log.png

参考文献

31
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
31
Help us understand the problem. What is going on with this article?