PostgreSQL failing peer authentication with Ansible - postgresql

I am running PostgreSQL 9.3 on FreeBSD. FreeBSD uses pgsql as the default system user for PostgreSQL. My /usr/local/pgsql/data/pg_hba.conf looks like this:
# TYPE DATABASE USER ADDRESS METHOD
local all pgsql peer
local all all md5
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
With this configuration I can connect to the database as pgsql without a password.
$ su pgsql
$ psql template1
template1=# \l
List of databases
...
That works as intended.
On a remote machine, I have an Ansible task to create a database on the FreeBSD server.
- name: Create the postgresql database
postgresql_db: name=mydatabase login_user=pgsql
Executing this task fails with the error Peer authentication failed for user "pgsql".
PLAY [web] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [host.example.org]
TASK: [database | Create the postgresql database] *****************************
failed: [host.example.org] => {"failed": true}
msg: unable to connect to database: FATAL: Peer authentication failed for user "pgsql"
FATAL: all hosts have already failed -- aborting
Why does this fail when peer authentication for the user pgsql is clearly working?

This worked for me:
- name: Create postgres database
become: true
become_user: postgres
postgresql_db:
name: <database-name>
In your specific case the user might be pgsql, but I think usually the user is postgres.

Or with slightly different syntax (from Ansible 1.9) and for user creation (might be helpful for someone)
- name: Create postgres user
postgresql_user: name={{ pg_user }} password={{ pg_password }}
become: true
become_user: postgres

For those running into "Failed to set permissions on the temporary files Ansible needs to create..." in order to switch to the postgres user with become_user you can leverage pipelining on Ubuntu hosts.
Create a ansible.cfg in your playbook directory and add the following lines:
[ssh_connection]
pipelining=True
Update: according to #lolcode Ansible 2.9.0 has updated to ansible_pipelining
[ssh_connection]
ansible_pipelining = true
Update 4/30/2020: for those who still have issues, try installing acl which will cause Ansible to use this acl filesystem to mount module that need to be accessible by the 2nd user instead of making them readable by everyone. Thanks #Andreas Florath
- name: install setfacl support
become: yes
apt: pkg=acl

I had the same problem. In my case I overlooked that I configured my Ansible-playbook to run as another Linux user than the one with peer access (pgsql in your case). Solution is either run the Ansible play as pgsql:
- name: Create the postgresql database
remote_user: pgsql
postgresql_db: name=mydatabase login_user=pgsql
...
Or run it as root, and su to pgsql for the command:
- name: Create the postgresql database
remote_user: root
become: yes
become_user: pgsql
postgresql_db: name=mydatabase login_user=pgsql
...
... depending on your access rights via ssh.
This is using Ansible 2.0.

Another workaround is to connect via host (localhost) rather than the default local peer authentication method:
- name: Create the postgresql database
postgresql_db:
name: mydatabase
login_user: postgres
login_host: 127.0.0.1
Depending on the settings in pg_hba.conf, you may also need to provide login_password. You can circumvent this by setting
host all postgres 127.0.0.1/32 md5
to
host all postgres 127.0.0.1/32 trust

I notice your Postgres version is really out of date (9.3). I had this issue recently when working on an Ubuntu 14 server with Postgres 9.3.
I tried a dozen different things, and finally what worked was installing the acl package via apt. Ansible uses it for navigating some of it's permissions issues. The package is installed by default on newer distros, hence why I've only seen this problem crop up on an old server.

Thanks to this threat I made a variant of mdh's post. When I set up a database I generate a password for the postgres user and I store it in a file under the root directory.
I thought why not store it also (or instead) in a .pgpass file for root. So I created a template like this (only last line is important):
#### password file for posgres connection ###
#### *:*:*:*
#### works like
#### * : * : * : *
#### <ip addr> : <port nr> : <db name> : <password>
127.0.0.1:*:*:postgres:{{ new_postgres_pass }}
Store the .pgpass file in the home directory of root. Now you can use the module as root without switching user of having to change the pg_hba.conf:
- name: Ensure postgresql mydatabase
postgresql_db:
name: mydatabase
login_user: postgres
login_host: 127.0.0.1

If you don't have sudo (debian, etc) but have access to root
- name: Create database
remote_user: root
become: yes
become_method: su
become_user: postgres
postgresql_db:
name: my_db

