VPSにUbuntuをインストールし、ApacheにてCloudflareを用いてSSLをフル(厳密)に設定

:::note warn
この記事は素人随筆です。特にセキュリティ関係は基本情報技術者程度の知識しかありません。
VPSのセキュリティ対策はrootログイン無効化・ファイアウォールの設定・公開鍵認証の導入・パスワードログイン無効化・ポート変更のみ扱います。
:::

この記事の後半はドメインをCloudflareのネームサーバーで運用している（運用する）方をターゲットに随筆しています。前半はドメイン関係なく進められます。

#VPSを借りる
##おすすめサーバー
各自でサーバーを用意している方はスキップして大丈夫です。
この記事ではUbuntu20.04を使用します。

私は学生なので、とりあえず安いサーバーを借りることにしました。
私はContainer-VPSのC4プラン(月額228円)を借りました。

https://twitter.com/yuu1111main/status/1457560954791628801


<dl>
<dt>CPU</dt>
<dd>1vCPU</dd>
<dt>メモリ</dt>
<dd>4GB</dd>
<dt>ストレージ</dt>
<dd>40GB</dd>
<dt>帯域</dt>
<dd>100Mbps<dd>
<dt>通信量<dt>
<dd>4TB/月(超過時には帯域が10Mbpsに制限)</dd>
</dl>

:::note info
50%セール時に1年契約のため月額228円ですが、セールしていなくても月額456円と格安です。
:::

:::note alert
ヨーロッパのサーバなので、SSHにて文字を打つときにそこそこラグがあります。
その点がデメリットです。また、ゲームサーバーとして日本からアクセスするのも向いていません。
:::

##Ubuntuのインストール(Time4VPSの場合)
ダッシュボードでServicesから自分のサーバーを選択し、購入したサーバを選択、InstallOSを選び、次のように選択します。
<img alt="img" width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/a03281fd-bac7-7640-68da-1d21bd651ed2.png">

下記の画像のような表示が出たら成功です。
<img alt="img" width="600px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/806db8ea-8c95-bb60-29d1-f7a786c697a4.png">
ここのIP、Passwordについては後程利用するので、安全な場所に保管しておいてください。

:::note
忘れてしまっても、メニューのLogin Detailsから確認できます。
:::

###サーバーにアクセスできるか確認
RLoginを利用します。

https://github.com/kmiya-culti/RLogin/releases/

インストールが完了したら、新規を押して次の内容を入力します。

<dl>
<dt>エントリー(上)</dt>
<dd>root(22)</dd>
<dt>IP</dt>
<dd>先ほどのIPアドレス</dd>
<dt>ログインユーザー名</dt>
<dd>root</dd>
<dt>パスワードorパスフレーズ</dt>
<dd>先ほど保管したパスワード</dd>
</dl>
入力が完了したらOKを押して、追加されたものをダブルクリックして接続します。
このホストの公開鍵を信頼して接続しますか？と聞かれたら、接続するをクリックします。
信頼するホスト鍵のリストを更新しますか？と聞かれたらはいをクリックします。

```text
Welcome to Ubuntu 20.04(以下省略 
```
と出てきたらOSのインストールは終了です。お疲れ様でした。

#サーバーのセットアップ
##アップデート

:::note info
ちなみに、コピーやペーストは右クリックで行うことができます。
:::
まずはパッケージリストを更新します。

```shell-session
 # sudo apt update
Get: 1(省略
少し時間がかかります。
125 packages can be upgraded.(省略
```
次に、アップデートを行います

```shell-session
 # sudo apt dist-upgrade
Reading package lists...(省略

Do you want to continue?[Y/n]  ←この表示が出たらYを押してエンターを押す。
少し時間がかかります。

*** resolved.conf (Y/I/N/O/D/Z) [default=N] ? ←この表示もY。
```
##SSHポートの変更
:::note
ポートはマンションの中の部屋番号のようなものです。
デフォルトでは22になっているので、攻撃者は22を主な攻撃対象とします。
ですので、22以外のポートに変更して攻撃されるリスクを下げます。
:::
```shell-session
 # sudo vi /etc/ssh/sshd_config
```
と入力すると、

```shell-session
#       $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
(省略)
# possible, but leave them commented.  Uncommented options override the
# default value.

Include /etc/ssh/sshd_config.d/*.conf

#Port 22
#AddressFamily any
```
と表示されるので、キーボードの矢印を利用して__#Port 22__のところまで移動します。
そしたらキーボードのAを押してINSERTモードに変更します。（左下にINSERTと表示されます。）

