CRMのF-RevoをAWS Lightsailで構築したときにハマったこと(Apache,let's encrypt)

# はじめに
CRM(F-Revo)を導入したときにハマってしまったことを書いていきます。
[F-Revoの環境について](http://qiita.com/VTRyo/items/28c31f1fe8edb3f96e80 "F-Revoの環境について")はこちらです。
*Lightsailどうこうではない部分もあります。*

## CRMをインストールしようとしたらページが真っ白になった件
F-Revoのインストール設定を入力したあと、こんなページまで行きます。

![20150917093149.png](https://qiita-image-store.s3.amazonaws.com/0/157454/09f44ff3-b599-e35e-24cd-03af0cdb6518.png)

しかしこのあと次のページに遷移すると真っ白なページになって、戻るも進むなくなり、二進も三進もいかなくなりました。
**原因はCRMがPHP7に対応していないからでした。**
現場の開発はPHP7でやっていたため、できればPHP7を使用してF-Revoをインストールしたかったのですが、プライオリティは低いということでPHP5.6を再インストールしました。

> **参考**
オープンソースなので、自己責任でソースを書き換えればPHP7でも動作するという書き込みもありましたのでご参考までに。
> Vtiger with PHP7
https://discussions.vtiger.com/index.php?p=/discussion/183662/vtiger-with-php7/p1
PHP 7 compatibility
http://code.vtiger.com/vtiger/vtigercrm/issues/197

## Let's encryptがうまく実行されない件
オレオレ認証局ではなく、Let's encryptを利用して証明書を作成しようと試みましたが失敗した話です。
結論から言うと、**mod24_sslがインストールされていないから**に落ち着きます。
「Let's encryptはとにかく簡単。パッケージをインストールしてコマンドを叩けば自動で証明書の作成がされるよ」とみたいな話ではあるものの、凡ミスのせいで鮮やかにコケたというお話です。

ではコケるまでの手順を見ていきましょう。
1. インストールコマンドを叩く

```
$ wget https://dl.eff.org/certbot-auto
```
```
$ chmod a+x certbot-auto
```
```
$ ./certbot-auto --agree-tos --webroot-path <RootDirectory> -d <DomainName> -m <E-Mail>
※--webroot-pathはhttpdを実行したまま証明書を発行できるオプションです。
```
はい！　ここでコケました！
そして下記のエラーが出力されました。

```
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for <DomainName>
No vhost exists with servername or alias of: <DomainName> (or it's in a file with multiple vhosts, which Certbot can't parse yet). No vhost was selected. Please specify ServerName or ServerAlias in the Apache config, or split vhosts into separate files.
Falling back to default vhost *:443...
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. <DomainName> (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to <IPaddress>:443 for TLS-SNI-01 challenge

IMPORTANT NOTES:
```

翻訳すると、「DomainNameを持つ仮想ホストは存在しません」みたいなことが書いてあり、「Apacheの設定でServerNameまたはServerAliasを指定するか、仮想ホストを別々のファイルに分割してください」ともあります。
試しにApache設定にVirtualHostを追記しましたがエラーに変化はないです。
```/etc/resolv.conf```の設定ミスというわけでもなかったです。
443が云々というエラーメッセージもあるのでssl.confを見に行ってみると、```ssl.conf```がないことに気づきました。
というわけで、mod24_sslを```yum install```し、Let's encryptにて証明書発行が実行できました。

## 常時https接続に設定変更したらCRMのWEBページにたどり着けなくなった件
少し話が長くなりますので、結論からいうと**config.inc.phpに記載されたsite_URLがhttp://~**になっていたことと、**/etc/httpd/conf.d/le-redirect-DomainName.com.conf**が原因でした。

#### 事の始まり
Let's encryptのコマンドを無事実行し、いよいよ終了が近づくと「httpもhttpsもイケるようにする？それとも常時https接続にする？」みたいな二択が表示されます。

・・・で、もともと常時https接続にする予定だったこともあり、常時の方を選択しました。
「よーしこれで80ポートは閉めていいな？」ということで、LightsailのGUIコンソール側でセキュリティルールを変更しました。
そしてこのあとユーザさんから「ログインできない！」と続々お問い合わせが来てしまったのです。
見てみると、エラー内容はタイムアウトでした。

となると、まず疑うべきは

* 「常時https接続する」を選択したときに、自動でどこかにその設定を読み込むコンフィグが作成された可能性

ということです。そのコンフィグが作成されたこと一点が原因でログイン画面に行けないのであれば、コンフィグ名を変更してやることで今までのようにhttp接続でログインページにたどり着けるようになるはずです。

はい、ありました。```le-redirect```と名前がついてるので決定的です。
中身を見てみると、httpsにRewriteしているようです。とりあえずこのファイル名を変更し、httpdを再起動します。

```/etc/httpd/conf.d/le-redirect-DomainName.com.conf
<VirtualHost _default_:80>
ServerName <DomainName>:443
ServerAlias <DomainName>
ServerSignature Off

RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]

ErrorLog /var/log/httpd/redirect.error.log
LogLevel warn
</VirtualHost>
```
ただ、これだけだと80ポートを閉じているのでhttp通信もできない状態。再度Lightsailの80ポートを開きます。
これで一旦、http通信ではあるけれどログインページにはこれまで通りいけるはず！

* 強制リダイレクトしてるファイルを読み込ませない
* http通信を許可する

**応急処置が終わったら次はhttpsで接続できるようにしていきます。**

#### そもそもなんでHTTPS接続できなかったか
いわゆるリダイレクトループと言えばいいんでしょうか。

リクエスト→http→強制でhttpsに変換→config.inc.phpに記載されたsite_URLがhttp://~のためhttpになる→強制でhttpsに→→→というイメージです。

config.inc.phpを一部抜粋するとこんな感じで記述されています。

```/var/www/html/config.inc.php
$site_URL = 'http://<IPaddress>';
```
つまりこれを、httpsと記述してやればいいわけです。もっというと、ドメイン名でURLを表記させたいので以下のように変更しました。

```/var/www/html/config.inc.php
#$site_URL = 'http://<IPaddress>/~';
$site_URL = 'https://<DomainName>/~';
```
そして改めて、必要のない80ポートを閉じます。
これで私の環境ではhttps接続が可能になりました！

## おわりに
長くなりましたが、大抵ネットワーク関連で死ぬときは設定漏れか把握してないファイルがいるみたいなときなんですかね。ともあれユーザが安全、安定して使用してもらえるよう運用していきたいです。