Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web password is regenerated every time the container is recreated #364

Closed
3 of 7 tasks
ericparton opened this issue Nov 21, 2018 · 19 comments
Closed
3 of 7 tasks

Web password is regenerated every time the container is recreated #364

ericparton opened this issue Nov 21, 2018 · 19 comments

Comments

@ericparton
Copy link

This is a...

  • Request for a new or modified feature
  • Issue trying to run the docker image
  • Issue trying to build / test / develop the docker image

Description

I'm using docker compose to manage an installation of pihole, but every time the container needs to be recreated as the result of an update to the container or a configuration change, the web password is set to a new random value. Per the documentation, I'm mounting a persistent volume at /etc/pihole, which does save the rest of my settings, but just not the web password.

Expected Behavior

The web password is stored in somewhere in /etc/pihole and persisted with the rest of the configuration if a volume is mounted there.

Actual Behavior

The web password is not persisted with the rest of the configuration and is always regenerated when a new container is created, even if the container is reusing the configuration from a mounted volume.

Steps to Reproduce and debugging done

  1. Create a container using the instructions in the readme
  2. Stop that container, then create a new container with the same volumes
  3. Observe that the web passwords are not the same

Debug steps I have tried

  • I have tried destroying my container instance, pulling the newest image version, and re-creating a new container
  • I have tried running the nearly stock docker run example in the readme (removing any customizations I added)
  • I have tried running without my volume data mounts to eliminate volumes as the cause
  • I have searched this repository for existing issues and pull requests that look similar

Context and extra information

There is a workaround by setting the WEBPASSWORD variable, but you have to then hard code a password somewhere.

Your Environment

  • Docker Host Operating System and OS Version: Ubuntu 18.0.4
  • Docker Version: 18.09
  • Hardware architecture: x86
@nxadm
Copy link
Contributor

nxadm commented Nov 21, 2018

You can set the password in something like docker-compose?

# cat docker-compose.yml 
version: '2'
services:
  pihole:
    build:
      context: /opt/docker/_upstream/docker-pi-hole
      dockerfile: Dockerfile_amd64
    environment:
      - TZ='Europe/Brussels'
      - ServerIP=192.168.1.2
      - WEBPASSWORD=FooBar
      - DNS1=8.8.8.8
      - DNS2=8.8.4.4
      - IPv6=False
    ports:
      - "192.168.1.2:53:53"
      - "192.168.1.2:53:53/udp"
      - "192.168.1.2:80:80"
      - "192.168.1.2:443:443"
    volumes:
      - /opt/docker/pihole/rw/pihole:/etc/pihole
      - /opt/docker/pihole/rw/dnsmasq.d:/etc/dnsmasq.d
#    init: true    
    restart: always
#    network_mode: "host"

@LordMike
Copy link

Would it be possible to not set the password, ie. use the one configured?

Perhaps test if the config file has a WEBPASSWORD set.

@ericparton
Copy link
Author

@nxadm yeah, that's pretty much what I'm doing now, but it forces you to hard code that password in the compose file

@nxadm
Copy link
Contributor

nxadm commented Nov 22, 2018

@ericparton It seems to me you need to put it somewhere. You can have a look at things like vault if you want to centralize your secrets.

@LordMike
Copy link

@nxadm but it's already stored in the config file - passing it in via. the environment should only be a one-time thing.

The config file is, in my case, already mounted in using a volume.

@zion
Copy link

zion commented Dec 4, 2018

This is happening to me as well, for now Im just adding it to the docker-compose environment params. However I also noticed that when the container restarts or is updated, the selections of dns server on this page: /admin/settings.php?tab=dns are reverted back to default, which is Google.

Where is these data stored? Is it not /etc/pihole?

@nxadm
Copy link
Contributor

nxadm commented Dec 8, 2018

On my setup:

    volumes:
      - /opt/docker/pihole/rw/pihole:/etc/pihole
      - /opt/docker/pihole/rw/dnsmasq.d:/etc/dnsmasq.d

@zion
Copy link

zion commented Dec 8, 2018

In my compose file I don’t have the dnsmasq file mapped. Maybe that’s it. I’ll try it soon. I like your org structure on your host machine. I’m gonna use that. Thanks

@zion
Copy link

zion commented Dec 10, 2018

Adding the dnsmasq.d volume mount solved my issue! Thanks @nxadm

@meilon
Copy link

meilon commented Dec 11, 2018

The problem with the re-genarated password still exists, because that is how it currently is setup. In start.sh the first command issued is generate_password, which doesn't check if there is a password in the config file:

generate_password() {
if [ -z "${WEBPASSWORD+x}" ] ; then
# Not set at all, give the user a random pass
WEBPASSWORD=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
echo "Assigning random password: $WEBPASSWORD"
fi;
}

This then gets used by setup_web_password:

setup_web_password() {
PASS="$1"
# Turn bash debug on while setting up password (to print it)
if [[ "$PASS" == "" ]] ; then
echo "" | pihole -a -p
else
echo "Setting password: ${PASS}"
set -x
pihole -a -p "$PASS" "$PASS"
fi
# Turn bash debug back off after print password setup
# (subshell to null hides printing output)
{ set +x; } 2>/dev/null
# To avoid printing this if conditional in bash debug, turn off debug above..
# then re-enable debug if necessary (more code but cleaner printed output)
if [ "${PH_VERBOSE:-0}" -gt 0 ] ; then
set -x
fi
}

This of course is the same for other settings like DNS servers to use, web port and the likes.

In my opinion, the first thing that start.sh should check if there is a config file and abort generating and setting stuff from the env vars should be disabled in that case. Please only generate a config if there is no existing config!
After the first generation of the docker container I should only need to use docker specific arguments with docker run (which volumes to mount, which network to connect to, which ports to forward, ...) and no application specific commands (like environment variables). That's what the persistent volumes are for.
If I messed up my config and want to start from scratch I delete/move the volumes and start from there.

If there is already such a feature implemented and I didn't see it, I guess that my issue is related to #328

@nxadm
Copy link
Contributor

nxadm commented Dec 11, 2018

@meilon

The "fix" should be straight forward. However, in my case I have no problems with providing it through a compose file or Hashicorp's Vault (if I want it centralized). However, the clear-text password is needed by the application and I struggle to see the difference between a compose file (chmod 400) and a file on a mounted volume.

@meilon
Copy link

meilon commented Dec 11, 2018

I know we are talking about an app most of us are deploying on the local home network without outside access. But:

You store the clear-text password on the filesystem with a docker-compose, pi-hole saves it as a double-hashed string. Not the most secure thing, but certainly a lot better than clear-text. The Vault is nice if the execution of the docker run isn't logged (bash .history or something like it, don't know your integration), and last but not least, the password is readable in docker logs

Setting a fixed password is clearly a workaround. But all other long running docker containers on my systems save their important stuff in their volumes and load their settings from there after a re-generation (aka "updating") of the container. I've never changed a setting by removing the container and starting it with different env vars. What's the point of using volumes then?

@nxadm
Copy link
Contributor

nxadm commented Dec 11, 2018

@meilon

I see what you mean.

(When using Vault you can use https://github.com/hashicorp/consul-template to wrap the actual application so no bash history or enviroment variables are set. This is more FYI than an answer to your requirements.)

@meilon
Copy link

meilon commented Feb 15, 2019

It has been two months and nothing happened. If it is okay I would try and write up a PR for this. I'd add a mechanism to the start.sh which checks if there is a config. If it's there it will ignore any ENV variables. concerning the config files.

@diginc
Copy link
Collaborator

diginc commented Feb 15, 2019

Sorry for no action for so long, contributions by pull request are greatly appreciated. Would an escape hatch design to skip the web password setup function based off an ENV work instead? It is probably simpler to implement and I've seen the need for this in other cases and even wrote one.

setup_blocklists() {
local blocklists="$1"
# Exit/return early without setting up adlists with defaults for any of the following conditions:
# 1. NO_SETUP env is set
exit_string="(exiting ${FUNCNAME[0]} early)"
if [ -n "${NO_SETUP}" ]; then
echo "::: NO_SETUP requested ($exit_string)"
return
fi

To make this scale up I think SKIP_SETUP_WEB_PASSWORD for your case and SKIP_ should be the convention.

@meilon
Copy link

meilon commented Feb 16, 2019

They way I learned to use docker images is just start it with the bare minimum. Just set what you need to get into the app, and change the settings in there. That way you start the container the same way every time. Also the docker start script doesn't need to change every time something changes in the way the apps configuration mechanism changes.
This would not be true if SKIP_X gets implemented. Why ask the users to use a fancy script to setup the application, then, please stop the container, remove it and then start it again with different ENVs if you want to change your DNS from Google to CloudFlare? ENVs should only be used to make the app work inside the container. Set timezone, use specific UID and GUID to make volumes work etc.

If I want to change something, why should I want to stop my DNS server and start with a fresh container? Why recommending a mounted volume for the configuration if it doesn't persist? If there is a config, don't touch it.

I just had a look at the most popular images on dockerhub using ENVs: mongo, mysql and in 12th place, postgres. They either say Do note that none of the variables below will have any effect if you start the container with a data directory that already contains a database: any pre-existing database will always be left untouched on container startup. or they don't change the behaviour between restarts of the container like postgres. If you don't set POSTGRES_PASSWORD, it's still the same after a container/host restart- Restarting the container should change nothing except restarting the application. And in the case of this containerized pi-hole, it does!

@diginc
Copy link
Collaborator

diginc commented Feb 17, 2019

Gotcha, yeah we can make this work with a check against a password already being set. I think the same approach could be taken for many of the other env variables / setupVar.conf settings but that maybe best saved for a larger refactor. For now I'll get web password done.

diginc added a commit that referenced this issue Feb 17, 2019
Signed-off-by: Adam Hill <[email protected]>
@diginc
Copy link
Collaborator

diginc commented Feb 17, 2019

Please try out pihole/pihole:dev docker image to see if it resolves this issue.

@meilon
Copy link

meilon commented Feb 18, 2019

Yes, the web password didn't change

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

No branches or pull requests

6 participants