はじめてのGCP

手伝いをしたのでとりあえず備忘禄を。書かないと忘れてしまうのです。

ものによるけどWEBコンソール画面でポチって設定するとCLIとRestのリンクが出現するのでエビデンス残しつつ再現性を確保するのに便利で親切なのかなと思いました。
あとマニュアルは親切に書いてあるのでよく読むとよさそう。

#### **・CloudDNS**
まずCloudDNSでドメインを取得（手動ポチポチ見て分かる感じだったので詳細は割愛）
参考：
https://qiita.com/NagaokaKenichi/items/95052742d40392f3215e
http://iga-ninja.hatenablog.com/entry/2015/01/24/171524

#### **・ネットワーク：VPCなど**

別にデフォルトでもよくてデフォルトだと既存のFWルールとかで事足りるならあんまり何もしなくてもいい感じではあったけど一応。
（AWSなどもデフォルトのNWじゃないとちょっと遅いとか噂にききましたが自分で測ったわけではない。。）

```
gcloud compute --project=$mypj networks create ${myvpc1} --description=${mypj}-${myvpc1} --mode=custom

gcloud compute --project=$mypj networks subnets create ${mypj}-subnet1 --network=${myvpc1} --region=${myregion} --range=10.0.0.0/22 --enable-private-ip-google-access
```

#### **・ファイアウォール**

ネットワークセキュリティグループ(AWSでいうACL）ってやつとVPCの中のメニューのファイアウォール（AWSだとSecurityGroup)というやつがあり、ファイアウォールについてはインスタンスごとに設定するものでhttpロードバランサには設定できず、httpロードバランサにはバックエンドサービスにたいしてネットワークセキュリティグループをかけられるがネットワークセキュリティグループで扱えるのはIPのみでTCPなどは扱うことができない、という特徴が。（AWSだとELBにもSecurityGroupの設定が可能で実質やりたい放題だけどもGroupじゃなくてサブネット指定のが早いし一つのオブジェクトに一つのルール割り当てがいいらしく複雑化しないように注意が要るかんじ。あとBigIPほど大量の送信元IPを登録できなくてnginx側で制限が要るみたいな話も）

また、一括で扱いたい場合にはNWタグというのをインスタンス（ホスト側）とルールに設定しておいて一致するものが制限の対象になるということに。共通なルールであればプロジェクト全部に効かせるのもできる。

defaultのsshのルールは全開なので制限したほうがいい。
defaultのルールはdefaultのVPCとサブネット用であるのでそれらを作ったならプロジェクト用に新たに作成する必要がある。

```
gcloud compute --project=$mypj firewall-rules create ${allow-company} --description=${allow-from-company-ssh-web} --direction=INGRESS --priority=1000 --network=${myvpc1} --action=ALLOW --rules=icmp,tcp:80,tcp:443,tcp:22 --source-ranges=${source-ip-range1},${source-ip-range2} --target-tags=web
```

あと準備中は全開にしない等の場合はロードバランサのヘルスチェックのIP開けないと
バックエンドサービスが無効なままバックンドのサーバにつながらないので注意。
https://cloud.google.com/compute/docs/load-balancing/health-checks?hl=ja

#### **・ComputeEngine**

参考：
https://qiita.com/kazunori279/items/c35cbc24c5b93df3ee6b

ssh鍵認証まわり
https://qiita.com/NewGyu/items/3a65e837519297951e79
https://cloud.google.com/compute/docs/ssh-in-browser?hl=ja
https://cloud.google.com/compute/docs/instances/connecting-to-instance#generatesshkeypair

いわゆるインスタンス・サーバ・IaaSみたいなの。GCPはインスタンスの起動が早いから使いたいというときに。
メタデータに鍵登録しとくと鍵認証をアカウントにしてくれたりとか。
各種公式イメージから普通に起動できます。
CloudShell（右上の[>_]こういうマークポチるとgcloudコマンドが使えるCUIコンソールが上がってくる）というやつで接続したり設定したり。
ただCloudShellで作った鍵はコピペがうまくいかなかったりするので違う方法で転送するとよさそう。

