ゼロトラスト超入門

同僚でもあるおかしんさんが技術書典で出していたゼロトラスト超入門を読んだ.

第1章 ゼロトラストとは

過去と比べてシステムの多様化が進んでおり、従来の境界モデルでの防御方法では現代におけるシステム利用やリスクへの対処として適切ではなくなってきた.
境界モデルの場合、ゾーン外からのトラフィックへの防御は優れているが、ゾーン内からのトラフィックはおざなりになりやすい.
ゼロトラストという考え方は、この課題に対してどう取り組むのかといったセキュリティ戦略である.
ゼロトラストでは以下の5つの考え方から構成されている.

ネットワークは常に敵意にさらされているとみなす 常に外部と内部の驚異が存在する ローカネットワークであることは、ネットワークを信頼するための条件として十分でない 全てのデバイス、ユーザー、およびネットワークフローが認証および承認されていること ポリシはー動的で、できるだけ多くのデータソースから決定されていること

※ ゼロトラスト入門から引用

所感

これはプライベートでも仕事でも普段から抱えていた問題をうまく言語してくれた内容だと思った.
故意・過失に関わらず、どうしてもインシデントというものは大なり小なり発生してしまう.
であれば、どうやってそれを最小に防ぐのか?ということを考える必要があって、このゼロトラストという考え方は非常にしっくりときた.

第2章 境界モデルの歴史

ネットワークの進化に伴って、境界モデルは生まれ進化してきた.
そして攻撃手法もより進化しており、境界モデルではそれに耐えられなくなったきた.

所感

改めて歴史を振り返れたのは面白かった.
脅威の進化の下りで書かれているのは攻撃手法の歴史でもあり、共感しながら読み進めた.
ここは知ってる人は飛ばしても良い内容かもしれない.

第3章 境界モデルの脆弱性

境界モデルは外部から内部への直接的な攻撃を防ぐことはできるが、内部へ何らかの方法でマルウェアなどが侵入できた場合は、非常に脆い.(メールの添付ファイルなど)

所感

攻撃手法にイメージがつかない人でも理解しやすいのではないのかな、と思いながら読み進めた.
実際流れも良く、事例も載っていてよかった.

第4章 境界モデルからゼロトラストへ

ゼロトラストモデルは境界モデルとは異なるアーキテクチャで構成される.
コントロールプレーンによってクライアントが認証・承認が行われ、それに基づきデータプレーンに対してクライアントからのアクセスを動的に設定する.
ユーザー認証、デバイス認証、信頼度に基づいて動的にポリシーが設定される.

所感

ゼロトラストモデルのアーキテクチャが載っており理解しやすかったように思う.
俺がゼロトラストを適用したいのは、それこそ自宅のネットワークだったり、サービス開発・運用をするネットワークに対してだ.
正直これを実現するのは今だと少し難しいという印象.
とはいえ方向性が見えた.

第5章 Googleのゼロトラスト(BeyondCorp)

Googleではゼロトラストの考え方を取り入れたBeyondCorpというセキュリティモデルがある.
バイスやユーザーのセキュアな識別が可能な仕組みを用意し、ネットワークにおける信頼を排除を行う.
アクセスレベルは時間とともに変化する可能性があり、アクセスコントロールはこれを複数のデータソースから動的に推測することが求めらる.
またBeyondCoprへ移行するための戦略を考え、段階的に実行している.

所感

ゼロトラストモデルを取り入れたセキュリティモデルの具体的な話は良かった.
またドキュメントが公開されているというのも良い.
この章を読むことで実装するために必要なことをイメージがついたのではないかな、と思う.

まとめ

境界モデルに問題意識がある人は一度読んでみると、ゼロトラストという考え方が以下に良いかが分かる本だと思う.
またゼロトラスト単体に着眼するわけではなくなりたちまで述べているので、ゼロトラストっていう言葉が気になった人は一読してみると面白いかもしれない.
これからゼロトラストを実践していかなけれれば.

進化的アーキテクチャ 後半

khasegawa.hatenablog.com

の続き

5章 進化的データ

データベースのスキーマは、アプリケーションのクラスやクラス階層と同じで、具体的な物事を抽象化したものである.
この物事に変化があったならば、スキーマも変更すべきである.
そうでなければ、物事と抽象化したスキーマとの間の関係性には乖離が生じる.
スキーマの進化を容易にするためには、「テスト」「バージョン管理」「漸進的に進む」といった仕組みが必要である.
共有データベースという複数のアプリケーションが1つのデータベースを参照する場合、あるアプリケーションがスキーマ変更をした場合に、他のアプリケーションが動作しなくなるといったことが起こりうる.
ならば、スキーマの状態に古い状態と新しい状態を残し、古いスキーマを参照するアプリケーションがなくなったら、削除すれば良くなる.

所感

乖離が生じると、実装に対してのコストがかかるだけでなく、暗黙的なコンテキストが多く増えると思われる.
最初のうちはいいかもしれないが、これが数年続いた時のリスクやコストは馬鹿にできないもになっていても不思議ではない.
これは何もアプリケーションだけでなく、ビジネス・ドメイン要件側でもそういった考えをしておく必要はありそうな気がしている.

6章 進化可能なアーキテクチャの構築

進化可能なアーキテクチャを構築するためには、以下3つの手順を行う.

  1. 進化の影響を受ける次元を特定する
  2. 各次元に対して適応度関数を定義する
  3. デプロイメントパイプラインを使って適応度関数を自動化する

新規プロジェクトを進化可能なアーキテクチャに構築していくのは、既存プロジェクトを改良するよりかは遥かに容易である.
既存のアーキテクチャを改良するには、適切な結合適応度関数を考えておく必要がある.
この適切な結合を推進するためには、モノリスから大きなサービスが協調して動作するアーキテクチャに変えていく必要がある.
うまく分割できないときもあるが、それはライブラリといった形式でそれぞれのサービスに提供するのが良い.
可逆性のある仕組みを構築することも重要.
可逆性のある仕組みとは、Blue/Greenデプロイのようなデプロイメントパイプラインを構築することにある.
DDDでの腐敗防止層を、ライブラリやフレームワークといった外的要因に対して用意しておくことで、アップデート時の影響を最小限にしておくことができる.
ライブラリなどといった依存は、メリットをもらたす反面、制約を課すということを忘れてはならない.
この利益と代償を考えながらアーキテクチャを構築していく必要がある.
また現時点で最善を考えつつも、数年後にはアーキテクチャの再構築などがしやすいようにアーキテクチャを構築する犠牲的アーキテクチャというアプローチも重要である.

所感

アーキテクチャやアプリケーション開発に具体的な手法について述べられているが、インフラ的な観点は少ないように見受けられる.
DDDの思想がベースになっているため、DDDの勉強をしておく必要がありそう.
アーキテクチャを設計するうえで必要になる観点を改めて考えることができる章でもあったように感じる.

7章 進化的アーキテクチャの落とし穴とアンチパターン

ベンダーキングアンチパターン
ベンダー依存になり、ベンダーがいないとダメな構造になることは非常に良くない.
腐敗防止層を用意しておけば防げる.

抽象化の欠如
抽象化には漏れがあるということを前提としておいた方がよい.
作業する抽象化レイヤよりも下にあるレイヤの少なくとも1つを理解することで多少は防げるが、複雑なアーキテクチャになるにつれてそれは難しいこととなる.
こういった点をうまく適応度関数で守れる仕組みを用意した方が良いだろう.

ラスト10%の罠
顧客が望む残り10%は実現可能だが、かなり難しい.

コード再利用の乱用
コードの再利用は、レゴブロックを組み立てるというよりは、臓器移植に似ている.
無理に再利用できるようなコードを書くと、使いやすさが損なわれる.
マイクロサービスでは、ドメイン間のエンティティを分離することにあるため、ある程度の重複は許容する.
重複を促しているわけではないことに注意.

不適切なガバナンス
ガバナンスモデルは、単一の関心事に対して解決策を求める.
これでは今の世の中では不十分で、ゴルディロックスガバナンスモデルを利用した、単純・中間・複雑といった3つの技術スタックを選定しておき、各サービス要件によって技術スタック要件がを導けるようにしておくことができる.

