Postgresql: การดำเนินการสคริปต์ psql ด้วยรหัสผ่าน


274

ฉันจะเรียกpsqlเพื่อที่จะไม่ให้ใส่รหัสผ่านได้อย่างไร

นี่คือสิ่งที่ฉันมี:

psql -Umyuser < myscript.sql

อย่างไรก็ตามฉันไม่สามารถหาข้อโต้แย้งที่ส่งผ่านรหัสผ่านได้ดังนั้น psql จะแจ้งให้เสมอ


4
ฉันลงเอยสำหรับตัวแปรสภาพแวดล้อม PGPASSWORD นี่เป็นการติดตั้ง usecase ของฉันอย่างสมบูรณ์แบบ เรียบง่ายและมีอยู่ในสคริปต์
Axel Fontaine


คำตอบ:


315

มีหลายวิธีในการตรวจสอบสิทธิ์กับ PostgreSQL คุณอาจต้องการที่จะตรวจสอบทางเลือกในการตรวจสอบรหัสผ่านที่https://www.postgresql.org/docs/current/static/client-authentication.html

เพื่อตอบคำถามของคุณมีวิธีการให้รหัสผ่านสำหรับการตรวจสอบตามรหัสผ่าน วิธีที่ชัดเจนคือผ่านทางพรอมต์รหัสผ่าน แทนที่จะเป็นเช่นนั้นคุณสามารถระบุรหัสผ่านในไฟล์ pgpass หรือผ่านPGPASSWORDตัวแปรสภาพแวดล้อม ดูเหล่านี้:

ไม่มีตัวเลือกในการให้รหัสผ่านเป็นอาร์กิวเมนต์บรรทัดคำสั่งเนื่องจากข้อมูลนั้นมักจะมีให้กับผู้ใช้ทั้งหมดและดังนั้นจึงไม่ปลอดภัย อย่างไรก็ตามในสภาพแวดล้อม Linux / Unix คุณสามารถระบุตัวแปรสภาพแวดล้อมสำหรับคำสั่งเดียวดังนี้:

PGPASSWORD=yourpass psql ...

11
ฉันคิดว่า PGPASSWORD เลิกใช้แล้ว แต่ยังใช้งานได้ btw เพียงแค่ FYI
Scott Marlowe

35
ใช่มันเลิกใช้แล้ว (และบันทึกไว้ในลิงก์ใดลิงก์หนึ่ง) เนื่องจากมันเกิดขึ้นมันก็อาจจะคุ้มค่าที่จะสังเกตว่าการคัดค้านนั้นมีการโต้แย้งกันอย่างถึงพริกถึงขิงเพราะมันมีประโยชน์อย่างยิ่งสำหรับหลาย ๆ คน แต่ยังสามารถใช้ได้ในบางสถานการณ์โดยไม่ต้องกังวลเรื่องความปลอดภัย สำหรับฉันแล้วดูเหมือนว่ามันไม่ได้เลวร้ายไปกว่าการจัดเก็บ. RPG ผ่านระบบไฟล์ NFS เช่น ฉันใช้ PGPASSWORD เป็นประจำ
Reece

1
ความคิดที่ว่าข้อมูลบรรทัดคำสั่งคือ "ใช้ได้กับผู้ใช้ทุกคน" ตั้งอยู่บนสมมติฐานโบราณเกี่ยวกับระบบที่ผู้ใช้หลายคนและไม่ได้นำไปใช้ในสภาพแวดล้อมที่ทันสมัยที่สุดที่มีระบบทำงานเพียงโปรแกรมเดียวและมันทั้งหมดโดยอัตโนมัติ
อเล็กซ์ R


67

คุณสามารถเพิ่มบรรทัดคำสั่งนี้ที่จุดเริ่มต้นของสคริปต์ของคุณ:

set PGPASSWORD=[your password]

24
ในคำสั่ง set ของฉันไม่ทำงาน แต่export PGPASSWORD=[password]ทำงานได้
Can Kavaklıoğlu

มันไม่ทำงานในเชลล์สคริปต์ ฉันกำลังใช้อยู่ #!/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
วินด์

2
พยายามอย่าใช้ช่องว่างเช่น PGPASSWORD=password.
Ariejan

48

หากคุณต้องการเชื่อมต่อหลายโฮสต์ / ฐานข้อมูลไฟล์ ~ / .pgpassเป็นวิธีที่จะไป

ขั้นตอน:

  1. สร้างไฟล์โดยใช้vim ~/.pgpassหรือคล้ายกัน ป้อนข้อมูลของคุณในรูปแบบต่อไปนี้: hostname:port:database:username:passwordอย่าเพิ่มอัญประกาศสตริงรอบค่าเขตข้อมูลของคุณ คุณยังสามารถใช้ * เป็นอักขระตัวแทนสำหรับเขตข้อมูลพอร์ต / ฐานข้อมูลของคุณ
  2. คุณต้องchmod 0600 ~/.pgpassเพื่อไม่ให้ถูกละเว้นโดย psql
  3. สร้างนามแฝงในโปรไฟล์ bash ที่รันคำสั่ง psql ของคุณ ตัวอย่างเช่น: alias postygresy='psql --host hostname database_name -U username'ค่าควรตรงกับค่าที่คุณป้อนเข้ากับไฟล์ ~ / .pgpass
  4. แหล่งที่มาของโปรไฟล์ทุบตีของคุณด้วย. ~/.bashrcหรือคล้ายกัน
  5. พิมพ์นามแฝงของคุณจากบรรทัดคำสั่ง

โปรดทราบว่าถ้าคุณมีชุดตัวแปรส่งออก PGPASSWORD = '' มันจะมีความสำคัญมากกว่าไฟล์


1
คุณต้องทำchmod 600ไฟล์มิฉะนั้นpsqlจะไม่สนใจไฟล์นั้น (อ้างอิงจากเอกสาร)
RichVel

33

นี่อาจเป็นคำถามเก่า แต่มีวิธีอื่นที่คุณสามารถใช้ที่ไม่มีใครพูดถึง เป็นไปได้ที่จะระบุรหัสผ่านโดยตรงใน URI การเชื่อมต่อ เอกสารที่สามารถพบได้ที่นี่ผลัดที่นี่

คุณสามารถระบุชื่อผู้ใช้และรหัสผ่านของคุณโดยตรงใน URI การเชื่อมต่อที่ให้ไว้กับpsql:

# postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
psql postgresql://username:password@localhost:5432/mydb

2
Postrgres 9.3 ละเว้นตัวแปรสภาพแวดล้อมPGPASSWORD
david.perez

14

หากคุณมีปัญหาบน windows เช่นฉัน (ฉันใช้ Windows 7 64 บิต) และset PGPASSWORD=[Password]ไม่ทำงาน

จากนั้นดังที่ Kavaklioglu พูดในความคิดเห็นอย่างใดอย่างหนึ่ง

export PGPASSWORD=[password]

คุณจะต้องบันทึกสิ่งนี้ไว้ที่ด้านบนของไฟล์หรือก่อนการใช้งานใด ๆ ดังนั้นจึงตั้งค่าก่อนที่จะถูกเรียก

ทำงานบน windows ได้แน่นอน :)


1
export PGPASSWORD=[password]ไม่ทำงานสำหรับฉันโดยใช้บรรทัดคำสั่ง (cmd.exe) เลย คุณแน่ใจหรือว่าไม่ได้ใช้ cygwin หรืออะไรทำนองนี้?
Devin Snyder

ใช้งานได้กับ cl คุณเพิ่มไปยังไฟล์ใช่มั้ย ตอนนี้เพิ่งพิมพ์ลงในคำสั่ง?
Jamie Hutber

มันโอเคที่จะใช้มันในสภาพแวดล้อม linux / mac สำหรับ windows ฉันคิดว่าคุณควรหาวิธีที่จะส่งออกตัวแปรสภาพแวดล้อมนี้
Pengfei.X

ดังนั้นเพิ่มรหัสผ่านส่วนกลาง ... นั่นเป็นแนวคิดที่น่าสนใจเช่นกัน
Jamie Hutber


7

