2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

KongAdvent Calendar 2024

Day 22

社内Proxy下でKong Gateway(Konnect)を利用する

Last updated at Posted at 2024-12-21

以前「Kong GatewayをProxy経由で利用する」というタイトルでForward Proxy Advanced Pluginを使っての接続方法を紹介した。
今回は逆方向でKongのコンポーネントを中に置き、外部のサービスに繋ぐようなケースを検証する。
社内Proxyが用意されていて、インターネットにアクセスする際にはそのProxy経由でないとアクセスできない会社は結構な数あると思う。
そういった会社の人がKong Gatewayを使う際に参考にしてもらえれば幸いである。
なお、今回はKonnectを使い、以下のような構成を検証する。
20241203085943.png

KonnectもKong Gatewayも基本的にはデプロイの仕方はそれほど変わらないので、Kong Gatewayで試す方はパラメータ設定部分などを上手く取り込んでもらえればと思う。

前提条件

以下の条件で検証する。

  • ProxyはSquidを利用
  • Data Plane、SquidはそれぞれAmazon Linux上に構築
  • Data PlaneはDockerで構築

なお、以下は既に実施済みのものとする。

  • EC2の払い出しやネットワーク設定
  • KonnectのControl Plane作成
  • EntraIDでのアプリケーション作成

構築・検証

以下の手順で構築・検証する。

  1. Proxyの構築
  2. Data Planeの構築
  3. 外部サービスとの接続
  4. OIDCとの連携確認

なお1の手順は前回記事のこちらと一緒なので割愛する。

Data Planeの構築

Dockerの有効化

Proxyのアドレスを環境変数に設定する。

export PROXY=http://172.31.66.0:3128

次に念の為Proxy経由で外部のサービスにアクセス出来ることを確認する。

$ curl -x http://172.31.66.0:3128 http://httpbin.org/user-agent
{
  "user-agent": "curl/8.5.0"
}

問題なければ.bashrcにProxyの環境変数を設定し、sourceコマンドで読み込む。

cat <<EOF >> ~/.bashrc
export HTTP_PROXY=$PROXY
export HTTPS_PROXY=$PROXY
export http_proxy=$PROXY
export https_proxy=$PROXY
export no_proxy="127.0.0.1,localhost"
export NO_PROXY="127.0.0.1,localhost"
EOF
.  ~/.bashrc

これで先程のcurlなどの環境変数を参照するコマンドはProxyの指定なしで外部にアクセスできるようになる。

$ curl http://httpbin.org/user-agent
{
  "user-agent": "curl/8.5.0"
}

次にDockerをインストールする。
今回はAmazon Linux 2023を使っているのでこちらの手順に従う。

sudo yum update -y
sudo yum install -y docker
sudo service docker start
sudo usermod -a -G docker ec2-user

ログインしなおせばdocker psが正常に動作する。

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

こちらの手順に従い、docker daemonがProxyを使えるようDocker側に設定を追加する。

sudo mkdir -p /etc/systemd/system/docker.service.d
cat <<EOF | sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=$HTTP_PROXY"
Environment="HTTPS_PROXY=$HTTPS_PROXY"
EOF

変更を反映しdaemonを再起動する。

sudo systemctl daemon-reload
sudo service docker restart

Kong Gatewayのイメージがpull出来ることを確認する。

docker pull kong/kong-gateway

Data Planeの構築

KonnectのWebUIにアクセスし、Gateway ManagerからControl Planeを選択後、Data Plane Nodes->New Data Plane NodeからData Planeのデプロイ画面に遷移する。
PlatformでLinux (Docker)を選択し、証明書を生成するとデプロイのためのdockerコマンドが表示されるのでこれをコピーする。
ここでProxyの設定を追加する。
ここでは以下のkong.confのパラメータを設定する。

  • proxy_server:Proxyを利用する際のURLを指定
  • proxy_server_ssl_verify:TLSの検証をするかどうか。ここではスキップするためoffを指定。
  • cluster_use_proxy:HybridモードでProxyを使う場合に指定。KonnectはHybridモード相当なのでonを指定

