99designs / aws-vault

A vault for securely storing and accessing AWS credentials in development environments
MIT License
8.52k stars 820 forks source link

fix: listen on all interfaces for ecs-server #1199

Open frco9 opened 1 year ago

frco9 commented 1 year ago

This MR is a quick fix that should solve https://github.com/99designs/aws-vault/issues/1198

Currently ecs-server only listens to the loopback address making it unreachable from docker containers on Linux.

mtibben commented 1 year ago

What are the potential security side-effects here? Should we be listening on all interfaces?

frco9 commented 1 year ago

That's a good question and it's a bit out of my domain of expertise. It would mean that if a user does not have a proper firewall, any user knowing the ip of the user, the port of the ecs-server and the auth token, would be able to request sessions token from the user's ecs-server. I agree it's not perfect as it increase attack surface, although as the port and auth token is supposed to only be accessible from the aws-vault subprocess, it seems not that obvious to find them ?

Otherwise, this could be made configurable as initially proposed in the issue ? Don't you have this access denied issue on Linux ?

mtibben commented 1 year ago

No, I use macOS. Perhaps we add a --listen-address flag that defaults to 127.0.0.1?

frco9 commented 1 year ago

@mtibben, I've made the changes, I'm not really used to develop in Golang. I've successfully compile and test it locally but please tell me if things can be refactored or if I've missed something.

frco9 commented 1 year ago

@mtibben could you take a look ?

mtibben commented 1 year ago

Tried this out, however realised that the aws cli (not sure about the sdk) doesn't actually allow arbitrary hosts

Unsupported host '::'.  Can only retrieve metadata from these hosts: 169.254.170.2, localhost, 127.0.0.1

So the problem seems confined to the docker scenario in the issue. Can you see if the solution described at https://github.com/99designs/aws-vault/issues/1198#issuecomment-1484249196 works?

frco9 commented 1 year ago

Issue is just that BaseURL is not returning a valid https url that could be fetched it returns http://[::]:{port}.

This seems linked to https://github.com/golang/go/issues/9334. To "fix" that and force to bind on ipv4 I have changed the network type from tcp to tcp4

Now base url returns the proper value:

AWS_CONTAINER_CREDENTIALS_FULL_URI=http://127.0.0.1:{port}
RemaniTinpo commented 1 year ago

:wave:

Hi,

I'm having the same issue as a Linux user. Any chance that this PR would be merged?

Thanks a lot, @frco9 and @mtibben

awilkins commented 1 year ago

Hey there!

As per my comment in the issue, on Linux, the safest value to pass to this argument would be the output of this

docker network inspect bridge | jq '.[0].IPAM.Config[0].Gateway'

In conjunction with adding this to your docker-compose.

    extra_hosts:
     - host.docker.internal:host-gateway

0.0.0.0 isn't terrible because the ECS server requires an auth token for access, which is passed down to the child process of aws-vault exec via the environment. Because this isn't available to a hypothetical adversary elsewhere in the network, in theory you're safe. In practice, someone might find an exploit or DoS attack for the ECS server implementation, so it's safer to only listen to interfaces you're expecting traffic from.

So the full command (with this option added) would be

aws-vault exec \
    --ecs-server \
    --listen-address $(docker network inspect bridge | jq '.[0].IPAM.Config[0].Gateway') \
    my-profile -- \
    docker compose up --build aws-vault-proxy