એક cgroup માંથી આવતા ટ્રાફિકને ચિહ્નિત કરવું સહેલો ભાગ છે. એક એપ્લિકેશન ભૌતિક ઇન્ટરફેસ દ્વારા બહાર નીકળે તે પહેલાં ત્રણ અલગ નિર્ણયો મેળ ખાવા જોઈએ, જ્યારે બાકીનું બધું ટનલમાં રહે છે: કયું socket આ અપવાદનું છે, ચિહ્ન કઈ રૂટિંગ શોધ શરૂ કરે છે, અને પેકેટ નીકળતી વખતે કયું સ્રોત સરનામું લઈ જાય છે. મોટાભાગના નિષ્ફળ પ્રયાસો પહેલું બરાબર કરે છે, બીજું અડધું કરે છે, અને ત્રીજા તરફ ક્યારેય જોતા નથી.

ત્રણ નિર્ણયો, એક નહીં

વર્ગીકરણ કહે છે કોને મુક્તિ છે. રૂટિંગ કહે છે ચિહ્નિત પેકેટ તેના બદલે ક્યાં જાય છે. સ્રોત પસંદગી કહે છે દૂરનો છેડો શું જોશે અને જવાબ ક્યાં પાછો આવવો જોઈએ.

આ સ્વતંત્ર રીતે નિષ્ફળ જાય છે. પેકેટ વર્ગીકૃત થઈ શકે, ભૌતિક ઇન્ટરફેસ પર ફરી રૂટ થઈ શકે, અને તોપણ એવું ખાનગી સરનામું વહન કરી શકે જે કોઈ અપસ્ટ્રીમ રાઉટર પાછું ન આપી શકે; પરિણામે એવો સમયસીમા થાય છે જે ફાયરવોલ બ્લોક જેવો લાગે છે. વર્ગીકરણના પગલામાં કંઈ પણ તેની ચેતવણી આપતું નથી. રૂટિંગના પગલામાં પણ નહીં.

ક્રમ પણ મહત્વનો છે. પેકેટ બને ત્યારે વર્ગીકરણ થાય છે, તે પછી રૂટિંગ થાય છે, અને અનુવાદ નિકાસ બિંદુ પર થાય છે.

ત્રણ તબક્કામાંથી કયો તૂટેલો છે તે જો તમે નામ ન આપી શકો, તો તમે ડિબગ કરતા નથી, નિયમો ફરી ગોઠવીને આશા રાખો છો.

એવા cgroup સાથે મેળ કરો જે કાલે પણ હશે

nftables socket ની cgroup v2 સભ્યતા ચકાસી શકે છે, જે ખરેખર ઉપયોગી છે કારણ કે તે પ્રક્રિયાને અનુસરે છે, ગંતવ્યને નહીં. ગૂંચ ઓળખકર્તામાં છે. મેનુમાંથી શરૂ થતી ડેસ્કટોપ એપ્લિકેશન ઘણી વાર ક્ષણિક scope માં રહે છે જેનું નામ આગલી વખતે શરૂ થતાં બદલાય છે.

nft list ruleset
systemctl status session.slice 2>/dev/null
cat /proc/self/cgroup

એક સેશનમાંથી scope નું નામ કોપી કરીને હાર્ડકોડ કરવાથી એવો નિયમ બને છે જે આજે કામ કરે છે અને કાલે ચૂપચાપ મેળ ખાવાનું બંધ કરે છે. તેના બદલે એપ્લિકેશનને જાણી જોઈને સ્થિર ચલાવવાના સંદર્ભમાં મૂકો, જેમ કે તમારા નિયંત્રણ હેઠળનું સમર્પિત scope કે unit, અને તેની સાથે મેળ કરો. પછી નિયમ રીબૂટ અને પેકેજ અપડેટ પછી પણ ટકે છે. તે એવી વસ્તુ પણ બને છે જેના વિશે સહકર્મી તમારા સેશન-ઇતિહાસ વિના વિચારી શકે.

તમે કઈ પદ્ધતિ વાપરો છો તે વિશે પણ ચોક્કસ રહો. cgroup v1 net_cls વર્ગીકરણ અને cgroup v2 socket મેળ બે અલગ વસ્તુઓ છે, અને દસ્તાવેજમાં સમાન નામનું ક્ષેત્ર હોવાથી તે બદલી શકાય તેવા બનતા નથી.

route પ્રકારની ચેઇન જ બીજી શોધ શરૂ કરે છે

સ્થાનિક રીતે ઉત્પન્ન થતા ટ્રાફિક માટે ચેઇનનો પ્રકાર નક્કી કરે છે કે ચિહ્ન મૂક્યા પછી કંઈ થાય છે કે નહીં. filter પ્રકારની આઉટપુટ ચેઇન પેકેટને ચિહ્નિત કરી શકે છે અને કર્નલ પહેલેથી પસંદ કરેલા રૂટનો ઉપયોગ ચાલુ રાખશે. route પ્રકારની ચેઇન એ પદ્ધતિ છે જે નવી શોધ માંગે છે.

