פרוקסי ארגוני ואפליקציות Windows — סידור פתרון הפרוקסי ב-WinINET, WinHTTP ו-.NET

· · Windows, Proxy, WinHTTP, WinINET, .NET, HttpClient, PAC, WPAD, רשת

«הדפדפן פותח אתרים חיצוניים, ורק אפליקציית העסק אינה מגיעה ל-API החיצוני.» «עובד במכונת הפיתוח, ונכנס לפסק זמן ברשת הלקוח.» «מתקשר כשאני מריץ ידנית, ונכשל ברגע שאני הופך לשירות Windows.» — כאשר מריצים אפליקציית עסק בסביבה עם פרוקסי ארגוני, ייעוץ מסוג זה הוא מהנפוצים ביותר.

ברוב המקרים הסיבה אינה תקלת שרת פרוקסי ואינה באג באפליקציה. ב-Windows יש כמה משפחות נפרדות של מה שאנשים קוראים «הגדרות פרוקסי», ואילו הגדרות מי קורא נבדל לפי אפליקציה (לפי מחסנית ה-HTTP שהיא משתמשת) ולפי חשבון ההרצה — אי-ההתאמה הזו. ההגדרות שהדפדפן קורא, שאלו שירות קורא, ואלו ש-HttpClient של .NET קורא יכולות כל אחת להיות דבר אחר. ברגע שהמבנה הזה בראש, בידוד «עובד בדפדפן, אבל…» נעשה מהיר להפתיע.

המאמר מיועד לאנשי IT בחברות קטנות ובינוניות ולמפתחי אפליקציות Windows. הוא קושר בתמונה אחת את שלוש משפחות הגדרות הפרוקסי — WinINET, WinHTTP ומשתני סביבה — קונפיגורציה אוטומטית של PAC ו-WPAD, ההבדל בפתרון פרוקסי בין .NET Framework ל-.NET (Core ואילך), פרוקסי מזהה (407), בדיקת TLS, ואת הליך הבידוד המעשי. דפוסי יצירת HttpClient ותכנון פסקי זמן עצמם מכוסים ב-«אל תעטפו HttpClient ב-using», ולכן מאמר זה מתרכז בפתרון פרוקסי.

1. המסקנה תחילה

  • הגדרות פרוקסי של Windows אינן דבר אחד; יש לפחות שלוש משפחות. (1) הגדרות WinINET לכל משתמש (דף «פרוקסי» באפליקציית ההגדרות = אפשרויות האינטרנט הישנות), (2) הגדרות מכונה של WinHTTP (netsh winhttp), ו-(3) משתני הסביבה HTTP_PROXY / HTTPS_PROXY. איזו נקראת מוכרעת בצד האפליקציה.12
  • «הפרוקסי» שרואים באפליקציית ההגדרות הוא הגדרות לכל משתמש של WinINET. דפדפנים ואפליקציות אינטראקטיביות קוראים אותן; שירותי Windows לא. WinINET אינו נתמך לשימוש בשירות; שימוש שירות הוא עבודת WinHTTP.13
  • הסיבה הנפוצה ביותר ל-«עובד ידנית ולא כשירות» היא הבדל חשבון הרצה. LocalSystem וחשבון שירות אינם רואים את הפרוקסי לכל משתמש שמנהל הגדיר על המסך שלו.34
  • netsh winhttp set proxy הוא הגדרה סטטית; אינו מטפל ב-PAC, בגילוי אוטומטי או באימות פרוקסי. אם רוצים להגדיר PAC או WPAD לכל מכונה, צריך את צד netsh winhttp set advproxy.42
  • תוצאות PAC משתנות לכל URL. הפונקציה FindProxyForURL של קובץ ה-PAC מקבלת URL ומארח ומחזירה רשימת פרוקסי או חיבור ישיר (DIRECT). «האתר ההוא עובד, ורק ה-API הזה לא» יכול להיות ענף PAC.56
  • HttpClient ב-.NET (Core ואילך) מאתחל את פרוקסי ברירת המחדל בסדר משתני סביבה → הגדרות פרוקסי משתמש Windows. אם אחד מ-HTTP_PROXY, HTTPS_PROXY או ALL_PROXY מוגדר, הוא קודם להגדרות מערכת ההפעלה, ולכן יכול לקרות התאונה «מישהו השאיר משתנה סביבה».7
  • ברירת המחדל של .NET Framework היא אפשרויות האינטרנט של חשבון ההרצה, וניתן לדרוס אותה ב-defaultProxy ב-app.config. הגדרות קובץ התצורה קודמות להגדרות המערכת.89
  • 407 הוא שגיאת אימות פרוקסי; זה דבר אחר מ-401 (אימות שרת). הסכמות כוללות Negotiate, NTLM ו-Basic, וב-.NET מעבירים אישורים עם DefaultProxyCredentials או WebProxy.UseDefaultCredentials. שימו לב שתחת חשבון שירות תוכן «אישורי ברירת המחדל» משתנה.101112
  • פרוקסי בדיקת TLS מחזיק רק כסט עם הפצת אישור רשות האישורים הפנימית. מכונות וזמני ריצה שלא קיבלו אותו מקבלים שגיאת אימות אישור. פתרו בהפצה למאגר האישורים, לא בביטול האימות באפליקציה.134

במשפט אחד: בכל פעם שאומרים «בדקתי את הגדרות הפרוקסי», תמיד להיות מסוגלים לומר איזו משלוש המשפחות בדקתם, ומאיזה חשבון — זה נושא המאמר.

2. ב-Windows יש שלוש משפחות של «הגדרות פרוקסי»

תחילה, המפה הכוללת. הנתיבים שאפליקציית Windows משתמשת בהם למצוא פרוקסי ארגוני נופלים לשלוש המשפחות האלה.

משפחת הגדרות היכן מגדירים / הפקודה היקף מי קורא בעיקר
(1) WinINET (אפשרויות אינטרנט) הגדרות → רשת ואינטרנט → פרוקסי, inetcpl.cpl לכל משתמש (ברירת מחדל) דפדפנים, אפליקציות שולחן אינטראקטיביות, ברירת מחדל של .NET Framework
(2) WinHTTP (הגדרות מכונה) netsh winhttp set proxy / set advproxy מכונה שירותי Windows, חלק מרכיבי מערכת ההפעלה
(3) משתני סביבה HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY תהליך (עוברים בירושה לפי מקום ההגדרה) HttpClient ב-.NET (Core ואילך), curl, כלים חוצי-פלטפורמה כמו Node.js ו-Python

(1) הוא מה שאנשים מזהים בדרך כלל כ-«הגדרות הפרוקסי של Windows»; המהות היא תצורת WinINET. היסטורית אלו אפשרויות האינטרנט של Internet Explorer, וכברירת מחדל הן נשמרות לכל משתמש.4

(2) הוא ברירת המחדל לכל מכונה להקשרים כמו שירות שבהם «אין משתמש מחובר». (3) הוא בעיקר מוסכמת כלים שבאים מעולם חוצה-הפלטפורמות; ב-Windows גם .NET (Core ואילך) ו-curl וכדומה קוראים אותם.7

הנקודה החשובה היא שאיזו משפחה נקראת מוכרעת בצד האפליקציה, לא בצד ההגדרות. אם האפליקציה משתמשת ב-WinINET פנימית היא קוראת (1); אם WinHTTP, (2) (או דריסה ספציפית לאפליקציה); אם .NET (Core ואילך), (3) ואז (1). לכן בדרך כלל זה לא «הגדרות הפרוקסי נכונות אבל עדיין לא מתחבר»; המציאות היא «המשפחה שהאפליקציה קראה הייתה משפחה אחרת מזו שבדקתם».

שלוש משפחות של הגדרות פרוקסי WindowsWinINET הוא הגדרות לכל משתמש ואפשרויות אינטרנט, WinHTTP הוא ברירת מחדל של המכונה דרך netsh, ומשתני סביבה הם בהיקף תהליך. איזו משפחה נקראת מחליטה האפליקציה, לא צד ההגדרותאיזו משפחה?הגדרות WinINET לכל משתמשהגדרות מכונה של WinHTTPHTTP_PROXY וחבריםדפדפנים ואפליקציות שולחןשירותים וחלקי מערכת.NET Core+ ו-curl

איור 1: שלוש משפחות זו לצד זו. האפליקציה בוחרת איזו היא קוראת.

אם מפעילים את מדיניות הקבוצה «הפוך הגדרות פרוקסי למכונה (ולא למשתמש)», אפשר להעביר את (1) לכל מכונה ולהחיל את אותן הגדרות על כל משתמש. עם MDM (Intune וכדומה) אפשר להגדיר לכל מכשיר עם NetworkProxy CSP.4

3. WinINET ו-WinHTTP — לאפליקציות אינטראקטיביות ולשירותים

3.1. ההבדל בתפקידים

WinINET ו-WinHTTP שניהם מחסניות לקוח HTTP מובנות ב-Windows, אך הם מניחים שימושים שונים.

  • WinINET: מכוון לאפליקציות שולחן אינטראקטיביות. הוא יורש אוטומטית את אפשרויות האינטרנט של המשתמש (פרוקסי, עוגיות, מטמון אישורים) ואף יכול להציג ממשק הזנת אישורים אם צריך. שימוש בשירות או בתהליך דמוי-שירות אינו נתמך.1
  • WinHTTP: מכוון לשירותים ולצד השרת. הוא תומך בהרצה תחת חשבון שירות, בהתחזות שרשור ובבידוד הפעלה; בתמורה אינו חולק את הגדרות הדפדפן של המשתמש, עוגיות או אישורים. גם אינו מציג ממשק.3

ההנחיה של Microsoft עצמה ברורה באותה מידה: «השתמשו ב-WinINET אלא אם אתם רצים בתוך שירות, או בתהליך דמוי-שירות שזקוק לבידוד הפעלה ולהתחזות» — במילים אחרות, אם זה שירות, השתמשו ב-WinHTTP.1

WinINET לאפליקציות אינטראקטיביות, WinHTTP לשירותיםWinINET יורש את אפשרויות האינטרנט של המשתמש המחובר ואינו נתמך בשירות. WinHTTP רץ תחת חשבון שירות בלי ממשק ואינו חולק את הגדרות הדפדפן של המשתמשכןשירות או דמוי-שירותאפליקציית שולחן אינטראקטיבית?WinINETWinHTTPקורא אפשרויות אינטרנט של המשתמשהגדרות מכונה, בלי ממשק

איור 2: אפליקציות אינטראקטיביות משתמשות ב-WinINET. שירות משתמש ב-WinHTTP.

3.2. פעולות netsh winhttp בסיסיות

פרוקסי ברירת המחדל של המכונה של WinHTTP מופעל עם netsh.2

:: 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

שני אילוצים לזכור כאן.

  1. netsh winhttp set proxy הוא הגדרה סטטית. הוא אינו מטפל בגילוי אוטומטי של פרוקסי, ולא בציון URL של PAC, ולא באימות פרוקסי.4
  2. import proxy source=ie מעתיק רק את ההגדרות הסטטיות באותו רגע; אינו עוקב אחרי שינויים מאוחרים בצד אפשרויות האינטרנט. כאשר צריך תצורה לכל מכונה שכוללת PAC או גילוי אוטומטי, הגדירו את ההגדרות המפורטות בצורת JSON (Proxy, ProxyBypass, AutoconfigUrl, AutoDetect) עם netsh winhttp set advproxy.2

3.3. המלכודת הנפוצה ביותר: שירות אינו קורא את הגדרות IE של המשתמש

הדפוס שרואים הכי הרבה בשטח, בסדר הזמן, נראה כך.

  1. מפתח מריץ את הכלי במחשב שלו → הגדרות הפרוקסי לכל משתמש (1) נכנסות לתוקף ועובד
  2. בייצור משאירים אותו תושב כשירות Windows (איך לבנות ולהפעיל שירותי Windows) תחת LocalSystem
  3. ההגדרות הנראות מ-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

מדוע שירות אינו רואה את הגדרות IE של המשתמשהרצת מפתח קוראת הגדרות WinINET לכל משתמש ועובדת. כ-LocalSystem ההגדרות האלה בלתי נראות. אפליקציית WinHTTP מקורית אז הולכת אחרי הגדרות מכונה לא מוגדרות (DIRECT). שירות .NET Core+ עדיין משתמש במשתני סביבה או handler.Proxy מפורש ואינו עובר ל-netsh winhttpWinHTTP.NET Core+הרצה ידנית כמשתמשהגדרות WinINET לכל משתמש חלותשירות Windows כ-LocalSystemהגדרות לכל משתמש בלתי נראותאיזו מחסנית HTTP?WinHTTP לא מוגדר = DIRECTמשתני סביבה או handler.Proxyה-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

הפעילו «גלה הגדרות אוטומטית» והמכונה מחפשת את מיקום קובץ ה-PAC בפרוטוקול WPAD (Web Proxy Auto-Discovery). בתצורה טיפוסית DHCP מוסר URL של PAC, או משתמשים ב-DNS לחפש מארח בשם wpad וה-PAC מורד מ-URL כמו http://wpad/wpad.dat.14

כלומר, «גילוי אוטומטי» אינו קסם; זה מנגנון שעובד רק ברשת שכבר הקימה סידור WPAD ב-DHCP/DNS. הפעלת גילוי אוטומטי לבדו ברשת בלי סידור כזה רק מוסיפה זמן המתנה לכישלון גילוי.

PAC פותר פרוקסי לכל URL, WPAD רק מוצא את ה-PACFindProxyForURL מקבל URL ומארח ומחזיר רשימת פרוקסי או DIRECT. WPAD מאתר את ה-PAC רק דרך DHCP או DNS. לקוח שאינו יכול להעריך PAC נופל לפרוקסי סטטי או למשתני סביבהרשימת פרוקסיDIRECTURL הבקשהFindProxyForURLלעבור דרך פרוקסילהתחבר בלי פרוקסיWPAD דרך DHCP או DNSלקוח שאינו מעריך PACהגדרות סטטיות או משתני סביבה

איור 4: PAC מחליט לכל URL. WPAD רק מוצא את קובץ ה-PAC.

4.3. איך מתנהגים לקוחות שאינם יכולים להעריך PAC

לא כל לקוח יכול להעריך PAC.

  • ההגדרות הסטטיות של netsh winhttp set proxy אינן מעריכות PAC.4
  • כלים שמשתמשים בסגנון משתנה הסביבה 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 — ברירת המחדל אפשרויות אינטרנט, נדרסת ב-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 ריק והגדרות המערכת (אפשרויות האינטרנט) בשימוש; כתבו proxyaddress וכדומה ואלו קודמות. מהתוכנית אפשר להחליף את אותה ברירת מחדל ב-WebRequest.DefaultWebProxy.98

