自分用パスワード管理アプリをLightSailに導入した話

# はじめに

## パスワード管理ソフトが必要だ

WEBサービス全盛の昨今、パスワードの管理は非常にやっかいな問題となっています。
一人で１００も２００もアカウントを持つと、もはや記憶に頼った管理はパスワード使い回しを招き、
逆に危険な状況になってきました。

## パスワード管理サービスとかは怖い

かといって、クラウド型パスワードマネージャを使うと、ハッキングを受けたときに心配です。
cf. [パスワード一元管理のLastPassにハッキング、情報流出も](http://www.itmedia.co.jp/enterprise/articles/1506/16/news050.html)

この手のサービスは、使い勝手が向上し利用ユーザが増えれば増えるほど、
ハッキングのターゲットになりやすいという、ジレンマもあります。

## パンがないならお菓子を（ｒｙ

だったら、自分専用で自分しかURLを知らないパスワード管理アプリを作ったらいいじゃん？
一人分のアカウントしか入っていないなら、攻撃する人もコスパあわないだろうし。
ということで、OSSのパスワード管理アプリをLightSailに入れてみた。

## なにを入れたの？
サーバホスティング型で、ドキュメントが一番整ってそうな[passbolt](https://www.passbolt.com/)を入れてみた。

# LightSailのインスタンスを立ち上げる

一応ubuntuの一番安いインスタンスにしてみました。

1. LightSailの管理画面で<KBD>Create Instance</KBD>ボタンを押す
2. "Pick your instance image"の下の<KBD>OS Only</KBD>ボタンを押す
3. Ubuntuを選択
4. Name your instanceに適当な名前を入れる
5. できあがったインスタンスの名前をクリックし、
6. Networkingタブに移って、<KBD>Create Static IP</KBD>ボタンを押して、IPを付与する
7. **Homeに戻って、再度、インスタンスの名前をクリックし、Networkingタブに移り、FirewallにHTTPSを追加する**

※7をやって無くて、ハマったのは内緒

# OS最新化＆日本語化＆日本時間への変更
別にやらなくてもいいけど、一応

```bash:Console
sudo su
apt update
apt -y dist-upgrade
apt -y autoremove
apt-get -y update
apt-get -y upgrade
apt-get -y install language-pack-ja-base language-pack-ja ibus-mozc
apt-get -y install fonts-ipafont
update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
timedatectl set-timezone Asia/Tokyo
```

終わったらLightSailの管理画面からRestartを実施

# ドメイン設定

適当なドメインを取得してください。

ドメインを取得しなくても動きますが、
ここではドメインを取得し、LightSailのIPに紐付けている前提で進めます。

# ミドルウェアのインストール

## nginx のインストール

```bash:Console
curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sh -c "echo 'deb http://nginx.org/packages/ubuntu/ trusty nginx' >> /etc/apt/sources.list"
sh -c "echo 'deb-src http://nginx.org/packages/ubuntu/ trusty nginx' >> /etc/apt/sources.list"
apt-get -y update
apt-get -y install nginx
```

## mysqlのインストール
```bash:Console
cd /tmp
wget https://dev.mysql.com/get/mysql-apt-config_0.8.8-1_all.deb
dpkg -i mysql-apt-config_0.8.8-1_all.deb
apt-get -y update
apt-get -y install mysql-server
```
2017/09/30現在のmysqlの最新版が0.8.8-1なので、上記を利用。
ここから最新版を確認してください。
https://dev.mysql.com/downloads/repo/apt/

## passbolt用DB作成
```bash:console
mysql -u root -p
```
```mysql:mysql
create database passbolt;
grant all on passbolt.* to 'passbolt'@'localhost' identified by '{任意のパスワード}';
exit;
```
ここではDatabase名、User名をpassboltにしていますが、別になんでもいいです。

## phpインストール
```bash:console
add-apt-repository ppa:ondrej/php
apt-get -y update
apt-get -y install php7.0-fpm php7.0-gd php7.0-mbstring php7.0-mcrypt php7.0-fpm php7.0-opcache php7.0-xml php7.0-mysql php7.0-cli php-pear php7.0-dev
```
## nginx と phpの動作確認

```bash:console
mkdir -p /var/www/passbolt
echo hogehoge > /var/www/passbolt/index.html
echo \<?= \'PHPテスト\' ?\> > /var/www/passbolt/index.php
vi /etc/nginx/conf.d/default.conf
vi /etc/php/7.0/fpm/pool.d/www.conf
```

```diff:/etc/nginx/conf.d/default.confの修正内容
server {
   listen       80;
-  server_name  localhost;
+  server_name  {紐付けたドメイン};

   #charset koi8-r;
   #access_log  /var/log/nginx/log/host.access.log  main;

   location / {
-      root   /usr/share/nginx/html;
+      root   /var/www/passbolt;
-      index  index.html index.htm;
+      index  index.php index.html index.htm;
   }

#｛中略｝

   # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
   #
-  #location ~ \.php$ {
-  #    root           html;
-  #    fastcgi_pass   127.0.0.1:9000;
-  #    fastcgi_index  index.php;
-  #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
-  #    include        fastcgi_params;
-  #}
+  location ~ \.php$ { 
+      root           /var/www/passbolt; 
+      fastcgi_pass   unix:/var/run/php/php7.0-fpm.sock; 
+      fastcgi_index  index.php;
+      fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
+      include        fastcgi_params;
+   }

#｛後略｝

}
```

```diff:/etc/php/7.0/fpm/pool.d/www.confの変更内容
- user = www-data
- group = www-data
+ user = nginx
+ group = nginx
  
- listen.owner = www-data
- listen.group = www-data
+ listen.owner = nginx
+ listen.group = nginx
```

```bash:console
service nginx restart
service php7.0-fpm restart
```
ブラウザで、ドメインにアクセスして、PHPテストと表示されれば、ここまでOK

## SSL設定

LetsencryptでSSLを取得します。
なぜかnginxを止めないとうまく取得できないので、止めてから実施します。

```bash:console
nginx -s stop
cd /usr/local
git clone https://github.com/certbot/certbot
cd certbot
./certbot-auto certonly --standalone -d 紐付けたドメイン -m メールアドレス --agree-tos -n
vi /etc/nginx/conf.d/default.conf
```
```diff:/etc/nginx/conf.d/default.confの修正内容
server {
   listen       80;
+  listen       443 ssl;
   server_name  {紐付けたドメイン};

+  ssl_certificate      /etc/letsencrypt/live/{紐付けたドメイン}/fullchain.pem;
+  ssl_certificate_key  /etc/letsencrypt/live/{紐付けたドメイン}/privkey.pem;
+  ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
+  ssl_prefer_server_ciphers on;
+  ssl_session_cache    builtin:1000 shared:SSL:10m;
+  ssl_session_timeout  10m;
+  ssl_stapling on;

   #charset koi8-r;
   #access_log  /var/log/nginx/log/host.access.log  main;

   location / {
       root   /var/www/passbolt;
       index  index.php index.html index.htm;
   }

#｛中略｝

   # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
   #
   location ~ \.php$ { 
       root           /var/www/passbolt; 
       fastcgi_pass   unix:/var/run/php/php7.0-fpm.sock; 
       fastcgi_index  index.php;
       fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
+      fastcgi_param  HTTPS on; 
       include        fastcgi_params;
    }

#｛後略｝

}
```

変更したら、再起動

```bash:console
service nginx restart
```

再起動に成功したら、
https://{紐付けたドメイン} にアクセスして、"PHPテスト"と表示されればここまでOK

# PGP鍵を作成する

## エントロピー低い問題を対策する

LightsailのUbuntuのは、すでにGnuPGがインストールされているので、すぐにでも鍵を作成できるが、

```bash:console
cat /proc/sys/kernel/random/entropy_avail
```
で出てくる数値が3桁前半と笑っちゃうくらい低いので、対策します。

```bash:console
apt-get install -y rng-tools
rngd -r /dev/urandom
cat /proc/sys/kernel/random/entropy_avail
```
これで、3000くらいにはなったはずです。

## 鍵を作成する
```bash:console
gpg --gen-key
```

質問内容は

- 鍵の種類を選択して ⇒ １を選択
- 鍵の有効期間は? (0) ⇒ 0
- これでいいですか？ ⇒ y
- 本名 ⇒ なんでもいい
- 電子メール・アドレス ⇒ なんでもいい
- コメント ⇒ なんでもいい
- ～～OK(O)か終了(Q)? ⇒ o
- パスフレーズ ⇒ **絶対に入力しない**

最後のパスフレーズを空でEnter押すのが絶対に必要です。
パスフレーズを入れると、Passboltが使えなくなります。

キーの作成に成功したら、出力される結果の下から2行目に

```bash:console
フィンガー・プリント = XXXX XXXX XXXX XXXX XXXX  XXXX XXXX XXXX XXXX XXXX
```
みたいなのが出てくるので、**必ずメモっておきましょう**。

## 鍵をエクスポートして配置する

passbolt向けに鍵をエクスポートします。
その前に、passboltをgitからcloneします。

```bash:console
cd /var/www/
rm -r passbolt
git clone https://github.com/passbolt/passbolt.git
gpg --armor --export-secret-keys メールアドレス > /var/www/passbolt/app/Config/gpg/private.key
gpg --armor --export メールアドレス > /var/www/passbolt/app/Config/gpg/public.key
```

## phpがGnuPGを扱えるようにする
```bash:console
apt-get install libgpgme11-dev php7.0-gnupg
pecl install gnupg
cp /etc/php/7.0/fpm/php.ini /etc/php/7.0/fpm/php.ini.bak
vi /etc/php/7.0/fpm/php.ini
```
/etc/php/7.0/fpm/php.iniには、

```php:/etc/php/7.0/fpm/php.ini
extension=gnupg.so
```
の一行を追加

その後、phpの再起動

```bash:console
service php7.0-fpm restart
```

# Passboltのインストール

## 設定の変更

```bash:console
cd /var/www/passbolt/app/Config
cp core.php.default core.php
cp database.php.default database.php
cp app.php.default app.php
cp email.php.default email.php
vi core.php
vi database.php
vi app.php
vi email.php
```
それぞれのファイル変更は以下の通り

```php:core.php
Configure::write('Security.salt', 'ランダム文字列を入れる');
Configure::write('Security.cipherSeed', 'ランダム数値を入れる');

Configure::write('App.fullBaseUrl', 'https://{紐付けたドメイン}');
```

↑ 該当キーを探し、変更してください。
**fullBaseUrl は、かならずhttpsにしてください。後から気づくと相当面倒です。**

```php:database.php
public $default = array(
	'datasource' => 'Database/Mysql',
	'persistent' => false,
	'host' => 'localhost',
	'login' => 'passbolt',
	'password' => 'mysqlでユーザ作ったときのパスワード',
	'database' => 'passbolt'
);
```
↑ いくつか定義されていますが、$default のみ変更で大丈夫です。

```diff:app.php
'GPG' => [
	'env' => [
		'setenv' => true,
-		'home' => '/home/www-data/.gnupg',
+		'home' => '/var/www/passbolt/app/Config/gpg',
	],
	'serverKey' => [
-		'fingerprint' => '2FC8945833C51946E937F9FED47B0811573EE67E',
+		'fingerprint' => 'メモしたフィンガープリントを、スペース外して入力',

-		'public' => APP . 'Config' . DS . 'gpg' . DS . 'unsecure.key',
+		'public' => APP . 'Config' . DS . 'gpg' . DS . 'public.key',
-		'private' => APP . 'Config' . DS . 'gpg' . DS . 'unsecure_private.key',
+		'private' => APP . 'Config' . DS . 'gpg' . DS . 'private.key'
-		'passphrase' => ''
	]
]
```
↑ 最後のpassphrase行を削除しますので、'private'の行のラストの カンマ も削除してください。

```php:email.php
public $default = array(
	'transport' => 'Smtp',
	'from' => array('任意のメールアドレス' => 'Passbolt'),
	'host' => 'smtpサーバ',
	'port' => 587,
	'timeout' => 30,
	'username' => '任意のメールアドレス',
	'password' => 'パスワード',
	'tls' => false,
);
```
↑ これも $defaultのみの修正で良いそうです。

なお、Gmail経由で送信したい場合は、

```php:email.php
public $default = array(
	'transport' => 'Smtp',
	'from' => array('任意のメールアドレス' => 'Passbolt'),
	'host' => 'ssl://smtp.gmail.com',
	'port' => 465,
	'timeout' => 30,
	'username' => '任意のメールアドレス',
	'password' => 'パスワード',
);
```
とする。

Passbolt（というかCake）はメールはあくまでQueueにためるだけなので、
送信するには、

```bash:console
/var/www/passbolt/app/Console/cake EmailQueue.sender 
```
を実行して上げる必要がある。

いちいちやるのがめんどうだという人は、Cronに登録しておくとよいと思います。

## ファイル等の権限変更

```bash:console
cd /var/www/passbolt/
chmod +w -R app/tmp
chmod +w app/webroot/img/public
chown -R nginx:nginx /var/www/passbolt/
```

## インストール

```bash:console
su -s /bin/bash -c "/var/www/passbolt/app/Console/cake install --no-admin" nginx
```
↑インストールコマンド

インストールに成功すると、今度は、管理ユーザを作る必要があります。

```bash:console
su -s /bin/bash -c "/var/www/passbolt/app/Console/cake passbolt register_user -u メールアドレス -f 名前（半角英数で） -l 名字(半角英数で） -r admin" nginx
```

ユーザ作成に成功すると、結果出力にURLがあるので、そこにアクセスして、アカウント作成を完了して下さい。

※ 名前と名字に2byte文字を入れると、動かなくなります。

以上になります。お疲れ様でした。

# 補足

## 氏名の変更

ログイン後、氏名を変更することができますが、この氏名を2byte文字にすると、
他のブラウザや、Extensionを入れ直した時とかに、ログインできなくなります。

こうなってしまうと、いったんmysqlにアクセスして、
profilesテーブルのfirst_name と last_nameを手動で書き換えないと、
二度とログインできなくなりますので、注意が必要です。

## ログイン環境

マルチ環境でログイン可能ですが、スマホは対応していません。。。
2018年には対応するとロードマップに載っていますが・・・。