Nginx反向代理之巨坑underscores_in_headers


一、背景

因為項目需求,在做Windows的相關的事情;基本架構就是Nginx--> Nginx --> IIS,在Linux機器上通過Nginx做反向代理到Windows的IIS;然后遇到的問題直接使用IIS的IP訪問是沒有任何問題的;只要通過Nginx的反向代理總會有部分會報錯;報錯具體如下:
 
1)表面錯誤
Server Error, unsaved changes may have been lost, please reload the page before you continue.

 

2)瀏覽器檢查報錯
 

 

3)應用層的具體日志報錯如下

<error errorId="fe8491dc-8dd1-49f2-8339-1dc3863b2280" host="aaaaaa" type="System.Web.Mvc.HttpAntiForgeryException" 
message="The required anti-forgery form field &quot;__RequestVerificationToken&quot; is not present." source="System.Web.WebPages"
detail="System.Web.Mvc.HttpAntiForgeryException (0x80004005): The required anti-forgery form field &quot;__RequestVerificationToken&quot; is not present.&#xD;&#xA;
at System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken)&#xD;&#xA;
at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext, String cookieToken, String formToken)&#xD;&#xA;
at SunGard.AvantGard.Web.Infrastructure.AntiForgeryHelper.Validate()&#xD;&#xA;
at SunGard.AvantGard.Web.Infrastructure.UseAntiForgeryTokenOnPostByDefault.OnActionExecuting(ActionExecutingContext filterContext)&#xD;&#xA;
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.InvokeActionMethodFilterAsynchronouslyRecursive(Int32 filterIndex)&#xD;&#xA;
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.InvokeActionMethodFilterAsynchronouslyRecursive(Int32 filterIndex)&#xD;&#xA;
at System.Web.Mvc.Async.AsyncControllerActionInvoker.&lt;&gt;c__DisplayClass7_0.&lt;BeginInvokeActionMethodWithFilters&gt;b__0(AsyncCallback asyncCallback, Object asyncState)&#xD;&#xA;
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)&#xD;&#xA;
at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeActionMethodWithFilters(ControllerContext controllerContext,
IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters, AsyncCallback callback, Object state)&#xD;&#xA;
at System.Web.Mvc.Async.AsyncControllerActionInvoker.&lt;&gt;c__DisplayClass3_1.&lt;BeginInvokeAction&gt;b__0(AsyncCallback asyncCallback, Object asyncState)
"
user="aaaaaa" time="2021-09-03T09:56:15.1925032Z" statusCode="500">

 

二、排查過程

1)直接使用IP行,加上Nginx的代理就是不行,說明肯定是Nginx的哪些配置有問題
2)通過瀏覽器的檢查,發現直接返回錯誤就是400,Bad request;於是把網上所有關於400的可能給排除了,還是不行
3)因為對Windows的服務確實很少用,也沒想着去看的應用日志;直到最后才想辦法找到他的應用日志,發現了上面的問題
4)在Nginx的配置文件里加上underscores_in_headers on配置后,解決。
 

三、根本原因

請求的請求頭參數有下划線,而Nginx代理默認會把header中參數有“_”下划線的參數去掉;解決這個問題只需要在Nginx的配置文件中添加: underscores_in_headers on;重啟Nginx即可。在上面的這個問題中,就是因為Cookies的參數里有兩個參數是帶有下划線的,因此每次請求Nginx都會把這兩個參數當作無效參數去掉,導致每次請求都需要認證,因此就會報上面的錯誤第一條。
 

 

四、總結

1)在做設計時就要考慮不要用下划線做請求頭
2)作為SRE層面,排查一定要根據日志來,程序有問題一定是有證據的,不能只靠猜測;要去找到可靠的證據來驗證自己的猜想。 日志、日志、日志,重要的事情說三遍,絕對是你排查第一需要看的,自己就是因為思想上有一定的懶惰,沒有直接第一時間去看應用日志,而是一直盯着瀏覽器返回的錯誤在排查導致排查時間過長。
3)排查問題從上到下,從下到上要適當的靈活變動;不能只停留在表層錯誤去排查問題,應用的日志是最能體現問題的。
 

五、學習交流

歡迎大家關注我的公眾號,一起交流、學習。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM