- 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 टिप्पणियां
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:80remote के port 80 को local 8080 पर forward करता है, औरRemoteForward 0.0.0.0:9022 0.0.0.0:22remote 9022 पर आने वाली SSH request को local port 22 पर forward करता हैLocalForwardऔरRemoteForwardमें बाईं तरफ target server होता है, दाईं तरफ local, औरlocalhostया127.0.0.1के बजाय0.0.0.0इस्तेमाल करने की tip भी हैssh_configtip शेयर करूं तो, घर के अंदर या 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 करें
थोड़े समय के लिए 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 बेहतर लगते हैं
single user/multiple machines के लिए, और अलग server हमेशा चालू रखने की जरूरत बिना GitHub जैसी जगह से settings खींचने वाला GitOps जैसा solution ढूंढ रहा हूं
bash/fishfunctions बना रखे हैं ताकि बस न्यूनतम arguments याद रखने पड़ेंभूल जाऊं तो documented function definitions देख लेता हूं
मेरे काम की बेहूदा enterprise environment में SSH tunneling जरूरी है
access permission लेने, port खोलने या firewall/VPN exception पाने में bureaucracy की वजह से कई हफ्ते लग सकते हैं
यह article
-Dका जिक्र करता है, लेकिन इसकी ताकत को पर्याप्त नहीं समझाताssh -D 8888 someserverचलाकर browser का SOCKS proxylocalhost:8888पर set कर दें, तो browser traffic पूराsomeserverके जरिए route होता हैFirefox में अब भी system default बदले बिना यह setting की जा सकती है, इसलिए यह बहुत उपयोगी है
लेकिन company में जाकर देखा तो IP allowlist की वजह से internet के किसी भी arbitrary server से SSH connection तक नहीं कर सकता था, और इतना परेशान हुआ कि HTTP tunnel बनाकर अपने control वाले server को allowlist में डालने का तरीका तक खोजने लगा, फिर आखिरकार नौकरी बदल ली
ऐसे 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 कहीं ज्यादा होने चाहिए
बेशक यह सिर्फ 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 काफी इस्तेमाल की है, लेकिन
-Joption के बारे में नहीं जानता थाहर कुछ महीनों में 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 के अलावा भी बहुत अलग-अलग कामों के लिए इसे लगातार इस्तेमाल कर रहा हूं
sshuttleआज़माएं तो tunneling काफी आसान हो जाती हैsshuttle -r user@host 10.0.0.0/8की तरह इस्तेमाल करने पर10/8range अपने-आप tunnel हो जाती है, और यह व्यावहारिक तौर पर SSH के ऊपर VPN जैसा काम करती हैजिज्ञासा है कि SSH में खुद कोई redirect feature है या नहीं
उदाहरण के लिए, अगर A, B पर SSH करना चाहे, तो B उसे C से connect करने को बताए, A transparently सीधे C से जुड़ जाए, और B उसके बाद core data path में न रहे—क्या ऐसा कोई feature है?
मेरा firewall/router DHCP option 67 ठीक से forward नहीं करता और हमेशा अपना ही address भेजता है, इसलिए जब उस port का PXE boot traffic router IP पर जाता है, तो उसे असली PXE boot server तक route करने के लिए virtual IP/rules set करने पड़े थे
वरना jump feature इस्तेमाल कर सकते हैं:
ssh -J B Cअगर B को path में रहने की जरूरत नहीं है और C से सीधे connect किया जा सकता है, तो बस C से सीधे connect करें; और अगर यह संभव नहीं है, तो वैसे भी B को hop के रूप में आना पड़ेगा
problem को और विस्तार से बताएं तो कोई ज्यादा उपयुक्त समाधान मिल सकता है
अगर host कुछ हद तक embedded हो, तो DNS को “routing” की जिम्मेदारी दी जा सकती है, लेकिन इस case में host key fingerprint verification खुद संभालना होगा