Ինչու OpenVPN-ի կեռիկը չի գտնում իր սկրիպտի կողքի ֆայլը
Կեռիկի հարաբերական ուղիները լուծվում են գործընթացի, ոչ թե սկրիպտի նկատմամբ։ Ամրացրե՛ք դրանք __file__-ով, ապա թույլտվություններից առաջ ստուգե՛ք անվանատարածքը և ինքնությունը։
Կեռիկները, որոնք աշխատում են առանց սխալի և այնուամենայնիվ հայտնում են բացակայող ֆայլի մասին, սովորաբար սխալ տեղ են նայում, ոչ թե ձախողվում իրենց գործում։ Սկրիպտի հարաբերական ուղիները լուծվում են գործընթացի աշխատանքային պանակի նկատմամբ, և ծառայությունը սկսվում է ձեր չընտրած աշխատանքային պանակով։ Սկրիպտի կողքի ֆայլը և այն ֆայլը, որը բացում է գործընթացը, նույն բանն են միայն այն ժամանակ, երբ ինչ-որ բան ամրացնում է դրանք։ Այդ ճեղքը բացատրում է կեռիկների ձախողումների մեծ մասը, որոնք սխալմամբ թույլտվությունների խնդիր են կարդացվում։
Ստուգե՛ք ուղին թույլտվություններից առաջ, որովհետև սխալ ֆայլի վրա թույլտվության սխալը դեռ սխալ ֆայլն է։
Հարաբերական ուղին լուծվում է գործընթացի, ոչ թե ֆայլի նկատմամբ
Երբ սկրիպտը կանչում է open("policy.json"), միջուկը անունը լուծում է գործընթացի ընթացիկ աշխատանքային պանակի նկատմամբ։ Սկրիպտի սեփական դիրքից ոչինչ չի մասնակցում այդ որոնմանը։ OpenVPN կեռիկները սկսում է իր իսկ ընտրած պանակից, և cd ընտրանքը կարող է փոխել այն, ուստի իր պանակից ձեռքով փորձարկված սկրիպտն այլ կերպ է վարվում, երբ դեմոնը գործարկում է այն։ Ձեռքի փորձարկումը անցնում է, ծառայության գործարկումը ձախողվում է, և մատյանի տողը հիշատակում է միայն բացակայող անունը։
Python-ը բացահայտում է սկրիպտի դիրքը որպես __file__, և հենց դա է հնարավոր դարձնում ամրացումը։ Path(__file__).resolve().parent / "policy.json" ուղի է կառուցում ֆայլից, ոչ թե գործընթացից։ Այդ մեկ տողը հեռացնում է աշխատանքային պանակից կախվածությունը՝ ոչինչ չփոխելով արտոնություններում։
Ամրացրե՛ք ուղին դիտավորյալ, ապա ստուգե՛ք, թե ինչ է անում resolve-ը
resolve() հետևում է սիմվոլիկ հղումներին, ուստի այն տեղադրումը, որը կեռիկը հղում է իր տեղում, ամրանում է հղման նպատակակետում, ոչ թե հղումը պարունակող պանակում։ Սա սովորաբար այն է, ինչ ուզում եք տարբերակված տեղակայման համար, և սխալ է այն դասավորության համար, որը տվյալներ է սպասում սիմվոլիկ հղման կողքին։ Որոշե՛ք, թե տեղակայումն ինչ նկատի ունի, և գրե՛ք կոդը համապատասխան, փոխարենը արտադրության մեջ չբացահայտելով տարբերությունը։ Path(__file__).parent առանց resolve() պահպանում է հղման սեփական պանակը։
Եթե տվյալները պատկանում են օրինակին, ոչ թե ծրագրին, վերցրե՛ք բացարձակ ուղի կարգավորումից։ Տեղի կոշտ կոդավորումը կեռիկը կապում է մեկ հոսթի դասավորության հետ։
Անցե՛ք չորս սահման հերթականությամբ
Սկսե՛ք աշխատանքային պանակից՝ համեմատե՛ք միավորի WorkingDirectory, OpenVPN-ի cd ընտրանքը և ցանկացած փաթաթիչ, որը փոխում է պանակը exec-ից առաջ։ Ապա հաստատե՛ք լուծված դիրքը, որովհետև նույնանման անունով ֆայլը մեկ այլ տեղակայման մեջ կարող է պատասխանել որոնմանը և թաքցնել սխալը։ Հետո գալիս է ֆայլային համակարգի տեսքը՝ chroot-ը կամ ծառայության mount-անվանատարածքը կարող են հոսթի բացարձակ ուղին պարզապես բացակա դարձնել։ Վերջինը մուտքի ինքնությունն է, որը տեսանելիությունից առանձին հարց է։
ProtectHome և PrivateTmp թաքցնում են տարբեր տեղեր, և նրանցից ոչ մեկը չի երևում հոսթից վերցված պանակի ցանկում։ Մի ուղի, որը shell-ում գոյություն ունի root-ի համար, կարող է անտեսանելի լինել միավորի անվանատարածքի ներսում, և դրա համար է, որ ծառայությունից դուրս նույն հրամանի փորձարկումը այդքան քիչ բան է ապացուցում։
Ուղղե՛ք որոնումը՝ չընդլայնելով ծառայությունը
Ուղու ամրացումը լուծում է միայն առաջին սահմանը։ Այն չի բացահայտում պանակ, որը ծառայությունը թաքցնում է, և չի տալիս արտոնություն չունեցող հաշվին մուտք դեպի միայն root-ի ֆայլ։ script-security բարձրացնելը փոխում է, թե որ սկրիպտները OpenVPN-ը կգործարկի; դա ոչ մի ազդեցություն չունի այն բանի վրա, թե որտեղ է լուծվում հարաբերական անունը։ Ամբողջ ծառայության աշխատանքային պանակը փոխելը խնդրից ավելի լայն է, որովհետև յուրաքանչյուր այլ հարաբերական վկայագրի, մատյանի կամ օժանդակ ուղի շարժվում է դրա հետ։
Նախընտրե՛ք նեղ ուղղումը՝ որոշիչ ուղի սկրիպտում, բացահայտ կարգավորման արժեք օրինակի տվյալների համար, և ֆայլի սեփականություն, որը համապատասխանում է այն հաշվին, որի ներքո կեռիկն իրականում աշխատում է։
Արձանագրե՛ք ապացույց, որը անվանում է սահմանը
Օգտակար ձախողման հաշվետվությունը պարունակում է երեք բան՝ ճշգրիտ ուղին, որը փորձել է կեռիկը, միջավայրը, որը ստեղծել է այն, և թե որ սահմանն է մերժել։ Տպե՛ք լուծված ուղին և բացառությունը՝ առանց ֆայլի պարունակությունը թափելու։ Այդ եռյակը տարանջատում է սխալ ամրացումը թաքնված mount-ից և թույլտվության մերժումից, որոնք երեք տարբեր ուղղումներ են։
Այն պնդումը, թե root-ը կարող է ֆայլը կարդալ տերմինալից, պատասխանում է այդ հարցերից մեկին և ոչ մեկին մյուսներից։ Փոխարենը փորձարկե՛ք ծառայության սեփական համատեքստից։