地方在住・ぼっちおじさんの勉強法（IT ざっくばらん会 in 磐田・10/27）

## 誰？
![2.png](https://qiita-image-store.s3.amazonaws.com/0/123899/5949c621-73f4-737a-20db-1a330a3bd6a1.png)

 - 名古屋で IT インフラ管理などをやってます
 - 元情シスの Web インフラ担当です（アプリケーションコードも書きます）
 - その他についてはこの後の内容から読み取ってください

---

## 今日話すこと

 - Why ぼっち？
 - 勉強法
   - 資格・検定試験受験
   - 勉強会・カンファレンスへの参加
   - ブログでのアウトプット
   - Twitter
 - 最近取り組んだこと
   - Web サービスの常時 HTTPS 対応

---

## Why ぼっち？（1/2）

 - 自己分析
   - 仕事が速くない
   - 正確でもない
   - 周囲の人と同じことをするモチベーションがいまいち湧かない
 - 価値を出すには周囲とは別のことをするのが良さそう
   - お手本はいない
   - でも自由にできそう（できた）
 - 失敗して障害を起こしたとき自分の責任で復旧させないといけない
   - 力が付く

---

## Why ぼっち？（2/2）

 - やってきたこと
   - NW 構築、インターネット導入、高速化、拠点 VPN 接続
   - サーバリプレース、社内→ DC 移設
   - NT ドメイン運用変更＆ AD 移行
   - UTM 導入
   - Web システムリプレース（ブレード化＆ストレージサーバ導入、VM 導入、AWS 移行）
 - 但しリスクはある
   - 知識が偏る（補正する人がいない）
   - 組織の SPOF になりやすい（フォローできる人がいない）
   - 実際に原因不明の不調が 8 ～ 9 年（一時休職）

---

## 勉強法／資格・検定試験受験（1/2）

 - 目的
   - 基礎知識・一般知識の習得と整理
 - きっかけ
   - Web システムリプレースプロジェクト（3 回目）の失敗
   - 「10 年前の知識で勝負をしている」→反省
 - ポイント
   - 得られるものを意識する
   - アウトプットを意識する
 - IPA の SC → NW → DB 受験
   - 「知識の習得と整理」ができる試験を受ける（箔をつけたいわけではない）
   - 論文試験は午後Ⅱがない分魅力に欠ける（知識の整理にはなるけど）

---

## 勉強法／資格・検定試験受験（2/2）

 - その後登録セキスペに（自腹）
   - 「安全な Web サイトの作り方」に倣い、登録セキスペのオンライン講習システムの問題点を指摘（実地訓練？）
   - 指摘点が修正される→最終的に（春登録のセキスペが利用する）オンライン講習システム（U 社受託）がリニューアル（脱 Struts 1 ？）
 - 社内向け IPA 試験勉強会を開催
   - 参加者から AP・SC・DB 合格者が出た

---

## 勉強法／勉強会・カンファレンスへの参加（1/2）

 - 目的
   - 新しい知識のインプット・社外のつながり
 - きっかけ
   - SC 受験直後、偶然「名古屋情報セキュリティ勉強会」が復活したので参加
 - ポイント
   - 思い立ったら躊躇しない
   - でも無理はしない
 - コミュニティの良さを知る
 - 名古屋では参加できる勉強会が限られるので、東京・大阪などに積極的に出ていく
   - お金は後から付いてくるので自費参加を躊躇しない
   - 有休消化しまくる
   - 社内稟議で消耗しない（モチベーションは有限）

---

## 勉強法／勉強会・カンファレンスへの参加（2/2）

 - ぼっち参加を気にしない
   - 社外に「仲間」ができるので「ぼっち」ではなくなる
 - 無理はしない
   - 興味がない勉強会に参加しても身につかない
   - 気が乗らないときは懇親会に参加しない
 - アウトプットを意識する
   - 受けてきたハンズオンなどを社内の希望者に再演
   - 伝えることを意識してインプットすると、曖昧さの排除につながるし理解も深まる
 - 事情でどうしても参加できない方はインフラ勉強会などのオンライン勉強会もあります
   - https://wp.infra-workshop.tech/

---

## 勉強法／ブログでのアウトプット

 - きっかけ
   - 勉強会で LT したら大コケ→そのまま成仏させるのはもったいない
 - ポイント
   - 無理をしない
   - 構えすぎない
 - 件の LT の内容を書き直して Qiita へ
   - https://qiita.com/hmatsu47
   - その後は概ね月 2 本ペース
   - 興味があること、記事にできそうなことだけ書く
   - 思ったほどマサカリは飛んでこない（みんな自意識過剰？）
 - 勉強会参加記録ははてなブログへ
   - https://hmatsu47.hatenablog.com

---

## 勉強法／Twitter

 - きっかけ：勉強会のお礼を伝えたくてアカウント開設
 - ポイント
   - フォローは少しずつ増やしていく
   - 並行してブログなどでアウトプットを継続する
   - 困っている人に手を差し伸べる
 - いきなり 4 桁フォローしても情報の整理が追い付かない
 - 継続的アウトプットが「つながる意味のある人」とのつながりを生む
 - 困っている人に手を差し伸べる＝自分の勉強にもなる

---

## 最近取り組んだこと／Web サービスの常時 HTTPS 対応（1/3）

 - 多ドメイン（数千 FQDN 規模）のサービスの常時 HTTPS 対応
   - 顧客が持つ独自ドメインが 4 桁ある CMS サービス
 - 約 1 ヶ月でほぼ対応完了（アイデアと検証：自分／実装：同僚）
 - 方法について Qiita に書いた
   - https://qiita.com/hmatsu47/items/54bfcd599546a5988bd2

![4.png](https://qiita-image-store.s3.amazonaws.com/0/123899/1c7834f0-6eb5-8527-5249-3c6fc14b601e.png)

---

## 最近取り組んだこと／Web サービスの常時 HTTPS 対応（2/3）

 - SNI で送られてきた FQDN をスクリプトで証明書と突合
   - nginx に ngx_lua（ngx_mruby も可）を組み合わせて使う

```config:nginx.conf（関連部分）
http {

    # HTTPS server

    server {
        listen       443 ssl;
        listen       [::]:443 ssl;
        server_name  _;

        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_certificate certs/www.example.com.pem;
        ssl_certificate_key certs/www.example.com.key;
        ssl_session_tickets on;
        ssl_session_ticket_key certs/ticket.key;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout 5m;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        ssl_certificate_by_lua_block {
            local ssl = require "ngx.ssl"

            local ok, err = ssl.clear_certs()
            if not ok then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end

            local name, err = ssl.server_name()
            if not name then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end

            local ok, err = ngx.re.match(name, "^([A-Za-z0-9][A-Za-z0-9%.%-]{1,251}[A-Za-z])$", "jo")
            if not ok then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end

            local ssl_certificate = string.format("conf/certs/%s.pem", name)
            local ssl_certificate_key = string.format("conf/certs/%s.key", name)

            local file, err = io.open(ssl_certificate, "r")
            if not file then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end
            local pem_cert = file:read("*all")
            io.close(file)

            local cert, err = ssl.cert_pem_to_der(pem_cert)
            if not cert then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end

            local ok, err = ssl.set_der_cert(cert)
            if not ok then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end

            local file, err = io.open(ssl_certificate_key, "r")
            if not file then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end
            local pem_priv_key = file:read("*all")
            io.close(file)

            local priv_key, err = ssl.priv_key_pem_to_der(pem_priv_key)
            if not priv_key then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end

            local ok, err = ssl.set_der_priv_key(priv_key)
            if not ok then
                ngx.log(ngx.ERR, err)
                return ngx.exit(ngx.ERROR)
            end

        }

        location / {

            access_by_lua_block {
                local headers = ngx.req.get_headers()
                local host = headers["Host"]
                local m, err = ngx.re.match(host, "(?<hostname>[^:]+)", "jo")
                if err then
                    ngx.log(ngx.ERR, err)
                    return
                end
            }

            proxy_redirect   off;
            proxy_set_header Host               $host;
            proxy_set_header X-Real-IP          $remote_addr;
            proxy_set_header X-Forwarded-Host   $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;

            proxy_pass http://【バックエンドサーバのIPアドレス】:【同・ポート番号】;
        }
    }
}
```

---

## 最近取り組んだこと／Web サービスの常時 HTTPS 対応（3/3）

 - 技術の進化
   - 20 年前：1FQDN の HTTPS サイトに対して 1 つのグローバル IP アドレスが必要
   - 10 年前：SNI でワイルドカード／マルチドメイン証明書を使えば条件付きで複数 FQDN も可、でも対応ブラウザが限られる
   - ここ数年：SNI を利用してスクリプトで動的な対応が可能
 - ほかにも、HTTPS を取り巻く技術については変化が激しい
   - OCSP（Online Certificate Status Protocol）関連（CRL → OCSP、OCSP Stapling）
   - HSTS（HTTP Strict Transport Security）/ HSTS Preload
   - HPKP（HTTP Public Key Pinning）→ Chrome 67 で対応サポート廃止（Expect-CT へ）
   - X-Security ヘッダ（「X-」が外れるものも）
 - QUIC + TLS 1.3（TCP の終わりの始まり）

---

## まとめ

 - 「ぼっち」は武器
   - 「ロールモデルが身近にいない」＝実はチャンスかも？
 - 但し、知識が偏るし、成果をあげればあげるほど組織の SPOF になりがち
   - いつかは「ぼっちからの脱却」が必要
   - といいつつ今もまだ模索中
 - アウトプットを意識してインプットする
 - 無理はしない
   - Enjoy！

---

## ありがとうございました