OpenVPN પર chroot નિષ્ફળ: AppArmor નિયમ કે ક્ષમતા?
AppArmor પ્રોફાઇલમાં પાથ ઉમેરવાથી ક્યારેય CAP_SYS_CHROOT મળતું નથી, અને નકારાયેલ chroot ત્રણ અલગ સ્તરોમાંથી આવી શકે છે. કયું બદલવું તે નક્કી કરો.
ડેમન chroot નિષ્ફળતા લોગ કરે છે અને પ્રોફાઇલ પહેલેથી જ ઉદાર દેખાય છે, તેથી લોભામણો ઉપાય પાથ નિયમ પહોળો કરીને ફરી શરૂ કરવાનો છે. તે સામાન્ય રીતે કંઈ બદલતું નથી, કારણ કે chroot એ પ્રિવિલેજ દ્વારા નિયંત્રિત છે જે પ્રોફાઇલ ક્યારેય સોંપી શક્યું ન હતું. કયા સ્તરને અડવું તે નક્કી કરવા માટે ત્રણ સસ્તી તપાસ જોઈએ: પ્રક્રિયાને શું રાખવાની છૂટ છે, નીતિ શું પરવાનગી આપે છે, અને લોન્ચરે તે બંનેનું મહત્વ થાય તે પહેલાં શું દૂર કર્યું.
બે અલગ દરવાજા, અને ફક્ત એક જ AppArmor નો છે
chroot ને જે વપરાશકર્તા નામસ્થાનમાં પ્રક્રિયા ચાલે છે ત્યાં CAP_SYS_CHROOT જોઈએ. આ સામાન્ય Linux પ્રિવિલેજ છે, જે કર્નલ કૉલ પાથ સાથે કંઈ કરે તે પહેલાં તપાસે છે. અલગથી, અમલ કરતું AppArmor પ્રોફાઇલ ક્ષમતાને નકારી શકે છે જ્યારે પ્રક્રિયા પાસે તે હોય, કારણ કે ફરજિયાત નીતિ ઓળખપત્રોની જગ્યાએ નહીં પણ તેમની સાથે સલાહ લેવાય છે. આ ભેદ વ્યવહારમાં મહત્વનો છે: બંને સ્તરો અલગ ફાઇલોમાં રહે છે અને સામાન્ય રીતે અલગ લોકો તેમને જાળવે છે.
બંને દરવાજા એક જ errno સાથે નિષ્ફળ જાય છે. બંને EPERM આપે છે, અને બંને ડેમન લોગમાં સામાન્ય પરવાનગી ફરિયાદ તરીકે દેખાય છે, એટલે પ્રોફાઇલની સામગ્રીની અટકળ કરવાથી આટલો સમય બગડે છે. તમે ઉમેરવા જઈ રહ્યા હતા તે પાથ નિયમ chroot સફળ થયા પછી ફાઇલ ઍક્સેસ નિયંત્રિત કરે છે; તેની સાથે ક્રિયા પરવાનગી છે કે નહીં તેનો કોઈ સંબંધ નથી.
ત્રીજો દરવાજો બંનેની ઉપર આવેલો છે. જો સેવા નિયંત્રક અથવા રેપરે પ્રક્રિયાને તેના બાઉન્ડિંગ સેટમાં ક્ષમતા વિના શરૂ કરી હોય, તો કોઈ AppArmor ફેરફાર તેને પાછી લાવી શકતો નથી, અને પ્રોફાઇલમાં ક્ષમતાઓ ઉમેરવાથી ફક્ત એવો ઇરાદો દસ્તાવેજ થાય છે જેને કર્નલ માનશે નહીં.
નીતિ સંપાદિત કરતાં પહેલાં પ્રિવિલેજ સ્થિતિ વાંચો
ચાલુ પ્રક્રિયાથી શરૂ કરો, તમે સક્રિય માનો છો તે રૂપરેખાંકનથી નહીં. સ્થિતિ ફાઇલ પાંચ ક્ષમતા માસ્ક અને no-new-privileges ફ્લેગ દર્શાવે છે, અને તે અલગ પ્રશ્નોના જવાબ આપે છે:
grep -E '^(CapInh|CapPrm|CapEff|CapBnd|CapAmb|NoNewPrivs):' /proc/$(pidof openvpn)/status
sudo aa-status | grep -i openvpnCapEff એ કૉલ માટે મહત્વનો સમૂહ છે: CapBnd માં હાજર પણ CapEff માં ગેરહાજર ક્ષમતા છત દ્વારા પરવાનગી છે અને હાલમાં ધરાવવામાં નથી. CapAmb ત્યારે મહત્વનું છે જ્યારે બાઇનરી સામાન્ય setuid અર્થમાં વિશેષાધિકૃત નથી, કારણ કે પર્યાવરણીય ક્ષમતાઓ એ રીત છે જેનાથી સેવા ફાઇલ ક્ષમતાઓ વિના exec દરમિયાન પ્રિવિલેજ રાખે છે. CapInh માં એવા બિટ્સ છે જે exec દરમિયાન વારસાગત થઈ શકે, પણ ફક્ત ત્યારે જ જ્યારે ચલાવાયેલ ફાઇલનો વારસાગત સમૂહ પરવાનગી આપે, તેથી ત્યાંનું એક બિટ એકલું કંઈ આપતું નથી.
પછી ખાતરી કરો કે કઈ પ્રોફાઇલ ખરેખર જોડાયેલી છે. પ્રક્રિયા તમે અપેક્ષા ન કરી હોય તેવા પ્રોફાઇલ નામથી મર્યાદિત હોઈ શકે, ખાસ કરીને જ્યારે વિતરણ તેની પોતાની યુનિટ ફાઇલ અને પ્રોફાઇલ સાથે મોકલે, અને /proc/PID/attr/current વાંચવાથી તે એક લીટીમાં સ્પષ્ટ થાય છે. તમારી સંપાદિત ફાઇલની સરખામણી કર્નલ જે પ્રોફાઇલ જણાવે છે તેની સાથે કારણ સુધારવા અને કોઈ ન લોડ કરતી ફાઇલ સંપાદિત કરવા વચ્ચેનો ફરક છે.
ક્ષમતા નિયમ ફક્ત ત્યારે ઉમેરો જ્યારે ઑડિટ ટ્રેઇલ એમ કહે
કર્નલ અને ઑડિટ રેકોર્ડ નકારનારું સ્તર નામ આપે છે. એવું નકાર જુઓ જેમાં ક્રિયા capable અને નામ sys_chroot સાથે જે પ્રોફાઇલે તેને જન્મ આપ્યો તેનો સમાવેશ હોય. જો એ રેકોર્ડ હાજર હોય, તો પ્રક્રિયા પાસે ક્ષમતા પહેલેથી હતી અને AppArmor એ નકારી, અને લક્ષિત ફેરફાર વાસ્તવિક પ્રોફાઇલની અંદર એક ક્ષમતા નિયમ છે:
capability sys_chroot,તેને ખરેખર જોડાયેલી પ્રોફાઇલમાં ટુકડા તરીકે રાખો, અને કીવર્ડને apparmor.d પ્રોફાઇલ સંદર્ભ સામે ચકાસો, અસંબંધિત ટ્યુટોરિયલમાંથી નિયમ કૉપિ કરવાને બદલે. તેને વિભાજિત include માં નાખવાથી તે ફાઇલ ખેંચતા દરેક મર્યાદિત પ્રોગ્રામને મળે છે, અને પ્રોફાઇલને complain મોડમાં બદલવાથી આગલું નકાર છુપાય છે, આને ઉકેલવાને બદલે. પ્રોફાઇલ નિયમ નીતિ-નકાર દૂર કરે છે; તે પ્રિવિલેજ બનાવતું નથી, તેથી જે પ્રક્રિયા પાસે ક્યારેય તેના પ્રભાવી સમૂહમાં CAP_SYS_CHROOT ન હતું તે નિયમ સાથે પણ નિષ્ફળ જશે.
જો ઑડિટ રેકોર્ડમાં AppArmor નકાર બિલકુલ ન દેખાય, તો પ્રોફાઇલ સંપાદિત કરવાનું બંધ કરો. તમે ઓળખપત્રોની સમસ્યા જોઈ રહ્યા છો, અને બાકીનું કામ યુનિટ ફાઇલ અથવા મૂળ પ્રક્રિયામાં છે, નીતિ ભાષામાં નહીં.
સેવા નિયંત્રક પોતાની છત રાખે છે
systemd દરેક સેવા માટે ક્ષમતા બાઉન્ડિંગ સેટ સેટ કરે છે, અને મૂળભૂત રીતે તે સમૂહ સાંકડો હોય છે. ત્યાં બાકાત કરેલું કંઈ પણ પ્રોફાઇલ શું કહે છે તે ધ્યાનમાં લીધા વિના પ્રક્રિયા માટે અનુપલબ્ધ છે, એટલે કઠોર યુનિટ એ ક્રિયામાં નિષ્ફળ જઈ શકે જે ડેમન હાથથી શરૂ કરતી વખતે કામ કરતી હતી. સંબંધિત નિર્દેશો યુનિટમાં વાંચવા સરળ છે અને જ્યારે એપ્લિકેશન નિષ્ફળતા જણાવે ત્યારે ધ્યાનમાં ન આવે તેવા પણ સરળ છે. વિતરણ પેકેજ દ્વારા મોકલાયેલા drop-in એ એવી છતનો સામાન્ય સ્રોત છે જે કોઈએ ગોઠવી હોવાનું યાદ નથી.
છત ઊંચી કરવી અને ક્ષમતા આપવી બે ફેરફાર છે, એક નહીં. બાઉન્ડિંગ સેટની નોંધ કહે છે કે પ્રક્રિયા ક્ષમતા રાખી શકે છે; તે તેને પ્રભાવી સમૂહમાં ઉમેરતી નથી, અને NoNewPrivs પછીના ઉન્નયનને સફળ થવાથી રોકી શકે છે, બાકીનું બધું મેળ ખાતું હોય તો પણ. ફક્ત એ જ ઉમેરો જે ક્રિયાને જોઈએ, બાકીની કઠોરતા અકબંધ રાખો, અને એક કૉલ પસાર કરવા બધી ક્ષમતાઓ આપવાના ટૂંકા રસ્તાને નકારો.
અહીં ક્રમ પણ મહત્વનો છે. પહેલા યુનિટની છત બદલો, ચકાસો કે CapEff માં હવે બિટ છે, અને પછી જ નક્કી કરો કે AppArmor હજી નકારે છે કે નહીં. બંને ફેરફાર એકસાથે કરવાથી નિષ્ફળતા ચાલુ રહે તો તમે ફરી અટકળમાં પડો છો.
નકાર દૂર થયા પછી, જેલ પોતે તપાસો
સફળ chroot મૂળને ખસેડે છે, તેથી ડેમન પછીથી અડતો દરેક પાથ નવા વૃક્ષમાં ઉકેલાય છે. ખૂટતું રૂપરેખાંકન, ગેરહાજર ઉપકરણ નોડ અથવા કૉપિ ન થયેલી પ્રમાણપત્ર ડિરેક્ટરી હવે ફાઇલ ભૂલ તરીકે દેખાશે, અને એ ભૂલ ક્ષમતાની સમસ્યા નહીં પણ ગોઠવણીની સમસ્યા છે. બીજી પરવાનગી ઉમેરવાને બદલે આગલી ઘટના વાંચો. આ ખસેડવું સાપેક્ષ પાથનો અર્થ પણ બદલે છે, એટલે કઠોરતા માર્ગદર્શિકાઓ ડેમન રૂપરેખાંકનમાં નિરપેક્ષ પાથ પર ભાર મૂકે છે.
chroot શું કરતું નથી તે યાદ રાખવું પણ મદદ કરે છે. તે પાથ સીમા છે, સેન્ડબોક્સ નહીં: પ્રિવિલેજ રાખતી પ્રક્રિયા તેમાંથી નાસી શકે છે, એટલે કૉલ પછી ક્ષમતા સામાન્ય રીતે છોડી દેવાય છે અને એટલે નિયંત્રણ ડેમનની આસપાસ રહેવું જોઈએ. AppArmor પ્રોફાઇલ, ક્ષમતા બાઉન્ડિંગ સેટ અને ફાઇલસિસ્ટમ પ્રતિબંધોને સાથે રાખવા એ આ કસરતનો હેતુ છે, સેવા શરૂ થાય પછી દૂર કરવાનો બાકી રહેલો કચરો નહીં.
નિર્ણય નિયમ ટૂંકો છે. જો ઑડિટ રેકોર્ડ AppArmor નું નામ લે, તો જોડાયેલી પ્રોફાઇલમાં એક ક્ષમતા નિયમ ઉમેરો. જો પ્રભાવી સમૂહ ખાલી હોય, તો યુનિટની છત અને પ્રિવિલેજ છોડવાનો ક્રમ સુધારો. જો પ્રોફાઇલ તમે સંપાદિત કરેલી ન હોય, તો સંપાદન બંધ કરો અને સાચી શોધો.