
reproxy v1.7.1
軽量なエッジHTTP(S)サーバーおよびリバースプロキシ。自動SSL、Docker/Consulディスカバリー、ルートごとの認証、レート制限、ヘルスチェックベースのフェイルオーバーを備えています。
Reproxyは、さまざまなプロバイダ(docker、static、file、consul catalog)をサポートするシンプルなエッジHTTP(s)サーバー / リバースプロキシです。1つ以上のプロバイダが、リクエストされたサーバー、リクエストURL、宛先URL、ヘルスチェックURLに関する情報を提供します。単一のバイナリまたはdockerコンテナとして配布されます。
- Let's Encryptによる自動SSL終端
- ユーザー提供のSSL証明書のサポート
- シンプルかつ柔軟なプロキシルール
- 静的、コマンドラインによるプロキシルールプロバイダ
- 動的なファイルベースのプロキシルールプロバイダ
- 自動検出を備えたDockerプロバイダ
- サービスタグによる検出を備えたConsul Catalogプロバイダ
- 複数の(仮想)ホストのサポート
- オプションのトラフィック圧縮
- オプションのIPベースのアクセス制御
- ルートごとのBasic認証
- ユーザー定義のサイズ制限とタイムアウト
- 単一バイナリ配布
- Dockerコンテナ配布
- オプションの「SPAフレンドリー」モードを備えた組み込み静的アセットサーバー
- リダイレクトルールのサポート
- 全体のアクティビティおよびユーザーのアクティビティに対するオプションのリミッター
- ライブヘルスチェックとフェイルオーバー/ロードバランシング
- ルート情報とprometheusメトリクスを備えた管理サーバー
- RPC経由のプラグインサポートによるカスタム機能の実装
- Apache Log Formatと簡易stdoutレポートの両方によるオプションのログ出力
サーバー(ホスト)はFQDN、すなわちs.example.com、*(キャッチオール)、または正規表現として設定できます。完全一致が優先されるため、サーバーがexample.comとexample\.(com|org)の2つのルールがある場合、example.com/some/urlへのリクエストは前者にマッチします。リクエストURLは正規表現にでき、例えば^/api/(.*)とし、宛先URLには正規表現でマッチしたグループを含めることができます。すなわちhttp://d.example.com:8080/$1です。上記の例では、http://s.example.com/api/something?foo=barはhttp://d.example.com:8080/something?foo=barにプロキシされます。
便宜上、末尾に/が付くリクエストで正規表現グループがない場合は/(.*)に展開され、その場合の宛先は/$1に展開されます。すなわち、/api/ -> http://127.0.0.1/serviceは^/api/(.*) -> http://127.0.0.1/service/$1に変換されます。
宛先URLではホスト置換がサポートされています。例えば、/files/${host}はマッチしたホスト名に置き換えられます。$host(波括弧なし)も使用できます。
HTTPとHTTPSの両方がサポートされています。HTTPSでは、静的証明書を使用できるほか、自動ACME(Let's Encrypt)証明書も使用できます。オプションのアセットサーバーを使用して静的ファイルを配信できます。reproxyを起動するには、少なくとも1つのプロバイダを定義する必要があります。残りのパラメータは厳密にオプションであり、適切なデフォルト値を持っています。
例:
- 静的プロバイダを使用する場合:
reproxy --static.enabled --static.rule="*,example.com/api/(.*),https://api.example.com/$1" - 自動docker検出を使用する場合:
reproxy --docker.enabled --docker.auto - dockerコンテナとして:
docker up -p 80:8080 umputun/reproxy --docker.enabled --docker.auto - 自動SSLを使用する場合:
docker up -p 80:8080 -p 443:8443 umputun/reproxy --docker.enabled --docker.auto --ssl.type=auto --ssl.fqdn=example.com
インストール
Reproxyは、小さな自己完結型バイナリとして、またDockerイメージとして配布されています。バイナリとイメージの両方が複数のアーキテクチャと複数のオペレーティングシステムをサポートしており、linux_x86_64、linux_arm64、linux_arm、macos_x86_64、macos_arm64、windows_x86_64、windows_armが含まれます。また、arm64とx86の両方のdebおよびrpmパッケージも提供しています。
- バイナリ配布の場合、リリースセクションから適切なファイルをダウンロードしてください
- Homebrewユーザーの場合:
brew install umputun/apps/reproxy - DockerコンテナはDocker HubおよびGithub Container Registryで利用可能です。つまり、
docker pull umputun/reproxyまたはdocker pull ghcr.io/umputun/reproxyです。
最新の安定版には:vX.Y.ZというDockerタグ(:latestエイリアス付き)が付いており、現在のmasterには:masterタグが付いています。
プロバイダー
プロキシルールはさまざまなプロバイダーから提供されます。現在含まれているのはfile、docker、static、consul-catalogです。各プロバイダーは、プロキシされるリクエストと静的(アセット)の両方に対して複数のルーティングルールを定義できます。ユーザーは複数のプロバイダーを同時に設定できます。
さまざまなプロバイダーの例はexamplesを参照してください
静的プロバイダー
これは最もシンプルなプロバイダーで、すべてのマッピングルールをコマンドライン(または環境変数)で直接定義します。複数のルールをサポートしています。各ルールは3〜7個のカンマ区切り要素server,sourceurl,destination[,ping-url[,forward-health-checks[,timeout[,throttle]]]]です。例えば:
*,^/api/(.*),https://api.example.com/$1-/apiプレフィックスを持つ任意のホスト/サーバーへのすべてのリクエストをhttps://api.example.comにプロキシしますexample.com,/foo/bar,https://api.example.com/zzz,https://api.example.com/ping-example.comへのすべてのリクエストと/foo/barURLを持つリクエストをhttps://api.example.com/zzzにプロキシし、ヘルスチェックにはhttps://api.example.com/pingを使用します。example.com,/foo/bar,https://api.example.com/zzz,https://api.example.com/ping,true- 上記と同じですが、/pingおよび/healthリクエストもバックエンドに転送します。example.com,^/upload/(.*),https://api.example.com/$1,,,5m- ルートごとのリクエストタイムアウトを5分に設定します(4番目と5番目のフィールドは空にしてping-urlとforward-health-checksをスキップします)。example.com,^/login,https://api.example.com/login,,,,2- ルートごとのスロットルをユーザーあたり2リクエスト/秒に設定します(それより前の位置フィールドは空のままにします)。
4番目の要素は、ヘルスレポートに使用されるオプションのping URLを定義します。5番目の要素は、ヘルスチェックリクエストのバックエンドへの転送をオプションで有効にします(true、yes、1)。詳細はヘルスチェックセクションを参照してください。6番目の要素は、オプションのルートごとのリクエストタイムアウト(Goのduration、例: 5m、30s)です。0または空の場合はグローバルな--timeout.write設定を継承します。7番目の要素は、オプションのルートごとのユーザーあたりのリクエスト/秒制限です。0または空の場合は--throttle.userを継承します。空の位置フィールドも許可されます(例: 未使用の中間フィールドに,,)。
ファイルプロバイダー
このプロバイダーはルーティングルールを含むyamlファイルを使用します。
reproxy --file.enabled --file.name=config.yml
config.ymlの例:
default: # the same as * (catch-all) server
- { route: "^/api/svc1/(.*)", dest: "http://127.0.0.1:8080/blah1/$1" }
- {
route: "/api/svc3/xyz",
dest: "http://127.0.0.3:8080/blah3/xyz",
ping: "http://127.0.0.3:8080/ping",
remote: "192.168.1.0/24, 127.0.0.1", # optional, restrict access to the route
forward-health-checks: true # optional, forward /ping and /health to backend
}
- {
route: "^/admin/(.*)",
dest: "http://127.0.0.4:8080/$1",
auth: "admin:$2y$05$..." # optional, per-route basic auth (htpasswd bcrypt format)
}
- {
route: "^/upload/(.*)",
dest: "http://127.0.0.5:8080/$1",
timeout: 5m # optional, per-route request timeout (Go duration). 0 or omitted inherits --timeout.write
}
- {
route: "^/login",
dest: "http://127.0.0.6:8080/login",
throttle: 2 # optional, per-route req/sec per user. 0 or omitted inherits --throttle.user
}
srv.example.com:
- { route: "^/api/svc2/(.*)", dest: "http://127.0.0.2:8080/blah2/$1/abc" }
- { route: "/web/", dest: "/var/www", "assets": true }
"*.files.example.com":
- { route: "^/files/(.*)", dest: "http://123.123.200.200:8080/$host/$1" }
これは動的プロバイダーであり、ファイルの変更は自動的に適用されます。
異なるドメイン上の複数の静的サイトは、サーバー名をキーとして assets: true を使用することで配信できます:
site-en.example.com:
- { route: "/", dest: "/var/www/en", "assets": true }
site-ru.example.com:
- { route: "/", dest: "/var/www/ru", "assets": true }
重要: アセットルールの route フィールドは正規表現ではなくパスプレフィックス(例: /、/web/)でなければなりません。^/(.*) のような正規表現パターンは assets: true では機能しません。静的アセットのマッチングは正規表現ではなくパスプレフィックスの比較を使用するためです。
Docker プロバイダー
Docker プロバイダーは、追加設定を必要としない完全自動の検出(--docker.auto 付き)をサポートしています。デフォルトでは、http://<url>/<container name>/(.*) のようなすべてのリクエストを、指定されたコンテナの内部 IP と公開ポートにリダイレクトします。アクティブ(実行中)なコンテナのみが検出されます。
このデフォルトはラベルで変更できます: