6 पॉइंट द्वारा GN⁺ 2024-09-20 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • SSH टनलिंग सुरक्षित SSH कनेक्शन के ऊपर TCP ट्रैफिक ले जाती है, और legacy protocols को encrypt करने, admin panels तक पहुंचने, और NAT के पीछे servers से कनेक्ट करने जैसे सीमित रास्तों को सुरक्षित रूप से खोलने के लिए इस्तेमाल होती है
  • Server-side पर AllowTcpForwarding yes जरूरी है, और loopback के अलावा किसी interface पर port खोलने के लिए GatewayPorts yes सेटिंग और SSH server restart जरूरी है
  • ssh -J, ssh -L, ssh -R, ssh -D क्रमशः jump host, local forwarding, remote forwarding, और SOCKS5-based dynamic forwarding के लिए हैं
  • Tunnel को background में बनाए रखने के लिए ssh -fN का उपयोग करें, और disconnect detection को ClientAliveInterval और ClientAliveCountMax जैसी heartbeat settings से adjust करें
  • SSH टनलिंग UDP को सीधे support नहीं करती और TCP-over-TCP में latency और throughput समस्याएं हो सकती हैं, इसलिए यह VPN replacement से ज्यादा किसी specific TCP path को खोलने वाला tool है

SSH टनलिंग कब इस्तेमाल करें

  • SSH टनलिंग और port forwarding, SSH connection के जरिए TCP traffic को client से server तक, या server से client तक forward करते हैं
  • TCP ports और UNIX sockets इस्तेमाल किए जा सकते हैं, लेकिन examples TCP ports पर केंद्रित हैं
  • आम use cases security, troubleshooting, और connection bypass में बंटते हैं
    • Security
      • FTP जैसे unsafe connections या legacy protocols को encrypt करता है
      • Public-key authentication पर आधारित SSH tunnel से web admin panel तक access देता है
      • 80/443 जैसे अतिरिक्त ports expose किए बिना केवल port 22 खोल सकते हैं
    • Troubleshooting
      • Firewall या content filters को bypass करता है
      • दूसरा network path चुनता है
    • Connection
      • NAT के पीछे मौजूद server तक access करता है
      • Jump host के जरिए internet से internal server में प्रवेश करता है
      • Local port को internet पर expose करता है

Port forwarding से पहले जांचने वाली settings

  • Examples के options को environment के अनुसार मिलाकर configure किया जा सकता है
  • अगर bind_address specify नहीं किया गया है, तो default localhost है
  • Local और remote users को अपनी-अपनी machines पर ports खोलने की permission चाहिए
    • 0-1024 ports के लिए, अलग setting न हो तो root privileges जरूरी हैं
    • बाकी ports सामान्य user भी set कर सकता है
    • Client और network firewalls भी forwarding path के हिसाब से खुले होने चाहिए
  • SSH server पर port forwarding enabled होनी चाहिए
    • AllowTcpForwarding yes
    • अक्सर यह default रूप से enabled होता है, लेकिन server configuration जांचना जरूरी है
  • 127.0.0.1 के अलावा किसी interface पर port forward करने के लिए SSH server में GatewayPorts enable करें
    • GatewayPorts yes
    • Setting के बाद SSH server service को restart करना होगा

SSH jump host और multi-hop tunnel

  • ssh -J का इस्तेमाल एक या अधिक hosts के जरिए remote host से transparently connect करने के लिए किया जाता है
ssh -J user@REMOTE-MACHINE:22 -p 22 user@10.99.99.1
  • Default port 22 इस्तेमाल करते समय port notation छोड़ी जा सकती है
  • REMOTE-MACHINE को jump host के रूप में इस्तेमाल करने पर connection इस तरह दिखता है
[user@REMOTE-MACHINE]$ ss | grep -i ssh
tcp ESTAB 0 0 167.135.173.108:ssh 192.160.140.207:45960
tcp ESTAB 0 0 10.99.99.2:49770 10.99.99.1:ssh
  • Example addresses की भूमिकाएं इस प्रकार हैं
    • 167.135.173.108: REMOTE-MACHINE का public IP
    • 192.160.140.207: LOCAL-MACHINE का public IP
    • 10.99.99.2: REMOTE-MACHINE का internal IP
    • 10.99.99.1: REMOTE-WEBAPP का internal IP
  • कई jump hosts इस्तेमाल करते समय comma से अलग करें