```
$ gcloud beta compute --project "$mypj" instances create "$mynode1" \
--zone "${myregion}-a" --machine-type "n1-standard-1" --subnet "$mysubnet1" \
--maintenance-policy "MIGRATE" \
--service-account "$myaccount" \
--scopes "https://www.googleapis.com/auth/datastore" \
--min-cpu-platform "Automatic" --tags "web" --image "centos-7-v20180314" --image-project "centos-cloud" \
--boot-disk-size "20" --boot-disk-type "pd-standard" --boot-disk-device-name "$mydisc1"
```

出来上がったインスタンスにログインするのにFWルールの制限について気にする必要があった。（defaultのNWじゃないのでSSHが全開ではなかった）
`wget -q -O - http://taruo.net/ip/?raw`で取れるローカルのGlobalIP値をtcp:22で許可してCloudShellから以下のコマンドでつないだ。

```
$ gcloud compute --project "$mypj" ssh --zone "${myregion}-a" "$mynode1"
```
これをするとインスタンスに自動でgmailでGCPに登録してコンソールログインしているのと同じ名前のOSアカウントがsudo権限つきで作成され鍵作成および鍵登録までされる。

CloudShellのIPはつなぐたびに変わるがそれをANSIWHOISで追って検索したところGCPのレンジは以下になるようだったのでここをSSH許可でdefaultの全開よりはまだマシと思われた

```
NetRange:       35.192.0.0 - 35.207.255.255
CIDR:           35.192.0.0/12
NetName:        GOOGLE-CLOUD
```

マシンイメージ取るときは止めるの推奨という警告がでてたが止めずにとることも可能ではあった（整合性が保証はされないやつだけどステートフルでないならいい気はする）。

####  **・httpロードバランサ**

