Skip to content
This repository has been archived by the owner on Dec 6, 2023. It is now read-only.

Vault runs with the default listener of 127.0.0.1, but Docker requires that applications inside containers listen on 0.0.0.0 #241

Open
TMFEspresso opened this issue Sep 17, 2021 · 3 comments

Comments

@TMFEspresso
Copy link

Describe the bug
The only way to run vault login -method=oidc from inside a container is to specify the listenaddress parameter to be 0.0.0.0.

To Reproduce
If you try to run the following:

docker run --rm -it \
  --cap-add=IPC_LOCK \
  --volume ${PWD}:/app \
  -p '8200:8200' \
  -p '8250:8250' \
  -e 'VAULT_ADDR=https://remote-vault-instance-that-auths-via-oidc.com' \
  vault:latest vault login -method=oidc

And then you paste the resulting redirect url into your browser, you will get a 404.

This is because vault as an application is listening on 127.0.0.1 from inside the container. Docker does not like this.

How you can determine that Vault is listening on that address is by running the following:

# start up a vault container 
docker run --rm -it \
  --cap-add=IPC_LOCK \
  --volume ${PWD}:/app \
  --name=vault \
  -p '8200:8200' \
  -p '8250:8250' \
  -e 'VAULT_ADDR=https://remote-vault-instance-that-auths-via-oidc.com' \
  vault:latest /bin/ash

# install net-tools so you get netstat
apk add net-tools

# run the vault login command, without defining a different listenaddress
vault login -method=oidc

# while the `vault login` is still running, in another tab/window, exec into the docker container 
docker exec -it $(docker ps -q --filter "name=vault") /bin/ash

# run netstat like so:
netstat -anp

You should get something like:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:8250          0.0.0.0:*               LISTEN      28/vault
tcp        0      0 172.17.0.3:40342        10.10.5.147:443         ESTABLISHED 28/vault

In order for localhost:8250 to correctly map from your host machine, to Docker, and to your application, that 127.0.0.1:8250 blurb needs to be 0.0.0.0:8250 (or something like :::8250).

To cross-reference this with a properly configured application's container, like nginx, we get this:

docker exec -it $(docker ps -q --filter "name=nginx") /bin/bash
root@c761ba56b8aa:/# netstat -anp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro 
tcp6       0      0 :::80                   :::*                    LISTEN      1/nginx: master pro 

If we assume that that output is what is needed for something like localhost:80 to map from a host machine to an nginx application inside a Docker container, we can run our vault login test again like so:

# while exec'd into the vault container we spun up before, run this:
vault login -method=oidc listenaddress=0.0.0.0

# open a new tab/window, exec into that vault container, then run this:
netstat -anp

And you see that netstat is showing similar output to what nginx is utilizing:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 172.17.0.3:40346        10.10.5.147:443         ESTABLISHED 63/vault
tcp        0      0 :::8250                 :::*                    LISTEN      63/vault

And more importantly, you can visit the url output by vault login -method=oidc listenaddress=0.0.0.0 in your host machine's browser, and the redirect works properly, and then the login succeeds inside the container.

Expected behavior

In a perfect world, running vault login -method=oidc from inside a container would just work with no additional parameters, since the container and the Vault application inside it would automatically set the listenaddress to 0.0.0.0.

If this is unachievable, PLEASE FOR ALL THE KITTENS ON THE INTERNET update your Docker Hub docs to include that parameter in this use case since this is not at all straightforward.

Environment:

  • Vault Server Version (retrieve with vault status): 1.8.1
  • Vault CLI Version (retrieve with vault version): Vault v1.8.2
  • Server Operating System/Architecture: OSX 11.3.1 & Docker 20.10.8, build 3967b7d

Vault server configuration file(s): none, just the base container

@Gourds
Copy link

Gourds commented Nov 5, 2021

+1

@typoworx-de
Copy link

typoworx-de commented Nov 24, 2021

Any solution on this? I'm trying to setup this on docker, but it's very confusing, that the docs mention the solution to use ENV VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:1234

But this leads to the following error starting up the container:

Error parsing synthesized cluster address 0.0.0.0: parse "0.0.0.0": invalid URI for request

This is also discussed here (link follows), mentioning this solution inside configuration-file:

address = "0.0.0.0:8200"
tls_disable = "true"

https://discuss.hashicorp.com/t/vault-server-ui-not-accessible-outside-localhost/20326

Which also won't work, showing up:

Error initializing listener of type tcp: listen tcp4 0.0.0.0:8200: bind: address already in use

or switching to different port it starts, but is not reachable on the container-ip assigned :-(

@Gourds
Copy link

Gourds commented Nov 25, 2021

@typoworx-de The following configuration is valid for me
docker-compose

version: '3.3'
services:
  vault:
    image: vault:1.8.5
    container_name: vault
    environment:
      VAULT_ADDR: "http://0.0.0.0:8200"
      VAULT_API_ADDR: "http://0.0.0.0:8200"
      VAULT_ADDRESS: "http://0.0.0.0:8200"
      # VAULT_UI: true
      # VAULT_TOKEN:
    ports:
      - "8200:8200"
    restart: always
    volumes:
      - /srv/docker/vault/logs:/vault/logs
      - /srv/docker/vault/data:/vault/data
      - /srv/docker/vault/config:/vault/config
      - /srv/docker/vault/certs:/certs
    cap_add:
      - IPC_LOCK
    entrypoint: vault server -config /vault/config/config.hcl
    networks:
      - my-network

networks:
  my-network:
    external:
      name: gourds-demo

config.hcl

ui = true
disable_mlock = "true"

storage "raft" {
  path    = "/vault/data"
  node_id = "node1"
}

listener "tcp" {
  address = "[::]:8200"
  tls_disable = true
  tls_cert_file = "/certs/server.crt"
  tls_key_file  = "/certs/server.key"
}

api_addr = "http://0.0.0.0:8200"
cluster_addr = "https://127.0.0.1:8201"

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants