繁体   English   中英

如何使用 Python 通过 SSL 连接到远程 PostgreSQL 数据库

[英]How to connect to a remote PostgreSQL database through SSL with Python

我想通过 Python 连接到远程 PostgreSQL 数据库来做一些基本的数据分析。 该数据库需要 SSL (verify-ca),以及三个文件(我有):

  • 服务器根证书文件
  • 客户证书文件
  • 客户端密钥文件

我一直无法找到描述如何与 Python 建立这种联系的教程。 任何帮助表示赞赏。

使用psycopg2模块。

您需要在连接字符串中使用 ssl 选项,或者将它们添加为关键字参数:

import psycopg2

conn = psycopg2.connect(dbname='yourdb', user='dbuser', password='abcd1234', host='server', port='5432', sslmode='require')

在这种情况下, sslmode指定 SSL 是必需的。

要执行服务器证书验证,您可以将sslmode设置为verify-fullverify-ca 您需要在sslrootcert中提供服务器证书的路径。 sslcertsslkey值分别设置为您的客户端证书和密钥。

它在 PostgreSQL Connection Strings 文档(另见 Parameter Key Words)和SSL Support中有详细解释。

您也可以使用带有 paramiko 和 sshtunnel 的 ssh 隧道:

import psycopg2
import paramiko
from sshtunnel import SSHTunnelForwarder

mypkey = paramiko.RSAKey.from_private_key_file('/path/to/private/key')

tunnel =  SSHTunnelForwarder(
        (host_ip, 22),
        ssh_username=username,
        ssh_pkey=mypkey,
        remote_bind_address=('localhost', psql_port))

tunnel.start()
conn = psycopg2.connect(dbname='gisdata', user=psql_username, password=psql_password, host='127.0.0.1', port=tunnel.local_bind_port)

添加这个是为了完整性,因为我在 SO 的其他任何地方都找不到它。 就像@mhawke 所说,您可以使用psycopg2 ,但您也可以使用任何其他允许您手动指定数据库 postgresql URI 的 Python 数据库模块(ORM 等)( postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...] )因为psycopg2.connect用来强制 ssl 连接的sslmode="require"参数只是postgresql:// URI 的一部分你用来连接到你的数据库(见33.1.2. 参数关键字)。 因此,如果您想使用sqlalchemy或其他 ORM 而不是 vanilla psycopg2 ,您可以将所需的sslmode到数据库 URI 的末尾并以这种方式连接。

import sqlalchemy

DATABASE_URI = "postgresql://postgres:postgres@localhost:5432/dbname"
# sqlalchemy 1.4+ uses postgresql:// instead of postgres://
ssl_mode = "?sslmode=require"
DATABASE_URI += ssl_mode

engine = sqlalchemy.create_engine(URI)
Session = sqlalchemy.orm.sessionmaker(bind=engine)

关于 SSL 支持的 postgres 文档中有一个漂亮的数字(表 33.1 )分解了您可以提供的不同选项。 如果您想使用任何需要您指定特定证书路径的更高级的选项,您可以使用格式字符串将其放入。

如果需要使用 psycopg2 使用 SSL 证书连接到 PostgresSQL 数据库,则需要将证书 SSL 证书放在 python 程序的子目录中,然后可以在连接字符串中引用证书。 我相信您也可以设置环境变量,但在我的示例中,我的 SSL 证书将位于子目录中。

我的 python 脚本位于一个目录中,如下所示:

/Users/myusername/Desktop/MyCoolPythonProgram/test_database_connection.py

我的 SSL 证书位于如下目录中:

/Users/myusername/Desktop/MyCoolPythonProgram/database/ssl_certificate/database/ssl_certificate/ca-certificate.crt

我的 HOSTNAME 是来自 DigitalOcean 的 URL,但您的可能是 IP 地址。

这就是我的 test_database_connection.py 脚本的样子:

import psycopg2
import os

POSTGRES_DATABASE_HOST_ADDRESS = "your-database-name-do-user-12345678-0.b.db.ondigitalocean.com"
POSTGRES_DATABASE_NAME = "defaultdb"
POSTGRES_USERNAME = "doadmin"
POSTGRES_PASSWORD = "$uperD00P3Rp@$$W0RDg0E$here"
# HOW TO (Relative Path Python): https://stackoverflow.com/questions/918154/relative-paths-in-python
path_to_current_directory = os.path.dirname(__file__)
relative_path_to_ssl_cert = 'database/ssl_certificate/ca-certificate.crt'
SSL_ROOT_CERT = os.path.join(path_to_current_directory , relative_path_to_ssl_cert )
POSTGRES_CONNECTION_PORT = "1234" # Set this to the correct port! Mine is provided by DigitalOcean and it's NOT 1234

db_info = "host='%s' dbname='%s' user='%s' password='%s' sslmode='require' sslrootcert='%s' port='%s'" % (POSTGRES_DATABASE_HOST_ADDRESS, POSTGRES_DATABASE_NAME, POSTGRES_USERNAME, POSTGRES_PASSWORD, SSL_ROOT_CERT, POSTGRES_CONNECTION_PORT)
postgres_connection = psycopg2.connect(db_info)
with postgres_connection:
    with postgres_connection.cursor() as postgres_cursor:
        sql = "SELECT * FROM your_table;"
        postgres_cursor.execute(sql)
        results = postgres_cursor.fetchall()
        for row in results:
            print("row in result")

        print("Connection Success!")

        # Close Database Cursor/Connection
        postgres_cursor.close()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM