Error when Zuul routing to a HTTPS url

16,182

It has been a little while since I have played with this because we ended up not being able to use it due to the limitation of not being able to pass the users certificate through the proxy. However, you asked for my help, so I'll try to share what I did have working.

I was able to get 2-way SSL working between both the ZUUL, acting as an Edge Server, and the Services on the backend while running in their own VMs (i.e. doing a mvn spring-boot:run on each service).

Here is my Zuul Conifg:

info:
  component: Zuul Server

endpoints:
  restart:
    enabled: true
  shutdown:
    enabled: true
  health:
    sensitive: false

zuul:
  routes:
    ui: /**
    api: /api/**

logging:
  level:
    ROOT: INFO
    org.springframework.web: DEBUG

server:
  port: 8443
  ssl:
      key-store: classpath:dev/localhost.jks
      key-store-password: yourpassword
      keyStoreType: JKS
      keyAlias: localhost
      clientAuth: want
      trust-store: classpath:dev/localhost.jks

ribbon:
    IsSecure: true

The Edge Server itself is nothing interesting:

@SpringBootApplication
@Controller
@EnableAutoConfiguration
@EnableZuulProxy
public class ZuulEdgeServer {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ZuulEdgeServer.class).web(true).run(args);
    }
}

Now in my other services I had the following in their application.yml files:

server:
  port: 8444
  ssl:
      key-store: classpath:dev/localhost.jks
      key-store-password: yourpassword
      keyStoreType: JKS
      keyAlias: localhost
      clientAuth: want
      trust-store: classpath:dev/localhost.jks

eureka:
  instance: 
    nonSecurePortEnabled: false
    securePortEnabled: true
    securePort: ${server.port}
    homePageUrl: https://${eureka.instance.hostname}:${server.port}/
    secureVirtualHostName: ${spring.application.name}

My Eureka Config doesn't have much too it, but just in case:

server:
  port: 8761

eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false
  server:
    waitTimeInMsWhenSyncEmpty: 0

My bootstrap.yml's in most the applications look like this:

spring:
  application:
    name: eureka
  cloud:
    config:
      uri: ${vcap.services.${PREFIX:}configserver.credentials.uri:http://user:password@localhost:8888}

I mainly found I needed the spring.application.name in there to resolve conflicts when running the applications within the same container.

If I remember right, the important parts from above were:

  • ribbon.isSecure = true in the zuul config
  • eureka.instance.securePortEnabled = true and the securePort in the backend services.

I can't remember if the secureVirtualHostName was important or not.

Hopefully this info can help you out though!

Share:
16,182
yathirigan
Author by

yathirigan

Solution Architect currently working with Microservices, APIs, Cloud Native Architecture for PCF PaaS

Updated on June 08, 2022

Comments

  • yathirigan
    yathirigan about 2 years

    I have a Spring Boot application (recently enabled it for HTTPS + self signed certificate) which is registered in Eureka and visible in the Eureka dashboard.

    We have a Zuul Filter layer which gets the user request and then passes it on to the Spring Boot application. This was working fine until the app was accessible via HTTP. But, once i enabled HTTPS, the zuul routing is failing.

    Here is the Zuul route configuration in my yaml file. Should my Zuul Route configuration have any special configuration for HTTPS enabled URL/App ?

    zuul:
      routes:
        ms:
           path: /app/**
           stripPrefix: true
    
        ms:   
          ribbon:
            ServerListRefreshInterval: 1000
            ConnectTimeout: 20000
            ReadTimeout: 20000
    

    Here is the exception stack trace (showing that Zuul is trying to route to the HTTP URL , instead of the HTTPS url)

    Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: msRibbonCommand failed and no fallback available.
        at com.netflix.hystrix.AbstractCommand$20.call(AbstractCommand.java:816) ~[hystrix-core-1.4.0-RC6.jar:na]
        at com.netflix.hystrix.AbstractCommand$20.call(AbstractCommand.java:798) ~[hystrix-core-1.4.0-RC6.jar:na]
        at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:76) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$ThrowObservable$1.call(Observable.java:10493) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$ThrowObservable$1.call(Observable.java:10483) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:77) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorMap$1.onError(OperatorMap.java:48) ~[rxjava-core-0.20.7.jar:na]
        at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:318) ~[hystrix-core-1.4.0-RC6.jar:na]
        at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:310) ~[hystrix-core-1.4.0-RC6.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:77) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorMap$1.onError(OperatorMap.java:48) ~[rxjava-core-0.20.7.jar:na]
        at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$3.onError(AbstractCommand.java:995) ~[hystrix-core-1.4.0-RC6.jar:na]
        at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$ThrowObservable$1.call(Observable.java:10493) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$ThrowObservable$1.call(Observable.java:10483) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:77) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorMap$1.onError(OperatorMap.java:48) ~[rxjava-core-0.20.7.jar:na]
        at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:301) ~[hystrix-core-1.4.0-RC6.jar:na]
        at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:293) ~[hystrix-core-1.4.0-RC6.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
        at com.netflix.hystrix.AbstractCommand$1.call(AbstractCommand.java:388) ~[hystrix-core-1.4.0-RC6.jar:na]
        at com.netflix.hystrix.AbstractCommand$1.call(AbstractCommand.java:368) ~[hystrix-core-1.4.0-RC6.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
        at com.netflix.hystrix.AbstractCommand$ObservableCommand$1.call(AbstractCommand.java:1097) ~[hystrix-core-1.4.0-RC6.jar:na]
        at com.netflix.hystrix.AbstractCommand$ObservableCommand$1.call(AbstractCommand.java:1093) ~[hystrix-core-1.4.0-RC6.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.subscribe(Observable.java:8680) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.BlockingOperatorToFuture.toFuture(BlockingOperatorToFuture.java:55) ~[rxjava-core-0.20.7.jar:na]
        at rx.observables.BlockingObservable.toFuture(BlockingObservable.java:420) ~[rxjava-core-0.20.7.jar:na]
        at com.netflix.hystrix.HystrixCommand.queue(HystrixCommand.java:385) ~[hystrix-core-1.4.0-RC6.jar:na]
        at com.netflix.hystrix.HystrixCommand.execute(HystrixCommand.java:339) ~[hystrix-core-1.4.0-RC6.jar:na]
        at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.forward(RibbonRoutingFilter.java:130) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        ... 82 common frames omitted
    Caused by: com.netflix.client.ClientException: null
        at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:123) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
        at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:81) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
        at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.forward(RibbonCommand.java:129) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.run(RibbonCommand.java:103) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.run(RibbonCommand.java:1) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:298) ~[hystrix-core-1.4.0-RC6.jar:na]
        ... 125 common frames omitted
    Caused by: org.apache.http.client.ClientProtocolException: null
        at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:867) ~[httpclient-4.3.6.jar:4.3.6]
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:115) ~[httpclient-4.3.6.jar:4.3.6]
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57) ~[httpclient-4.3.6.jar:4.3.6]
        at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:170) ~[jersey-apache-client4-1.11.jar:1.11]
        at com.sun.jersey.api.client.Client.handle(Client.java:648) ~[jersey-client-1.13.jar:1.13]
        at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680) ~[jersey-client-1.13.jar:1.13]
        at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) ~[jersey-client-1.13.jar:1.13]
        at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:568) ~[jersey-client-1.13.jar:1.13]
        at com.netflix.niws.client.http.RestClient.execute(RestClient.java:621) ~[ribbon-httpclient-2.0-RC13.jar:na]
        at com.netflix.niws.client.http.RestClient.execute(RestClient.java:527) ~[ribbon-httpclient-2.0-RC13.jar:na]
        at com.netflix.niws.client.http.RestClient.execute(RestClient.java:92) ~[ribbon-httpclient-2.0-RC13.jar:na]
        at com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:109) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
        at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
        at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
        at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:41) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:30) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorConcat$ConcatSubscriber.subscribeNext(OperatorConcat.java:163) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorConcat$ConcatSubscriber.onNext(OperatorConcat.java:128) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorConcat$ConcatSubscriber.onNext(OperatorConcat.java:65) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54) ~[rxjava-core-0.20.7.jar:na]
        at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:185) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
        at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:112) ~[rxjava-core-0.20.7.jar:na]
        at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:85) ~[rxjava-core-0.20.7.jar:na]
        at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:65) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:77) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:41) ~[rxjava-core-0.20.7.jar:na]
        at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:30) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
        at rx.Observable.subscribe(Observable.java:8680) ~[rxjava-core-0.20.7.jar:na]
        at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:452) ~[rxjava-core-0.20.7.jar:na]
        at rx.observables.BlockingObservable.single(BlockingObservable.java:348) ~[rxjava-core-0.20.7.jar:na]
        at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:102) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
        ... 130 common frames omitted
    Caused by: org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:151) ~[httpclient-4.3.6.jar:4.3.6]
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57) ~[httpclient-4.3.6.jar:4.3.6]
        at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261) ~[httpcore-4.4.jar:4.4]
        at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:283) ~[httpcore-4.4.jar:4.4]
        at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:251) ~[httpclient-4.3.6.jar:4.3.6]
        at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:223) ~[httpclient-4.3.6.jar:4.3.6]
        at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272) ~[httpcore-4.4.jar:4.4]
        at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124) ~[httpcore-4.4.jar:4.4]
        at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:685) ~[httpclient-4.3.6.jar:4.3.6]
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:487) ~[httpclient-4.3.6.jar:4.3.6]
        at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863) ~[httpclient-4.3.6.jar:4.3.6]
    

    Update: After adding the isRibbon secure property, this error was gone and now i have a new error.