საჯარო SSH რელეზე გავლისას ორ ურთიერთდაუკავშირებელ საზღვარზე ფერხდება და ერთის გასწორება ჩვეულებრივ მეორეს ავლენს. ან კიდე HTTP პასუხს აბრუნებს ნაკადის გატარების ნაცვლად, ან რელე წინ ამატებს სათაურს, რომლის წაკითხვაზეც ბექენდს არასდროს შეუთანხმებია. სამი პირობა განსაზღვრავს, რომელს უყურებთ: რაზე მიუთითებს რეალურად საჯარო ჩანაწერი, რას უგზავნის ნაკადის ბლოკი ზედა დინებას და რომელ სახელს ამოწმებს SSH კლიენტი. იმუშავეთ მათზე ამ თანმიმდევრობით.

ორი საზღვარი, ორი სიმპტომი

კიდის ხარვეზი ისე გამოიყურება, თითქოს HTTP სტატუსის გვერდი მოდის იქ, სადაც SSH ბანერი უნდა იყოს. კავშირი TCP დონეზე სრულდება და პირველი ბაიტები ვებ სერვერის ტექსტია. ეს პროტოკოლის შეუთანხმებლობაა და არა დაკარგული პაკეტი. ის ასევე გეუბნებათ, რომ კიდე განზრახ სხვა რამეს ემსახურება ამ სახელისთვის.

ზედა დინების ხარვეზი სხვაგვარად გამოიყურება. კავშირი sshd-მდე აღწევს, sshd კითხულობს ბაიტებს, რომლებიც მისი მოსალოდნელი იდენტიფიკაციის გაცვლა არ არის, და სესია იღუპება ან იკიდება გასაღების არასდროს შეთავაზებით.

ამ ორის არევა ადვილია, რადგან ორივე ქმნის კლიენტს, რომელიც უკავშირდება და შემდეგ ფერხდება. პირველი პროტოკოლური პასუხი, რომელსაც მიიღებთ, არის ის, რაც მათ განასხვავებს, ამიტომ ის ბილეთში უნდა იყოს.

PROXY სათაური შეტყობინებაა და არა გადამრთველი

ნაკადის მოდულში proxy_protocol on NGINX-ს ავალებს სასარგებლო დატვირთვამდე ზედა დინებისკენ დაწეროს PROXY პროტოკოლის სათაური. ის არ რთავს TCP პროქსს და არაფერი აქვს საერთო SSH დაშიფვრასთან. ეს მიმღებისთვის მიმართული შენიშვნაა. თუ მიმღები ვერ წაიკითხავს, ის ნაკადის დასაწყისში ნაგავდება.

მიმღებმა სერვისმა განზრახ უნდა მოიხმაროს ეს სათაური. ჩვეულებრივი sshd კავშირის პირველ ბაიტებად SSH იდენტიფიკაციის გაცვლას ელოდება, ამიტომ მოულოდნელი შესავალი ხელის ჩამორთმევას ისე არღვევს, რომ დაზიანებულ სერვერს ჰგავს.

stream {
    server {
        listen 2222;
        proxy_pass 10.77.0.20:22;
    }
}

ეს ფრაგმენტი მთლიანი მოქმედი რელეა VPN-ით მისადგომი ბექენდისთვის. PROXY დირექტივა არ ჩნდება, რადგან მიმღები ამ პროტოკოლზე არ ლაპარაკობს, და ეს არყოფნა გადაწყვეტილებაა და არა გამოტოვება.

ორივე მიმართულებაც გამოყავით. proxy_protocol-ის listen სტრიქონზე დაყენება ნიშნავს, რომ NGINX ელოდება საკუთარი კლიენტის მიერ სათაურის პირველად გაგზავნას; ჩვეულებრივი SSH კლიენტისთვის მისი ჩართვა ზუსტად იმ პრობლემის საპირისპიროს ქმნის, რომლის გადაჭრასაც ხალხი ჩვეულებრივ ცდილობს.

რას აღწევს რეალურად საჯარო ჰოსტის სახელი

HTTP 400 გვერდი SSH სესიაში კიდის შესახებ მტკიცებულებაა. გზაზე რაღაც HTTP-ზე ლაპარაკობს და ბექენდზე გასაღების ან ანგარიშის არანაირი სამუშაო ამას არ შეცვლის. შეწყვიტეთ ბექენდის შეცვლა, სანამ კიდე მოწესრიგდება.

