﻿# VPN 連線後 SQL Server 發生「無法產生 SSPI 內容」錯誤

由於開發人員的電腦環境都比複雜的，像我們公司內部就有架設 AD ( Active Directory ) 而登入到客戶的 VPN 環境下也有自己的 AD，像我之前寫過的【[主機於 AD 環境下設定 VPN 時需注意 DNS 設定是否正確](/post/2010/12/16/Setup-DNS-manually-when-PC-located-in-the-AD-environment.aspx)】文章就是因為撥接上 VPN 之後所發生的問題，原本以為問題就這樣解決，但是事實並非如此，當我撥接上 VPN 之後若要再用 Windows 驗證的方式連接公司內部 SQL Server 時，卻會發生【 **無法產生 SSPI 內容。 (Microsoft SQL Server)** 】的錯誤，直到剛剛才找到解決之道。

首先我先來描述完整的問題，當我撥接上 VPN 之後，只要採用 **Windows Authentication** 登入公司內部的 SQL Server 就會發生【 **無法產生 SSPI 內容。 (Microsoft SQL Server)** 】的錯誤，如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e8da12716dec934d19fa-SNAGHTML104fc3c1.png)

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/847b10d86ff7ca0ec759-SNAGHTML105061b4_thumb.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c78df8fc0cb4b70d2bf1-SNAGHTML105061b4.png)

但是若改用 **SQL Server Authentication** 就可以正常連線，通常遇到這種問題都是因為 NTLM 或 Kerberos 驗證發生失敗才會這樣，不過為什麼只有撥接上 VPN 後才會發生錯誤呢？

