დაშიფრული ბაიტების გადაცემა სერტიფიკატის არასდროს ფლობისას არის ის, რასაც TLS passthrough რელე აკეთებს, და ეს მოწყობა მოსახერხებელიცაა და ოდნავ დამაბნეველიც. რადგან არაფერი განიშიფრება, HTTP ფორმის არაფერი არ არსებობს ფილტრაციისთვის, ამიტომ ჩვეულებრივი location ბლოკი და მისი წვდომის წესები აქ არაფერს არ იძლევა. გადაწყვეტილება, რომელიც NGINX-ს აქვს, თავად კავშირს ეხება: რომელი ქსელური peer-ი შემოვიდა და უნდა გადავიდეს თუ არა ის საერთოდ.

გადაწყვეტილება stream-ს ეკუთვნის, არა HTTP-ს

stream კონტექსტში NGINX TCP სესიებთან მუშაობს. ის ხედავს კავშირის peer მისამართს და შეუძლია მასზე დალაგებული allow და deny წესები გამოიყენოს, სანამ რომელიმე ბაიტი backend-ს მიაღწევს. ეს სრული მიღების გადაწყვეტილებაა და არ მოითხოვს კერძო გასაღებს, სერტიფიკატს ან HTTP ანალიზს.

MechanismWhat it decidesWhere it lives
stream allow/denyWhether this TCP peer is relayedstream server block
ssl_preread mapWhich backend a named connection goes tostream, with the preread module
HTTP location ruleWhether an HTTP request is servedhttp server block

ის სამი ხაზი არასდროს ანაცვლებს ერთმანეთს. HTTP წვდომის დირექტივის კოპირება ნებისმიერ ფაილში, რომელიც 443 პორტს ახსენებს, არაფერს ცვლის, რადგან stream სერვერი არასდროს კითხულობს http კონტექსტს.

მიიღეთ კავშირი, სანამ გადასცემთ

ჩათვალეთ, რომ არსებობს არსებული ინსტალაცია stream და stream-access მოდულებით, VPN კლიენტები წყაროს მისამართებს 10.90.0.0/24-ში ინახავენ, და backend 192.168.50.20:443-ზე უკვე ემსახურება მოსალოდნელ HTTPS იდენტობას.

stream {
    server {
        listen 443;

        allow 10.90.0.0/24;
        deny all;

        proxy_pass 192.168.50.20:443;
    }
}

წაიკითხეთ ეს როგორც ახალი listener-ის ფრაგმენტი, არა როგორც მოქმედი კონფიგურაციის პირდაპირი ჩანაცვლება. ჯერ გადახედეთ არსებულ listener-ებს და include-ებს, რადგან უკვე დაკავებულ პორტზე მეორე listener მარცხდება reload-ის დროს, არა მოთხოვნის დროს.

ყურადღება მიაქციეთ, რა აკლია: listen ... ssl არ არის, სერტიფიკატის დირექტივა არ არის. NGINX გადასცემს დაშიფრულ ნაკადს, ხოლო backend ამთავრებს TLS-ს და წარმოადგენს სერტიფიკატს, რომელსაც კლიენტი ამოწმებს. allowlist-ზე ჩავარდნილი კლიენტის TCP სესია უარყოფილია, არა HTTP 403 გვერდი, და ნებისმიერი ხელსაწყო, რომელიც სტატუსის კოდს ელოდება, რაღაც უსარგებლოს შეატყობინებს.

რას ფარავს allowlist და რას არა

თუ რელე უკვე ირჩევს backend-ებს სერვერის სახელით, ssl_preread და map შეუძლია გააგრძელოს ეს სამუშაო, თუ მოდული ხელმისაწვდომია. სახელს მაინც კლიენტი აწვდის და სახელის წარდგენა არ ამტკიცებს, რომ კლიენტი VPN-ს შეუერთდა.

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

ღირს კიდევ ორი ხარვეზის დასახელება. prefix-ის დამთხვევა არაფერს ამბობს იმაზე, რომელი ინტერფეისით მოვიდა პაკეტი, და სხვაგან არსებული HTTP წესი ვერ შეზღუდავს ამ listener-ს. ორივე მიზეზია იმისა, რომ ჰოსტის დონის ingress პოლიტიკა სურათში შევინარჩუნოთ, ნაცვლად იმისა, რომ ერთი allow ხაზი მთელ საზღვრად მივიჩნიოთ. ჩაწერეთ საზღვარი როგორც ორი კონტროლი, რომლებიც უნდა შეთანხმდეს, რათა რომელიმეს ცვლილება გადაიხედოს.

ვის მისამართს ხედავს NGINX სინამდვილეში?

დატვირთვის ბალანსირება, სხვა proxy ან source NAT შეიძლება NGINX-ის წინ შუამავალი ჩასვას, ამიტომ დაკვირვებული peer არ არის VPN კლიენტის შიდა მისამართი. შეამოწმეთ რეალური გზა prefix-ის არჩევამდე, რადგან არასწორ მისამართზე დაწერილი allowlist ან თარჯიმნის უკან ყველას უშვებს, ან არავის.

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

შეამოწმეთ ორივე შედეგი reload-ამდე

დაადასტურეთ კონფიგურაცია, გააკეთეთ reload, შემდეგ ორჯერ შეამოწმეთ: ახალი დაშვებული სესია, რომელიც უნდა მუშაობდეს, და უარყოფილი, რომელიც არ უნდა მუშაობდეს. დაშვებულ ტესტში შეინარჩუნეთ backend სერტიფიკატის ჩვეულებრივი შემოწმება, რადგან რელე, რომელიც უკავშირდება, მაგრამ backend-ს ვერ ამოწმებს, ერთი პრობლემა გადაჭრა და მეორე შექმნა.

nginx -t
ss -tnp | grep ':443'

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

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