table inet bypass {
  chain mark {
    type route hook output priority mangle; policy accept;
    socket cgroupv2 level 2 "app.slice" meta mark set 0x1 comment "app bypass"
  }
}
ip rule add fwmark 0x1 lookup 200
ip route add default via 203.0.113.1 dev wlan0 table 200

પછી ચિહ્નને એવા નીતિ નિયમની જરૂર છે જે તેને ટેબલમાં મોકલે, અને તે ટેબલ પૂર્ણ હોવું જોઈએ: ડિફોલ્ટ રૂટ, એપ્લિકેશનને હજી જરૂરી હોય તેવા સ્થાનિક ગંતવ્યો, અને ખરેખર જવાબ આપતું અપસ્ટ્રીમ ગેટવે.

ચિહ્નનું મૂલ્ય જાણી જોઈને પસંદ કરો. WireGuard બહારના પરિવહન ટ્રાફિક માટે પોતાનું fwmark વાપરે છે, અને આકસ્મિક રીતે એ જ સંખ્યા પર પહોંચવું ટનલની પોતાની રૂટિંગ અપવાદમાં એવી રીતે દખલ કરી શકે છે જેનું નિદાન કષ્ટદાયક છે.

સ્રોત સરનામું રૂટને અનુસરતું નથી

જે socket પહેલેથી ટનલ માર્ગ માટે સ્રોત સરનામું પસંદ કરી ચૂક્યું છે તે ફરી રૂટ થયા પછી પણ તે સરનામું રાખે છે. રૂટિંગ ફેરફારમાં કંઈ પણ તેને ફરી લખતું નથી, તેથી પેકેટ ભૌતિક ઇન્ટરફેસ છોડે છે એવા ખાનગી સ્રોત સાથે જે અપસ્ટ્રીમ નેટવર્ક પાછું ન આપી શકે.

દેખાતું લક્ષણ એ છે એપ્લિકેશન જે ડેટા મોકલતી હોય તેવું લાગે છે અને ક્યારેય જવાબ મળતો નથી, અને ફાયરવોલ લોગ જે કંઈ બતાવતો નથી કારણ કે પેકેટ ક્યારેય પાછું આવ્યું નહીં.

સંકુચિત સુધારો એ છે તે એપ્લિકેશનના ચિહ્ન અને તેના વાસ્તવિક આઉટપુટ ઇન્ટરફેસ સુધી મર્યાદિત સ્રોત-અનુવાદ નિયમ, જે હાલના NATને બદલવાને બદલે તેની સાથે જોડાય છે:

table inet bypass {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    meta mark 0x1 oifname "wlan0" masquerade
  }
}

ફક્ત અપવાદનું અનુવાદ કરો, બીજું કંઈ નહીં. સામાન્ય masquerade નિયમ લક્ષણ સુધારે છે અને કયો ટ્રાફિક કયો માર્ગ ગયો તે કહેવાની તમારી ક્ષમતા નષ્ટ કરે છે. ચિહ્ન, વાસ્તવિક આઉટપુટ ઇન્ટરફેસ અને શક્ય હોય તો એપ્લિકેશનના પોતાના સરનામા પર મેળ કરો. પહોળા નિયમો લખવા સહેલા છે અને પછીથી ઓડિટ કરવા લગભગ અશક્ય.

અપવાદમાંથી હજી શું બહાર નીકળે છે

નામ-ઉકેલ બીજા cgroup માંના અલગ resolver પ્રક્રિયામાંથી આવી શકે છે, તેથી બ્રાઉઝરના socket ને વર્ગીકૃત કરવાથી તેની શોધો વર્ગીકૃત થતી નથી. જો resolver ની પ્રશ્નાવલિ ટનલમાં રહે અને જોડાણ તેની બહાર નીકળે, તો split-horizon જવાબો માર્ગ સાથે મેળ ન ખાઈ શકે. તે અસંગતિ એવી નિષ્ફળતાઓ ઉત્પન્ન કરે છે જે DNS બગ જેવી લાગે છે અને છે નહીં.

બાળ પ્રક્રિયાઓ મોટાભાગની ગોઠવણોમાં cgroup વારસામાં લે છે, પણ જે helper પોતાને પોતાના scope માં ખસેડે છે તે નથી લેતું. ધારણા કરવાને બદલે ચકાસો, ખાસ કરીને જે પોતાને ફરી ચલાવે છે તેના માટે.

અંતે, ટનલ બંધ હોય ત્યારે શું થવું જોઈએ તે નક્કી કરો. જે અપવાદ ચૂપચાપ સંપૂર્ણ બાયપાસ બની જાય છે તે બંધ નિષ્ફળ થતા અપવાદ કરતાં અલગ સુરક્ષા વલણ છે, અને તેમાંથી ફક્ત એક જ તમારો આશય હતો.

સંબંધિત લેખો