უსაფრთხო და ეფექტური სენდბოქსის შექმნა Windows-ზე Codex-ის ჩართვისთვის
დევიდ ვიზენი, ტექნიკური პერსონალის წევრი
როდესაც 2025 წლის სექტემბერში Codex-ის საინჟინრო გუნდს შევუერთდი, Windows-ისთვის განკუთვნილ Codex-ს სენდბოქსის იმპლემენტაცია არ ჰქონდა, რაც ნიშნავდა, რომ OpenAI-ს კოდირების აგენტების გამოყენებისას Windows-ის მომხმარებლები იძულებული იყვნენ, ორი ცუდი ვარიანტიდან ერთ-ერთი აერჩიათ:
- თითქმის ყველა იმ ბრძანების დადასტურება (წაკითხვის ოპერაციებისაც კი), რომელთა შესრულებაც პროგრამირების აგენტს სურდა, რაც არაეფექტური და შემაწუხებელია. Codex-ის გამოყენების ერთ-ერთი მთავარი უპირატესობა ისაა, რომ მთელი რუტინული სამუშაოს თავად შესრულება არ გიწევთ.
- სრული წვდომის რეჟიმის ჩართვა: Codex-ისთვის ყველა ბრძანების დამტკიცებისა და შეზღუდვების გარეშე გაშვების შესაძლებლობის მიცემა, რაც ამცირებს ბარიერებს ზედამხედველობის ხარჯზე.
Codex, ჩვენი პროგრამირების აგენტი, მუშაობს დეველოპერების ლეპტოპებზე — იქნება ეს CLI-ს, IDE-ს გაფართოებისა თუ სამუშაო დაფის აპის მეშვეობით. ის მართავს საუბარს კლავიატურასთან მყოფ ადამიანსა და ღრუბლოვან გარემოში გაშვებულ მოდელს შორის, რათა შესრულდეს ლოგიკური დასკვნის გამოტანა.
Codex ნაგულისხმევად რეალური მომხმარებლის ნებართვებით მუშაობს, რაც ნიშნავს, რომ მას შეუძლია, შეასრულოს ყველა ის მოქმედება, რომლის შესრულებაც მომხმარებელს შეუძლია. ეს ეფექტური და პოტენციურად სახიფათოა. კოდირების მოდელმა შეიძლება სისტემას ადგილობრივად ბრძანებების შესრულება დაავალოს — ტესტების გაშვებით დაწყებული, ფაილის წაკითხვით ან რედაქტირებით გაგრძელებული და Git-ის განშტოების შექმნით დასრულებული — ამიტომ Codex-ის ნაგულისხმევი რეჟიმი ცდილობს ეფექტიანობასა და უსაფრთხოებას შორის სწორი ბალანსის პოვნას. ეს ნაგულისხმევი რეჟიმი Codex-ს საშუალებას აძლევს, ფაილები თითქმის ყველგან წაიკითხოს და ისინი თქვენს სამუშაო სივრცეში (ანუ დირექტორიაში, საიდანაც Codex-ს უშვებთ) ჩაწეროს, ინტერნეტზე წვდომის გარეშე, თუ თავად არ მიუთითებთ, რომ ეს გსურთ. ფაილების ჩაწერისა და ქსელზე წვდომის უსაფრთხო ფარგლებში ავტომატურად შეზღუდვის მისაღწევად Codex-ს სჭირდება სენდბოქსის გარემო, რომელიც ამ შეზღუდვებს რეალურად აღასრულებს.
სენდბოქსი არის იზოლირებული შესრულების გარემო. როდესაც დეველოპერი Codex-ს იყენებს, მისი კომპიუტერის ოპერაციული სისტემა ბრძანებას შეზღუდული უფლებებით უშვებს, ხოლო ეს შეზღუდვები პროცესების სქემის ქვედა დონეებზეც ვრცელდება. Codex-ის ყოველი ბრძანება თავიდანვე სენდბოქსშია იზოლირებული და ყოველი შემდგომი პროცესი იმავე საზღვრის შიგნით რჩება.
Codex-ს ეფექტური სენდბოქსის დანერგვისთვის სჭირდება იზოლაციის ფუნქციები, რომლებსაც კომპიუტერის ოპერაციული სისტემა აღასრულებს. ზოგიერთი ოპერაციული სისტემა უზრუნველყოფს ხელსაწყოებს, რომლებიც ამას კარგად აკეთებს (მაგალითად, macOS-ზე Seatbelt, Linux-ზე seccomp ან bubblewrap); თუმცა Windows ამჟამად ამ ტიპის შესაძლებლობას ჩაშენებულად არ უზრუნველყოფს.
იმისთვის, რომ Codex Windows-ზეც ისეთივე უსაფრთხო და სასიამოვნო გამოსაყენებელი ყოფილიყო, როგორც სხვა პლატფორმებზე, საჭირო გახდა ჩვენი საკუთარი სენდბოქსის დანერგვა.
Windows უზრუნველყოფს გარკვეულ ინსტრუმენტებსა და საწყის ფუნქციებს იზოლაციისთვის. მიუხედავად იმისა, რომ არცერთი მათგანი სრულად არ აკმაყოფილებდა ჩვენს მოთხოვნებს, ჩვენ განვიხილეთ რამდენიმე პოტენციური გადაწყვეტა — კერძოდ, AppContainer, Windows Sandbox და Mandatory Integrity Control-ის მარკირება.
AppContainer
- რა: AppContainer არის Windows-ის საკუთრივი სენდბოქსი — შესაძლებლობებზე დაფუძნებული იზოლაციის მოდელი, რომელიც შექმნილია იმ აპებისთვის, რომლებმაც წინასწარ ზუსტად იცის, რაზე წვდომა სჭირდება.
- რატომ: მიმზიდველია, რადგან საუკეთესო ძალისხმევაზე დაფუძნებული შეზღუდვების ნაცვლად რეალურ OS-ის საზღვარს გვთავაზობს.
- რატომ არა: Codex არ არის ერთი მკაცრად შემოსაზღვრული აპლიკაცია. ის უზრუნველყოფს ღია ტიპის დეველოპერულ სამუშაო ნაკადებს: shell-ებს, Git-ს, Python-ს, პაკეტების მმართველებს, აწყობის ინსტრუმენტებსა და სხვა ორობით ფაილებს, რომლებიც აგენტს საჭიროდ მიაჩნია. პრაქტიკაში ამის გამო AppContainer ამ პრობლემისთვის შეუფერებელი აღმოჩნდა. ეს ძლიერი იზოლაცია იყო, მაგრამ სამუშაო დატვირთვების ბევრად უფრო ვიწრო კლასისთვის, ვიდრე პრინციპისთვის „აგენტს მივცეთ საშუალება, დეველოპერის მსგავსად იმოქმედოს“.
Windows Sandbox
- რა: Windows Sandbox არის Microsoft-ის ერთჯერადი მსუბუქი VM. გეძლევათ Windows-ის ახალი სამუშაო დაფა ძლიერი იზოლაციის საზღვრით და ყველაფერი, რასაც მასში გააკეთებთ, სესიის დასრულებისას ქრება.
- რატომ: საინტერესოა აშკარა მიზეზების გამო — ბევრად უფრო თავსებადია ნებისმიერ პროგრამულ უზრუნველყოფასთან, ვიდრე AppContainer, ხოლო უსაფრთხოების თვალსაზრისით, გაცილებით უფრო ძლიერი იზოლირებული გარემოა.
- რატომ არა: Codex-მა პირდაპირ უნდა იმოქმედოს მომხმარებლის რეალურ გამონატან ასლზე, ინსტრუმენტებსა და გარემოზე და არა ცალკე ერთჯერად სამუშაო დაფაზე, რომელსაც დაყენება და ჰოსტის/სტუმრის ხიდური დაკავშირება დასჭირდება. მას ასევე ჰქონდა პროდუქტის ფუნდამენტური პრობლემა: Windows Sandbox არ არის ხელმისაწვდომი Windows Home-ის SKU-ებზე.
მთლიანობის სავალდებულო კონტროლის (MIC) მთლიანობის მარკირება
- რა: Windows-ს აქვს კონცეფცია, რომელსაც „მთლიანობის დონეები“ ეწოდება, როგორიცაა დაბალი, საშუალო და მაღალი, რაც განსაზღვრავს, რამდენად ენდობა სისტემა ობიექტებსა და პროცესებს. ძირითადი წესი ის არის, რომ დაბალი მთლიანობის დონის მქონე პროცესს არ შეუძლია ჩაწერა მაღალი მთლიანობის დონის ობიექტში მაშინაც კი, თუ ჩვეულებრივი ACL ამას დაუშვებდა. მაგალითად, დაბალი მთლიანობის დონის პროცესი ნაკლებად სანდოდ ითვლება, ამიტომ Windows ბლოკავს მის ჩაწერას საშუალო მთლიანობის დონის ობიექტებში, თუ ეს ობიექტები ცხადად ხელახლა არ მოინიშნება ამის დასაშვებად.
- რატომ: MIC ქაღალდზე ელეგანტურად გამოიყურებოდა — გაუშვით Codex დაბალი მთლიანობის დონეზე, ხელახლა მონიშნეთ ჩაწერადი ძირეული დირექტორიები დაბალი მთლიანობის დონით და მიეცით Windows-ს საშუალება, უზრუნველყოს ჩაწერის აკრძალვა ყველა სხვა ადგილას. ეს მოგვცემდა ადმინისტრატორის უფლებების გარეშე გამოსაყენებელ გზას, რომლის უკან რეალური OS-ის მექანიზმი იდგებოდა.
- რატომ არა: ACL-ების მსგავსად, მთლიანობის ნიშნულები ცვლის ჰოსტის რეალურ ფაილურ სისტემას და ამ შემთხვევაში სემანტიკური ცვლილება განსაკუთრებით ფართოა. სამუშაო სივრცის დაბალი მთლიანობის მქონედ მონიშვნა მხოლოდ იმას არ ნიშნავს, რომ „Codex-ს აქ წერა შეუძლია“. ეს ნიშნავს, რომ დაბალი მთლიანობის პროცესებს, ზოგადად, შეუძლიათ იქ ჩაწერა. რეალურ დეველოპერის კომპიუტერზე ეს მომხმარებლის რეალურ სამუშაო ასლს ჰოსტისთვის დაბალი მთლიანობის მიმღებ წერტილად აქცევს, რაც გაცილებით უფრო სარისკოა, ვიდრე წვდომის კონტროლის სიების (ACL-ების) ფრთხილად და მიზნობრივად მინიჭება სენდბოქსის ერთი დიზაინისთვის. მაშინაც კი, თუ საშუალო მთლიანობის დონის დეველოპერის ინსტრუმენტები მუშაობას განაგრძობს, სამუშაო სივრცის საფუძვლად არსებული ნდობის მოდელი ისე შეიცვალა, რომ რთულია მისი იზოლირება, ხოლო დასაბუთება — კიდევ უფრო რთული.
ყველა ვარიანტის არაპერსპექტიულად შეფასების შემდეგ დავიწყეთ საკუთარი გადაწყვეტის დაპროექტება, რათა Windows-ის მომხმარებლებისთვის Codex-ის კარგი გამოცდილება შეგვეთავაზებინა.
ჩვენმა პირველმა მუშა პროტოტიპმა ჩვენთვის საჭირო იზოლაციის უზრუნველსაყოფად Windows-ის კონცეფციებისა და ინსტრუმენტების კომბინაცია გამოიყენა. თავიდანვე ერთ-ერთი მიზანი იყო, მას უფლებების ამაღლების მოთხოვნის გარეშე ემუშავა — ანუ Codex-ს არ დასჭირდებოდა მომხმარებლისთვის ადმინისტრატორის უფლებების მოთხოვნა მხოლოდ სენდბოქსის დასაყენებლად ან გასაშვებად. ეს ნიშნავდა იმის გარკვევას, როგორ დაგვეწესებინა გონივრული შეზღუდვები ორ საკითხზე: ფაილებში ჩაწერასა და ქსელზე წვდომაზე.
ფაილებში ჩაწერის ოპერაციებს საერთოდ რომ არ ვზღუდავდეთ, უსაფრთხოების პრობლემა გვექნებოდა. თუ ფაილებში ჩაწერის ოპერაციებს ზედმეტად შევზღუდავდით, სენდბოქსი მომხმარებლის პროდუქტიულობას შეაფერხებდა, რადგან მუდმივი დასტურის მოთხოვნა იქნებოდა საჭირო. ამ პრობლემის გადასაჭრელად დავეყრდენით Windows-ის ორ მნიშვნელოვან საბაზისო კომპონენტს: SID-ებსა და ჩაწერაზე შეზღუდულ ჟეტონებს.
SID, ანუ უსაფრთხოების იდენტიფიკატორი, არის იდენტობა, რომელსაც Windows ნებართვებს უკავშირებს. თითოეულ მომხმარებელს აქვს SID, ჯგუფებს აქვთ SID-ები და შესვლის ერთ სესიასაც კი ენიჭება საკუთარი SID. მაგალითად, ამჟამად შესულ სესიას შეიძლება ჰქონდეს SID, როგორიცაა S-1-5-5-X-Y. ადგილობრივი ადმინისტრატორების ჯგუფისთვის მინიჭებული SID, შესაძლოა, იყოს S-1-5-32-544.
Windows ასევე გაძლევთ საშუალებას, შექმნათ სინთეზური SID-ები, რომლებიც რეალურ მომხმარებელს არ შეესაბამება, მაგრამ მაინც შეიძლება გამოჩნდეს ACL-ებში (Access Control Lists — წვდომის კონტროლის სიები), რომლებიც განსაზღვრავს, ვის შეეძლოს კონკრეტული ფაილების ან დირექტორიების წაკითხვა, ჩაწერა ან შესრულება. ეს SID-ებს ჩვენი სენდბოქსისთვის სასარგებლო საბაზისო კომპონენტად აქცევს: შეგვიძლია SID-ები შევქმნათ მხოლოდ Codex-ის სენდბოქსისთვის, ისე რომ მანქანაზე სხვა არაფერზე გავლენა არ მოვახდინოთ.
პროცესის ჟეტონი არის Windows-ში არსებული უსაფრთხოების ობიექტები, რომლებიც განსაზღვრავს გაშვებული პროცესის იდენტობასა და პრივილეგიებს. ისინი განსაზღვრავს, რა მოქმედებების შესრულება შეეძლოს პროცესს. ჩაწერის შეზღუდვის მქონე ჟეტონი არის პროცესის ჟეტონის კონკრეტული ტიპი, რომლის გამოც Windows ჩაწერის ოპერაციებისას წვდომის დამატებით შემოწმებას ასრულებს.
ჩაწერის წარმატებით შესასრულებლად, ორი შემოწმება წარმატებით უნდა შესრულდეს:
- ჩვეულებრივი მომხმარებლის იდენტობა („ჟეტონის მფლობელი“) უნდა იყოს უფლებამოსილი ამის გაკეთებაზე
- ჟეტონის შეზღუდული SID-ების სიაში მინიმუმ ერთ SID-ს, ასევე, უნდა ჰქონდეს მინიჭებული წვდომა
პრაქტიკაში ამ შემოწმებებმა საშუალება მოგვცა, ACL-ების გამოყენებით ზუსტად განგვესაზღვრა, სად შეეძლო სენდბოქსს ფაილური სისტემის შეცვლა, რამაც უზრუნველყო ჩაწერის ოპერაციებისთვის საჭირო დეტალიზაციის დონე.
SID-ებისა და ჩაწერაზე შეზღუდული ჟეტონების გამოყენებით ჩვენი ამაღლებული პრივილეგიების არმქონე სენდბოქსი ასე მუშაობდა:
- სენდბოქსის კონფიგურაციამ შექმნა სინთეზური SID, სახელად
sandbox-write. sandbox-writeSID-ს მიენიჭა ჩაწერის, შესრულებისა და წაშლის წვდომა- მიმდინარე სამუშაო დირექტორია
- ნებისმიერი დამატებითი
writable_roots, რომელიც კონფიგურირებულიაconfig.toml-ში.
- სენდბოქსის კონფიგურაციამ იმავე SID-ს აშკარად აუკრძალა ჩაწერის წვდომა ისეთ ადგილებზე, როგორიცაა „ჩაწერადი ზონის შიგნით მხოლოდ წაკითხვადი“ ადგილები:
<cwd>/.git<cwd>/.codex<cwd>/.agents
- Codex-მა ბრძანებები გაუშვა ჩაწერაზე შეზღუდული ჟეტონით, რომლის შეზღუდული SID-ების სიაში შედის
ყველა, ამჟამად შესული სესიის SID დაsandbox-write-ის სინთეზური SID.
ამ პროცესმა ეფექტურად გადაჭრა ფაილებში ჩაწერის შეზღუდვის პრობლემა და პერსპექტიული ჩანდა. ახლა გვჭირდებოდა სენდბოქსის ქსელზე წვდომის შეზღუდვის გადაწყვეტა.
ქსელური წვდომის შეზღუდვა იზოლირებული გარემოს მნიშვნელოვანი ნაწილია; მის გარეშე მავნე კოდს შეეძლებოდა კომპიუტერიდან მონაცემების ფარულად გატანა ინტერნეტში. ვინაიდან გვსურდა, თავიდან აგვეცილებინა პრივილეგიების ამაღლების მოთხოვნა, ქსელური ტრაფიკის საიმედოდ დაბლოკვისთვის შეზღუდული ვარიანტები გვქონდა. ის ხელსაწყოები, რომელთა გამოყენებაც გვსურდა, მაგალითად Windows Firewall, როგორც წესი, ადმინისტრატორის ნებართვების გარეშე ვერ დაინსტალირდებოდა.
Windows Firewall-ის ვარიანტად არქონის გამო, შევზღუდეთ ის, რისი კონტროლიც შეგვეძლო. ვცადეთ, შვილობილი გარემო „fail-closed“ პრინციპით მოგვეწყო იმ სახის ქსელური ინსტრუმენტებისთვის, რომლებსაც დეველოპერები რეალურად იყენებენ, რათა Git-ის ბრძანებები, პაკეტების ინსტალატორები და ა.შ. სენდბოქსში წარუმატებლად დასრულებულიყო და მომხმარებელს ინტერნეტთან დაკავშირებული ნებისმიერი ოპერაციის დამტკიცება დასჭირვებოდა. იდეა იყო აშკარა შემოვლითი გზების „მოწამვლა“: პროქსის გათვალისწინებით ტრაფიკის არამოქმედ საბოლოო წერტილზე გაგზავნა, Git-ის HTTP(S) ტრანსპორტისთვის იმავეს გაკეთებინება და Git over SSH-ის დაუყოვნებლივ ჩავარდნა. გარდა ამისა, PATH-ის დასაწყისში დავამატეთ მცირე denybin დირექტორია და გადავაწყვეთ PATHEXT -ის თანმიმდევრობა, რათა SSH-ისა და SCP-ს სტაბ-სკრიპტები რეალურ ორობით ფაილებამდე აღმოჩენილიყო.
მაგალითად, აქ მოცემულია გარემოს კონკრეტული გადაფარვები, რომლებიც ქსელზე წვდომის შეზღუდვისთვის გამოვიყენეთ:
HTTPS_PROXY=http://127.0.0.1:9ALL_PROXY=http://127.0.0.1:9GIT_HTTPS_PROXY=http://127.0.0.1:9NO_PROXY=localhost,127.0.0.1,::1GIT_SSH_COMMAND=cmd /c exit 1
ამან ნორმალური, ხელსაწყოებით გენერირებული ტრაფიკის დიდი ნაწილი დააფიქსირა, მაგრამ მაინც მხოლოდ სარეკომენდაციო ხასიათის იყო. პროცესმა შეიძლება უგულებელყოს გარემო, გვერდი აუაროს PATH-ს, ან, უბრალოდ, სოკეტები პირდაპირ გახსნას — ეს მეტისმეტად სარისკოა.
როგორც ნებისმიერი საინტერესო პროგრამული განხორციელების შემთხვევაში, პირველ პროტოტიპს ჰქონდა გარკვეული დადებითი და უარყოფითი მხარეები. მიუხედავად იმისა, რომ მან თავისი საქმე შეასრულა Windows-ის მხოლოდ რამდენიმე სტანდარტული შესაძლებლობის გამოყენებით, უზრუნველყო ფაილურ სისტემაში ჩაწერის ძალიან მკაფიო და დეტალური კონტროლი და მუშაობდა გაფართოებული უფლებების გარეშე — რაც გამორიცხავდა მომხმარებლების მიერ უფლებების გადამეტებული მოთხოვნების დადასტურების ან ლოკალურ მოწყობილობაზე ადმინისტრატორად ყოფნის საჭიროებას — მას ჰქონდა სერიოზული ნაკლოვანებები, რომელთაგან ზოგიერთის გამოც ის საბოლოო დიზაინად ვერ დავამტკიცეთ:
- კონფიგურაციის სიჩქარე: სამუშაო სივრცეში ACL-ების დანერგვა შეიძლება ხარჯიანი იყოს სამუშაო სივრცის დირექტორიის ტოპოლოგიის მიხედვით.
- კვალი: დეველოპერის სისტემაზე რეალური ACL-ები გამოვიყენეთ, თუმცა ეს კვალი განსაკუთრებით ინვაზიური არ არის, რადგან ყველა გამოყენებული ACL ეხება სპეციალურად შექმნილ სინთეზურ SID-ს, რომელსაც მხოლოდ სენდბოქსი იყენებს.
- ძნელად შესაცვლელი სემანტიკა: ფაილზე დაფუძნებული შეზღუდვებისთვის ACL-ებზე დამოკიდებულება ნიშნავს, რომ სენდბოქსის სემანტიკის შეცვლა დიდ დანახარჯებს მოითხოვს და კომპლექსურია. მაშინ, როცა macOS-ზე შეგვიძლია დინამიკურად შევცვალოთ, როგორ ვაგენერირებთ
.sbplფაილს, რომელიც Seatbelt-ის კონფიგურაციისთვის გამოიყენება, Windows-ის სენდბოქსს შეიძლება დასჭირდეს ნელი და ინტენსიური ოპერაცია ACL-ების შესაცვლელად. - ქსელის დაცვა სუსტია. როგორც ადრე აღინიშნა, ის „სარეკომენდაციო“ ხასიათის იყო, მას ნამდვილად გვერდს აუვლიდა ზოგიერთი პროგრამა, რომელიც საკუთარ ქსელურ დასტას იყენებდა, და ის არ იყო შექმნილი მავნე კოდისთვის წინააღმდეგობის გასაწევად.
პირველი სამი პრობლემა თან ახლავს მორგებული სენდბოქსის იმპლემენტაციას, რომელიც საკმარისად მოქნილია აგენტური ნაკადებისთვის. თუმცა, ქსელის შეზღუდვის შემთხვევა განსხვავებული იყო.
გარდა იმისა, რომ მავნე აგენტს შეუძლია მარტივად აუაროს გვერდი გარემოზე დაფუძნებულ ქსელის შეზღუდვას, ასევე მრავალი კეთილი განზრახვით შექმნილი კოდი ან ორობითი ფაილიც შეძლებდა ამ შეზღუდვის გვერდის ავლას, თუ ისინი არ გაითვალისწინებს გარემოს პროქსი-ცვლადებს ან გამოიყენებს საკუთარ სოკეტზე დაფუძნებულ ქსელურ კოდს. მიგვაჩნდა, რომ ეს ასპექტი საკმარისი იყო უკეთეს სენდბოქსში ინვესტირების განსახილველად.
ქსელური წვდომის უკეთ შესაზღუდად გვსურდა, გამოგვეყენებინა Windows Firewall, რომელიც საშუალებას გვაძლევს, დავბლოკოთ გამავალი ქსელური ტრაფიკი მომხმარებლებისთვის ან პროგრამებისთვის. სამწუხაროდ, რამდენიმე მიზეზის გამო ვერ მოვახერხეთ ფუნქციური Firewall-ის წესის ეფექტურად შექმნა, რომელიც მხოლოდ Codex-ის სისტემის მიერ გაშვებულ ბრძანებებზე გავრცელდებოდა:
- Windows არ იძლევა Firewall-ის წესის შეზღუდული ჟეტონის არაძირითად იდენტობასთან შესაბამისობის დადგენის საშუალებას. ეს ნიშნავს, რომ ვერ შევძელით Firewall-ის წესის გამოყენება „ნებისმიერ ჟეტონზე, რომელიც თავის შეზღუდული SID-ების სიაში მოიცავს ჩვენს სინთეზურ SID-ს“.
- მიუხედავად იმისა, რომ შეგვეძლო, შეგვექმნა Firewall-ის წესი, რომელიც კონკრეტულ ბინარულ ფაილს ემთხვევა, ეს მხოლოდ თავად
codex.exe-სთვის ქსელური წვდომის შეზღუდვის საშუალებას გვაძლევს. ეს არ გავრცელდებოდა იმ პროცესებზე, რომლებსაც აგენტი მომხმარებლის სახელით უშვებს, როგორიცაა Git-ის ან Python-ის პროცესები. - Firewall-ის დამთხვევის სხვა განზომილებებიც არასწორი ფორმის იყო. მომხმარებლის ფარგლებით მოქმედი წესები უფლებების ამაღლების გარეშე მომუშავე დიზაინში კვლავ Windows-ის რეალურ მომხმარებელს ემთხვეოდა და არა მხოლოდ შეზღუდულ წარმოებულ პროცესს. პროგრამის ბილიკის წესები ზედმეტად ზოგადი იყო: მათ შეეძლო
codex.exe-ს ანpython.exe-ს ზოგადად დაბლოკვა, მაგრამ არაpython.exe-ს ამ სენდბოქსში იზოლირებული გაშვების დაბლოკვა. პორტზე ან მისამართზე დაფუძნებული წესებიც სრულიად არასწორი წესი იყო. მაგალითად, ჩვენ არ გვსურდა 443-ე პორტის დაბლოკვა; გვსურდა ნებისმიერი გამავალი ქსელური წვდომის დაბლოკვა ამ კონკრეტული შეზღუდული პროცესების სქემისთვის.
სპეციფიკურად სენდბოქსში მოქცეული ბრძანებებისთვის Firewall-ის წესის გამოყენების მიზნით საჭირო იყო მათი გაშვება ცალკე სუბიექტის სახელით და არა „ნამდვილი“ მომხმარებლის სახელით. ამ მიდგომამ ახალ გზაზე დაგვაყენა — ისეთზე, რომლის ფარგლებშიც შევარბილეთ ჩვენი „აუმაღლებლობის“ შეზღუდვა.
სენდბოქსის შემდეგი იტერაცია, რომელიც ჩვენი მიმდინარე დანერგვაა, დაყენების დროს ადმინისტრატორის გაფართოებულ ნებართვებს მოითხოვს. შესაბამისად, მას „გაფაროებულ სენდბოქსს“ ვუწოდებ. იმ ზღვარზე, სადაც Codex-ი სისტემაში ბრძანებას აგროვებს უშვებს, გაფართოებული უფლებების მქონე სენდბოქსი ზუსტად ისევე გამოიყურება, როგორც უფლებების არმქონე. ის მაინც უშვებს წარმოებულ პროცესებს შეზღუდული ტოკენით — ანალოგიურად, write_restricted ტოკენით, შეზღუდული SID-ების იმავე სიით: [Everyone, Logon, Synthetic]— თუმცა, ამ ტოკენის სუბიექტი აღარ არის Windows-ის რეალური მომხმარებელი, არამედ Codex-ის მიერ შექმნილი ორი ლოკალური მომხმარებლიდან ერთ-ერთი:
CodexSandboxOffline(რომელიც Firewall-ის წესების სამიზნედ არის მითითებული)CodexSandboxOnline(რომელიც Firewall-ის წესების სამიზნე არ არის)
ეს ერთი შეხედვით მცირე დეტალი სინამდვილეში მნიშვნელოვან გავლენას ახდენს სენდბოქსზე, მის გამოყენების შესაძლებლობასა და მისი კონფიგურაციისა და გაშვების პროცესის სირთულეზე.
ვიზუალურად ის ჰგავს უფლებების ამაღლების გარეშე მომუშავე პროტოტიპს, თუმცა დამატებულია Firewall-ის წესები და გამოყოფილი Windows-ის მომხმარებელი, რომელიც რეალურად ასრულებს ბრძანებებს. (თუმცა ამ ახალი ცნებების შემოტანა ნიშნავს, რომ საწყისი გამართვის მეტი სამუშაოა საჭირო, სანამ სენდბოქსი ბრძანებების გაშვებასა და დაცვას დაიწყებს.)
აუმაღლებელი სენდბოქსის დიზაინს მარტივი დაყენების ეტაპი ჰქონდა, თუმცა ის შედარებით მცირე ზომის იყო:
- საჭიროების შემთხვევაში შექმენით სინთეზური SID
- გამოიყენეთ ACL-ები sandbox-write-ის სინთეზური SID-სთვის
თუმცა ამაღლებული უფლებების მქონე სენდბოქსს მეტი რამის გაკეთება სჭირდება.
- შექმენით სინთეზური SID, თუ ის ჯერ არ არის შექმნილი
- შექმენით ონლაინ და ოფლაინ სენდბოქსის მომხმარებლები, თუ ისინი უკვე შექმნილი არ არის
- ახლად შექმნილი მომხმარებლების ავტორიზაციის მონაცემები შეინახეთ ლოკალურად და დაშიფრეთ Windows Data Protection API-ს (DPAPI) გამოყენებით, ისეთ ადგილას, საიდანაც იზოლირებული გარემოს მომხმარებლები მათ რეალურად ვერ წაიკითხავენ.
- შექმენით Firewall-ის წესები, რომლებიც
CodexSandboxOffline-ის მომხმარებლისთვის სრულად დაბლოკავს გამავალ ქსელურ წვდომას, ან თუ ასეთი წესები უკვე არსებობს, დაადასტურეთ, რომ ისინი სწორად არის კონფიგურირებული
დაყენების ეტაპზე დამატებითი სირთულეა. მოსალოდნელია, რომ Codex-ის სენდბოქსს ჰქონდეს Windows-ის რეალური მომხმარებლის ეკვივალენტური წაკითხვის წვდომა. ეს მიიღწეოდა აუმაღლებელ სენდბოქსში, სადაც შეზღუდული ჟეტონის სუბიექტის SID Windows-ის მომხმარებელი იყო. თუმცა ეს თავისით არ ხდება, როდესაც სუბიექტი CodexSandbox-ის ახალი მომხმარებელი ხდება. Windows-ში ბევრი შესაბამისი დირექტორია „ავთენტიფიცირებულ მომხმარებლებს“ მიანიჭებს წაკითხვის/შესრულების ნებართვებს. ერთი საყურადღებო მაგალითია მომხმარებლის პროფილის დირექტორია. ნაგულისხმევად, Windows-ის მომხმარებლებს არ შეუძლიათ Windows-ის სხვა მომხმარებლების პროფილის დირექტორიების წაკითხვა, ამიტომ ბევრ სცენარში ფაილების წაკითხვის მარტივი ოპერაციებიც კი ვერ შესრულდება.
ამის მოსაგვარებლად სენდბოქსის დაყენების პროცესს დავამატეთ კიდევ ერთი შრე — სენდბოქსის მომხმარებლებისთვის ACL-ების წაკითხვის უფლების მისანიჭებლად, როდესაც ასეთი ACL-ები, შესაძლოა, ჯერ არ არსებობდეს. მაგალითად, Windows-ის ზოგიერთ ხშირად გამოყენებულ დირექტორიაზე:
C:\Users\<real-user>C:\Windows\C:\Program Files\C:\Program Files (x86)\C:\ProgramData\
ვინაიდან დირექტორიების ეს სია საუკეთესო მცდელობის პრინციპით არის შედგენილი და თითოეულ მათგანზე ACL-ების დაყენება შეიძლება საკმაოდ რესურსტევადი იყოს, ამ ლოგიკას ასინქრონულად ვასრულებთ, რომ სენდბოქსის დაყენების ეტაპს, რომელიც მომხმარებლებს აყოვნებს, მათი დასრულებისთვის ლოდინი არ მოუწიოს.
ჩვენ დაყენების ლოგიკა ცალკე ორობით ფაილში მოვათავსეთ, ნაწილობრივ იმისთვის, რომ UAC-ს ზღვარი მხოლოდ საჭიროების შემთხვევაში გადაგველახა. მაგრამ უფრო სიღრმისეული მიზეზი არქიტექტურული იყო: სენდბოქსის კონფიგურაციას codex.exe-სგან ფუნდამენტურად განსხვავებული ფუნქცია აქვს. სენდბოქსის დაყენების ლოგიკის განცალკევებულ ორობით ფაილში მოქცევამ codex.exe-ს საშუალება მისცა, დარჩენილიყო ჩვეულებრივ სისტემად ამაღლებული პრივილეგიების გარეშე; Windows-ის სპეციფიკური დაყენების მექანიზმი სხვა პლატფორმებზე codex.exe-ს ზედმეტად გადატვირთვისგან დაიცვა; უფრო ხანგრძლივად მიმდინარე დაყენების სამუშაო მთავარი პროცესის მოქმედების ციკლისგან გამოაცალკევა; და მოგვცა ერთი სივრცე იმ დაყენების სხვადასხვა გზის დასამუშავებლად, რომლებიც სენდბოქსს სჭირდებოდა.
Windows-ში მომხმარებლისა და ჟეტონის შესვლის საზღვრების მუშაობის თავისებურებების გამო, ვეღარ გავაგრძელებდით შეზღუდული ჟეტონის შექმნასა და მის კონტექსტში პროცესის გაშვებას ისე, როგორც ამას აუმაღლებელი სენდბოქსით ვაკეთებდით. Windows-ის სხვა მომხმარებლის სახელით ბრძანებების რეალურად გასაშვებად ჩვენი პირველი იდეა იყო შემდეგი სამუშაო პროცესი:
codex.exeმუშაობს Windows-ის რეალური მომხმარებლის სახელით. შემდეგ, თანმიმდევრობით, Codex:- იძახებს
LogonUserW(...)ფუნქციას სენდბოქსის მომხმარებლისთვის. - იძახებს
CreateRestrictedToken(...)ფუნქციას შესაბამისი სენდბოქს-მომხმარებლის ჟეტონზე. - აღნიშნული შეზღუდული სენდბოქსის მომხმარებლის ჟეტონის გამოყენებით, იძახებს
CreateProcessAsUserW(...)-ს საბოლოო წარმოებული პროცესის გასაშვებად.
- იძახებს
პრაქტიკაში ამ სასურველი ნაკადმა ვერ იმუშავა, რადგან CreateProcessAsUserW(...) ფუნქციასთან პრივილეგიების ბარიერი არსებობდა. ეს ნიშნავს, რომ codex.exe-ს შეეძლო სენდბოქსის მომხმარებლისთვის შეზღუდული ჟეტონის შექმნა, მაგრამ ვერ ახერხებდა ამ ჟეტონით წარმოებული პროცესის საიმედოდ გაშვებას საზღვრის რეალური მომხმარებლის მხრიდან. ჩვენ გვჭირდებოდა პროცესი, რომელიც უკვე სენდბოქსის მომხმარებლის სახელით მუშაობდა — ეს საშუალებას მოგვცემდა, რომ შეზღუდვის ეტაპი და საბოლოო გაშვება სენდბოქსის მომხმარებლის მხარეს და არა რეალური მომხმარებლის მხარეს განხორციელებულიყო.
ამ მოთხოვნამ გამოიწვია codex-command-runner.exe-ს შექმნა — ახალი ორობითი ფაილის, რომლის ერთადერთი ამოცანაა შეზღუდული ჟეტონის შექმნა და მოთხოვნილი ბრძანების გაშვება. იმის ნაცვლად, რომ codex.exe-ს ვთხოვოთ, მთელი პროცესი თავად შეასრულოს (რეალური მომხმარებელი → სენდბოქსის მომხმარებელი → შეზღუდული ჟეტონი → წარმოებული პროცესი), პროცესი ორ ნაწილად გავყავით:
ნაწილი 1
codex.exeიძახებსCreateProcessWithLogonW(...)ფუნქციას, რომcodex-command-runner.exeსენდბოქსის მომხმარებლის სახელით გაუშვას, შეზღუდული ჟეტონის გამოყენების გარეშე.
ნაწილი 2
- გამშვების შიგნით
OpenProcessToken(GetCurrentProcess(), ...)ხსნის გამშვების საკუთარ ჟეტონს, რომელიც უკვე სენდბოქსის მომხმარებელს ეკუთვნის. - გამშვები იძახებს
GetTokenInformation(...)ფუნქციას, რომ ამოიღოს სენდბოქსის შესვლის SID, შემდეგ კიCreateRestrictedToken(...)ფუნქციას, რომ შექმნას საბოლოო შეზღუდული ჟეტონი. - გამშვების შიგნით ის იძახებს
CreateProcessAsUserW(...)ფუნქციას შეზღუდული ჟეტონით, რომ გაუშვას რეალური წარმოებული პროცესი.
ალბერტ აინშტაინმა თქვა: „ყველაფერი უნდა გაკეთდეს რაც შეიძლება მარტივად, მაგრამ არა უფრო მარტივად“. ამ სულისკვეთებით ჩვენმა დიზაინმა სათანადოდ გადაჭრა თითოეული პრობლემა. საბოლოო არქიტექტურაში შედის ოთხი შრე, რომლებიც ადრე უკვე განვიხილეთ:
- თავად
codex.exe codex-windows-sandbox-setup.exeდაყენების პროცესში ამაღლებულ უფლებებთან დაკავშირებული ყველა სამუშაოს შესასრულებლადcodex-command-runner.exeშეზღუდული ჟეტონების ბრძანებების შესასრულებლად- წარმოებული პროცესი
როცა პირველად მივუდექი ამ პროექტს, არ მქონდა მკაფიო წარმოდგენა, საბოლოოდ სადამდე მივიდოდა. ჩემი მიდგომა იყო, დამეწყო Codex-სა და ოპერაციულ სისტემას შორის საზღვარზე სენდბოქსინგის შესაძლებლობის ინსტრუმენტირება. ეს მიდგომა ძალიან ჰგავს იმას, თუ როგორ არის დანერგილი Codex-ის სენდბოქსი macOS-სა და Linux-ზე.
როდესაც მეტი გავიგე იმ კონკრეტული ინსტრუმენტების შესახებ, რომლებსაც Windows გვთავაზობს, და უსაფრთხოებასა და გამოყენების სიმარტივეს შორის ბალანსის დაცვისთვის მიღებული ათობით გადაწყვეტილების შედეგად, სისტემა თავის ამჟამინდელ ფორმამდე განვითარდა — რამდენიმე ორობითი ფაილი, მორგებული მომხმარებლები, Firewall-ის წესები, ამაღლებული პრივილეგიებით შესრულებადი დაყენების ეტაპი, ასინქრონული პროცესები და სხვა.
ეს განსაკუთრებით მარტივი სისტემა არ არის, მაგრამ სირთულის თითოეული ელემენტი აუცილებლობიდან გამომდინარე დაემატა, რom შექმნილიყო სენდბოქსის გარემო, რომელიც ერთდროულად უსაფრთხოა და, შეძლებისდაგვარად, მომხმარებელს ხელს არ უშლის.
Windows-ზე Codex-ის მომხმარებლებისთვის კარგი გამოცდილების უზრუნველსაყოფად ჩვენი მიზანი იყო, შეგვექმნა უსაფრთხო და სასარგებლო პროდუქტი, რომელიც აგენტებს თქვენი მუდმივი ყურადღების გარეშე სამუშაოს შესრულების საშუალებას მისცემდა.
ამ პროექტის ერთ-ერთი მთავარი გაკვეთილი ის იყო, რომ Windows-მა არ მოგვცა ერთი ისეთი საწყისი ფუნქცია, რომელიც პირდაპირ და ზუსტად შეესაბამება „უსაფრთხო ავტონომიური კოდირების აგენტს“. ჩვენ რამდენიმე ინსტრუმენტი და კონცეფცია გავაერთიანეთ, რომ რაღაც თანმიმდევრული შეგვექმნა. ზოგიერთი საწყისი იდეა ჩიხური აღმოჩნდა. საბოლოო დიზაინი წარმოადგენდა იმ ადრინდელი პროტოტიპების ჰიბრიდს, რომელთაგანაც თითოეული პრობლემის ნაწილს აგვარებდა.
კიდევ ერთი გაკვეთილი ის იყო, რომ კოდის აგენტისთვის უსაფრთხოება უფრო კლასიკური აპლიკაციების უსაფრთხოებასთან შედარებით სრულიად სხვა ტიპის საკითხია. Codex რეალური დეველოპერული სამუშაო პროცესებისთვის უნდა მუშაობდეს. საინჟინრო სამუშაო აგენტურ სამუშაო დატვირთვებთან თავსებადობასა და რეალურ აღსრულებას შორის ბალანსის პოვნას ეხებოდა. ამ დაძაბულობამ საბოლოო დიზაინში მიღებული კომპრომისები განსაზღვრა.
გაინტერესებთ Codex-ის სენდბოქსის მოქმედებაში ნახვა? სცადეთ ის.


