SSH Tunneling (SSH Port Forwarding)

Wai Yan SoeWai Yan Soe
4 min read

Burmese Bytes က ပြန်လည်ကြိုဆိုလိုက်ပါတယ် စာလည်းမရေးဖြစ်တာကြာပြီဆိုတော့ ဒီနေ့မှာ တော့ SSH Tunneling အကြောင်းလေး အတတ်နိုင်ဆုံး လိုရင်း တိုရှင်းလေး ပြောပြပေးပါမယ်။ ဒီ Post ကတော့ Lab အသေးစိပ်တော့ပါမှာမဟုတ်ပါဘူး။ အဆင်မပြေတာရှိရင် Burmese Bytes Facebook Page Messenger ကနေ လာပြောနိုင်ပါတယ်ဗျ။

SSH Tunneling (SSH Port Forwarding) ဆိုတာကတော့ မှတ်ရလွယ်အောင်ပြောရရင်တော့ SSH Connection ထဲကနေတဆင့် local or remote server တွေရဲ့ service port တွေကို tunnel တစ်ခုလိုမျိုး Forward လုပ်ပေးတာလို့ မှတ်သားနိုင်ပါတယ်။ SSH Tunneling (SSH Port Forwarding) မှာ သုံးမျိုးတွေ့နိုင်ပါတယ်။

  1. Local Port Forwarding

  2. Remote Port Forwarding

  3. Dynamic Port Forwarding (SOCKS proxy)

1. Local Port Forwarding

Remote Server မှာရှိတဲ့ Service Port တွေကို SSH Connection ကနေတဆင့် Local Machine ဆီကို Forward လုပ်ပေးတာလို့ပြောရမယ်ဗျ။

Example Scenario

ပုံအရဆိုရင်ကျွန်တော်တို့မှာ Private Network တစ်ခုရှိတယ် ဆိုကြပါစို့။ အဲ့ထဲမှာ Internal Services တွေရှိမယ်။ Public ကနေ SSH Server (Jump host) ဆီကို လာတဲ့ inbound SSH (Default Port Number 22) တစ်ခုပဲ allowed ဖြစ်မယ် ဆိုပါတော့။ ကျန်တာအားလုံး all deny ပေါ့။ ဒီလိုအခြေအနေမျိုးမှာ တခြားသော Service တွေကို Public Internet ပေါ်ကနေ temporary access လုပ်ဖို့လိုလာပြီဆိုရင် ဘယ်လိုလုပ်မလဲ ?

ဒါဆိုရင်တော့ Option တစ်ခုအနေနဲ့ SSH ရဲ့ Local Port Forwarding ကိုအသုံးပြုလို့ရပါတယ်။ ကျွန်တော်တို့ Laptop ကတော့ SSH Server (Jump host) ကို SSH access ရနေဖို့တော့လိုပါမယ်။ SSH Server (Jump host) ကလည်း ကျွန်တော်တို့ Forward လုပ်မယ့် Remote Server or Internal Service တွေဆီကို Access ရနေဖို့လိုပါမယ်။ ဒါမှသာ Forward လုပ်လို့ရမှာပါ။

ssh -L [local_port]:[remote_host]:[remote_port] [user]@[ssh_server]

စာရှည်သွားမှာစိုးလို့ တစ်ခုချင်းအောက်မှာ အတိုချုပ် ချရေးထားပါတယ်။

local_port  = local_machine_port (localhost:3000) | your_laptop:port 
remote_host = internal_server 
remote_port = internal_server_port (internal_server:8080) | internal_service_address
user        = ssh_user
ssh_server  = jump_host (ssh)

လိုအပ်တာတွေကို ပြင်ပြီး ဒီတိုင်း Run လို့ရပါတယ်။

ssh -L 3000:internal_server:8080 ssh_user@ssh_server

ဒီတိုင်းလေးသာ Run လိုက်မယ်ဆိုရင်
Private Network ထဲမှာရှိတဲ့ internal_server ရဲ့ port number 8080 (Internal Service) လေးဟာ SSH Tunnel ပေါ်ကနေအဆင့် ကျွန်တော်တို့ laptop - local machine ရဲ့ Port Number 3000 (localhost:3000) မှာ LISTEN ဖြစ်နေပါပြီ။ web service ဆိုရင်တော့ browser ကနေခေါ်ကြည့်နိုင်ပါပြီ။

Command Run တဲ့အခါ SSH Shell ထဲ ကို မဝင်သွားချင်ရင်တော့ -N ဆိုတဲ့ Option လေးကို ထည့်သုံးလို့ရပါတယ်။

SSH Config ကိုလည်းသုံးနိုင်ပါတယ်။ ~/.ssh/config

#example ssh config
Host jump_host
    Hostname ssh_server_address
    User ssh_user
#   Port ssh_port
#   IdentityFile <ssh_key_location>
#   Compression yes
    LocalForward 3000 internal_server_1:8080
    LocalForward 3001 internal_server_2:9090

ssh jump_host or ssh jump_host & ဆိုပြီး run လိုက်တာနဲ့ရပါပြီ။ Command နောက်ဆုံးမှာ & လေးကိုသုံးပြီး Background jobs အနေနဲ့လည်း Run လို့လည်းရပါသေးတယ်။

2. Remote Port Forwarding

Localhost က service port တွေကို SSH Server / remote host ဆီကို forward လုပ်ပေးတာဖြစ်ပါတယ်။ Reverse SSH Tunneling လိုလည်း ခေါ်ကြပါသေးတယ်။

Example Scenario

ဥပမာတစ်ခုအနေနဲ့ပြောရရင် Applications Project တစ်ခုကို Location တစ်နေရာဆီရောက်ကြတဲ့ Developers တွေက Develop ကြတယ်ဆိုကြပါတော့ဗျာ။ တစ်ယောက်နဲ့ တစ်ယောက် Service Address တွေ share သုံးဖို့လိုတဲ့ အခါမှာ Internet ပေါ်ကနေ Local စက်ရဲ့ service address or port number တွေကို တစ်ယောက်နဲ့တစ်ယောက်ဘယ်လို Share ကြမလဲ ? တခြားသော Public မှာရှိနေတဲ့ service တွေကနေ မိမိစက်ရဲ့ service address port တစ်ခုခုကို access လုပ်ဖို့လိုတဲ့အခါကြရင်ရောဘယ်လိုလုပ်ကြမလဲ?

တခြား သော NgrokVSCode Port forwarding တို့ကိုသုံးလို့ရသလို SSH ရဲ့ Remote Port Forwarding ကိုအသုံးပြုလို့ရပါတယ်။ Public SSH Server တစ်ခု ရှိဖို့တော့လိုပါမယ်။ Localhost ကနေ Public SSH Server ဆီကို SSH Access ရထားဖို့လည်းလိုပါမယ်။

ssh -R [remote_port]:[local_host]:[local_port] [user]@[ssh_server]

စာရှည်သွားမှာစိုးလို့ တစ်ခုချင်းအောက် မှာ အတိုချုပ် ချရေးထားပါတယ်။

local_host  = localhost | your_laptop
local_port  = your_laptop_port | (localhost:3000)
user        = ssh_user
ssh_server  = public_ssh_server
remote_port = public_ssh_server_port

လိုအပ်တာတွေကို ပြင်ပြီး ဒီတိုင်း Run လို့ရပါတယ်။

ssh -R 8080:localhost:3000 ssh_user@public_ssh_server

ဒီတိုင်း Run လိုက်တဲ့အခါမှာတော့ Public SSH Server ထဲ ဝင်ကြည့်မယ်ဆိုရင် ပုံအရဆို Dev 1 Local Machine ရဲ့ port number 3000 မှာ Run နေတဲ့ Service လေးက Public SSH Server ရဲ့ localhost 127.0.0.1:8080 မှာ LISTEN ဖြစ်နေတာကို တွေရပါလိမ့်မယ်။ Public SSH Server ထဲမှာ netstat -ant နဲ့စစ်ကြည့်လို့ရပါတယ်။

ဒါကို Public က access လုပ်ဖို့အတွက် /etc/ssh/sshd_config ထဲမှာပြင်ပေးဖို့တော့လို့ပါမယ်။ #GatewayPorts no ဆိုတာကို ရှာလိုက်ပြီးတော့ Comment ပိတ်ထားတာကိုဖွင့်လိုက်ပြီး no ကို yes ပြောင်းပြီး SSH service ကို restart ချလိုက်ပါ။ ပြီးရင်တော့ tunnel ကို ပြန် စ လိုက်ပါ။

sshd_config ထဲမှာ GatewayPorts ကို yes လို့ပေးလိုက်တာနဲ့ host မှာရှိတဲ့ network card အားလုံးနဲ့ bind သွားတာဖြစ်လို့ netstat -ant နဲ့စစ်ကြည့်တဲ့အခါ 0.0.0.0:8080 ဆိုပြီးတွေ့ရပါလိမ့်မယ်။ Public ကနေပြီးလည်း access ရပါပြီ။

ပုံအရဆို Dev 2 ရဲ့ laptop ကတော့ public_ssh_server_address:8080 ကို ခေါ်ကြည့်လို့ရပါပြီ Dev 1 စက် localhost:3000 မှာ run နေတဲ့ service လေးကိုတွေ့ရပါလိမ့်မယ်။ (http service ဆိုရင် Gateway port မပြင်ပဲ nginx ကို သုံးပြီး forward ထပ်လုပ်လည်းရပါတယ်။)

8080:localhost:3000 ဆိုတဲ့နေရာမှာ ပုံအရဆို dev3 laptop မှာ ရှိနေတဲ့ service တွေကိုပါ SSH Tunnel ပေါ်ကနေ forward ထပ်လုပ် ပေးလို့ရပါသေးတယ်။ dev 1 laptop ကနေတော့ dev 3 ရဲ့ service တွေကို access ရေနေဖို့လိုပါမယ်။
example - ssh -R 9090:dev3_laptop:5000 ssh_user@public_ssh_server

Command Run တဲ့အခါ SSH Shell ထဲ ကို မဝင်သွားချင်ရင်တော့ -N ဆိုတဲ့ Option လေးကို ထည့်သုံးလို့ရပါတယ်။

SSH Config ကိုလည်းသုံးနိုင်ပါတယ်။ ~/.ssh/config

Host public_ssh
    Hostname ssh_server_address
    User ssh_user
#   Port ssh_port
#   IdentityFile <ssh_key_location>
#   Compression yes
    RemoteForward 8080 localhost:3000
    RemoteForward 9090 dev3_laptop:5000

ssh public_ssh or ssh public_ssh & ဆိုပြီး run လိုက်တာနဲ့ရပါပြီ။ Command နောက်ဆုံးမှာ & လေးကိုသုံးပြီး Background jobs အနေနဲ့လည်း Run လို့ရပါပြီ။

3. Dynamic Port Forwarding (SOCKS proxy)

ဒီတစ်ခုကတော့ အပေါ်ကနှစ်ခုနဲ့ နည်းနည်းကွာခြားပါတယ်။ သူက tunnel စလိုက်တာနဲ့ Local မှာ ရှိတဲ့ traffic တွေအားလုံး SSH Tunnel ထဲကနေ forward သွားပါတယ် Proxy တစ်ခုလိုအလုပ်လုပ်ပါတယ်။ အပေါ်ကနှစ်ခုကတော့ specific port တွေကိုပဲ forward လုပ်ပါတယ်။

Example Scenario

ဥပမာ Network ထဲမှာ ပိတ်ထားတဲ့ ဝင်ရောက်ခွင့် မပြုထားတဲ့ website တွေကို SSH Tunnel ပေါ်ကနေတဆင့် ကျော်ကြည့်ချင်တဲ့အခါသုံးလို့ရပါတယ်။

ssh -D [local_port] [user]@[ssh_server]
ssh -D 9090 user@ssh_server

ဒီတိုင်း Run လိုက်တဲ့အခါမှာ Localhost ရဲ့ Port Number 9090 မှာ Proxy address တစ်ခု အနေ့နဲ့ Run ပါတယ်။

Command Run တဲ့အခါ SSH Shell ထဲ ကို မဝင်သွားချင်ရင်တော့ -N ဆိုတဲ့ Option လေးကို ထည့်သုံးလို့ရပါတယ်။

SSH Config ကိုလ ည်းသုံးနိုင်ပါတယ်။ ~/.ssh/config

Host ssh_proxy
    Hostname ssh_server_address
    User ssh_user
#   Port ssh_port
#   IdentityFile <ssh_key_location>
#   Compression yes
    DynamicForward 9090

ssh ssh_proxy or ssh ssh_proxy & ဆိုပြီး run လိုက်တာနဲ့ရပါပြီ။ Command နောက်ဆုံးမှာ & လေးကိုသုံးပြီး Background jobs အနေနဲ့လည်း Run လို့ရပါပြီ။

အောက်မှာပြထားတဲ့အတိုင်း Proxy Settings လေးတွေချိန်းပြီး Block ထားတဲ့ site တွေကို SSH Tunnel ပေါ်ကနေတဆင့် access လုပ်လို့ရသွားပါလိမ့်မယ်။

Linux Gnome proxy settings

Windows Proxy Settings


⚠️သတိထားသင့်သည့်အချက်များ ... ။

  • ဒီ post ကတော့ education purpose အတွက်ပဲ knowledge sharing လုပ်တာမလို့ Personal use case အတွက်ပဲသုံးစေချင်ပါတယ်။

  • Productions မှာ မသုံးတာတော့အကောင်းဆုံးပါပဲ သုံးဖို့လိုအပ်လာတဲ့ အခါမှာလည်း ကိုယ်ရောက်နေတဲ့ Origination ရဲ့ proper approval တွေနဲ့ သွားသင့်ပါတယ်။

  • Origination တွေဘက်ကလည်း ဒီလို သာမာန်မဟုတ်တဲ့ Connection တွေနဲ့ Data တွေကို ခိုးယူထုတ်လို့ရနိုင်တာမလို့ သတိထားပြီး ကြိုတင်ကာကွယ်ဖို့ Planning ရှိသင့်ပါတယ်။


Example Scenarios တွေနဲ့ပြောပြထားပေမယ့် အခြေအနေ အမျိုးမျိုးမှာ ပုံစံအမျိုးမျိုးနဲ့အသုံးပြုလို့ရနိုင်ပါတယ်။

SSH Tunneling (SSH Port Forwarding) အကြောင်း အသေးစိပ်ထပ်သိချင်ရင်တော့ အောက်က လင့်တွေမှာ ဆက်လေ့လာနိုင်ပါတယ်။

အထောက်အကူတစ်ခုမဟုတ်တောင် Knowledge လေးတစ်ခုတော့တိုးသွားမယ်လို့မျှော်လင့်ပါတယ်။ နောက်ထပ် Articles တွေမှာ ပြန်လည်တွေ့ပါမယ်။ 😊

2
Subscribe to my newsletter

Read articles from Wai Yan Soe directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Wai Yan Soe
Wai Yan Soe