Postgresql: Criando scripts de execução psql com senha

274

Como posso chamar o psql para que ele não solicite uma senha ?

Isto é o que eu tenho:

psql -Umyuser < myscript.sql

No entanto, não consegui encontrar o argumento que passa a senha e, portanto, o psql sempre solicita isso.

Axel Fontaine
fonte
4
Acabei indo para a variável de ambiente PGPASSWORD. Isso encaixou perfeitamente no meu caso. Simples e independente no script.
Axel Fontaine
Acabei de encontrar este postgresguide.com/utilities/psql.html
D_C

Respostas:

315

Existem várias maneiras de autenticar no PostgreSQL. Você pode investigar alternativas à autenticação de senha em https://www.postgresql.org/docs/current/static/client-authentication.html .

Para responder à sua pergunta, existem algumas maneiras de fornecer uma senha para autenticação baseada em senha. A maneira óbvia é através do prompt de senha. Em vez disso, você pode fornecer a senha em um arquivo pgpass ou através da PGPASSWORDvariável de ambiente. Veja estes:

Não há opção para fornecer a senha como um argumento de linha de comando, porque essas informações geralmente estão disponíveis para todos os usuários e, portanto, inseguras. No entanto, em ambientes Linux / Unix, você pode fornecer uma variável de ambiente para um único comando como este:

PGPASSWORD=yourpass psql ...
Reece
fonte
11
Eu acho que PGPASSWORD está obsoleto, mas ainda funciona, btw. Apenas FYI
Scott Marlowe
35
Sim, está obsoleto (e observado em um dos links). Desde que surgiu, provavelmente também vale a pena notar que a depreciação é muito contestada, porque é extremamente útil para muitas pessoas e ainda pode ser usada em algumas circunstâncias sem sérias preocupações de segurança. Parece-me que não é pior do que armazenar .pgpass em um sistema de arquivos NFS, por exemplo. Eu uso PGPASSWORD rotineiramente.
Reece
1
a ideia de que as informações de linha de comando é "disponível para todos os usuários" se baseia em pressupostos antiquados sobre sistemas multi-utilizador e não se aplica na maioria dos ambientes modernos onde os sistemas basta executar uma única aplicação e é tudo automatizado
Alex R
159
PGPASSWORD=[your password] psql -Umyuser < myscript.sql
Greg
fonte
1
isso funciona também em terraform. Você, meu amigo, é um salva-vidas
wildthing81
67

Você pode adicionar esta linha de comando no início do seu script:

set PGPASSWORD=[your password]
jbaylina
fonte
24
no meu comando caso conjunto não funcionou, mas export PGPASSWORD=[password]fez trabalho
Can Kavaklıoğlu
não funciona no shell script. Estou usando #!/bin/sh set PGPASSWORD = postgres psql -h 192.168.3.200 -U postgres incx_um << EOF DELETE FROM usrmgt.user_one_time_codes WHERE time < NOW() - INTERVAL '30 minute' EOF
Govind Gupta
2
Tente não usar espaços, por exemplo. PGPASSWORD=password.
Ariejan 29/11
48

Se você pretende ter vários hosts / conexões com o banco de dados, o arquivo ~ / .pgpass é o caminho a seguir.

Passos:

  1. Crie o arquivo usando vim ~/.pgpassou similar. Insira suas informações no seguinte formato: hostname:port:database:username:passwordNão adicione aspas em torno dos valores do seu campo. Você também pode usar * como um curinga para seus campos de porta / banco de dados.
  2. Você deve chmod 0600 ~/.pgpass, para que não seja ignorado silenciosamente pelo psql.
  3. Crie um alias no seu perfil do bash que execute seu comando psql para você. Por exemplo: alias postygresy='psql --host hostname database_name -U username'Os valores devem corresponder aos que você inseriu no arquivo ~ / .pgpass.
  4. Crie seu perfil do bash com . ~/.bashrcou similar.
  5. Digite seu alias na linha de comando.

Observe que se você tiver um conjunto de variáveis ​​PGPASSWORD = '' de exportação, ele terá precedência sobre o arquivo.

tandy
fonte
1
Você deve fazer um chmod 600no arquivo, caso contrário psqlo ignorará silenciosamente (de acordo com os documentos).
19419 RichVel
33

Essa pode ser uma pergunta antiga, mas há um método alternativo que você pode usar e que ninguém mencionou. É possível especificar a senha diretamente no URI da conexão. A documentação pode ser encontrada aqui , ou aqui .

Você pode fornecer seu nome de usuário e senha diretamente no URI de conexão fornecido para psql:

# postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
psql postgresql://username:password@localhost:5432/mydb
ajxs
fonte
2
Postrgres 9.3 ignora variável de ambientePGPASSWORD
david.perez 27/03
14

Se você está tendo problemas no Windows como eu (estou usando o Windows 7 de 64 bits) e set PGPASSWORD=[Password]não funcionou.

Então, como Kavaklioglu disse em um dos comentários,

export PGPASSWORD=[password]

Você precisará salvá-lo na parte superior do arquivo ou antes de qualquer uso, para que seja definido antes de ser chamado.

Certamente funciona no Windows :)

Jamie Hutber
fonte
1
export PGPASSWORD=[password]não funciona para mim usando a linha de comando (cmd.exe). Tem certeza de que não estava usando o cygwin ou algo semelhante?
Devin Snyder
Só funciona com cl, você adicionou ao arquivo, certo? Agora, basta digitar no comando?
21714 Jamie Hutber #
tudo bem em usá-lo no ambiente linux / mac, para o windows, acho que você deve encontrar uma maneira de exportar essa variável de ambiente.
Pengfei.X
Então adicione uma senha global ... Isso é uma idéia interessante, bem
Jamie Hutber
7

