由於開發人員的電腦環境都比複雜的,像我們公司內部就有架設 AD ( Active Directory ) 而登入到客戶的 VPN 環境下也有自己的 AD,像我之前寫過的【主機於 AD 環境下設定 VPN 時需注意 DNS 設定是否正確】文章就是因為撥接上 VPN 之後所發生的問題,原本以為問題就這樣解決,但是事實並非如此,當我撥接上 VPN 之後若要再用 Windows 驗證的方式連接公司內部 SQL Server 時,卻會發生【 無法產生 SSPI 內容。 (Microsoft SQL Server) 】的錯誤,直到剛剛才找到解決之道。
首先我先來描述完整的問題,當我撥接上 VPN 之後,只要採用 Windows Authentication 登入公司內部的 SQL Server 就會發生【 無法產生 SSPI 內容。 (Microsoft SQL Server) 】的錯誤,如下圖示:
但是若改用 SQL Server Authentication 就可以正常連線,通常遇到這種問題都是因為 NTLM 或 Kerberos 驗證發生失敗才會這樣,不過為什麼只有撥接上 VPN 後才會發生錯誤呢?
為了釐清這個問題,我先利用 Microsoft Network Monitor 3.4 收錄一下在做 SQL Server 登入時到底在做 Kerberos 驗證時有哪些差別,我發現在登入 VPN 的情況下,Kerberos Request Body 會多送出一個 Tag1 與 Cname 的資料,這些參數資料在沒登入 VPN 的情況下是沒有的,有了這點微薄但看不懂得資訊,大概能猜出問題應該就出在 Kerberos 驗證了。
接著就閱讀了以下幾篇非常精華的文章:
讀完這幾篇文章後,我學到了幾個 SPN ( Service Principal Name ) 可能會引發 SQL Server 無法使用 Windows 驗證連線的問題 ( 例如使用網域帳戶當 SQL Server Instance 的執行帳戶時,若發生不正常關機的情況可能會導致 SQL Server 無法連線 ),不過雖然知道了原理,但還是無法理解為何只要撥接上 VPN 就會導致 Kerberos 驗證發生失敗,網路上的文章也沒有說明與此問題相關的原理,所以還是沒辦法解決我的問題,總不能就叫我撥接 VPN 時就不能使用公司網域內的那些使用 Kerberos 驗證的各種服務吧!
發現問題需要運氣,瞭解問題需要實力,解決問題需要創意
後來我聯想到我經常會利用 認證管理員 (Credential Manager) 儲存一些常用的 Windows 驗證帳號密碼,想說進去看看有什麼蛛絲馬跡,開啟方式如下圖示:
我發現只要 VPN 撥接上之後,便會在我的 Windows 7 裡自動建立起一個名為 *Session 的項目在「認證管理員」裡!如下圖示:
首先,我撥接上 VPN 根本不需要任何 Windows 認證,我只是為了要使用遠端桌面而已,因此我便嘗試把這筆 *Session 資料手動刪除,神奇的是問題就這樣解決了,哈哈哈哈~
刪除 *Session 之後,連接公司網域內的 SQL Server 使用 Windows 驗證就不再會出錯了!!
不過這一招有個缺點,就是每次成功撥接 VPN 之後都要手動刪除這筆資料,還好一天只要做一次這動作,對於哪些撥接 VPN 經常斷線的人來說就累了!之後要是有機會我再想想看有沒有其他較為徹底的解決辦法摟。
最後,終極的解決之道已經出爐,需要的人請參考以下手動設定方式,只要設定一次,日後就可以高枕無憂,不再受到 VPN 連線干擾之苦!
步驟 1:找到以下 rasphone.pbk 檔案,並使用 Notepad 記事本開啟編輯
%APPDATA%\Microsoft\Network\Connections\Pbk\rasphone.pbk
步驟 2:找到該檔案內 UseRasCredentials=1 的參數,並全部修改成 UseRasCredentials=0 之後存檔
備註 1:該 rasphone.pbk 檔案是所有 VPN 連線的定義檔,裡面全部都是定義 VPN 連線時的參數,而 UseRasCredentials 參數是沒有介面可以設定的,因此必須手動修改才行。而當 UseRasCredentials 參數設定為 0 之後,VPN 撥接連線完成後就不會再有這筆 *Session 認證資料了。
備註 2:如果你的電腦不在網域內,其實不會有這個問題存在。如果你要登入遠端的網域進行作業,也不需要套用本篇文章所建議的解決方法。
相關連結