Luaの2行の魔法、または元のHTTPAuthorizationヘッダー-authorizationヘッダーをWebサービスに取り込む方法

この記事はそれらに役立ちます:



  • サーバーへの1回のリクエストで複数のタイプの認証を使用する必要がある人。
  • 特定のサービスを保護する方法を考えずに、Kubernetes / Dockerの世界のサービスを一般的なインターネットに公開したい人。
  • すべてがすでに誰かによって行われていると考えており、世界をもう少し便利で安全なものにしたいと考えています。






Kubernetesを通じて提供されるForewordServicesには、豊富な認証方法があります。よりファッショナブルなものの1つは、Authorization:Bearerヘッダーです。例:1つのヘッダーで多くのキー(したがって値)を転送するJWT認証(JSON Webトークン)。レジストリ(Dockerイメージリポジトリ)などの基本的な権限もあります。この認証はCookieを使用せず、サーバーへのすべての要求にブラウザーによって自動的に追加されます(Safariを除く-まだ決定していないニュアンスがあります)。







問題1:



ストレージOSインターフェイスでFirefoxとSafariを介してログインできず、ローダーが表示され、それだけです。



ミニ仮説:



プロキシの問題。簡単なチェックで結果が示されました。プロキシを使用しない認証(証明書を使用したユニバーサルセキュアアクセス)の場合、すべてが機能します。それで、取引は何ですか?



ネットワークスタックを分析したところ、Authorizationヘッダーが使用されていることがわかりましたが、以前、Rancherサービスのプロキシの構成中に、このヘッダーがプロキシされたサービスに渡され、証明書の認証データが含まれていることが判明したため、認証プロセスの完了後に削除することにしました(FakeBasicAuth )。



問題2:



多くのWebサーバーでは、個人証明書による認証は、おそらくWebサーバーのメインコードの変更を減らすために、基本認証のエミュレーション(実際にはユーザーの要求を妨害する)によって実装されます。このメソッドはFakeBasicAuthと呼ばれます。このようなヘッダーを設定した後、WebサーバーはユーザーからのAuthorizationヘッダーを上書きします。



仮説:



  1. FakeBasicAuthヘッダーのスコープはさらに制限が厳しく、元のヘッダーが復元されてプロキシされたリソースに転送され、元のヘッダーがあればそれだけが転送されます。
  2. Authorizationヘッダーのスコープは、FakeBasicAuthメカニズムをアクティブ化する前にヘッダーを保存し、後で復元するように設計できます。


可視状態-目的:



ストレージOSが許可します。外部インターネットでサービスを利用できるようにするための統一されたアプローチを維持しながら、このサービスを構成できます。



追加の目標:



考えられるすべてのhttpサービス(たとえば、モバイルアプリケーション用のREST APIまたはレジストリDocker)の機能を維持しながら、統一された高速で安全なhttpアクセス。



確認方法は?



  • docker loginregistry-rancher.xxx.ru-キーとログイン/パスワードを使用します。
  • storageos-rancher.xxx.ru/#/login -コンフィグ秘密からのログインとパスワードを使用rancher.xxx.ru/p/c-84bnv:P-qj9qm /秘密/ KUBE-システム:INIT-SECRは...(Safariで仕事をしません)。
  • レジストリ-ui -rancher.xxx.ru-ブラウザとレジストリからのログイン/パスワードを使用します。注意深く読んでいる人のために、トリック:標準のdocker loginregistry-rancher.xxx.ruの代わりにこのインターフェースを使用することができます-レジストリへの組み込みのプロキシがあります。


仮説のテスト:



1。以前の経験に基づいて、そのような要求に対してインターネット上で方法を見つけてみましょう。証明書を介した外部の基本的なapache認証。ldap



については多かれ少なかれ適切な記事がありましたこの方法では:



RewriteEngine on
RewriteCond %{IS_SUBREQ} ^false$
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule . - [E=RU:%1]
RequestHeader set REMOTE_USER %{RU}e


そして、構造を通して追加のヘッダーでタイトルを渡します



RequestHeader add Authorization "expr=%{env:zt-auth-before}" "expr=%{env:zt-auth-before} =~/.{1,}/"


ただし、残念ながら、この構成は、同一のヘッダー、ユーザーの要求のヘッダーの作成を意味するものではなく、envが正しく形成されていません。



したがって、標準的な書き換えに基づく方法は役に立たず、複雑であることが判明しました。



2.標準でそれを行うことができない場合は、luaに目を向ける必要があります。証明書が処理される前に実行される要求処理ブロックがあることを以前に確認しました。記事lua_load_resty_coreのブロック図と初期構築のmodule_lua_writinghooks命令もう一度見てください



同じスクリプトを使用できることがわかりました(ZeroTechでAppleSafariとクライアント証明書をWebソケットで友達にした方法)FakeBasicAuthに置き換える前に、Authorizationヘッダーを保持します。







LuaHookAccessChecker /usr/local/etc/apache24/sslincludes/websocket_token.lua handler early


Luaでは、次のようになります。




require 'apache2'

function handler(r)
        local fmt = '%Y%m%d%H%M%S'
        local timeout = 3600 -- 1 hour
        local auth = r.headers_in['Authorization']

        r.notes['zt-cert-timeout'] = timeout
        r.notes['zt-cert-date-next'] = os.date(fmt,os.time()+timeout)
        r.notes['zt-cert-date-halfnext'] = os.date(fmt,os.time()+ (timeout/2))
        r.notes['zt-cert-date-now'] = os.date(fmt,os.time())

        if auth ~= nil then
                r.notes['zt-auth-before'] = auth
        end

        return apache2.OK
end


注:



新しい構造は太字で示されています。また、Luaから取得したenvはexpr式でのみ使用可能であることがわかっているため、zt-certトークンの暗号化の横に構造を追加します。



#ユーザーへの送信Cookie




Header set Set-Cookie "expr=zt-cert=%{sha1:...


#プロキシされたサービスにヘッダーを渡す




RequestHeader add Authorization "expr=%{env:zt-auth-before}" "expr=%{env:zt-auth-before} =~/.{1,}/"


サービスに転送するためのデータの可用性は、データをユーザーに転送してブラウザーに戻すことによってチェックされました。



Header add Authorization "expr=%{env:zt-auth-before}" "expr=%{env:zt-auth-before} =~/.{1,}/"


ここで最も興味深いのは、データの存在をチェックして、ヘッダーがユーザーのブラウザーの外部から送信されていない場合に、プロキシされたサービスにヘッダーを送信しないようにする方法です。建設の2番目の部分はこれに責任があります:



"expr=%{env:zt-auth-before} =~/.{1,}/"


完了:



現時点では、インターネット上に既成のソリューションはありません。「車輪を再発明」したくなかったため、バリエーションの検索とテストに約3時間かかりました。



5行を追加し、そのうち3行は安全に削除できます。どう思いますか?-記事へのコメントに回答のオプションを記入してください。



実際には2行しかなく、承認の見出しが宛先に届くため、この経験については書きたくありませんでしたが、証明書に関する以前の研究に関する豊富な知識を使用しているため、とにかく情報を共有することにしました(この記事について話します)。さらに、未知の言語で非常に単純な独自の何かを書く勇気のある人はほとんどいません。






All Articles