הגדרת Smart Dialer

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

קובץ הגדרות YAML לחיוג חכם

ההגדרה שמקבלת החייגן החכם היא בפורמט YAML. לדוגמה:

dns:
  - system: {}
  - https:
      name: 8.8.8.8
  - https:
      name: 9.9.9.9
tls:
  - ""
  - split:2
  - tlsfrag:1

fallback:
  - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1

הגדרת DNS

  • השדה dns מציין רשימה של מקודדי DNS לבדיקה.
  • כל פותר DNS יכול להיות אחד מהסוגים הבאים:
    • system: שימוש בפתרון הבעיות של המערכת. מציינים באמצעות אובייקט ריק.
    • https: שימוש במפענח DNS מוצפן על גבי HTTPS ‏ (DoH).
    • tls: שימוש במקודד DNS מוצפן באמצעות TLS‏ (DoT).
    • udp: שימוש ב-UDP resolver.
    • tcp: שימוש ב-TCP resolver.

מקודד DNS-over-HTTPS‏ (DoH)

https:
  name: dns.google
  address: 8.8.8.8
  • name: שם הדומיין של שרת DoH.
  • address: המארח:היציאה של שרת ה-DoH. ברירת המחדל היא name:443.

מקודד DNS-over-TLS ‏ (DoT)

tls:
  name: dns.google
  address: 8.8.8.8
  • name: שם הדומיין של שרת DoT.
  • address: המארח:היציאה של שרת ה-DoT. ברירת המחדל היא name:853.

UDP Resolver

udp:
  address: 8.8.8.8
  • address: המארח:היציאה של פותר ה-UDP.

TCP Resolver

tcp:
  address: 8.8.8.8
  • address: המארח:היציאה של פותר ה-TCP.

הגדרת TLS

  • השדה tls מציין רשימה של פרוטוקולי TLS לתעבורה שצריך לבדוק.
  • כל העברה באמצעות TLS היא מחרוזת שמציינת את ההעברה שבה יש להשתמש.
  • לדוגמה, override:host=cloudflare.net|tlsfrag:1 מציין תעבורה שמשתמשת בהסתרת דומיין עם Cloudflare ובפיצול TLS. פרטים נוספים מופיעים במסמכי התיעוד בנושא הגדרות.

הגדרת חזרה למצב ראשוני

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

מחרוזות הגיבוי צריכות להיות:

  • מחרוזת הגדרה תקינה StreamDialer כמוגדר ב-configurl.
  • אובייקט הגדרה תקין של Psiphon כצאצא של שדה psiphon.

דוגמה לשרת Shadowsocks

fallback:
  - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1

דוגמה לשרת SOCKS5

fallback:
  - socks5://[USERINFO]@[HOST]:[PORT]

דוגמה להגדרת Psiphon

כדי להשתמש ברשת Psiphon, צריך:

  1. כדי לקבל גישה לרשת שלהם, צריך לפנות לצוות של Psiphon כדי לקבל הגדרה. יכול להיות שיהיה צורך בחוזה.
  2. מוסיפים את הגדרות Psiphon שקיבלתם לקטע fallback בהגדרות של Smart Dialer. מכיוון ש-JSON תואם ל-YAML, אפשר להעתיק ולהדביק את ההגדרה של Psiphon ישירות לקטע fallback, כך:
fallback:
  - psiphon: {
      "PropagationChannelId": "FFFFFFFFFFFFFFFF",
      "SponsorId": "FFFFFFFFFFFFFFFF",
      "DisableLocalSocksProxy" : true,
      "DisableLocalHTTPProxy" : true,
      ...
    }

איך משתמשים בחייגן החכם

כדי להשתמש בחייגן החכם, יוצרים אובייקט StrategyFinder ומפעילים את השיטה NewDialer, ומעבירים את רשימת הדומיינים לבדיקה ואת הגדרת ה-YAML. השיטה NewDialer תחזיר transport.StreamDialer שאפשר להשתמש בו כדי ליצור חיבורים באמצעות האסטרטגיה שנמצאה. לדוגמה:

finder := &smart.StrategyFinder{
    TestTimeout:  5 * time.Second,
    LogWriter:   os.Stdout,
    StreamDialer: &transport.TCPDialer{},
    PacketDialer: &transport.UDPDialer{},
}

configBytes := []byte(`
dns:
  - system: {}
  - https:
      name: 8.8.8.8
  - https:
      name: 9.9.9.9
tls:
  - ""
  - split:2
  - tlsfrag:1
fallback:
  - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1
`)

dialer, err := finder.NewDialer(
  context.Background(),
  []string{"www.google.com"},
  configBytes
)
if err != nil {
    // Handle error.
}

// Use dialer to create connections.

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

הוספת שיטת חלופה חדשה

המערכת משתמשת באסטרטגיות חלופיות אם אף אחת מהאסטרטגיות ללא שרת proxy לא מצליחה. בדרך כלל מדובר בשרתי proxy שאמורים להיות אמינים יותר.

כדי להוסיף אסטרטגיית גיבוי חדשה:

  1. יוצרים פונקציית FallbackParser. הפונקציה הזו מקבלת YAMLNode ומחזירה transport.StreamDialer וחתימת הגדרה.
  2. רושמים את FallbackParser באמצעות השיטה mobileproxy.SmartDialerOptions.RegisterFallbackParser.

לדוגמה, כך אפשר לרשום חלופה שמוגדרת עם {error: "my error message"} שתמיד מחזירה שגיאה בחיוג:

func RegisterErrorConfig(opt *mobileproxy.SmartDialerOptions, name string) {
    opt.RegisterFallbackParser(name, func(ctx context.Context, yamlNode smart.YAMLNode) (transport.StreamDialer, string, error) {
        switch typed := yamlNode.(type) {
        case string:
            dialer := transport.FuncStreamDialer(func(ctx context.Context, addr string) (transport.StreamConn, error) {
                return nil, errors.New(typed)
            })
            return dialer, typed, nil
        default:
            return nil, "", fmt.Errorf("invalid error dialer config")
        }
    })
}

func main() {
    // ...
  opts := mobileproxy.NewSmartDialerOptions(mobileproxy.NewListFromLines(*testDomainsFlag), *configFlag)
    opts.SetLogWriter(mobileproxy.NewStderrLogWriter())
    RegisterErrorConfig(opts, "error")
  //...
}