GCPで実現するBeyondCorp RemoteAccess

# 本記事

:ok: GCPのリソース
:ng: ゼロトラストネットワークの概念および説明

# BeyondCorp Remote Access

[BeyondCorp - 企業セキュリティに対する新しいアプローチ](https://cloud.google.com/beyondcorp) に
Googleが提唱している [ゼロトラストネットワーク](https://cybersecurity-jp.com/security-measures/33227) の実現方法の一つです。

# 検証環境

* [Google Workspace](https://workspace.google.co.jp/) アカウント ※2020.10にG Suite からブランド名変更
    * [Google Domain](https://domains.google/) でドメイン取得
          * [お名前.com](https://www.onamae.com/)や[Amazon Route53](https://aws.amazon.com/jp/route53/) あるいは自作など外部向けDNSサーバがあればよいです（後々でAレコード追加するため）
    * [Google Cloud Platform](https://console.cloud.google.com/)で、プロジェクトの管理者権限
* [WatchGuard社FireBox T-15w](https://www.watchguard.co.jp/products/network-security-appliances/firebox-t15)
    * [AWSとWatchGuard製FireBoxのVPN接続](https://qiita.com/mid480/items/9b87d1119e62e6d8a9bd)

# 検証のゴール

* Fireboxのログイン画面をインターネット経由でアクセスする
    * アクセス元が`Any-Trusted`のみ許可のためインターネットからは本来アクセスできない設定

# システム構成

# 設定

## CloudVPN

別途掲載しているので省略します。
 [GCPとWatchGuard製FireBoxのVPN接続](https://qiita.com/mid480/items/40cf8e082b9cbfec58f3)

### GCP側の設定

以下。

### On-prem側の設定

不要。GCPとのVPN接続しているため。

## GAE

* 利用したコマンド各種
    * `npm init` で入力した内容は追加で一部あり
    * 参考にある `runtime:nodejs8` は2020年10月18日でサポート対象外のため、 `runtime:nodejs10`へ変更

```
mkdir gae-proxy
cd gae-proxy/
npm init
npm install http --save
npm install http-proxy --save
vi app.yaml
vi index.js
vi package.json
cat package.json
ls -l
gcloud app deploy
```

参考： [GAE Standard環境のNode.jsでリバースプロキシ構築](https://www.kwonline.org/memo2/2019/02/22/reverse-proxy-on-gae-standard-nodejs/)

### ReverseProxy

* app.yaml

```
runtime: nodejs10
```

* index.js

```
const http = require('http');
const httpProxy = require('http-proxy');
const port = process.env.PORT || 8080;
httpProxy.createProxyServer({target: 'http://192.168.***.***:8080/'}).listen(port);
```

* package.json

```
{
  "name": "gae-proxy",
  "version": "1.0.0",
  "description": "proxy",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "Unknown",
  "license": "MIT",
  "dependencies": {
    "http": "0.0.1-security",
    "http-proxy": "^1.18.1"
  }
}
```

## IAP

### IAPの作成

#### OAuth同意画面

* ユーザの種類
    * 内部 ... Google Workspace(G Suite)のユーザのみ
    * 外部 ... Googleアカウント全員

![008_IAP_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/37c5a3a3-4907-17a7-430f-339c15256884.png)

* 画面に表示する項目
    * アプリ名 ... 画面に表示する
    * ユーザサポートメール ... 外部公開してもよい問い合わせ先メールアドレス（Google グループでサポート用グループメールアドレス発行を推奨）
    * デベロッパーの連絡先情報 ... なにか問題があったときの連絡先

![009_IAP_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/86fdbef2-cd74-308e-b95d-8881bfc1e2f8.png)

### 認証ユーザの設定

* IAPで認証するユーザの設定

![012_IAP_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/b0c1edb5-ca80-f1a2-6d75-e4ff7478154c.png)

* IAPの有効化前確認

![013_IAP_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/eefef54b-a509-d46c-732c-2a137f5cd882.png)

画面中央の `IAP` を有効化するとIAPの保護対象となる

## Access Context Manager

## 設定ユーザへの権限設定

* プロジェクト内部の権限ではなく組織全体の権限適用
    * ●が３つなのは、プロジェクト（リソース管理グループ）を表す
        * 不要になったらプロジェクト毎、削除（シャットダウン）することで課金制御が可能
    * 🏢が組織を表す
        * 組織全体の権限を制御するときはこちらで制御しなければならない
 
**ハマるポイント** 
プロジェクト内で権限を付与したからといって、
組織全体に関わるリソース（Access Context Manager）に対して、
アクセス権限を与えたことにならない。

![014_IAP_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/d90b543d-577d-d1d1-c3ae-1b65d818a8c3.png)

画面上部が必ず組織全体のアイコンになっていることを確認しアクセス権限を付与すること

![015_IAP_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/ffc46976-cc93-9fae-8dbe-166434676a0b.png)

そこで初めてAccess Context Managerへのアクセスが可能となる

![016_IAP_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/7dedd43a-a00b-c91a-967e-7a0e7976bb5d.png)

### 認証可能なデバイスの設定

#### 全体

* 条件を作成
    * 基本モード ... GUIで設定
    * 詳細モード ... JSONといったコードベースで設定

![017_ACL_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/1ed3fd3c-36aa-9fc9-e4ba-d3f48c317eda.png)

#### リージョン（アクセス元の国）

`JP` で日本を絞り込み検索するとよい

![018_ACL_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/c018373b-48b0-85db-a39a-c847aed82024.png)

#### OSのポリシー

バージョン指定は数値設定となるため、
制御で細かい設定が可能な一方メンテナンスコストが高くなるため、
バージョン指定は可能な限り設定しないことを推奨。

![019_ACL_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/93c4a66e-b86a-db66-7ec6-f0de06cab2e2.png)

#### サンプルポリシー

![020_ACL_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/7e55cd82-32fc-08cc-ca7c-35ae07258b55.png)

## ここまで設定したものの...

### GAEでカスタムドメインの利用が可能

* サンプルで作成した環境の場合、Google Domainでドメインを取得しているため親和性が高い
* 外部のドメイン事業者で取得している場合は、DNSレコードの変更が必要

![021_GAE_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182636/4989ffb5-2dcd-5d6f-1be0-2ae70e6deb67.png)

### Google マネージド証明書

Googleが提供するSSL証明書が **無料** で利用可能な模様。

> 使用されるSSL証明書の発行元が「Let’s Encrypt」

とあるので、利用するユーザが嫌わなければこちらの採用も無料で検討してよいのではないかと考えるようになりました。
ただ、発行のリクエストから最大で48時間掛かるともあるので、導入までのリードタイムは考えないといけないです。

参考：
[Google マネージド SSL 証明書の使用](https://cloud.google.com/load-balancing/docs/ssl-certificates/google-managed-certs?hl=ja)
 [GCPで無料HTTPS化｛Compute Engine編｝](https://www.apps-gcp.com/gcpで無料https化｛compute-engine編｝/)

# まとめ

IAPはHTTPS前提であり初期検証を行っていた構成は
そもそもHTTPのバックエンドに投げる構成ではなダメ。
また、Google公式ドキュメントを読み込んでいく中で、
自然と頭の中でオンプレミスにあるリソースへのアクセスを前提としていたので、
IAP Connector（GKE）を利用する前提かと思っていたが、
リバースプロキシをGCP内に置くとなると、ライトな構成になっていく印象を受けた。

[IAP による App Engine アプリの保護](https://cloud.google.com/context-aware-access/docs/securing-app-engine?hl=ja)
[IAP でオンプレミス アプリとリソースを保護する](https://cloud.google.com/context-aware-access/docs/securing-on-premises?hl=ja)

## 1.NGパターン

```
Client (person) -[HTTPS]→ Internet -[HTTPS]→ IAP Connector -[HTTP]→ (CloudVPN) → On-Prem Server
```

## 2.On-Premに置くことを前提

```
Client (person) -[HTTPS]→ Internet -[HTTPS]→ IAP Connector -[HTTPS]→ (CloudVPN) -[HTTPS]→ Reverse Proxy -[HTTP]-> On-Prem Server
```

## 3.On-Premに置くことを前提

```
Client (person) -[HTTPS]→ Internet -[HTTPS]→ IAP Connector -[HTTPS]→ (CloudVPN) -[HTTPS]→ Reverse Proxy -[HTTP]-> On-Prem Server
```

1,2,3 で共通していたことは、IAP ConnectorがGKEで動くPodであることが運用課題だった。
ここに来て検証をすすめる中でGAE自体をReverse Proxyとする場合に、GKEを使う必要がなくなったように見える。

## 4.GAEをカスタムドメイン + Google マネージド証明書 でReverseProxyとする前提

```
Client (person) -[HTTPS]→ Internet -[HTTPS]→ GAE -[HTTP]→  (CloudVPN) -[HTTP]-> On-Prem Server
```