haproxytech / kubernetes-ingress

HAProxy Kubernetes Ingress Controller
https://www.haproxy.com/documentation/kubernetes/
Apache License 2.0
717 stars 200 forks source link

IPv6: Received something which does not look like a PROXY protocol header #616

Closed aep closed 6 months ago

aep commented 8 months ago

in version 1.10.11, with dual stack enabled, https over ipv6 randomly results in connection reset

the log indicates:

IPv6: Received something which does not look like a PROXY protocol header

possibly this has something to do with both frontend https listening on :: instead of [::1] which it should to follow the thing done for ipv4

Status:       Running
IP:           10.182.80.161
IPs:
  IP:           10.182.80.161
  IP:           fdfd:b6:1::ed1
Controlled By:  DaemonSet/admin-kubernetes-ingress

Containers:
  kubernetes-ingress-controller:
    Container ID:  cri-o://aca77e6fecfec6780d97c1775394114651fcd1fb99eb03f91864690844ddcbbe
    Image:         haproxytech/kubernetes-ingress:1.10.11
    Image ID:      docker.io/haproxytech/kubernetes-ingress@sha256:592674421a83e7962aeeeaeac072732232bf53faff32b7a8086b9e13c52c6cb6
    Ports:         8080/TCP, 8443/TCP, 1024/TCP
    Host Ports:    80/TCP, 443/TCP, 1024/TCP
    Args:
      --default-ssl-certificate=ingress/admin-kubernetes-ingress-default-cert
      --configmap=ingress/admin-kubernetes-ingress
      --http-bind-port=8080
      --https-bind-port=8443
      --ingress.class=admin
      --publish-service=ingress/admin-kubernetes-ingress
      --log=debug
      --prometheus
/ # cat /etc/haproxy/haproxy.cfg 
# _version=9
# HAProxy Technologies
# https://www.haproxy.com/
# this file is not meant to be changed directly
# it is under haproxy ingress controller management

global
  localpeer local
  master-worker
  pidfile /var/run/haproxy.pid
  stats socket /var/run/haproxy-runtime-api.sock expose-fd listeners level admin
  stats timeout 36000
  tune.ssl.default-dh-param 2048
  ssl-default-bind-options no-sslv3 no-tls-tickets no-tlsv10
  ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!3DES
  hard-stop-after 1800000
  log stdout format raw daemon
  default-path config

defaults
  log global
  log-format '%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs "%HM %[var(txn.base)] %HV"'
  option redispatch 0
  option dontlognull
  option http-keep-alive
  timeout http-request 5000
  timeout connect 5000
  timeout client 50000
  timeout queue 5000
  timeout server 50000
  timeout tunnel 3600000
  timeout http-keep-alive 60000

peers localinstance
  peer local 127.0.0.1:10000

frontend healthz
  mode http
  bind 0.0.0.0:1042 name v4
  bind :::1042 name v6 v4v6
  monitor-uri /healthz
  option dontlog-normal

frontend http
  mode http
  bind 0.0.0.0:8080 name v4
  bind :::8080 name v6
  http-request set-var(txn.base) base
  http-request set-var(txn.path) path
  http-request set-var(txn.host) req.hdr(Host),field(1,:),lower
  http-request set-var(txn.host_match) var(txn.host),map(/etc/haproxy/maps/host.map)
  http-request set-var(txn.host_match) var(txn.host),regsub(^[^.]*,,),map(/etc/haproxy/maps/host.map,'') if !{ var(txn.host_match) -m found }
  http-request set-var(txn.path_match) var(txn.host_match),concat(,txn.path,),map(/etc/haproxy/maps/path-exact.map)
  http-request set-var(txn.path_match) var(txn.host_match),concat(,txn.path,),map_beg(/etc/haproxy/maps/path-prefix.map) if !{ var(txn.path_match) -m found }
  http-request deny deny_status 403 if { var(txn.path_match) -m dom 9df5c5b72e74927daab429c3adaf0822 } !{ src -f /etc/haproxy/maps/whitelist-7ea526968d6dbb9fff840c8026065a2b.map }
  http-request redirect location https://%[hdr(host),field(1,:)]:443%[capture.req.uri] code 302 if { var(txn.path_match) -m dom dbe4b28f9c4404fc36a7ae76ead9a37d } 
  use_backend %[var(txn.path_match),field(1,.)]
  default_backend ingress_default-local-service_http

