Nginx docker IP not a trusted proxy to HA

So running HA in Docker with the configuration.yaml lines for http to trust my nginx reverse proxy - also running in Docker. Nginx docker network was on IP 172.18.0.0/24. All good for a week.

Last night it all stopped working. No remote access. After investigation I found nginx docker had restarted and its network was now on 172.20.0.0/24. This subnet was not in the trusted proxies. So i added it and now all is well again.

How do I prevent nginx docker from changing its IP and thereby becoming an UNtrusted proxy - or is there a better way to handle this in HA.

This is not normal

Docker networks will not normal change IP range as this is fixed. It seems more like nginx container was recreated and new network made. Is this docker compose?

Create a docker network yourself and make the nginx container use that network instead of the docker default network.

can you elaborate on what you mean and the benefits, with a use case please. I found this but have to say it’s over my head:
docker network create | Docker Docs

@tmjpugh you are absolutely spot on. This is docker-compose and I did delete the images due to an issue and recreated them with docker-compose up -d. I had no idea docker creates new networks each time but then I guess that is pretty obvious. Would a subnet mask of 172.0.0.0/24 in trusted proxies - or is that either/both (a)bad practice, (b)not possible anyway.

It’s actually not as bad as it looks. Its good practice for a few reasons, but it will definitely help with this issue you are having.

After you create your network, you can add that subnet you used in this as your trusted proxy in homeassistant.

You will need to modify your docker-compose to make your nginx use this network by adding

networks:
  default:
    external:
      name:  the_name_you_used_for_your_network

Tear down and re-create your containers and it should now be part of the new network.

You mean 172.0.0.0/24 ?

And create the network with docker network create …

You can define the subnet you want to use. In this example I will use 172.0.3.0/24

docker network create -d bridge --subnet 172.0.3.0/24 --gateway 172.0.3.1 my_new_network

After this, you can confirm the network was created by doing docker network ls

so would your command create a bridge between my local network on 192.168.0.0/24?
and
the gateway 172.0.3.1 - is that something docker provides or do I need to set it up because currently nothing has that ip to my knowledge?

Docker would take care of the bridging. All you should need to do is create the docker network and then adjust your docker-compose for the containers you want to be part of this network.

so - ?? - where is the gateway , 172.0.3.1 ??

and if I use my ‘own’ network in each docker-compose, what does that actually do , do I still need the ports mappings for example?

port mapping is for external devices to connect to port in docker container. it opens port into docker network same as you opening port in your router

if you create a docker network nothing can access it except another container in that docker network.

Gateway has no meaning here. its containers on a network connecting to each other directly.

Your original problems was compose created a new network with new IPs and removed the old. to prevent this you will create a docker network, not managed by compose, that will survive compose up/down (stack restarts)

when this new network is created you just need to tell compose to use that network


service:
  homeassistant:
    hostname: homeassistant
    networks:
      that_network_you_made:
      zwavejs: #this is a network that was created to use with a seperate zwavejs container
  nginx:
    hostname: nginx
    networks:
      that_network_you_made:
        ipv4_address: 172.18.0.4 #give it a static ip on that network you created
networks:
  that_network_you_made:
    external: true
  zwavejs:
    external: true

with this nginx will keep a static IP on the network and you can just trust the single IP.
Also, in nginx you can reach HA at homeassistant:8123. You cannot trust hostnames but HA will still be able to ping nginx at nginx. And as an addional example if you have a seperate zwavejs container and created a network for that homeassistant could be seen on that network but nginx would not since that network was not defined for it

if you don’t use portainer, use portainer. it makes all this easier to do.

2 Likes

excellent. i understand now. and reading the docker guides it NOW makes sense. thank hou so.much @tmjpugh

that’s EXACTLY what I’m after… a segregated networkjsu for all the docker containers

portainer? i will google that…

Q1…
so i suppose this is the inverse of the insanley insecure network_mode: host

Q2.
whats difference between this

networks:
  that_network_you_made:
    external: true
  zwavejs:
    external: true

and this...

networks:
   external:
      that_network_you_made
      zwavejs

both seem to be accepted

Q3. so to share port 443 across two contIners would it be…


ports:
- 127.0.0.1:443:127.0.0.1:443

…to limit connections only from the host (dockers)
EDIT: nope, if i create my own docker network and connect dockers to it…ports are all accessible inter-containers … yes?

yes. this is just the standard docker bridge.

There are comments on both side re: host networking. I dont think it is insecure, just dont like to give unnecessary access. For years I avoided it for HA. In the end i created mac vlan and prefer this. macvlan also allows discovery, mdns and other stuff.

unsure. not sure if that is option. used docker 7 years and only 2 day ago started using compose. I believe your 2nd option is just wrong but truly do not know.