This problem due to postgres authentication methods configured at /etc/postgresql/10/main/pg_hba.conf , the configuration location may vary depending on the version installed, /etc/postgresql//main/pg_hba.conf
sample ansible recipe
---
- name : "Dump PostgreSQL database"
gather_facts: true
hosts: posgre_host
tasks:
- name: Dump existing PostgreSQL database
community.postgresql.postgresql_db:
name: demo
state: dump
target: /tmp/backup/backup.sql.gz
become: true
From
local all postgres peer
To
local all postgres trust
Here trust authentication method anyone connect to the server is authorized to access the database, since ansible is working based on ssh, it is safe to change.

So if I understood well you are on a remote machine, and maybe you should change /usr/local/pgsql/data/pg_hba.conf to allow remote connections 'host all all 0.0.0.0/0 md5' or another specific network address.

Related

Using ansible to create postgres user on aws vps ubuntu 22.04

I have a code like this:
- name: Create DB user
postgresql_user:
state: present
name: "{{db_user}}"
password: "{{db_pass}}"
become: true
become_user: postgres
- name: Create DB instance
postgresql_db:
state: present
name: "{{db_name}}"
owner: "{{db_user}}"
become: true
become_user: postgres
And got the error :
TASK [deploy/django-api/db : Create DB user] ***********************************
fatal: [aws-server]: FAILED! => {"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chmod: invalid mode: 'A+user:postgres:rx:allow'\nTry 'chmod --help' for more information.\n}). For information on working around this, see https://docs.ansible.com/ansible-core/2.13/user_guide/become.html#risks-of-becoming-an-unprivileged-user"}
By the way the installation of postgres is done successfully, also i test to create postgres user directly on the server and it's created, using the command
sudo -u postgres createuser --interactive
If anyone can help me with thanks.
EDIT : i fixed it by installing ACL on the remote server :
sudo apt-get install acl

Peer authentication failed for user "db_user"

I am trying to set-up automatic backup for postgres db on a local headless server on Debian. I have a script:
#!/bin/bash
export PGPASSFILE='/home/mtn/.pgpass'
pg_dumpall -U db_user --verbose 2>/var/log/postgresql/pgdump.log | gzip > /mnt/bulk-data/db_backup/db_bak.gz
Have a .pgpass file:
-rw------- 1 mtn mtn 47 Nov 13 10:14 .pgpass
with:
*:*:*:postgres:guest
*:*:*:db_user:guest
And a sudo crontab -e job:
20 0 * * * /home/mtn/backup.sh >/dev/null 2>&1
pg_hba:
local all postgres peer
When i try to run it i get:
pg_dumpall: error: could not connect to database "template1": FATAL: Peer authentication failed for user "db_user"
Where's the mistake?
PS Everything works if i change the script to run as root sudo -u postgres pg_dumpall.
UPDATE:
What worked for me in the end is adding this line to pg_ident.conf:
omicron root postgres
Then to pg_hba.conf before everything else:
local all all ident map=omicron
And changing script to run pg_dumpall as user postgres (only because db_user didn't have all necessary privilegies to dumpall).
In the absence of a user map via pg_ident.conf, only a linux user named "db_user" is allowed to log in as the database user "db_user". That is what peer authentication means. Your .pgpass doesn't matter, as peer authentication doesn't use passwords.
The one line from pg_hba you show also doesn't matter, because "postgres" != "db_user" so that line doesn't match. But clearly you have other lines as well which you haven't shown us. If you look in the server's log file you should find more details about the error, and which line of pg_hba was used.
There are lots of solutions. You could change your linux username to match the postgres username, or change the postgres username to match the linux username, or use pg_ident.conf to map between them, or change your pg_hba (the correct line of it!) to use md5 rather than peer.

How to set postgres password using ansible

Usually I do :
sudo -su postgres
psql
\password
\q
to change postgres password. Now I want to automate this step using ansible.
Ansible postgresql_user module will help to set/reset the database user password. Here is the sample
- name: pd reset database user
become: yes
become_method: sudo
become_user: postgres
postgresql_user:
db: test
name: test
password: ""
For Reference, here is ansible link: https://docs.ansible.com/ansible/latest/collections/community/postgresql/postgresql_user_module.html#ansible-collections-community-postgresql-postgresql-user-module

Ecto Postgres install error password authentication failed

I created a phoenix project from the hello example using digital ocean. I entered the username and password from the etc/motd.tail file. I keep getting the error message below. I am a beginner and for some reason I just cannot get ecto to install correctly.
** (Mix) The database for Hello.Repo couldn't be created, reason given: psql: FATAL: password authentication failed for user "elixir"
FATAL: password authentication failed for user "elixir"
You can use the following Postgress database credentials:
* User: elixir
* Pass: ***
install. Any help would be appreciated.
I get the same error using Ubuntu 14.04 and I corrected resetting the 'postgres' password:
$ sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
and restart postgres service:
sudo service postgresql restart
I assume this error is happening on the mix ecto.create task?
This happens because Ecto uses psql to create the database, however this is no longer the case in the upcoming Ecto 2.0.
The following GitHub issue shows the same issue https://github.com/elixir-lang/ecto/issues/1207
The relevant comment with the fix is https://github.com/elixir-lang/ecto/issues/1207#issuecomment-172570064:
My database config (pg_hba.conf) was apparently wrong.
For anyone else encountering this:
host all my_user 127.0.0.1/32 trust will not work
host all my_user localhost trust will work
Please check your pg_hba.conf (likely in /etc/postsgresql/9.x/pg_hba.conf).
We just need to create a new postgresql username and password according to the files inside config folder using this db method
$ sudo -u postgres createuser <username>
$ sudo -u postgres createdb <dbname>
$ sudo -u postgres psql
psql=# alter user <username> with encrypted password '<password>';
psql=# grant all privileges on database <dbname> to <username> ;
I needed to update the pg_hba.conf to make this work.
I am using Fedora, so get to /var/lib/pgsql/data
# "local" is for Unix domain socket connections only
local all postgres peer
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 ident
Then I created an elixir user in postgres with databse creation capabilities and configured it in dev.exs (user/password/database)

fe_sendauth: no password supplied

database.yml:
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
development:
adapter: postgresql
encoding: utf8
database: sampleapp_dev #can be anything unique
#host: localhost
#username: 7stud
#password:
#adapter: sqlite3
#database: db/development.sqlite3
pool: 5
timeout: 5000
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: postgresql
encoding: utf8
database: sampleapp_test #can be anything unique
#host: localhost
#username: 7stud
#password:
#adapter: sqlite3
#database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: postgresql
database: sampleapp_prod #can be anything unique
#host: localhost
#username: 7stud
#password:
#adapter: sqlite3
#database: db/production.sqlite3
pool: 5
timeout: 5000
pg_hba.conf:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication postgres md5
#host replication postgres 127.0.0.1/32 md5
#host replication postgres ::1/128 md5
I changed the METHOD in the first three lines from md5 to trust, but I still get the error.
And no matter what combinations of things I try in database.yml, when I do:
~/rails_projects/sample_app4_0$ bundle exec rake db:create:all
I always get the error:
fe_sendauth: no password supplied
I followed this tutorial to get things setup:
https://pragtob.wordpress.com/2012/09/12/setting-up-postgresql-for-ruby-on-rails-on-linux
Mac OSX 10.6.8
PostgreSQL 9.2.4 installed via enterpriseDB installer
Install dir: /Library/PostgreSQL/9.2
After making changes to the pg_hba.conf or postgresql.conf files, the cluster needs to be reloaded to pick up the changes.
From the command line: pg_ctl reload
From within a db (as superuser): select pg_reload_conf();
From PGAdmin: right-click db name, select "Reload Configuration"
Note: the reload is not sufficient for changes like enabling archiving, changing shared_buffers, etc -- those require a cluster restart.
I just put --password flag into my command and after hitting Enter it asked me for password, which I supplied.
psql -U postgres --password
Password:<Enter your password>
Then this will appear. postgres=#
This worked for me
This occurs if the password for the database is not given.
default="postgres://postgres:password#127.0.0.1:5432/DBname"
I also had same issue. But my application was running on docker daemon. I changed those environment in docker-compose.yml file. And also changed in database.yml file. These changes resolved my issue.
DATABASE_HOST= db
POSTGRES_PASSWORD= password
What worked for me was making sure that I had these four lines after development, test, and production in the database.yml file. I leave username and password blank here for security purposes, but fill these out in the actual application
username:
password:
host: localhost
port: 5432