リリース速度の欠如
生物の進化にはライフサイクルの短さは重要である.
それと同じでソフトウェアのライフサイクルも短い方が進化可能性を高めるうえで必要になる.

製品のカスタマイズ
顧客ごとにカスタマイズを請け負うと、それだけコストがかかるということを認識しておく.

レポート機能
アプリケーションとレポート機能はデータを共有する必要はないのに不必要に共有してしまう.
共有しないようにレポートではレポート用のデータを書き出すようなアーキテクチャにすべきである.

計画範囲
大幅な先行投資が必要とする技術には従ってはいけない.

所感

最近、自分が考えていることと同じような結論になっている箇所があって納得感があった.
ベンダーキングアンチパターンは腐敗防止層を入れる典型的な例で良さそう.
DDDをほぼ知らない状態なので、DDDを知るべきだという強い意識を持てる.
また現職では自社サービスを提供しているところであるため、より納得できる例が載っているのが面白い.

8章 進化的アーキテクチャの実践

進化的アーキテクチャを実践していくには、多くの関心事がある.
それは技術的なものだけでなく、ビジネス上の問題や組織・チームといった問題である.
組織・チームでいえばコミュニケーションコストがある.
機能横断型の方が調整の手間が少なくなりやすい.
ただ闇雲にすればいいというものではなく、Jeff Bezos氏が提唱した2枚のピザという概念がある.
大きな2枚のピザで賄える人数が1チームに最適だという話です.
チームの人が増えるとそれだけ各メンバー間のリンクが増えて管理するのが難しくなる.
実験するための基盤を組織に築くことも重要である.
外部からアイデアを取り入れる経路を作ったり、改善のサイクルを作ったり、イノベーションの時間を用意する必要がある.
全て進化的アーキテクチャにすればよいというものでもないことに注意.

所感

見出し通りの内容だったかと思う.
進化的なアーキテクチャであるかどうかは別として、それ以外でも有用そうな話はあった.
2枚のピザは割と有名な話だが、もう少し学術的な面で気になるところではある.
組織構造的な話には首を突っ込みたくないけど、そうは言ってられないしな.

まとめ

トータルとしては、1~5章までは軽く読む程度でいよい内容であったと思います.
細かい例が載っていたりしたが、要点さえ抑えておけば良さそうです.
7,8章をしっかり読めばこの本が言いたいことが載っているところなのかもしれない.
現職ではチャレンジが必要なフェーズであるので、そこで自分が議論するために必要な情報の1つを知れたという意味では良い本だったと思えます.
組織的な話は面倒そうなので必要な限り首突っ込みたくない.
とは言いつつ、何故か首を突ちっ込みがち...

進化的アーキテクチャ 前半

会社の福利厚生を利用して購入した進化的アーキテクチャを読んでいる.

TL;DR

  • 進化的アーキテクチャは、具体的なアーキテクチャを決める手法ではなく、継続的に変更可能なアーキテクチャを支援するための手法
  • 漸進的な変更適応度関数適切な結合から構成される
  • 適応度関数は、要件が担保できているかを確認する仕組みのことで、自動テストや手動テスト・監査・セキュリティレビューがある
  • 漸進的な変更は、開発とデプロイメントの2つの側面からなり、「テストがしやすいアーキテクチャにすること」「継続的デリバリーができるデプロイメントパイプラインを定義すること」が大事
  • オーバーヘッドが少なく最大の利益をもらたす適切な結合があるアーキテクチャを選択しましょう

1章 ソフトウェアアーキテクチャ

1章では、進化的アーキテクチャとは何かを定義している.

将来を見据えたアーキテクチャを設計するのは非常に難しい.
アーキテクチャを設計するには、ビジネス・ドメイン要件から、セキュリティ・パフォーマンス・スケーラビリティなどといったアーキテクチャ特性を踏まえて、それぞれの釣り合いをとりながら最適解を見つけることである.
しかし、ある時点で決定した段階では最適解だったアーキテクチャでも、時間が経つにつれ最適解ではなくなる場合がある.
何故最適解でなくなるかといえば、ビジネス・ドメイン要件の変更といった要因や、言語やプラットフォームのアップデートなど多岐に渡る.
これらはいつ起こるのは予測しづらいが、いつか起きること自体は分かっている.
ならば、それらに対応し変化し続け、最適解であり続けるためのアーキテクチャ特性進化可能性を設計する際の関心事に入れる.
これらを踏まえ、進化的アーキテクチャとは

