Par de socket fronte a cabeceira reenviada: en que enderezo confiar?
O par de socket e unha cabeceira reenviada son probas distintas. Compare o que demostra cada unha e confíe na cabeceira só a través dunha cadea de proxy que vostede controle.
Unha solicitude que chega á súa aplicación leva dous tipos de probas sobre o enderezo: o par que abriu a conexión de rede e un campo HTTP que afirma o enderezo dun cliente anterior. Responden a preguntas distintas. O par de socket obsérvase, mentres que a cabeceira afírmase por quen a escribiu, e ningún dos dous debería substituír en silencio ao outro nun rexistro ou nunha regra de acceso. A comparación seguinte mantén os dous separados e despois mostra a única disposición na que a cabeceira resulta utilizábel.
Describa a ruta antes de comparar nada:
Client -> approved reverse proxy -> application originNesa disposición, o par de socket da orixe adoita ser o proxy, e unha cabeceira de reenvío pode levar a afirmación do proxy sobre o cliente. O seu valor procede da relación controlada con ese proxy, non do nome da cabeceira.
Dous tipos de probas sobre o enderezo
O par de socket é un feito sobre unha conexión TCP: algo completou un saúdo desde ese enderezo. Non é necesariamente a persoa, o dispositivo ou a conta que lle importa, porque unha VPN ou unha saída de Tor poden ser lexitimamente a fonte que observa un servizo. Aínda así, é o único enderezo que o propio host verificou, e niso consiste todo o seu valor.
Un campo de reenvío son metadatos sobre unha cadea. X-Forwarded-For, X-Real-IP e o campo estandarizado Forwarded pode escribilo calquera cliente que chegue a un punto final que os reproduce, así que a súa fiabilidade depende por completo de a quen se lle permitiu establecelos.
Manteña ambos no contexto da solicitude con nomes distintos. Unha aplicación que sobrescribe o par coa cabeceira perde a capacidade de reconstruír máis tarde un erro de confianza, e iso é xusto cando o necesita.
Unha cabeceira nunca redirixe a conexión
Escribir un enderezo nun campo de reenvío non cambia a orixe da conexión TCP que chega ao servidor, nin altera o encamiñamento en ningún punto da ruta. O encamiñamento VPN ordinario ou NAT de orixe entrega o tráfico sen ningunha cabeceira HTTP. Do mesmo xeito, unha pasarela de tránsito non reescribe un intercambio HTTPS ben protexido sen cambiar a disposición do punto final TLS.
O erro inverso é igual de común: HTTPS non fai veraz unha cabeceira de reenvío proporcionada polo cliente. Protexe o transporte dunha afirmación falsa exactamente igual que o dunha verdadeira.
Se un colega propón un cambio de cabeceira para arranxar un problema de encamiñamento, o diagnóstico xa foi mal. Arranxe a ruta ou arranxe a configuración do proxy que escribe a cabeceira.
Nomee o proxy autorizado a afirmar
Dúas regras fan utilizábel un campo de reenvío, e ambas son configuración e non código. A beira normaliza ou descarta todo o que chega de fóra, segundo o seu propio comportamento documentado para eses campos. Despois a orixe toma un enderezo de substitución da ruta de proxy que vostede nomeou e de ningún outro sitio. Esa segunda regra só se mantén mentres os clientes non poidan chegar á orixe por outra vía, xa que unha orixe que responde tanto a solicitudes directas como a través de proxy non sabe cal das dúas está servindo.
O módulo de IP real de NGINX mostra a división con claridade. set_real_ip_from nomea os remitentes cuxa afirmación conta, e real_ip_header di que campo a leva; o primeiro exerce a confianza, o segundo só di onde mirar.
set_real_ip_from 10.20.0.0/24;
real_ip_header X-Forwarded-For;
# real_ip_recursive off - take the rightmost value in the field
# real_ip_recursive on - walk the list back past every trusted address
Unha directiva de selección de cabeceira por si soa aínda non establece nada sobre quen enviou o valor.
A seguridade do transporte debe percorrer todo o camiño entre os compoñentes en que confía. Unha beira que normaliza correctamente perde ese valor no momento en que un salto non protexido máis abaixo permite que outro edite a afirmación mentres viaxa.
Xestione con deliberación as cadeas de varios saltos
Varios proxies necesitan un modelo de cadea explícito. Non tome o valor máis á esquerda ou máis á dereita separado por comas porque algún artigo de blog o fixera; descubra cal dos seus proxies engade, cal substitúe e cal conserva o campo entrante. NGINX, por exemplo, pode percorrer a lista cara atrás contra o seu conxunto de confianza e deterse no primeiro enderezo que non posúe, e esa é a regra dese produto, non unha lei que siga cada marco de traballo. Lea a documentación do seu propio proxy coas mesmas dúas preguntas: que valor selecciona e en que remitentes cre?
Escriba a cadea: orde de saltos, que salto establece o campo e que salto elimina as copias entrantes. Despois manteña esa nota xunto á configuración do proxy, non só no tícket. Despois probeo enviando unha solicitude cunha cabeceira falsificada polo proceso de validación aprobado e confirmando que a orixe a ignora.
Cando engada un salto, revise ese documento. Un novo balanceador de carga inserido diante do proxy de confianza pode cambiar que enderezo gaña sen que ninguén edite a aplicación.
Manteña as dúas observacións no rexistro
Onde o diagnóstico está autorizado, rexistre o par da conexión e o enderezo de cliente normalizado como dous campos separados, e engada só os metadatos de reenvío que o propósito realmente necesite. Despois demostre o despregamento con dúas solicitudes: unha a través do proxy que debería rexistrar ambos os valores con sentido, e un intento directo á orixe que debe ser rexeitado.
Lembre o que significa a parella. A cabeceira engade contexto proporcionado por un compoñente que vostede escolleu confiar; o par segue a ser o único enderezo que o seu host viu realmente. Ningunha das dúas é proba de identidade individual, e un deseño que trate calquera delas como proba equivocarase respecto de alguén.