ssh -J user@REMOTE-MACHINE:22,user@ANOTHER-REMOTE-MACHINE:22 -p 22 user@10.99.99.1

Local port forwarding

  • Local port forwarding में ssh -L option इस्तेमाल होता है
  • पहला example LOCAL-MACHINE के 10.10.10.1:8001 को REMOTE-MACHINE के localhost:8000 पर forward करता है
ssh -L 10.10.10.1:8001:localhost:8000 user@REMOTE-MACHINE
  • REMOTE-MACHINE पर केवल 127.0.0.1 से bind web server access log ऐसा दिखता है
127.0.0.1 - - [30/Dec/2022 18:05:15] "GET / HTTP/1.1" 200
  • यह request LOCAL-MACHINE से शुरू हुई थी
  • दूसरा example local 8001 को REMOTE-MACHINE के जरिए 10.99.99.1:8000 तक forward करता है
ssh -L 8001:10.99.99.1:8000 user@REMOTE-MACHINE
  • REMOTE-WEBAPP के web server access log में यह request REMOTE-MACHINE के internal IP से आई हुई दर्ज होती है
10.99.99.2 - - [30/Dec/2022 21:28:42] "GET / HTTP/1.1" 200

Remote port forwarding

  • Remote port forwarding में ssh -R option इस्तेमाल होता है
  • Example REMOTE-MACHINE के 8000 को local side के localhost:8001 या 10.10.10.2:8001 पर forward करता है
ssh -R 8000:localhost:8001 user@REMOTE-MACHINE
ssh -R 8000:10.10.10.2:8001 user@REMOTE-MACHINE
  • किसी specific remote interface 10.99.99.2:8000 पर listen करने के लिए भी configure किया जा सकता है
ssh -R 10.99.99.2:8000:10.10.10.2:8001 user@REMOTE-MACHINE
  • Loopback interface के अलावा कहीं listen करने के लिए SSH server पर GatewayPorts yes enabled होना चाहिए

Dynamic port forwarding और SOCKS5

  • कई ports forward करते समय SSH SOCKS protocol का इस्तेमाल करता है
  • SOCKS एक transparent proxy protocol है, और SSH इसका latest version SOCKS5 इस्तेमाल करता है
  • SOCKS5 server का default port RFC 1928 में defined 1080 है
  • Client को application layer या OS layer पर SOCKS proxy इस्तेमाल करने के लिए configure करना होगा
  • ssh -D example 10.10.10.1:5555 पर SOCKS proxy खोलता है
ssh -D 10.10.10.1:5555 user@REMOTE-MACHINE
  • LOCAL client पर curl से connection path test किया जा सकता है
curl -L -x socks5://10.10.10.1:5555 brrl.net/ip
  • सही तरीके से काम करने पर REMOTE-MACHINE का public IP return होगा

SSH TUN/TAP टनलिंग

  • -w flag से bidirectional tunnel बनाया जा सकता है
  • Interface पहले से create होना चाहिए
  • इस तरीके के बारे में caveat है कि इसे test नहीं किया गया है
-w local_tun[:remote_tun]

Background में run करना और बंद करना

  • Tunnel को native तरीके से background में run करने के लिए -fN इस्तेमाल करें
    • -f: background execution
    • -N: shell नहीं खोलता
ssh -fN -L 8001:127.0.0.1:8000 user@REMOTE-MACHINE
  • इसके अलावा screen या अन्य tools इस्तेमाल किए जा सकते हैं
  • Background में चल रहे SSH को process खोजकर PID से terminate करें
user@pleasejustwork:~$ ps -ef | grep ssh
[...]
user 19255 1 0 11:40 ? 00:00:00 ssh -fN -L 8001:127.0.0.1:8000 user@REMOTE-MACHINE
[...]
kill 19255