Dockerでデプロイする場合、kong.confの設定はKONG_を頭に付けて大文字にした環境変数を渡してあげることで設定できる。
そのため、以下のパラメータを追加してdocker runを実行すればよい

-e "KONG_PROXY_SERVER=$HTTPS_PROXY" \
-e "KONG_PROXY_SERVER_TLS_VERIFY=off" \
-e "KONG_CLUSTER_USE_PROXY=on" \

追加して起動すると無事にData Planeとして認識される。
20241202190802.png

外部サービスとの接続

Konnect上にService、Routeを作成し、Routeに対してForward Proxy Advanced Pluginを設定して外部サービスと通信できるか確認する。
ここではそれぞれのエンティティの作成はAPIを利用して行う。
API利用のため、最初にKonnectのトークン、ControlPlaneのID、KonnectのAPIエンドポイントをそれぞれ環境変数に設定する。

KONNECT_TOKEN=kpat_ER1WQxxxx
CP_ID=788397a0-b6f4-4dc8-a2f8-63cc6f0c62bb
KONNECT_API=https://us.api.konghq.com/v2

最初に外部サービスのhttpbin.orgと繋ぐためのエンティティServiceを作成する。

curl -s -X POST \
  "${KONNECT_API}/control-planes/${CP_ID}/core-entities/services" \
  -H "Authorization: Bearer $KONNECT_TOKEN" \
  -d name=httpbin-service \
  -d url=https://httpbin.org

作成時に表示されるServiceのIDを環境変数に設定する。

SERVICE_ID=75e92f55-5516-4173-8ad3-3491d6c51578

Proxy経由でService(httpbin.org)にアクセスするためのエンティティRouteを作成し、<ProxyのIP:Port>/httpbinでアクセスできるよう設定する。

curl -s -X POST \
  "${KONNECT_API}/control-planes/${CP_ID}/core-entities/routes" \
  -H "Authorization: Bearer ${KONNECT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "httpbin-route",
    "paths": ["/httpbin"],
    "service": {
      "id": "'"${SERVICE_ID}"'"
    }
  }'

作成したRouteのIDは後で使うので環境変数に設定しておく。

ROUTE_ID=0a8ca643-a2b2-4f1e-af17-fb39ce813b3c

Data Planeを構築したマシンからProxy経由で接続してみる。

$ curl -X GET -m 2 localhost:8000/httpbin
curl: (28) Operation timed out after 2002 milliseconds with 0 bytes received

今はForward Proxy Advanced Pluginの設定がないのでタイムアウトとなる。
Routeに対してForward Proxy Advanced Pluginを設定する。

curl -X POST \
  "${KONNECT_API}/control-planes/${CP_ID}/core-entities/routes/${ROUTE_ID}/plugins" \
  -H "Authorization: Bearer $KONNECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "forward-proxy",
    "config": {
      "http_proxy_host": "172.31.66.0",
      "http_proxy_port": 3128,
      "https_proxy_host": "172.31.66.0",
      "https_proxy_port": 3128,
      "https_verify": false
     }
   }'

設定すると自動でプラグインが有効化されるので、再度curlを試してみる。

$ curl -X GET -m 2 localhost:8000/httpbin
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>httpbin.org</title>
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700"
        rel="stylesheet">
:(省略)

無事通信出来た。

OIDCとの連携確認

最後におまけ的にOIDCとの連携も確認してみる。
OpenID Connect Pluginの設定にはProxyの設定があるので、これが使えるかの確認となる。
今回はEntraIDとの接続確認を行う。
EntraIDを使ったPlugin設定は過去に「APIの認証をEntra ID(旧Azure AD)で行う」で説明しているので今回は説明は大幅に省略して進める。
分からない部分は適宜そちらの記事を参照して欲しい。

Issuer、クライアントID、クライアントSecret、テナントIDを環境変数に設定する。

AZURE_ISSUER=https://login.microsoftonline.com/f177c1d6-50cf-49e0-818a-xxxxxx/v2.0
AZURE_CLIENT_ID=36cd0496-ab59-4ffd-8925-xxxxxx
AZURE_CLIENT_SECRET=U_u8Q~Jq3RRbYixxxxx
AZURE_TENANT_ID=$(sed "s@.*.com/\(.*\)/v2.0@\1@g" <<< "$AZURE_ISSUER")

次にリダイレクトURIを設定する。リダイレクト先は<ProxyのIP:Port>/<Routeのパス>になる。

ENDPOINT=http://localhost:8000/httpbin

OIDC PluginをRouteに設定する。

curl -X POST \
  "${KONNECT_API}/control-planes/${CP_ID}/core-entities/routes/${ROUTE_ID}/plugins" \
  -H "Authorization: Bearer $KONNECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "openid-connect",
    "config": {
      "issuer": "'"${AZURE_ISSUER}"'/.well-known/openid-configuration",
      "issuers_allowed": [
        "https://sts.windows.net/'"${AZURE_TENANT_ID}"'/",
        "https://login.microsoftonline.com/'"${AZURE_TENANT_ID}"'/v2.0",
        "https://login.windows.net/'"${AZURE_TENANT_ID}"'/v2.0"
      ],
      "client_id": ["'"${AZURE_CLIENT_ID}"'"],
      "client_secret": ["'"${AZURE_CLIENT_SECRET}"'"],
      "redirect_uri": ["'"${ENDPOINT}"'"],
      "display_errors": true,
      "scopes": [
        "openid",
        "email",
        "profile",
        "'"${AZURE_CLIENT_ID}"'/.default"
      ],
      "verify_parameters": false,
      "http_proxy": "http://172.31.66.0:3128",
      "https_proxy": "http://172.31.66.0:3128",
      "authorization_endpoint": "https://login.microsoftonline.com/'"${AZURE_TENANT_ID}"'/oauth2/v2.0/authorize",
      "token_endpoint": "https://login.microsoftonline.com/'"${AZURE_TENANT_ID}"'/oauth2/v2.0/token",
    }
  }'

前回記事と違う点として、http_proxyhttps_proxyでProxyを指定しており、authorization_endpointtoken_endpointでEntraIDの認可のエンドポイントとトークンのエンドポイントを指定している点である。
これ、試行方法によってエラーが出たり出なかったりして、必須なのかがよく分かっていないが、付けておけばとりあえず問題ないと思う。
なお、指定しなかった場合は以下のようなエラーが出る。

{"message":"An unexpected error occurred (authorization endpoint was not specified)"}

以上でOIDC認証をProxy経由で利用できる。

設定後、curlで動作確認する。
curlで確認する場合はトークンが必要なので以下で発行する。

BEARER_TOKEN=$(curl -X POST "https://login.microsoftonline.com/${AZURE_TENANT_ID}/oauth2/v2.0/token" \
 --data scope="${AZURE_CLIENT_ID}/.default" \
 --data grant_type="client_credentials" \
 --data client_id="${AZURE_CLIENT_ID}" \
 --data client_secret="${AZURE_CLIENT_SECRET}" \
 | jq -r '.access_token')

発行したトークンを使ってアクセスする。

$ curl -s $ENDPOINT/user-agent -H "Authorization: Bearer $BEARER_TOKEN"
{
  "user-agent": "curl/8.5.0"
}

問題なくアクセスできた。
またトークンがないとアクセスできないので、OIDC Plugin連携も適切に設定されていることが分かる。

おわりに

今回は閉鎖環境でData Planeを構築し、Forward Proxy Advanced PluginやOpenID Connect Pluginを使って外部のサービスにアクセスしてみた。
Proxyの設定箇所がコンポーネントごとに出てきて手間ではあるが、設定すればProxy経由でも問題なく動作することが確認できた。
自社のProxyのせいでなかなかKong Gatewayの検証が出来なかった人はこちらの記事を参考に試していただければ幸いである。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?