Dadas as preocupações de segurança sobre o uso da variável de ambiente PGPASSWORD, acho que a melhor solução geral é a seguinte:

  1. Escreva seu próprio arquivo pgpass temporário com a senha que deseja usar.
  2. Use a variável de ambiente PGPASSFILE para dizer ao psql para usar esse arquivo.
  3. Remova o arquivo pgpass temporário

Há alguns pontos de nota aqui. A Etapa 1 existe para evitar a sujeira no arquivo ~ / .pgpass do usuário que possa existir. Você também deve garantir que o arquivo tenha permissões 0600 ou menos.

Alguns sugeriram aproveitar o bash para atalho da seguinte maneira:

PGPASSFILE=<(echo myserver:5432:mydb:jdoe:password) psql -h myserver -U jdoe -p 5432 mydb

Isso usa a sintaxe <() para evitar a necessidade de gravar os dados em um arquivo real. Mas não funciona porque o psql verifica qual arquivo está sendo usado e gera um erro como este:

WARNING: password file "/dev/fd/63" is not a plain file
mightybyte
fonte
Um exemplo de trabalho dessa abordagem aparece em stackoverflow.com/a/40614592/3696363 - outra resposta a esta pergunta.
Eliyahu Skoczylas
Embora esse usuário não tenha realmente pedido a mesma coisa que estou procurando, diria que a abordagem não corresponde. Ao usar a sintaxe PGPASSFILE = <(qualquer que seja), é possível descriptografar um arquivo e apenas tê-lo presente no descritor de arquivo criado. Ao escrever um arquivo temporário, você não está resolvendo fundamentalmente o problema de ter um arquivo em disco com credenciais. Não é divertido lidar com regras arbitrárias da indústria como essa, mas é algo com o qual muitas pessoas lidam.
Desidero 18/10
7

Isso pode ser feito simplesmente usando PGPASSWORD. Estou usando o psql 9.5.10. No seu caso, a solução seria

PGPASSWORD=password psql -U myuser < myscript.sql

pyAddict
fonte
5

Com base na resposta de mightybyte para aqueles que não se sentem confortáveis ​​com o script * nix shell, aqui está um script de trabalho:

#!/bin/sh
PGPASSFILE=/tmp/pgpasswd$$
touch $PGPASSFILE
chmod 600 $PGPASSFILE
echo "myserver:5432:mydb:jdoe:password" > $PGPASSFILE
export PGPASSFILE
psql mydb
rm $PGPASSFILE

O cifrão duplo ( $$) na /tmp/pgpasswd$$linha 2 anexa o número do ID do processo ao nome do arquivo, para que este script possa ser executado mais de uma vez, mesmo simultaneamente, sem efeitos colaterais.

Observe o uso do chmodcomando na linha 4 - assim como o erro " não é um arquivo simples " descrito por mightybyte , também há um erro " permissões " se isso não for feito.

Na linha 7, você não precisará usar o sinalizador -hmyserver , -pmyport ou -Ujdoe se usar os padrões ( localhost : 5432 ) e tiver apenas um usuário de banco de dados. Para vários usuários, (mas a conexão padrão) altere essa linha para

psql mydb jdoe

Não esqueça de tornar o script executável com

chmod +x runpsql( ou o que você chamou de arquivo de script )

ATUALIZAR:

Eu segui o conselho de RichVel e tornei o arquivo ilegível antes de colocar a senha nele. Isso fecha um pequeno furo de segurança. Obrigado!

Eliyahu Skoczylas
fonte
4
Você pode usar mktemppara criar um arquivo temporário em vez de criar seu próprio esquema de nomenclatura. Ele cria um novo arquivo temporário (chamado algo como /tmp/tmp.ITXUNYgiNhno Linux e /var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4no MacOS X) e imprime seu nome em stdout.
Ivan Kolmychek
1
Problema de segurança É melhor fazer chmod 600depois de criar o arquivo, mas antes de gravar a senha nele. Conforme escrito, um script mal-intencionado no servidor poderia tentar continuamente ler arquivos desse formato e, às vezes, conseguiria obter a senha. Além disso, se esse script for interrompido por algum motivo, o arquivo será deixado no disco - a gravação de um trapmanipulador de shell resolveria isso. Dado que não é trivial escrever um script seguro como esse, recomendo o uso export PGPASSWORD.
RichVel 18/02/19
Obrigado, @RichVel por apontar essa pequena falha de segurança. Toque em criar e tornar o arquivo privado antes de inserir a senha. É uma melhoria definitiva. Esse tipo de solução é necessário porque PGPASSWORDfoi descontinuado na 9.3.
Eliyahu Skoczylas 11/04/19
Alguns dos docs dizer que é obsoleto, mas como mencionado em um comentário no este Q & A , a depreciação é contestada e ainda funciona como de Postgres 10.6
RichVel
5

Uma alternativa ao uso da PGPASSWORDvariável de ambiente é usar a conninfostring de acordo com a documentação

Uma maneira alternativa de especificar parâmetros de conexão está em uma string conninfo ou em um URI, que é usado em vez de um nome de banco de dados. Esse mecanismo oferece controle muito amplo sobre a conexão.

$ psql "host=<server> port=5432 dbname=<db> user=<user> password=<password>"

postgres=>
ubi
fonte
-1

Acho que o psql mostra o prompt de senha, mesmo que você defina a variável PGPASSWORD, mas você pode especificar a opção -w para o psql omitir o prompt de senha.

Mark Lokshin
fonte
-6

Use -w no comando: psql -h localhost -p 5432 -U user -w

vjOnstack
fonte