I'm trying to understand how role passwords are supposed to operate in Postgres.
https://www.postgresql.org/docs/current/static/sql-createrole.html says for ENCRYPTED / UNENCRYPTED
If the presented password string is already in MD5-encrypted format, then it is stored encrypted as-is,
So my unencrypted password is: MyPassword .
The MD5 hash of "MyPassword" is 48503dfd58720bd5ff35c102065a52d7
If I do
-- See https://www.postgresql.org/docs/9.6/static/sql-alterrole.html
ALTER ROLE "MeOhMy"
LOGIN
PASSWORD '48503dfd58720bd5ff35c102065a52d7'
;
And then attempt to use "MyPassword" when doing
sudo -u postgres psql meohmy -h 127.0.0.1 -d meohmy_development
I, of course, first get prompted for my sudo password and then I get prompted by Postgres "Password for meohmy"
If I enter MyPassword I get
FATAL: password authentication failed for user "ralph#dos32.com"
If I enter, instead, 48503dfd58720bd5ff35c102065a52d7 then I can sign in.
What am I not understanding?
To create an md5 password for PostgreSQL, the formula is:
"md5" + md5(password + username)
Here are 3 ways you can create one, where the username is "admin" and the password is "password123"...
Linux:
# echo -n "md5"; echo -n "password123admin" | md5sum | awk '{print $1}'
md53f84a3c26198d9b94054ca7a3839366d
NOTE: The -n is critical to avoid including the newline character in your hash!
MacOS:
➜ echo -n "md5"; md5 -qs "password123admin"
md53f84a3c26198d9b94054ca7a3839366d
Python 2:
>>> import hashlib
>>> print("md5" + hashlib.md5("password123" + "admin").hexdigest())
md53f84a3c26198d9b94054ca7a3839366d
Python 3:
as above, but use binary strings
print("md5" + hashlib.md5(b"password123" + b"admin").hexdigest())
Postgresql hashed passwords have md5 prefix:
md548503dfd58720bd5ff35c102065a52d7
Using Postgres11 on GCP Cloud SQL. Gitlab version gitlab-ee 13.3.4 Omnibus install
# gitlab-ctl pg-password-md5 gitlab_user
Enter password:
Confirm password:
and
# echo -n <password for gitlab_user>gitlab_user | md5sum
are equivalent.
Note: My db user is gitlab_user
The answer provided by #zerkms is partially correct. It led me to the right answer.
The answer provided in Generating postgresql user password is the answer that works for me.
Related
I want to write a script that will check whether replication is on or not, so I wrote the command in a script:- PGPASSWORD='********' psql -U user_name -p 54032 -c "select * from pg_stat_replication" -d postgres
but I want to encrypt the password for security purposes so I did MD5 encryption and put the hash of it.
PGPASSWORD='a67a4e657061eac2036a88ec523dbbbb' psql -U user_name -p 54032 -c "select * from pg_stat_replication" -d postgres
It's not working Please help me.
There is no way to avoid having a clear text password somewhere, either on the command line or in the environment or in a password file.
If you want to authenticate without a clear text password anywhere, use certificate authentication with a client certificate.
I am trying to login to mongodb database using mongodb shell, and if the password contains any special characters like # or & , the authentication fails.
mongo mongo.cloud.com:8888/database -u username -p a7IF#WV^#66!
mongo mongo.cloud.com:8888/database -u username -p a7IF#WV^&66!
Note: I am using windows command prompt.
If your password contains special characters like #, &, | and other shell special characters, you need to quote it. Additionally, if your password contains a dollar sign, you need to use single quotes around the password to avoid variable interpolation by your shell.
mongo mongo.cloud.com:8888/database -u username -p "a7IF#WV^#66!"
or
mongo mongo.cloud.com:8888/database -u username -p '${password}a7IF#WV^#66!'
I am trying to automate database creation process with a shell script and one thing I've hit a road block with passing a password to psql.
Here is a bit of code from the shell script:
psql -U $DB_USER -h localhost -c"$DB_RECREATE_SQL"
How do I pass a password to psql in a non-interactive way?
Set the PGPASSWORD environment variable inside the script before calling psql
PGPASSWORD=pass1234 psql -U MyUsername myDatabaseName
For reference, see http://www.postgresql.org/docs/current/static/libpq-envars.html
Edit
Since Postgres 9.2 there is also the option to specify a connection string or URI that can contain the username and password. Syntax is:
$ psql postgresql://[user[:password]#][host][:port][,...][/dbname][?param1=value1&...]
Using that is a security risk because the password is visible in plain text when looking at the command line of a running process e.g. using ps (Linux), ProcessExplorer (Windows) or similar tools, by other users.
See also this question on Database Administrators
From the official documentation:
It is also convenient to have a ~/.pgpass file to avoid regularly having to type in passwords. See Section 30.13 for more information.
...
This file should contain lines of the following format:
hostname:port:database:username:password
The password field from the first line that matches the current connection parameters will be used.
in one line:
export PGPASSWORD='password'; psql -h 'server name' -U 'user name' -d 'base name' -c 'command'
with command a sql command such as "select * from schema.table"
or more readable:
export PGPASSWORD='password'
psql -h 'server name' -U 'user name' -d 'base name' \
-c 'command' (eg. "select * from schema.table")
I tend to prefer passing a URL to psql:
psql "postgresql://$DB_USER:$DB_PWD#$DB_SERVER/$DB_NAME"
This gives me the freedom to name my environment variables as I wish and avoids creating unnecessary files.
This requires libpq. The documentation can be found here.
On Windows:
Assign value to PGPASSWORD: C:\>set PGPASSWORD=pass
Run command: C:\>psql -d database -U user
Ready
Or in one line,
set PGPASSWORD=pass&& psql -d database -U user
Note the lack of space before the && !
This can be done by creating a .pgpass file in the home directory of the (Linux) User.
.pgpass file format:
<databaseip>:<port>:<databasename>:<dbusername>:<password>
You can also use wild card * in place of details.
Say I wanted to run tmp.sql without prompting for a password.
With the following code you can in *.sh file
echo "192.168.1.1:*:*:postgres:postgrespwd" > $HOME/.pgpass
echo "` chmod 0600 $HOME/.pgpass `"
echo " ` psql -h 192.168.1.1 -p 5432 -U postgres postgres -f tmp.sql `
An alternative to using the PGPASSWORD environment variable is to use the conninfo string according to the documentation:
An alternative way to specify connection parameters is in a conninfo
string or a URI, which is used instead of a database name. This
mechanism give you very wide control over the connection.
$ psql "host=<server> port=5432 dbname=<db> user=<user> password=<password>"
postgres=>
If its not too late to add most of the options in one answer:
There are a couple of options:
set it in the pgpass file. link
set an environment variable and get it from there:
export PGPASSWORD='password'
and then run your psql to login or even run the command from
there:
psql -h clustername -U username -d testdb
On windows you will have to use "set" :
set PGPASSWORD=pass and then login to the psql bash.
Pass it via URL & env variable:
psql "postgresql://$USER_NAME:$PASSWORD#$HOST_NAME/$DB_NAME"
Just to add more clarity.
You can assign the password to the PGPASSWORD variable.
So instead of the below which will require you to type the password:
psql --host=aurora-postgres.cluster-fgshdjdf.eu-west-1.rds.amazonaws.com --port=5432 --user=my_master_user --password --dbname=postgres
We will replace the --password flag with PGPASSWORD=QghyumjB3ZtCQkdf. So it will be:
PGPASSWORD=QghyumjB3ZtCQkdf psql --host=aurora-postgres.cluster-fgshdjdf.eu-west-1.rds.amazonaws.com --port=5432 --user=my_master_user --dbname=postgres
This way you will not be required to type the password.
Added content of pg_env.sh to my .bashrc:
cat /opt/PostgreSQL/10/pg_env.sh
#!/bin/sh
# The script sets environment variables helpful for PostgreSQL
export PATH=/opt/PostgreSQL/10/bin:$PATH
export PGDATA=/opt/PostgreSQL/10/data
export PGDATABASE=postgres
export PGUSER=postgres
export PGPORT=5433
export PGLOCALEDIR=/opt/PostgreSQL/10/share/locale
export MANPATH=$MANPATH:/opt/PostgreSQL/10/share/man
with addition of (as per user4653174 suggestion)
export PGPASSWORD='password'
psql postgresql://myawsumuser:myPassword#127.0.0.1:5432/myawsumdb
This PSQL statement in PowerShell:
.\psql --% -h localhost -p 5000 -U postgres -d mydatabase -c `
(SELECT * ...... do something);
Works - and does not prompt for a password.
.\psql.exe --help
States the -w switch is required for no password.
Why does this command work without a password? The database has a password.
The command does not work in the PSQL interactive shell without password authentication, only in PowerShell.
-w is not required for "no password" reread what it says, from my man psql
-w --no-password Never issue a password prompt. If the server requires password authentication and a password is not available by other means such as a .pgpass file, the connection attempt will fail. This option can be useful in batch jobs and scripts where no user is present to enter a password. Note that this option will remain set for the entire session, and so it affects uses of the meta-command \connect as well as the initial connection attempt.
-w is meant for when you're running psql scripts and input for a password is not possible, like in a headless session.
Why does this command work without a password? The database has a password.
Even if the database has a password, if your pg_hba.conf file has trust no password will be required. To debug this further we need to see your pg_hba.conf.
During the installation of my app, I want to create a PostgreSQL-Database and some tables and functions.
For that purpose I use PSQL.EXE that ships with PostgreSQL. I have 2 scripts. The first one creates the database and a corresponding user that has rights to execute scripts on that database. I want to execute the second script as this just created user. Unfortunately I can't find a way to pass the password for that user as a command line argument. Omitting the password leads to a stop of execution and a prompt for the user to enter the password, which I would like to avoid - since this is executed during installtion of my app.
Is there any way to pass the password as argument or is there any other command line tool I could use?
To explain the environment a bit further. I use WiX 3.5 setup as a "MSI-Builder".
You can either use a pgpass file as dbenhur answerd, or you can set the environment variable PGPASSWORD before calling psql:
SET PGPASSWORD=my_very_secret_password
psql somedb someuser
All supported environment variables are documented in the manual: http://www.postgresql.org/docs/current/static/libpq-envars.html
You can't supply password via cmdline arg (and don't want to as that's poor security practice).
You can provide a .pgpass file to support automatic script authentication. Here's the docs.
Better still, if you have access to create the db role then you already have all the access you need without having to carefully log in with a password. Have the second script operate under the same user as the first but include the following line to switch user:
set role my_new_user;
Where my_new_user is the name of the role you want to run it as.
If you only divided the scripts because of the different logins then with this they can go in the same file and just switch role mid way through.
Note:
On the off chance that you are not creating the DB and new role as a super user this may be a little more complex. If this is the case you will need to create the new role with:
create role my_new_role ... ADMIN my_role;
Where my_new_role is the role you're creating and my_role is your current user. Then when you're finished simply:
revoke my_new_role from my_role;
For completion, you can also use URI (doc link)
List dbs
psql "postgresql://username:password#localhost/postgres" -l
I also crafted this command to have only names (please tell me if you know a better way):
psql "postgresql://username:password#localhost/postgres" -l | awk -F '|' '{print $1}'| sed -e '/^\s*$/ d' -e '1,3d'|sed '$d'|awk '{print $1}'
You can also use unix socket to connect:
# ss -x -a |grep postgres|awk '{print $5}'
/var/run/postgresql/.s.PGSQL.5432
Note that the parent directory of the socket is used:
# sudo -u postgres psql -d "postgresql:///postgres?host=/var/run/postgresql/" -l
You can only do this if you have this line in your pg_hba.conf:
local all postgres ident
"ident" uses unix user for authent
dump a db
Here I added a different port number
pg_dump -Fc "postgresql://username:password#localhost:9001/${db}" > "backup_${db}.pgdump"
With dumpall you need a super user or role (with CREATE ROLE ... SUPERUSER). And it must have access to all DB. By default postgres can.
but in my case I couldn't use pg_dumpall with postgres because his password was removed by devs.
So I used:
sudo -u postgres pg_dumpall -d "postgresql:///?host=/var/run/postgresql/" > all.dump
tested version
# cat /opt/postgresql/PG_VERSION
9.6
hth