運用10年以上のサービスを常時HTTPS(AOSSL)に移行した話


開始から10年以上経つサービスのAOSSL化プロジェクトのPMをしたので手順やポイントをまとめます。

# 環境

* オンプレミス
* PHP 5.3.24 
* ZendFramework 1.10.4 (一部)
* Nginx(RP) 1.15.2 → apache 2.2
* oracle 11g

#### ローカル環境

* windows 7

# 移行に関して使ったツール

* [Azure DevOps](https://azure.microsoft.com/ja-jp/)
* [jenkins](https://jenkins.io/)
* [git bash](https://gitforwindows.org/)
* [mixed-content-scan](https://github.com/bramus/mixed-content-scan)
* テスト仕様書 
* アクセスログ（対象ドメインへのPOST注意。リダイレクトでの対応はパラメータが消えてしまう。）

# 10年運用を変えない弊害

```
AOSSL化させるってめっちゃ簡単やん。
「http」を「https」に書き換えれば終わりでしょ。
```

と思う方も多いと思います。
それは最近のアーキテクチャに沿った構成のお話。
10年以上も前のシステムになると弊害の山々。
弊害の一例になります。

```
・サーバ構成図なし
・テストコードなし
・オンプレにFTPでアップロードするデプロイ
・バージョン管理がされていない、Gitの知識がある人が皆無
・デプロイ時にローカル、テスト、本番でコメントアウトする運用のプログラム
・Zendフレームワークを一部のみ利用、viewにも処理がある
・1000近いテーブル
・データベース内にもURLなどがある
・openSSLのバージョンが古い
```

聞いただけで気持ち悪くなりますよね。
できるねという人はPMになりましょう。

# 組織体制

インフラ、アプリケーション、プロモーションの部署がそれぞれ分かれており、
組織をまたいだプロジェクトマネジメントが必要。

# 何からやるべきか？

### とにかくまずは影響調査と計画から
スケジュールを立てる上で「影響調査」が最重要
10人日いただき手順を固め計画を練りました。

その上で以下二つのスコープを明確します。
・https化する対象サイト
・対象サイトを参照する関連サイト

### 構成図
全体把握する上で構成図が必要です。
まずは構成図を作成しました。
![move.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272635/9e2d0562-24a1-b782-a6e0-3526bb136a18.png)
絵が下手でごめんなさい。

#### 図の説明

```
・デプロイ時、担当者は修正ファイルをコンテンツサーバにFTPアップロードし公開していた
・アプリケーションサーバのDocumentRootはコンテンツサーバ（ファイルサーバ）へマウント
・コンテンツサーバはオンプレミス、アクセスは社内のみ
・httpsの検証環境としてステージング環境が用意されている
・ストレージからAzureDevOpsにjenkinsを使って日々の差分をpush
・一括置換はローカルPCで最新リポジトリに対して実施
```

デプロイ時のプログラムの統合管理ができていないことが大きな問題でした。

まずは日々の改修差分を管理できるようにしました。
オンプレのコンテンサーバからAzureDevOpsに直接アクセス許可がされていなったため、
外部に通信できるようストレージサーバを用意しました。(図の右側青色部分)
jenkinsが用意されていたので日々の運用差分をAzureDevOpsに記録して行きました。

# 計画、準備フェーズ

仕様書がない時点で何をどうテストするか不明なため、まずはテスト項目を明確にします。

|役割|人数| 
|:--------|------:|
| PM |1人 |
| 開発 |2人 |
| テスト |3人 |　
|計| 6人|

#### 1. サーバ構成図を起こす

初見のサイトに関してRPサーバのnginx、アプリケーションサーバのApacheのconfをひたすらおいながら、構成を理解しました。

サーバ構成図を書いた際のポイントは2点

     ポイント1 
       Rewriteを隈なく洗い出す
       → テストを網羅するためにRewriteのパターンをあらかじめ洗い出す

     ポイント2
       SSL化する対象のDocumentRoot、データベースを明確にしておく
       → httpをhttpsに置換するスコープを明確にする

#### 2. マスタースケジュールを作成

次に上申をするためにマスタースケジュールとなるWBSを作成しました。
WBSを要約すると計画、実施、検証のフェーズに分けました。

|工程|内容|人日| 
|:--------|----|------:|
| 計画、準備 |スコープや実施するまでの準備|35人日 |
| 実施 |スクリプト作成、精度向上|23人日 |
| 検証 ||50人日 |
|合計| |108人日|

検証については、mixed-contents-scanを使いつつ、
大きな改修になるので検証は人数をかけて調査していきます。

#### 3. httpsを検証できるステージングサーバを構築

本番、テストステージング環境を用意し、httpsでアクセスできるように検証環境を構築します。
ここでプログラムを書きながらmixed-contentsを潰していきます。

#### 4. オンプレミスにあるコンテンツをGit管理

オンプレにあるコンテンツをGit管理する上で問題となる点が大きく2点ありました。

```
1. オンプレのコンテンツサーバはセキュリティ上、外部ネットワークに接続できない構成である点
→　外部ネットワークに接続できる中継サーバを用意する必要性がある。

2. テスト、本番サーバのコンテンツが分散管理されてしまっている点
→　テストと本番でファイル数、内容に差分がある。

```

そこで

```
Azure DevOpsからアクセスできるストレージにマウント環境を構築
→ DevOpsのプロジェクトに登録し、対象をpush(15万ファイルほど。。)
→ デイリーの差分を吸収する仕掛けをjenkinsで実装(git addして、ブランチにpushするだけ)
→ ローカル環境で一括置換スクリプトで実行
(図の2～5)
```

# 実施フェーズ

#### 1. 一括置換できるようにローカル環境を整備

ローカルPCに以下をインストール

* [git bash](https://gitforwindows.org/)
* [mixed-content-scan](https://github.com/bramus/mixed-content-scan)

#### 2. httpからhttpsに切り替えるパターンの抽出

今回はドメイン単位でhttps対応可否(curlアクセスのレスポンス)を確認し置換スクリプトを作成しました。
置換スクリプトの詳細については別記事にしたいと思います。

# 検証フェーズ

#### mixed-contents、テスト仕様書を使った検証

今回はmixed-conents-scanとテスト仕様書を兼用して
テスト⇔スクリプト修正を繰り返し品質をあげました。

テストは開発、テスト担当含め5名ほど、2週間弱で完了。

#### はまりどころ

サーバ間通信していた箇所でAPIが呼び出せない問題が発生。
TLS1.2に対応するためには、以下がバージョンへの対応が必要です。

```
TLS1.2に対応に必要なバージョン
・curlバージョン　7.34.0以上
・OpenSSLバージョン　1.0.1以上
```

該当サーバはとても古く対応していない。。

```
該当サーバ
・curlのバージョン　  7.15.5
・OpenSSLバージョン 0.9.8b
```

暫定対応としてAPIはhttpのまま、サーバのリダイレクト解除で回避。
バージョンアップしないと。。汗


# 本番切り替え

#### タイムスケジュール作成

今回の切り替え方法だとサーバ設定変更と同時にプログラムの修正が必要なため、
綿密にタイムスケジュールを作成し、インフラ担当と打ち合わを実施。

#### 切替リハーサル

あらかじめリハーサルをしておくと安心です。
切り替え方次第でダウンタイム等、サービス側への影響は最小にとどめることができます。

#### 切り替え

リハーサルのおかげでタイムスケジュール通り、問題なく切り替え完了。

今思えば、DNS切り替えで対応できるともっと楽だったかな。

# まとめ

今回はPMとして10年以上前から運用されているサービスのAOSSL化プロジェクトにかかわりました。
一括置換スクリプトの精度が重要なので別途記事にしたいと思います。
AOSSL移行計画を練る上でポイントとなる点をまとめておきます。

```
・現状のサーバ構成を正しく理解すること
　コレに尽きます。初見であればなおさら。

・SSLを検証できるサーバの構築、調達をすること
　事前検証できるサーバを調達できたので、とても効率よく対応できました。

・検証は効率的に、主要機能のテストは綿密にすること
　mixed-contents-scanを使い検証しましたが、主要な機能部分はやはり人の手で確認したほうが早いです。
　テストコードはないので早めにリソース確保しましょう。

・切替えのタイムスケジュールを作成し関係者と協議しておく
　切替え対応は手順を間違えるとダウンタイムにつながります、事前に関係者の認識合わせをしておくとよいでしょう。
```

# 追記

```
切り替え方法として
マウントしているフォルダをリネームしてリリースしたがプロセスが残り切り替わらないので
アプリケーションサーバのリスタートが必要。もしくはマウント先自体を切り替えるとよい。
```