La magie de 2 lignes dans Lua, ou comment transmettre les en-tĂȘtes d'autorisation HTTP Authorization originaux au service Web

L'article sera utile Ă  ceux:



  • qui doit utiliser plusieurs types d'autorisation dans une seule demande au serveur;
  • qui veut ouvrir les services du monde Kubernetes / Docker Ă  l'Internet gĂ©nĂ©ral, sans rĂ©flĂ©chir Ă  la maniĂšre de protĂ©ger un service particulier;
  • pense que tout a dĂ©jĂ  Ă©tĂ© fait par quelqu'un et aimerait rendre le monde un peu plus pratique et plus sĂ»r.


Avant-propos Les



services mis Ă  disposition via Kubernetes disposent d'un riche ensemble de mĂ©thodes d'autorisation. L'un des plus Ă  la mode est l'en-tĂȘte Authorization: Bearer - par exemple: autorisation JWT ( JSON Web Token ) avec le transfert de nombreuses clĂ©s, et donc de valeurs, dans un en-tĂȘte. Il existe Ă©galement des autorisations de base, par exemple pour le registre (rĂ©fĂ©rentiel d'images Docker). Cette autorisation n'utilise pas de cookies et est automatiquement ajoutĂ©e par le navigateur (sauf pour Safari - il y a des nuances que nous n'avons pas encore dĂ©cidĂ©es) Ă  toutes les demandes au serveur.







ProblĂšme 1:



Je ne peux pas me connecter via Firefox et Safari dans l'interface du systÚme d'exploitation de stockage, le chargeur est affiché, et c'est tout.



Mini-hypothĂšse:



problÚme de proxy. Une vérification rapide a montré le résultat: si l'autorisation sans utiliser de proxy (accÚs sécurisé universel avec un certificat), alors tout fonctionne. Alors, quel est le problÚme?



AprĂšs avoir analysĂ© la pile rĂ©seau, nous avons rĂ©alisĂ© que l'en-tĂȘte Authorization Ă©tait utilisĂ©, cependant, plus tĂŽt, lors de la configuration du proxy des services Rancher, il a Ă©tĂ© dĂ©couvert que cet en-tĂȘte est passĂ© au service proxy et contient les donnĂ©es d'autorisation pour le certificat, il a donc Ă©tĂ© dĂ©cidĂ© de simplement le supprimer une fois le processus d'autorisation terminĂ© (FakeBasicAuth ).



ProblĂšme 2:



Dans de nombreux serveurs Web, l'autorisation de certificat personnel est implĂ©mentĂ©e par Ă©mulation de l'autorisation de base (en fait, interfĂ©rant avec la demande de l'utilisateur), probablement afin de rĂ©duire les changements dans le code principal du serveur Web. Cette mĂ©thode s'appelle FakeBasicAuth. AprĂšs avoir dĂ©fini un tel en-tĂȘte, le serveur Web Ă©crase l'en-tĂȘte d'autorisation qui provient de l'utilisateur.



HypothĂšses:



  1. La portĂ©e de l'en-tĂȘte FakeBasicAuth se prĂȘte Ă  encore plus de restriction, de sorte que l'en-tĂȘte d'origine est restaurĂ© pour transmission Ă  la ressource mandatĂ©e de sorte que seul l'en-tĂȘte d'origine, le cas Ă©chĂ©ant, soit transmis.
  2. La portĂ©e de l'en-tĂȘte Authorization peut ĂȘtre conçue de sorte que l'en-tĂȘte soit enregistrĂ© avant d'activer le mĂ©canisme FakeBasicAuth et restaurĂ© aprĂšs.


État visible - Objectif: le



systÚme d'exploitation de stockage autorise, vous pouvez configurer ce service tout en conservant une approche unifiée pour rendre les services disponibles sur Internet externe.



Objectif supplémentaire:



accÚs http unifié, rapide et sécurisé tout en préservant les fonctionnalités de tous les services http possibles (par exemple, API REST pour une application mobile ou Registry Docker).



Comment vérifier?



  • docker login registry-rancher.xxx.ru - en utilisant les clĂ©s et login / mot de passe.
  • storageos-rancher.xxx.ru/#/login - en utilisant le login et le mot de passe des configs secret rancher.xxx.ru/p/c-84bnv : p-qj9qm / secrets / kube-system: init-secr ... (ne fonctionne pas dans Safari ).
  • registry-ui-rancher.xxx.ru - en utilisant un navigateur et un login / mot de passe du registre. Pour ceux qui lisent attentivement l'astuce: vous pouvez utiliser cette interface au lieu de la connexion standard du docker registry-rancher.xxx.ru - il y a un proxy intĂ©grĂ© au registre.


Test des hypothĂšses:



1. Sur la base de l'expérience précédente, essayons de trouver un moyen sur Internet pour de telles demandes: authentification apache externe basique via cert.



Il y avait un article plus ou moins adéquat sur ldap . De cette façon:



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


Et puis passez le titre dans des en-tĂȘtes supplĂ©mentaires Ă  travers la construction



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


Mais, malheureusement, cette construction n'implique pas la crĂ©ation d'un en-tĂȘte identique, l'en-tĂȘte de la requĂȘte de l'utilisateur, et env est formĂ© de maniĂšre incorrecte.



Par conséquent, la méthode basée sur la réécriture standard s'est avérée inutile et compliquée.



2. Si nous ne pouvons pas le faire en standard, alors nous devons nous tourner vers lua, nous avons vu précédemment qu'il y a des blocs de traitement de demande qui sont exécutés avant que les certificats ne soient traités, regardez à nouveau le diagramme de l'article lua_load_resty_core et l'instruction module_lua_writinghooks avec la construction précoce.



Il s'avĂšre que nous pouvons utiliser le mĂȘme script ( Comment, chez ZeroTech, nous nous sommes fait des amis Apple Safari et des certificats clients avec des websockets) pour conserver l'en-tĂȘte Authorization avant de le remplacer par FakeBasicAuth.







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


Dans Lua, cela ressemble maintenant Ă  ceci:




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


Remarque: les



nouveaux designs sont en gras. Et comme on sait que l'env obtenu de Lua n'est disponible que pour les expressions expr, on ajoute une construction à cÎté du cryptage du jeton zt-cert:



# cookies sortants Ă  l'utilisateur




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


# transmettre les en-tĂȘtes au service mandatĂ©




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


La disponibilité des données pour le transfert vers le service a été vérifiée en transférant les données à l'utilisateur vers le navigateur:



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


Le plus intĂ©ressant ici est un moyen de vĂ©rifier la prĂ©sence de donnĂ©es, afin de ne pas transmettre l'en-tĂȘte au service mandatĂ© s'il ne provenait pas de l'extĂ©rieur du navigateur de l'utilisateur. La deuxiĂšme partie de la construction en est responsable:



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


AchĂšvement: Il n'y a pas de



solutions toutes faites sur Internet pour le moment, environ trois heures ont été passées à chercher et à essayer de tester les variantes, car je ne voulais pas «réinventer la roue».



Ajout de 5 lignes, dont 3 peuvent ĂȘtre supprimĂ©es en toute sĂ©curitĂ©. Qu'est-ce que tu penses? - Écrivez vos options de rĂ©ponse dans les commentaires de l'article.



Je ne voulais pas Ă©crire sur cette expĂ©rience, car en fait il ne s'agit que de 2 lignes et la rubrique Autorisation atteindra le destinataire, mais j'ai quand mĂȘme dĂ©cidĂ© de partager l'information, car elle utilise une bonne rĂ©serve de connaissances des recherches prĂ©cĂ©dentes sur les certificats (nous parlons de cet article ). De plus, il n'y a pratiquement pas de casse-cou pour Ă©crire quelque chose de leur propre et si simple dans une langue inconnue.






All Articles