ConoHaで爆速プロキシサーバーを試す（Ubuntu 16.04 + squid）

この記事は[ConoHa Advent Calendar](https://qiita.com/advent-calendar/2017/conoha) 13日目の記事になります。昨日は[hironobu_s](https://twitter.com/hironobu_s)さんで、「[conohasayで楽しいターミナル生活を](https://qiita.com/hironobu_s/items/e19de0a3a5e057c7064a)」でした。さて、今日はConoHaちゃんを使って爆速プロキシサーバーを立ててみたいと思います。出来るだけ初心者にも分かりやすいように書きたいと思います。（※自分が初心者）

# 参考にした主なサイト
[5分で作るPROXYサーバー on @Qiita](https://qiita.com/pcnikki/items/404329f9ad9cb6e235d4)
[proxyサーバ squidでアクセス時に認証を要求する設定 パソコン鳥のブログ/ウェブリブログ](http://vogel.at.webry.info/201306/article_19.html)
[プロキシサーバ(Squid)にDigest認証を実装する - フルスタックエンジニアを目指して](http://skkskynw.hateblo.jp/entry/2016/09/04/165725)

# 【準備1】サーバーの作成

基本の1GBプランでサーバー（インスタンス）を作成します。OSはUbuntu 16.04 (64bit版)を選択しました。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/78152/76a5a954-a482-b18e-afc0-0a7054be26a9.png)

SSH鍵は、以前作成したものがあったので、今回はそれを使いましたが、なければ新規キー登録を選んでください。（画面左にある`セキュリティ→SSH Key`から作成することもできます。）

![01.png](https://qiita-image-store.s3.amazonaws.com/0/78152/3c1931dd-fe35-e8cb-0498-c4a4152c6799.png)

少し待つと、サーバーが作成されます。

# 【補足】もしもSSHの設定の途中で間違えてサーバーにアクセスできなくなってしまったら

もし設定の途中で間違えて、SSH接続できなくなった場合があるかもしれません。

```
# ↓ConoHaちゃんをいぢめる
yuinore@114-514-810-893:~$ sudo ifdown ens3
```

その場合は、ConoHaコントロールパネルの`サーバー`から、`コンソール`を選択すると、コンソールログインができますので、ユーザー名である`root`と、最初の登録時に入力したroot パスワードを入力すると、コンソールログインすることができますので、なんとかすることができます。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/78152/d8389454-26d1-34b5-6594-4213da55a8fc.png)

```
# ↓なんとかする
root@114-514-810-893:~# ifup ens3
```

# 【準備2】ユーザーの作成とSSHの設定

作成したSSH鍵と、作成されたサーバーのIPアドレスを使用して、BashからSSH接続します。ユーザー名にはrootを使用します。

```bash
kuro@ubuntu:~$ ssh root@114.514.810.893 -i ~/20170832000000.pem -p 22
```

rootへログインできると危ない（らしい）ので、[adduserコマンド](http://masaoo.blogspot.jp/2009/08/ubuntu-adduser.html)でユーザーを追加します。adduserの後に続けて好きな**あなたのユーザー名**を入力します。また、`Enter new UNIX password` の後に続けてパスワードを入力します。画面には何も表示されませんが、そのまま続けてください。その後に名前などを聞かれますが、何も入力せずにエンターキーを押して問題ありません。

```bash:リモートサーバー
root@114-514-810-893:~# adduser yuinore
```

`.ssh`ディレクトリとSSH鍵をコピーして、sshログインできるようにします。`yuinore`の部分を**あなたのユーザー名**に変えて入力してください。また、[（パーミッションと）所有者を設定します](https://qiita.com/youcune/items/2f427979403771f2e03a)。

```bash:リモートサーバー
root@114-514-810-893:~# cp -r /root/.ssh/ /home/yuinore
root@114-514-810-893:~# chmod 700 /home/yuinore/.ssh
root@114-514-810-893:~# chmod 600 /home/yuinore/.ssh/authorized_keys
root@114-514-810-893:~# chown yuinore:yuinore /home/yuinore/.ssh
root@114-514-810-893:~# chown yuinore:yuinore /home/yuinore/.ssh/authorized_keys 
```

この設定ができたら、正しくSSH接続できることを確認します。

```bash:リモートサーバー
root@114-514-810-893:~# exit
```

```bash:ローカル
kuro@ubuntu:~$ ssh yuinore@114.514.810.893 -i ~/20170832000000.pem -p 22
```

# 【準備3】sudoersへの追加

もう一度rootでログインし直します。[gpasswdコマンドでsudoグループに自分を追加します](https://qiita.com/white_aspara25/items/c1b9d02310b4731bfbaa)。

```bash:リモートサーバー
root@114-514-810-893:~# gpasswd -a yuinore sudo
Adding user yuinore to group sudo
root@114-514-810-893:~# getent group | grep sudo  # 確認
sudo\:x:27:yuinore
```

**あなたのユーザー名**でSSH接続して、sudoが使えることを確認します。

```bash
root@114-514-810-893:~# exit
kuro@ubuntu:~$ ssh yuinore@114.514.810.893 -i ~/20170832000000.pem -p 22
yuinore@114-514-810-893:~$ sudo echo Hello World!
```

Hello World! と表示されたら実験は成功です。

# 【準備4】rootログインの禁止とポート番号の変更

```bash:リモートサーバー
sudo vim /etc/ssh/sshd_config 
```

以下に示す該当行を変更します。`PermitRootLogin`を`no`にすることで、rootログインを禁止します。

```bash:変更後
Port 【ポート番号】
PermitRootLogin no
ChallengeResponseAuthentication no
PasswordAuthentication no
```

【ポート番号】の部分には、**1024～49151の範囲の適当な数字**を入れてください。変更が終わったら、sshdを再起動します。

```bash:リモートサーバー
sudo /etc/init.d/ssh restart
```

パスワードを用いたログインとrootログインができないことを確認します。

```bash:ローカル
kuro@ubuntu:~$ ssh root@114.514.810.893 -p 364364
Permission denied (publickey).
kuro@ubuntu:~$ ssh yuinore@114.514.810.893 -p 364364
Permission denied (publickey).
kuro@ubuntu:~$ ssh root@114.514.810.893 -i ~/20170832000000.pem -p 364364
Permission denied (publickey).
kuro@ubuntu:~$ ssh yuinore@114.514.810.893 -i ~/20170832000000.pem -p 364364
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-57-generic x86_64)
```

# squidのインストール

さて、本題のsquidをインストールします。

```bash:リモートサーバー
sudo apt-get install squid
```

インストールが終わったら、[digest認証用のパスワードファイルを作成](http://vogel.at.webry.info/201306/article_19.html)します。digest認証とbasic認証のどちらが良いかについては諸説ありそうですが、今回はdigest認証を選択しました。

```bash:リモートサーバー
sudo apt-get install apache2-utils
sudo htpasswd -cp /etc/squid/passwd yuinore
```

その後、squidの設定ファイルを編集します。

```bash:リモートサーバー
sudo vim /etc/squid/squid.conf
```

[以下の2行をコメントアウトしてください](https://qiita.com/pcnikki/items/404329f9ad9cb6e235d4)。他の行はコメントアウトしないでください。

```text:squid.conf
# http_access deny all
# http_port 3128
```

次に、squid.confの末尾に以下の設定を追記します。【ポート番号】の部分には**先ほどとは異なる**1024～49151の範囲の適当な数字を入れてください。また、[タイプミスには十分気をつけてください](https://www.cherrypieweb.com/weblog/technical/20100603003022.php)。

ちなみに、**[Ubuntuではdigest_pw_authの場所が変更になっている](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12156891347)**ようなので注意してください。これで1時間くらいハマりました。ファイルが存在するかどうか、一応確認しておいた方が良さそうです。

```text:squid.conf
http_port 【ポート番号】

auth_param digest program /usr/lib/squid3/digest_file_auth /etc/squid/passwd

auth_param digest children 20 startup=0 idle=1
auth_param digest realm Squid is ika. (gyokai)
auth_param digest nonce_garbage_interval 5 minutes
auth_param digest nonce_max_duration 30 minutes
auth_param digest nonce_max_count 50

visible_hostname yuinore.moe

acl myacl1 proxy_auth REQUIRED
http_access allow myacl1
http_access deny all

forwarded_for off

header_access X-Forwarded-For deny all
header_access Via deny all
header_access Cache-Control deny all
```

squidを再起動します。

```bash:リモートサーバー
sudo /etc/init.d/squid restart
```

ローカルから接続テストをします。それっぽいものが出ていれば成功です。

```bash:ローカル
# HTTP接続
curl --proxy-digest -U yuinore:YOURPASSWORD -x 114.514.810.893:810931 -L http://example.com | tail

# HTTPS接続
curl --proxy-digest -U yuinore:YOURPASSWORD -x 114.514.810.893:810931 -L https://www.yahoo.co.jp | tail
```

# 【補足】IPアドレスでアクセスを制御する

もし、パスワードによる認証ではなくIPアドレスによってアクセスを制御したい場合は、次のようにするといいそうです。パスワードを入力する必要がない代わりに、そのIPアドレスが変更されると設定も修正する必要があります。下の設定の123.456.654.321には接続元のIPアドレスを入れてください。

```text:squid.conf
http_port 【ポート番号】

visible_hostname yuinore.moe

acl myacl1 src 123.456.654.321/255.255.255.255
http_access allow myacl1
http_access deny all

forwarded_for off

header_access X-Forwarded-For deny all
header_access Via deny all
header_access Cache-Control deny all
```

# 測定

お待ちかねのスピード測定ですが、どんな結果になったでしょうか。444kBのファイルと8.63MBのファイルに対して、それぞれ約3時間/約6時間ごとにプロキシ経由と直接接続で特定のファイルを各国の24のサーバーからダウンロードするのを、11月の中頃から約7日間ずつ続けました。（勝手に）サーバーを使わせて頂きありがとうございました。サーバーのリストとソースコードは下の方に置いてあります。

## 結果

N はデータの件数で、ratioは直接接続とプロキシ経由の速度の比です。

### 444kBのファイルの場合
```
-------- Overseas --------
ratio = 2.672861196130555
direct : 91.11 kB/s (N = 1227)
proxy : 243.53 kB/s (N = 1227)
proxy_to_remote : 368.44 kB/s (N = 1227)
local_to_proxy : 2109.98 kB/s (N = 1227)
-------- Japan --------
ratio = 1.1864754754007445
direct : 353.36 kB/s (N = 177)
proxy : 419.26 kB/s (N = 177)
proxy_to_remote : 708.11 kB/s (N = 177)
local_to_proxy : 2526.98 kB/s (N = 177)
```

### 8.63MBのファイルの場合
```
-------- Overseas --------
ratio = 12.187210141108308
direct : 81.87 kB/s (N = 683)
proxy : 997.71 kB/s (N = 683)
proxy_to_remote : 2304.21 kB/s (N = 683)
local_to_proxy : 2629.74 kB/s (N = 683)
-------- Japan --------
ratio = 2.0042917665918734
direct : 405.48 kB/s (N = 100)
proxy : 812.7 kB/s (N = 100)
proxy_to_remote : 1195.03 kB/s (N = 100)
local_to_proxy : 1722.49 kB/s (N = 100)
```

海外サーバーへの接続においては、プロキシを使用すると**速度が平均で12倍になりました！** また、サーバーによっては最大で平均31倍の差がありました。 速い！！ やったねたえちゃん！！

・・・

・・・・・・

・・・・・・・・・プロキシの方が速いというのはとても疑惑の結果な気がするのですが、誰か理由がわかりますかね・・・？

## ソースコードと生出力
[speedtest.sh](https://gist.github.com/yuinore/16b5b0249f3b627cc52c755ac8c01a32)
[centos_mirror_pickup.txt](https://gist.github.com/yuinore/7748667055d832b42a484d7ae0367863) （サーバーリスト）
[analyze_statistics.html](https://gist.github.com/yuinore/543d895d18214bb7ac44283af7afd17f)
[statistics_444kb.csv](https://www.dropbox.com/s/ml3yt4txyo5yf0r/statistics_444kb.csv?dl=1)
[statistics_9mb.csv](https://www.dropbox.com/s/xqqugy5gxe3gw95/statistics_9mb.csv?dl=1)

# さいごに

色々詰め込んだら収拾がつかなくなってしまいましたが、なんとか書き終えることができました。もし間違いなどありましたら教えて頂けたら嬉しいです。明日は[kazsw](https://twitter.com/_internet_ghost)さんで、「ObjectStorage」の予定です。お楽しみに。