:::note
※うまく動かない場合は<a href="https://qiita.com/tommy_g/items/3ad4b26ccb4893f2760e">こちら</a>を参考にvimというエディタをインストールしてください。インストールが完了したらコマンドのviをvimに置き換えて本記事の通りにやってみましょう。
:::
__#Port 22__の#を削除し、22を1024～65535の間の値に変更します。
入力例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/3d7e5c81-6869-3453-8112-66601b3d285f.png)

:::note info
ただし、このポートは49152～65535の間に設定することが推奨します。
:::

https://www.nic.ad.jp/ja/basics/terms/port-number.html

:::note alert
変更後の数字は必ず覚えてください。忘れてしまうとコンソールにアクセスするのが難しくなります。
:::
変更が終了したら、__Esc__→__：__の順に押し、:wqと入力してEnterを押します。

終了したら、次のように入力して変更を適用します。

```shell-session
 # sudo systemctl restart sshd
```
完了したら一度切断し、接続を押してから、先ほど追加したものを選択してから編集をクリック、TCPポートを先ほど設定したものにしてアクセスできるか確認してください。
エントリー(上)の数字も一緒に変更しておくと分かりやすいです

黄色のところで接続・切断ができます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/6e2f6f71-19af-91aa-fce7-c667f06cdc52.png)


<img alt="img" width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/da515083-b311-cd46-7838-a752e0d6f04f.png">
無事に黒い画面が表示されたらポート変更は完了です。お疲れさまでした。

##ファイアウォールのインストール
:::note info
ファイアウォールは直訳すると防火壁という意味になり、ITの世界ではアクセス制御をすることができます。設定することで攻撃されるリスクを下げます。
:::
```shell-session
インストール
 # sudo apt-get install ufw

ファイアウォールを念のため無効化する
 # sudo ufw disable

全てのポートを閉じる
 # sudo ufw default deny

SSHポートを開放する
 # sudo ufw allow (先ほど設定したファイアウォールのポート番号)/tcp
（↓入力例）
 # sudo ufw allow 61234/tcp

HTTP・HTTPSポートを開放する
 # sudo ufw allow 80/tcp
 # sudo ufw allow 443/tcp

ファイアウォールを有効にする
 # sudo ufw enable

Command may disrupt existing ssh connections. Proceed with operation (y|n)? ←yと入力してEnter

設定を読み込む
 # sudo ufw reload
```
完了したら、RLoginで切断して、再度接続できるか確認してください。
#rootユーザーの無効化
:::note info
ポートについてマンションに例えてお話ししましたが、rootユーザーとはマンションの大家だと思ってください。すべての権限がある大家さんの入室を禁止することで、攻撃リスクを下げます。（権限が必要な場合は都度権限を取得します。）
:::
##ユーザーを作成
###ユーザーを追加
ユーザーの追加にあたって、ユーザー名とパスワードを決めておいてください。

:::note warn
ユーザー名に大文字は利用できません。
:::

```shell-session
 # adduser ユーザー名
(入力例)
 # adduser miyayu
Adding user `miyayu' ...
(省略)
Copying files from `/etc/skel' ...
New password: ←パスワードを入力
Retype new password: ←パスワードを再入力
(省略)
Full Name[]: ←何も入れずにエンター Otherまで同じように続ける
Other[]: 
Is the information correct? [Y/n] ←yと入力
```
###権限を与える
次のように入力します

```shell-session
 # gpasswd -a ユーザー名 sudo 
 入力例)
 # gpasswd -a miyayu sudo
```

###追加したユーザーの権限があるか検証
一度RLoginを終了し、追加したユーザとパスワードでログインできるか確認します

:::note info
ユーザーを追加しましょう。
エントリー・ホスト・ログインユーザー名・パスワード・TCPポートを入力します
:::
次のコマンドを入力します。

```shell-session
 $ sudo su -
[sudo] password for ユーザー名: ←追加したユーザのパスワードを入力
 root@****:~# ←このように表示されたら検証は成功です。
```
##rootログインを無効化する
```shell-session 
 $ sudo vi /etc/ssh/sshd_config
 # もしここでパスワード入力を求められたら入力してください。
```
__PermitRootLogin yes__まで移動します。Aを押してINSERTモードにして、yesをNoに変更します

```shell-session:書き換えた後
PermitRootLogin no
```
__Esc__→__：__の後に__wq__で保存します。次のコマンドを実行してください

```shell-session
 $ sudo systemctl restart ssh
```
完了したら、RLoginを終了し、rootアカウントでログインしてみてください。ログインに失敗したら成功です。（日本語が変ですね。）
rootアカウントはRLogin上から削除してかまいません。
#公開鍵認証
##鍵を作成する
パスフレーズ（パスワード）のようなものを考えて置き、安全な場所に保管してください。

:::note info
アカウントのパスワードとパスフレーズは別のものです。混同しないようにしましょう
:::
Windowsのコマンドプロンプトを開き、次のように入力します

```shell-session
> ssh-keygen.exe -t rsa
```
3か所ほど入力を求められるので入力します。

```shell-session:出力
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\UserName/.ssh/id_rsa):　←そのままEnter
Created directory 'C:\Users\UserName/.ssh'.
Enter passphrase (empty for no passphrase): ←パスフレーズを入力
Enter same passphrase again: ←パスフレーズを入力
Your identification has been saved in C:\Users\UserName/.ssh/id_rsa.
Your public key has been saved in C:\Users\UserName/.ssh/id_rsa.pub.
The key fingerprint is:
略
The key's randomart image is:
+---[RSA 3072]----+
略
+----[SHA256]-----+
```
##鍵を転送する
Windows上で作成した公開鍵をVPS上にアップロードします。
コマンドプロンプトで次を入力します。

```shell-session
コマンドプロンプトで入力します
> cd %homepath%
> scp -P SSHのポート番号 ./.ssh/id_rsa.pub ユーザー名@VPSのIP:~/
入力例
> scp -P 61234 ./.ssh/id_rsa.pub miyayu@222.222.222.222:~/

入力を求められる場合
Are you sure you want to continue connecting (yes/no/[fingerprint])? ←Yesと入力する
UserName@222.222.222.222's password: ←作成したユーザーのパスワードを入力

このように表示されたら成功
id_rsa.pub  100%  577     1.8KB/s   00:00
```
##鍵を利用できるようにする
RLoginでVPSにアクセスします。
ディレクトリを作成します。

```shell-session
 $ mkdir ~/.ssh
```
作成したディレクトリに鍵を移動します。

```shell-session
 $ mv ~/id_rsa.pub ~/.ssh/authorized_keys
```
パーミッションを変更します。

```shell-session
 $ chmod 600 ~/.ssh/authorized_keys
```
###鍵を変換する

###正常に設定されたか確認する
RLoginを開き直し、接続先の新規画面を開きます。いままで通り入力しますが、パスワードは次の指示に従って入力してください。
パスワードorパスフレーズのところにパス__フレーズ__を入力し、SSH認証鍵をクリックして、__C:\Users\ユーザー名\.ssh\id_rsa__を開きます。
隠しフォルダを表示する設定にしていないとアクセスできないかもしれないので、見つからない方は表示方法を調べてみてください。

:::note info
エントリー・ホスト名・TCPポート・ログインユーザー名・パスフレーズ・SSH認証鍵を設定します
:::
設定が完了したらダブルクリックで接続し、コンソールが開けば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/df3ea9de-fb62-6015-915e-71c683a6b2bd.png)
##パスワードでのログインを無効化する
コンソールで次のように入力します

```shell-session
 $ sudo vi /etc/ssh/sshd_config
```
そしたら次の場所を探し、Aを押してINSERTモードにして次のように変更します。

```shell-session
変更前
#PasswordAuthentication yes

変更後
PasswordAuthentication no
```
完了したらEsc→:wqで閉じましょう
### sshを再読み込みする
次のコマンドを入力する

```shell-session
 $ sudo systemctl restart ssh
```
### パスワードでアクセスできないようになっているか確認する
RLoginでパスワードログインができないかどうか確認しましょう。(SSH認証鍵を設定していないほうのアカウント)
ログインできなかった場合、成功です。そのアカウントは削除しても大丈夫です。
#Apacheのインストール
さて、ここまでやってきてようやくサーバーの設定が完了しました。
今度はApache(Webサーバーのソフトウェア)をインストールしていきます。
次のコマンドを入力しましょう

```shell-session
 $ sudo apt install apache2

Do you want to continue?[Y/n] ← Yと入力してエンター
```
Apacheのインストールが開始されます。
##確認！
インストールが完了したら、ChromeなどのブラウザでVPSのIPアドレスを入力しましょう。次のように表示されたらOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/009bf0f9-c894-b17a-ae47-ae1f4e9bf269.png)

Apacheのインストール編はこれにて終了です。お疲れ様でした。早いですね。
ちなみに、初期状態だとrootでないとhtmlなどを書き込めないので、こちらを参考に権限設定することをお勧めします。

https://qiita.com/yuu1111main/items/77976d7ece0ecfb35157

#CloudFlareのSSLを設定する
##DNSの設定
Cloudflareにてドメインを選択し、レコードの追加から手続きを行ってください。プロキシはONにしましょう。

##エッジ証明書の取得
こちらを参考にしました。

https://devanswers.co/configure-cloudflare-origin-ca-apache/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/b833f7f0-25fd-312e-23d7-9800a971a5e6.png)
CloudFlareにログイン後、自分のドメインを選択して上部の__SSL/TLS__を選択し、下部の__オリジンサーバー__を選択します。
__証明書を作成__をクリックして、画面の指示に従って作成します。
プライベートキーの種類はRSA(2048)、証明書の効力は15 yearsにします。
そして、キーフォーマットはPEM(Default)にします。
オリジン証明書とプライベートキーは必要になるので__必ずどこかにメモ__を取ってください。後から__再確認不可__です
###キーのコピー
RLoginでサーバーにアクセスして、次のように入力します

```shell-session
 $ sudo mkdir -p /etc/cloudflare/
```
そして、次のように入力してファイルを作成します。

```shell-session
 $ sudo vi /etc/cloudflare/ドメイン名.pem
入力例)
 $ sudo vi /etc/cloudflare/t4.miyayu.xyz.pem
```
そしたらメモしてあったオリジン証明書を貼り付けます。(---BEGIN から END CERTIFICATE---)までを貼り付けます。（最後に改行があったら消してください）
![スクリーンショット 2021-11-11 215248.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362835/fa092e49-0998-8698-9eb5-dd7282fdbcb1.png)
いつも通りEsc→:wqで保存します。※保存できないときは:wq!
次のように入力します。

```shell-session
 $ sudo vi /etc/cloudflare/ドメイン名.key
入力例）
 $ sudo vi /etc/cloudflare/t4.miyayu.xyz.key
```
そしたら先ほどと同じように、プライベートキーを貼り付け、保存します。※保存できないときは:wq!
###権限設定
次のように入力していきます。#の行はコメントですので入力しなくて大丈夫です

```shell-session
 $ cd /etc/
 # cloudflareフォルダの所有者をrootにする
 $ sudo chown -R root cloudflare
 $ cd cloudflare
 # ファイルの権限を変更
 $ sudo chown www-data ドメイン名.key
 $ sudo chmod 400 ドメイン名.key 
 $ sudo chmod 400 ドメイン名.pem 
```
##Apacheコンフィグの設定
まず、次の文章をメモ帳などにコピーして、必要な事項を入力します。

```conf
<VirtualHost *:80>

    ServerAdmin 管理者メールアドレス
    ServerName ドメイン
    ServerAlias www.ドメイン
    DocumentRoot /var/www/html/
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =example.com [OR]
    RewriteCond %{SERVER_NAME} =www.example.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

<VirtualHost *:443>

    ServerAdmin 管理者メールアドレス
    ServerName ドメイン
    ServerAlias www.ドメイン
    DocumentRoot /var/www/html/
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on
    SSLCertificateFile /etc/cloudflare/ドメイン.pem
    SSLCertificateKeyFile /etc/cloudflare/ドメイン.key

</VirtualHost>
```
入力例：

```conf
<VirtualHost *:80>

    ServerAdmin admin@t4.miyayu.xyz
    ServerName t4.miyayu.xyz
    ServerAlias www.t4.miyayu.xyz
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =t4.miyayu.xyz [OR]
    RewriteCond %{SERVER_NAME} =www.t4.miyayu.xyz
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>
<VirtualHost *:443>
    ServerAdmin admin@t4.miyayu.xyz
    ServerName t4.miyayu.xyz
    ServerAlias www.t4.miyayu.xyz
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on
    SSLCertificateFile /etc/cloudflare/t4.miyayu.xyz.pem
    SSLCertificateKeyFile /etc/cloudflare/t4.miyayu.xyz.key

</VirtualHost>
```
入力が完了したら、元々生成されていたファイルを削除します。
次のコマンドを入力します

```shell-session
 $ cd /etc/apache2/sites-available
 $ sudo rm -rf *
```

先ほどメモ帳などに移したものをサーバーに書き込みます。
次のコマンドを入力後、貼り付け、Esc→:wqで保存します

```shell-session
 $ sudo vi t4.miyayu.xyz.conf
```
###コンフィグを有効化する
次のようにコマンドを入力します。

```shell-session
 $ cd /etc/apache2/sites-available

 # 設定を反映
 $ sudo a2ensite ドメイン名.conf

 # SSLを有効化
 $ sudo a2enmod ssl

 # Rewriteを有効化
 $ sudo a2enmod rewrite

 # Apacheの再起動
 $ sudo systemctl restart apache2
```

###最終確認
Cloudflareに設定したドメインでサイトにアクセスし、無事にページが開けば成功です！！お疲れさまでした！！