frontend https
  mode http
  bind 127.0.0.1:8443 name v4 crt /etc/haproxy/certs/frontend ssl alpn h2,http/1.1 accept-proxy
  bind :::8443 name v6 crt /etc/haproxy/certs/frontend ssl v4v6 alpn h2,http/1.1 accept-proxy
  http-request set-var(txn.base) base
  http-request set-var(txn.path) path
  http-request set-var(txn.host) req.hdr(Host),field(1,:),lower
  http-request set-var(txn.host_match) var(txn.host),map(/etc/haproxy/maps/host.map)
  http-request set-var(txn.host_match) var(txn.host),regsub(^[^.]*,,),map(/etc/haproxy/maps/host.map,'') if !{ var(txn.host_match) -m found }
  http-request set-var(txn.path_match) var(txn.host_match),concat(,txn.path,),map(/etc/haproxy/maps/path-exact.map)
  http-request set-var(txn.path_match) var(txn.host_match),concat(,txn.path,),map_beg(/etc/haproxy/maps/path-prefix.map) if !{ var(txn.path_match) -m found }
  http-request deny deny_status 403 if { var(txn.path_match) -m dom 9df5c5b72e74927daab429c3adaf0822 } !{ src -f /etc/haproxy/maps/whitelist-7ea526968d6dbb9fff840c8026065a2b.map }
  http-request set-header X-Forwarded-Proto https
  use_backend %[var(txn.path_match),field(1,.)]
  default_backend ingress_default-local-service_http

frontend ssl
  mode tcp
  bind 0.0.0.0:8443 name v4
  bind :::8443 name v6 v4v6
  log-format '%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs SNI: %[var(sess.sni)]'
  tcp-request content reject if !{ req_ssl_hello_type 1 }
  tcp-request inspect-delay 5000
  tcp-request content set-var(sess.sni) req_ssl_sni
  tcp-request content set-var(txn.sni_match) req_ssl_sni,map(/etc/haproxy/maps/sni.map)
  tcp-request content set-var(txn.sni_match) req_ssl_sni,regsub(^[^.]*,,),map(/etc/haproxy/maps/sni.map)
  tcp-request content reject if { var(txn.sni_match) -m dom 9df5c5b72e74927daab429c3adaf0822 } !{ src -f /etc/haproxy/maps/whitelist-7ea526968d6dbb9fff840c8026065a2b.map }
  use_backend %[var(txn.sni_match),field(1,.)]
  default_backend ssl

frontend stats
  mode http
  bind *:1024 name stats
  bind :::1024 name v6
  stats enable
  stats uri /
  stats refresh 10s
  http-request set-var(txn.base) base
  http-request use-service prometheus-exporter if { path /metrics }

backend ssl
  mode tcp
  server https 127.0.0.1:8443 send-proxy-v2
aep commented 8 months ago

i believe this only happens when an ingress has ssl passthrough enabled. however, i cant figure out why. the code looks fine?

https://github.com/haproxytech/kubernetes-ingress/blob/master/pkg/handler/https.go#L69

ivanmatmati commented 8 months ago

Hi @aep , thanks for reporting. We'll check that.

ivanmatmati commented 7 months ago

Hi @aep , it's solved in the latest code which will be included in the next release. Can you test the nightly build ? You only have to replace the version/latest of the controller Docker image inside the yaml file with nightly.

stale[bot] commented 6 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.