จากความกังวลด้านความปลอดภัยเกี่ยวกับการใช้ตัวแปรสภาพแวดล้อม PGPASSWORD ฉันคิดว่าโซลูชันโดยรวมที่ดีที่สุดมีดังนี้:

  1. เขียนไฟล์ pgpass ชั่วคราวของคุณเองด้วยรหัสผ่านที่คุณต้องการใช้
  2. ใช้ตัวแปรสภาพแวดล้อม PGPASSFILE เพื่อบอก psql ให้ใช้ไฟล์นั้น
  3. ลบไฟล์ pgpass ชั่วคราว

มีโน้ตอยู่สองสามจุดที่นี่ ขั้นตอนที่ 1 มีไว้เพื่อหลีกเลี่ยงการลอกคราบด้วยไฟล์ ~ / .pgpass ของผู้ใช้ที่อาจมีอยู่ คุณต้องตรวจสอบให้แน่ใจว่าไฟล์มีสิทธิ์ 0600 หรือน้อยกว่า

บางคนแนะนำให้ใช้ประโยชน์จากการทุบตีเพื่อทางลัดดังนี้:

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

นี่ใช้ไวยากรณ์ <() เพื่อหลีกเลี่ยงการต้องเขียนข้อมูลลงในไฟล์จริง แต่มันไม่ทำงานเพราะ psql ตรวจสอบไฟล์ที่ใช้อยู่และจะเกิดข้อผิดพลาดเช่นนี้:

WARNING: password file "/dev/fd/63" is not a plain file

ตัวอย่างการทำงานของวิธีนี้ปรากฏในstackoverflow.com/a/40614592/3696363 - อีกคำตอบสำหรับคำถามนี้
Eliyahu Skoczylas

แม้ว่าผู้ใช้รายนี้จะไม่ขอสิ่งเดียวกับที่ฉันกำลังมองหา แต่ฉันจะบอกว่าวิธีการไม่ตรงกัน เมื่อใช้ไวยากรณ์ PGPASSFILE = <(อะไรก็ตาม) คุณสามารถทำสิ่งต่าง ๆ เช่นถอดรหัสไฟล์และมีเพียงไฟล์นั้นอยู่ในไฟล์ descriptor ที่สร้างขึ้น โดยการเขียนไฟล์ temp คุณจะไม่ได้แก้ปัญหาพื้นฐานของการมีไฟล์บนดิสก์ที่มีหนังสือรับรอง มันไม่ใช่เรื่องสนุกที่จะจัดการกับกฎเกณฑ์อุตสาหกรรมโดยพลการ แต่มันเป็นสิ่งที่หลายคนจัดการ
Desidero

7

สามารถทำได้ง่ายๆโดยใช้ PGPASSWORD ฉันใช้ psql 9.5.10 ในกรณีของคุณการแก้ปัญหาจะเป็น

PGPASSWORD=password psql -U myuser < myscript.sql


5

สร้างจากคำตอบอันยิ่งใหญ่ของผู้ที่ไม่พอใจกับการเขียนสคริปต์* nix shell นี่เป็นสคริปต์ที่ใช้งานได้:

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

เครื่องหมายดอลลาร์สองตัว ( $$) ใน/tmp/pgpasswd$$บรรทัด 2 ต่อท้ายหมายเลข ID กระบวนการต่อท้ายชื่อไฟล์เพื่อให้สคริปต์นี้สามารถทำงานได้มากกว่าหนึ่งครั้งแม้ในเวลาเดียวกันโดยไม่มีผลข้างเคียง

สังเกตการใช้chmodคำสั่งที่บรรทัด 4 - เช่นเดียวกับข้อผิดพลาด" ไม่ใช่ไฟล์ธรรมดา " ที่อาจอธิบายได้โดยมีข้อผิดพลาด " สิทธิ์ " หากยังไม่เสร็จ

ที่บรรทัดที่ 7 คุณจะไม่ต้องใช้-hmyserver , -pmyportหรือ-Ujdoe flag หากคุณใช้ค่าเริ่มต้น ( localhost : 5432 ) และมีผู้ใช้ฐานข้อมูลเพียงคนเดียว สำหรับผู้ใช้หลายคน (แต่การเชื่อมต่อเริ่มต้น) เปลี่ยนบรรทัดนั้นเป็น

