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

რას ფარავს შესაძლებლობა

თავისი სახელთა სივრცის შიგნით, NET_ADMIN-ის მქონე პროცესს შეუძლია ინტერფეისების აწევა და დაწევა, მისამართების მინიჭება, მარშრუტების დამატება და წაშლა და firewall-ის წესების წერა, რაც არის ოპერაციათა ის ჯგუფი, რომელსაც capabilities(7) ამ შესაძლებლობის ქვეშ აგროვებს. მას ასევე შეუძლია ინტერფეისის დონის პარამეტრების რეგულირება, რომლებიც აკონტროლებენ, როგორ აყენებს ბირთვი ტრაფიკს რიგში და ფილტრავს მას. VPN კლიენტს, როგორც წესი, გაშვებისას რამდენიმე მათგანი სჭირდება და შემდეგ სხვა არაფერი. ამიტომ სურათების უმეტესობა ითხოვს უფრო დიდ წვდომას, ვიდრე იყენებს.

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

სახელთა სივრცე წყვეტს დაზიანების რადიუსს

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

გადაიტანეთ ეს კონტეინერი ჰოსტის ქსელში და იგივე მინიჭება ახლა არედაქტირებს ჰოსტის მარშრუტებს და ჰოსტის firewall-ს, რადგან ცალკე სახელთა სივრცე აღარ დარჩა. კლიენტს, რომელსაც ერთი გვირაბი უნდა ემართა, შეუძლია მთელი მანქანის ტრაფიკის გადამისამართება, და შეცდომა მის დაშლის სკრიპტში ჰოსტზე ტოვებს წესებს, რომლებიც არავის დაუწერია. თავად შესაძლებლობაში არაფერი შეცვლილა; შეიცვალა კონტექსტი. ამიტომ ერთი და იგივე compose ფაილი ორ ჰოსტზე სხვაგვარად იქცევა.

სამი წინაპირობა, რომლებიც ერთად იყრიან თავს

VPN კონტეინერებში გაშვების ხარვეზები, როგორც წესი, ეხება სამი ცალკე რამიდან ერთს: შესაძლებლობას, გვირაბის მოწყობილობას და პროტოკოლის ბირთვულ მხარდაჭერას. სამივეს ერთდროულად მიცემა მუშაობს და ასევე შეუძლებელს ხდის შემდეგი ხარვეზის მიკუთვნებას. მინიმალური compose ნაწილი აძლევს შესაძლებლობას და ცხადად გადასცემს მოწყობილობის კვანძს:

services:
  vpn:
    image: example/vpn-client:latest
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1

წაიკითხეთ თავად სურათის დოკუმენტაცია, თუ რომელი sysctl სჭირდება, რადგან კონტეინერში sysctl-მა შეიძლება მოითხოვოს დამატებითი პრივილეგია ან ჰოსტის დონის პარამეტრი. სადაც სურათი მხოლოდ მომხმარებლის სივრცის რეჟიმს უჭერს მხარს, მოწყობილობა საერთოდ არ არის საჭირო და შესაძლებლობების სია შესაბამისად მცირდება.

მიეცით ვიწრო ოპერაცია და არა რეჟიმი

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

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

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

შეამოწმეთ ცვლილება და ჩაწერეთ, რატომ არსებობს ნებართვა

სანამ გვირაბს გამართავთ, დაადასტურეთ, თუ რა მიიღო კონტეინერმა სინამდვილეში. ქვემოთ მოცემული შემოწმება აცნობს დამატებულ შესაძლებლობებს და ქსელურ რეჟიმს, შემდეგ კი აჩვენებს, როგორ გამოიყურება ინტერფეისების სია შიგნიდან:

docker inspect --format '{{.HostConfig.CapAdd}} {{.HostConfig.NetworkMode}} {{.HostConfig.Privileged}}' vpn
docker exec vpn sh -c 'grep CapEff /proc/self/status'
docker exec vpn ip -br addr
docker exec vpn ip route

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

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

დაწერეთ მიზეზი ყოველი შესაძლებლობის გვერდით: რომელ ოპერაციას სჭირდებოდა ის და რა ფუჭდება მის გარეშე. ეს შენიშვნა გადაუვლის სურათის განახლებებს და ეს არის განსხვავება გადამოწმებულ პრივილეგიათა სიასა და კოპირებით გაზრდილ სიას შორის.

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