web-dev-qa-db-ja.com

pyodbcを使用してLinuxからWindows SQL Serverに認証する

Linuxマシンからpyodbcを使用してWindows SQL Serverに接続しようとしています。

私にはいくつかの制約があります:

  • Windowsドメインアカウントでログオンする必要があります
  • Python3を使用する必要があります
  • LinuxからWindowsへの移行が必要
  • 特定のインスタンスに接続する必要がある

Microsoftの説明に従って環境をセットアップし、それを機能させています(pyodbcをインポートして、構成済みのムール貝ドライバーを使用できます)。

私はWindowsドメイン認証に精通していないので、問題はどこにあるのでしょうか。

私の接続文字列:

DRIVER={ODBC Driver 17 for SQL Server};SERVER=myserver.mydomain.com;PORT=1433;DATABASE=MyDatabase;Domain=MyCompanyDomain;Instance=MyInstance;UID=myDomainUser;PWD=XXXXXXXX;Trusted_Connection=yes;Integrated_Security=SSPI

おそらく、SQLサーバーで直接認証するのではなく、「Trusted_Connection」を使用してWindowsドメイン認証を使用する必要があります。

実行時に発生するエラーpyodbc.connect(connString)

pyodbc.Error: ('HY000', '[HY000] [unixODBC][Microsoft][ODBC Driver 17 for SQL Server]SSPI Provider: No Kerberos credentials available (851968) (SQLDriverConnect)')

他のソースからは、このコードは現在ログインしているユーザーの資格情報を使用するため、これはWindowsで動作するはずです。

私の質問は、Windowsドメインの資格情報を使用してLinuxからWindows SQL Serverインスタンスに接続する方法です。

11
Esser420

結局、FreeTDSドライバの上にあるpyodbcであるpymssqlライブラリを使用することになりました。それはそのままで機能しました。

このライブラリを見つけるのにとても苦労したのは奇妙です。

5
Esser420

これを機能させるには、Kerberosチケットを取得する必要があります。この例では、LinuxシステムがKerberos経由で認証するように設定されているかどうか、またはコードが接続文字列に到達する前に以前にKerberosチケットを取得したかどうかは指定していません。

LinuxシステムがKerberosを介して認証するように設定されている場合、概念実証として、コマンドラインからkinitを使用してKerberosチケットを取得できます。 WSLを介してWindows上のUbuntuで実行されているpython3で動作するのは次のとおりです。 pythonコード:

#!/usr/bin/env python

# minimal example using Kerberos auth
import sys
import re
import pyodbc

driver='{ODBC Driver 17 for SQL Server}'
server = sys.argv[1]
database = sys.argv[2]

# trusted_connection uses kerberos ticket and ignores UID and PASSWORD in connection string
# https://docs.Microsoft.com/en-us/sql/connect/odbc/linux-mac/using-integrated-authentication?view=sql-server-ver15

try:
    cnxn = pyodbc.connect(driver=driver, server=server, database=database, trusted_connection='yes')
    cursor = cnxn.cursor()
except pyodbc.Error as ex:
    msg = ex.args[1]
    if re.search('No Kerberos', msg):
        print('You must login using kinit before using this script.')
        exit(1)
    else:
        raise

# Sample select query
cursor.execute("SELECT @@version;")
row = cursor.fetchone()
while row:
    print(row[0])
    row = cursor.fetchone()
print('success')

これは、チケットがない場合に通知します。チケットを使用するため、スクリプトでユーザーまたはパスワードを指定する必要はありません。両方とも無視されます。

今それを実行します:

user@localhost:~# kdestroy # make sure there are no active tickets
kdestroy: No credentials cache found while destroying cache

user@localhost:~# python pyodbc_sql_server_test.py tcp:dbserver.example.com mydatabase
You must login using kinit before using this script.

user@localhost:~# kinit
Password for [email protected]:

user@localhost:~# python pyodbc_sql_server_test.py tcp:dbserver.example.com mydatabase
Microsoft SQL Server 2016 (SP2-GDR) (KB4505220) - 13.0.5101.9 (X64)
        Jun 15 2019 23:15:58
        Copyright (c) Microsoft Corporation
        Enterprise Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: )

success

user@localhost:~#

pythonコードからKerberosチケットを取得することもできますが、これはこの回答の範囲外です。python = Kerberosモジュールが解決策を示している可能性があります。

Linuxシステムをセットアップして、ユーザーがログインするとすぐに、他のプロセスに渡すことができるKerberosチケットを自動的に取得することもできます。これもこの回答の範囲外ですが、Linuxログイン時に自動Kerberosチケットを検索すると、いくつかの手掛かりが得られる可能性があります。

1
benrifkah

私は同じことをやろうとしていて、OPの回答を読んだ後、pymssqlをテストしましたが、以下でうまく機能することに気づきました:

pymssql.connect(server='myserver', user='domain\username', password='password', database='mydb')

それがすべてのpymssqlに必要であることを理解した後、私はpyodbcに戻ってそれを動作させることができました:

pyodbc.connect("DRIVER={FreeTDS};SERVER=myserver;PORT=1433;DATABASE=mydb;UID=domain\username;PWD=password;TDS_Version=8.0")
0
Pathead

Linuxを介したWindows認証の生成は複雑です。 EasySoftDB(商用)はこれを処理できましたが、FreeTDSは複雑なサポートを提供しています。

https://docs.Microsoft.com/en-us/sql/connect/odbc/linux-mac/using-integrated-authentication

私の提案は、Windows認証から離れてSQL認証を使用することです。接続文字列でユーザー名とパスワードを提供することを除いて、実際にはセキュリティの違いはありません。しかし、これはあなたの人生をずっと簡単にします。

0
eatmeimadanish