Help us understand the problem. What is going on with this article?

CORS対応のためのReverse Proxyにtraefikを使ってみた

More than 1 year has passed since last update.

はじめに

ブラウザから外部サービスのAPIにアクセスするためにCORS対応目的のReverse Proxyが必要になり
Technology Radar vol.20に載っていたtraefikを使ってみました。

CORSによるクロスドメイン通信とは

CORS(Cross-Origin Resource Sharing)によるクロスドメイン通信とは悪意のあるサイトから情報を
守るためのブラウザの機能に対して信頼できるサイトとして許可するためのものです。

スライド3.PNG

信頼できるサイトに対してID/PASSなどでサインインしているとき、
ブラウザ内にはCookieで認証情報を保持しております。
その時フィッシングメールなど何らかの手段で悪意のあるサイトにアクセスしてしまったときに
罠コンテンツから正規コンテンツにアクセスされたときにCookieとともにアクセスして情報を抜くことが可能となってしまうため、
このような攻撃を防ぐためにブラウザのセキュリティ機能の1つにSOP(Same Origin Policy)があります。
これによって異なるドメイン間の通信にはアクセスを許可するためのCORS対応が必要となります。

JavaScriptのAjaxなどで異なるドメインからの呼び出しは制限されており下記のようなエラーが出力されることになります。

Origin http://example.com is not allowed by Access-Control-Allow-Origin.

このエラーを回避するためには、呼び出される側のAPIレスポンスヘッダ Access-Control-Allow-Origin: <Domain>に許可するドメイン名を指定します。
広く公開されているAPIの多くは Access-Control-Allow-Origin: * (アスタリスク)が許可されておりますが、
最近のChromeではドメイン名指定ではないものもエラーとなるようになっております。

Reverse Proxyとは

特定のサーバへの要求を必ず経由するように設置されたプロキシサーバです。

  • ロードバランサー的な機能
    • URLに応じたサーバ分岐
    • 負荷分散
  • キャッシュ
    など

スライド4.PNG
サービスサーバの手前にReverse Proxyを立てることでURLに応じたサービスサーバや
ポートの振り分けを行ったり負荷分散のために複数のサービスサーバに割り振ることができます。

今回のReverse Proxyの立ち位置

APIサーバ群の手前にKongによって全APIのCORS対応を行っている環境で外部APIへのアクセスを
Kongの後ろに立てたReverse Proxy経由で行うことでCORS対応を行うものです。
SAS-ReverseProxy(traefik).png

traefikとは

スライド6 - コピー.PNG

traefikとは Go 言語で書かれたリバースプロキシで設定を動的に変えられることが特徴です。
リバースプロキシと言えば Nginx が主流ですがそれと比較して下記メリットが挙げられます。

  • 設定ファイルを変更した後のリロードが不要
  • バックエンドサーバが起動していなくてもOK
  • Web UI

Web UI

設定方法のバリエーション

  • 設定ファイル (ファイル監視による更新後自動反映)
  • Rest API
  • DynamoDB
  • Dockerプロセス
  • ECS
  • など...

実行方法

traefik downloadからダウンロードしたバイナリファイルに設定ファイルを指定して実行する。

./bin/traefik -c ./config/traefik.toml
./config/traefik.toml
################################################################
# Global configuration
################################################################
defaultEntryPoints = ["http", "https"]

[accessLog]

[entryPoints]
  [entryPoints.http]
    address = ":80"

[file]
  directory = "./rules/"
  watch = true

:information_source: watch = true とすることで rules 配下のファイルが更新されると自動反映されます。

./rules/example.toml
[frontends.example]
  entryPoints = ["http"]
  backend = "example"
  passHostHeader = false
  [frontends.example.routes.route]
    rule = "PathPrefixStrip: /reverseproxy/https://example.com"

[backends.example.servers.server]
  url = "https://example.com"

:information_source: デフォルトでは転送先サーバへのリクエストホストヘッダーに転送元サーバのホストが渡るため
転送先に弾かれるケースがあるため passHostHeader = false とします。

こちらの設定で外部APIへReverse Proxy経由でのアクセスが可能となります。
http://<Reverse Proxy Host>/reverseproxy/https://example.com

まとめ

今回は多機能なtraefikを用いて最小限の機能のみを使ってReverse Proxyを立ててみましたが、
動的に設定変更できるメリットに魅力を感じました。

ummt
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした