AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / server / Perguntas / 1166553
Accepted
W Jeswin
W Jeswin
Asked: 2024-10-14 15:47:49 +0800 CST2024-10-14 15:47:49 +0800 CST 2024-10-14 15:47:49 +0800 CST

Escape duplo em $ssl_client_s_dn do nginx

  • 772

Tenho um certificado de cliente que tem caracteres não ingleses no assunto. Quando uso o atributo $ssl_client_s_dn do ngx_http_ssl_module, o valor é escapado duas vezes.

valor real = "L=D'UNCONGÉ"

o \xC3 é codificado novamente para obter \x5CC3, preciso evitar isso

valor real = "L=D'UNCONG\x5CC3\x5C89"

valor esperado = "L=D'UNCONG\xC3\x89"

Alguém pode me aconselhar sobre o que fiz de errado? Como posso evitar isso?

nginx
  • 1 1 respostas
  • 64 Views

1 respostas

  • Voted
  1. Best Answer
    bellasys
    2024-10-16T23:42:37+08:002024-10-16T23:42:37+08:00

    Há muitas peças neste quebra-cabeça.

    Primeiro, deixe-me comentar que o "Valor Esperado" que você mencionou inclui constantes numéricas Hexadecimais (formato: \xHH). Isso só seria 'esperado' onde esta é uma codificação padrão.

    O próprio Nginx usa a maioria das literais de string e constantes numéricas, como representações hexadecimais, octais ou Unicode, sem problemas nas configurações; e o mesmo acontece quando ele lê cabeçalhos. Por isso, fiquei inicialmente confuso com o formato incomum desse "escape duplo".

    Verifiquei o RFC sobre a codificação Cert de Distinguished Name (DN). Há uma diferença sutil em como a Cert String é formatada em comparação a algo como strings de URL duplamente codificadas, mas a diferença é importante.

    Observe o RFC e, em particular, observe a tabela de exemplos no final da seção 5 e veja os valores "entre aspas" vs. UTF-8: https://datatracker.ietf.org/doc/html/rfc2253#section-5

    O RFC afirma que o Cert UTF-8 "É" (0xC389) quando Quoted é \C3\89. Com base no Valor Real que você relatou, isso confirma => que o Nginx está lendo um valor Quoted do próprio Cert.

    Então o Nginx escapa o "\" em \C3\89 e isso explica por que ele se torna \x5CC3\x5C89 como em seu "Valor Real".

    No entanto, essa representação incomum é (provavelmente) limitada aos Logs do próprio Nginx - dependendo de suas configurações, provavelmente não é o valor real de $ssl_client_s_dn.

    Por padrão, o Nginx escapa strings em Logs, mas não escapa valores em variáveis. Em relação ao formato de log, você pode evitar o escape adicionando uma opção à diretiva log_format:

    #find this in the http {} block of Nginx
    # 'main' is just an example name
      log_format main ... # 'main' is a just a name, yours might be different
    
    #make it so
      log_format main escape=none ... # keep your name, not 'main' 
    

    Anexe a variável $ssl_client_s_dn ao local apropriado no valor log_format para que ela possa ser verificada. Estude o Nginx Log Module se necessário para ver como fazer isso https://nginx.org/en/docs/http/ngx_http_log_module.html

    Se você é novo no Nginx, isso pode ser muita coisa para destrinchar... então deixe-me rever os pontos principais e, após cuidadosa consideração, espero que você consiga adaptar a configuração corretamente para atender ao caso de uso exato:

    1. Este problema é específico da implementação, o que significa que não tem uma solução genérica. Não há uma questão fundamental simples aqui - é um caso complexo de vários fatores dependentes.

    2. Evitar logs de escape ajudará você a entender melhor o valor que recebeu do certificado; certifique-se de registrar pelo menos $ssl_client_s_dn até ter certeza de que tudo está funcionando conforme o esperado.

    3. Se algum Proxy/Servidor/Serviço diferente de um Usuário Final enviar o Certificado do Cliente para o Nginx, tenha em mente que esta é a principal Dependência: a maneira como eles constroem a codificação do Certificado determina como o DN do Assunto do Certificado será lido pelo Nginx.

    4. Observe que este ponto sozinho poderia resolver casos em que o Upstream está deturpando o valor do Header - Se você estiver enviando o valor de $ssl_client_s_dn para o App/Uptream em um Header, certifique-se de NÃO colocá-lo entre aspas, porque isso não precisa ser escapado para o Nginx e provavelmente não precisa ser escapado pelo Upstream. Se isso já tiver sido feito, altere para que você o coloque entre aspas. Embora eu prefira o método sem aspas, esta simples alteração pode "consertar" o problema para o App/Upstream:

       location /blah {
           ...
           #try this first, replacing X-Subject-DN with the correct Header name
           proxy_set_header X-Subject-DN $ssl_client_s_dn;
      
           #then try this, do not use both else duplicate Header
           proxy_set_header X-Subject-DN "$ssl_client_s_dn";
       }
      
    5. Estou fazendo muitas suposições. Você pode não encaminhar o Cert Subject DN para outro recurso, você pode apenas avaliá-lo no Nginx, você pode já ter atualizado log_format com escape=none , há tantas situações possíveis...

    Em todos esses casos, lembre-se de que cada componente pode escapar do valor manipulado ou escapá-lo somente em Logs. Saber como cada componente é configurado e como eles manipulam String Literals, caracteres multibyte UTF-8 e/ou Constantes Numéricas é essencial!

    Considere pelo menos estes fatores:

    a => Remetente do Certificado do Cliente, como os dados iniciais do Certificado são formatados

    b => O Nginx normalmente usa o DN exato do assunto do certificado que recebe, mas escapa valores em seus próprios logs por padrão, a menos que você substitua esse comportamento.

    c => App/Upstream (se você enviar $ssl_client_s_dn no Cabeçalho) pode escapar o valor do Cabeçalho, ou pode deixá-lo intocado e apenas escapá-lo em Logs como o Nginx...

    Esses são conceitos fundamentais - que tal fornecer uma solução para a questão?

    Há uma maneira de modificar o valor do Cert DN definido em $ssl_client_s_dn ao enviar para o Upstream, se isso for desejado.

    #place in Nginx http block only
    map $ssl_client_s_dn $client_dn_fix {
        default $ssl_client_s_dn;
        "L=D'UNCONG\C3\89" "L=D'UNCONGÉ"; #Actual Value you mention
        "L=D'UNCONG\xC3\x89" "hex-constant";
        "L=D'UNCONG\x5CC3\x5C89" "escaped-hex-const";
        "L=D'UNCONGÉ" "original";
        "L=D'UNCONG\x5CxC3\x5Cx89" "double-escaped";
        "~L=D'UNCONG[\x5C]C3[\x5C]89" "regex-cert-escaped";
        "~L=D'UNCONG[\x5C]xC3[\x5C]x89" "regex-hex-escaped";
    }
    
    #then add to the Location {} block as appropriate
    location /blah {
        ...
        proxy_set_header X-Subject-DN $client_dn_fix;
        ...
    }
    

    Registre o valor de $client_dn_fix e $ssl_client_s_dn.

    Ao revisar os Logs, você poderá ver o valor real do Certs Subject DN expresso em $ssl_client_s_dn e $client_dn_fix, validando então a visão do Nginx sobre ele.

    Depois de revisar os logs para entender melhor as operações internas, você pode substituir valores como "hex escape" ou "original" por uma string como: "L=D'UNCONGÉ" (literais UTF-8) ou "L=D'UNCONG\xC3\x89" para que o Upstream receba o "Valor Esperado".

    Há muitas maneiras possíveis de implementar os conceitos aqui, depende apenas do que você realmente precisa.

    Edição: O OP confirmou que "L=D'UNCONG\C3\89" aparece nos Logs ao verificar o valor de $ssl_client_s_dn , então o mapa a seguir finalmente é útil, observe que isso reduz Chave/Valores para 2 entradas:

    #place in Nginx http block only
    map $ssl_client_s_dn $client_dn_fix {
        default $ssl_client_s_dn;
        "L=D'UNCONG\C3\89" "L=D'UNCONG\xC3\x89"; #Expected Value
    }
    # $client_dn_fix now contains the Expected Value as OP requested
    # modify this value as desired, could also set with original String Literals like => "L=D'UNCONGÉ" 
    
    • 0

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Você pode passar usuário/passar para autenticação básica HTTP em parâmetros de URL?

    • 5 respostas
  • Marko Smith

    Ping uma porta específica

    • 18 respostas
  • Marko Smith

    Verifique se a porta está aberta ou fechada em um servidor Linux?

    • 7 respostas
  • Marko Smith

    Como automatizar o login SSH com senha?

    • 10 respostas
  • Marko Smith

    Como posso dizer ao Git para Windows onde encontrar minha chave RSA privada?

    • 30 respostas
  • Marko Smith

    Qual é o nome de usuário/senha de superusuário padrão para postgres após uma nova instalação?

    • 5 respostas
  • Marko Smith

    Qual porta o SFTP usa?

    • 6 respostas
  • Marko Smith

    Linha de comando para listar usuários em um grupo do Windows Active Directory?

    • 9 respostas
  • Marko Smith

    O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL?

    • 3 respostas
  • Marko Smith

    Como determinar se uma variável bash está vazia?

    • 15 respostas
  • Martin Hope
    Davie Ping uma porta específica 2009-10-09 01:57:50 +0800 CST
  • Martin Hope
    kernel O scp pode copiar diretórios recursivamente? 2011-04-29 20:24:45 +0800 CST
  • Martin Hope
    Robert ssh retorna "Proprietário incorreto ou permissões em ~/.ssh/config" 2011-03-30 10:15:48 +0800 CST
  • Martin Hope
    Eonil Como automatizar o login SSH com senha? 2011-03-02 03:07:12 +0800 CST
  • Martin Hope
    gunwin Como lidar com um servidor comprometido? 2011-01-03 13:31:27 +0800 CST
  • Martin Hope
    Tom Feiner Como posso classificar a saída du -h por tamanho 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent Como determinar se uma variável bash está vazia? 2009-05-13 09:54:48 +0800 CST

Hot tag

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve