Hello guys,
I'm having some trouble trying to not pass my passwords in plain text at the patroni.yml file.
I've already deployed patroni successfully by filling the patroni.yml as the example (with plain-text passwords) and now I want to improve it... By passing this passwords as variables that will be filled in another file.
Knowing ansible structure, I tried to put this variables in /etc/group_vars/all file but patroni doesn't seem to find them.
Part of /etc/patroni.yml file:
authentication:
replication:
username: replicator
password: "{{ replicator_pass }}"
superuser:
username: postgres
password: "{{ postgres_pass }}"
Error in /var/log/messages:
Dec 2 19:41:35 postgresql01 patroni: 2018-12-02 19:41:35,810 INFO: Error communicating with PostgreSQL. Will try again later
Dec 2 19:41:37 postgresql01 patroni: 2018-12-02 19:41:37,265 ERROR: get_postgresql_status
Dec 2 19:41:37 postgresql01 patroni: Traceback (most recent call last):
Dec 2 19:41:37 postgresql01 patroni: File "/usr/lib/python2.7/site-packages/patroni/api.py", line 424, in get_postgresql_status
Dec 2 19:41:37 postgresql01 patroni: self.server.patroni.postgresql.lsn_name), retry=retry)[0]
Dec 2 19:41:37 postgresql01 patroni: File "/usr/lib/python2.7/site-packages/patroni/api.py", line 399, in query
Dec 2 19:41:37 postgresql01 patroni: return self.server.query(sql, *params)
Dec 2 19:41:37 postgresql01 patroni: File "/usr/lib/python2.7/site-packages/patroni/api.py", line 480, in query
Dec 2 19:41:37 postgresql01 patroni: raise PostgresConnectionException('connection problems')
Dec 2 19:41:37 postgresql01 patroni: PostgresConnectionException: 'connection problems'
Dec 2 19:41:40 postgresql01 patroni: 2018-12-02 19:41:40,274 ERROR: get_postgresql_status
/etc/systemd/system/patroni.service file:
[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=syslog.target network.target
[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/bin/patroni /etc/patroni.yml
KillMode=process
TimeoutSec=30
Restart=no
[Install]
WantedBy=multi-user.targ
Is passing variables supported by patroni code? Is there a specific place where I should put the variables file?
If not, how is the recommended way to deploy patroni without the need of putting the passwords in plain-text?
Thank you!
Is passing variables supported by patroni code?
No, it is not supported. Actually keeping passwords in a different file doesn't change anything. It is still possible to read them with the same permissions as the patroni config and therefore risks are absolutely the same.
Is passing variables supported by patroni code?
No, it is not supported. Actually keeping passwords in a different file doesn't change anything. It is still possible to read them with the same permissions as the patroni config and therefore risks are absolutely the same.
I see... Actually my original idea was to use ansible vault. That's why I would need the value of the variables in another file... Anyway, is there another way to accomplish this? Encrypt the passwords... Use another method... Anything that is not plain-text?
It would be great if patroni could read hashes (SHA256 for example) written in the config file, like (for example) haproxy. Via hashlib (https://docs.python.org/2/library/hashlib.html#module-hashlib) I guess this would need a PR from us..
Patroni itself can not do that. The idea of ansible and vault, that in the repository where you keep configs there is no unencrypted passwords, but after deploying it to the server you get a normal config.
Just think about this problem from a different perspective. Patroni has all permissions to manage postgres (start and stop it, read all files from PGDATA). This is way more than just reading config file with the password. If somebody has enough permissions to read patroni config, the same person could also read all files from PGDATA.
Granted,, no doubt about what you say above. One has to proper protect the postgresql login/group and of course, setup secure permissions for the Patroni config file. No big deal.
Patroni itself can not do that. The idea of ansible and vault, that in the repository where you keep configs there is no unencrypted passwords, but after deploying it to the server you get a normal config.
Just think about this problem from a different perspective. Patroni has all permissions to manage postgres (start and stop it, read all files from PGDATA). This is way more than just reading config file with the password. If somebody has enough permissions to read patroni config, the same person could also read all files from PGDATA.
Nice approach... Basically my main though was about not keeping this passwords exposed in the config file without further analysing other aspects of the configuration itself. So, I'll work on the config file permissions. Thank you!
Hi @biarocha ,
PR: https://github.com/zalando/patroni/pull/746 looks to solve the problem of keeping the passwords in separate file. But it doesn't change anything from security point of view.
It is still possible to read them with the same permissions as the patroni config and therefore risks are absolutely the same.
@biarocha actually @srikanth-medikonda is right, it is possible to pass superuser and replication passwords via environment variables PATRONI_SUPERUSER_PASSWORD and PATRONI_REPLICATION_PASSWORD: https://github.com/zalando/patroni/blob/master/docs/ENVIRONMENT.rst#postgresql
At the end it doesn't improve security at all (actually makes it worse), because on some platforms it is possible to read environment from other user...
Well where this helps is if you keep your configuration files in some configuration management system or version-control repository prior to deploy, where others could potentially get to the credentials if you make mistakes. I agree that on-instance it does not matter much.
Most helpful comment
It would be great if patroni could read hashes (SHA256 for example) written in the config file, like (for example) haproxy. Via hashlib (https://docs.python.org/2/library/hashlib.html#module-hashlib) I guess this would need a PR from us..