ვარსკვლავი Vault-ის გზის შუაში wildcard არ არის
ვადაგასულმა ტოკენმა საიდუმლოებების ოპერატორი გააჩერა. მისმა ხელახლა გაცემამ უფრო ძველი ბაგი გამოავლინა: Vault-ის 27 პოლიტიკა * სიმბოლოთი გზის შუაში ჩუმად კრძალავდა იმას, რასაც აცხადებდა.
Gambchamp-ში საერთო HashiCorp Vault რამდენიმე კლიენტის გარემოს ემსახურება, ერთ-ერთ კლასტერში კი საიდუმლოებების ოპერატორი მისგან მნიშვნელობებს Kubernetes-ში სინქრონიზებს. ერთ დღეს ოპერატორი უკვე ექვსი საათი იყო crash-loop-ში — 68 გადატვირთვა, და ყოველი reconcile ვარდებოდა:
PUT /v1/auth/token/renew-self → 403
* permission denied
* invalid token
ორი პრობლემა და არა ერთი
ადვილია მხოლოდ პირველი სტრიქონის წაკითხვა და პოლიტიკაში პრობლემის ძებნა. გადამწყვეტი მეორეა: არავალიდურ ტოკენზე Vault ორივე შეტყობინებით პასუხობს. თავად ავარია მხოლოდ ის იყო, რომ ოპერატორის სტატიკური ტოკენის ვადა გავიდა ან გაუქმდა.
ხელახლა გაცემა მექანიკური უნდა ყოფილიყო. არ გამოვიდა. ახალი ტოკენი გარემოს სამი დოკუმენტირებული read-only პოლიტიკით ოპერატორისთვის საჭირო ოთხიდან სამ გზას კითხულობდა. მეოთხე permission denied-ს აბრუნებდა, თუმცა პოლიტიკა მას პირდაპირ ასახელებდა.
Glob, რომელიც არასოდეს ყოფილა glob
Vault-ის ACL-ში * wildcard არის მხოლოდ გზის ბოლო სიმბოლოდ. + ზუსტად ერთ სეგმენტს ემთხვევა. ყველა სხვა ადგილას * უბრალოდ სეგმენტია, რომლის სახელიც ფაქტობრივად *-ია:
# wildcard-ს ჰგავს, ემთხვევა მხოლოდ სეგმენტს სახელად "*"
path "…/frontend/*/config" { capabilities = ["read"] }
# როგორი უნდა ყოფილიყო
path "…/frontend/+/config" { capabilities = ["read"] }
ყველა პოლიტიკის გადამოწმებამ 27 იპოვა *-ით გზის შუაში. Vault ასეთ პოლიტიკას ვალიდურად იღებს — „ეს შაბლონი არასოდეს დაემთხვევა“ ტიპის შემოწმება არ არსებობს.
ნიშანი იმისა, რომ ეს შაბლონის შეცდომა იყო და არა განზრახვა: შესაბამისი ფართო პოლიტიკა ყველა კლიენტისთვის სწორად იყო დაწერილი, +-ით. ესე იგი, ძველი ტოკენი მთელი ამ ხნის განმავლობაში სწორედ მას ატარებდა — ყველა კლიენტის ფრონტენდის საიდუმლოებების წაკითხვის უფლებას და არა მხოლოდ საკუთარის. ტოკენის ვადის გასვლამ ზედმეტი უფლებები გამოავლინა, რომლებიც უხილავი იყო, სანამ ყველაფერი მუშაობდა.
გამოსწორება
ავარიის შუაში 27 საერთო პოლიტიკის შეცვლა არ დავიწყე. ამის ნაცვლად შევქმენი ერთი ცალკე პოლიტიკა სწორი + სინტაქსით, ზუსტად იმ ოთხ გზაზე, რომელსაც ოპერატორი კითხულობს, და გავეცი ახალი ტოკენი ოპერატორისთვის სამი მნიშვნელოვანი თვისებით:
defaultდატოვეთ პოლიტიკების სიაში — იქ არისrenew-selfდაlookup-self, მათ გარეშე იგივე ავარია ტაიმერით განმეორდება;-period-ttl-ის ნაცვლად, რათა ტოკენი განახლდეს, სანამ მომხმარებელი ცოცხალია;-orphan, რათა მისი შემქმნელი ტოკენის გაუქმება კასკადურად არ გავრცელდეს.
მიერთებამდე გავუშვი ზუსტად ის გამოძახება, რომელიც ვარდებოდა (token renew), წავიკითხე ოთხი საჭირო გზა და შევამოწმე, რომ სხვა გარემოს გზა აკრძალულია. საერთო შაბლონების გასწორება ცალკე, აუჩქარებელ ამოცანად იქცა.
დასკვნები
- Vault-ის 403 ორი შეცდომის სტრიქონით — მეორე წაიკითხეთ.
invalid tokenპოლიტიკის პრობლემა არ არის. *გზის შუაში ლიტერალია. ერთი სეგმენტისთვის —+, და გახსოვდეთ, რომ Vault არ გაგაფრთხილებთ.vault token capabilities <path>ერთადერთია, რაც პოლიტიკაზე სიმართლეს ამბობს.- წვდომას არასოდეს „ასწორებთ“ უფრო ფართო პოლიტიკის მიმაგრებით. ეს მყისიერად მუშაობს და ჩუმად სხვა გარემოების წაკითხვას იძლევა.
- ნამდვილი სისუსტე სტატიკური ტოკენებია. Kubernetes auth ServiceAccount-ით ამ კლასის გაუმართაობას მთლიანად აქრობს.