SQLAlchemy проверяет SSL соединение - PullRequest
2 голосов
/ 20 марта 2019

Я хотел бы проверить соединение SSL, которое устанавливает SQLAlchemy при использовании create_engine для соединения с базой данных PostgreSQL.Например, если у меня есть следующий код Python 3:

from sqlalchemy import create_engine

conn_string = "postgresql+psycopg2://myuser:******@someserver:5432/somedb"

conn_args = {
    "sslmode": "verify-full",
    "sslrootcert": "/etc/ssl/certs/ca-certificates.crt",
}

engine = create_engine(conn_string, connect_args=conn_args)

Я знаю, что могу напечатать содержимое engine.__dict__, но оно не содержит никакой информации о настройках SSL (версия TLS,набор шифров и т. д.), который он использует для подключения:

{
    '_echo': False,
    'dialect': <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f988a217978>,
    'dispatch': <sqlalchemy.event.base.ConnectionEventsDispatch object at 0x7f988938e788>,
    'engine': Engine(postgresql+psycopg2://myuser:******@someserver:5432/somedb),
    'logger': <Logger sqlalchemy.engine.base.Engine (DEBUG)>,
    'pool': <sqlalchemy.pool.impl.QueuePool object at 0x7f988a238c50>,
    'url': postgresql+psycopg2://myuser:******@someserver:5432/somedb
}

Я знаю, что могу сделать что-то вроде SELECT * FROM pg_stat_ssl;, но хранит ли механизм SQLAlchemy такую ​​информацию в виде атрибута / метода класса?

Спасибо!

1 Ответ

1 голос
/ 21 марта 2019

Я не использую postgres, так что, надеюсь, это справедливо для вас.

SQLAlchemy берет информацию, предоставленную вами в url, и передает ее в базовую библиотеку dbapi, которая также указана в url,в вашем случае это psycopg2.

Ваш экземпляр engine подключается к базе данных только при необходимости, и sqlalchemy просто передает информацию о соединении драйверу, указанному в URL, который возвращает соединение, используемое sqlalchemy.

Простите, что это mysql, но в принципе должно быть одинаковым для вас:

>>> engine
Engine(mysql+mysqlconnector://test:***@localhost/test)
>>> conn = engine.connect()
>>> conn
<sqlalchemy.engine.base.Connection object at 0x000001614ACBE2B0>
>>> conn.connection
<sqlalchemy.pool._ConnectionFairy object at 0x000001614BF08630>
>>> conn.connection.connection
<mysql.connector.connection_cext.CMySQLConnection object at 0x000001614AB7E1D0>

Вызов engine.connect() возвращает экземпляр sqlalchemy.engine.base.Connection, который имеет connection propertyдля которого строка документации говорит:

Базовое соединение DB-API, управляемое этим Соединением.

Однако, как вы можете видеть из вышесказанного, оно на самом деле возвращает sqlalchemy.pool._ConnectionFairyобъект, который из его строки документации:

Прокси-сервер соединения DBAPI ...

Вот метод __init__() феи соединения, икакВы можете видеть, что он имеет атрибут connection, который является фактическим базовым соединением dbapi.

def __init__(self, dbapi_connection, connection_record, echo):
    self.connection = dbapi_connection
    self._connection_record = connection_record
    self._echo = echo

Что касается информации, доступной для объекта соединения dbapi, это зависит от реализации этого конкретного драйвера.Например, объекты подключения psycopg2 имеют атрибут info:

A ConnectionInfo объект, предоставляющий информацию о собственном подключении libpq.

Этот info объект имеет такие атрибуты, как ssl_in_use:

True, если для соединения используется SSL, False, если нет.

И ssl_attribute:

Возвращает информацию о соединении, связанную с SSL.

Так что вам не нужно копать слишком глубокочтобы получить фактическое соединение с БД, чтобы увидеть, что на самом деле происходит.

Кроме того, если вы хотите убедиться, что все клиентские соединения являются ssl, вы всегда можете force them to.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...