Ծրագիրը, որը խոսում է միայն SOCKS, սովորական VPN-ում ոչնչի հետ խոսելու բան չունի, քանի որ թունելը փոխադրում է փաթեթներ, իսկ ծրագիրը վստահված սերվերի վերջնակետ է ուզում։ OpenSSH-ը կարող է տրամադրել այդ վերջնակետը, երբ մուտքի սեփականատերը թույլ է տալիս, քանի որ դինամիկ փոխանցումը մեկ SSH նստաշրջանը դարձնում է տեղական վստահված սերվեր։ Այնուհետև պետք է իրարից տարբեր պահել երկու թռիչք՝ թունելը, որը հասնում է SSH հոստին, և կապը, որը այդ հոստը հետագայում բացում է։ Նրանց տարանջատումը բացատրում է և՛ ինչու է այս դասավորությունը աշխատում, և՛ ինչ այն երբեք չի անի։

Ինչի է վերածվում SSH լսողը և ինչի՝ ոչ

Դինամիկ փոխանցումը ստիպում է SSH հաճախորդին լսել տեղական և խոսել SOCKS4 կամ SOCKS5 այն ամենի հետ, ինչ միանում է։ Յուրաքանչյուր հարցում անվանում է նպատակակետ, և SSH սերվերը բացում է հետագա կապը, այդ պատճառով նպատակակետի որոնումը կարող է տեղի ունենալ հեռավոր կողմում։ Սա TCP փոխանցում է ծրագրի մակարդակում, ոչ թե VPN ամբողջ սարքի համար։ Այն չի կրում ոչ UDP միավորում, ոչ ICMP, և ոչինչ այն ծրագրերի համար, որոնք լիովին անտեսում են վստահված սերվերի կարգավորումները։ SSH սերվերից ծրագիր թռիչքը նույնպես ձեր թունելի ներսում չէ, ինչը նշանակալի է, երբ նպատակակետը թրաֆիկ ընդունում է միայն հայտնի ցանցերից։

Նախապայմանները իրական են՝ երթուղի դեպի SSH հոստ, լիազորված հաշիվ, ստուգված սերվերի հոստ բանալի և փոխանցման թույլտվություն։ Ոչ մեկը դրանցից վստահված սերվերը չի ստեղծում, և վերջինը սովորաբար առաջինն է, որ բացակայում է։ Հաստատեք բոլոր չորսը նախքան որևէ այլ բան վրիպազերծելը, քանի որ հաճախորդի կողմից ձախողումը նույն տեսքն ունի, որն էլ բացակայի։

Սկսեք այն loopback-ի վրա՝ բացահայտ պորտով

Ընտրեք չօգտագործվող տեղական պորտ և բացահայտ կապեք այն loopback-ին՝ հասցեն բաց թողնելու փոխարեն։ Ստորև երեք տարբերակներից յուրաքանչյուրը մեկ պատճառով գոյություն ունի։

ssh -D 127.0.0.1:1080 -NT -o ControlPath=none -o ExitOnForwardFailure=yes \
  [email protected]

-N բաց է թողնում հեռավոր հրամանը, և -T բաց է թողնում կեղծ տերմինալը, ուստի նստաշրջանը գոյություն ունի միայն փոխանցելու համար։ ExitOnForwardFailure ստիպում է հաճախորդին դուրս գալ, երբ լսողը հնարավոր չէ ստեղծել՝ ձեր ուզած փոխանցումն առանց աշխատելու փոխարեն։ ControlPath=none նստաշրջանը հեռու է պահում գոյություն ունեցող մուլտիպլեքս կապից, որը կարող է իր փոխանցումներն ավելացնել։ Loopback-ը լսողին հեռու է պահում LAN-ից, սակայն համօգտագործվող մեքենայում դա լիազորման սահման չէ, քանի որ այլ տեղական պրոցեսներ նույնպես կարող են հասնել դրան։ OpenSSH հաճախորդի տեղեկագիրը փաստաթղթավորում է այս բոլոր դրոշները, և loopback-ի նախազգուշացումը բխում է նրանից, թե ինչ է լսող սոքեթը։

Անուններն ուղարկեք վստահված սերվերի միջով, ոչ թե շուրջը

SOCKS5 հաճախորդը կարող է ինքը լուծել նպատակակետը կամ խնդրել վստահված սերվերին անել դա, և այդ ընտրությունը որոշում է, թե որ լուծիչը կպատասխանի։ socks5h-ով curl-ը հոստի անունն ուղարկում է վստահված սերվերի միջով, ուստի որոնումը տեղի է ունենում SSH սերվերում։ Սովորական socks5-ով դյուրակիրը նախ ինքն է լուծում, և ճամփորդում է միայն կապը, ինչը լուռ զրոյացնում է նպատակը, երբ անունը ներքին է։ Ստորև հարցումը նաև մաքրում է առանց վստահված սերվերի ցանկը, որպեսզի ժառանգված NO_PROXY արժեքը չկարողանա այն տանել վստահված սերվերի շուրջը։

curl -sS --noproxy '' --proxy socks5h://127.0.0.1:1080 https://app.corp.example/health

Վկայագրի ստուգումը և ծրագրի սեփական մուտքը դեռ գործում են, քանի որ վստահված սերվերը ոչ մեկը չի փոխարինում։ Մնում են երկու որոնում՝ դյուրակիրը պետք է հասնի SSH հոստին թույլատրված VPN և DNS ուղով, և SSH սերվերը պետք է ինքը լուծի ծրագրի անունը։ Երկրորդը կարելի է առանձին ստուգել նախքան ցանկացած թրաֆիկ վստահված սերվերով անցնելը։

ssh [email protected] getent hosts app.corp.example

Ապացուցեք մեկ թույլատրված նպատակակետ, ապա փակեք նստաշրջանը

Փորձարկեք նպատակակետ, որը քաղաքականությունը թույլատրում է, և մեկը, որը պետք է մերժի, քանի որ աշխատող փոխանցումը ապացուցում է միայն, որ լսողն աշխատում է, և ոչ ավելին։ Ծրագիրը տեսնում է աղբյուրի հասցեն, որը ընտրում է SSH սերվերը, և դա ձեր դյուրակիրի թունելի հասցեն չէ։ Այնտեղ, որտեղ հեռավոր կողմը գրանցում է կապերը ըստ աղբյուրի, այդ տարբերությունն առաջինն է, ինչ պետք է ստուգել, երբ հարցումը մերժվում է։

Կանգնեցրեք նստաշրջանը դրա տեր պրոցեսի միջով, այլ ոչ թե սպանելով անկապ shell։ Ապա հաստատեք, որ լսողը գնացել է, քանի որ դեռ պատասխանող պորտը նստաշրջան է, որը դուք իրոք չեք փակել։ Հեռացրեք միայն այն վստահված սերվերի կարգավորումը, որը ներմուծեց այս վարժությունը, և թողեք ծրագրի մնացած կարգավորումները հանգիստ։ Առանց հսկողության տերմինալը, որը պահում է փոխանցման կանոն, ծառայություն չէ, և մշտական վստահված սերվերը պահանջում է հաստատված կենսացիկլ, այլ ոչ թե մոռացված պատուհան։

ss -ltn | grep 1080

Անհաջողություններ, որոնք այս դասավորությունը չի կարող ուղղել

Որոշ ախտանիշներ ուղիղ մատնանշում են վերևի սահմանները, և դրանց վաղ ճանաչումը խնայում է վստահված սերվերի վրիպազերծման մի կեսօր։ Աղյուսակը կապում է այն, ինչ տեսնում եք, այն բանի հետ, ինչ այն սովորաբար նշանակում է։ Վերջին սյունակում ամեն ինչ ձևավորման հարց է, ոչ թե կարգավորման սխալ։

What you seeWhat it usually meansWhere to look
The app connects and nothing followsIt ignores proxy settings entirelyIts own network settings, not the SSH session
A name resolution error for the destinationThe SSH server cannot resolve itServer resolver and search domains
A UDP-only application failsDynamic forwarding carries TCP onlyThis arrangement cannot serve it
curl works, the browser does notThe browser is not using the socks5h endpointBrowser proxy configuration
The listener answers after the session endedAnother process owns port 1080The ss output, then the owning process

Առաջին երեք տողերն այն են, ինչ մարդիկ սխալ են ախտորոշում, քանի որ յուրաքանչյուրը ստեղծում է միացման փորձ, այլ ոչ թե սխալ հենց վստահված սերվերի մասին։ Անունը, որը լուծվում է դյուրակիրում, ոչինչ չի ասում սերվերի լուծիչի մասին, և ձախողումը կարդացվում է փոխարենը որպես վկայագրի կամ ժամկետի խնդիր։ Միայն UDP-ով աշխատող ծրագրերը կանգնած են ձևավորումից դուրս, ոչ թե դրա ներսում կոտրված, և ոչ մի լրացուցիչ ssh ընտրանք դա չի փոխում։ Դիտարկիչի տողը սովորական հիշեցումն է, որ վստահված սերվերի կարգավորումները յուրաքանչյուր ծրագրի համար են։ Վերջին տողը փակման ստուգման գոյության պատճառն է՝ պորտը, որը դեռ լսում է, նշանակում է, որ հիմա այն պատկանում է ուրիշ բանի։

Առնչվող հոդվածներ