Linuxマシンからpyodbcを使用してWindows SQL Serverに接続しようとしています。
私にはいくつかの制約があります:
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インスタンスに接続する方法です。
結局、FreeTDSドライバの上にあるpyodbcであるpymssqlライブラリを使用することになりました。それはそのままで機能しました。
このライブラリを見つけるのにとても苦労したのは奇妙です。
これを機能させるには、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チケットを検索すると、いくつかの手掛かりが得られる可能性があります。
私は同じことをやろうとしていて、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")
Linuxを介したWindows認証の生成は複雑です。 EasySoftDB(商用)はこれを処理できましたが、FreeTDSは複雑なサポートを提供しています。
https://docs.Microsoft.com/en-us/sql/connect/odbc/linux-mac/using-integrated-authentication
私の提案は、Windows認証から離れてSQL認証を使用することです。接続文字列でユーザー名とパスワードを提供することを除いて、実際にはセキュリティの違いはありません。しかし、これはあなたの人生をずっと簡単にします。