A mágica das 2 linhas em Lua ou como trazer os cabeçalhos de autorização de cabeçalho de Autorização HTTP originais para o serviço da web

O artigo será útil para aqueles:



  • quem precisa usar vários tipos de autorização em uma solicitação ao servidor;
  • quem deseja abrir os serviços do mundo Kubernetes / Docker para a Internet geral, sem pensar em como proteger um determinado serviço;
  • pensa que tudo já foi feito por alguém e gostaria de tornar o mundo um pouco mais cómodo e seguro.


Os



serviços de Foreword disponibilizados por meio do Kubernetes têm um amplo conjunto de métodos de autorização. Um dos mais modernos é o cabeçalho Authorization: Bearer - por exemplo: autorização JWT ( JSON Web Token ) com a transferência de muitas chaves e, portanto, valores, em um cabeçalho. Existem também autorizações básicas, por exemplo, para o Registro (repositório de imagens Docker). Esta autorização não usa cookies e é adicionada automaticamente pelo navegador (exceto para Safari - existem nuances que ainda não decidimos) a todas as solicitações ao servidor.







Problema 1:



Não consigo fazer login através do Firefox e Safari na interface do Storage OS, o Loader é mostrado e pronto.



Mini-hipótese:



problema de proxy. Uma rápida verificação mostrou o resultado: se a autorização sem usar proxy (acesso seguro universal usando um certificado), então tudo funciona. Qual é o problema?



Depois de analisar a pilha de rede, percebemos que o cabeçalho de autorização está sendo usado, porém, anteriormente, durante a configuração do proxy dos serviços do Rancher, verificou-se que esse cabeçalho é passado para o serviço com proxy e contém os dados de autorização do certificado, portanto, decidiu-se simplesmente excluí-lo após a conclusão do processo de autorização (FakeBasicAuth )



Problema 2:



Em muitos servidores web, a autorização de certificado pessoal é implementada através da emulação da autorização Basic (na verdade, interferindo na solicitação do usuário), provavelmente para reduzir as alterações no código principal do servidor web. Este método é denominado FakeBasicAuth. Depois de definir esse cabeçalho, o servidor da web sobrescreve o cabeçalho de autorização que vem do usuário.



Hipóteses:



  1. O escopo do cabeçalho FakeBasicAuth se presta a ainda mais restrições, de modo que o cabeçalho original é restaurado para transferência para o recurso com proxy, de modo que apenas o cabeçalho original, se houver, será transferido.
  2. O escopo do cabeçalho de autorização pode ser projetado de forma que o cabeçalho seja salvo antes de ativar o mecanismo FakeBasicAuth e restaurado depois.


Estado visível - Objetivo: o



SO de armazenamento autoriza, você pode configurar este serviço enquanto mantém uma abordagem unificada para disponibilizar os serviços na Internet externa.



Objetivo adicional:



Acesso http unificado, rápido e seguro, mantendo a funcionalidade de todos os serviços http possíveis (por exemplo, API REST para um aplicativo móvel ou Registry Docker).



Como verificar?



  • docker login registry-rancher.xxx.ru - usando chaves e login / senha.
  • storageos-rancher.xxx.ru/#/login - usando login e senha de configs secret rancher.xxx.ru/p/c-84bnv : p-qj9qm / secrets / kube-system: init-secr ... (não funciona no Safari )
  • registry-ui-rancher.xxx.ru - usando um navegador e login / senha do Registro. Para quem lê com atenção, o truque: você pode usar essa interface em vez do registro de login docker padrão-rancher.xxx.ru - há proxy embutido para o Registro.


Hipóteses de teste:



1. Com base na experiência anterior, vamos tentar encontrar uma maneira na Internet para tais solicitações: autenticação apache external basic via cert.



Havia um artigo mais ou menos adequado sobre o ldap . Nesse caminho:



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


E então passe o título em cabeçalhos adicionais durante a construção



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


Mas, infelizmente, essa construção não implica na criação de um cabeçalho idêntico, o cabeçalho da solicitação do usuário, e env é formado incorretamente.



Portanto, o método baseado na reescrita padrão revelou-se inútil e complicado.



2. Se não pudermos fazer isso como padrão, então precisamos voltar para lua, vimos anteriormente que existem blocos de processamento de solicitação que são executados antes do processamento dos certificados, observe novamente o fluxograma do artigo lua_load_resty_core e a instrução module_lua_writinghooks com a construção inicial.



Acontece que podemos usar o mesmo script ( Como nós na ZeroTech fizemos amigos Apple Safari e certificados de cliente com websockets) para preservar o cabeçalho de autorização antes de substituí-lo por FakeBasicAuth.







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


Em Lua, agora é assim:




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


Nota: os



novos designs estão em negrito. E como sabemos que o env obtido de Lua está disponível apenas para expressões expr, adicionamos uma construção ao lado da criptografia do token zt-cert:



# cookies de saída para o usuário




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


# passa cabeçalhos para o serviço com proxy




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


A disponibilidade de dados para transferência para o serviço foi verificada pela transferência de dados de volta para o usuário para o navegador:



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


O mais interessante aqui é uma forma de verificar a presença de dados, de modo a não transmitir o cabeçalho ao serviço proxy se ele não vier de fora do navegador do usuário. A segunda parte da construção é responsável por isso:



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


Conclusão: Não existem



soluções prontas na Internet no momento, cerca de três horas foram gastas pesquisando e tentando testar as variações, pois não queria “reinventar a roda”.



Adicionadas 5 linhas, 3 das quais podem ser removidas com segurança. O que você acha? - Escreva suas opções de respostas nos comentários do artigo.



Não queria escrever sobre esta experiência, pois na verdade são apenas 2 linhas e o cabeçalho da Autorização chegará ao destinatário, mas decidi compartilhar a informação de qualquer maneira, já que utiliza um bom acervo de conhecimentos de pesquisas anteriores sobre certificados (estamos falando sobre este artigo ). Além disso, dificilmente existem pessoas ousadas para escrever algo próprio e tão simples em uma língua desconhecida.






All Articles