Nginx удаляет заголовок Content-Length при работе в качестве обратного прокси-сервера за WAF

#http #nginx #reverse-proxy #artifactory #web-application-firewall

#http #nginx #обратный прокси #артефактор #веб-приложение-брандмауэр

Вопрос:

У меня есть Nginx 1.16.1 в качестве обратного прокси-сервера для JFrog Artifactory, и они доступны из внешних сетей через брандмауэр веб-приложений. Я пытаюсь заставить docker клиента работать с этой настройкой. Он отправляет HEAD запрос и ожидает a Content-Length , чтобы проверить наличие слоя. Теперь я вижу, что Content-Length это не включено в ответ, полученный клиентом. Я могу проверить его, отправив тот же запрос, используя curl этот sends docker :

 $ curl -H 'User-Agent: docker/19.03.13 go/go1.13.15 git-commit/4484c46d9d kernel/4.19.128-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/19.03.13 (linux))' 
  -H "Authorization: Bearer ${TOKEN}" 
  -H 'Connection: close' 
  -I 
   "https://${ARTIFACTORY_URL}/v2/${IMAGE}/blobs/${DIGEST}"
HTTP/1.1 200 OK
Date: Mon, 09 Nov 2020 14:57:05 GMT
Server: Secure Entry Server
Content-Type: application/octet-stream
Docker-Content-Digest: sha256:[MASKED]
Docker-Distribution-Api-Version: registry/2.0
X-Artifactory-Id: [MASKED]
X-Artifactory-Node-Id: [MASKED]
Set-Cookie: SCDID_S=[MASKED]; path=/; Secure; HttpOnly
Connection: close
  

Однако я вижу в журнале доступа Artifactory, что он устанавливает этот заголовок ответа. Раньше я tcpdump видел, какими данными обмениваются Nginx и Artifactory:

 HEAD /v2/[MASKED]/blobs/[MASKED] HTTP/1.1
X-JFrog-Override-Base-Url: https://[MASKED]:443
X-Forwarded-Port: 443
X-Forwarded-Proto: https
Host: [MASKED]
X-Forwarded-For: 10.10.40.14
Connection: close
ClientCorrelator: 0rIKeSpqZ9E$
RequestCorrelator: 7f0100-9099-2020.11.09_1457.05.275-001
HSP_CLIENT_ADDR: [MASKED]
Hsp-ListenerUri: https://[MASKED]
HSP_HTTPS_HOST: [MASKED]:443
Accept: */*
Authorization: Bearer [MASKED]
User-Agent: docker/19.03.13 go/go1.13.15 git-commit/4484c46d9d kernel/4.19.128-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/19.03.13 (linux))
HTTPS: on
SSLSessionID: 78ad360e9ea54f5efdb72ea223a63b6cbc7788ae9a1e876620e398040d06182c
SSLSessionTimeLeft: 3600
SSLSessionAge: 0
SSLCipher: ECDHE-RSA-AES128-GCM-SHA256
SSLCipherKeySize: 128
SSLProtocolVersion: TLSv1.2
Via: HTTP/1.1 Secure Entry Server

HTTP/1.1 200 OK
Content-Length: 2529
Content-Type: application/octet-stream
Date: Mon, 09 Nov 2020 14:57:05 GMT
Docker-Content-Digest: [MASKED]
Docker-Distribution-Api-Version: registry/2.0
Server: Artifactory/7.4.1 70401900
X-Artifactory-Id: 5a2dee84b6d80d2f:1f521881:17554c79de4:-8000
X-Artifactory-Node-Id: [MASKED]
Connection: close
  

Анализатор трафика в WAF показывает, что Content-Length во входящем ответе от Artifactory отсутствует. Следовательно, за его удаление должен отвечать Nginx.

Теперь, когда я подключаюсь через VPN, чтобы обойти WAF, ответ выглядит нормально:

 Host:           [MASKED]
User-Agent:     docker/19.03.13 go/go1.13.15 ...
Authorization:  Bearer [MASKED]
Connection:     close

Date:                           Fri, 06 Nov 2020 17:13:58 GMT
Content-Type:                   application/octet-stream
Content-Length:                 2529
Docker-Content-Digest:          [MASKED]
Docker-Distribution-Api-Version:registry/2.0
Server:                         Artifactory/7.4.1 70401900
X-Artifactory-Id:               5a2dee84b6d80d2f:1f521881:17554c79de4:-8000
X-Artifactory-Node-Id:          [MASKED]
Connection:                     close
  

Но я также замечаю, что в запросе задано меньше заголовков. Это какой-то дополнительный WAF-заголовок, который вызывает удаление Nginx Content-Length ? Я не вижу ничего, связанного с этим, в журнале отладки Nginx. Есть мысли?

Комментарии:

1. какой WAF использует ваша организация? возможно, что WAF удаляет заголовок длины содержимого (например, если ответ фрагментирован или сжат)

2. Привет, Дрор, заголовок отсутствует во входящем ответе на WAF, прежде чем будет применена какая-либо обработка. Кроме того, вы видите, что ответ не является ни фрагментированным, ни сжатым, поскольку это просто ответ на HEAD запрос.