自分でもGoogle Cloud Platformの無料枠でサーバを建ててみた。

やむにやまれぬ事情から個人用の公開サーバを建てたくて調べたところ、どうやらGoogle Cloud Platform(以降、GCP)のCompute Engineには

* f1-microインスタンス1台
    * リージョンは一部を除く北米のみ。
* HDD ３０GB
* 北米リージョンから外への通信量 1GB
    * 中国とオーストラリアへ通信は無料枠なし。

までなら無料で使用できるようです。

そして以下の記事がとても参考になったので自分もやってみました。

* [GCE の無料枠のサーバを立るときに、初見でハマりそうなところ](https://qiita.com/ndxbn/items/7ef0a96e409a5b5837bd)
    * 基本はこの記事に従えば大丈夫。
* [GCPの課金データ取得のススメ](https://qiita.com/hnw/items/409d6b7c431ca5f74eb2)
    * 課金されると怖いので。上記でも最初に設定するように言及されている。
* [無料で最強のクラウドノート環境を手に入れる](https://qiita.com/techneconn/items/bc75cbd8b9af56ac30b0)
    * 無料枠だとメモリが0.6GBと貧弱だけどスワップを作成すればなんとかなりそうと希望が持てた。

この記事は、その時の作業の備忘録として記載しています。

## 課金データ取得の設定
実際にはVMインスタンスの作成後に行いましたが、GCPの利用を開始したら最初に行うべきという意味で、最初に記載します。

### Cloud Storageの作成
1. Google Cloud Platform画面右上の[ナビゲーション メニュー]から[Storage]→[ブラウザ]をクリック。
2. 画面上の[バケットを作成]をクリック。
3. [バケットに名前を付ける]で名前を入力し、[続行]ボタンをクリック。
4. [データの保存場所の選択]で、[ロケーションタイプ]にRegionをチェックし、[続行]ボタンをクリック。
5. [データのデフォルトのストレージクラスを選択する]で、Standardのまま、[続行]ボタンをクリック。
6. [オブジェクトへのアクセスを制御する方法を選択する]で、きめ細かい管理のまま、[続行]ボタンをクリック。
7. [作成]ボタンをクリック。

### 課金データのエクスポート
1. Google Cloud Platform画面右上の[ナビゲーション メニュー]から[お支払い]→[課金データのエクスポート]をクリック。
2. 課金データのエクスポート画面で[ファイルのエクスポート]をクリック。
3. バケット名に、上記Cloud Storageで作成したバケット名を入力。
4. レポート接頭辞として任意の名前を入力。ここでは元ネタと同じbilling-reportとした。
5. [形式]として、やはり元ネタと同じCSVのまま。
6. [保存]ボタンをクリック。

### 課金データを確認
1. 翌日とかに再びGoogle Cloud Platform画面右上の[ナビゲーション メニュー]から[Storage]→[ブラウザ]をクリック。
2. バケットの一覧から、エクスポート先のバケットの名前をクリック。
3. バケットの詳細画面で、billing-report-yyyy-MM-dd.csvのようなファイルができている。
    * ファイルサイズは１２９Bで、中身を見るとヘッダ行だけだった。とりあえず課金が発生していないか、１２９Bを超えてないかでチェックしておけば良さそう。

## VMインスタンスの構築
### VMインスタンスの作成

1. Google Cloud Platform画面右上の[ナビゲーション メニュー]から[Compute Engine]→[VMインスタンス]をクリック。
2. 画面上の[インスタンスを作成]をクリック。
3. [マシンの構成]で[汎用]の[シリーズ]にN1、[マシンタイプ]にf1-microを選択。
    * 初期画面でE2が選択されており、f1-microや、f1みたいなそれらしいシリーズが見つからず、戸惑いました。  
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/3625b3c1-6632-7e83-9bc8-eaae16981bee.png)
4. [ブートディスク]で[変更]ボタンをクリックし、希望のOSを選択。
    * 今回はCentOS 8で、無料枠上限の30GBにしました。  
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/e94aef12-00b0-2dff-bdfa-d6daf2c17f70.png)
5. [ファイアウォール]で、[HTTP トラフィックを許可する]と[HTTPS トラフィックを許可する]をチェック。
    * HTTPは、Let's Encryptで証明書を作成するため。
6. [管理、セキュリティ、ディスク、ネットワーキング、単一テナンシー]を開き、[ネットワーキング]の[ネットワーク インターフェース]をクリック。  
   [外部IP]で[IPアドレスを作成]を選択すると[新しい静的IPアドレスの予約]ダイアログが表示されるので、適切な名前を入力して[予約]。  
   そして[完了]ボタンをクリック。
    * DNSに登録したいため静的IPアドレスを作成。
    * [新しい静的IPアドレスの予約]で入力した名前や、[ネットワーク階層サービス]での選択の違いが、どんな結果になるかは、まだ理解してないです。  
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/e3fe4380-d5e2-c596-5be4-08a63fc4ea4c.png)
7. [作成]ボタンをクリック。

### SSH認証鍵の登録

VMインスタンスの作成前にって話もあったのですが、作成後でも大丈夫でした。

1. 自前のCentOS環境で```ssh-keygen -t ed25519```を実行し、生成された公開鍵ファイル(拡張子が.pubの方)の中身をクリップボードにコピー。
    * 鍵は、強固で早いという話なので、ed25519にしました。
    * 公開鍵にはssh-keygenを実行した時のユーザ名が含まれている。
2. Google Cloud Platform画面右上の[ナビゲーション メニュー]から[Compute Engine]→[メタデータ]をクリック。
3. メタデータ画面で[SSH認証鍵]をクリック。
4. [SSH認証鍵を追加]ボタンをクリック。
    * これはSSH認証鍵が未登録の時のみの操作。
5. [公開SSH認証鍵を入力]の欄へクリップボードからペースト。
    * そうすると左側にssh-keygenを実行した時のユーザ名が表示される。
6. [保存]ボタンをクリック。

### VMインスタンスへログイン

```bash
ssh -i 【秘密鍵ファイルへのパス】 【ユーザ名】@【VMインスタンスの外部IPアドレス】
```

### SSHポートの変更

SSHのデフォルトポート番号(22)は常に攻撃を受ける可能性があるので、ログインしたら最初にポート番号の変更を行います。

#### 変更先ポートを開放する
1. Google Cloud Platform画面右上の[ナビゲーション メニュー]から[VCPネットワーク]→[ファイアウォール]をクリック。
2. ファイアウォール画面で[ファイアウォール ルールを作成]をクリック。
3. [名前]に、ルール名を入力。
4. [ターゲットタグ]に、このルールの対象となるインスタンスに付けるタグ名を入力。
    * 今回の使い方は無料で済ますため、インスタンスは1台だけなので、[ターゲット]を[ネットワーク上の全てのインスタンス]で良かったかも。
5. [ソースIPの範囲]だけど、使い勝手の問題もあるので、0.0.0.0/0を入力。
    * 日本国内のIPアドレスだけに制限とか、簡単にできると良いのだけど、、、
6. [tcp]をチェックし、変更先のポート番号を入力。  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/9ec0c1ad-2d15-7ac4-b3b2-0ed782765b4b.png)
7. [作成]ボタンをクリック。
8. Google Cloud Platform画面右上の[ナビゲーション メニュー]から[Compute Engine]→[VMインスタンス]をクリック。
9. VMインスタンス画面で、作成したインスタンスの名前をクリック。
10. VMインスタンスの詳細画面で、[編集]をクリック。
11. [ネットワークタグ]に、作成したファイアウォール ルールのターゲットタグ名を入力。
12. [保存]ボタンをクリック 

#### sshdのポート番号を変更
1. ```sudo vim /etc/ssh/sshd_config```で設定ファイルを開き、下記のように変更先ポート番号を設定して保存。

    ```
    #Port 22
    Port 22222              ←追記
    #AddressFamily any
    #ListenAddress 0.0.0.0
    #ListenAddress ::
    ```

2. SELinuxに、変更先ポートをsshで使用することを定義。
   その前にsemanageコマンドが無いので、policycoreutils-python-utilsパッケージをインストール。

    ```bash
    sudo dnf install -y policycoreutils-python-utils
    sudo semanage port -a -t ssh_port_t -p tcp 22222
    ```
3. 変更を反映。

    ```bash
    sudo systemctl restart sshd
    ```
    * restartじゃなくてreloadでも良かったみたい。
    * これで22ポートでListenされなくなる。


4. 安全のため現在のターミナル接続は残したまま、ログインできるのを確認する。

    ```bash
    ssh -i 【秘密鍵ファイルへのパス】 -p 22222 【ユーザ名】@【VMインスタンスの外部IPアドレス】
    ```

### SWAP領域の追加

メモリが0.6GBなのにSWAP領域がないので追加する。

```bash
              total        used        free      shared  buff/cache   available
Mem:            572          54         268          10         249         207
Swap:             0           0           0
$ sudo fallocate -l 2G /swapfile
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
$ sudo sh -c 'echo "/swapfile none swap sw 0 0" >> /etc/fstab'
$ free -m
              total        used        free      shared  buff/cache   available
Mem:            572          54         268          10         249         207
Swap:          2047           0        2047
```

### nginxのインストール
```bash
$ sudo dnf install nginx
$ sudo systemctl start nginx
$ sudo systemctl enable nginx
```

### Let's Encryptで証明書を発行

[この記事](https://qiita.com/megasys1968/items/90c74aa84590f6c96919)を書いた後、[certbotのドキュメント](https://certbot.eff.org/lets-encrypt/centosrhel8-nginx)を見たら、certbotのインストールにはsnapというパッケージマネージャが必要になったんですね。

で、この記事と同じdynuでドメインを登録。

```bash
$ sudo dnf install epel-release
$ sudo dnf upgrade
$ sudo yum install snapd
$ sudo systemctl enable --now snapd.socket
$ sudo ln -s /var/lib/snapd/snap /snap

$ sudo snap install core; sudo snap refresh core
$ sudo snap install core
$ sudo snap refresh core
$ sudo dnf remove certbot
$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
$ sudo certbot --nginx
```

* ```dnf search certbot```したらcertbotは見つかるけどバージョンが１つ前の１．９．０だった。

これでnginxにhttpsで接続できるようになりました。

## 課題
ただのHTMLページを表示するだけなら問題はなかったし、詳しい説明は省くけどpgadminを動かしてnginxからリバースプロキシでアクセスできるようにした時も問題ありませんでした。
しかし、pgadminと同様にmattermostを動かして、リバースプロキシでアクセスすると以下のような警告がChromeで表示される人がいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/7cbfbe3d-513f-255c-da81-e5ee3943934d.png)

この表示がでない人もいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387890/37c8ad7d-fb46-f6c7-88cd-e653a03ec0b4.png)

このあたり、ちょっとスッキリしません。。。
何か判ったら追記したいと思います。