Basic auth გაქრა 80-ე პორტზე Ingress-იდან Gateway API-ზე გადასვლის შემდეგ
ყველა სტატუსი მწვანე იყო, ჩემი curl 401-ს აბრუნებდა. WordPress-ის შესვლა კი ყველასთვის ღია იყო: Gateway API პოლიტიკას ერთ listener-ს აბამს, Ingress-ის ანოტაციები კი ყველა პორტს ფარავდა.
ორი კვირის შემდეგ, რაც Optimacros-ის საჯარო მარკეტინგული საიტები ingress-nginx-იდან Envoy Gateway-ზე გადავიტანეთ — მიგრაცია ჰოსტ-ჰოსტ იყო შემოწმებული, — WordPress-ის შესვლის გვერდი ცხრავე საიტზე პაროლის გარეშე აღმოჩნდა ხელმისაწვდომი. პირდაპირ ბრაუზერიდან.
ყველაზე უსიამოვნო ის არის, რომ ყველა შემოწმება საპირისპიროს ამბობდა:
- ყოველი
SecurityPolicyიყოAccepted: True; - ყოველი
HTTPRoute—AcceptedდაResolvedRefs; - Gateway-ის შემოწმება
curl --resolve <host>:443:<gateway-ip>-ით 401-ს აბრუნებდა, ზუსტად ჩაფიქრებულისამებრ.
მანიფესტები სწორი იყო, სტატუსები მწვანე, ჩემი საკუთარი შემოწმება კი „სწორ“ პასუხს იმეორებდა. არ ეთანხმებოდა მხოლოდ ბრაუზერი.
მარშრუტი ერთ listener-ზე ცხოვრობდა
დაცული მარშრუტი ასე იყო მიბმული:
parentRefs:
- kind: Gateway
name: <gateway>
sectionName: https # მხოლოდ პორტი 443
მაგრამ ეს პლატფორმა კონტენტს განზრახ :80 listener-ზე აწვდის. გარე nginx-ფრონტი TLS-ს ასრულებს და კლასტერთან ჩვეულებრივი HTTP-ით მუშაობს, ხოლო უპირობო გადამისამართება :80-ზე ERR_TOO_MANY_REDIRECTS-ს იძლეოდა — Gateway API-ს ფილტრებს არ შეუძლიათ „გადამისამართება მხოლოდ მაშინ, თუ მოთხოვნა ჯერ არ არის HTTPS“, რადგან X-Forwarded-Proto-ს არ კითხულობენ.
ესე იგი, კლიენტების რეალური გზა პორტი 80 იყო. პორტ 80-ზე კი შესვლის გვერდის მარშრუტი საერთოდ არ არსებობდა. მოთხოვნები ზოგად PathPrefix: / წესში ცვიოდა და WordPress-ში ყოველგვარი ავთენტიფიკაციის გარეშე ხვდებოდა.
დაფარვა ერთი-ერთზე არ ითარგმნება
აი, კონცეპტუალური განსხვავება, რამაც ყველაფერი გამოიწვია. ingress-nginx auth-* ანოტაციებს Ingress-ზე პორტისგან დამოუკიდებლად იყენებდა: ერთი ობიექტი 80-საც ფარავდა და 443-საც. Gateway API მარშრუტს — და, შესაბამისად, ნებისმიერ პოლიტიკას, რომელიც მას მიზნად ისახავს, — კონკრეტულ listener-ს აბამს. გზებისა და ანოტაციების ერთი-ერთზე თარგმნა დაფარვის ერთი-ერთზე თარგმნას არ ნიშნავს.
--resolve …:443-ით შემოწმება კი ზუსტად იმ გზას ამოწმებდა, რომლითაც არავინ სარგებლობს.
გამოსწორება
წყვილი HTTPRoute sectionName: http-ზე, იგივე Exact-დამთხვევით, იგივე ბექენდით, basic auth-ის იგივე საიდუმლოებით და საკუთარი SecurityPolicy-ით. X-Forwarded-Proto: https სათაურის ფილტრიც უნდა დაკოპირებულიყო, თორემ WordPress, რომლის საიტის მისამართი HTTPS-ია, 301-ით პასუხობს და ფრონტი ციკლში ვარდება.
პრიორიტეტები ისევ ჩვენს მხარესაა: Gateway API Exact-ს PathPrefix-ზე მაღლა აყენებს, ამიტომ AJAX-ის ენდპოინტს, რომელსაც საჯარო ფორმები ეყრდნობა, მოგვიანებით შეიძლება მიეცეს საკუთარი მარშრუტი ავთენტიფიკაციის გარეშე, შესვლის გვერდის გახსნის გარეშე. ცვლილება Git-ით გავიდა — GitOps-კონტროლერი ხელით გაკეთებულ ყველაფერს აბრუნებს, — და მხოლოდ დამატებითი იყო, ამიტომ დაბრუნება :443-ის მომუშავე გზას არ შეეხებოდა.
დასკვნები
- პოლიტიკის
Accepted: Trueნიშნავს, რომ ის მიზანს მიება, და არა იმას, რომ მიზანი ტრაფიკს ფარავს. სტატუსის ველი „ამ listener-ს დაცული მარშრუტი არ აქვს“ არ არსებობს. - შეამოწმეთ იმ გზით, რომლითაც რეალური კლიენტები დადიან. TLS-ის დამასრულებელი ფრონტის უკან
--resolve443-ზე არასწორი შემოწმებაა. დაამატეთ საკონტროლო ჰოსტი, რომელიც არ შეგიცვლიათ. - Ingress-იდან Gateway API-ზე ნებისმიერი გადასვლის შემდეგ შეამოწმეთ ყველაფერი, რაც ადრე პორტისგან დამოუკიდებელი ანოტაციებიდან მოდიოდა: ავთენტიფიკაცია, წყაროების allowlist-ები, rate limit, WAF-ის წესები.
- შესვლის გვერდის დახურვა WordPress-ის დახურვას არ ნიშნავს:
xmlrpc.phpდამოუკიდებლად ავთენტიფიცირებს და ორივე listener-ზე უნდა დაიხუროს.