0

I'm using Alpine Linux via Docker. I want to make an HTTPS connection to host.docker.internal. There is a service on the host machine that can be reached via localhost:8443 on the host machine. I want to connect to this same service from the container. --network host will not work because within the container, localhost needs to refer to the container, not to the host machine.

The service running on the host machine on port 8443 is actually coming from an SSH tunnel to an EC2 container, to ultimately allow connection to an Opensearch server in our AWS network that is listening on port 443.

This is what I have done in order to achieve this:

  1. Create a self-signed cert for host.docker.internal that specifies a subject alternative name:
    openssl req -newkey rsa:4096 \
             -x509 \
             -sha256 \
             -days 30650 \
             -nodes \
             -out docker-host.crt \
             -keyout docker-host.key \
             -subj "/C=US/ST=Nevada/L=Las Vegas/O=Company/OU=Engineering/CN=host.docker.internal" \
             -addext "subjectAltName=DNS:host.docker.internal"
    
  2. Copy this to /usr/local/share/ca-certificates: cp docker-host.crt /usr/local/share/ca-certificates
  3. Run update-ca-certificates
  4. Confirm the cert is recognized:
    openssl verify -CApath /etc/ssl/certs docker-host.crt
    
  5. Try to use curl to connect: curl https://host.docker.internal:8443/

I always get the error curl: (60) SSL: no alternative certificate subject name matches target host name 'host.docker.internal'

I tried creating a "bundle" certificate:

cat docker-host.pem cert.pem > bundle.pem
cp bundle.pem /usr/local/share/ca-certificates/docker-host.crt

cert.pem was created with openssl s_client -showcerts -servername host.docker.internal -connect host.docker.internal:8443 > cert.pem

I got this command from cURL's page on this issue.

docker-host.pem is created with cat docker-host.key docker-host.crt > docker-host.pem. I tried copying this .pem (renamed to .crt of course) to /usr/local/share/ca-certificates/ but it makes no difference.

No matter what, I always get the same error. Surely I am misunderstanding something.

Please advise. Thank you.

  • 'a service on the host machine' (listening at 8443) is not using your new cert and key. You need to change 'a service' to do so. How to do this depends on the details of 'a service' which you didn't identify or describe in any way. BTW Las Vegas is not a state or province -- but curl doesn't care, it doesn't check any names other than SAN and maybe CN, and I doubt anything else will care either. – dave_thompson_085 Jul 21 '22 at 05:11
  • @dave_thompson_085 Thanks so much for this. Hmm... what you say makes sense. Sorry, I do mean to provide more details, so that I hope my situation makes more sense. And yes, I didn't really make it for Las Vegas, but I will correct that nonetheless. – Spencer Williams Jul 21 '22 at 13:56
  • 1
    You say this is actually a tunnel to a (remote) Opensearch server, thus you need that Opensearch server to use your key-and-cert. If it is also accessed by client(s) anywhere outside your container, that(those) cannot use the name `host.docker.internal` to reach the server and cannot accept the new cert, so you need the server to use _both_ certs depending on SNI; most can nowadays but I don't know Opensearch in particular. Possibly a better solution is to have the container client use the _correct_ name of the server but resolve it to your desired (docker-host) address (172.17.something); – dave_thompson_085 Jul 25 '22 at 08:52
  • `curl` can do this by itself (see option `--resolve` in the man page) but other programs may need you to set `/etc/hosts` and/or run a local DNS like dnsmasq or unbound either in the container or in the host but only used by the container(s?). – dave_thompson_085 Jul 25 '22 at 08:54
  • @dave_thompson_085 Thanks so much for this advice. Yes, I see the main problem is that the server ultimately being reached does not have `host.docker.internal` as an alternative name, so I am better understanding the error. I see that I could have the Opensearch server name resolve to the docker host IP. Or maybe run a web server on the host as a reverse proxy, using the .internal SSL cert. Such a solution would be too much for this project, and I ended up fixing a problem in a package that was not acknowledging the no_ssl_verify setting. Nevertheless, I will explore an alternate solution. – Spencer Williams Jul 26 '22 at 19:43

0 Answers0