← ყველა სტატია

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-ის დამასრულებელი ფრონტის უკან --resolve 443-ზე არასწორი შემოწმებაა. დაამატეთ საკონტროლო ჰოსტი, რომელიც არ შეგიცვლიათ.
  • Ingress-იდან Gateway API-ზე ნებისმიერი გადასვლის შემდეგ შეამოწმეთ ყველაფერი, რაც ადრე პორტისგან დამოუკიდებელი ანოტაციებიდან მოდიოდა: ავთენტიფიკაცია, წყაროების allowlist-ები, rate limit, WAF-ის წესები.
  • შესვლის გვერდის დახურვა WordPress-ის დახურვას არ ნიშნავს: xmlrpc.php დამოუკიდებლად ავთენტიფიცირებს და ორივე listener-ზე უნდა დაიხუროს.