3
votes

I'd need to configure nginx as reverse proxy for some apps run in docker. Portainer is working well, but HashiCorp Vault has still issues. Further steps will be using nginx for SSL connection for all running apps. All the apps are in most simply setting I could use without any special features.

Environment

  • Centos 7
  • nginx from rpm 1.16.1-1 (for debug option, in further use it should be in container as well)
  • portainer
  • vault 1.2.4
/etc/nginx/nginx.conf

        user  nginx;
    worker_processes  1;

    error_log  /var/log/nginx/error.log debug;
    pid        /var/run/nginx.pid;


    events {
      worker_connections  1024;
    }


    http {
      include       /etc/nginx/mime.types;
      default_type  application/octet-stream;

      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';

      access_log  /var/log/nginx/access.log  main;

      sendfile        on;
      #tcp_nopush     on;

      keepalive_timeout  65;

      #gzip  on;

      server {
        listen 80;
        server_name 1.2.3.4;

        location /portainer/ {
          proxy_pass http://1.2.3.4:9000/;
          rewrite ^/portainer(/.*) $1 break;
          proxy_redirect     off;
          proxy_set_header   Host $host;
          proxy_set_header   X-Real-IP $remote_addr;
          proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header   X-Forwarded-Host $server_name;
        }

        location /vault/ {
          proxy_pass http://1.2.3.4:8200/;
          rewrite ^/vault(/.*) $1 break;
          proxy_redirect     off;
          proxy_set_header   Host $host;
          proxy_set_header   X-Real-IP $remote_addr;
          proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header   X-Forwarded-Host $server_name;
        }
      }

      #include /etc/nginx/conf.d/*.conf;
    }

/var/lib/docker/volumes/vault_vault_config/_data/vault.json


    {
      "backend": {
        "file": {
          "path": "/vault/file"
        }
      },
      "listener": {
        "tcp":{
          "address": "0.0.0.0:8200",
          "tls_disable": 1
        }
      },
      "ui": true,
      "disable_mlock": true,
      "disable_clustering": true
    }

Note: "disable_mlock" is needed to run in docker, "disable_clustering" should solve my issue, but it's not working as expected.

/var/lib/docker/apps/vault-stack.yml


    version: '3.2'

    services:
      vault:
        image: vault
        deploy:
          replicas: 1
        ports:
          - 8200:8200
        environment:
          - VAULT_ADDR=http://127.0.0.1:8200
        volumes:
          - vault_config:/vault/config
          - vault_logs:/vault/logs
          - vault_file:/vault/file
        entrypoint: vault server -config=/vault/config/vault.json

    volumes:
      vault_config:
        driver: local
      vault_file:
        driver: local
      vault_logs:
        driver: local

Issue

Portainer is working well, but with vault I have still issue that I get 404 error. When I go to http://1.2.3.4/vault I get redirection to http://1.2.3.4/ui which obviously doesn't exist. As I found out, it's because of "307 Temporary Redirect" Here comes some output from /var/log/nginx/error.log


    2019/11/12 14:06:41 [debug] 13564#13564: *8 using configuration "/vault/"
    2019/11/12 14:06:41 [debug] 13564#13564: *8 HTTP/1.1 301 Moved Permanently
    Location: http://1.2.3.4/vault/
    2019/11/12 14:06:41 [notice] 13564#13564: *8 "^/vault(/.*)" matches "/vault/", client: 10.20.30.40, server: 1.2.3.4, request: "GET /vault/ HTTP/1.1", host: "1.2.3.4"
    2019/11/12 14:06:41 [notice] 13564#13564: *8 rewritten data: "/", args: "", client: 10.20.30.40, server: 1.2.3.4, request: "GET /vault/ HTTP/1.1", host: "1.2.3.4"
    2019/11/12 14:06:41 [debug] 13564#13564: *8 HTTP/1.1 307 Temporary Redirect
    Location: /ui/
    2019/11/12 14:06:41 [error] 13564#13564: *8 "/etc/nginx/html/ui/index.html" is not found (2: No such file or directory), client: 10.20.30.40, server: 1.2.3.4, request: "GET /ui/ HTTP/1.1", host: "1.2.3.4"

What I've tried

Almost everything :) Spent already too many hours to make this working and that's the reason why I'm here. I've got many different errors from 500 Internal to "too many redirects" when I tried to catch the redirection and put there my own. Tried to solve it on "server" side in vault by disabling clustering (as in vault.json)

1
Did you see this article? keyboardinterrupt.org/…aug70co

1 Answers

2
votes

I tried to achieve the same thing. This is the only way I got it working...

location /vault/ {
    proxy_pass  http://vault:8200/;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Accept-Encoding ""; # needed for sub_filter to work with gzip enabled (https://stackoverflow.com/a/36274259/3375325)

    proxy_redirect /ui/ /vault/ui/;

    sub_filter '<head>' '<head><base href="/vault/">';
    sub_filter '"/ui/' '"ui/';
    sub_filter_once off;
}
location /v1 {
    proxy_pass http://vault:8200;
}

Solution mostly taken from https://github.com/Folcky/hashicorp-vault-and-nginx/blob/master/vault.location

A cleaner solution IMHO would be to use a sub-domain like vault.mycompany.com to be able to exclusively use the root context.