NO. Docker containers on same docker network can access all container ports. if HA and NGINX are both using a docker network called “smarthome” and you defined HA hostname as “homeassistant”. NGINX could access HA at port 443 using “homeassistant:443”. No need to use IP and best you dont as IP can change with exception being my example for NGINX above where a static IP is defined for the network

looks like you figured out #3 on your own

1 Like

@tmjpugh
tha nk younfor sharing your experience and inight. it is all working now after a few.tweaks. and thanks tonyou the topic is easier to understand
:ok_hand:

Well, I did as you said, created my own network 'daz_docker_network"

then I have this yaml:


version: '3.4'
services:
  energenie_mqtt_client:
    image: gpbenton/engmqttclient:1.0.0
    restart: unless-stopped
    container_name: energenie_mqtt_client
    privileged: true
    working_dir: /opt/energenie_mqtt_client/
    command: ["-h", "localhost"]
    volumes:
      - $PWD/engMQTTClient/log4c:/etc/log4c
      - /dev/mem:/dev/mem
    environment:
      LOG4C_RCPATH: '/etc/log4c/log4crc'
      LOG4C_PRIORITY: info
      LOG4C_APPENDER: stdout
    networks:
      -  daz_docker_network

  mosquitto:
    container_name: mosquitto
    restart: unless-stopped
    image: eclipse-mosquitto
    volumes:
      - ./config:/mosquitto/config
      - mosquitto_persistence_database:/mosquitto/data
      - /etc/localtime:/etc/localtime:ro
    networks:
      - daz_docker_network

volumes:
  mosquitto_persistence_database:

networks:
  daz_docker_network:
    external: true
    driver: bridge

but it doesnt work. Each service cannot see each other.

If I add network_mode: host then all is well.

What have I done wrong?

Presuming you manually created daz_docker_network, remove “driver: bridge”

If you Did Not manually create daz_docker_network, remove “external: true”

EDIT
Just to be clear, only the 2 service above will work on daz_docker_network based on above

1 Like

Mmmm…i created using the instruction above

…using daz_docker_network as the name

so bridge is incorrect? extrrnal is correct? and if I use the same network config in other docker_-compiose files, why will only these two services see it nexus i want that network to be for all containers.?

yes. Keep external: true and remove driver: bridge

You can add any container to the network at docker run, adding it in compose, or using docker network connect command.

All working. This is the final config:

version: '3.4'
services:
  energenie_mqtt_client:
    image: gpbenton/engmqttclient:1.0.0
    restart: unless-stopped
    container_name: energenie_mqtt_client
    privileged: true
    working_dir: /opt/energenie_mqtt_client/
    command: ["-h", "172.0.1.100"]
    volumes:
      - $PWD/engMQTTClient/log4c:/etc/log4c
      - /dev/mem:/dev/mem
    environment:
      LOG4C_RCPATH: '/etc/log4c/log4crc'
      LOG4C_PRIORITY: info
      LOG4C_APPENDER: stdout
    networks:
      - daz_docker_network

  mosquitto:
    container_name: mosquitto
    restart: unless-stopped
    image: eclipse-mosquitto
    volumes:
      - ./config:/mosquitto/config
      - mosquitto_persistence_database:/mosquitto/data
      - /etc/localtime:/etc/localtime:ro
    networks:
      daz_docker_network:
        ipv4_address: 172.0.1.100

volumes:
  mosquitto_persistence_database:

networks:
  daz_docker_network:
    external: true

Where I was going wrong was using localhost as the argument to the command in the mosquito client. After reading the docker network reference and only on the back of your help and explanations, did I grasp that localhost is the container and not the docker host. So I had to assign an IP to the broker and use that in the client. I also had to set the IP as a listener in mosquitto.conf

All good now. Thanks muchly

However, MQTT/HA problem…
I have locked in the IP to the broker in this docker. I could not take the docker to another setup and have it working. So the issue is that in daz_docker_network the mqtt broker for home assistant is in the container whose network IP is 172.0.1.100. I dont want to have to configure HA to ‘see’ the broker so can I set the broker listener to 0.0.0.0 - i.e. any IP in daz_docker_network can connect at default port 1883?
(well what I mean is - is it ok? or bad practice? I mean it seems to work fine as I tried it but…?)
and i probably should move mosquitto to its own container.

EDIT: I do not believe I can get away without using the broker IP in HA MQTT integration. I was using localhost but of course that is scoped only to the container HA is running in. Kind of need a reference to the docker network as docker_local or something?? Then I can use docker_local:1883 in the mqtt integration and if the IP changes for the broker then it wont break anything. Not sure if this is possible though?