«เบราว์เซอร์เปิดไซต์ภายนอกได้ แต่มีแค่แอปธุรกิจที่ไปไม่ถึง API ภายนอก» «รันบนเครื่องพัฒนา แต่หมดเวลาบนเครือข่ายลูกค้า» «สื่อสารเมื่อรันด้วยมือ และล้มเหลวทันทีที่ทำให้เป็นบริการ Windows» — เมื่อคุณรันแอปธุรกิจในสภาพแวดล้อมที่มีพร็อกซีองค์กร คำปรึกษาแบบนี้เป็นกลุ่มที่พบบ่อยที่สุด
ในกรณีส่วนใหญ่สาเหตุไม่ใช่พร็อกซีเซิร์ฟเวอร์ล่มและไม่ใช่บั๊กแอป Windows มีหลายตระกูลแยกของสิ่งที่คนเรียก «ค่าพร็อกซี» และค่าใดใครอ่านต่างกันตามแอป (ตามสแตก HTTP ที่ใช้) และตามบัญชีที่รัน — ความไม่ตรงกันนั้น ค่าที่เบราว์เซอร์อ่าน ค่าที่บริการอ่าน และค่าที่ HttpClient ของ .NET อ่าน แต่ละอย่างอาจเป็นคนละเรื่อง พอโครงสร้างนั้นอยู่ในหัว การแยก «รันได้ในเบราว์เซอร์ แต่…» จะเร็วอย่างน่าประหลาด
บทความนี้มุ่งไปที่เจ้าหน้าที่ไอทีของบริษัทขนาดเล็กและกลางและนักพัฒนาแอป Windows มันผูก ในภาพเดียว สามตระกูลค่าพร็อกซี — WinINET, WinHTTP และตัวแปรสภาพแวดล้อม — การตั้งค่าอัตโนมัติ PAC และ WPAD ความต่างของการหาพร็อกซีระหว่าง .NET Framework กับ .NET (Core เป็นต้นไป) พร็อกซียืนยันตัวตน (407) การตรวจ TLS และขั้นตอนแยกปัญหาเชิงปฏิบัติ รูปแบบการสร้าง HttpClient และการออกแบบหมดเวลาเองอยู่ใน «อย่าห่อ HttpClient ในบล็อก using» ดังนั้นบทความนี้โฟกัสที่ การหาพร็อกซี
1. สรุปก่อนเลย
- ค่าพร็อกซี Windows ไม่ใช่สิ่งเดียว มีอย่างน้อยสามตระกูล (1) ค่าต่อผู้ใช้ของ WinINET (หน้า «Proxy» ในแอปการตั้งค่า = Internet Options เก่า) (2) ค่าเครื่องของ WinHTTP (
netsh winhttp) และ (3) ตัวแปรสภาพแวดล้อมHTTP_PROXY/HTTPS_PROXYอันใดถูกอ่านตัดสินที่ฝั่งแอป12 - «Proxy» ที่เห็นในแอปการตั้งค่าคือค่าต่อผู้ใช้ของ WinINET เบราว์เซอร์และแอปโต้ตอบอ่าน บริการ Windowsไม่อ่าน WinINET ไม่รองรับการใช้ในบริการ การใช้บริการเป็นงานของ WinHTTP13
- สาเหตุที่พบบ่อยที่สุดของ «รันด้วยมือได้แต่ไม่เป็นบริการ» คือความต่างของบัญชีที่รัน LocalSystem และบัญชีบริการมองไม่เห็นพร็อกซีต่อผู้ใช้ที่ผู้ดูแลตั้งบนหน้าจอของตน34
netsh winhttp set proxyเป็นค่าสถิต ไม่จัดการ PAC การตรวจจับอัตโนมัติ หรือการยืนยันตัวตนพร็อกซี หากต้องการตั้ง PAC หรือ WPAD ต่อเครื่อง ต้องใช้ฝั่งnetsh winhttp set advproxy42- ผล PAC เปลี่ยนตาม URL ฟังก์ชัน
FindProxyForURLของไฟล์ PAC รับ URL และโฮสต์แล้วคืนรายการพร็อกซีหรือการเชื่อมตรง (DIRECT) «ไซต์นั้นรันได้ แต่มีแค่ API นี้ที่ไม่ได้» อาจเป็นสาขา PAC56 - HttpClient บน .NET (Core เป็นต้นไป) เริ่มต้นพร็อกซีเริ่มต้นในลำดับตัวแปรสภาพแวดล้อม → ค่าพร็อกซีผู้ใช้ Windows หากกำหนด
HTTP_PROXY,HTTPS_PROXYหรือALL_PROXYใดอันหนึ่ง มันจะเหนือกว่าค่า OS จึงเกิดอุบัติเหตุ «มีคนทิ้งตัวแปรสภาพแวดล้อมไว้» ได้7 - ค่าเริ่มต้นของ .NET Framework คือ Internet Options ของบัญชีที่รัน และทับได้ด้วย
defaultProxyใน app.config ค่าไฟล์การตั้งค่าเหนือกว่าค่าของระบบ89 - 407 เป็นข้อผิดพลาดยืนยันตัวตนพร็อกซี ต่างจาก 401 (การยืนยันตัวตนเซิร์ฟเวอร์) สคีมามี Negotiate, NTLM และ Basic และใน .NET คุณส่งข้อมูลรับรองด้วย
DefaultProxyCredentialsหรือWebProxy.UseDefaultCredentialsสังเกตว่าภายใต้บัญชีบริการเนื้อหาของ «ข้อมูลรับรองเริ่มต้น» เปลี่ยน101112 - พร็อกซีตรวจ TLS อยู่ได้เฉพาะเป็นชุดกับการแจกจ่ายใบรับรอง CA ภายใน เครื่องและรันไทม์ที่ยังไม่ได้รับจะได้ข้อผิดพลาดตรวจสอบใบรับรอง แก้ด้วยการแจกจ่ายไปที่เก็บใบรับรอง ไม่ใช่ปิดการตรวจสอบในแอป134
ประโยคเดียว: ทุกครั้งที่พูดว่า «ตรวจค่าพร็อกซีแล้ว» ต้องพูดได้เสมอว่าตรวจตระกูลใดในสามตระกูล และจากบัญชีใด — นั่นคือหัวข้อของบทความนี้
2. Windows มีสามตระกูลของ «ค่าพร็อกซี»
ก่อนอื่น แผนที่รวม เส้นทางที่แอป Windows ใช้หาพร็อกซีองค์กรตกอยู่ในสามตระกูลนี้
| ตระกูลค่า | ที่ตั้ง / คำสั่ง | ขอบเขต | ใครอ่านเป็นหลัก |
|---|---|---|---|
| (1) WinINET (Internet Options) | การตั้งค่า → เครือข่ายและอินเทอร์เน็ต → พร็อกซี, inetcpl.cpl |
ต่อผู้ใช้ (ค่าเริ่มต้น) | เบราว์เซอร์, แอปเดสก์ท็อปโต้ตอบ, ค่าเริ่มต้น .NET Framework |
| (2) WinHTTP (ค่าเครื่อง) | netsh winhttp set proxy / set advproxy |
เครื่อง | บริการ Windows, บางส่วนประกอบของ OS |
| (3) ตัวแปรสภาพแวดล้อม | HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY |
โพรเซส (สืบทอดตามที่กำหนด) | HttpClient บน .NET (Core เป็นต้นไป), curl, เครื่องมือข้ามแพลตฟอร์มเช่น Node.js และ Python |
(1) คือสิ่งที่คนทั่วไปรู้ว่า «ค่าพร็อกซี Windows» สาระคือการตั้งค่า WinINET ในประวัติคือ Internet Options ของ Internet Explorer และตามค่าเริ่มต้นเก็บต่อผู้ใช้4
(2) คือค่าเริ่มต้นต่อเครื่องสำหรับบริบทเช่นบริการที่ «ไม่มีผู้ใช้ลงชื่อเข้าใช้» (3) ส่วนใหญ่เป็นธรรมเนียมของเครื่องมือจากโลกข้ามแพลตฟอร์ม บน Windows .NET (Core เป็นต้นไป) และ curl ฯลฯ ก็อ่านเช่นกัน7
จุดสำคัญคือ ตระกูลใดถูกอ่านตัดสินที่ฝั่งแอป ไม่ใช่ฝั่งการตั้งค่า หากแอปใช้ WinINET ภายในมันอ่าน (1) หาก WinHTTP อ่าน (2) (หรือการทับเฉพาะแอป) หาก .NET (Core เป็นต้นไป) อ่าน (3) แล้ว (1) ดังนั้นโดยปกติไม่ใช่ «ค่าพร็อกซีถูกแต่ยังต่อไม่ได้» ความจริงคือ «ตระกูลที่แอปอ่านเป็นตระกูลอื่นจากที่คุณตรวจ»
flowchart TB
accTitle: สามตระกูลค่าพร็อกซีของ Windows
accDescr: WinINET คือการตั้งค่าและ Internet Options ต่อผู้ใช้ WinHTTP คือค่าเริ่มต้นเครื่องผ่าน netsh และตัวแปรสภาพแวดล้อมมีขอบเขตโพรเซส ตระกูลใดถูกอ่านตัดสินโดยแอป ไม่ใช่ฝั่งการตั้งค่า
fam{"ตระกูลใด?"}
fam --> wininet["ค่าต่อผู้ใช้ของ WinINET"]
fam --> winhttp["ค่าเครื่องของ WinHTTP"]
fam --> env["HTTP_PROXY และพวกพ้อง"]
wininet -.-> r1["เบราว์เซอร์และแอปเดสก์ท็อป"]
winhttp -.-> r2["บริการและบางส่วนของ OS"]
env -.-> r3[".NET Core+ และ curl"]
ภาพ 1: สามตระกูลนั่งเคียงกัน แอปเลือกว่าจะอ่านอันใด
หากเปิดนโยบายกลุ่ม «Make proxy settings per-machine (rather than per-user)» คุณสลับ (1) เป็นต่อเครื่องแล้วใช้ค่าเดียวกันกับทุกผู้ใช้ได้ ด้วย MDM (Intune ฯลฯ) ตั้งต่ออุปกรณ์ด้วย NetworkProxy CSP ได้4
3. WinINET และ WinHTTP — สำหรับแอปโต้ตอบและสำหรับบริการ
3.1. ความต่างของบทบาท
WinINET และ WinHTTP ทั้งคู่เป็นสแตกไคลเอนต์ HTTP ในกล่องของ Windows แต่สมมติการใช้ต่างกัน
- WinINET: มุ่งแอปเดสก์ท็อปโต้ตอบ สืบทอด Internet Options ของผู้ใช้โดยอัตโนมัติ (พร็อกซี คุกกี้ แคชข้อมูลรับรอง) และแสดง UI กรอกข้อมูลรับรองได้หากจำเป็น การใช้ในบริการหรือโพรเซสคล้ายบริการไม่รองรับ1
- WinHTTP: มุ่งบริการและฝั่งเซิร์ฟเวอร์ รองรับการรันภายใต้บัญชีบริการ การสวมตัวเธรด และการแยกเซสชัน แลกกับการไม่แชร์ค่าเบราว์เซอร์ คุกกี้ หรือข้อมูลรับรองของผู้ใช้ และไม่แสดง UI3
คำแนะนำของ Microsoft เองชัดเท่ากัน: «ใช้ WinINET เว้นแต่คุณรันในบริการ หรือในโพรเซสคล้ายบริการที่ต้องการแยกเซสชันและการสวมตัว» — พูดอีกอย่าง ถ้าเป็นบริการ ใช้ WinHTTP1
flowchart TB
accTitle: WinINET สำหรับแอปโต้ตอบ WinHTTP สำหรับบริการ
accDescr: WinINET สืบทอด Internet Options ของผู้ใช้ที่ลงชื่อเข้าใช้ และไม่รองรับในบริการ WinHTTP รันภายใต้บัญชีบริการโดยไม่มี UI และไม่แชร์ค่าเบราว์เซอร์ของผู้ใช้
q{"แอปเดสก์ท็อปโต้ตอบ?"}
q -->|"ใช่"| ie["WinINET"]
q -->|"บริการหรือคล้ายบริการ"| wh["WinHTTP"]
ie -.-> ieNote["อ่าน Internet Options ของผู้ใช้"]
wh -.-> whNote["ค่าเครื่อง ไม่มี UI"]
ภาพ 2: แอปโต้ตอบใช้ WinINET บริการใช้ WinHTTP
3.2. การดำเนินการพื้นฐานของ netsh winhttp
พร็อกซีค่าเริ่มต้นเครื่องของ WinHTTP ดำเนินการด้วย netsh2
:: Display the current WinHTTP proxy settings
netsh winhttp show proxy
:: Set a static proxy (with a bypass list)
netsh winhttp set proxy proxy-server="proxy.example.co.jp:8080" bypass-list="*.example.co.jp;<local>"
:: Import the Internet Options (WinINET) settings
netsh winhttp import proxy source=ie
:: Return to the default (DIRECT)
netsh winhttp reset proxy
ข้อจำกัดสองข้อที่ควรจำที่นี่
netsh winhttp set proxyเป็นค่าสถิต ไม่จัดการการตรวจจับพร็อกซีอัตโนมัติ การระบุ URL PAC หรือการยืนยันตัวตนพร็อกซี4import proxy source=ieคัดลอกค่าสถิต ณ ขณะนั้นเท่านั้น ไม่ตามการเปลี่ยนภายหลังฝั่ง Internet Options เมื่อต้องการการตั้งค่าต่อเครื่องที่รวม PAC หรือการตรวจจับอัตโนมัติ ให้ตั้งค่ารายละเอียดรูป JSON (Proxy,ProxyBypass,AutoconfigUrl,AutoDetect) ด้วยnetsh winhttp set advproxy2
3.3. กับดักที่พบบ่อยที่สุด: บริการไม่อ่านค่า IE ของผู้ใช้
รูปแบบที่เห็นบ่อยที่สุดในไซต์ ตามลำดับเวลา ดูแบบนี้
- นักพัฒนารันเครื่องมือบนพีซีของตน → ค่าพร็อกซีต่อผู้ใช้ (1) มีผลและรันได้
- ในโปรดักชันถูกทิ้งให้ค้างเป็นบริการ Windows (วิธีสร้างและเดินบริการ Windows) ภายใต้ LocalSystem
- ค่าที่เห็นจาก LocalSystem เป็นคนละเรื่อง (ค่าต่อผู้ใช้มองไม่เห็น และค่าเครื่อง WinHTTP ไม่ได้ตั้ง = DIRECT) → พยายามเชื่อมตรงไป API ภายนอกแล้วหมดเวลา
ไม่ใช่ «ไม่รันทั้งที่เป็นเครื่องเดียวกัน» แม้บนเครื่องเดียวกัน บัญชีที่รันต่างกันหมายถึงชุดค่าพร็อกซีที่มองเห็นต่างกัน สำหรับโพรเซสที่สื่อสารแม้ไม่มีผู้ใช้ลงชื่อเข้าใช้ แนวทางที่ถูกคือเตรียมค่าต่อเครื่อง ในรูปที่สแตก HTTP ของโพรเซสนั้นอ่านจริง สำหรับแอปเนทีฟหรือส่วนประกอบ Windows ที่ใช้ WinHTTP ค่า WinHTTP ของ netsh มีผล4 ในทางกลับกัน HttpClient บน .NET (Core เป็นต้นไป) ไม่อ่านค่าเครื่องของ WinHTTP (ดูบทที่ 5) ดังนั้นสำหรับบริการ .NET ให้ตั้งตัวแปรสภาพแวดล้อมระบบ (HTTPS_PROXY ฯลฯ) หรือระบุ HttpClientHandler.Proxy ชัดจากค่าแอป
อุบัติเหตุเกิดอีกทิศด้วย หากคุณอบพร็อกซีสถิตลงแล็ปท็อปที่ย้ายระหว่างเครือข่ายองค์กรกับภายนอกด้วย netsh winhttp set proxy พร็อกซีนั้นเข้าไม่ถึงนอกบริษัทและการสื่อสารตายสนิท ถือค่าสถิตระดับเครื่องเป็นเครื่องมือสำหรับเซิร์ฟเวอร์ที่การตั้งค่าเครือข่ายไม่เปลี่ยน4
flowchart TB
accTitle: ทำไมบริการจึงไม่เห็นค่า IE ของผู้ใช้
accDescr: การรันของนักพัฒนาอ่านค่า WinINET ต่อผู้ใช้และสำเร็จ ในฐานะ LocalSystem ค่านั้นมองไม่เห็น แอป WinHTTP เนทีฟจึงตามค่าเครื่องที่ไม่ได้ตั้ง (DIRECT) บริการ .NET Core+ ยังใช้ตัวแปรสภาพแวดล้อมหรือ handler.Proxy ชัดและไม่สลับไป netsh winhttp
dev["รันด้วยมือในฐานะผู้ใช้"] --> ok["ค่าต่อผู้ใช้ของ WinINET มีผล"]
svc["บริการ Windows ในฐานะ LocalSystem"] --> miss["ค่าต่อผู้ใช้มองไม่เห็น"]
miss --> stack{"สแตก HTTP ใด?"}
stack -->|"WinHTTP"| direct["WinHTTP ไม่ได้ตั้ง = DIRECT"]
stack -->|".NET Core+"| env["ตัวแปรสภาพแวดล้อมหรือ handler.Proxy"]
direct --> fail["API ภายนอกหมดเวลา"]
ภาพ 3: เครื่องเดียวกัน บัญชีต่างกัน ชุดค่าพร็อกซีที่มองเห็นต่างกัน
4. PAC และ WPAD — «การตั้งค่าอัตโนมัติ» คืออะไรจริง ๆ
4.1. ไฟล์ PAC และ FindProxyForURL
ไฟล์ PAC (Proxy Auto-Configuration) คือ JavaScript (ECMAScript) ที่คำนวณ «จะใช้พร็อกซีใดสำหรับ URL นี้» และมีฟังก์ชันชื่อ FindProxyForURL(url, host) เสมอ ฟังก์ชันคืนรายการพร็อกซีที่ควรใช้ หรือค่าคืนพิเศษ (DIRECT) ที่หมายความว่าเชื่อมตรงโดยไม่ใช้พร็อกซีได้5
function FindProxyForURL(url, host) {
// Internal domains and private addresses go direct
if (dnsDomainIs(host, ".example.co.jp") ||
isInNet(host, "10.0.0.0", "255.0.0.0")) {
return "DIRECT";
}
// Everything else goes through a proxy. Fall back to the next if the first is unavailable
return "PROXY proxy1.example.co.jp:8080; PROXY proxy2.example.co.jp:8080; DIRECT";
}
ผลเชิงปฏิบัติสองอย่างตามมา
- ต้องหาพร็อกซีต่อ URL เพราะ PAC คืนพร็อกซีต่างกันหรือเชื่อมตรงตาม URL (โฮสต์) ได้ ฟีเจอร์พร็อกซีอัตโนมัติของ WinHTTP จึงออกแบบให้ส่ง URL คำขอแล้วถามทุกครั้ง6 «เบราว์เซอร์เห็นไซต์อื่นได้» ไม่ใช่หลักฐานว่า API ปัญหาเดินเส้นเดียวกัน
- DIRECT คือคำสั่ง «ไปโดยไม่ใช้พร็อกซี» หากทราฟฟิกที่ควรเป็นภายในไม่เคยปรากฏในล็อกพร็อกซี สงสัยก่อนว่า PAC คืน DIRECT (หรือตรงกับรายการบายพาส)
4.2. การตรวจจับอัตโนมัติผ่าน WPAD
เปิด «Automatically detect settings» แล้วเครื่องจะหาตำแหน่งไฟล์ PAC ด้วยโปรโตคอล WPAD (Web Proxy Auto-Discovery) ในการตั้งค่าแบบทั่วไป DHCP ส่ง URL PAC หรือใช้ DNS หาโฮสต์ชื่อ wpad แล้วดาวน์โหลด PAC จาก URL เช่น http://wpad/wpad.dat14
กล่าวอีกอย่าง «การตรวจจับอัตโนมัติ» ไม่ใช่เวทมนตร์ เป็นกลไกที่ ทำงานเฉพาะบนเครือข่ายที่จัด WPAD ใน DHCP/DNS ไว้แล้ว การเปิดการตรวจจับอัตโนมัติอย่างเดียวบนเครือข่ายที่ไม่มีจัดเช่นนั้นเพียงเพิ่มเวลารอความล้มเหลวของการตรวจจับ
flowchart TB
accTitle: PAC หาพร็อกซีต่อ URL WPAD เพียงหา PAC
accDescr: FindProxyForURL รับ URL และโฮสต์แล้วคืนรายการพร็อกซีหรือ DIRECT WPAD เพียงหา PAC ผ่าน DHCP หรือ DNS ไคลเอนต์ที่ประเมิน PAC ไม่ได้ตกไปพร็อกซีสถิตหรือตัวแปรสภาพแวดล้อม
url["URL คำขอ"] --> pac["FindProxyForURL"]
pac -->|"รายการพร็อกซี"| via["ผ่านพร็อกซี"]
pac -->|"DIRECT"| dir["เชื่อมโดยไม่ใช้พร็อกซี"]
wpad["WPAD ผ่าน DHCP หรือ DNS"] -.-> pac
nopac["ไคลเอนต์ประเมิน PAC ไม่ได้"] -.-> fb["ค่าสถิตหรือตัวแปรสภาพแวดล้อม"]
ภาพ 4: PAC ตัดสินต่อ URL WPAD เพียงหาไฟล์ PAC
4.3. ไคลเอนต์ที่ประเมิน PAC ไม่ได้ประพฤติอย่างไร
ไม่ใช่ทุกไคลเอนต์ประเมิน PAC ได้
- ค่าสถิตของ
netsh winhttp set proxyไม่ประเมิน PAC4 - เครื่องมือที่ใช้สไตล์ตัวแปรสภาพแวดล้อม
HTTP_PROXYโดยทั่วไปเขียนได้แค่ URL พร็อกซีคงที่ (ไม่มีที่เขียน URL PAC)7 - สำหรับแอปเนทีฟที่ใช้ WinHTTP โดยตรง ขึ้นกับว่าเปิดเซสชันอย่างไร แอปที่เปิดด้วย
WinHttpOpenบน Windows 8.1 เป็นต้นไปโดยระบุWINHTTP_ACCESS_TYPE_AUTOMATIC_PROXYให้ WinHTTP หาค่าพร็อกซีระบบ/ผู้ใช้ (รวม WPAD/PAC) ต่อคำขอโดยอัตโนมัติ15 หากเปิดด้วยWINHTTP_ACCESS_TYPE_DEFAULT_PROXYเก่า (เลิกใช้ตั้งแต่ 8.1) หรือคล้ายกัน พร็อกซีอัตโนมัติไม่ถูกรวมเข้าสแตก HTTP และแอปต้องเรียกWinHttpGetProxyForUrlเองแล้วนำผลไปใช้กับคำขอ กล่าวอีกอย่าง บนอิมพลีเมนต์เก่า PAC อาจมีอยู่แล้วยังไม่ถูกใช้5
«เบราว์เซอร์ไปพร็อกซีที่ถูกผ่าน PAC แต่แอปธุรกิจไม่อ่าน PAC แล้วพยายามเชื่อมตรงแล้วล้มเหลว» — นี่คือความไม่ตรงกันหลักอีกแบบ บนเครือข่ายที่เดินด้วย PAC คุณต้องตัดสินทางสำรอง — ค่าสถิตหรือตัวแปรสภาพแวดล้อม — สำหรับไคลเอนต์ที่อ่าน PAC ไม่ได้
5. การหาพร็อกซีของ .NET — Framework กับ Core เป็นต้นไปเป็นคนละเรื่อง
ค่าพร็อกซีที่แอป .NET อ่านต่างกันตามค่าเริ่มต้นระหว่าง .NET Framework กับ .NET (Core เป็นต้นไป) ปนสองอย่างแล้วคุณจะสอบสวนแอป .NET 8 ด้วยความรู้ยุค Framework แล้วพลาด
5.1. .NET Framework — ค่าเริ่มต้นคือ Internet Options ทับด้วย defaultProxy
บน .NET Framework HttpWebRequest และ HttpClient ที่นั่งทับใช้พร็อกซีเริ่มต้นเว้นแต่คุณระบุ Proxy ชัด พร็อกซีเริ่มต้นตัดสินจากชุดของค่าอินเทอร์เน็ตระบบ (ค่า WinINET ของบัญชีที่รัน) กับไฟล์การตั้งค่า และ ค่าไฟล์การตั้งค่ามีลำดับสูงกว่า8
คุณควบคุมค่าเริ่มต้นนี้ด้วยอิลิเมนต์ system.net/defaultProxy ใน app.config (หรือ machine.config)9
<configuration>
<system.net>
<!-- useDefaultCredentials: whether to send default credentials to an authenticating proxy -->
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy usesystemdefault="true"
proxyaddress="http://proxy.example.co.jp:8080"
bypassonlocal="true" />
<bypasslist>
<add address="[a-z]+\.example\.co\.jp$" />
</bypasslist>
</defaultProxy>
</system.net>
</configuration>
ปล่อยอิลิเมนต์ defaultProxy ว่างแล้วใช้ค่าของระบบ (Internet Options) เขียน proxyaddress ฯลฯ แล้วสิ่งนั้นมีลำดับสูงกว่า จากโปรแกรมคุณแทนค่าเริ่มต้นเดียวกันด้วย WebRequest.DefaultWebProxy ได้98
กับดักบทที่ 3.3 ใช้ที่นี่ด้วย เพราะค่าเริ่มต้นคือ «Internet Options ของบัญชีที่รัน» แอป .NET Framework ที่รันภายใต้บัญชีบริการอ่านชุดค่าต่าง (มักว่าง) จากที่เห็นบนเดสก์ท็อปของผู้ดูแล
5.2. .NET (Core เป็นต้นไป) — ตัวแปรสภาพแวดล้อมก่อน แล้วค่าผู้ใช้ของ OS
HttpClient บน .NET (Core เป็นต้นไป) มีพร็อพเพอร์ตีสถิต HttpClient.DefaultProxy เว้นแต่แฮนด์เลอร์ระบุพร็อกซีชัด ทุกอินสแตนซ์ HttpClient ใช้มัน กฎการเริ่มต้นบน Windows คือ «อ่านตัวแปรสภาพแวดล้อม และหากไม่ได้กำหนด ให้อ่านค่าพร็อกซีผู้ใช้»7
ตัวแปรสภาพแวดล้อมที่ใช้มีดังนี้7
| ตัวแปรสภาพแวดล้อม | ความหมาย |
|---|---|
HTTP_PROXY |
พร็อกซีสำหรับคำขอ HTTP |
HTTPS_PROXY |
พร็อกซีสำหรับคำขอ HTTPS |
ALL_PROXY |
สำรองเมื่อข้างบนไม่ได้กำหนด |
NO_PROXY |
รายการโฮสต์คั่นด้วยจุลภาคที่ไม่ควรใช้พร็อกซี |
สามอย่างที่ต้องดู
- หากกำหนด
HTTP_PROXY,HTTPS_PROXYหรือALL_PROXYใดอันหนึ่ง มันจะเหนือกว่าค่าพร็อกซีฝั่ง OS การกำหนดเฉพาะNO_PROXYไม่ตั้งพร็อกซีจากตัวแปรสภาพแวดล้อม และบน Windows ค่าพร็อกซีผู้ใช้ของ OS ยังถูกใช้ต่อไป «ค่าที่มองไม่เห็น» เช่น ทิ้งHTTPS_PROXYเป็นตัวแปรสภาพแวดล้อมระบบหลังทดลองเก่า หรือเทมเพลต CI/CD ฉีดเข้ามา เป็นแหล่งเพาะอุบัติเหตุ NO_PROXYไม่รองรับไวด์การ์ด (*) เพื่อจับโดเมนย่อยใส่จุดนำหน้า (.example.comจับwww.example.comแต่ไม่จับexample.comเอง)7- บนที่ไม่ใช่ Windows (คอนเทนเนอร์ Linux ฯลฯ) หากตัวแปรสภาพแวดล้อมไม่ได้กำหนด จะเริ่มต้น โดยไม่มีพร็อกซี พฤติกรรมเริ่มต้นของแอปเดียวกันที่เปลี่ยนระหว่าง Windows กับ Linux เป็นสิ่งที่ควรยืนยันตอนย้ายคอนเทนเนอร์7
5.3. การระบุชัด — HttpClientHandler.Proxy และ UseProxy
บนรันไทม์ใด ลำดับสูงสุดคือการระบุชัดบนแฮนด์เลอร์ การระบุ HttpClientHandler.Proxy เหนือกว่าค่า OS และไฟล์การตั้งค่า และ UseProxy = false ไม่ใช้พร็อกซีเลย14
using System.Net;
// Use a proxy read from app settings explicitly
var handler = new HttpClientHandler
{
Proxy = new WebProxy("http://proxy.example.co.jp:8080")
{
BypassProxyOnLocal = true,
BypassList = new[] { @"^intra\.example\.co\.jp$" },
UseDefaultCredentials = true // On an authenticating proxy, respond with the running account's credentials
},
UseProxy = true
};
var client = new HttpClient(handler);
// A client that never uses a proxy (for direct internal APIs)
var directHandler = new HttpClientHandler { UseProxy = false };
var directClient = new HttpClient(directHandler);
เมื่อไม่มีการระบุชัดและตามค่า OS การบายพาสปลายทางท้องถิ่นอัตโนมัติมีกฎ ชื่อแบนที่ไม่มีจุด ที่อยู่ลูปแบ็ก ปลายทางที่ตรงกับซัฟฟิกซ์โดเมนของเครื่องเอง ฯลฯ อาจถูกถือเป็น «ท้องถิ่น»14 ปรากฏการณ์เช่น «พฤติกรรมเปลี่ยนถ้าระบุที่อยู่ IP» หรือ «เริ่มผ่านพร็อกซีทันทีเมื่อใช้ FQDN» อาจเกิดจากคำตัดสินนี้
ลำดับความสำคัญมีดังนี้
| ลำดับ (สูง → ต่ำ) | .NET Framework | .NET (Core เป็นต้นไป) |
|---|---|---|
| 1 | การระบุชัดเช่น HttpClientHandler.Proxy |
เหมือนกัน |
| 2 | defaultProxy ใน app.config |
การกำหนดให้ HttpClient.DefaultProxy |
| 3 | Internet Options ของบัญชีที่รัน | ตัวแปรสภาพแวดล้อม (HTTP_PROXY ฯลฯ) |
| 4 | — | ค่าพร็อกซีผู้ใช้ Windows |
flowchart TB
accTitle: การหาพร็อกซีเริ่มต้นใน Framework กับ Core เป็นต้นไป
accDescr: HttpClientHandler.Proxy ชัดชนะเสมอ Framework แล้วใช้ app.config defaultProxy และ Internet Options ของบัญชีที่รัน Core เป็นต้นไปใช้การกำหนด HttpClient.DefaultProxy แล้วตัวแปรสภาพแวดล้อม แล้วค่าพร็อกซีผู้ใช้ Windows
expl["handler.Proxy ชัด"] --> done["ใช้พร็อกซีนั้น"]
noexpl["ไม่มี Proxy ชัด"] --> fw{"รันไทม์ใด?"}
fw -->|"Framework"| cfg["app.config defaultProxy"]
cfg --> ie["Internet Options ของบัญชีที่รัน"]
fw -->|"Core เป็นต้นไป"| dp["HttpClient.DefaultProxy"]
dp --> ev["HTTP_PROXY และพวกพ้อง"]
ev --> user["ค่าพร็อกซีผู้ใช้ Windows"]
ภาพ 5: การระบุชัดชนะเสมอ เส้นทางเริ่มต้นต่างตามรันไทม์
6. พร็อกซียืนยันตัวตน — 407 คือข้อผิดพลาดยืนยันตัวตนของพร็อกซี
6.1. อย่าปน 407 กับ 401
เมื่อคุณพยายามผ่านพร็อกซีที่ขอการยืนยันตัวตน พร็อกซีคืนรหัสสถานะ 407 (Proxy Authentication Required) และส่วนหัว Proxy-Authenticate ที่รายการสคีมาที่ใช้ได้ นั่นต่างจากคำขอการยืนยันตัวตนของเซิร์ฟเวอร์ปลายทาง (401 และ WWW-Authenticate) ทั้งฝ่ายที่คุณส่งข้อมูลรับรองและที่ตั้งค่าต่างกัน10
flowchart TB
accTitle: 407 คือพร็อกซี 401 คือเซิร์ฟเวอร์ปลายทาง
accDescr: 407 และ Proxy-Authenticate มาจากพร็อกซี 401 และ WWW-Authenticate มาจากเซิร์ฟเวอร์ปลายทาง ข้อมูลรับรองและที่ตั้งค่าต่างกัน
req["คำขอขาออก"] --> who{"ใครขอการยืนยันตัวตน?"}
who -->|"พร็อกซี"| e407["407 + Proxy-Authenticate"]
who -->|"ปลายทาง"| e401["401 + WWW-Authenticate"]
e407 -.-> cred["DefaultProxyCredentials"]
ภาพ 6: 407 คือการยืนยันตัวตนพร็อกซี 401 คือการยืนยันตัวตนเซิร์ฟเวอร์
สคีมามี Basic ที่ส่งชื่อผู้ใช้และรหัสผ่านตามที่เป็น และสคีมาท้าทาย/ตอบเช่น Negotiate (Kerberos/NTLM) ในสคีมาท้าทาย/ตอบ รหัสผ่านเองไม่เดินทางบนเครือข่าย และการยืนยันตัวตนเสร็จในหลายรอบแลกเปลี่ยน10 กลไกว่า «ตก» ไปสคีมาใดมีรายละเอียดใน «NTLM และ Kerberos อธิบายด้วยแผนภาพ»
6.2. วิธีส่งข้อมูลรับรองใน .NET
เมื่อต้องการใช้พร็อกซีเริ่มต้นที่มาจากค่า OS และให้ผ่านเฉพาะการยืนยันตัวตน ใช้ HttpClientHandler.DefaultProxyCredentials นี่คือข้อมูลรับรองที่ส่งไปยังพร็อกซีเริ่มต้นนั้นเมื่อ UseProxy = true และ Proxy = null (= พร็อกซีเริ่มต้นของระบบ)11
using System.Net;
var handler = new HttpClientHandler
{
UseProxy = true, // The default. Combined with a null Proxy, this uses the system-default proxy
Proxy = null,
// Respond to 407 with the credentials of the running account (signed-in user or service account)
DefaultProxyCredentials = CredentialCache.DefaultCredentials
};
var client = new HttpClient(handler);
เมื่อระบุพร็อกซีชัด วางข้อมูลรับรองฝั่ง WebProxy ในหลายสถานการณ์ไคลเอนต์คำแนะนำคือใช้ ข้อมูลรับรองเริ่มต้นของผู้ใช้ที่ลงชื่อเข้าใช้ แทนชื่อผู้ใช้และรหัสผ่านรายบุคคล และ WebProxy.UseDefaultCredentials = true คือสิ่งนั้น12
6.3. ปัญหา 407 ของบัญชีบริการ
บัญชีที่รันสำคัญที่นี่ด้วย «ข้อมูลรับรองเริ่มต้น» หมายถึง ข้อมูลรับรองของบัญชีที่กำลังรันโพรเซสนั้น รันเป็นผู้ใช้โต้ตอบแล้วการยืนยันตัวตนกับพร็อกซีเป็นผู้ใช้นั้น รันเป็นบริการ LocalSystem แล้วเป็นบัญชีคอมพิวเตอร์
- หากพร็อกซียืนยันตัวตนผู้ใช้ผ่าน Active Directory มันยืนยันบัญชีคอมพิวเตอร์หรือบัญชีท้องถิ่นไม่ได้ และ 407 ต่อเนื่องทันทีที่ทำให้แอปเป็นบริการ
- ในทางกลับกัน บางสภาพแวดล้อมมีการยกเว้นการยืนยันตัวตนฝั่งพร็อกซีสำหรับบริการ (ตาม IP ต้นทางหรือตามบัญชี)
ดังนั้นการสอบสวน 407 ไม่จบที่ «ค่าของแอป» อย่างเดียว เป็นชุดกับการตรวจออกแบบฝั่งโครงสร้างพื้นฐาน: พร็อกซียืนยันบัญชีที่รันได้หรือไม่ สำหรับแอปที่จะทำให้เป็นบริการ ควรตัดสินตอนออกแบบอย่างใดอย่างหนึ่ง: รันภายใต้บัญชีบริการโดเมน (gMSA ฯลฯ) ยกเว้นการยืนยันตัวตนฝั่งพร็อกซี หรือตั้งพร็อกซีรีเลย์ภายในที่ไม่ต้องยืนยันตัวตน
ยังมีสไตล์ฝังข้อมูลรับรองในตัวแปรสภาพแวดล้อม เช่น HTTP_PROXY=http://user:pass@proxy:80807 แต่รหัสผ่านข้อความชัดจะเปิดในตัวแปรสภาพแวดล้อม (= ข้อมูลโพรเซส) จึงไม่แนะนำสำหรับการเดินงานประจำ
7. HTTPS และพร็อกซี — อุโมงค์ CONNECT และการตรวจ TLS
7.1. HTTPS ผ่านพร็อกซีเป็น «อุโมงค์»
เมื่อใช้พร็อกซีกับ HTTPS ไคลเอนต์ส่งคำขอ CONNECT destination-host:443 ไปยังพร็อกซีก่อน และพร็อกซีเปิดอุโมงค์ TCP สำเร็จแล้วพร็อกซีคืน 200 จากนั้นไคลเอนต์และเซิร์ฟเวอร์ปลายทางทำแฮนด์เชค TLS ในอุโมงค์นั้น หากอุโมงค์ไม่เปิด พร็อกซีคืน 407 (ต้องยืนยันตัวตน) 502 ฯลฯ16
ในโมเดลนี้พร็อกซีอ่านเนื้อหาในอุโมงค์ (HTTPS เข้ารหัส) ไม่ได้ สิ่งที่เหลือในล็อกพร็อกซีคือชื่อโฮสต์ปลายทางและการเชื่อมสำเร็จหรือไม่ เส้นทาง URL มองไม่เห็น — นั่นคือพฤติกรรมของพร็อกซี «ผ่านตรง»
flowchart TB
accTitle: HTTPS ผ่านพร็อกซีคืออุโมงค์ CONNECT
accDescr: ไคลเอนต์ส่ง CONNECT ไปยังพร็อกซี พร็อกซีเปิดอุโมงค์ TCP แล้วคืน 200 จากนั้นไคลเอนต์และปลายทางทำแฮนด์เชค TLS ในอุโมงค์ ล็อกพร็อกซีเห็นโฮสต์ ไม่เห็นเส้นทาง URL
cli["ไคลเอนต์"] -->|"CONNECT host:443"| px["พร็อกซี"]
px -->|"200 และอุโมงค์ TCP"| dest["ปลายทาง"]
dest -->|"TLS ในอุโมงค์"| cli
px -.-> log["ล็อก: เฉพาะโฮสต์และความสำเร็จ"]
ภาพ 7: พร็อกซีผ่านตรงเห็นโฮสต์ ไม่เห็นเส้นทางที่เข้ารหัส
7.2. พร็อกซีตรวจ TLS และข้อผิดพลาดใบรับรอง
ในทางกลับกัน พร็อกซีผลิตภัณฑ์ความปลอดภัยมีชนิด ตรวจ TLS (ถอดรหัส SSL, break and inspect) ที่ยุติ TLS ตรวจเนื้อหา แล้วเข้ารหัสใหม่ก่อนส่งต่อ ในสคีมานี้ใบรับรองเซิร์ฟเวอร์ที่เสนอให้ไคลเอนต์ไม่ใช่ของจริง ถูกแทนด้วยใบรับรองที่ CA ของพร็อกซีลงนามใหม่13
ข้อสมมติที่ทำให้การตั้งค่านี้ยืนได้จึงคือ «ใบรับรอง CA ของพร็อกซีถูกแจกจ่ายไปยังรากที่เชื่อถือของทุกไคลเอนต์» บนเครื่องที่ยังไม่ได้รับ หรือใน รันไทม์ที่ไม่ดูที่เก็บใบรับรอง Windows (เครื่องมือที่มีที่เก็บความเชื่อถือของตนเอง) คุณได้ข้อผิดพลาดตรวจสอบใบรับรอง ใน .NET มักปรากฏเป็น HttpRequestException ที่ห่อ AuthenticationException (ข้อความแบบ «the remote certificate is invalid»)
หลักการแก้มีดังนี้
- แจกจ่ายใบรับรอง CA ภายในไปยังที่เก็บ «Trusted Root Certification Authorities» ของเครื่องท้องถิ่น การแยกระหว่างที่เก็บผู้ใช้กับที่เก็บเครื่องอยู่ใน «ที่เก็บใบรับรอง Windows ในทางปฏิบัติ»
- อย่าปิดการตรวจสอบใบรับรองในโค้ด วิธีแก้ที่คืน true เสมอจาก
ServerCertificateCustomValidationCallbackกลายเป็นแอปที่เปราะซึ่งตรวจจับคนกลางไม่ได้ทันทีที่ออกสู่เครือข่ายภายนอก - ทราฟฟิกที่ปักใบรับรองตรวจไม่ได้ตั้งแต่แรก การเชื่อมที่ตรวจใบรับรอง Microsoft เฉพาะเจาะจงอย่างที่บางส่วนประกอบ Windows ทำ จะล้มเหลวทันทีที่พร็อกซีสลับใบรับรอง และไม่มีทางแก้ นอกจากการยกเว้น4 สำหรับทราฟฟิกมุ่ง SaaS เช่น Microsoft 365 Microsoft เองแนะนำให้ยกเว้นจากการถอดรหัสและตรวจที่ชั้นเครือข่าย13
อาการ «เห็นทุกไซต์ภายใน แต่มีแค่บริการคลาวด์เฉพาะที่เกิดข้อผิดพลาดใบรับรองในแอป» ควรให้สงสัยชุดของรายการยกเว้นการตรวจ TLS กับการปักก่อน
flowchart TB
accTitle: พร็อกซีตรวจ TLS ลงนามใบรับรองใหม่
accDescr: พร็อกซียุติ TLS ตรวจเนื้อหา และเสนอใบรับรองที่ CA ของมันลงนามใหม่ การตรวจสอบยืนได้เฉพาะเมื่อ CA นั้นอยู่ในรากที่เชื่อถือ อย่าปิดการตรวจสอบในโค้ด
real["ใบรับรองเซิร์ฟเวอร์จริง"] --> px["พร็อกซีตรวจ TLS"]
px --> fake["ลงนามใหม่โดย CA ของพร็อกซี"]
fake --> client["การตรวจสอบของไคลเอนต์"]
client -->|"CA อยู่ในรากที่เชื่อถือ"| ok["สำเร็จ"]
client -->|"ไม่มี CA"| err["ข้อผิดพลาดใบรับรอง"]
err -.-> fix["แจกจ่าย CA ไปที่เก็บ"]
ภาพ 8: การตรวจทำงานได้เฉพาะเป็นชุดกับการแจกจ่าย CA ภายใน
8. ขั้นตอนแยกปัญหา — ห้าขั้นระบุตัวการ
สอบสวน «ต่อไม่ได้» อย่างเครื่องกลในลำดับนี้
| ขั้น | สิ่งที่คุณทำ | สิ่งที่คุณได้รู้ |
|---|---|---|
| (1) ทำซ้ำ | เข้า URL ปัญหาด้วย curl.exe -v หรือ Invoke-WebRequest (ควรบนเครื่องเดียวกัน ภายใต้บัญชีเดียวกัน) |
เป็นปัญหาเฉพาะแอปหรือปัญหาสภาพแวดล้อม |
| (2) เก็บค่า | เก็บสามตระกูล: netsh winhttp show proxy ค่าต่อผู้ใช้ และตัวแปรสภาพแวดล้อม |
มีอะไรในตระกูลใด |
| (3) ระบุบัญชี | ระบุบัญชีที่รันของแอปเป้าหมาย (บริการ ตัวจัดตารางงาน ผู้ใช้อื่น) | รันภายใต้ค่าใดและข้อมูลรับรองใด |
| (4) จัดประเภทข้อผิดพลาด | แยก 407 / 403 / หาชื่อล้มเหลว / หมดเวลา / ข้อผิดพลาดใบรับรอง | แยกการยืนยันตัวตนพร็อกซี การปฏิเสธนโยบาย เส้นทาง และการตรวจ TLS |
| (5) ล็อกพร็อกซี | ตรวจเวลาที่ตรงในล็อกเข้าถึงของเซิร์ฟเวอร์พร็อกซี | ไปถึงพร็อกซีหรือไม่ และยืนยันตัวตนในฐานะใคร |
คุณเก็บ (2) ได้ในครั้งเดียวด้วย PowerShell
# (1) Per-user (WinINET) settings — note that this reads HKCU of the running account
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' |
Select-Object ProxyEnable, ProxyServer, ProxyOverride, AutoConfigURL
# (2) Machine (WinHTTP) settings
netsh winhttp show proxy
# (3) Environment variables
Get-ChildItem env: | Where-Object Name -match 'proxy'
เคล็ดลับเชิงปฏิบัติสองสามข้อ
- ในการทดสอบทำซ้ำของ (1) รู้ว่าเครื่องมืออ่านตระกูลค่าใด
curl.exeในกล่องของ Windows ระบุพร็อกซีชัดด้วย-x http://proxy:8080ได้ และสำหรับการตรวจสอบ TLS โดยปกติใช้ที่เก็บใบรับรองของ OS (Schannel)Invoke-WebRequestของ Windows PowerShell 5.1 ตามฝั่ง .NET Framework (Internet Options ตามค่าเริ่มต้น) PowerShell 7 ตามฝั่ง .NET (ตัวแปรสภาพแวดล้อมก่อน) «curl รันได้แต่แอปไม่ได้» เองเป็นคำใบ้ของการไม่ตรงกันระหว่างตระกูลการตั้งค่า - หากเป้าหมายใน (3) เป็นบริการ ตรวจ (1) และ (2) อีกครั้งภายใต้บัญชีเดียวกับบริการ การตรวจในเซสชันของผู้ดูแลเองไม่ใช่หลักฐานว่า LocalSystem เห็นอะไร
- ในการจัดประเภทข้อผิดพลาดของ (4) เอาบทที่ 6 (การยืนยันตัวตน) เป็นผู้สมัครแรกสำหรับ 407 บทที่ 7 (การตรวจ TLS) สำหรับข้อผิดพลาดใบรับรอง และ «ยังไม่ถึงพร็อกซี» (เส้นทาง การหาชื่อ ไฟร์วอลล์) สำหรับหมดเวลา รูปแบบที่สาเหตุเป็นกฎขาเข้าของ Windows Firewall มากกว่าพร็อกซีอยู่ใน «ไฟร์วอลล์ Windows และแอปพลิเคชันธุรกิจ»
- หากไปถึง (5) แล้วยังไม่มีร่องรอยในล็อกพร็อกซี ทราฟฟิกไม่เคยถึงพร็อกซี สงสัยคำตัดสิน DIRECT ของ PAC รายการบายพาส หรือตัวแปรสภาพแวดล้อมที่เหลือ และหากจำเป็นยืนยันปลายทางจริงด้วยการจับแพ็กเก็ต («การจับแพ็กเก็ตบน Windows ในทางปฏิบัติ — เลือก pktmon, netsh trace และ Wireshark»)
flowchart TB
accTitle: ห้าขั้นแยกความล้มเหลวของพร็อกซี
accDescr: ทำซ้ำภายใต้บัญชีเดียวกัน เก็บสามตระกูลค่า ระบุบัญชีที่รัน จัดประเภทข้อผิดพลาด แล้วตรวจล็อกพร็อกซี
s1["ทำซ้ำด้วย curl"] --> s2["เก็บสามตระกูล"]
s2 --> s3["ระบุบัญชี"]
s3 --> s4["จัดประเภทข้อผิดพลาด"]
s4 --> s5["ตรวจล็อกพร็อกซี"]
s4 -.-> e407["407: การยืนยันตัวตน"]
s4 -.-> ecert["ข้อผิดพลาดใบรับรอง: การตรวจ"]
s4 -.-> eto["หมดเวลา: ไม่เคยถึง"]
ภาพ 9: เดินห้าขั้นตามลำดับ ชั้นข้อผิดพลาดเลือกบทถัดไป
9. คำแนะนำการออกแบบ — ทำให้แอปเป็นแอปที่ «ตั้งพร็อกซีได้»
พลิกขั้นตอนสอบสวนแล้วมันกลายเป็นแนวทางการออกแบบฝั่งแอป สำหรับแอป Windows ที่จะส่งเข้าสภาพแวดล้อมที่มีพร็อกซีองค์กร สิ่งต่อไปนี้เป็นคำแนะนำ
- ทำให้พร็อกซีตั้งค่าได้จากค่าแอป ค่าเริ่มต้นคือ «ตามค่า OS» ในสภาพแวดล้อมส่วนใหญ่ค่าเริ่มต้นพอ ในสภาพแวดล้อมพิเศษเท่านั้น — อ่าน PAC ไม่ได้ รันเป็นบริการ การตั้งค่าพร็อกซีพิเศษ — ให้ระบุ URL พร็อกซี รายการบายพาส และ «ไม่ใช้พร็อกซี» จากไฟล์การตั้งค่าได้ จุดอิมพลีเมนต์คือ
HttpClientHandler.Proxy/UseProxyในหัวข้อ 5.314 - เขียนว่าปลายทางภายใน (API ฐานข้อมูล เซิร์ฟเวอร์ใบอนุญาต ฯลฯ) ถูกปฏิบัติเป็นข้อยกเว้นพร็อกซีอย่างไร ใส่ในรูปที่เขียนลงขั้นตอนการปรับใช้ได้ว่าถูกยกเว้นด้วย PAC DIRECT รายการบายพาส หรือ
NO_PROXYกฎการจับของNO_PROXY(ไม่มีไวด์การ์ด จุดนำหน้าหมายความว่าอะไร) ถูกเข้าใจผิดกว้าง จึงแนบตัวอย่าง7 - ออกแบบหมดเวลาและการลองใหม่บนสมมติฐานว่าผ่านพร็อกซี หากพร็อกซีล่มหรือติดที่การยืนยันตัวตน อิมพลีเมนต์ที่รอหมดเวลาเริ่มต้นยาวจะแช่ทั้ง UI และการปฏิบัติการ แยกหมดเวลาการเชื่อมที่สั้นกว่า และจำกัดการลองใหม่เฉพาะคำขอที่ทำซ้ำได้โดยไม่เปลี่ยนผล (รายละเอียดการออกแบบอยู่ใน «อย่าห่อ HttpClient ในบล็อก using»)
- ล็อก «ใช้พร็อกซีใด» ให้แอปเองตอบคำถามแรกของการสอบสวนความล้มเหลวได้
ล็อกอย่างใน (4) มีผลแล้วหากบันทึกแค่ผลของการหา จุดคือ อนุมานเส้นทางจากค่า (แฮนด์เลอร์) ที่คุณใช้ตั้งค่าไคลเอนต์จริง หากล็อก HttpClient.DefaultProxy โดยตรง คุณจะบันทึกค่าที่ไม่ตรงกับเส้นทางจริงเมื่อแฮนด์เลอร์ระบุ Proxy ชัดหรือตั้ง UseProxy = false
using System.Net.Http;
// handler is the same instance used to create the HttpClient
// UseProxy=false is always direct. An explicit specification wins; otherwise DefaultProxy is used
var effectiveProxy = handler.UseProxy
? handler.Proxy ?? HttpClient.DefaultProxy
: null;
var target = new Uri("https://api.example.com/v1/orders");
var route = effectiveProxy is null || effectiveProxy.IsBypassed(target)
? "DIRECT"
: effectiveProxy.GetProxy(target)?.ToString() ?? "DIRECT";
logger.LogInformation("HTTP send {Target} route {Route} account {User}",
target, route, Environment.UserName);
หากตอนเริ่มต้นคุณบันทึกครั้งหนึ่ง «เส้นทาง» และ «บัญชีที่รัน» สำหรับปลายทางหลัก ขั้น (1) ถึง (3) ของบทที่ 8 จบเพียงอ่านล็อก เมื่อถูกบอกว่า «รันได้ในเบราว์เซอร์ แต่…» การพูดจากฝั่งแอปได้ว่า «ฉันใช้ค่านี้ และเส้นทางนี้» คือเงื่อนไขของแอปที่แข็งต่อปัญหาพร็อกซี
flowchart TB
accTitle: ทำให้พร็อกซีตั้งค่าได้และล็อกเส้นทาง
accDescr: ค่าเริ่มต้นตามค่า OS อนุญาต URL พร็อกซีชัดหรือบายพาสหรือไม่ใช้พร็อกซีจากค่าแอป และล็อกเส้นทางที่ใช้จริงพร้อมบัญชีที่รัน
def["ค่าเริ่มต้น: ตามค่า OS"] --> exc{"สภาพแวดล้อมพิเศษ?"}
exc -->|"อ่าน PAC ไม่ได้ / บริการ / พิเศษ"| cfg["ตั้ง URL บายพาส หรือไม่ใช้พร็อกซี"]
exc -->|"กรณีทั่วไป"| os["ใช้ค่าเริ่มต้นของ OS"]
cfg --> log["ล็อกเส้นทางและบัญชี"]
os --> log
ภาพ 10: ตั้งค่าเมื่อจำเป็น ล็อกเสมอว่าใช้เส้นทางใด
10. สรุป
- ค่าพร็อกซี Windows แยกเป็นสามตระกูล — ค่าต่อผู้ใช้ของ WinINET ค่าเครื่องของ WinHTTP และตัวแปรสภาพแวดล้อม — และอันใดถูกอ่านตัดสินโดยแอป (สแตก HTTP) และบัญชีที่รัน
- WinINET สำหรับแอปโต้ตอบและไม่รองรับการใช้ในบริการ การใช้บริการเป็นงานของ WinHTTP (
netsh winhttp) สำหรับ «รันด้วยมือได้แต่ไม่เป็นบริการ» สงสัยความต่างของบัญชีที่รันก่อน netsh winhttp set proxyเป็นค่าสถิตและไม่จัดการ PAC การตรวจจับอัตโนมัติ หรือการยืนยันตัวตน บนเครือข่ายที่เดินด้วย PAC คุณต้องตัดสินว่าไคลเอนต์ที่อ่าน PAC ไม่ได้จะถูกปฏิบัติอย่างไรFindProxyForURLของ PAC คืนพร็อกซีหรือ DIRECT ต่อ URL WPAD ทำงานเฉพาะบนเครือข่ายที่มีการจัด DHCP/DNS- ค่าเริ่มต้นของ .NET Framework คือ Internet Options ของบัญชีที่รัน (ทับด้วย
defaultProxy) .NET (Core เป็นต้นไป) คือตัวแปรสภาพแวดล้อมแล้วค่าพร็อกซีผู้ใช้ การระบุชัด (HttpClientHandler.Proxy) มีลำดับสูงสุดเสมอ - 407 เป็นข้อผิดพลาดยืนยันตัวตนพร็อกซี ในแอปที่รันภายใต้บัญชีบริการสาเหตุคลาสสิกคือ «ข้อมูลรับรองเริ่มต้น» กลายเป็นคนละคน
- พร็อกซีตรวจ TLS สมมติการแจกจ่ายใบรับรอง CA ภายใน และคำตอบที่ถูกต่อข้อผิดพลาดใบรับรองคือการแจกจ่ายไปที่เก็บ ไม่ใช่ปิดการตรวจสอบ ทราฟฟิกที่ปักต้องการการยกเว้น
- แยกอย่างเครื่องกลในลำดับ «ทำซ้ำ → เก็บสามตระกูลค่า → ระบุบัญชีที่รัน → จัดประเภทข้อผิดพลาด → ล็อกพร็อกซี» ฝั่งแอป การออกแบบที่ «ตั้งพร็อกซีได้ และล็อกเส้นทางที่ใช้» คือการป้องกันที่ดีที่สุด
ครั้งถัดไปที่ถูกปรึกษาว่า «มีแค่แอปธุรกิจที่ต่อไม่ได้» ถามนี้ก่อน
แอปนั้นรันภายใต้บัญชีของใคร และอ่านตระกูลใดในสามตระกูลค่าพร็อกซี
คำถามเดียวเปลี่ยนทางเข้าของการสอบสวนมาก
บทความที่เกี่ยวข้อง
- อย่าห่อ HttpClient ในบล็อก using — การสื่อสาร HTTP เชิงปฏิบัติในแอปธุรกิจ C# (รูปแบบการสร้าง หมดเวลา การลองใหม่)
- การจับแพ็กเก็ตบน Windows ในทางปฏิบัติ — เลือก pktmon, netsh trace และ Wireshark
- ไฟร์วอลล์ Windows และแอปพลิเคชันธุรกิจ — ลงทะเบียนกฎขาเข้าจากตัวติดตั้ง
- วิธีสร้างและเดินบริการ Windows ── จากการเลือกระหว่างตัวจัดตารางงานกับบริการ ถึงการทำให้ BackgroundService เป็นบริการ Windows
- NTLM และ Kerberos อธิบายด้วยแผนภาพ — ทำไมการยืนยันตัวตนจึงตกไป NTLM
- ที่เก็บใบรับรอง Windows ในทางปฏิบัติ — ผู้ใช้หรือเครื่อง ควรใช้อันใด
ด้านให้คำปรึกษาที่เกี่ยวข้อง
KomuraSoft LLC รับการสอบสวนปัญหาการสื่อสารของแอป Windows บนสภาพแวดล้อมพร็อกซีองค์กร พร็อกซียืนยันตัวตน และการตรวจ TLS — «รันบนเครื่องพัฒนาแต่สื่อสารไม่ได้บนเครือข่ายลูกค้า» «หลังทำให้เป็นบริการแล้วไปไม่ถึง API ภายนอก» — และให้คำปรึกษาการออกแบบการสื่อสารของแอปธุรกิจที่สมมติสภาพแวดล้อมพร็อกซี (รายการตั้งค่า หมดเวลา การออกแบบล็อก) เริ่มจากจัดขั้นตอนการทำซ้ำและวิธีเก็บล็อกได้
ลิงก์อ้างอิง
-
Microsoft Learn, WinINet vs. WinHTTP. เกี่ยวกับคำแนะนำให้ใช้ WinINET เว้นแต่คุณอยู่ในบริการหรือโพรเซสที่ต้องการการสวมตัวและการแยกเซสชัน และเกี่ยวกับตารางเปรียบเทียบฟีเจอร์ที่ครอบคลุมแคชข้อมูลรับรอง คำเตือนข้อมูลรับรอง การรองรับบริการ การสวมตัว การแยกเซสชัน และคล้ายกัน ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, netsh winhttp. เกี่ยวกับไวยากรณ์ของ netsh winhttp show/set/import/reset proxy-server และ bypass-list ของ set proxy import proxy source=ie และค่าพร็อกซีรายละเอียดรูป JSON (Proxy, ProxyBypass, AutoconfigUrl, AutoDetect) ผ่าน set advproxy ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, About WinHTTP. เกี่ยวกับ WinHTTP เป็นสแตก HTTP ที่ออกแบบสำหรับการใช้บริการและฝั่งเซิร์ฟเวอร์ รองรับการทำงานภายใต้บัญชีบริการและการสวมตัว และไม่แชร์คุกกี้ แคช ข้อมูลรับรองของเบราว์เซอร์ หรือ Internet Options ของผู้ใช้ ↩ ↩2 ↩3
-
Microsoft Learn, Using a proxy with Delivery Optimization. เกี่ยวกับ netsh winhttp set proxy เป็นค่าสถิตที่ไม่รองรับการตรวจจับอัตโนมัติ URL PAC หรือการยืนยันตัวตนพร็อกซี การตั้งค่าพร็อกซีต่ออุปกรณ์สำหรับบริบทที่ไม่มีผู้ใช้ลงชื่อเข้าใช้ (NetworkProxy CSP นโยบาย «Make proxy settings per-machine») และทราฟฟิกที่ปักใบรับรองล้มเหลวภายใต้การตรวจ TLS และต้องการการยกเว้น ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10
-
Microsoft Learn, WinHTTP AutoProxy Support. เกี่ยวกับสคริปต์ PAC ที่มีฟังก์ชัน FindProxyForURL(url, host) คำนวณรายการพร็อกซีต่อคำขอและระบุการเชื่อมตรงด้วยค่าคืนพิเศษ และเกี่ยวกับ API AutoProxy เก่าที่ไม่รวมพร็อกซีอัตโนมัติเข้าสแตก HTTP โดยอัตโนมัติ จึงต้องให้แอปเรียก WinHttpGetProxyForUrl ↩ ↩2 ↩3
-
Microsoft Learn, WinHttpGetProxyForUrl function. เกี่ยวกับเป็นอิมพลีเมนต์ของโปรโตคอล WPAD ต้องเรียกต่อ URL เพราะไฟล์ PAC คืนพร็อกซีต่างกันต่อ URL ได้ และรองรับทั้ง URL PAC ชัดและการตรวจจับอัตโนมัติจากเครือข่าย ↩ ↩2
-
Microsoft Learn, HttpClient.DefaultProxy Property. เกี่ยวกับ Windows อ่านตัวแปรสภาพแวดล้อม HTTP_PROXY, HTTPS_PROXY, ALL_PROXY และ NO_PROXY ก่อน และหากไม่ได้กำหนด อ่านค่าพร็อกซีผู้ใช้ Linux เริ่มต้นโดยไม่มีพร็อกซีหากไม่มีตัวแปรสภาพแวดล้อม NO_PROXY ไม่รองรับไวด์การ์ดและใช้การจับโดเมนย่อยด้วยจุดนำหน้า และ URL พร็อกซีรวมชื่อผู้ใช้และรหัสผ่านได้ ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
-
Microsoft Learn, Configuring Internet Applications. เกี่ยวกับอิลิเมนต์ defaultProxy นิยามพร็อกซีเริ่มต้นบน .NET Framework HttpWebRequest ที่ไม่มีพร็อพเพอร์ตี Proxy ใช้พร็อกซีเริ่มต้น และค่าอินเทอร์เน็ตระบบกับค่าไฟล์การตั้งค่าถูกรวมโดยฝั่งไฟล์การตั้งค่ามีลำดับสูงกว่า ↩ ↩2 ↩3
-
Microsoft Learn, defaultProxy element (network settings). เกี่ยวกับแอตทริบิวต์ enabled และ useDefaultCredentials ของอิลิเมนต์ system.net/defaultProxy อิลิเมนต์ลูก proxy, bypasslist และ module การใช้ค่าพร็อกซีของระบบหากอิลิเมนต์ว่าง และการตั้งค่าด้วย HttpClient.DefaultProxy เมื่อย้ายไป .NET 6 เป็นต้นไป ↩ ↩2 ↩3
-
Microsoft Learn, Authentication in WinHTTP. เกี่ยวกับรหัสสถานะ 407 และส่วนหัว Proxy-Authenticate ที่ถูกคืนเมื่อต้องยืนยันตัวตนพร็อกซี (การยืนยันตัวตนเซิร์ฟเวอร์คือ 401 และ WWW-Authenticate) ความต่างระหว่างการยืนยันตัวตน Basic กับสคีมาท้าทาย/ตอบเช่น Kerberos และสคีมาท้าทาย/ตอบหมายความว่าชื่อผู้ใช้และรหัสผ่านไม่เดินทางบนเครือข่าย ↩ ↩2 ↩3
-
Microsoft Learn, HttpClientHandler.DefaultProxyCredentials Property. เกี่ยวกับพร็อพเพอร์ตีที่ตั้งข้อมูลรับรองที่ใช้ยืนยันตัวตนกับพร็อกซีเริ่มต้นเมื่อ UseProxy เป็น true และ Proxy เป็น null เพื่อใช้พร็อกซีเริ่มต้นของระบบ ↩ ↩2
-
Microsoft Learn, WebProxy.Credentials Property. เกี่ยวกับพร็อพเพอร์ตี Credentials เป็นข้อมูลรับรองที่ส่งไปยังพร็อกซีเพื่อตอบ HTTP 407 และคำแนะนำในหลายสถานการณ์ไคลเอนต์ให้ตั้ง UseDefaultCredentials เป็น true เพื่อใช้ข้อมูลรับรองเริ่มต้นของผู้ใช้ที่ลงชื่อเข้าใช้ ↩ ↩2
-
Microsoft Learn, Understanding implications when using network intermediation to decrypt or manipulate Microsoft 365 traffic at the network layer. เกี่ยวกับการตรวจ TLS (ถอดรหัส SSL) เป็นการตั้งค่าที่พร็อกซีหรือไฟร์วอลล์ถอดรหัส ตรวจ และเข้ารหัส TLS ใหม่ สามารถทำให้บริการที่สมมติ TLS ปลายทางถึงปลายทางทำงานผิดและประสิทธิภาพลด และคำแนะนำให้ยกเว้นทราฟฟิกมุ่ง Microsoft 365 จากการถอดรหัสและตรวจที่ชั้นเครือข่าย ↩ ↩2 ↩3
-
Microsoft Learn, Make HTTP requests with the HttpClient class. เกี่ยวกับสองวิธีตั้งค่า HttpClient.DefaultProxy และ HttpClientHandler.Proxy การระบุ Proxy มีลำดับสูงกว่าไฟล์การตั้งค่าและค่าเครื่องท้องถิ่น การตั้งค่า WPAD แบบทั่วไปที่รับไฟล์ PAC (wpad.dat ฯลฯ) ผ่านชื่อ DNS wpad หรือ DHCP และการตัดสินบายพาสปลายทางท้องถิ่นด้วยชื่อแบน ลูปแบ็ก และการจับซัฟฟิกซ์โดเมน ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, WinHttpOpen function. เกี่ยวกับความหมายของแต่ละค่า dwAccessType WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY (Windows 8.1 เป็นต้นไป) ตัดสินพร็อกซีจากค่าพร็อกซีระบบ/ผู้ใช้โดยอัตโนมัติและจัดการเฟลโอเวอร์กับการยืนยันตัวตนโดยอัตโนมัติด้วย และ WINHTTP_ACCESS_TYPE_DEFAULT_PROXY ถูกเลิกใช้ตั้งแต่ 8.1 ↩
-
Microsoft Learn, Work with existing on-premises proxy servers. เกี่ยวกับ HTTPS ขาออกถูกสร้างด้วยคำขอ CONNECT ไปยังพร็อกซี ความสำเร็จคืน HTTP 200 และการตอบเช่น 407 (ต้องยืนยันตัวตน) หรือ 502 บ่งว่าพร็อกซีไม่อนุญาตการสื่อสาร จึงควรเดินการแยกปัญหาร่วมกับทีมฝั่งพร็อกซี ↩
บทความที่เกี่ยวข้อง
บทความล่าสุดที่มีแท็กเดียวกัน เพื่อเจาะลึกหัวข้อใกล้เคียง
จับแพ็กเก็ตบน Windows ในทางปฏิบัติ — เลือก pktmon, netsh trace และ Wireshark
ความล้มเหลวที่เหลือเพียง "timeout" ในล็อกแอป สืบได้ลึกขึ้นหนึ่งชั้นด้วยการดูแพ็กเก็ตที่วิ่งบนสายจริง แม้ติดตั้ง Wireshark บนเซิร์ฟเวอร์ไม...
เชิงลึกของการจำลองเสมือนบน Windows (ตอนที่ 3) — เครื่องเสมือนที่บูตในไม่กี่วินาที: ทำไม WSL2, Windows Sandbox และคอนเทนเนอร์จึงเบา
ทำไม WSL2 และ Windows Sandbox จึงเริ่มในไม่กี่วินาทีและรู้สึกเบา? บทความนี้อธิบายกลไก ตั้งแต่ dynamic base image และ direct map ไปจนถึงกา...
เชิงลึกของการจำลองเสมือนบน Windows (ตอนที่ 2) — หน่วยความจำที่แม้เคอร์เนลก็มองไม่เห็น: กลไกของ VBS, HVCI และ Credential Guard
เมื่อติดตั้งใหม่บนฮาร์ดแวร์ที่รองรับ VBS จะเปิดตามค่าเริ่มต้น และใช้ hypervisor กับ SLAT สร้างการแยกที่แข็งกว่าเคอร์เนล บทความนี้อธิบายโค...
เชิงลึกของการจำลองเสมือนบน Windows (ตอนที่ 1) — Windows ของคุณรันอยู่ที่ไหนจริง ๆ? Hypervisor และพาร์ติชัน
เมื่อเปิด Hyper-V แล้ว Windows ฝั่งโฮสต์เองก็รันบน hypervisor ในฐานะ root partition บทความนี้อธิบายรากฐานของการจำลองเสมือนผ่านบทบาทของ VT...
Win32 Thread Pool API — คอนเคอร์เรนซีโดยไม่สร้างเธรดเอง ด้วย CreateThreadpoolWork
โค้ดเนทีฟของคุณกระจายการเรียก CreateThread ไปทั่วหรือไม่ บทความนี้อธิบาย Win32 thread pool API ที่ออกแบบใหม่ใน Vista — ออบเจ็กต์สี่ชนิด w...
หัวข้อที่เกี่ยวข้อง
หน้าเหล่านี้วางหัวข้อไว้ในบริบทที่กว้างขึ้นของบริการและการตัดสินใจ
หัวข้อเทคนิคของ Windows
ประตูสู่การพัฒนา Windows การตรวจสอบบั๊ก และการใช้ประโยชน์จากสินทรัพย์เดิม
บริการที่เกี่ยวข้องกับหัวข้อนี้
บทความนี้เกี่ยวข้องโดยตรงกับบริการต่อไปนี้
พัฒนาแอป Windows
แอปธุรกิจ การเชื่อมต่ออุปกรณ์ และเครื่องมือสื่อสาร ตั้งแต่ความต้องการจนถึงการพัฒนา
คำถามที่พบบ่อย
คำถามที่มักพบในการปรึกษาเกี่ยวกับหัวข้อของบทความนี้
- เบราว์เซอร์ต่อได้ แต่มีแค่แอปธุรกิจที่ข้ามพร็อกซีองค์กรไม่ได้ ทำไม
- เบราว์เซอร์อ่านค่าพร็อกซีต่อผู้ใช้ของ WinINET แต่แอปธุรกิจไม่จำเป็นต้องอ่านค่าเดียวกัน แอปที่รันเป็นบริการ Windows หรือภายใต้บัญชีอื่นดูค่าที่เห็นจากบัญชีนั้น ค่าเครื่องของ WinHTTP หรือตัวแปรสภาพแวดล้อม ระบุบัญชีที่รันก่อน แล้วตรวจค่าพร็อกซีที่เห็นจากบัญชีนั้นทั้งด้วย netsh winhttp show proxy และในค่าผู้ใช้ หากทำซ้ำได้ด้วย curl.exe หรือคล้ายกันภายใต้บัญชีเดียวกันบนเครื่องเดียวกัน ให้ถือเป็นการไม่ตรงกันระหว่างตระกูลการตั้งค่า ไม่ใช่ปัญหาเฉพาะแอป
- ตั้ง netsh winhttp set proxy แล้ว แต่ทราฟฟิกของแอปไม่เปลี่ยน ทำไม
- สิ่งที่ netsh winhttp ตั้งคือค่าเริ่มต้นระดับเครื่องของ WinHTTP ไม่กระทบเบราว์เซอร์หรือแอปโต้ตอบที่อ่าน WinINET หรือ HttpClient ของ .NET (Core เป็นต้นไป) ซึ่งให้ความสำคัญตัวแปรสภาพแวดล้อมก่อน netsh winhttp set proxy ยังเป็นค่าสถิต ไม่จัดการการตั้งค่าอัตโนมัติ PAC การตรวจจับอัตโนมัติ หรือการยืนยันตัวตนพร็อกซี ต้องยืนยันก่อนว่าแอปเป้าหมายใช้สแตก HTTP ใดและหาพร็อกซีจากตระกูลการตั้งค่าใด
- แอป .NET อ่านค่าพร็อกซีใด
- .NET Framework ตามค่าเริ่มต้นใช้ Internet Options (เทียบเท่า WinINET) ของบัญชีที่รัน และสามารถทับด้วยอิลิเมนต์ system.net/defaultProxy ใน app.config HttpClient บน .NET (Core เป็นต้นไป) อ่านตัวแปรสภาพแวดล้อมเช่น HTTP_PROXY, HTTPS_PROXY และ NO_PROXY ก่อน และหากไม่ได้กำหนดจะตกไปค่าพร็อกซีผู้ใช้ Windows ในทั้งสองกรณี HttpClientHandler.Proxy ที่ระบุชัดมีลำดับสูงกว่า ลำดับการหาค่าเริ่มต้นต่างกันระหว่าง Framework กับ Core เป็นต้นไป จึงต้องตรวจพฤติกรรมพร็อกซีอีกครั้งเมื่อย้าย
- ควรตรวจอะไรเมื่อได้ 407 Proxy Authentication Required
- 407 เป็นสัญญาณว่าพร็อกซีเองกำลังขอการยืนยันตัวตน ต่างจากข้อผิดพลาดยืนยันตัวตนเซิร์ฟเวอร์ปลายทาง (401) ยืนยันสคีมาที่พร็อกซีขอ (Negotiate, NTLM, Basic) จากส่วนหัว Proxy-Authenticate ก่อน และใน .NET ส่งข้อมูลรับรองด้วย HttpClientHandler.DefaultProxyCredentials หรือ WebProxy.UseDefaultCredentials ในแอปที่รันภายใต้บัญชีบริการ «ข้อมูลรับรองเริ่มต้น» กลายเป็นของบัญชีบริการนั้น จึงเกิดเหตุคลาสสิกที่ทำงานกับผู้ใช้โต้ตอบแล้ว 407 ทันทีที่ทำให้เป็นบริการ ตรวจล็อกฝั่งพร็อกซีด้วยว่ายืนยันตัวตนในฐานะใคร
- พร็อกซีตรวจ TLS ทำให้เกิดข้อผิดพลาดใบรับรอง ปิดการตรวจสอบใบรับรองได้ไหม
- ไม่แนะนำให้ปิด พร็อกซีตรวจ TLS ถอดรหัสทราฟฟิกแล้วเสนอใบรับรองที่ CA ของมันลงนามใหม่ให้ไคลเอนต์ การตรวจสอบจึงล้มเหลวหากใบรับรอง CA นั้นไม่อยู่ในรากที่เชื่อถือ การแก้ที่ถูกต้องคือแจกจ่ายใบรับรอง CA ภายในไปยังที่เก็บใบรับรอง Windows (โดยปกติ Trusted Root Certification Authorities ของเครื่องท้องถิ่น) การปิดการตรวจสอบในโค้ดหมายความว่าตรวจจับการโจมตีคนกลางไม่ได้เมื่อแอปถูกใช้บนเครือข่ายภายนอก และช่องโหว่ยังอยู่