Slide 1

Slide 1 text

Plug & WAF 2022-02-27 tokyo.ex #16

Slide 2

Slide 2 text

agenda ● About Me ● ゴール ● WAFとは何か ● Webアプリ(MVC)の構造 ● 何故Plugが必要なのか ● Plugの構造 ● Plugのインターフェース ● Plugのデータフロー ● DEMO ● まとめ

Slide 3

Slide 3 text

About Me ● おーはら / Twitter: @ohrdev / Github: ohr486 ● 株式会社ドリコム SRE部 部長 ○ Work: ■ エンジニアマネージャ ● 技術戦略の策定/推進 ● エンジニア採用/採用戦略策定 ■ サーバー/インフラエンジニア ● 開発現場でゲームのバックエンド (Rails/Phoenix/Go/HCL)のコード書いてます ■ 新規事業/ディレクター ● 負荷試験支援/DevOps推進支援/設計コンサル ● Community ○ tokyo.ex / Japan Elixir Association / Erlang&Elixir Fest ● Hobby ○ 仏像制作 ○ 自転車

Slide 4

Slide 4 text

ゴール ● ターゲット ○ Plugが何をしているか理解したい人 ○ 何故Plugがあるかを理解したい人 ○ PhoenixとPlugの関係について理解したい人 ● ゴール ○ (Phoenixを含む)WAFの構造について理解する ○ Plugの構造について理解する ○ PhoenixとPlugの関係について理解する

Slide 5

Slide 5 text

WAFとは何か ● WAF = Web Application Framework ○ elixir -> phoenix ○ ruby -> rails ○ python -> django ● Webアプリを作るためのフレームワーク ○ webアプリとは? ■ インターネット/ネットワークを介して利用するアプリケーション ■ ここでは、webブラウザ上で動作するという前提で進めます ○ ex) wiki, blog, 掲示板, ECサイト, etc

Slide 6

Slide 6 text

Webアプリ(MVC)の構造 Webサーバー Webアプリ データベース Nginx Apache Cowboy etc プロトコル HTTP WebSocket Phoenix Rails Django etc MySQL PostgreSQL Spanner etc DB I/F Ecto ActiveRecord etc WAF I/F Plug Rack WSGI etc cowboy Plug Phoenix Endpoint Router Pipeline Controller View Template Ecto DB View Controller Model

Slide 7

Slide 7 text

何故Plugが必要なのか ● 歴史的背景 ○ WAFの乱立とWebサーバーの多様化により、 WAFとWebサーバーの接続部分の組み合わせ爆発 が発生し、全ての接続を網羅するのが難しくなった ○ この問題を解決する為、 WAFとWebサーバーの統一的な I/Fを定めた仕様が策定された ○ WAF,Webサーバー共に、この I/Fに対応すればどの組み合わせの接続も担保できる WAF1 WAF2 WAF3 フレームワーク Webサーバー Apache nginx lighttpd … … WAF1 WAF2 WAF3 フレームワーク Webサーバー Apache nginx lighttpd 共通のI/F Phoenix cowboy Plug Rails nginx Rack

Slide 8

Slide 8 text

Plugの構造 cowboy Plug(I/F) Phoenix Endpoint Router Pipeline Controller View Template HTTPコネクションのリク エスト/レスポンスを抽象 化した構造体 %Plug.Conn %Plug.Conn Plug %Plug.Conn HTTP Request HTTP Response Plug Plug Plug Plug PhoenixではPlugとして実 装されている Plug Plug Conn Conn’ Conn’’ Plugとは Connを受け取り、Connの内 部情報を更新して返却するモ ジュール/関数 pipeline

Slide 9

Slide 9 text

Plugのインターフェース ● Plugは以下の2つに分類される ○ Function Plugs ○ Module Plugs ○ これらのPlugはplugマクロを使って、コントローラー層/Routerに差し込まれる ■ https://github.com/ohr486/tokyoex_16_sample/blob/main/plug_sample/lib/plug_sample/router.ex#L8-L12 ● Function Plugs ○ Plug.Connとオプションを引数にとり、Plug.Connを返却する関数 ■ (Plug.Conn.t, Plug.opts) :: Plug.Conn.t ○ https://github.com/ohr486/tokyoex_16_sample/blob/main/plug_sample/lib/plug_sample/router.ex#L31 ● Module Plugs ○ 以下の2つの関数をexportするモジュール ■ init/1 : 引数のオプションを使って自身を初期化する関数、 コンパイル時に実行される ■ call/2 : Plug.Connとオプションを引数にとり、Plug.Connの内部情報を更新して返却する関数 ○ https://github.com/ohr486/tokyoex_16_sample/blob/main/plug_sample/lib/plug_sample/module_plug.ex

Slide 10

Slide 10 text

Plugのデータフロー Func Plug Module Plug Conn Conn’ Conn’’ HTTP Request HTTP Response func_plug(conn, opts) ModulePlug.call(conn’, opts) ModulePlug.init(opts) compile時に呼出 defmodule MyAppMod.Router do use Plug.Router … plug :func_plug plug ModulePlug … end Plug.Routerによる定義 plugを通過する際に呼出 plugを通過する際に呼出

Slide 11

Slide 11 text

DEMO サンプルコード https://github.com/ohr486/tokyoex_16_sample/tree/main/plug_sample

Slide 12

Slide 12 text

まとめ ● WAFとPlugの構造について紹介しました ● 何故Plugが必要なのかについて紹介しました ● PhoenixのRoutingやHTTP層の実装のCodeReadingをする際、%Plug.Connの データ構造を追っていくと理解しやすいです ● 独自実装のカスタムPlugは簡単に作成できます、PlugはHTTPリクエスト/レスポン スのデータ構造をダイレクトに操作できるので非常に強力で有用です