SSH connection बनाए रखना और reconnect करना

  • SSH connection बनाए रखने के कई तरीके हैं
  • Timeout handling के लिए heartbeat options client, server, या दोनों तरफ set किए जा सकते हैं
  • ClientAliveInterval connection बनाए रखने के लिए हर n seconds में request भेजता है
ClientAliveInterval 15
  • ClientAliveCountMax दूसरी तरफ से response न मिलने के बाद connection बंद करने से पहले भेजी जाने वाली heartbeat requests की संख्या है
ClientAliveCountMax 3
  • 3 default है, और 0 पर set करने से connection termination disable हो जाता है
  • Example setting में response न आने पर लगभग 45 seconds बाद connection कट जाएगा
  • Connection बंद होने के बाद reconnect के लिए autossh, scripts, cronjob आदि इस्तेमाल किए जा सकते हैं

सीमाएं और security caveats

  • UDP

    • SSH सही decryption के लिए reliable delivery पर depend करता है
    • UDP reliability नहीं देता, इसलिए SSH tunnel में supported नहीं है और recommended नहीं है
    • UDP over SSH tunneling पर एक method है, लेकिन caveat है कि इसे test नहीं किया गया है
  • TCP-over-TCP

    • Overhead के कारण throughput कम होता है और latency बढ़ती है
    • Packet loss या high latency वाले connections में TCP meltdown हो सकता है
    • TCP over TCP पर लेख देखा जा सकता है
    • कुछ समय तक OpenVPN-over-TCP इस्तेमाल करने पर throughput UDP से कम था, लेकिन यह stable चला, और results configuration पर काफी depend करते हैं
  • VPN replacement के रूप में इस्तेमाल की सीमाएं

    • SSH टनलिंग को VPN की तरह इस्तेमाल किया जा सकता है, लेकिन बेहतर performance के लिए VPN ज्यादा suitable है
  • Security risks

    • अगर इस feature की जरूरत नहीं है तो इसे disable करने की सलाह दी जाती है
    • Attackers SSH टनलिंग और port forwarding का इस्तेमाल कर firewalls और अन्य security measures से बच सकते हैं
  • Reference docs

