fwmark સાથે એક જ Linux હોસ્ટ પર બે OpenVPN ક્લાયન્ટ જોડો
બંને ક્લાયન્ટને ડિફોલ્ટ રૂટ જોઈએ છે. અંદરના સર્વરને હોસ્ટ રૂટથી પિન કરો, બીજા ક્લાયન્ટને ટેબલ ફરીથી લખતા રોકો, અને પછી fwmark વડે ફ્લોની દિશા નક્કી કરો.
એક જ Linux હોસ્ટ પર બીજો OpenVPN ક્લાયન્ટ ઉમેરવો બેમાંથી એક જગ્યાએ નિષ્ફળ જાય છે. કાં તો અંદરનો ક્લાયન્ટ પોતાના સર્વર સુધી પહોંચી શકતો નથી કારણ કે બહારના ટનલે એ ટ્રાન્સપોર્ટ કબજે કરી લીધો છે, અથવા બીજો ક્લાયન્ટ રૂટ ટેબલ ફરીથી લખે છે અને પહેલું ટનલ કામ કરવાનું બંધ કરે છે. બંને સમસ્યાઓ રૂટિંગમાં છે, એન્ક્રિપ્શનમાં નહીં, અને બંને નવું ટનલ કોઈ પણ એપ્લિકેશન ટ્રાફિક લે તે પહેલાં ઉકેલાય છે. અહીંના સરનામાં ઉદાહરણ માટે છે: tun0 એ બહારનું ટનલ છે, 203.0.113.9 એ અંદરનું સર્વર છે, અને TCP 9999 એ ફ્લો છે જે અંદરનો રસ્તો વાપરવો જોઈએ.
બે નિષ્ફળતાના પ્રકાર, એક રૂટ ટેબલ
અંદરનો ક્લાયન્ટ પોતાના સર્વર તરફ UDP સોકેટ ખોલે છે, અને એ સોકેટ બીજા કોઈ પણ જેવું જ વર્તમાન રૂટ ટેબલને અનુસરે છે. જો બહારનું ટનલ પહેલેથી ડિફોલ્ટ ધરાવે છે, તો હેન્ડશેક પેકેટ બહારના ટનલમાં જાય છે. એ ત્યારે જ કામ કરે છે જ્યારે બહારનું સર્વર અંદરના સર્વર સુધી પહોંચી શકે અને સામેનો ભાગ ફ્લો વહન કરવા સંમત થાય; નહીં તો હેન્ડશેક અટકી જાય છે અને ક્લાયન્ટ ફરી પ્રયાસ કરે છે.
બીજી નિષ્ફળતા સર્વર પુશમાંથી આવે છે. સામાન્ય પુશ redirect-gateway def1 છે, જે ડિફોલ્ટ રૂટ બદલવાને બદલે 0.0.0.0/1 અને 128.0.0.0/1 સ્થાપિત કરે છે. તેથી જે બે ક્લાયન્ટ પોતપોતાની /1 જોડી સ્થાપિત કરે છે તે અથડાય છે, અને લગભગ દરેક ગંતવ્ય માટે નવી જોડી જીતે છે. જ્યારે બીજું જોડાયા પછી ટનલ મરી જાય ત્યારે ટેબલમાં એ બે પ્રીફિક્સ જુઓ, કારણ કે ડિફોલ્ટ રૂટ પોતે કદાચ ક્યારેય બદલાયો જ ન હોય.
ફ્લોને માર્ક કરો અને તેને ટેબલ આપો
પસંદ કરેલા ટ્રાફિકને mangle ટેબલમાં માર્ક કરીને અને પોલિસી નિયમમાં એ માર્ક સાથે મેળ કરીને દિશા આપો. નિયમ સમર્પિત ટેબલ તરફ ઇશારો કરે છે જેનો ડિફોલ્ટ રૂટ અંદરનું ઉપકરણ છે, જેથી ફક્ત માર્ક કરેલા પેકેટ જ અંદરનો રસ્તો લે.
iptables -t mangle -A PREROUTING -p tcp -m multiport --dport 9999 -j MARK --set-mark 0x9999
ip rule add fwmark 0x9999 table 200 pref 1000
ip route add default dev tun1 table 200આ નિયમ સેટમાં મોટા ભાગની નિષ્ફળતાઓ બે ભૂલોમાંથી આવે છે. ફાયરવોલ જે માર્ક મૂલ્ય સેટ કરે છે અને નિયમ જે મૂલ્ય સાથે મેળ કરે છે તે સરખા જ હોવા જોઈએ, કારણ કે તફાવત કોઈ ભૂલ કે અસર ઉત્પન્ન કરતું નથી. અને PREROUTING ફક્ત બહારથી આવતા પેકેટ જુએ છે, તેથી આ હોસ્ટ પર શરૂ થયેલા કનેક્શનને માર્ક થવા પહેલાં સમાન મેળ સાથે OUTPUT નિયમની જરૂર પડે છે.
બીજા ક્લાયન્ટ પાસેથી રૂટની માલિકી લઈ લો
બે વિકલ્પો બીજા ક્લાયન્ટને ટેબલ સંપાદિત કરતા રોકે છે, અને તેઓ જુદા જુદા મુદ્દે કામ કરે છે. route-nopull પુશ કરેલા રૂટ વિકલ્પોને અવગણે છે, તેથી કંઈ સ્થાપિત થતું નથી. route-noexec પુશ કરેલા વિકલ્પોને ક્લાયન્ટના પર્યાવરણમાં સ્વીકારે છે પણ ટેબલ ફેરફાર હૂક પર છોડી દે છે, જે તમે ત્યારે ઇચ્છો છો જ્યારે સર્વરે શું આપ્યું તે જોવું હોય.
હૂક પોતાના પર્યાવરણમાં પુશ કરેલા મૂલ્યો સાથે ચાલે છે, અને તેણે ફક્ત તમે મંજૂર કરેલી એન્ટ્રીઓ ઉમેરવી જોઈએ. તેને idempotent બનાવો: ફરીથી બનાવતા પહેલાં જે ટેબલ તેનું છે તે ખાલી કરો, અને એવું ન ધારો કે અગાઉની વારે સ્વચ્છ સ્થિતિ છોડી હતી. ફરી કનેક્ટ થવાથી હૂક ફરી ચાલે છે, અને સાફ કર્યા વિના ઉમેરતો હૂક નકલી રૂટ એકઠા કરે છે.
એક માલિક પસંદ કરો અને તેને લખી રાખો. જે પ્રોફાઇલ બંને વિકલ્પો સેટ કરે છે, અથવા જે હૂક મેન્યુઅલ સ્ક્રિપ્ટ સાથે સ્પર્ધા કરે છે, તે એવું ટેબલ બનાવે છે જે કોઈ પછીથી સમજાવી શકે નહીં.
બંને સર્વર સરનામાં પિન કરો
અંદરના ક્લાયન્ટના કનેક્શન પહેલાં અંદરના સર્વરને બહારના ઉપકરણ દ્વારા હોસ્ટ રૂટની જરૂર છે. એ જ એન્ટ્રી અંદરના ટ્રાન્સપોર્ટને બહારના ટનલની અંદર રાખે છે, તેને ડિફોલ્ટને અનુસરવા દેવાને બદલે.
ip route add 203.0.113.9/32 dev tun0
ip route get 203.0.113.9મુખ્ય ટેબલમાં બહારના સર્વર માટે પણ મેળ ખાતો હોસ્ટ રૂટ ઉમેરો, નહીં તો ફરી કનેક્ટ થવાથી બહારના ક્લાયન્ટનું પોતાનું ટ્રાન્સપોર્ટ તેના પોતાના ટનલમાં રૂટ થઈ શકે છે. ક્રમ વૈકલ્પિક નથી: સંબંધિત ઇન્ટરફેસ અસ્તિત્વમાં આવ્યા પછી જ આ એન્ટ્રીઓ ઉમેરો, એટલે કે હૂક અથવા સ્ક્રિપ્ટ જે કનેક્શન પછી ચાલે. બંધ ઉપકરણ તરફ ઇશારો કરતો રૂટ દૂર કરવામાં આવે છે અથવા અવગણવામાં આવે છે, તેથી બૂટ વખતે લખાયેલી એન્ટ્રી તમે ધારેલા ક્રમમાં ટકી શકતી નથી.
આખું ટેબલ વાંચવાને બદલે લુકઅપ તપાસો. રૂટ લુકઅપનું આઉટપુટ એ ઉપકરણ અને સ્રોત સરનામું જણાવે છે જે કર્નલ વાપરશે, અને ક્લાયન્ટ સોકેટ ખોલે ત્યારે બરાબર એ જ મેળવે છે.
ચેઇનની કસોટી કરો અને નિષ્ફળતા દેખાય તેવી બનાવો
અંદરનો ક્લાયન્ટ કનેક્ટ થતી વખતે બહારના ઇન્ટરફેસ પર કેપ્ચર કરો. અંદરનો હેન્ડશેક બહારના ટનલની અંદર એન્ક્રિપ્ટેડ પેલોડ તરીકે દેખાવો જોઈએ; જો તે 203.0.113.9 તરફ સાદા UDP તરીકે દેખાય, તો હોસ્ટ રૂટ ગેરહાજર છે અને ચેઇન ક્યારેય બન્યું જ નથી.
ભૌતિક અપલિંક પર ચૂપચાપ પાછું જતું ચેઇન સૌથી ખરાબ પરિણામ છે, કારણ કે ઇન્ટરફેસની સ્થિતિ કંઈ જાહેર કરતી નથી અને અંદરનો ટ્રાફિક ખોટા સ્રોત સરનામેથી નીકળે છે. જો બહારનું ટનલ પડે ત્યારે બીજો ક્લાયન્ટ સીધો ફરી કનેક્ટ થઈ શકે છે, તો એ માર્ગ બંધ કરો અથવા તેને બહારના ઇન્ટરફેસ સાથે બાંધો જેથી નિષ્ફળતા દેખાય.
બે ફ્લો અને એક નિયમ ડમ્પ સાથે પૂરું કરો: માર્ક કરેલું કનેક્શન અને માર્ક ન કરેલું એ જુદા રસ્તા લેવા જોઈએ, અને ip rule show એ તમે ઇચ્છેલી પ્રાથમિકતા યાદીમાં દર્શાવવી જોઈએ. જો બંને ફ્લો એક જ રસ્તો લે, તો માર્ક તમે ધારો છો ત્યાં લાગુ પડતું નથી.