Cloudflare-ის ჩვეულებრივი პროქსირებული ჩანაწერი თავის მხარდაჭერილ HTTP და HTTPS ტრაფიკს განსაზღვრულ პორტებზე ატარებს. ჰოსტის სახელისთვის პროქსის ჩართვა ზოგად TCP რელეს არ ქმნის და SSH-ის 443 პორტზე გადატანა მას HTTPS-ად არ აქცევს.

არსებობს ორი სამუშაო მიმართულება. მხოლოდ DNS ჩანაწერს შეუძლია მიუთითოს თქვენს საკუთარ TCP რელეზე, რაც გამოვლენის გადაწყვეტილებას თქვენს ხელში ტოვებს. ალტერნატივად გამოიყენეთ პროდუქტი, რომელიც ცალსახად ადოკუმენტებს SSH-ის ტრანსპორტირებას, საკუთარი წყაროს, კლიენტისა და წვდომის კონფიგურაციით.

რასაც არ უნდა აირჩიოთ, რელეს მაინც სჭირდება VPN მარშრუტი ბექენდამდე, ნებადართული კავშირი და დაბრუნების გზა. მარშრუტი სავალდებულოა, რადგან საჯარო მხარე მუშაობს.

შეინარჩუნეთ SSH იდენტობა სტაბილურად ფსევდონიმით

მომხმარებლებს ჩვეულებრივ სურთ გააგრძელონ არსებული ჰოსტის სახელის აკრეფა. SSH კონფიგურაციის ფსევდონიმს შეუძლია ეს გააკეთოს რელეში არაფრის შეცვლის გარეშე და ცვლილებას კლიენტის მხარეს ტოვებს, სადაც მისი ადგილია.

Host git.example.com
    HostName ssh-entry.example.net
    Port 2222
    User git
    HostKeyAlias git.example.com

HostKeyAlias-ის გარეშე OpenSSH ჰოსტის გასაღებს ეძებს იმ სახელით, რომელზეც უკავშირდება, ამიტომ ჩანაწერი ინაცვლებს და ყოველი მომხმარებელი პირველ გამოყენებაზე ხედავს გაფრთხილებას შეცვლილი გასაღების შესახებ. ფსევდონიმის დაყენება known-hosts ჩანაწერებს სტაბილურად ინახავს, სანამ კავშირი კვლავ რელეზე მიდის.

ეს ფსევდონიმი მხოლოდ SSH-ზე დაფუძნებულ დისტანციურ საცავებს ეხება. HTTPS Git URL მას არ ეკითხება და ტიპიური დისტანციური URL უნდა შეესაბამებოდეს იმ ტრანსპორტს, რომელიც რეალურად მოამზადეთ.

რაც არ უნდა გააკეთოთ, ეს არის ჰოსტის გასაღების შემოწმების გამორთვა გაფრთხილების მოსაშორებლად. ეს ხსნის დაცვას, რომლის შეხებაც გადაგზავნის შეკეთებას არასდროს უთხოვია, და გარეგნულ დისკომფორტს რეალურ გამოვლენად აქცევს.

შეამოწმეთ ყოველი ნახტომი ცალკე

გამოსცადეთ საჯარო მსმენელი ცალკე, შემდეგ რელედან ბექენდამდე კავშირი რელეს ჰოსტიდან, და მხოლოდ ამის შემდეგ კლიენტი ბოლოდან ბოლომდე. ამ სამი ტესტიდან თითოეული განსხვავებულ ფენას გამორიცხავს. ერთის გამოტოვება ნიშნავს, რომ დარჩენილი ორი შედეგი ვერ იქნება განმარტებული. სამი დაკვირვება, სამი ადგილი, სადაც ხარვეზი შეიძლება ცხოვრობდეს.

შეინახეთ დანიშნულების მისამართი, პორტი და პროტოკოლის პირველი ბაიტები ყოველ შედეგთან ერთად. ეს სამეული განასხვავებს კიდის შეცდომას VPN მარშრუტიზაციის პრობლემისგან და SSH ავთენტიფიკაციის ხარვეზისგან, და ეს არის განსხვავება შეკეთებასა და ვარაუდს შორის.

დაბოლოს, დაადოკუმენტეთ განზრახული გამოვლენა. TCP რელე, რომელიც SSH-ს კერძო ბექენდამდე მიჰყავს, განზრახ გახსნილი ხვრელია საჯარო პერიმეტრზე და იმსახურებს იმავე გადახედვას, როგორც ნებისმიერი სხვა შემომავალი სერვისი.

დაკავშირებული სტატიები