1 टिप्पणियां

 
GN⁺ 2024-09-20
Hacker News की राय
  • 2024 में SSH command को लंबा-चौड़ा सीधे लिखने के बजाय ~/.ssh/config में LocalForward, RemoteForward, ProxyJump सेट करना बेहतर है
    ऐसे remote server तक ssh, scp, rsync से पहुंचते समय, जहां बीच में कई SSH connections से होकर जाना पड़ता है, यह काफी समय बचाता है
    उदाहरण के लिए jump-host-1, jump-host-2, jump-host-3 को ProxyJump से जोड़ दें और target-server से alias के जरिए connect करें
    LocalForward 0.0.0.0:8080 0.0.0.0:80 remote के port 80 को local 8080 पर forward करता है, और RemoteForward 0.0.0.0:9022 0.0.0.0:22 remote 9022 पर आने वाली SSH request को local port 22 पर forward करता है
    LocalForward और RemoteForward में बाईं तरफ target server होता है, दाईं तरफ local, और localhost या 127.0.0.1 के बजाय 0.0.0.0 इस्तेमाल करने की tip भी है

    • ssh_config tip शेयर करूं तो, घर के अंदर या self-hosted VPN के अंदर हर device पर direct SSH करने और बाहर से jump host के जरिए जाने के लिए automatic branching वाली configuration उपयोगी है
      Match host *.example.org exec "getent ahosts router.example.org | grep -q ^10.0.0.1" की तरह router address से पहले यह detect किया जा सकता है कि आप घर/VPN पर हैं या नहीं, और arp से MAC address expected value से अलग हो तो ProxyJump jump.example.org इस्तेमाल कराया जा सकता है
      order महत्वपूर्ण है: पहले VPN/घर के network का detection करें, फिर बाहरी स्थिति में jump host apply करें
    • कभी-कभी काम सिर्फ एक बार का होता है और config file तक बनाना नहीं चाहते
      थोड़े समय के लिए VPS बनाकर SSH को SOCKS proxy की तरह इस्तेमाल करते हुए regional restrictions bypass करनी हों, या किसी दूसरी team की थोड़ी मदद के लिए ऐसे server में एक बार जाना हो जहां आम तौर पर access नहीं करते, तो command-line options बेहतर लगते हैं
    • 0.0.0.0 इस्तेमाल करना risky हो सकता है
      यह सभी network interfaces पर port खोल सकता है, और खासकर remote server पर firewall न हो तो आप कुछ चीज इंटरनेट पर सभी के लिए expose कर देंगे
      अक्सर इस्तेमाल होने वाली tunneling या port forwarding के लिए config file अच्छी है, लेकिन one-off या rare tasks के लिए command-line options बेहतर लगते हैं
    • ऐसी SSH settings को कई local machines पर standardize करके deploy करना हो तो लोग इसे कैसे manage करते हैं, यह जानने की उत्सुकता है
      single user/multiple machines के लिए, और अलग server हमेशा चालू रखने की जरूरत बिना GitHub जैसी जगह से settings खींचने वाला GitOps जैसा solution ढूंढ रहा हूं
    • हमेशा shell खुलना जरूरी नहीं होता, इसलिए basic bash/fish functions बना रखे हैं ताकि बस न्यूनतम arguments याद रखने पड़ें
      भूल जाऊं तो documented function definitions देख लेता हूं
  • मेरे काम की बेहूदा enterprise environment में SSH tunneling जरूरी है
    access permission लेने, port खोलने या firewall/VPN exception पाने में bureaucracy की वजह से कई हफ्ते लग सकते हैं
    यह article -D का जिक्र करता है, लेकिन इसकी ताकत को पर्याप्त नहीं समझाता
    ssh -D 8888 someserver चलाकर browser का SOCKS proxy localhost:8888 पर set कर दें, तो browser traffic पूरा someserver के जरिए route होता है
    Firefox में अब भी system default बदले बिना यह setting की जा सकती है, इसलिए यह बहुत उपयोगी है

    • 2000 के दशक के मध्य में, घर के बाहर web browse करते समय यह लगभग standard तरीका था
      लेकिन company में जाकर देखा तो IP allowlist की वजह से internet के किसी भी arbitrary server से SSH connection तक नहीं कर सकता था, और इतना परेशान हुआ कि HTTP tunnel बनाकर अपने control वाले server को allowlist में डालने का तरीका तक खोजने लगा, फिर आखिरकार नौकरी बदल ली
    • corporate network को bypass करना अच्छा विचार नहीं है
      ऐसे restrictions की वजह होती है, और bypass करना organization की प्रक्रियाओं और security expertise की कमी/अनदेखी जैसा दिख सकता है
      अगर access permission मिलने में हफ्ते या महीने लगते हैं, तो उतना इंतजार करना चाहिए; आप confidential information में backdoor खोलने या security कमजोर करने की जिम्मेदारी नहीं लेना चाहेंगे
  • सुबह 3 बजे किया गया मेरा सबसे messy SSH tunneling hack तीन datacenters को जोड़ने का काम था
    एक ही metro area में मौजूद तीन facilities internet backbone से connected थीं, लेकिन अजीब routing policy के कारण A केवल B से, और केवल B ही C से connect कर सकता था
    आखिरकार A का data B के जरिए C तक ले जाने के लिए rsync + SSH tunnel + keys + routing tricks को मिलाना पड़ा, और spell जैसी commands को कुछ बार ठीक करने के बाद जब सब कुछ एक साथ चल पड़ा तो जादू जैसा लगा
    आज देखें तो कैसे करना है यह बहुत स्पष्ट है, लेकिन उस समय beginner होने के नाते यह बड़ी उपलब्धि थी, और synchronization पूरा होने की पुष्टि करते समय जो thrill था वह अब भी याद है

    • ~/.ssh/config और ProxyJump इस्तेमाल करें तो A, B, C, D, E जैसे कितने भी stages में practically jump करके जा सकते हैं
  • visualization की details अच्छी हैं
    networking में, खासकर lower-level connections पर traffic को visually represent करने वाले tools कहीं ज्यादा होने चाहिए

    • यहां का diagram भी देखने लायक है: https://www.nathanhandy.blog/articles/osi-model-revisited.ht...
      बेशक यह सिर्फ static conceptual representation है, और ज्यादातर network vendors भी किसी न किसी तरह की traffic visualization देते हैं, लेकिन आमतौर पर वह individual metrics या graphs के स्तर तक सीमित रहती है
  • अगर Linux server या IoT device firewall के पीछे है और fixed IP भी नहीं है, लेकिन SSH से connect करना चाहते हैं, तो https://sshreach.me जैसी tunneling service इस्तेमाल कर सकते हैं

  • कई सालों से tunneling काफी इस्तेमाल की है, लेकिन -J option के बारे में नहीं जानता था
    हर कुछ महीनों में tunnel की जरूरत पड़ने पर 30 मिनट configuration में लगाने के बजाय, कोई visual tool होता जो tunnel configure कर दे, तो अच्छा होता

  • बताया गया है कि TCP-over-TCP overhead बढ़ाकर throughput घटाता है और latency बढ़ाता है, और packet loss या satellite network जैसी high-latency connections में TCP meltdown पैदा कर सकता है
    लेकिन SSH tunnel में, जब तक TAP/TUN का उपयोग नहीं किया जाता, असल में यह समस्या नहीं बनती
    क्योंकि SSH TCP stream को खोलकर आगे भेजता है
    हालांकि कई channels इस्तेमाल करते समय head-of-line blocking की वजह से performance घट सकती है

  • करीब 15 साल पहले university network के firewall को bypass करने के लिए SSH tunnel सीखा था, और default port को बदलकर 443 करना पड़ा था
    उसके बाद से firewall bypass के अलावा भी बहुत अलग-अलग कामों के लिए इसे लगातार इस्तेमाल कर रहा हूं

    • firewall bypass या local services को network के पार expose करने के अलावा किन कामों में आपको इससे फायदा/मज़ा मिला, यह जानने की जिज्ञासा है
  • sshuttle आज़माएं तो tunneling काफी आसान हो जाती है
    sshuttle -r user@host 10.0.0.0/8 की तरह इस्तेमाल करने पर 10/8 range अपने-आप tunnel हो जाती है, और यह व्यावहारिक तौर पर SSH के ऊपर VPN जैसा काम करती है

  • जिज्ञासा है कि SSH में खुद कोई redirect feature है या नहीं
    उदाहरण के लिए, अगर A, B पर SSH करना चाहे, तो B उसे C से connect करने को बताए, A transparently सीधे C से जुड़ जाए, और B उसके बाद core data path में न रहे—क्या ऐसा कोई feature है?

    • virtual IP से शायद कुछ वैसा किया जा सकता है
      मेरा firewall/router DHCP option 67 ठीक से forward नहीं करता और हमेशा अपना ही address भेजता है, इसलिए जब उस port का PXE boot traffic router IP पर जाता है, तो उसे असली PXE boot server तक route करने के लिए virtual IP/rules set करने पड़े थे
    • अगर A को यह पता न हो कि असली target C है, तो यह misleading हो सकता है
      वरना jump feature इस्तेमाल कर सकते हैं: ssh -J B C
      अगर B को path में रहने की जरूरत नहीं है और C से सीधे connect किया जा सकता है, तो बस C से सीधे connect करें; और अगर यह संभव नहीं है, तो वैसे भी B को hop के रूप में आना पड़ेगा
    • B, C की ओर port forwarding, यानी packet routing, कर सकता है, लेकिन HTTP के permanent redirect जैसा कोई equivalent feature शायद नहीं है
      problem को और विस्तार से बताएं तो कोई ज्यादा उपयुक्त समाधान मिल सकता है
      अगर host कुछ हद तक embedded हो, तो DNS को “routing” की जिम्मेदारी दी जा सकती है, लेकिन इस case में host key fingerprint verification खुद संभालना होगा