Windows-ում Codex-ը գործարկելու համար անվտանգ, արդյունավետ sandbox-ի կառուցում
Հեղինակ՝ David Wiesen, տեխնիկական անձնակազմի անդամ
Երբ ես 2025 թվականի սեպտեմբերին միացա Codex-ի ինժեներական թիմին, Windows-ի համար Codex-ը sandbox-ի իրականացում չուներ, ինչը նշանակում էր, որ Windows-ի օգտատերերը OpenAI-ի կոդավորման ագենտներն օգտագործելիս ստիպված էին ընտրել երկու ոչ բավարար տարբերակների միջև.
- Հաստատել գրեթե յուրաքանչյուր հրաման (նույնիսկ՝ ընթերցման), որը կոդավորման ագենտը ցանկանում էր գործարկել, ինչը անարդյունավետ և նյարդայնացնող է։ Codex-ն օգտագործելու կարևոր առավելություններից մեկն այն է, որ պետք չէ ամբողջ ձանձրալի աշխատանքն ինքներդ անել։
- Միացնել Full Access ռեժիմը՝ թույլ տալով Codex-ին գործարկել բոլոր հրամանները առանց հաստատման կամ սահմանափակումների, ինչը վերահսկողության հաշվին նվազեցնում է խոչընդոտները։
Codex-ը՝ մեր կոդավորման ագենտը, աշխատում է ծրագրավորողների նոթբուքերում՝ լինի դա CLI-ի, IDE ընդլայնման, թե desktop հավելվածի միջոցով։ Այն կառավարում է զրույցը ստեղնաշարի առջև գտնվող մարդու և ամպում աշխատող մոդելի միջև՝ ինֆերենսը մշակելու համար։
Codex-ը, ըստ կանխադրման, աշխատում է իրական օգտատիրոջ արտոնություններով, այսինքն՝ կարող է անել այն ամենը, ինչ հասանելի է օգտատիրոջը։ Սա հզոր, բայց նաև պոտենցիալ վտանգավոր հնարավորություն է։ Կոդավորման մոդելը կարող է harness-ին հանձնարարել տեղային մասշտաբով գործարկել տարբեր հրամաններ՝ սկսած թեստերի գործարկումից մինչև ֆայլերի ընթերցում, խմբագրում կամ Git branch-ի ստեղծում, ուստի Codex-ի լռելյայն ռեժիմը փորձում է պահպանել արդյունավետության և անվտանգության միջև ճիշտ հավասարակշռություն։ Այս ռեժիմը Codex-ին թույլ է տալիս գրեթե ցանկացած վայրից կարդալ ֆայլեր և ֆայլեր գրել ձեր աշխատատարածքի ներսում (այսինքն՝ այն գրացուցակում, որտեղից գործարկում եք Codex-ը)՝ առանց ինտերնետ հասանելիության, եթե դուք հատուկ չնշեք, որ այն անհրաժեշտ է։ Ֆայլերի գրառումն ու ցանցային հասանելիությունը անվտանգ սահմաններում ավտոմատ սահմանափակելու համար Codex-ին անհրաժեշտ է sandbox միջավայր, որն իրականում կիրառում է այդ սահմանափակումները
Սենդբոքսը սահմանափակ կատարման միջավայր է։ Երբ ծրագրավորողն օգտագործում է Codex-ը, նրա համակարգչի օպերացիոն համակարգը հրաման է գործարկում նվազեցված արտոնություններով, և այդ սահմանափակումները փոխանցվում են գործընթացների ծառով ներքև։ Codex-ի յուրաքանչյուր հրաման հենց սկզբից գործարկվում է մեկուսացված միջավայրում, և դրանից առաջացած յուրաքանչյուր գործընթաց մնում է նույն սահմանի ներսում։
Արդյունավետ sandbox իրականացնելու համար Codex-ին պետք են մեկուսացման հնարավորություններ, որոնք կիրառվում են համակարգչի օպերացիոն համակարգի կողմից։ Որոշ օպերացիոն համակարգեր տրամադրում են օգտակար գործիքներ, որոնք սա լավ են անում (օրինակ՝ Seatbelt-ը MacOs-ում, seccomp-ը կամ bubblewrap-ը Linux-ում), սակայն Windows-ը ներկայումս այս տեսակի հնարավորություններ անմիջապես չի տրամադրում։
Որպեսզի Codex-ի օգտագործումը Windows-ում նույնքան անվտանգ և հաճելի լինի, որքանով դա արվում է մնացած հարթակներում, մեզ պետք էր իրականացնել մեր սեփական sandbox-ը։
Windows-ը մեկուսացման համար առաջարկում է որոշ գործիքներ և պրիմիտիվներ։ Թեև դրանցից ոչ մեկը լիովին չէր համապատասխանում մեր պահանջներին, մենք դիտարկեցինք մի շարք հնարավոր լուծումներ, այդ թվում՝ AppContainer-ը, Windows Sandbox-ը և Mandatory Integrity Control-ի նշագրումը։
AppContainer
- Ինչ է սա. AppContainer-ը Windows-ի բնիկ sandbox-ն է՝ հնարավորությունների վրա հիմնված մեկուսացման մոդել, որը նախատեսված է այն հավելվածների համար, որոնք նախապես ճշգրիտ գիտեն, թե ինչին պետք է մուտք գործեն։
- Ինչու. Գրավիչ է, քանի որ առաջարկում է օպերացիոն համակարգի իրական սահման, ոչ թե լավագույն ջանքերով սահմանափակումներ։
- Ինչու ոչ. Codex-ը խիստ սահմանափակ շրջանակով մեկ հավելված չէ։ Այն ապահովում է մշակողների բաց աշխատանքային հոսքեր՝ հրամանային շելեր, Git, Python, փաթեթների կառավարիչներ, կառուցման գործիքներ և ցանկացած այլ բինար ֆայլեր, որոնք գործակալը անհրաժեշտ է համարում։ Գործնականում դա AppContainer-ը դարձնում էր տվյալ խնդրի համար ոչ հարմար լուծում։ Դա ուժեղ մեկուսացում էր, բայց նախատեսված էր աշխատանքային ծանրաբեռնվածությունների շատ ավելի նեղ դասի համար, քան այն դեպքը, երբ «գործակալին թույլ են տալիս գործել մշակողի պես»։
Windows Sandbox
- Ի՞նչ է. Windows Sandbox-ը Microsoft-ի մեկանգամյա օգտագործման թեթև վիրտուալ մեքենան է (VM)։ Դուք ստանում եք թարմ Windows աշխատասեղան՝ հուսալի մեկուսացմամբ, և դրա ներսում կատարված բոլոր գործողություններն ու փոփոխությունները անհետանում են սեսիայի ավարտից հետո։
- Ինչու. Դա հետաքրքիր տարբերակ էր ակնհայտ պատճառներով․ այն կամայական ծրագրային ապահովման հետ շատ ավելի համատեղելի էր, քան AppContainer-ը, և անվտանգության տեսանկյունից շատ ավելի ուժեղ մեկուսացված միջավայր էր ապահովում։
- Ինչու ոչ. Codex-ը պետք է անմիջապես աշխատի օգտատիրոջ իրական checkout-ի, գործիքների և միջավայրի վրա, ոչ թե առանձին ժամանակավոր աշխատասեղանի միջավայրում, որի համար անհրաժեշտ կլիներ առանձին կարգավորում և host/guest միջավայրերի միջև ինտեգրում։ Այն նաև ուներ արտադրանքի հիմնարար խնդիր․ Windows Sandbox-ը նույնիսկ հասանելի չէ Windows Home SKU-ներում։
Mandatory Integrity Control (MIC)-ի ամբողջականության պիտակավորում
- Ի՞նչ. Windows-ում կա «ամբողջականության մակարդակներ» կոչվող հասկացություն, օրինակ՝ ցածր, միջին և բարձր, որոնք որոշում են, թե համակարգը որքանով է վստահում օբյեկտներին և գործընթացներին։ Հիմնական կանոնն այն է, որ ավելի ցածր ամբողջականության մակարդակ ունեցող գործընթացը չի կարող գրել ավելի բարձր ամբողջականության մակարդակ ունեցող օբյեկտում, նույնիսկ եթե սովորական ACL-ը այլ պարագայում դա թույլ տար։ Օրինակ՝ ցածր ամբողջականության գործընթացը համարվում է պակաս վստահելի, ուստի Windows-ն արգելափակում է դրա կողմից սովորական միջին ամբողջականության օբյեկտներում գրառում կատարելը, եթե այդ օբյեկտները հստակորեն վերանշված չեն՝ դա թույլատրելու համար։
- Ինչու. MIC-ը տեսականորեն շատ լավ լուծում էր թվում՝ գործարկել Codex-ը ցածր ամբողջականության մակարդակով, գրառման համար նախատեսված root-երը վերանշագրել որպես ցածր ամբողջականություն և թողնել, որ Windows-ը մնացած բոլոր վայրերում կիրառի գրառումների արգելքը։ Դա մեզ կտար ոչ ադմինիստրատորական ուղի՝ իր հիմքում ունենալով իրական ՕՀ մեխանիզմ։
- Ինչու ոչ. ACL-ների նման, ամբողջականության պիտակները փոփոխում են իրական հոսթի ֆայլային համակարգը, և այս դեպքում իմաստային փոփոխությունը հատկապես լայն է։ Աշխատատարածքը որպես ցածր ամբողջականության նշելը չի նշանակում միայն՝ «Codex-ը կարող է այստեղ գրել»։ Դա նշանակում է, որ ցածր ամբողջականության մակարդակ ունեցող գործընթացները ընդհանուր առմամբ կարող են այնտեղ գրել։ Իրական մշակողի մեքենայի վրա դա օգտատիրոջ իրական աշխատանքային պատճենը վերածում է հոսթի համար ցածր ամբողջականության ընդունիչի, ինչը շատ ավելի ռիսկային է, քան մեկ sandbox նախագծման համար խնամքով թիրախավորված ACL-ներ տրամադրելը։ Նույնիսկ եթե միջին ամբողջականության մակարդակով մշակողի գործիքները շարունակեն աշխատել, աշխատատարածքի հիմքում ընկած վստահության մոդելը փոխվել է այնպիսի կերպ, որը դժվար է սահմանափակել և էլ ավելի դժվար՝ հիմնավորել։
Բոլոր տարբերակները գնահատելով որպես ոչ մեկնարկային՝ Windows-ի օգտատերերին լավ Codex փորձառություն ապահովելու համար մենք սկսեցինք նախագծել մեր սեփական լուծումը։
Մեր առաջին աշխատող նախատիպը օգտագործում էր Windows-ի հայեցակարգերի և գործիքների համադրություն՝ մեզ անհրաժեշտ մեկուսացումն իրականացնելու համար։ Սկզբից ի վեր նպատակներից մեկն այն էր, որ սա աշխատեր առանց իրավունքների բարձրացում պահանջելու, այսինքն՝ Codex-ը կարիք չէր ունենա օգտատիրոջից ադմինիստրատորի արտոնությունների հարցում անել՝ միայն sandbox-ը կարգավորելու կամ գործարկելու համար։ Դա նշանակում էր հասկանալ, թե ինչպես խելամիտ սահմանափակումներ սահմանել երկու բանի համար՝ ֆայլերում գրելու գործողությունների և ցանցային հասանելիության։
Եթե մենք ընդհանրապես չսահմանափակեինք ֆայլերում գրառում կատարելը, կառաջանար անվտանգության խնդիր։ Եթե չափազանց սահմանափակեինք այն, sandbox-ը կվնասեր օգտատիրոջ արտադրողականությանը՝ պահանջելով մշտական հաստատումներ։ Այս խնդիրը լուծելու համար մենք հիմնվեցինք Windows-ի երկու կարևոր կառուցվածքային բաղադրիչների վրա՝ SID-երի և write-restricted թոքենների վրա։
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-երը դարձնում է օգտակար կառուցվածքային տարր մեր sandbox-ի համար․ մենք կարող ենք ստեղծել SID-եր միայն Codex sandbox-ի օգտագործման համար՝ չազդելով համակարգի այլ մասերի վրա։
Գործընթացի թոքենները Windows-ում անվտանգության օբյեկտներ են, որոնք սահմանում են աշխատող գործընթացի ինքնությունը և արտոնությունները։ Դրանք որոշում են, թե ինչ գործողություններ կարող է կատարել գործընթացը։ Գրելու սահմանափակում ունեցող թոքենը գործընթացի թոքենի հատուկ տեսակ է, որի դեպքում Windows-ը գրելու գործողությունների ժամանակ կատարում է մուտքի իրավունքի լրացուցիչ ստուգում։
Որպեսզի գրառումը հաջողվի, պետք է անցնի երկու ստուգում.
- Սովորական օգտատիրոջ ինքնությունը (թոքենի «սեփականատերը») պետք է իրավունք ունենա դա անել
- Թոքենի սահմանափակված SID-ների ցանկում գտնվող առնվազն մեկ SID-ին նույնպես պետք է տրամադրվի հասանելիություն
Գործնականում այս ստուգումները մեզ թույլ տվեցին ACL-ների միջոցով ճշգրիտ սահմանել, թե որտեղ sandbox-ը կարող էր փոփոխել ֆայլային համակարգը, ինչը մեզ տալիս էր գրելու գործողությունների նկատմամբ անհրաժեշտ մանրամասն վերահսկում։
SID-երի և write-restricted թոքենների օգնությամբ մեր ոչ արտոնյալ sandbox-ը գործում էր հետևյալ կերպ․
- Sandbox-ի կարգավորման գործընթացը ստեղծում էր
sandbox-writeանունով սինթետիկ SID։ sandbox-writeSID-ին տրամադրվել է գրելու, գործարկելու և ջնջելու հասանելիություն դեպի- Ընթացիկ աշխատանքային գրացուցակը
- Ցանկացած լրացուցիչ
writable_roots, որոնք կազմաձևված ենconfig.toml-ում։
- Sandbox-ի կազմաձևումը նույն SID-ի համար բացահայտորեն սահմանում էր գրելու հասանելիության արգելք «writable տարածքի ներսում միայն կարդալու» վայրերում, օրինակ՝
<cwd>/.git<cwd>/.codex<cwd>/.agents
- Codex-ը հրամանները գործարկում էր write-restricted թոքենով, որի restricted SID ցուցակը ներառում է
Everyone-ը, ընթացիկ մուտքագրված սեսիայի SID-ը ևsandbox-writeսինթետիկ SID-ը։
Այս մեխանիզմը արդյունավետորեն լուծում էր ֆայլերում գրառումները սահմանափակելու խնդիրը և բավական խոստումնալից էր թվում։ Հաջորդ քայլը sandbox-ի ցանցային հասանելիությունը սահմանափակելու լուծում գտնելն էր։
Ցանցային հասանելիության սահմանափակումը sandbox-ի կարևոր բաղադրիչ է․ առանց դրա վնասաբեր կոդը կարող էր մեքենայից տվյալներ արտահոսեցնել դեպի ինտերնետ։ Քանի որ ցանկանում էինք խուսափել արտոնությունների բարձրացման պահանջից, ցանցային տրաֆիկը հուսալիորեն արգելափակելու մեր տարբերակները սահմանափակ էին։ Այն գործիքները, որոնք ցանկանում էինք օգտագործել, օրինակ՝ Windows Firewall-ը, ընդհանուր առմամբ չէին կարող օգտագործվել առանց ադմինիստրատորի իրավունքների։
Քանի որ Windows Firewall-ը որպես տարբերակ հասանելի չէր, մենք սահմանափակեցինք այն, ինչ կարող էինք վերահսկել։ Մենք փորձեցինք դուստր միջավայրը դարձնել փակմամբ խափանվող այն տեսակի ցանցային գործիքների համար, որոնք մշակողները իրականում օգտագործում են, որպեսզի Git հրամանները, փաթեթների տեղադրիչները և այլն խափանվեին մեկուսացված միջավայրում, և օգտատերը ստիպված լիներ հաստատել ինտերնետին ուղղված ցանկացած գործողություն։ Գաղափարն այն էր, որ թունավորվեն ակնհայտ փախուստի ուղիները․ պրոքսիից տեղյակ տրաֆիկն ուղարկել չգործող վերջնակետի, ստիպել Git-ի HTTP(S) տրանսպորտին անել նույնը և այնպես անել, որ SSH-ով Git-ը անմիջապես ձախողվի։ Բացի այդ, մենք PATH -ի սկզբում ավելացրինք փոքր denybin գրացուցակ և վերադասավորեցինք PATHEXT-ը, որպեսզի ստաբ SSH և SCP սկրիպտները գտնվեին իրական բինար ֆայլերից առաջ։
Օրինակ՝ ահա միջավայրի մի քանի հատուկ override-ներ, որոնք մենք կիրառում էինք ցանցային հասանելիությունը սահմանափակելու նպատակով․
HTTPS_PROXY=http://127.0.0.1:9ALL_PROXY=http://127.0.0.1:9GIT_HTTPS_PROXY=http://127.0.0.1:9NO_PROXY=տեղական հոսթ,127.0.0.1,::1GIT_SSH_COMMAND=cmd /c exit 1
Դա որսում էր սովորական գործիքներով իրականացվող տրաֆիկի մեծ մասը, սակայն դեռևս միայն խորհրդատվական բնույթ ուներ։ Գործընթացը կարող էր անտեսել միջավայրը, շրջանցել PATH-ը կամ պարզապես անմիջապես socket-ներ բացել, և դա չափազանց ռիսկային էր։
Ինչպես ցանկացած հետաքրքիր ծրագրային իրականացման դեպքում, առաջին նախատիպն ուներ որոշ առավելություններ և թերություններ։ Թեև այն կատարում էր իր գործը՝ օգտագործելով Windows-ի ընդամենը մի քանի ստանդարտ հնարավորություններ, թույլ էր տալիս ֆայլային համակարգում շատ հստակ և մանրամասն գրառումներ կատարել և աշխատում էր առանց բարձրացված արտոնությունների՝ նվազեցնելով օգտատերերի կողմից արտոնությունների բարձրացման չափազանց շատ հարցումներ ընդունելու կամ իրենց տեղական սարքում ադմինիստրատոր լինելու անհրաժեշտությունը, այն ուներ որոշ իրական թերություններ, որոնցից մի քանիսը թույլ չտվեցին, որ այն դառնա մեր վերջնական լուծումը.
- Կարգավորման արագություն. Աշխատատարածքի գրացուցակի տոպոլոգիայից կախված՝ աշխատատարածքի ACL-ների կիրառումը կարող է պահանջել զգալի ռեսուրսներ։
- Հետք. Մենք ծրագրավորողի համակարգում կիրառեցինք իրական ACL-ներ, թեև դրանց ազդեցությունը առանձնապես ներխուժող չէր, քանի որ կիրառված բոլոր ACL-ները վերաբերում էին հատուկ ստեղծված սինթետիկ SID-ի, որն օգտագործվում էր միայն sandbox-ի կողմից։
- Դժվար փոփոխվող սեմանտիկա. Ֆայլերի վրա հիմնված սահմանափակումների համար ACL-ներից կախվածությունը նշանակում է, որ sandbox-ի սեմանտիկան փոխելը ծախսատար և բարդ է։ Մինչդեռ macOS-ում մենք կարող ենք դինամիկ կերպով փոխել, թե ինչպես ենք գեներացնում
.sbpl-ը Seatbelt-ը կազմաձևելու համար օգտագործվող ֆայլը՝ Windows-ի ավազարկղը կարող է պահանջել դանդաղ և ռեսուրսատար գործողություն՝ ACL-ները կարգավորելու համար։ - Ցանցի պաշտպանությունը թույլ է։ Ինչպես արդեն նշել ենք, այն «խորհրդատվական» էր, որոշ ծրագրեր, որոնք իրականացնում էին իրենց սեփական ցանցային stack-ը, անպայման կշրջանցեին այն, և այն նախատեսված չէր հակազդող կոդի դիմակայության համար։
Առաջին երեք խնդիրները բնորոշ են այնպիսի հարմարեցված sandbox իրականացմանը, որը բավարար ճկուն է ագենտային հոսքերի համար։ Ցանցի ճնշման պատմությունը, սակայն, այլ էր։
Բացի այն հանգամանքից, որ վնասաբեր ագենտը հեշտությամբ կարող էր շրջանցել միջավայրի վրա հիմնված ցանցային սահմանափակումները, շատ բարեխիղճ կոդ/բինարիներ նույնպես կշրջանցեին դրանք պարզապես այն պատճառով, որ չէին հետևում միջավայրի proxy փոփոխականներին կամ օգտագործում էին socket-ների վրա հիմնված սեփական ցանցային կոդը։ Մենք համարեցինք, որ միայն այս հանգամանքն արդեն բավարար էր ավելի լավ sandbox ռեժիմում ներդրում կատարելու մասին մտածելու համար։
Ավելի լավ ցանցային սահմանափակում ստանալու համար մենք ցանկանում էինք օգտագործել Windows Firewall-ը, որը հնարավորություն է տալիս արգելափակել ծրագրերի կամ օգտատերերի ելքային ցանցային տրաֆիկը։ Ցավոք, մի քանի պատճառներով մեզ չհաջողվեց ստեղծել firewall-ի գործունակ կանոն, որը կվերաբերեր միայն Codex harness-ի կողմից գործարկվող հրամանների.
- Windows-ը թույլ չի տալիս firewall-ի կանոնը համապատասխանեցնել սահմանափակված թոքենի ոչ հիմնական ինքնությանը։ Սա նշանակում է, որ մենք չէինք կարող կիրառել firewall-ի կանոն «ցանկացած թոքենի վրա, որն իր restricted SID ցուցակում ներառում է մեր սինթետիկ SID-ն»։
- Թեև մենք կարող էինք ստեղծել firewall կանոն, որը համապատասխանում է որոշակի բինարի, դա միայն թույլ է տալիս սահմանափակել հենց
codex.exe-ի ցանցային հասանելիությունը։ Դա չէր կիրառվի այն պրոցեսների նկատմամբ, որոնք գործակալը ստեղծում է օգտատիրոջ անունից, օրինակ՝ Git-ի կամ Python-ի պրոցեսների նկատմամբ։ - Firewall-ի համապատասխանեցման մյուս չափորոշիչներն էլ սխալ կառուցվածք ունեին։ Օգտատիրոջ շրջանակով կանոնները առանց բարձրացված արտոնությունների նախագծում դեռևս համապատասխանում էին Windows-ի իրական օգտատիրոջը, ոչ թե միայն սահմանափակված child գործընթացին։ Ծրագրի ուղու կանոնները չափազանց ընդհանրական էին․ դրանք կարող էին ընդհանուր առմամբ արգելափակել
codex.exe-ն կամpython.exe-ն, բայց ոչpython.exe-ի՝ մեկուսացված միջավայրում կատարվող այս կոնկրետ գործարկումը։ Պորտի կամ հասցեի վրա հիմնված կանոնները նույնպես ամբողջովին սխալ քաղաքականություն էին։ Օրինակ՝ մենք չէինք ուզում արգելափակել 443 պորտը. մենք ուզում էինք արգելափակել կամայական ելքային հասանելիությունը այս կոնկրետ սահմանափակված գործընթացների ծառի համար։
Firewall-ի կանոնը կոնկրետ մեր sandbox-ում գործարկվող հրամանների վրա կիրառելու համար մենք պետք է դրանք գործարկեինք որպես առանձին principal, այլ ոչ թե որպես «իրական» օգտատեր։ Այս մոտեցումը մեզ տարավ նոր ուղղությամբ, որտեղ մենք մեղմեցինք մեր «առանց արտոնությունների բարձրացման» սահմանափակումը։
Sandbox միջավայրի հաջորդ տարբերակը, որը մեր ընթացիկ իրականացումն է, կարգավորման պահին պահանջում է բարձրացված ադմինիստրատորի թույլտվություններ։ Ուստի ես այն անվանում եմ «բարձրացված սանդբոքս»։ Այն սահմանագծում, որտեղ Codex-ը համակարգում գործարկում է հրաման, բարձրացված արտոնություններով մեկուսացված միջավայրը նման է առանց բարձրացված արտոնությունների միջավայրին։ Այն դեռ դուստր պրոցեսներ է գործարկում սահմանափակված թոքենի ներքո՝ նմանապես write_restricted թոքեն՝ [Everyone, Logon, Synthetic]նույն սահմանափակված SID ցուցակով, սակայն այս թոքենի սուբյեկտն այլևս Windows-ի իրական օգտատերը չէ, այլ Codex-ի կողմից ստեղծված երկու տեղական օգտատերերից մեկը՝
CodexSandboxOffline(այն, որի նկատմամբ կիրառվում են firewall-ի կանոնները)CodexSandboxOnline(այն, որի նկատմամբ firewall-ի կանոնները չեն կիրառվում)
Այս թվացյալ փոքր մանրուքը իրականում ունի կարևոր հետևանքներ sandbox-ի, դրա օգտագործման շրջանակի և կարգավորման ու runtime-ում դրա գործարկման բարդության համար։
Այն արտաքին տեսքով նման է unelevated նախատիպին՝ firewall-ի կանոնների և հատուկ Windows օգտատիրոջ ներդրմամբ, որը իրականում կատարում է հրամանների գործարկումը։ (Այնուամենայնիվ, այս նոր հասկացությունների ավելացումը նշանակում է, որ sandbox-ի աշխատանքը սկսելու և հրամանների պաշտպանությունը ապահովելու համար ավելի շատ setup աշխատանք է պահանջվում)։
Ոչ արտոնյալ sandbox նախագծումն ուներ պարզ կարգավորման քայլ, սակայն այն համեմատաբար փոքր էր.
- Անհրաժեշտության դեպքում ստեղծել սինթետիկ SID
- Կիրառել ACL-ներ sandbox-write սինթետիկ SID-ի համար
Սակայն elevated sandbox-ը ավելի շատ աշխատանք է պահանջում։
- Ստեղծել սինթետիկ SID, եթե այն դեռ ստեղծված չէ
- Ստեղծել առցանց և անցանց sandbox օգտատերերը, եթե դրանք դեռ ստեղծված չեն
- Պահպանել նոր ստեղծված օգտատերերի հավատարմագրերը տեղականում և դրանք գաղտնագրել Windows Data Protection API-ի (DPAPI) միջոցով՝ այնպիսի վայրում, որտեղ sandbox օգտատերերը իրականում չեն կարող դրանք կարդալ
- Ստեղծել firewall-ի կանոններ, որոնք արգելափակում են բոլոր ելքային ցանցային հասանելիությունները
CodexSandboxOfflineօգտատիրոջ համար, կամ եթե դրանք արդեն գոյություն ունեն, ստուգել, որ դրանք ճիշտ են
Կարգավորման փուլում կա ևս մեկ բարդացնող հանգամանք։ Ակնկալվում է, որ Codex-ի sandbox միջավայրը կունենա ընթերցման հասանելիություն, որը համարժեք է Windows-ի փաստացի օգտատիրոջ հասանելիությանը։ Չբարձրացված արտոնություններով ավազարկղում, որտեղ սահմանափակված թոքենի հիմնական SID-ը Windows-ի օգտատերն էր, սա իրականացվեց։ Սակայն դա անվճար չի ստացվում, երբ սուբյեկտը դառնում է նոր CodexSandbox օգտատեր։ Windows-ում բազմաթիվ համապատասխան գրացուցակներ «Նույնականացված օգտատերեր» խմբին կտրամադրեն կարդալու/գործարկելու թույլտվություններ։ Հատկանշական օրինակներից մեկը օգտատիրոջ պրոֆիլի գրացուցակն է։ Լռելյայն Windows-ի օգտատերերը չեն կարող կարդալ Windows-ի այլ օգտատերերի պրոֆիլի պանակները, ուստի շատ սցենարներում նույնիսկ ֆայլի ընթերցման պարզ գործողությունները կձախողվեին։
Այս հարցը լուծելու նպատակով մենք sandbox-ի setup գործընթացին ավելացրինք լրացուցիչ փուլ՝ sandbox օգտատերերին ընթերցման ACL-ներ տրամադրելու համար այն տեղերում, որտեղ դրանք հնարավոր է դեռ չլինեին սահմանված։ Օրինակ՝ Windows-ի հաճախ օգտագործվող որոշ գրացուցակներ՝
C:\Users\<real-user>C:\Windows\C:\Program Files\C:\Program Files (x86)\C:\ProgramData\
Քանի որ այս գրացուցակների ցանկը լավագույն փորձի բնույթ ունի, և դրանցից յուրաքանչյուրի վրա ACL-ների տեղադրումը կարող է բավականին թանկարժեք լինել, մենք այս գործընթացը իրականացնում ենք ասինխրոն, որպեսզի sandbox-ի setup քայլը, որը օգտատիրոջ համար արգելափակող է, չպետք է սպասի դրանց ավարտին։
Մենք տեղակայման տրամաբանությունը ամփոփեցինք առանձին բինար ֆայլում՝ մասամբ այն պատճառով, որ UAC-ի սահմանը հատենք միայն անհրաժեշտության դեպքում։ Սակայն ավելի խորքային պատճառը ճարտարապետական էր․ sandbox-ի կարգավորումն ունի սկզբունքորեն այլ խնդիր, քան codex.exe-ը։ Sandbox-ի կարգավորման տրամաբանությունը առանձին բինարում պահելը թույլ տվեց codex.exe -ին մնալ սովորական, ոչ արտոնյալ harness, թույլ տվեց Windows-ին հատուկ կարգավորման մեխանիզմները չուռճացնեն codex.exe -ը այլ հարթակներում, տարանջատեց ավելի երկարատև կարգավորման աշխատանքը հիմնական գործընթացի կյանքի տևողությունից, և մեզ տվեց մեկ վայր՝ sandbox-ին անհրաժեշտ տարբեր կարգավորման ուղիները մշակելու համար։
Windows-ում օգտատիրոջ և թոքենի մուտքի սահմանների աշխատանքի պատճառով մենք չէինք կարող շարունակել ստեղծել սահմանափակ թոքեն և դրա ներքո գործընթաց գործարկել այնպես, ինչպես կարողանում էինք ոչ արտոնյալ sandbox-ում։ Իրականում որպես այլ Windows օգտատեր հրամաններ գործարկելու համար մեր առաջին գաղափարը հետևյալ հոսքն էր.
codex.exe-ը աշխատում է որպես Windows-ի իրական օգտատեր։ Այնուհետև, հաջորդականությամբ, Codex-ը:- Կանչում է
LogonUserW(...)-ը sandbox-ի օգտատիրոջ համար։ - Կանչում է
CreateRestrictedToken(...)-ը այդ sandbox-օգտատիրոջ թոքենի վրա։ - Օգտագործելով այդ սահմանափակված sandbox-օգտատիրոջ թոքենը՝ կանչում է
CreateProcessAsUserW(...)-ը՝ վերջնական զավակ գործընթացը գործարկելու համար։
- Կանչում է
Գործնականում այդ ցանկալի ընթացքը չաշխատեց՝ CreateProcessAsUserW(...)-ի մոտ արտոնությունների պատնեշի պատճառով։ Սա նշանակում է, որ codex.exe -ը կարող էր սենդբոքսի օգտատիրոջ համար ստեղծել սահմանափակ թոքեն, սակայն սահմանի՝ իրական օգտատիրոջ կողմում չէր կարող հուսալիորեն այդ թոքենով դուստր գործընթաց գործարկել։ Մեզ անհրաժեշտ էր մի պրոցես, որն արդեն աշխատում էր որպես sandbox-ի օգտատեր. դա թույլ կտար, որ սահմանափակման քայլը և վերջնական գործարկումը տեղի ունենային սահմանի sandbox-ի օգտատիրոջ կողմում, այլ ոչ թե իրական օգտատիրոջ կողմում։
Այդ պահանջը հանգեցրեց codex-command-runner.exe-ի ստեղծմանը՝ նոր գործարկվող բինարի, որի միակ նպատակը սահմանափակված թոքեն թողարկելն ու պահանջված հրամանը գործարկելն է։ Փոխանակ codex.exe -ից պահանջելու ամբողջ հոսքը ինքնուրույն կատարել (իրական օգտատեր → sandbox օգտատեր → սահմանափակ թոքեն → child գործընթաց), մենք հոսքը բաժանեցինք երկու մասի.
Մաս 1
codex.exe-ը կանչում էCreateProcessWithLogonW(...)՝codex-command-runner.exe-ը sandbox օգտատիրոջ անունից գործարկելու համար՝ դեռ առանց սահմանափակ թոքեն օգտագործելու։
Մաս 2
- Runner-ի ներսում
OpenProcessToken(GetCurrentProcess(), ...)-ը բացում է runner-ի սեփական թոքենը, որն արդեն պատկանում է sandbox օգտատիրոջը։ - Runner-ը կանչում է
GetTokenInformation(...)՝ sandbox logon SID-ը հանելու համար, ապաCreateRestrictedToken(...)՝ վերջնական սահմանափակ թոքենը կառուցելու համար։ - Դեռ runner-ի ներսում այն կանչում է
CreateProcessAsUserW(...)՝ այդ սահմանափակ թոքենով իրական child գործընթացը գործարկելու համար։
Ալբերտ Այնշտայնը ասել է․ «Ամեն ինչ պետք է հնարավորինս պարզեցվի, բայց ոչ դրանից ավելի պարզ»։ Այդ ոգով մեր դիզայնը բավարար կերպով լուծեց յուրաքանչյուր խնդիր։ Վերջնական ճարտարապետությունը բաղկացած է չորս շերտերից, որոնց մասին մենք արդեն խոսել ենք.
- ինքը՝
codex.exe-ը codex-windows-sandbox-setup.exe՝ արտոնյալ կարգավորման հետ կապված ամբողջ աշխատանքը մշակելու համարcodex-command-runner.exe՝ սահմանափակ թոքենով հրամաններ գործարկելու համար- Child գործընթացը
Երբ առաջին անգամ սկսեցի այս նախագիծը, չունեի հստակ պատկերացում, թե այն ինչ արդյունքի կհասնի։ Ես սկսեցի Codex-ի և օպերացիոն համակարգի միջև ընկած սահմանում sandbox-ի հնարավորության ինստրումենտացումից։ Այս մոտեցումը մոտ է նրան, թե ինչպես է Codex-ի sandbox-ը իրականացված MacOS-ում և Linux-ում։
Windows-ի տրամադրած գործիքներին ավելի խոր ծանոթանալու և անվտանգության ու օգտագործման հարմարավետության միջև տասնյակ փոխզիջումային որոշումներ ընդունելու ընթացքում համակարգը ձևավորվեց իր ներկայիս տեսքին՝ բազմաբինար կառուցվածք, հատուկ ստեղծված օգտատերեր, firewall-ի կանոններ, բարձրացված setup քայլ, ասինխրոն գործընթացներ և այլն։
Սա առանձնապես պարզ համակարգ չէ, բայց բարդության յուրաքանչյուր մասը ավելացվել է անհրաժեշտությունից ելնելով՝ sandbox կառուցելու համար, որը և՛ անվտանգ է, և՛ հնարավորինս չի խանգարում օգտատիրոջը։
Windows-ում Codex-ի օգտատերերի համար լավ օգտագործման փորձ ապահովելու ուղղությամբ մեր նպատակն էր ստեղծել անվտանգ լուծում, որը չի զիջում գործունակությանը․ Codex-ի կիրառման հիմնական իմաստն այն է, որ ագենտները կարողանան կատարել աշխատանք առանց ձեր մշտական ուշադրության։
Այս նախագծից ստացված կարևոր դասերից մեկն այն էր, որ Windows-ը մեզ չէր տալիս մեկ պարզ պրիմիտիվ, որը ուղիղ կերպով համապատասխանում է «անվտանգ ինքնավար կոդավորման ագենտին»։ Մենք միավորեցինք մի քանի գործիքներ և գաղափարներ՝ կառուցելու միասնական համակարգ։ Որոշ սկզբնական մոտեցումներ տանում էին փակուղի։ Վերջնական դիզայնը նախորդ նախատիպերի հիբրիդ էր, որոնցից յուրաքանչյուրն իր մասով լուծում էր ընդհանուր խնդիրը։
Մյուս դասը այն էր, որ կոդավորման ագենտի անվտանգությունը բոլորովին այլ բնույթ ունի, քան ավելի դասական ծրագրերի կիրառական անվտանգությունը։ Codex-ը պետք է աշխատի իրական ծրագրավորողների աշխատանքային հոսքերի հետ։ Ինժեներական աշխատանքը վերաբերում էր ագենտային workload-ի հետ համատեղելիության և իրական կիրարկման միջև հավասարակշռության գտնելուն։ Այդ լարվածությունը ձևավորեց վերջնական դիզայնի փոխզիջումները։
Հետաքրքրվա՞ծ եք տեսնել Codex sandbox-ը գործողության մեջ։ Փորձեք այն։


