0

我现在有点迷路了。我建立了一个 Kubernetes 集群,部署了一个 Spring Boot API 和一个运行良好的 LoadBalancer。现在我想在 LoadBalancer 上启用代理协议以保留真实的客户端 IP,但是一旦我这样做了,我的 Spring Boot API 总是返回一个400 Bad RequestIllegalArgumentException抛出一个。

这是简短的堆栈跟踪(我屏蔽了 IP 地址):

2020-09-29 20:05:58.382  INFO 1 --- [nio-8080-exec-1] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header
 Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level.

java.lang.IllegalArgumentException: Invalid character found in the HTTP protocol [255.255.255.253 255.255.255.254]
        at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:560) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:260) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
        at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]

我正在使用 Hetzner 的hcloud-cloud-controller-manager

这是我的负载平衡器:

apiVersion: v1
kind: Service
metadata:
  labels:
    service: auth-service
  name: auth-service-service
  annotations:
    load-balancer.hetzner.cloud/name: "lb-backend"
    load-balancer.hetzner.cloud/health-check-port: "80"
    load-balancer.hetzner.cloud/uses-proxyprotocol: "true"
spec:
  ports:
    - name: http
      port: 80
      targetPort: 8080
  selector:
    service: auth-service
  externalTrafficPolicy: Local
  type: LoadBalancer

这是我的弹簧配置:

spring:
  datasource:
    platform: postgres
    url: ${DATABASE_CS}
    username: ${DATABASE_USERNAME}
    password: ${DATABASE_PASSWORD}
    driver-class-name: org.postgresql.Driver
  flyway:
    schemas: authservice
  jpa:
    show-sql: false
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        jdbc:
          lob:
            non_contextual_creation: true
    hibernate:
      ddl-auto: validate

security:
  jwt:
    secret-key: ${JWT_SECRET_KEY}
    expires: ${JWT_EXPIRES:300000}

mail:
  from: ${MAIL_FROM}
  fromName: ${MAIL_FROM_NAME}
  smtp:
    host: ${SMTP_HOST}
    username: ${SMTP_USERNAME}
    password: ${SMTP_PASSWORD}
    port: ${SMTP_PORT:25}
  mjml:
    app-id: ${MJML_APP_ID}
    app-secret: ${MJML_SECRET_KEY}
stripe:
  keys:
    secret: ${STRIPE_SECRET_KEY}
    public: ${STRIPE_PUBLIC_KEY}
server:
  forward-headers-strategy: native

您可能已经注意到,我已经尝试基于此问题启用前向标头。

谢谢你的帮助!

4

1 回答 1

0

您启用了 PROXY 协议,它不是 HTTP,而是一种不同的协议,用于将 TCP 连接隧道连接到下游服务器,尽可能多地保留信息。 https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

我很确定您想禁用此 load-balancer.hetzner.cloud/uses-proxyprotocol: "true" 功能,而是依赖远程地址的转发标头为客户端提供正确的值。

老实说,我不知道 tomcat 支持 PROXY 协议。(编辑:目前没有,请参阅https://bz.apache.org/bugzilla/show_bug.cgi?id=57830

于 2020-09-29T21:32:15.897 回答