3種類くらいあってhttp(s)ロードバランサ(L7、httpとhttpsのみ)とsslプロキシ(L7,TCPプロトコルがいくつかから選べる）とネットワークバランサ(L4)という感じでそれぞれ設定項目が違うようだった。
今回はhttp(s)ロードバランサにしました。

SSLポリシーの設定がベータで、min-tls-versionをTLS1.2にするとかも可能ではあった。（CLI設定のみ）

証明書登録してインスタンスグループ作ってインスタンス登録してバックエンドサービス作ってから
LB新規作成する感じでフロントエンドサービスとURLマップとかを設定するとなんかできる。
バックエンドサービスへは80番で到達するのでサーバ側に直に来ない場合は証明書登録が要らない。
（今回はpgadmin4が相乗りでサーバ側もSSLにした）

##### **・letsencrypt+clouddnsでワイルドカードかつSANな証明書をつくる**
なんかワイルドカードのはずが名前が一致しないエラーがでてSAN(ServerAliasName)的に-d追加でつくりなおしたりなど。

https://letsencrypt.jp/docs/acme-v2-wildcards.html
https://advanceffort.com/lets-encrypt-%E3%83%AF%E3%82%A4%E3%83%AB%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89%E8%A8%AD%E5%AE%9A%E6%89%8B%E9%A0%86/

```
sudo certbot certonly --manual --agree-tos --manual-public-ip-logging-ok \
 -d "*.${mydomain1}" -d "${mydomain1}" -d "${mydomain2}" -d "${mydomain3}" \
 --preferred-challenges dns -m ${my_mailaddr} --server https://acme-v02.api.letsencrypt.org/directory
```

表示されたサブドメインとトークンをDNSにTXTレコード登録して伝搬してdigれたらEnterを-dの数だけ繰り返す

##### **・証明書をLBに登録**
日付で登録して差し替えると更新時断なしでいける模様（証明書は中間証明書も入ってるfullchain.pemを上げる）

```
#日付つきの名前で証明書登録
sudo gcloud compute ssl-certificates create ${mydomain1}-cert-$(/bin/date +%Y%m%d) \
    --certificate /etc/letsencrypt/live/${mydomain1}/fullchain.pem \
    --private-key /etc/letsencrypt/live/${mydomain1}/privkey.pem \
    --description "$(/bin/date +%Y%m%d) ${mydomain1} wildcard certification."

#ターゲットHTTPプロキシリソースの証明書を更新する
sudo gcloud compute target-https-proxies update $my-lb1-target-proxy \
 --ssl-certificates ${mydomain1}-cert-$(/bin/date +%Y%m%d) --url-map $my-lb1

# ターゲットHTTPプロキシリソースをフロントエンドに割り当てる
sudo gcloud compute forwarding-rules set-target $my-fs --target-https-proxy $my-lb1-target-proxy --global

# ふるい証明書リソースを削除
$ sudo gcloud compute ssl-certificates delete ${mydomain1}-cert-yyyymmdd -q
```

##### **・LBつくるまわり**

　・インスタンスグループを作る

※どうやらシングルゾーンでないとunmanagedが選べないようにコンソール上表示されている。
　（オートスケールやら自動回復やイメージテンプレート登録などのマネージド機能はシングルでもマルチでも選べるがアンマネージドはシングルしか選べない）

```
$ sudo gcloud compute --project=$mypj instance-groups unmanaged \
   create ${my-ins-group1} --zone=${myregion}-a

$ sudo gcloud compute --project=$mypj instance-groups unmanaged \
   add-instances ${my-ins-group1} --zone=${myregion}-a --instances=${myhost1}
```

https://qiita.com/tora470/items/f4ec118ae59ec0342d03

　・ヘルスチェックを作る

```
sudo gcloud compute --project "$mypj" http-health-checks create "$my-helthchk-1" --port "80" \
 --request-path "/" --check-interval "60" --timeout "60" --unhealthy-threshold "2" --healthy-threshold "5"
```

　・バックエンドサービスを作る
https://cloud.google.com/compute/docs/load-balancing/http/backend-service?hl=ja

```
my-http-bs
プロトコルHTTP、名前付きポートhttp、タイムアウト30秒、
バックエンド：${my-ins-group1}
ヘルスチェック：$my-helthchk-1
セッションアフィニティ：なし（セッション管理とか送信元同じクライアントは同じサーバに振るとか）
接続ドレインのタイムアウト：300秒
```

　・バックエンドバケットも作れる
GCS（CloudStorage）はドメイン名つけたいときはドメインオーナーである認証が要る。
ドメイン名つける時だけドットが使えるがそうでなければ記号はハイフンかアンダーバーのみになる。
またLBのバックエンドにしたい場合にドメイン名つける必要はない。
https://qiita.com/takky/items/ce1e28c1ae5c62d1c4ec

　・外部IPアドレスを静的IPでLB用に確保
どうやらいつでも断なしでエフェメラル（再起動でかわる）ものと静的IPと変えられる（VPC＞外部IPアドレス、から）

　・CloudDNSにLBのIPをAレコードで登録する
${mydomain1} 10.xx.xx.xx

　・新しいHTTP(S)ロードバランサの作成から

```
名前：my-lb1
バックエンドの設定：さっきつくったものを選択
ホストとパスのルール：バックエンドを設定すると同時にすべて通すルールが作成されるためそのままでOK
フロントエンド（グローバル転送ルール）の設定：
　名前：my-fs
　プロトコル：HTTPS
　IP：さっき確保しておいたstaticip
　ポート：443
　証明書：さっき登録した$my-cert-yyyymmdd
```

https://cloud.google.com/compute/docs/load-balancing/http/global-forwarding-rules?hl=ja

　・LBとヘルスチェックAPIサーバからのhttpアクセスをファイアウォール設定で許可
バックエンドインスタンスとの接続がうまくいってなさそうなので以下FW許可登録した

```
gcloud compute --project=$mypj firewall-rules create allow-gcp-http-lb \
 --description=allow\ from\ gcp\ http\ load\ balancer \
 --direction=INGRESS --priority=1002 --network=${myvpc1} --action=ALLOW --rules=tcp:80,tcp:443 \
 --source-ranges=130.211.0.0/22,35.191.0.0/16 --target-tags=web
```
https://cloud.google.com/compute/docs/load-balancing/health-checks?hl=ja

##### **・SSLポリシー割り当て**

TLS1.2指定でないとアレということでCLIからの設定（ベータ）でTLS1.2制限をかける

```
$ sudo gcloud beta compute ssl-policies create ${my-custom-sslpolicy} --profile  MODERN --min-tls-version 1.2 
$ sudo gcloud beta compute ssl-policies list
NAME                 PROFILE  MIN_TLS_VERSION
${my-custom-sslpolicy}  MODERN   TLS_1_2

$ sudo gcloud beta compute target-https-proxies update \
>  $my-lb1-target-proxy --ssl-policy ${my-custom-sslpolicy} 

$ sudo gcloud beta compute target-https-proxies describe ${my-lb1}-target-proxy

id: '******'
kind: compute#targetHttpsProxy
name: ${my-lb1}-target-proxy 
selfLink: https://www.googleapis.com/compute/beta/projects/${mydomain1}/global/targetHttpsProxies/${my-lb1}-target-proxy
sslCertificates:


$ sudo gcloud beta compute ssl-policies describe ${my-custom-sslpolicy} 
creationTimestamp: '2018-03-29T06:08:14.547-07:00'
enabledFeatures:
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
fingerprint: ******
id: 'xxxxxxxxxxxxx'
kind: compute#sslPolicy
minTlsVersion: TLS_1_2
name: ${my-lb1}-target-proxy
profile: MODERN
```
https://cloud.google.com/compute/docs/load-balancing/ssl-policies?hl=ja
https://cloudplatform-jp.googleblog.com/2018/03/announcing-SSL-policies-for-HTTPS-and-SSL-proxy-load-balancers.html

####・CloudSQLでpostgresqlのインスタンスをつくる

CLIがベータだからなのか出ていなかったので以下のとおり設定

```
インスタンスID：$my-csql
デフォルトのユーザー パスワード：*******
リージョン：${myregion}
ゾーン：${myregion}-a
DBバージョン：9.6
	マシンtype：db-n1-standard-1選択できず
自動バックアップ：2-6時
可用性：シングル
ネットワークの承認：未設定
データベースフラグ追加：未設定
メンテスケジュールの設定：日曜の2-3時、遅め
ラベル：
environment:production
role:db
```

参考：
https://cloud.google.com/sql/docs/postgres/connect-admin-proxy?hl=ja
https://blog.hrendoh.com/google-appengine-php-using-cloud-sql/

外部アプリケーションから接続する方法などは以下にあるが本件では利用しない
https://cloud.google.com/sql/docs/mysql/connect-external-app?hl=ja&_ga=2.49698144.-779814870.1500864087#proxy

flagで設定更新ができるのが限られててpostgresqlだとtimezoneは変更するなら`ALTER DATABASE $mydbschema SET timezone TO 'Asia/Tokyo';` するしかなさそう。設定可能なフラグの一覧の中になかった。（バキューム関連の設定くらいしかできなさそう）
https://cloud.google.com/sql/docs/postgres/flags?hl=ja&_ga=2.145126898.-779814870.1500864087

PostgreSQL 9.6.5文書　第19章 サーバの設定
https://www.postgresql.jp/document/9.6/html/runtime-config.html
https://www.postgresql.jp/document/9.6/html/config-setting.html

ALTER SYSTEMで設定はできるがSUPER USER権限が無いと無理で、
クラウドサービスなCloudSQLは案の定SUPER USER権限は付けられなさそうだった。
https://www.postgresql.jp/document/9.6/html/sql-altersystem.html
https://cloud.google.com/sql/docs/postgres/users


##### **・cloud_sql_proxyをいれてそのsystemdユニット化**

GCPのサービスはVPCのプライベートサブネット上に作るという細やかさは期待できないので
cloud_sql_proxy入れない場合はSSL経由でグローバルIPでつなぐことになる。
cloud_sql_proxy入れるとアプリからはローカルへのアクセスでOKなようにでき
フェイルオーバ時も途切れはするものの同じ接続名でのアクセスが可能に。

https://cloud.google.com/sql/docs/postgres/sql-proxy
https://cloud.google.com/sql/docs/postgres/connect-admin-proxy?hl=ja

```
$ sudo wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy

$ sudo chmod +x cloud_sql_proxy
```

あと、GoogleCloudSQLAPIを有効化しておいた
https://console.developers.google.com/apis/api/sqladmin.googleapis.com/overview?project=649697318341

具体的にはこちら
https://www.googleapis.com/auth/sqlservice.admin

```
$ ./cloud_sql_proxy -instances=${mypj}:${myregion}:${db-instance-name}=tcp:5432 &
[1] 29343
$ 2018/03/27 19:57:49 Listening on 127.0.0.1:5432 for ${mypj}:${myregion}:${db-instance-name}
2018/03/27 19:57:49 Ready for new connections

$ netstat -lnpt
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      29343/./cloud_sql_p 

$ psql "host=127.0.0.1 sslmode=disable dbname=postgres user=postgres"
パスワード:
postgres=> \l
postgres-> \du
```

このままだとOS再起動で上がってこないのでsystemd化をする
https://qiita.com/kumanoryo/items/ef3fbec70b4138ffe1c2

```
$ sudo ln -s /usr/local/src/cloud_sql_proxy /usr/bin/cloud_sql_proxy
sudo mkdir /etc/systemd/system/cloud_sql_proxy\@.service.d
sudo vi /etc/systemd/system/cloud_sql_proxy\@.service.d/limits.conf

sudo vi /etc/systemd/system/cloud_sql_proxy\@.service
------------
[Unit]
Description = CloudSQL Proxy %i
After = network.target

[Service]
EnvironmentFile = /etc/sysconfig/cloud_sql_proxy/%i.conf
ExecStart = /usr/bin/cloud_sql_proxy -instances=${PROJECT_ID}:${REGION}:${INSTANCE_NAME}=tcp:${PORT}
ExecStop = /bin/kill ${MAINPID}
ExecReload = /bin/kill -HUP ${MAINPID}
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
------------
```

%iはinstance_nameかつたぶんsystemd的に確保するメモリ空間の名前と思われ、起動時に@のうしろに指定する。
別のSQLインスタンスにもつなぐ場合にはinstancesにカンマ区切りで接続名を指定する（とポート変えないとだめそうです）
https://cloud.google.com/sql/docs/postgres/sql-proxy#multiple-instances
https://www.freedesktop.org/software/systemd/man/systemd.unit.html
http://enakai00.hatenablog.com/entry/20130917/1379374797

```
sudo mkdir /etc/sysconfig/cloud_sql_proxy
sudo vi /etc/sysconfig/cloud_sql_proxy/${db-instance-name}.conf
------------
PROJECT_ID="${mypj}"
REGION="${myregion}"
INSTANCE_NAME="${db-instance-name}"
PORT="5432"
------------

$ sudo systemctl start cloud_sql_proxy@${db-instance-name}.service
$ sudo systemctl status cloud_sql_proxy@${db-instance-name}.service

$ sudo systemctl is-enabled cloud_sql_proxy@${db-instance-name}.service
$ sudo systemctl enable cloud_sql_proxy@${db-instance-name}.service
$ sudo systemctl is-enabled cloud_sql_proxy@${db-instance-name}.service
```

##### **・pgadmin4をapacheれんけいさす（GCPはなんの関係もない）**
phppgadminがphp7.1とpostgresql9.6に対応してる形跡がない気がしたのでpgadmin4をmod_wsgiと連携さした
http://www.youyoukankan.net/cms/postgresql-pgadmin4-install.html

```
$ sudo yum install pgadmin4-v2 mod_wsgi
$ rpm -ql pgadmin4-v2

$ cat /etc/pgadmin/pgadmin4.conf
ApplicationPath="/usr/lib/python2.7/site-packages/pgadmin4-web/"
PythonPath="/usr/lib/python2.7/site-packages:/usr/lib64/python2.7/site-packages"

$ cd /usr/lib/python2.7/site-packages/pgadmin4-web/
$ sudo touch config_local.py
$ sudo vi config_local.py 
$ sudo mkdir /var/lib/pgadmin4
$ sudo python setup.py
初期アカウント情報を入力
$ ls /var/lib/pgadmin4/
pgadmin4.db  pgadmin4.log  sessions  storage
$ systemctl status pgadmin4-v2
$ systemctl is-enabled pgadmin4-v2
disabled
$ sudo chown -R apache:apache /var/lib/pgadmin4
$ sudo systemctl start pgadmin4-v2
$ sudo systemctl status pgadmin4-v2
cd /etc/httpd/conf.d/
$ sudo cp -p pgadmin4-v2.conf{.sample,}
$ sudo vim pgadmin4-v2.conf
$ diff pgadmin4-v2.conf{.sample,}
1c1
< LoadModule wsgi_module modules/mod_wsgi.so
---
> #LoadModule wsgi_module modules/mod_wsgi.so
10c10,14
<               Require all granted
---
>               #Require all granted
>                 Require local
>                 # allow from companys office
>                 Require ip ${myip1}
>                 Require ip ${myip2}
$ sudo systemctl restart httpd
$ sudo systemctl status httpd
```

ログインしたらそこからアカウント作ったり接続情報設定したりが可能。
cloud_sql_proxyでつないでるのでpgadmin4からはローカルホストを指定してつなぐ。

ここでSELinuxが有効だとログインできなかったりするので注意。。

#### **・apache側でipとhttpアクセスをhttpsにRewriteする**

apache,phpの入れ方とかはremiから入れてるが割愛。php-pgsqlはpostgresqlのクライアント入れた後に入れるくらい。

RewriteするにあたりLBのヘルスチェックのIPからはリダイレクトしないように除外しないとLBのバックエンドサービス無効のままでブラウザではServerErrorになる。
2.4だとIP制限の書き方がちがったりNameVirtualHost不要になってたりなど。

```
$ sudo cat /etc/httpd/conf.d/rewrite.conf 
<ifModule mod_rewrite.c>
      RewriteEngine On
      LogLevel alert rewrite:trace3
      RewriteCond %{HTTPS} off
      RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</ifModule>

$ sudo cat /etc/httpd/conf.d/vhost.conf 
# Access using IP address to dummy
<VirtualHost *:80>
    ServerName any
    RewriteEngine On
    #LogLevel alert rewrite:trace3
    RewriteCond %{HTTP_USER_AGENT} !^GoogleHC
    RewriteCond %{REMOTE_ADDR} !^35.191.0.0/16
    RewriteCond %{REMOTE_ADDR} !^130.211.0.0/22
    RewriteCond %{REMOTE_ADDR} !^35.186.211.99/32
    RewriteCond %{REMOTE_ADDR} !^209.85.152.0/22
    RewriteCond %{REMOTE_ADDR} !^209.85.204.0/22
    RewriteCond %{HTTP_HOST} !=${mydomain}
    RewriteRule . https://${mydomain}/%{REQUEST_URI} [L,R=301]
</VirtualHost>

# Listen for virtual host requests on all IP addresses
<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/${mydomain}/html
    ServerName ${mydomain}
    ServerAlias ${mydomain1}
    ErrorLog "logs/${mydomain}.error_log"
    CustomLog "logs/${mydomain}.access_log" combined env=!nolog
    RewriteEngine On
    #LogLevel alert rewrite:trace3
    RewriteCond %{HTTP:X-Forwarded-Proto} =http
    RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    <Directory /var/www/vhosts/${mydomain}/html/>
        Options FollowSymLinks
        AllowOverride All
    </Directory>
</VirtualHost>
<VirtualHost *:80>
    ServerName admin.${mydomain}
    ErrorLog logs/admin.${mydomain}_error_log
    TransferLog logs/admin.${mydomain}_access_log
    RewriteEngine On
    #LogLevel alert rewrite:trace3
    RewriteCond %{HTTPS} off
    RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>

$ cat ssl.conf|grep -v '^#'|sed -e '/^$/d' 
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache         shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout  300
SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost *:443>
    ServerName any
    RewriteEngine On
    #LogLevel alert rewrite:trace3
    RewriteCond %{HTTP_HOST} !=${mydomain}
    RewriteRule ^/?(.*) https://admin.${mydomain}/$1 [L,R=301]
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/${mydomain}/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/${mydomain}/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/${mydomain}/chain.pem
</VirtualHost>
<VirtualHost _default_:443>
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLProxyProtocol all -SSLv3 
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLHonorCipherOrder     on
SSLCompression          off
SSLCertificateFile /etc/letsencrypt/live/${mydomain}/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/${mydomain}/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/${mydomain}/chain.pem
<FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
<VirtualHost *:443>
    ServerName admin.${mydomain}
    SSLEngine on
    ErrorLog logs/ssl_admin.${mydomain}_error_log
    TransferLog logs/ssl_admin.${mydomain}_access_log
    SSLCertificateFile /etc/letsencrypt/live/${mydomain}/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/${mydomain}/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/${mydomain}/chain.pem
    # Uncomment the following directive when using client certificate authentication
    #SSLCACertificateFile    /path/to/ca_certs_for_client_authentication
    # HSTS (mod_headers is required) (15768000 seconds = 6 months)
    Header always set Strict-Transport-Security "max-age=15768000"
</VirtualHost>
```
ssl設定生成参考
https://mozilla.github.io/server-side-tls/ssl-config-generator/
https://qiita.com/nightyknite/items/36cc1d4d067def437e04

LBとおす場合は%{HTTP:X-Forwarded-Proto} =httpだったら、httpsリダイレクトで
とおさない場合は単に%{HTTPS} offだったらリダイレクト。
https://stackoverflow.com/questions/38201969/redirecting-http-to-https-in-google-cloud/38202272
https://cloud.google.com/compute/docs/load-balancing/http/?hl=ja
https://qiita.com/kawaz/items/5e96dae9686e3ac402fe

mod_rewriteのマニュアルに利用できる変数が載ってた。
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
rewrite:trace3は割ともりもりログ出るので動確終わったら止めとく。

あと、LBの配下なのでKeepAliveTimeoutを620にするようにマニュアルに書いてあったのでそうした
(AWSも120にしろとマニュアルに書いてあるのでLB配下なら長いほうがよいのでしょう）



#### **・mailはOP25Bで普通には全く送れないのでSendGlidかなにかにリレーさす**
AWSだとSESがあるしMTAの逆引き登録して制限解除申請できるけどAzureだとSendGlidかExchange OnlineかでGCPだとsendgrid,mailgun,mailietあたりで日本の携帯キャリアのブラックリストのIP制限を通過できるのはSendGlidで独自ドメインは有料というはなし。
https://cloud.google.com/compute/docs/tutorials/sending-mail/?hl=ja


#### **・StackDriver(GoogleCloudMonitoring)のエージェント入れ**
サービスアカウント登録もしないとですがとりあえずエージェントいれるところ。
https://cloud.google.com/logging/docs/agent/installation?hl=ja
https://cloud.google.com/monitoring/agent/install-agent?hl=ja

```
$ cd /usr/local/src
$ sudo curl -sSO "https://dl.google.com/cloudagents/install-logging-agent.sh"
$ sudo bash install-logging-agent.sh
$ rpm -qa|grep google-fluentd
google-fluentd-catch-all-config-0.7-1.noarch
google-fluentd-1.5.29-1.el7.x86_64
$ sudo systemctl status google-fluentd
● google-fluentd.service - LSB: data collector for Treasure Data
   Loaded: loaded (/etc/rc.d/init.d/google-fluentd; bad; vendor preset: disabled)
   Active: active (running) since 水 2018-04-11 08:32:09 JST; 3h 35min ago

$ sudo curl -sSO https://dl.google.com/cloudagents/install-monitoring-agent.sh
$ sudo bash install-monitoring-agent.sh
$ rpm -qa|grep stackdriver
stackdriver-agent-5.5.2-379.el7.centos.x86_64
$ systemctl status stackdriver-agent
● stackdriver-agent.service - LSB: start and stop Stackdriver Agent
   Loaded: loaded (/etc/rc.d/init.d/stackdriver-agent; bad; vendor preset: disabled)
   Active: active (running) since 水 2018-04-11 11:37:43 JST; 4min 38s ago
～略～
```
つづきは詳しい記事が以下のあたりに
https://qiita.com/FumihikoSHIROYAMA/items/6846630b44fbc3f22b8e

ログに関しては月額50GB無料でAuditloggingというCloudTrailにあたるっぽいのがデフォルトで有効な様子で、
https://cloud.google.com/stackdriver/pricing?hl=ja#logs-allotments
エージェント入れた瞬間にデフォルト設定が勝手に入るので後はpathやをカスタマイズするとか独自のやつなら自分で設定書くとかで、
つけたtagでStackDriver側でフィルタ表示が可能になるかんじ。

```
$ sudo ls -l /etc/google-fluentd/config.d
合計 112
-rw-r-----. 1 root root  515  2月 22 02:29 apache.conf
-rw-r-----. 1 root root  624  2月 22 02:29 cassandra.conf
-rw-r-----. 1 root root 2471  2月 22 02:29 chef.conf
-rw-r-----. 1 root root  162  2月 22 02:29 forward.conf
-rw-r-----. 1 root root 1614  2月 22 02:29 gitlab.conf
-rw-r-----. 1 root root  238  2月 22 02:29 jenkins.conf
-rw-r-----. 1 root root  537  2月 22 02:29 jetty.conf
-rw-r-----. 1 root root  322  2月 22 02:29 joomla.conf
-rw-r-----. 1 root root  747  2月 22 02:29 magento.conf
-rw-r-----. 1 root root  368  2月 22 02:29 mediawiki.conf
-rw-r-----. 1 root root  167  2月 22 02:29 memcached.conf
-rw-r-----. 1 root root  163  2月 22 02:29 mongodb.conf
-rw-r-----. 1 root root  936  2月 22 02:29 mysql.conf
-rw-r-----. 1 root root  350  2月 22 02:29 nginx.conf
-rw-r-----. 1 root root  192  2月 22 02:29 postgresql.conf
-rw-r-----. 1 root root 5197  2月 22 02:29 puppet-enterprise.conf
-rw-r-----. 1 root root  485  2月 22 02:29 puppet.conf
-rw-r-----. 1 root root 1096  2月 22 02:29 rabbitmq.conf
-rw-r-----. 1 root root  177  2月 22 02:29 redis.conf
-rw-r-----. 1 root root  163  2月 22 02:29 redmine.conf
-rw-r-----. 1 root root  674  2月 22 02:29 salt.conf
-rw-r-----. 1 root root  154  2月 22 02:29 solr.conf
-rw-r-----. 1 root root  166  2月 22 02:29 sugarcrm.conf
-rw-r-----. 1 root root  273  2月 22 02:30 syslog.conf
-rw-r-----. 1 root root  271  2月 22 02:29 syslog_endpoint.conf
-rw-r-----. 1 root root  639  2月 22 02:29 tomcat.conf
-rw-r-----. 1 root root  373  2月 22 02:29 zookeeper.conf
$ sudo cat /etc/google-fluentd/config.d/syslog.conf
<source>
  @type tail

  # Parse the timestamp, but still collect the entire line as 'message'
  format /^(?<message>(?<time>[^ ]*\s*[^ ]* [^ ]*) .*)$/

  path /var/log/messages
  pos_file /var/lib/google-fluentd/pos/syslog.pos
  read_from_head true
  tag syslog
</source>
```
上記エージェント入れただけで特に何もしてない。（けどWebコンソール側に表示されるようになる。apacheはvhost切ってログファイル名変えた場合path変えるかsourceブロック増やしてgoogle-fluentdエージェントリスタートが要る）
聞いた話だと負荷的にまともに扱えるのは100台までくらいなんじゃないすかねということでした（ためしてはいない）

とりあえず以上。
ちなみにCloudFormationにあたるやつはCloudDeploymentManagerというらしい。
https://qiita.com/marcy-terui/items/1d19aa089fd076873180