MS-SQL: connecting Python on Linux – using Active Directory Credentials and Kerberos
Last Updated on July 13, 2023 by Hammad Rauf
Microsoft SQL Server (MS-SQL) is a very popular database server. Following the 3-tier architecture many applications use it as the back end database server. Apart from Microsoft Windows based applications sometimes the application are deployed on Linux servers. What is required when connecting a Python Application (on Linux) to a MS-SQL back-end using Windows (Active Directory Domain) user account? After some searching on the Internet a solution was found that allowed this possibility.
Following is a summary of what is needed in order to accomplish this connection between a Python application running on Linux and MS-SQL back-end using Active Directory user account credentials. The contents below are based on several different web-sites where parts of the solution were discovered. These steps have been verified on CentOS Linux 6.8 (RHEL 6.8). I have collected all the steps in one article.
Installing MS-SQL Driver (Pyodbc and Microsoft ODBC SQL Driver)
It turns out that it is not possible to use “pymssql” to connect using Active Directory user account on Linux Centos 6.8 (RHEL 6.8). The pymssql python driver library only supports MS-SQL user accounts. So for this problem we had to use “pyodbc” with Microsoft provided ODBC SQL Driver.
To install “pyodbc” and MS ODBC SQL Driver use the following steps.
sudo yum install gcc-c++ sudo yum install python-devel sudo yum install python-pip sudo yum install unixODBC-devel sudo pip install pyodbc # failed OR sudo yum install pyodbc
Now as root or Super User type the following. This will update the “yum” repositories list to include Microsoft published RHEL software site.
sudo su curl https://packages.microsoft.com/config/rhel/6/prod.repo > /etc/yum.repos.d/mssql-release.repo exit
Now type the following to download the MS ODBC SQL Server driver. There are some optional components that you may find useful. These steps also update the $PATH environment variable to include the optional tools.
sudo yum remove unixODBC-utf16 unixODBC-utf16-devel sudo ACCEPT_EULA=Y yum install msodbcsql sudo ACCEPT_EULA=Y yum install mssql-tools # optional echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc source ~/.bashrc sudo yum install unixODBC-devel # optional
Use the following steps to verify that the pyodbc and MS-ODBC SQL Driver installed correctly.
ls -l /usr/lib64/libodbc* odbc_config --version --longodbcversion --cflags --ulen --libs --odbcinstini --odbcini odbcinst -j isql --version ls -l /opt/microsoft/msodbcsql/lib64/ dltest /opt/microsoft/msodbcsql/lib64/libmsodbcsql-11.0.so.2270.0 SQLGetInstalledDrivers dltest /opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.0 SQLGetInstalledDrivers cat /etc/odbcinst.ini # should contain a section called [ODBC Driver 13 for SQL Server]
Connecting Via DSN
You may want to create a Data Source Name (DSN) to connect to the database. If that is the case then create a text file with the following contents and save it as “myconnection_dsn_stub.dsn”.
[MyDSNName] Driver = ODBC Driver 13 for SQL Server Description = My Database DSN Trace = No Server = db_server.mycontoso.com,1433
Now register the DSN entry and test connection in Python. Note that “Trusted connection = yes” forces the driver to use Active Directory (Kerberos) user account.
cat /etc/odbcinst.ini sudo odbcinst -i -s -f ./mycnonection_dsn_stub.dsn -l cat /etc/odbc.ini python -c "import pyodbc; print(pyodbc.connect('DSN=MyDSNName;DATABASE=db_name;UID=ad_user_id;PWD=*****;Trusted_Connection=yes'))"
If you have not installed and configured Kerberos (See below) then you will get following error message.
Traceback (most recent call last): File "", line 1, in pyodbc.Error: ('HY000', "[HY000] [unixODBC][Microsoft][ODBC Driver 13 for SQL Server]SSPI Provider: Credentials cache file '/tmp/krb5cc_500' not found (851968) (SQLDriverConnectW)")
Install Kerberos
Linux servers use Kerberos to work with Microsoft Windows Active Directory Domain servers. Kerberos provides a reliable and secure way for Linux servers to authenticate on Active Directory domains.
Install Kerberos by using the following steps.
sudo yum install krb5-workstation cat /etc/krb5.conf
To configure Kerberos to work in your Active Directory domains, you need to configure it. On a Windows Desktop computer perform the following steps to find out the Domain controller server name. Replace DOMAIN_NAME with actual domain name i.e. contoso.com .
C:\> nslookup > set type=all > _ldap._tcp.dc._msdcs.MYCONTOSO.COM mycontoso.com nameserver = my-domain-controller-server.MYCONTOSO.com ...................... ping my-domain-controller-server.MYCONTOSO.com
Now configure Kerberos as follows. Please note that the contents of “/etc/krb5.conf” file are shown as “cat” command output.
sudo cp /etc/krb5.conf /etc/krb5.conf_backup ls -l /etc/krb5* sudo vi /etc/krb5.conf cat /etc/krb5.conf [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = MYCONTOSO.COM [realms] MYCONTOSO.COM = { kdc = my-domain-controller-server.MYCONTOSO.com } [domain_realm] .mycontoso.com = MYCONTOSO.COM mycontoso.com = MYCONTOSO.COM
Kerberos works by passing the user account and password information to Active Directory server, which authenticates the user. If the user is authenticated successfully then a temporary Kerberos Ticket is saved in “/tmp/krb5cc” file. This ticket can be used to login to Windows Servers before the ticket expires.
To obtain Kerberos Ticket interactively, for testing the connection type the following commands.
kinit AD_USER_ID@MYCONTOSO.COM # Enter User Password klist # Lists Kerberos Tickets # Ticket cache: FILE:/tmp/krb5cc_500 # Default principal: AD_USER_ID@MYCONTOSO.COM # # Valid starting Expires Service principal # 08/31/17 14:17:29 09/01/17 00:17:50 krbtgt/MYCONTOSO.COM@MYCONTOSO.COM # renew until 09/01/17 14:17:29 # 08/31/17 14:18:56 09/01/17 00:17:50 MSSQLSvc/db_server.mycontoso.com:1433@MYCONTOSO.COM # renew until 09/01/17 14:17:29
Connecting Python With Kerberos Ticket
To test Connection with current Kerberos ticket type the following. Please note that this connection method is not using the DSN that we created earlier.
$ cat testConnection.py import pyodbc cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER=db_server.mycontonso.com,1433;DATABASE=db_name;Trusted_Connection=yes') cursor = cnxn.cursor() cursor.execute('SELECT TOP 10 [ServerName],[RunID],[JobID],[TimeStamp] FROM [db_name].[dbo].[table_name] ORDER BY [RunID] DESC') row = cursor.fetchone() if not row: print("No rows returned.") while row: print("ServerName=%s, JobID=%d, TimeStamp=%s" % (row[0], row[2], row[3])) row = cursor.fetchone() cnxn.close() $ python testConnection.py
Following is an example of how Python code can be used to obtain fresh Kerberos ticket and then connect to the MS-SQL database back-end.
from subprocess import Popen, PIPE import pyodbc # Login Credentials userid="AD_USER_ID" password='******' realm="MYCONTOSO.COM" kinit = '/usr/bin/kinit' # Get Fresh Kerberos Ticket kinit_args = [ kinit, '%s@%s' % (userid, realm) ] kinit = Popen(kinit_args, stdin=PIPE, stdout=PIPE, stderr=PIPE) kinit.stdin.write('%s\n' % password) kinit.wait() cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER=db_server.mycontoso.com,1433;DATABASE=db_name;Trusted_Connection=yes') cursor = cnxn.cursor() cursor.execute('''SELECT TOP 10 CAST([ServerName] AS VARCHAR) AS SERVERNAME ,[RunID] ,[JobID] ,CAST([LongText] AS VARCHAR(MAX)) AS LONGTEXT ,[TimeStamp] FROM [db_name].[dbo].[table_name]''') row = cursor.fetchone() if not row: print("No rows returned.") while row: print("ServerName=%s, LongText=%s, JobID=%d, TimeStamp=%s" % (row[0], row[3], row[2], row[4])) row = cursor.fetchone() cnxn.close()
Further Reading
The following list is not complete, but it provides some pointers for further reading on the topics discussed in this article.
- Python Kerberos Kinit – https://pypi.python.org/pypi/kerberos , Date accessed: September 26, 2017
- Python Kerberos – http://python-notes.curiousefficiency.org/en/latest/python_kerberos.html , Date accessed: September 26, 2017
- CentOS Home page- https://wiki.centos.org/FrontPage , Date accessed: September 26, 2017
- Three Tier Architecture – https://en.wikipedia.org/wiki/Multitier_architecture#Three-tier_architecture , Date accessed: September 26, 2017
- Kerberos Reference – https://web.mit.edu/kerberos/ , Date accessed: September 26, 2017
- pyodbc Driver/Bridge – https://mkleehammer.github.io/pyodbc/ , Date accessed: September 26, 2017
- Microsoft ODBC SQL Driver installation – https://docs.microsoft.com/en-us/sql/connect/python/pyodbc/step-1-configure-development-environment-for-pyodbc-python-development , Date accessed: September 26, 2017
- Microsoft ODBC Driver installation 2 – https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server , Date accessed: September 26, 2017
- Active Directory – https://en.m.wikipedia.org/wiki/Active_Directory , Date accessed: September 26, 2017