RHEL7环境下如何避免Kerberos Ticket过期?解决Python连SQL Server问题
Alright, let's tackle this Kerberos ticket expiration headache you're dealing with on RHEL7 for your SQL Server connection (using pypyodbc and Microsoft's ODBC Driver). The goal here is to set up persistent, auto-renewable credentials so you never have to manually create a ticket again. Here's a step-by-step breakdown:
A keytab is a file that stores your user's Kerberos encryption keys, allowing you to obtain tickets without entering a password every time. Here's how to generate one:
- First, if you have Kerberos admin access, fire up the
ktutiltool:ktutil - Add a new entry for your user account (replace placeholders with your actual info):
Note: Use the encryption type your domain uses—common alternatives areadd_entry -password -p your_username@YOUR_DOMAIN.COM -k 1 -e aes256-cts-hmac-sha1-96aes128-cts-hmac-sha1-96orrc4-hmacif older systems are involved. - Enter your user password when prompted.
- Save the keytab to a secure location (like
/etc/krb5.keytabor a user-specific path):wkt /etc/krb5.keytab - Exit
ktutilwithquit. - Lock down the keytab's permissions to keep it secure (only your user should read/write it):
chmod 600 /etc/krb5.keytab chown your_username:your_usergroup /etc/krb5.keytab
/etc/krb5.conf for Auto-Renewal Edit your Kerberos config file to extend ticket lifetimes and enable renewals:
- Open
/etc/krb5.confin a text editor (likeviornano). - In the
[libdefaults]section, add or update these settings:default_realm = YOUR_DOMAIN.COM ticket_lifetime = 1d # Base ticket validity (1 day is standard) renew_lifetime = 7d # Max time you can renew the ticket for forwardable = true renewable = true - Make sure the
[realms]section correctly points to your domain's KDC servers:[realms] YOUR_DOMAIN.COM = { kdc = kdc.your_domain.com admin_server = kdc.your_domain.com default_domain = your_domain.com } - Save the file. If you're running a Kerberos client service, restart it to apply changes:
systemctl restart krb5-workstation.service
Even with renewal enabled, we need a way to automatically refresh the ticket before it expires. A cron job is perfect for this:
- Open your user's crontab editor:
crontab -e - Add a line to run
kinitdaily (we'll use 2 AM as a low-traffic time):0 2 * * * /usr/bin/kinit -kt /etc/krb5.keytab your_username@YOUR_DOMAIN.COM > /dev/null 2>&1- The
-ktflag tellskinitto use the keytab instead of asking for a password. - Redirecting output to
/dev/nullprevents cron from sending you unnecessary emails.
- The
- Save and exit the editor. The cron job will now run daily to refresh your ticket.
- Test the keytab-based ticket acquisition:
kinit -kt /etc/krb5.keytab your_username@YOUR_DOMAIN.COM - Check the ticket details with
klist—look for therenew untilfield to confirm it's set to your configured 7-day window. - Update your Python connection string to ensure it uses Kerberos auth. Example:
import pypyodbc conn_str = """ DRIVER={ODBC Driver 17 for SQL Server}; SERVER=your_sql_server.your_domain.com; DATABASE=your_target_db; AUTHENTICATION=ActiveDirectoryKerberos; TRUSTED_CONNECTION=YES; """ try: conn = pypyodbc.connect(conn_str) print("Connection successful!") conn.close() except Exception as e: print(f"Connection failed: {str(e)}")
- If
kinitfails with the keytab, run it in verbose mode to debug:kinit -V -kt /etc/krb5.keytab your_username@YOUR_DOMAIN.COM - Double-check that
YOUR_DOMAIN.COMinkrb5.confis uppercase—Kerberos is case-sensitive here. - Verify your cron job is running by checking
/var/log/cronfor execution logs.
内容的提问来源于stack exchange,提问作者SSingh

