kubectlsso with keyマントシャベル日記



最近、チームはセキュリティ審査の準備などを理由に、遅延したネットワークやユーザーアクセス制御に注目している.
以前の仕事は大きな組織だったので、システムエンジニアリングチームは小さな部分に注意していました.
現在、規模の小さい組織には専門的なシステムエンジニアリングチームがなく、バックエンドチームのインフラストラクチャ資源を専門に担当する人員が不足しているため、多くの不足がある.
OS User、Kubernets User管理など改善課題は多いが、今回の挿入日記ではKubernets Userのアクセス制御を設定し、問題点を書き出そうとしている.

kubectl sso with keycloak


これまではkubectl configを1つだけ共有してkubernetsにアクセスしていたため,ユーザ認証の制御はあまりよくなかった.
Kubenetesは、ユーザーのオブジェクトが存在しないことを示します。Service Account TokenOIDCCAなどが認証の通過方法に関する問題であると考えている.
現在チームは、keycoatkというオープンソースのSSOソフトウェアをsingle sign-onのために使用しているため、OIDC認証を利用してユーザ認証を制御することを望んでいる.

Authentication


これに関連して、様々なkeyマントの使用例を探している間に、kubernetes korea groupにビデオが紹介され、このビデオを参照してkeyマントを通過するユーザ認証制御が実現された.
Kelowakを使用してKubernetesの管理を切断する方法-再配布
https://www.youtube.com/watch?v=owaK-V2MAjU
上のビデオを見てみると、すぐに理解できますが、以下のように設定プロセス全体を要約します.
  • キーマントクライアントを作成し、必要なプロトコルマッパを作成
  • プロトコルマッパによりaccess tokenにグループ情報
  • を注入する.
  • KubernetesクラスタにおいてOIDC Identity Providersを使用して鍵マント
  • を追加する.
    修正
  • kubectlは、鍵マントからトークンを受信し、API要求
  • を発行するように設定する.
    鍵漏洩クライアントとプロトコルマッピングとは?
  • Clients are entities that can request Keycloak to authenticate a user.
  • Protocol mappers map items (such as an email address, for example) to a specific claim in the identity and access token.
  • このように設定が完了すると,Kubernetesのユーザ認証を行うために鍵マントからトークンを発行する必要がある.
    この場合,それぞれのkeycookアカウントを用いることができ,自然と個人別にユーザ分離を行うことができる.

    Authorization

    User 접근 제어の目的は、口座の分離だけでなく、適切な権限の付与も含む.
    Kubernetesも、認証によってAPIリクエストを許可することはありません.
    次の図に示すように、認証は通過しました.権限を検証するために、認証プロセスも通過する必要があります.

    https://kubernetes.io/ko/docs/concepts/security/controlling-access/

    ロールの定義


    Kubernetesは、ロールベースのアクセス制御(RBAC)にロール、ロールバインドなどのオブジェクトを提供し、適切な権限を作成するために使用できます.
    この場合、roleとrole-bindingによって有効なscopeがあるので、以下の場合を考慮してtypeで使用できるのでroleを作成しました.
    AccessRoleタイプバインドタイプクラスタレベルリソース(ノード、pvなど)クラスタルーティングバインド非リソースURL(/api、/healtzなど)複数のネーミングスペース内のリソースおよびすべてのネーミングスペース内のリソースで、複数のネーミングスペース内の特定のネーミングスペースを持つネーミングスペースリソースに対して同じクラスタボリュームを繰り返し使用する場合、各ネーミングスペース内の特定のネーミングスペースを持つネーミングスペースリソースボリュームネーミングスペースで定義する必要があります.rolerolebinding

    役割の割当て


    作成したロールをユーザーにバインドする必要があります.
    ユーザsso認証に鍵マントクライアントを設定する過程で、要求されたaccess tokenにグループ情報をマッピングすることも設定される.
    グループベースのアクセス制御は、ロールの作成/管理にも便利であるため、ロールバインドはSubjectをグループ向けに設定します.

    KeyマントキャラクターとKubernetesのグループ


    これにより、keycookによってユーザ認証が処理され、認証されたユーザは、自分に与えられたロールに基づいて認証によってリソースにアクセスすることができる.
    しかし、これはなぜ可能なのでしょうか.
    正確に言えば、鍵マントから受け取ったtokenを通過しましたが、Kubernetesは何を見て、ライセンスを処理しましたか?どのようにUserがどのようなグループなのか知っていますか?
    これは、前に設定したkeycoatk clientのプロトコルマッピングに答えます.
    プロトコルマッパを設定するときに、KeyマントキャラクタがGroupという情報をToken内部に注入するように設定されているため、KubernetesはコミットしたTokenでGroup情報をチェックし、ライセンス処理を行います.
    次に、実際にKeloakを用いて受信したTokenをjwt.ioで復号する内容であり、Token情報にGroupsというキーが存在することがわかる.
    {
      "jti": "***,
      "exp": ***,
     (생략)
      "name": "LEE GEUNJE",
      "groups": [
        "developer"
      ],
      "preferred_username": "[email protected]",
      "given_name": "LEE",
      "family_name": "GEUNJE",
      "email": "[email protected]"
    }

    oidc authenticator: initializing plugin: 403 Forbidden


    すべての設定が完了した後、平和な日が続くある日、kubernetesリソースを確認しようとした私は突然次のようなエラーに遭遇しました.
    $ kubectl get pod
    error: You must be logged in to the server (Unauthorized)
    何が起こっているのか考えています.この間設定変更してないのに…
    昨日はまだ怒っていたのにどうして急にこんなことになったの.
    気がふさいでapiサーバーのログを見てみると、いくつかのログが目立っていました.
    E0308 08:02:34.802539 10 authentication.go:53] Unable to authenticate the request due to an error: [invalid bearer token, oidc: authenticator not initialized, unknown]
    E0308 08:02:34.802539 10 authentication.go:53] Unable to authenticate the request due to an error: [invalid bearer token, oidc: authenticator not initialized, unknown]
    E0308 08:00:25.549378 10 oidc.go:224] oidc authenticator: initializing plugin: 403 Forbidden: <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>
    <hr><center>nginx/1.17.8</center>
    </body>
    </html>
    うん.403 Forbidden ? authenticator not initialized ?
    よく考えてみると、あるPODのリソース使用量が急激に増加していることを確認したところ、あるPODがコインを採掘していることが判明したので、all open(0.0.0.0/0)に設置されている鍵マントalbを後続措置として制限したことを思い出した.
    Gitlab CPU Utilization is HIGH due to XMRig tool
    https://github.com/sameersbn/docker-gitlab/issues/2448#issuecomment-962450231
    これは、apiサーバがIDCプロバイダ間でネットワーク通信の問題が発生し、authenticatorが正常に動作しないことを疑わせる.

    SSHはKubectlできない


    私たちのチームはkubectlだけでなく、SSHアクセスにもkeycook認証を使用しています.
    すなわち,bastionサーバへのSSHアクセス時にも鍵を用いてユーザ認証を行うのではなく,鍵マントアカウントを用いてアクセス制御を行う.
    key秘密漏洩alb制限措置の後、sshとkubectlはkey秘密漏洩tokenを通じて認証されますが、なぜsshはアクセスできますが、kubectlはできませんか?
    以下のEKSアーキテクチャの内容に示すように、control planeEKS managed VPCに生成され、SSHとKubectlの違いといえば、鍵マントと通信するネットワーク経路が異なる.
  • SSH
    - EC2 -> NAT(Customer VPC) -> External -> ALB -> Keycloak
  • EKS API server
    - API Server -> EKS managed VPC(NAT?) -> External -> ALB -> Keycloak

  • eks-architecture

    EKS管理のVCC IPをACLに追加


    では、上記のように、EKS managed VPCのIPをKeloak ALB ACLに追加すればよい.
    でも「EKSが管理しているVPC情報をどうやって知るのか...」そうため息をつくと、組長が来て、「APIサーバーのエンドポイント」のIPを入れればいいのではないでしょうか.はい.
    AWSコンソールを直接開き、dnsutilでEKSのAPI 서버 엔드포인트を問い合わせ、IPをALB ACLに入れます.

    だから結構です.(ああ...)
    こうしてわけもわからず私の足首をつかんだやつがいなくなった.

    の最後の部分


    上記の手順により、チーム内のエンジニアがそれぞれのアカウントを通じてKubernetesにアクセスし、権限もよく分離され、特定の名前空間のリソースのみがアクセスできます.
    KubernetesをEKSとして接したときに知らなかった部分が多く、今でも知る必要があることが多いです.
    以前OpenStackをしていたときに一番気にしなかった部分はユーザー認証(keystone)という概念でしたが、今まで、こんなに気を使っていたら勉強すべきだったのですが、できませんでした.oidc authenticator: initializing plugin: 403 Forbiddenの問題については、API 서버 엔드포인트のIPを使用してACLを処理することが最善の方法だと思います.
    privateサブネットにはクラスタがあり、相互間の通信は外部を経由する必要はなく、private DNSを単独で作成し、もう一つのALBを構築してはどうかという意見もある.
    そのため、EKSはOIDC Identity Providersしか登録できないようです.
    直接公開される気がします
    この文章の内容はDev環境で発生しているので、後でprd環境については、個別のprivate route 53を作成して問題を解決します.
    シャベルの連続.