psql mydb jdoe

อย่าลืมที่จะทำให้สคริปต์ใช้งานได้ด้วย

chmod +x runpsql( หรือสิ่งที่คุณเรียกว่าไฟล์สคริปต์ )

UPDATE:

ฉันใช้คำแนะนำของRichVelและทำให้ไฟล์อ่านไม่ได้ก่อนที่จะใส่รหัสผ่านลงไป ที่ปิดรูโหว่เล็กน้อย ขอบคุณ!


4
คุณสามารถใช้mktempเพื่อสร้างไฟล์ชั่วคราวแทนที่จะมากับรูปแบบการตั้งชื่อของคุณเอง มันสร้างไฟล์ temp ใหม่ (ตั้งชื่อบางอย่างเช่น/tmp/tmp.ITXUNYgiNhใน Linux และ/var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4บน MacOS X) และพิมพ์ชื่อเป็น stdout
Ivan Kolmychek

1
ปัญหาด้านความปลอดภัยทางที่ดีควรทำchmod 600หลังจากสร้างไฟล์ แต่ก่อนที่จะเขียนรหัสผ่านลงไป ตามที่เขียนไว้สคริปต์ที่เป็นอันตรายบนเซิร์ฟเวอร์อาจพยายามอ่านไฟล์ในรูปแบบนี้อย่างต่อเนื่องและบางครั้งอาจประสบความสำเร็จในการรับรหัสผ่าน นอกจากนี้หากสคริปต์นี้ถูกขัดจังหวะด้วยเหตุผลบางอย่างไฟล์จะถูกทิ้งไว้บนดิสก์ - การเขียนเชลล์trapตัวจัดการจะแก้ปัญหานี้ เนื่องจากมันไม่สำคัญที่จะเขียนสคริปต์ที่ปลอดภัยเช่นนี้ฉันแนะนำให้ใช้export PGPASSWORDแทน
RichVel

ขอบคุณ @RichVel ที่ชี้ให้เห็นช่องโหว่เล็ก ๆ แตะที่การสร้างและทำให้ไฟล์เป็นส่วนตัวก่อนที่จะใส่รหัสผ่านในการปรับปรุงอย่างแน่นอน ต้องการโซลูชันชนิดนี้เนื่องจากPGPASSWORDเลิกใช้แล้วใน 9.3
Eliyahu Skoczylas

เอกสารบางฉบับบอกว่ามันเลิกใช้แล้ว แต่ดังที่ได้กล่าวไว้ในความคิดเห็นในคำถาม & คำตอบนี้การคัดค้านนั้นยังคงมีอยู่และยังคงใช้ได้เหมือน Postgres 10.6
RichVel

5

อีกทางเลือกหนึ่งในการใช้PGPASSWORDตัวแปรสภาพแวดล้อมคือการใช้conninfoสตริงตามเอกสารประกอบ

อีกวิธีหนึ่งในการระบุพารามิเตอร์การเชื่อมต่ออยู่ในสตริง conninfo หรือ URI ซึ่งใช้แทนชื่อฐานข้อมูล กลไกนี้ให้คุณควบคุมการเชื่อมต่อได้อย่างกว้างมาก

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

postgres=>


1

8 ปีต่อมา ...

สำหรับ mac ของฉันฉันต้องใส่บรรทัดลงในไฟล์ ~/.pgpassเช่น:

<IP>:<PORT>:<dbname>:<user>:<password>

ดูเพิ่มเติมที่:
https://www.postgresql.org/docs/current/libpq-pgpass.html
https://wiki.postgresql.org/wiki/Pgpass


อย่าใช้ -W สำหรับ psql หากคุณใช้ .pgpass พารามิเตอร์นี้ยกเลิกการใช้งาน. pass ผ่าน
avvensis

-1

ฉันพบว่า psql แสดงพรอมต์รหัสผ่านแม้ว่าคุณจะกำหนดตัวแปร PGPASSWORD แต่คุณสามารถระบุตัวเลือก -w สำหรับ psql เพื่อไม่ให้ใส่รหัสผ่านได้


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.