為了釐清這個問題，我先利用 [Microsoft Network Monitor 3.4](https://www.microsoft.com/en-us/download/details.aspx?id=4865) 收錄一下在做 SQL Server 登入時到底在做 Kerberos 驗證時有哪些差別，我發現在登入 VPN 的情況下，Kerberos Request Body 會多送出一個 Tag1 與 Cname 的資料，這些參數資料在沒登入 VPN 的情況下是沒有的，有了這點微薄但看不懂得資訊，大概能猜出問題應該就出在 Kerberos 驗證了。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e47461a9bfe0bdbece51-image_461.png)

接著就閱讀了以下幾篇非常精華的文章：

-   [How to troubleshoot the "Cannot generate SSPI context" error message](https://learn.microsoft.com/en-us/troubleshoot/sql/database-engine/connect/cannot-generate-sspi-context-error)
-   [“Cannot Generate SSPI Context” error message, more comments for SQL Server](https://learn.microsoft.com/en-us/archive/blogs/sql_protocols/cannot-generate-sspi-context-error-message-more-comments-for-sql-server)
-   [“Cannot generate SSPI context” error message, when connect to local SQL Server outside domain](https://learn.microsoft.com/en-us/archive/blogs/sql_protocols/cannot-generate-sspi-context-error-message-when-connect-to-local-sql-server-outside-domain)
-   [Using Kerberos with SQL Server](https://learn.microsoft.com/en-us/archive/blogs/sql_protocols/using-kerberos-with-sql-server)
-   [PRB：錯誤訊息：無法產生 SSPI 內容](https://web.archive.org/web/20130621195206/http://support.microsoft.com:80/kb/814401?)

讀完這幾篇文章後，我學到了幾個 SPN ( [Service Principal Name](http://msdn.microsoft.com/en-us/library/ms677949\(v=vs.85\).aspx) ) 可能會引發 SQL Server 無法使用 Windows 驗證連線的問題 ( 例如使用網域帳戶當 SQL Server Instance 的執行帳戶時，若發生不正常關機的情況可能會導致 SQL Server 無法連線 )，不過雖然知道了原理，但還是無法理解為何只要撥接上 VPN 就會導致 Kerberos 驗證發生失敗，網路上的文章也沒有說明與此問題相關的原理，所以還是沒辦法解決我的問題，總不能就叫我撥接 VPN 時就不能使用公司網域內的那些使用 Kerberos 驗證的各種服務吧！

> **發現問題需要運氣，瞭解問題需要實力，解決問題需要創意**

後來我聯想到我經常會利用 **認證管理員** (**Credential Manager**) 儲存一些常用的 Windows 驗證帳號密碼，想說進去看看有什麼蛛絲馬跡，開啟方式如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/92d5fe3ff24fbc63d4f5-image_462.png)

我發現只要 VPN 撥接上之後，便會在我的 Windows 7 裡自動建立起一個名為 **\*Session** 的項目在「認證管理員」裡！如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/03aa810d84f39bc57d87-image_463.png)

首先，我撥接上 VPN 根本不需要任何 Windows 認證，我只是為了要使用遠端桌面而已，因此我便嘗試把這筆 **\*Session** 資料手動刪除，神奇的是問題就這樣解決了，哈哈哈哈～

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/31a8129a2851bc169e7b-image_464.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ae56d70f30413dc51c0f-SNAGHTML108b6a3d.png)

刪除 **\*Session** 之後，連接公司網域內的 SQL Server 使用 Windows 驗證就不再會出錯了！！

不過這一招有個缺點，就是每次成功撥接 VPN 之後都要手動刪除這筆資料，還好一天只要做一次這動作，對於哪些撥接 VPN 經常斷線的人來說就累了！~~之後要是有機會我再想想看有沒有其他較為徹底的解決辦法摟。~~

最後，終極的解決之道已經出爐，需要的人請參考以下手動設定方式，只要設定一次，日後就可以高枕無憂，不再受到 VPN 連線干擾之苦！

步驟 1：找到以下 **rasphone.pbk** 檔案，並使用 Notepad 記事本開啟編輯

```
%APPDATA%\Microsoft\Network\Connections\Pbk\rasphone.pbk
```

步驟 2：找到該檔案內 UseRasCredentials=1 的參數，並全部修改成 **UseRasCredentials=0** 之後存檔

```
UseRasCredentials=0
```

**備註 1**：該 **rasphone.pbk** 檔案是所有 VPN 連線的定義檔，裡面全部都是定義 VPN 連線時的參數，而 UseRasCredentials 參數是沒有介面可以設定的，因此必須手動修改才行。而當 UseRasCredentials 參數設定為 0 之後，VPN 撥接連線完成後就不會再有這筆 **\*Session** 認證資料了。

**備註 2**：如果你的電腦不在網域內，其實不會有這個問題存在。如果你要登入遠端的網域進行作業，也不需要套用本篇文章所建議的解決方法。

**相關連結**

-   [How to troubleshoot the "Cannot generate SSPI context" error message](https://learn.microsoft.com/en-us/troubleshoot/sql/database-engine/connect/cannot-generate-sspi-context-error)
-   [“Cannot Generate SSPI Context” error message, more comments for SQL Server](https://learn.microsoft.com/en-us/archive/blogs/sql_protocols/cannot-generate-sspi-context-error-message-more-comments-for-sql-server)
-   [“Cannot generate SSPI context” error message, when connect to local SQL Server outside domain](https://learn.microsoft.com/en-us/archive/blogs/sql_protocols/cannot-generate-sspi-context-error-message-when-connect-to-local-sql-server-outside-domain)
-   [Using Kerberos with SQL Server](https://learn.microsoft.com/en-us/archive/blogs/sql_protocols/using-kerberos-with-sql-server)
-   [Service Principal Names (Windows)](http://msdn.microsoft.com/en-us/library/ms677949\(v=vs.85\).aspx)
-   [What Is A Service Principal Name SPN](https://learn.microsoft.com/en-us/windows/win32/ad/service-principal-names)
-   [PRB：錯誤訊息：無法產生 SSPI 內容](https://web.archive.org/web/20130621195206/http://support.microsoft.com:80/kb/814401?)
-   ["Access Denied" error message when you try to access remote resources](https://web.archive.org/web/20130618205822/http://support.microsoft.com/kb/822707/en-us)