המלכודת מפרק 3.3 חלה גם כאן. כי ברירת המחדל היא «אפשרויות האינטרנט של חשבון ההרצה», אפליקציית .NET Framework שרצה תחת חשבון שירות קוראת סט הגדרות אחר (בדרך כלל ריק) מאלו הנראות בשולחן של המנהל.

5.2. .NET (Core ואילך) — משתני סביבה תחילה, אחר כך הגדרות משתמש של מערכת ההפעלה

ל-HttpClient ב-.NET (Core ואילך) יש מאפיין סטטי HttpClient.DefaultProxy. אלא אם handler מציין פרוקסי במפורש, כל מופע HttpClient משתמש בו. כלל האתחול ב-Windows הוא «קרא משתני סביבה, ואם אינם מוגדרים קרא את הגדרות פרוקסי המשתמש».7

משתני הסביבה שבשימוש הם כדלקמן.7

משתנה סביבה משמעות
HTTP_PROXY פרוקסי לבקשות HTTP
HTTPS_PROXY פרוקסי לבקשות HTTPS
ALL_PROXY נפילה כאשר האמור לעיל אינו מוגדר
NO_PROXY רשימה מופרדת בפסיקים של מארחים שלא צריכים להשתמש בפרוקסי

שלושה דברים לשים לב.

  • אם אחד מ-HTTP_PROXY, HTTPS_PROXY או ALL_PROXY מוגדר, הוא קודם להגדרות הפרוקסי בצד מערכת ההפעלה. הגדרת NO_PROXY בלבד אינה מגדירה פרוקסי ממשתני סביבה, וב-Windows ממשיכים להשתמש בהגדרות פרוקסי המשתמש של מערכת ההפעלה. «הגדרות בלתי נראות» כמו השארת HTTPS_PROXY כמשתנה סביבה מערכתי אחרי ניסוי ישן, או תבנית CI/CD שמזריקה אותו, הן כר גידול לתאונות.
  • NO_PROXY אינו תומך בתווים כלליים (*). כדי להתאים תת-דומיין, שימו נקודה מובילה (.example.com מתאים ל-www.example.com אך לא ל-example.com עצמו).7
  • מחוץ ל-Windows (מכלי Linux וכדומה), אם משתני הסביבה אינם מוגדרים זה מאותחל בלי פרוקסי. שינוי התנהגות ברירת המחדל של אותה אפליקציה בין Windows ל-Linux הוא דבר לאשר בזמן מעבר למכל.7

5.3. ציון מפורש — HttpClientHandler.Proxy ו-UseProxy

בכל זמן ריצה, העדיפות הגבוהה ביותר היא ציון מפורש על ה-handler. ציון HttpClientHandler.Proxy קודם להגדרות מערכת ההפעלה ולקובץ התצורה, ו-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);

כאשר אין ציון מפורש והולכים אחרי הגדרות מערכת ההפעלה, לעקיפה אוטומטית של יעדים מקומיים יש כללים. שם שטוח בלי נקודה, כתובת לולאה, יעד שמתאים לסיומת הדומיין של המכונה עצמה וכדומה יכולים להיחשב «מקומיים».14 תופעות כמו «ההתנהגות משתנה אם מציינים כתובת IP» או «פתאום התחיל לעבור בפרוקסי כשהשתמשתי ב-FQDN» יכולות להיגרם משיפוט זה.

סדר העדיפות הוא כדלקמן.

עדיפות (גבוהה → נמוכה) .NET Framework .NET (Core ואילך)
1 ציון מפורש כמו HttpClientHandler.Proxy אותו דבר
2 defaultProxy ב-app.config השמה ל-HttpClient.DefaultProxy
3 אפשרויות האינטרנט של חשבון ההרצה משתני סביבה (HTTP_PROXY ואחרים)
4 הגדרות פרוקסי משתמש Windows
פתרון פרוקסי ברירת מחדל ב-Framework מול Core ואילךHttpClientHandler.Proxy מפורש תמיד מנצח. Framework אז משתמש ב-app.config defaultProxy ובאפשרויות האינטרנט של חשבון ההרצה. Core ואילך משתמש בהשמה ל-HttpClient.DefaultProxy, אחר כך משתני סביבה, אחר כך הגדרות פרוקסי משתמש WindowsFrameworkCore ואילךhandler.Proxy מפורשהפרוקסי הזה בשימושאין Proxy מפורשאיזה זמן ריצה?app.config defaultProxyאפשרויות אינטרנט של החשבוןHttpClient.DefaultProxyHTTP_PROXY וחבריםהגדרות פרוקסי משתמש Windows

איור 5: ציון מפורש תמיד מנצח. נתיב ברירת המחדל נבדל לפי זמן ריצה.

6. פרוקסי מזהה — 407 הוא שגיאת האימות של הפרוקסי

6.1. אל תבלבלו 407 עם 401

כאשר מנסים לעבור דרך פרוקסי שדורש אימות, הפרוקסי מחזיר קוד מצב 407 (Proxy Authentication Required) וכותרת Proxy-Authenticate שמונה את הסכמות הזמינות. זה דבר אחר מדרישת האימות של שרת היעד (401 ו-WWW-Authenticate); הצד שמעבירים אליו אישורים והמקום שמגדירים אותם שניהם שונים.10

407 הוא הפרוקסי, 401 הוא שרת היעד407 ו-Proxy-Authenticate באים מהפרוקסי. 401 ו-WWW-Authenticate באים משרת היעד. האישורים והמקום שמגדירים אותם נבדליםהפרוקסיהיעדבקשה יוצאתמי דורש אימות?407 + Proxy-Authenticate401 + WWW-AuthenticateDefaultProxyCredentials

איור 6: 407 הוא אימות פרוקסי. 401 הוא אימות שרת.

הסכמות כוללות Basic, ששולח את שם המשתמש והסיסמה כפי שהם, וסכמות אתגר/תגובה כמו Negotiate (Kerberos/NTLM). בסכמת אתגר/תגובה הסיסמה עצמה אינה נוסעת ברשת, והאימות מסתיים בכמה חילופים.10 מנגנון הסכמה שאליה הוא «נופל» מכוסה בפירוט רב יותר ב-«NTLM ו-Kerberos מוסברים בתרשימים».

6.2. איך להעביר אישורים ב-.NET

כאשר רוצים להשתמש בפרוקסי ברירת המחדל שמגיע מהגדרות מערכת ההפעלה ולהעביר רק את האימות, השתמשו ב-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 אינו נראה — זו התנהגות פרוקסי «מעבר».

HTTPS דרך פרוקסי הוא מנהרת CONNECTהלקוח שולח CONNECT לפרוקסי, הפרוקסי פותח מנהרת TCP ומחזיר 200, ואז הלקוח והיעד מבצעים לחיצת יד TLS במנהרה. יומן הפרוקסי רואה את המארח, לא את נתיב ה-URLCONNECT host:443200 ומנהרת TCPTLS במנהרהלקוחפרוקסייעדיומן: מארח והצלחה בלבד

איור 7: פרוקסי מעבר רואה את המארח, לא את הנתיב המוצפן.

7.2. פרוקסי בדיקת TLS ושגיאות אישור

פרוקסי של מוצרי אבטחה, לעומת זאת, כוללים סוג בדיקת TLS (פענוח SSL, שבירה ובדיקה) שמסיים TLS, בודק את התוכן, ומצפין מחדש לפני העברה. בסכמה זו אישור השרת שמוצג ללקוח אינו האמיתי; הוא מוחלף באישור שנחתם מחדש על ידי רשות האישורים של הפרוקסי.13

ההנחה שמחזיקה את התצורה הזו היא אפוא «אישור רשות האישורים של הפרוקסי הופץ לשורשים המהימנים של כל לקוח». במכונה שלא קיבלה אותו, או בזמן ריצה שאינו מסתכל על מאגר האישורים של Windows (כלים עם מאגר אמון משלהם), מקבלים שגיאת אימות אישור. ב-.NET זה בדרך כלל עולה כ-HttpRequestException שעוטף AuthenticationException (הודעה מסוג «the remote certificate is invalid»).

עקרונות התיקון הם כדלקמן.

  • הפיצו את אישור רשות האישורים הפנימית למאגר «רשויות אישורים שורשיות מהימנות» של המחשב המקומי. הפיצול בין מאגר המשתמש למאגר המחשב מכוסה ב-«מאגר האישורים של Windows בפועל».
  • אל תבטלו אימות אישורים בקוד. פתרון עוקף שמחזיר תמיד true מ-ServerCertificateCustomValidationCallback הופך לאפליקציה פגיעה שאינה יכולה לגלות איש-באמצע ברגע שהיא יוצאת לרשת חיצונית.
  • תעבורה עם נעיצת אישור אינה ניתנת לבדיקה מלכתחילה. חיבורים שמוודאים אישור Microsoft ספציפי, כמו שחלק מרכיבי Windows עושים, נכשלים ברגע שהפרוקסי מחליף את האישור, ואין פתרון עוקף מלבד החרגה.4 לתעבורה שמיועדת ל-SaaS כמו Microsoft 365, Microsoft עצמה ממליצה להחריג אותה מפענוח ובדיקה בשכבת הרשת.13

תסמין «כל אתר פנימי נראה, ורק שירות ענן מסוים מייצר שגיאת אישור באפליקציה» צריך לגרום לחשוד תחילה בשילוב של רשימת החרגת בדיקת TLS והנעיצה.

פרוקסי בדיקת TLS חותם מחדש את האישורהפרוקסי מסיים TLS, בודק את התוכן, ומציג אישור שנחתם מחדש על ידי רשות האישורים שלו. האימות מחזיק רק אם אותה רשות בשורשים המהימנים. אל תבטלו אימות בקודהרשות בשורשיםהרשות חסרהאישור שרת אמיתיפרוקסי בדיקת TLSנחתם מחדש על ידי רשות הפרוקסיאימות הלקוחהצלחהשגיאת אישורהפיצו את הרשות למאגר