複数の次元にわたる漸進的で誘導的な変更を支援するものである。

と定義される.
また進化的アーキテクチャは、漸進的な変更適応度関数適切な結合という側面から構成される. これらの具体的な話は後の章で述べられる.

2章 適応度関数

2章では、適応度関数の定義と、種類が記載されている.

アーキテクチャは、様々な要因やアーキテクチャ特性から構成されている.
これらの各要件を担保するために適応度関数という仕組みを用意する.
適応度関数は、それぞれの粒度やトリガー、自動か手動かなどといった分類があり、それぞれ得意不得意がある.
そのため、それらを適切に組み合わせていく必要がある.
早い段階で適応度関数を定義しておくことで、不必要な時間やお金を減らすことができる.
また、適応度関数も定期的に見直す必要がある.
適応度関数自体も様々な要因から影響を受けるからだ.

3章 漸進的な変更を支える技術

3章では、漸進的な変更の定義と、手法や具体例が記載されている.

漸進的な変更が支援するのは、開発とデプロイメントの2つである.
アーキテクチャを設計していく上で無視されがちなのはテスト可能性である.
テスト可能性は、アーキテクチャ特性を自動テストによって検証可能かどうかを示す特性である.
全てのアーキテクチャ特性をテストする必要はなく、容易にテスト可能な特性には、ガイドラインを作り、テストの自動化することが可能である.
デプロイメントは、適応度関数を検証するステージを組み込んだデプロイメントパイプラインを使って継続的なデリバリーを実践することである.
2つのケーススタディがあり、そこでどういったパイプラインが構成されているのかがよく分かる.
このパイプラインの中には自動化されたものだけではなく、手動で実施されるものが含まれるのが何とも面白い.

できる限り自動化できるに越したことはないのだが、2章適応度関数の話にあったメリデメに依存するのだろう.

4章 アーキテクチャ上の結合

4章では、アーキテクチャを組む上で必要となる、適切な結合についての具体的なアーキテクチャが記載されている.

アーキテクチャを設計するうえで、結合は必要悪だと避難されがちだが、結合なしに複雑なソフトウェアを構築するのは困難である.
進化的アーキテクチャでは、最小のオーバーヘッドで最大の利益をもたらす結合すべきアーキテクチャを特定する方法に注目している.
モノリスアーキテクチャから、レイヤード、そしてマイクロサービスなアーキテクチャを含めたいくつかのアーキテクチャが記載されている.
それぞれは、漸進的な変更適応度関数による誘導的な変更適切な結合の3つの観点から述べられている.

疎結合されたアーキテクチャであれば、進化を容易にするための多くの手段を提供することとなる.

感想

読む前は、具体的なアーキテクチャの手法の1つかな?と思って読みすすめていたが、そうではなかったことに少し驚いきました]. だが読み進めていくうえで確かに考慮が漏れやすいポイントであるなということが納得できるような内容でした.
まだ後半を読んでいないので楽しみです.

開発合宿してきました

2/9~2/11の3連休は開発合宿と称した温泉旅行に行ってきました.
宿泊先は伊香保のホテル天坊で、ホテル内に飲み屋もあり、比較的宿泊しやすい施設だったと思います.

いざ合宿

学生時代からの友人達との合宿だったので、がっつりとした開発合宿にはせず、開発もやりつつ温泉で日々の疲れを取るという目的がありました.
具体的に何をやっていたかと言うと

  • Gremrins, Inc.
  • それぞれのやりたい開発・技術的トピックに取り組む

の2つになります.

1つ目のGremrins, Inc.はゲームなので詳細は割愛しますが、Macでも動作するすごろくゲームなのでオススメしておきます.
2つ目のそれぞれのやりたい開発・技術的トピックに取り組むで、私が選んだのはiPad ProのブラウザからSession Managerで開発ができるか? です.

私は普段、ノートPCを持たずにiPad Proだけを持って、喫茶店で読書をしています.
読書もできる・音ゲーもできる・動画も見れる・RAW現像もできる、といったできることが増えてきているのですが、iPad Proで開発もできると嬉しくありませんか?
専用のアプリを使ったり、SSHクライアントアプリを使えば、実際に開発することもできます.
ただ専用のアプリだとできることが限られますし、SSHだとそのポートでの通信を事前に許可しておかなければなりません.
仮にiPadで開発するということであれば、SSHクライアントでマシンに接続して開発した方が良さそうです.
ですが、今回は挑戦したかったということもあり、インバウンドの通信を許可しなくても使えるセッションマネージャーをiPadのブラウザから操作できるのかやってみました.

結果としては

結果は、できなくもないが生産性がガタ落ちするです. Ctrlキーが使えないため、シェル上での操作やCUIのアプリケーションの操作が難しくなっています. Ctrlキーが使えないというのはキーが存在しないというわけではなく、iOSのブラウザでの制約でキーコードが0になるということが問題です.

詳細に興味がある方はスライドを見てください.

開発合宿という名の温泉旅行でしたが、次回はもう少し場所としても開発合宿っぽくしていこうと思います.

Delayed::Job再起動時にジョブがロックされたままにさせない

Delayed::Jobを気軽に再起動させたいために挙動確認した時のメモです.

実行環境

また、Delayed::Jobを起動する際に共通するオプションとして-n 2を指定する前提で書きます.

ソースコードは、graceful_delayedにまとめてあります.

再起動時にジョブがロックされたままにさせない

Delayed::Jobをbin/delayed_job経由で操作すると、daemonsというGemでWorkerプロセスが起動します.
このdaemonsは停止命令(stop)が実行されると、そのプロセスで処理が終了するまで待ち、プロセスを終了させます.
終了待機時間のデフォルト値は20秒となっており、20秒経っても処理が終了しない場合は処理を強制終了させます.

さてDelayed::Jobで20秒以上かかるジョブ実行中に、強制終了するとどうなるでしょうか?

実行中のジョブがロックされたまま、データベースに残り続けてしまいます.
こうなってしまうとQueueに残り続けてしまうゴミデータとなりますし、最悪の場合処理が失敗しているかもしれません.
では、ジョブがロックされたままにならないようにするにはどうしたら良いでしょうか?
私が考えた方法は2つあります.

  • raise_signal_exceptions:termもしくはtrueを指定する
  • daemonsの終了待機時間をDelayed::Worker.max_run_timeに数秒足した値を指定する(例: --daemon-options=-w,{seconds})

どちらが良いということもないはずなので、戦略的にどちらが良いのかを決めるのが良いでしょう.

このサイトの記事一覧・詳細が表示されていなかった

先週の金曜日から今日にかけて記事一覧・詳細が表示されていない現象に遭遇しました.
理由は、submoduleで組み込んでいるhello-friendというテーマで記事対象となるディレクトリ名の変更が行われていたためです.

とりあえずは、以下の対応を実施した.

  • 最新のテーマで動作するようにディレクトリ構造を変更
  • 最新のテーマで動作するように設定ファイルの変更
  • hello-friendリポジトリのrelease watch
  • 定期的に自動ビルドを行っている処理でsubmoduleの更新が入らないようにする

これ今日記事を書こうとしなかったら絶対に気づかなかったので危ないですね.

秘密鍵から公開鍵を生成する

sshで利用する秘密鍵から対応する公開鍵を生成する時のメモです.

公開鍵を生成する

ssh-keygenの-yオプションを使って、秘密鍵から公開鍵を生成することができます. ※1

$ ssh-keygen -y -f id_ed25519
ssh-ed25519 XXXXXXXXXXX

秘密鍵に対してパスワードが設定されている場合は、パスワードの入力が求められます.

$ ssh-keygen -y -f id_ed25519
Enter passphrase:
ssh-ed25519 XXXXXXXXXXX

さいごに

今回は秘密鍵から公開鍵を生成しましたが、これを利用すれば秘密鍵に使えるパスワードの確認もできます. ケースとしてはssh-keygenで鍵を生成した直後に、設定したパスワードの有効性を確認することができますしね.

※1 参考: https://euske.github.io/openssh-jman/ssh-keygen.html