vfarcic/docker-flow-proxy

Wrongly parsed env.variables while trying set non-swarm service

redtex opened this issue · 11 comments

Description
When I try to configure non-swarm service, which communicates through https with proxy, I've got 403 error.

Steps to reproduce the issue:

  1. Run Docker (17.09) in swarm mode
  2. Create secret with private key and certificate
  3. Deploy docker-flow-proxy service with https://raw.githubusercontent.com/vfarcic/docker-flow-proxy/master/docker-compose-stack.yml stack file
  4. Add secret to running proxy_proxy service
  5. Add env.variables to proxy_proxy service to provide access to non-swarm service:
docker service update \
    --env-add DFP_SERVICE_1_SERVICE_NAME=redmine.sdsys.ru \
    --env-add DFP_SERVICE_1_SERVICE_PATH=/ \
    --env-add DFP_SERVICE_1_SERVICE_DOMAIN=support.sdsys.ru \
    --env-add DFP_SERVICE_1_PORT=443 \
    --env-add DFP_SERVICE_1_OUTBOUND_HOSTNAME=192.168.21.96 \
    --env-add DFP_SERVICE_1_SSL_VERIFY_NONE=true \
    proxy_proxy

Describe the results you received:
Got 403 error in browser, when I try to open support.sdsys.ru

Describe the results you expected:
Succefully opened support.sdsys.ru page

Additional information you deem important (e.g. issue happens only occasionally):
In docker-flow-proxy container I've discovered wrongly set options, which as I assume, must be set only when there are set VERIFY_CLIENT_SSL=true, but I'm not doing it:

 backend redmine.sdsys.ru-be443_0
    mode http
    http-request redirect scheme https if !{ ssl_fc }
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    log global
    acl valid_client_cert_redmine.sdsys.ru443 ssl_c_used ssl_c_verify 0
    http-request deny unless valid_client_cert_redmine.sdsys.ru443
    server redmine.sdsys.ru redmine.sdsys.ru:443 ssl verify none/

This might have been caused by the problem described in #421 and fixed in vfarcic/docker-flow-proxy:18.01.29-101. Can you please try it out with vfarcic/docker-flow-proxy:18.01.29-101 and let me know if the issue still persists.

Hello, Vicror !!!
Thank you for fast response.
Sadly no, the problem not solved.
The service is ran with:

docker service inspect proxy_proxy | jq '.[0] | .Spec.TaskTemplate.ContainerSpec.Env'
[
  "DFP_SERVICE_1_HTTPS_ONLY=true",
  "LISTENER_ADDRESS=swarm-listener",
  "DFP_SERVICE_1_SERVICE_DOMAIN=support.sdsys.ru",
  "DFP_SERVICE_1_SSL_VERIFY_NONE=true",
  "DFP_SERVICE_1_PORT=443",
  "DFP_SERVICE_1_OUTBOUND_HOSTNAME=192.168.21.96",
  "DFP_SERVICE_1_SERVICE_NAME=redmineru",
  "MODE=swarm",
  "DFP_SERVICE_1_SERVICE_PATH=/"
]

And we have:

docker exec -it $(docker ps -q -f label=com.docker.swarm.service.name=proxy_proxy) grep -A 10 '^backend redmine' /cfg/haproxy.cfg
backend redmineru-be443_0
    mode http
    http-request redirect scheme https if !{ ssl_fc }
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    acl valid_client_cert_redmineru443 ssl_c_used ssl_c_verify 0
    http-request deny unless valid_client_cert_redmineru443
    server redmineru 192.168.21.96:443 ssl verify none

So, I still have a 403 error.

I think that what you're looking for is the verifyClientSsl parameter. Can you try it out?

Accroding to http://proxy.dockerflow.com/usage/ verifyClientSsl must be set to false by default.
Anyway, I've already set VERIFY_CLIENT_SSL to false with no success. It seems, like flow proxy sets VERIFY_CLIENT_SSL to true when SSL_VERIFY_NONE set to true. I think, it's some parsing error in code.

I think, here is wrong code in docker-flow-proxy/server/server.go:
verifyClientSsl, _ := strconv.ParseBool(os.Getenv(prefix + "_SSL_VERIFY_NONE"))
it should be replaced with:
verifyClientSsl, _ := strconv.ParseBool(os.Getenv(prefix + "_VERIFY_CLIENT_SSL"))

Can you make a PR?

Never done this before.
I'll try.

Don't know why, but this PR not passes UnitTests - co I close it, and there is one more line, which should be changed:

                redirectFromDomain := getSliceFromString(os.Getenv(fmt.Sprintf("%s_REDIRECT_FROM_DOMAIN_%d", prefix, i)))
                servicePathExclude := getSliceFromString(os.Getenv(fmt.Sprintf("%s_SERVICE_PATH_EXCLUDE_%d", prefix, i)))
-               verifyClientSsl, _ := strconv.ParseBool(os.Getenv(fmt.Sprintf("%s_SSL_VERIFY_NONE_%d", prefix, i)))
+               verifyClientSsl, _ := strconv.ParseBool(os.Getenv(fmt.Sprintf("%s_VERIFY_CLIENT_SSL_%d", prefix, i)))
                denyHttp, _ := strconv.ParseBool(os.Getenv(fmt.Sprintf("%s_DENY_HTTP_%d", prefix, i)))
                ignoreAuthorization, _ := strconv.ParseBool(os.Getenv(fmt.Sprintf("%s_IGNORE_AUTHORIZATION_%d", prefix, i)))

It should be fixed and available in vfarcic/docker-flow-proxy:18.01.31-103. Can you please try it out?

Victor, thank you. Now it works as expected.