איור 8: הבדיקה עובדת רק כסט עם הפצת רשות האישורים הפנימית.

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 הוא בדרך כלל משתמש במאגר האישורים של מערכת ההפעלה (Schannel). Invoke-WebRequest של Windows PowerShell 5.1 הולך אחרי צד .NET Framework (אפשרויות אינטרנט כברירת מחדל); PowerShell 7 הולך אחרי צד .NET (משתני סביבה תחילה). «curl עובד והאפליקציה לא» עצמו הוא רמז לאי-התאמה בין משפחות תצורה.
  • אם היעד ב-(3) הוא שירות, בדקו מחדש את (1) ו-(2) תחת אותו חשבון כמו השירות. בדיקה בהפעלה של המנהל עצמו אינה הוכחה למה ש-LocalSystem רואה.
  • בסיווג השגיאה ב-(4), קחו את פרק 6 (אימות) כמועמד ראשון ל-407, פרק 7 (בדיקת TLS) לשגיאת אישור, ו-«אינו מגיע לפרוקסי» (נתיב, פתרון שם, חומת אש) לפסק זמן. הדפוס שבו הסיבה היא כלל נכנס של חומת האש של Windows ולא הפרוקסי מכוסה ב-«חומת האש של Windows ואפליקציות עסקיות».
  • אם מגיעים ל-(5) ועדיין אין עקבות ביומן הפרוקסי, התעבורה מעולם לא הגיעה לפרוקסי. חשדו בהחלטת DIRECT של PAC, ברשימת עקיפה, או במשתנה סביבה שנשאר, ואם צריך אשרו את היעד בפועל בלכידת מנות («לכידת מנות ב-Windows בפועל — בחירה בין pktmon, netsh trace ו-Wireshark»).
חמישה צעדים לבידוד כשל פרוקסישחזרו תחת אותו חשבון, אספו את שלוש משפחות ההגדרות, זהו את חשבון ההרצה, סווגו את השגיאה, ואז בדקו את יומן הפרוקסישחזור עם curlאיסוף שלוש משפחותזיהוי החשבוןסיווג השגיאהבדיקת יומן הפרוקסי407: אימותשגיאת אישור: בדיקהפסק זמן: לא הגיע

איור 9: לכו את חמשת הצעדים לפי הסדר. מחלקת השגיאה בוחרת את הפרק הבא.

9. המלצת תכנון — הפכו את האפליקציה לכזו שאפשר «להגדיר עליה את הפרוקסי»

הפכו את הליך החקירה והוא הופך להנחיית תכנון בצד האפליקציה. לאפליקציית Windows שתספקו לסביבה עם פרוקסי ארגוני, מומלץ כדלקמן.

  1. הפכו את הפרוקסי לניתן להגדרה מהגדרות האפליקציה. ברירת המחדל היא «ללכת אחרי הגדרות מערכת ההפעלה». ברוב הסביבות ברירת המחדל מספיקה; רק בסביבות החריגות — אי אפשר לקרוא PAC, רץ כשירות, תצורת פרוקסי מיוחדת — אפשרו לציין URL פרוקסי, רשימת עקיפה, ו-«אל תשתמש בפרוקסי» מקובץ הגדרות. HttpClientHandler.Proxy / UseProxy בסעיף 5.3 הוא נקודת המימוש.14
  2. כתבו איך יעדים פנימיים (API, מסדי נתונים, שרתי רישוי וכדומה) מטופלים כחריגי פרוקסי. שימו בצורה שאפשר לכתוב בנוהל הפריסה אם הם מוחרגים על ידי PAC DIRECT, רשימת עקיפה, או NO_PROXY. כללי ההתאמה של NO_PROXY (בלי תווים כלליים, מה נקודה מובילה אומרת) מובנים לא נכון בהרחבה, ולכן צרפו דוגמאות.7
  3. תכננו פסקי זמן וניסיונות חוזרים בהנחה שעוברים דרך פרוקסי. אם הפרוקסי למטה או תקוע באימות, מימוש שמחכה לפסק זמן ברירת מחדל ארוך מקפיא גם את הממשק וגם את ההפעלה. הפרידו פסק זמן חיבור קצר יותר, והגבילו ניסיונות חוזרים לבקשות אידמפוטנטיות (פרטי תכנון ב-«אל תעטפו HttpClient ב-using»).
  4. רשמו ביומן «איזה פרוקסי היה בשימוש». הפכו את האפליקציה עצמה ליכולה לענות על השאלה הראשונה של חקירת כשל.

יומן כמו ב-(4) כבר יעיל אם הוא רושם רק את תוצאת הפתרון. הנקודה היא לגזור את הנתיב מההגדרות (ה-handler) שבאמת השתמשתם בהן כדי להגדיר את הלקוח. אם רושמים HttpClient.DefaultProxy ישירות, תרשמו ערך שאינו מסכים עם הנתיב בפועל כאשר ה-handler מציין 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 מסתיימים רק בקריאת היומן. כשאומרים לכם «עובד בדפדפן, אבל…», היכולת לומר מצד האפליקציה «השתמשתי בהגדרה הזו, ובנתיב הזה» היא תנאי של אפליקציה חזקה מול צרות פרוקסי.

הפכו את הפרוקסי לניתן להגדרה ורשמו את הנתיבכברירת מחדל ללכת אחרי הגדרות מערכת ההפעלה, לאפשר URL פרוקסי מפורש או עקיפה או בלי פרוקסי מהגדרות האפליקציה, ולרשום את המסלול שבאמת היה בשימוש יחד עם חשבון ההרצהPAC לא נקרא / שירות / מיוחדהמקרה הרגילברירת מחדל: ללכת אחרי מערכת ההפעלהסביבה חריגה?הגדירו URL, עקיפה, או בלי פרוקסיהשתמשו בברירת המחדל של מערכת ההפעלהרשמו מסלול וחשבון

איור 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 היא אפשרויות האינטרנט של חשבון ההרצה (ניתנת לדריסה ב-defaultProxy); .NET (Core ואילך) הוא משתני סביבה ואז הגדרות פרוקסי משתמש. ציון מפורש (HttpClientHandler.Proxy) תמיד בעדיפות הגבוהה ביותר.
  • 407 הוא שגיאת אימות פרוקסי; באפליקציה שרצה תחת חשבון שירות הסיבה הטיפוסית היא ש-«אישורי ברירת המחדל» הופכים לאדם אחר.
  • פרוקסי בדיקת TLS מניח הפצת אישור רשות האישורים הפנימית, והתשובה הנכונה לשגיאת אישור היא הפצה למאגר האישורים, לא ביטול האימות. תעבורה נעוצה צריכה החרגה.
  • בדדו באופן מכני בסדר «שחזור → איסוף שלוש משפחות ההגדרות → זיהוי חשבון ההרצה → סיווג השגיאה → יומן הפרוקסי». בצד האפליקציה, תכנון ש-«יכול להגדיר את הפרוקסי, ורושם את הנתיב שהשתמש בו» הוא המניעה הטובה ביותר.

בפעם הבאה שמייעצים לכם עם «רק אפליקציית העסק אינה מתחברת», שאלו תחילה את זה.

תחת חשבון של מי האפליקציה הזו רצה, ואיזו משלוש משפחות הגדרות הפרוקסי היא קוראת?

השאלה האחת הזו משנה מאוד את הכניסה לחקירה.

מאמרים קשורים

תחומי ייעוץ קשורים

KomuraSoft LLC מטפלת בחקירת תקלות תקשורת של אפליקציות Windows בסביבות פרוקסי ארגוני, פרוקסי מזהה ובדיקת TLS — «עובד במכונת הפיתוח אך אינו מתקשר ברשת הלקוח», «אחרי שהפכנו לשירות כבר לא הגיע ל-API החיצוני» — ובייעוץ על תכנון תקשורת של אפליקציות עסקיות שמניח סביבת פרוקסי (פריטי הגדרות, פסקי זמן, תכנון יומנים). אפשר להתחיל מסידור שלבי השחזור ואיך לאסוף יומנים.

קישורי עיון

  1. Microsoft Learn, WinINet vs. WinHTTP. על ההנחיה להשתמש ב-WinINET אלא אם אתם בשירות או בתהליך שזקוק להתחזות ולבידוד הפעלה, ועל טבלת השוואת התכונות שמכסה מטמון אישורים, הנחיות אישורים, תמיכת שירותים, התחזות, בידוד הפעלה וכדומה.  2 3 4

  2. 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

  3. Microsoft Learn, About WinHTTP. על כך ש-WinHTTP הוא מחסנית HTTP שתוכננה לשימוש שירות וצד שרת, תומכת בהרצה תחת חשבון שירות ובהתחזות, ואינה חולקת עוגיות, מטמון, אישורים של הדפדפן או אפשרויות האינטרנט של המשתמש.  2 3

  4. Microsoft Learn, Using a proxy with Delivery Optimization. על כך ש-netsh winhttp set proxy הוא הגדרה סטטית שאינה תומכת בגילוי אוטומטי, ב-URL של PAC או באימות פרוקסי; על תצורת פרוקסי לכל מכשיר להקשרים בלי משתמש מחובר (NetworkProxy CSP, מדיניות «הפוך הגדרות פרוקסי למכונה»); ועל תעבורה נעוצת-אישור שנכשלת תחת בדיקת TLS וזקוקה להחרגה.  2 3 4 5 6 7 8 9 10

  5. Microsoft Learn, WinHTTP AutoProxy Support. על כך שסקריפט PAC מכיל פונקציה FindProxyForURL(url, host) שמחשבת רשימת פרוקסי לכל בקשה ומציינת חיבור ישיר בערך החזרה מיוחד, ועל כך ש-API של AutoProxy הישן יותר אינו משלב אוטומטית פרוקסי אוטומטי במחסנית ה-HTTP כך שהאפליקציה צריכה לקרוא ל-WinHttpGetProxyForUrl.  2 3

  6. Microsoft Learn, WinHttpGetProxyForUrl function. על כך שזה מימוש של פרוטוקול WPAD, שצריך לקרוא לו לכל URL כי קובץ PAC יכול להחזיר פרוקסי אחר לכל URL, ושהוא תומך גם ב-URL PAC מפורש וגם בגילוי אוטומטי מהרשת.  2

  7. 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

  8. Microsoft Learn, Configuring Internet Applications. על כך שאלמנט defaultProxy מגדיר את פרוקסי ברירת המחדל ב-.NET Framework; ש-HttpWebRequest בלי מאפיין Proxy משתמש בפרוקסי ברירת המחדל; ושהגדרות אינטרנט של המערכת והגדרות קובץ התצורה משולבות עם עדיפות לצד קובץ התצורה.  2 3

  9. Microsoft Learn, defaultProxy element (network settings). על המאפיינים enabled ו-useDefaultCredentials של אלמנט system.net/defaultProxy, האלמנטים הילדים proxy, bypasslist ו-module, על כך שהגדרות הפרוקסי של המערכת בשימוש אם האלמנט ריק, ועל תצורה עם HttpClient.DefaultProxy במעבר ל-.NET 6 ואילך.  2 3

  10. Microsoft Learn, Authentication in WinHTTP. על כך שקוד מצב 407 וכותרת Proxy-Authenticate מוחזרים כאשר נדרש אימות פרוקסי (אימות שרת הוא 401 ו-WWW-Authenticate); על ההבדל בין אימות Basic לסכמות אתגר/תגובה כמו Kerberos; ועל כך שסכמת אתגר/תגובה פירושה ששם המשתמש והסיסמה אינם נוסעים ברשת.  2 3

  11. Microsoft Learn, HttpClientHandler.DefaultProxyCredentials Property. על המאפיין שמגדיר את האישורים המשמשים לאימות לפרוקסי ברירת המחדל כאשר UseProxy הוא true ו-Proxy הוא null כך שמשתמשים בפרוקסי ברירת המחדל של המערכת.  2

  12. Microsoft Learn, WebProxy.Credentials Property. על כך שמאפיין Credentials הוא האישורים שנשלחים לפרוקסי בתגובה ל-HTTP 407, ועל ההמלצה בתרחישי לקוח רבים להגדיר UseDefaultCredentials ל-true כדי שישתמשו באישורי ברירת המחדל של המשתמש המחובר.  2

  13. 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

  14. Microsoft Learn, Make HTTP requests with the HttpClient class. על שתי שיטות התצורה HttpClient.DefaultProxy ו-HttpClientHandler.Proxy; על כך שציון Proxy קודם לקובץ התצורה ולהגדרות המחשב המקומי; על תצורת WPAD הטיפוסית של קבלת קובץ PAC (wpad.dat וכדומה) דרך שם ה-DNS wpad או DHCP; ועל שיפוט עקיפת יעדים מקומיים לפי שם שטוח, לולאה והתאמת סיומת דומיין.  2 3 4

  15. Microsoft Learn, WinHttpOpen function. על משמעות כל ערך dwAccessType. WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY (Windows 8.1 ואילך) מחליט אוטומטית את הפרוקסי מהגדרות פרוקסי מערכת/משתמש ומטפל גם בכשל-מעבר ובאימות אוטומטית, ו-WINHTTP_ACCESS_TYPE_DEFAULT_PROXY מיושן מ-8.1 ואילך. 

  16. Microsoft Learn, Work with existing on-premises proxy servers. על כך ש-HTTPS יוצא מיוסד בבקשת CONNECT לפרוקסי; שהצלחה מחזירה HTTP 200; ושתגובות כמו 407 (נדרש אימות) או 502 מציינות שהפרוקסי אינו מתיר את התקשורת, ולכן כדאי להמשיך בבידוד עם צוות צד הפרוקסי. 

מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.

העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.

המאמר קשור ישירות לשירותים הבאים.

שאלות נפוצות

שאלות נפוצות בפניות בנושא המאמר.

הדפדפן מתחבר, ורק אפליקציית העסק אינה עוברת את הפרוקסי הארגוני. מדוע?
הדפדפן קורא את הגדרות הפרוקסי לכל משתמש של 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 משתמש כברירת מחדל בהגדרות אפשרויות האינטרנט (מקבילת 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 מפענח את התעבורה ואז מציג ללקוח אישור שנחתם מחדש על ידי רשות האישורים שלו, כך שהאימות נכשל אם אישור רשות זה אינו בשורשים המהימנים. התיקון הנכון הוא להפיץ את אישור רשות האישורים הפנימית למאגר האישורים של Windows (בדרך כלל רשויות אישורים שורשיות מהימנות של המחשב המקומי). ביטול האימות בקוד פירושו שמתקפת איש-באמצע לא תתגלה כאשר האפליקציה בשימוש ברשת חיצונית, והפגיעות נשארת.

פרופיל הכותב

עמוד היכרות עם כותב המאמר.

Go Komura

מנהל KomuraSoft LLC

מתמחה בפיתוח תוכנה עבור Windows, ייעוץ טכני וחקירת תקלות, בעיקר בפרויקטים עם מערכות קיימות ובאגים שקשה לשחזר.

קישורים ציבוריים

חזרה לבלוג