SSH Tunneling หรือ SSH Port Forwarding เป็นหนึ่งในเทคนิคด้านความปลอดภัยที่ทรงพลังที่สุดบน Linux VPS ช่วยให้คุณส่งข้อมูลผ่านช่องทางที่เข้ารหัสแล้ว เข้าถึง service ภายในที่ไม่ได้เปิด public port รวมถึงสร้าง SOCKS proxy ใช้ internet ผ่าน VPS ได้โดยไม่ต้องติดตั้ง software พิเศษ บทความนี้อธิบายทุกรูปแบบของ SSH Tunneling พร้อมคำสั่งจริงที่ใช้งานได้ทันที

SSH Tunneling คืออะไร และทำไมถึงสำคัญ

SSH (Secure Shell) ไม่ได้ใช้แค่สำหรับ remote login เท่านั้น แต่มีความสามารถ port forwarding ที่ช่วยให้การรับส่งข้อมูลผ่าน TCP port ใดๆ ถูกห่อหุ้มด้วยการเข้ารหัส SSH และส่งผ่าน secure channel ไปยัง VPS เทคนิคนี้เรียกว่า SSH Tunneling ประโยชน์หลักมีดังนี้

SSH Tunnel ทำงานโดยสร้าง encrypted channel ระหว่างเครื่องของคุณกับ VPS จากนั้น forward ข้อมูลระหว่าง local port และ destination port ผ่าน channel นั้น ทำให้ packet ที่ดักจับระหว่างทางอ่านไม่ออก

ประเภทของ SSH Port Forwarding

SSH มี Port Forwarding 3 รูปแบบหลัก แต่ละแบบมีจุดประสงค์ต่างกัน การเข้าใจความแตกต่างช่วยให้เลือกใช้ได้ถูกต้อง

ประเภท Flag ทิศทาง ใช้เมื่อ
Local Forwarding -L local → VPS → destination เข้า Database/Service บน VPS จาก local
Remote Forwarding -R VPS → local machine เปิด local service ให้ VPS เข้าถึง
Dynamic Forwarding -D local SOCKS5 proxy → VPS → internet ใช้ VPS เป็น proxy สำหรับ browser

Local Port Forwarding (-L) — เข้าถึง Service บน VPS

Local Port Forwarding ส่ง connection จาก port บน local machine ผ่าน SSH ไปยัง port บน VPS หรือเครื่องที่ VPS เข้าถึงได้ รูปแบบคำสั่งคือ

ssh -L [local_port]:[destination_host]:[destination_port] user@vps-ip

ตัวอย่างที่ใช้บ่อยที่สุดคือการเชื่อมต่อ MySQL บน VPS ที่ bind แค่ localhost (port 3306 ไม่ได้เปิด public)

# สร้าง tunnel จาก local port 13306 ไปยัง MySQL บน VPS
ssh -L 13306:localhost:3306 [email protected] -N

# จากนั้นเชื่อมต่อ MySQL ผ่าน local port ได้เลย
mysql -h 127.0.0.1 -P 13306 -u root -p

option -N บอก SSH ว่าไม่ต้องรัน command ใดๆ เพียงแค่สร้าง tunnel ไว้ ถ้าต้องการรัน background ให้เพิ่ม -f

# รัน tunnel เป็น background process
ssh -f -N -L 13306:localhost:3306 [email protected]

ตัวอย่างอื่นสำหรับ Redis และ PostgreSQL

# Tunnel ไปยัง Redis (port 6379)
ssh -L 16379:localhost:6379 [email protected] -N

# Tunnel ไปยัง PostgreSQL (port 5432)
ssh -L 15432:localhost:5432 [email protected] -N

# Tunnel ไปยัง phpMyAdmin บน VPS (สมมติรัน port 8080)
ssh -L 8888:localhost:8080 [email protected] -N
# เปิด browser ไปที่ http://localhost:8888

Local Forwarding ยังใช้เชื่อมต่อผ่าน VPS ไปยังเครื่องอื่นในเครือข่ายเดียวกันได้ด้วย

# เข้าถึงเครื่องในเครือข่าย private ของ VPS (เช่น 192.168.1.100)
ssh -L 8080:192.168.1.100:80 [email protected] -N

Remote Port Forwarding (-R) — เปิด Local Service ผ่าน VPS

Remote Port Forwarding ทำงานตรงข้ามกับ Local Forwarding โดยเปิด port บน VPS และ forward ไปยัง local machine ประโยชน์มากเมื่อต้องการให้คนอื่นเข้าถึง service บนเครื่อง local ของคุณที่ไม่มี public IP หรืออยู่หลัง NAT

ssh -R [vps_port]:[local_host]:[local_port] user@vps-ip

ตัวอย่างเปิด web server บน local ให้ผู้อื่นเข้าผ่าน VPS

# เปิด port 8080 บน VPS ชี้มาที่ local web server port 3000
ssh -R 8080:localhost:3000 [email protected] -N

# ผู้อื่นเข้า http://203.0.113.10:8080 จะเห็น local web server ของคุณ

การใช้งานต้องแก้ไข SSH config บน VPS ก่อนเพื่ออนุญาต GatewayPorts ไม่เช่นนั้น remote forwarding จะ bind เฉพาะ localhost ของ VPS เท่านั้น

# แก้ /etc/ssh/sshd_config บน VPS
GatewayPorts yes
# หรือถ้าต้องการ bind เฉพาะบาง IP
GatewayPorts clientspecified

# reload sshd
sudo systemctl reload sshd

กรณีต้องการ bind เฉพาะ interface บน VPS สามารถระบุได้ในคำสั่ง

# Bind เฉพาะ IP ใดๆ บน VPS
ssh -R 0.0.0.0:8080:localhost:3000 [email protected] -N

# Bind เฉพาะ localhost ของ VPS (default)
ssh -R 127.0.0.1:8080:localhost:3000 [email protected] -N

Dynamic Port Forwarding (-D) — SOCKS5 Proxy ผ่าน VPS

Dynamic Port Forwarding สร้าง SOCKS5 proxy บนเครื่อง local ที่ route traffic ทุกอย่างผ่าน VPS ต่างจาก Local Forwarding ที่กำหนด destination แค่อันเดียว Dynamic Forwarding รับ SOCKS protocol จาก application แล้ว proxy ไปยัง destination ใดๆ ที่ VPS เข้าถึงได้

# สร้าง SOCKS5 proxy บน local port 1080
ssh -D 1080 [email protected] -N

# รัน background
ssh -f -N -D 1080 [email protected]

หลังสร้าง tunnel แล้ว ตั้งค่า SOCKS5 proxy ใน application ที่ต้องการ

สำหรับ command line tools ทั้งระบบ ติดตั้ง proxychains และตั้งค่าใช้ SOCKS5

# ติดตั้ง proxychains
sudo apt install proxychains4

# แก้ /etc/proxychains4.conf
socks5 127.0.0.1 1080

# ใช้งาน
proxychains4 curl https://api.example.com
proxychains4 python3 myscript.py

เคล็ดลับ: เพิ่ม SSH options -o ServerAliveInterval=60 -o ServerAliveCountMax=3 ในทุกคำสั่ง tunnel เพื่อให้ SSH ส่ง keepalive packet ทุก 60 วินาที ป้องกัน tunnel หลุดเมื่อไม่มี traffic สักพัก โดยเฉพาะบน VPS ที่มี firewall ตัด idle connection โดยอัตโนมัติ

ตั้งค่า SSH Config File เพื่อใช้งาน Tunnel ได้สะดวก

การพิมพ์คำสั่ง ssh ยาวๆ ทุกครั้งไม่สะดวก สามารถบันทึกการตั้งค่าใน ~/.ssh/config เพื่อสร้าง shortcut ได้

# ~/.ssh/config

# Tunnel ไปยัง MySQL บน VPS
Host vps-mysql-tunnel
    HostName 203.0.113.10
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519
    LocalForward 13306 localhost:3306
    ServerAliveInterval 60
    ServerAliveCountMax 3

# SOCKS Proxy ผ่าน VPS
Host vps-socks
    HostName 203.0.113.10
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519
    DynamicForward 1080
    ServerAliveInterval 60

# Jump Host (Bastion)
Host internal-server
    HostName 192.168.1.50
    User ubuntu
    ProxyJump [email protected]
    IdentityFile ~/.ssh/id_ed25519

หลังตั้งค่าแล้วใช้งานได้ง่ายขึ้น

# เปิด MySQL tunnel
ssh -N vps-mysql-tunnel

# เปิด SOCKS proxy
ssh -N vps-socks

# เชื่อมต่อผ่าน jump host ตรงๆ
ssh internal-server

การใช้ autossh เพื่อ Tunnel ที่เสถียรและ Auto-Reconnect

autossh เป็น wrapper ของ SSH ที่คอย monitor connection และ reconnect โดยอัตโนมัติเมื่อ tunnel หลุด เหมาะมากสำหรับ tunnel ที่ต้องทำงานตลอดเวลา

# ติดตั้ง autossh
sudo apt update && sudo apt install autossh

# รัน tunnel ด้วย autossh
autossh -M 0 -o "ServerAliveInterval=30" -o "ServerAliveCountMax=3" \
    -N -L 13306:localhost:3306 [email protected]

-M 0 ปิด monitoring port ของ autossh เองและใช้ SSH ServerAlive แทน ซึ่งเสถียรกว่า

สร้าง systemd service สำหรับ Persistent Tunnel

# สร้างไฟล์ /etc/systemd/system/ssh-tunnel-mysql.service
[Unit]
Description=SSH Tunnel to VPS MySQL
After=network.target

[Service]
User=ubuntu
ExecStart=/usr/bin/autossh -M 0 \
    -o "ServerAliveInterval=30" \
    -o "ServerAliveCountMax=3" \
    -o "ExitOnForwardFailure=yes" \
    -N -L 13306:localhost:3306 \
    [email protected]
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
# เปิดใช้งานและเริ่ม service
sudo systemctl daemon-reload
sudo systemctl enable ssh-tunnel-mysql
sudo systemctl start ssh-tunnel-mysql

# ตรวจสอบสถานะ
sudo systemctl status ssh-tunnel-mysql

Service นี้จะเริ่มต้นอัตโนมัติเมื่อ boot และ restart ทันทีหาก tunnel หลุด ทำให้ database connection พร้อมใช้งานตลอดเวลาโดยไม่ต้องเปิด MySQL port สาธารณะ

Jump Host (Bastion Host) — เข้าถึงเซิร์ฟเวอร์ภายใน

Jump Host หรือ Bastion Host เป็นรูปแบบหนึ่งของ SSH Tunneling ที่ใช้ VPS เป็นจุดผ่านเพื่อเข้าถึงเซิร์ฟเวอร์ที่อยู่ใน private network ที่ไม่มี public IP สถาปัตยกรรมนี้ช่วยลดพื้นที่ถูกโจมตี (attack surface) เพราะเปิด SSH port แค่บน VPS เครื่องเดียว

# เชื่อมต่อผ่าน Jump Host แบบ one-liner
ssh -J [email protected] [email protected]

# หรือใช้ ProxyCommand (compatible กับ SSH เวอร์ชันเก่า)
ssh -o ProxyCommand="ssh -W %h:%p [email protected]" [email protected]

ใน SSH config file ตั้งค่าได้สะดวกกว่า

# ~/.ssh/config
Host bastion
    HostName 203.0.113.10
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519

Host db-server
    HostName 192.168.1.100
    User ubuntu
    ProxyJump bastion
    IdentityFile ~/.ssh/id_ed25519

Host app-server
    HostName 192.168.1.101
    User ubuntu
    ProxyJump bastion
    IdentityFile ~/.ssh/id_ed25519
# เชื่อมต่อตรงๆ ได้เลย — SSH จัดการ jump ให้อัตโนมัติ
ssh db-server
ssh app-server

ด้วย configuration นี้ ไม่ว่าจะมีเซิร์ฟเวอร์ภายในกี่เครื่อง ก็เข้าถึงได้ผ่าน bastion host เพียงจุดเดียว ทำให้การจัดการ security และ audit log ทำได้ง่ายกว่ามาก

การรักษาความปลอดภัยของ SSH Tunnel

แม้ SSH Tunnel จะเข้ารหัสแล้ว แต่การตั้งค่า SSH server ที่ไม่ดีก็เปิดช่องโหว่ได้ ควรปรับแต่งไฟล์ /etc/ssh/sshd_config บน VPS ดังนี้

# ปิด password authentication — ใช้ key เท่านั้น
PasswordAuthentication no
PubkeyAuthentication yes

# ปิด root login
PermitRootLogin no

# จำกัด user ที่ทำ forwarding ได้
AllowUsers ubuntu deploy

# ปิด X11 Forwarding ถ้าไม่ใช้
X11Forwarding no

# จำกัด TCP Forwarding เฉพาะ user ที่ต้องการ
# (ถ้าต้องการปิดสำหรับ user ทั่วไปทั้งหมด แล้วเปิดเฉพาะบาง user)
# ใช้ Match User directive
Match User ubuntu
    AllowTcpForwarding yes
    GatewayPorts no

สำหรับ VPS ที่ใช้เป็น jump host อย่างเดียว โดยไม่ต้องการให้ user รัน command ปกติได้

# บังคับให้ user ทำได้แค่ tunneling
Match User tunnel-user
    ForceCommand /bin/false
    AllowTcpForwarding yes
    X11Forwarding no
    PermitTTY no

นอกจากนี้ควรตั้งค่า firewall ให้รับ SSH เฉพาะจาก IP ที่อนุญาต และใช้ Fail2Ban ป้องกัน brute force

# UFW — อนุญาต SSH เฉพาะจาก IP ที่กำหนด
sudo ufw allow from 49.0.128.0/17 to any port 22
sudo ufw deny 22

# หรือเปลี่ยน SSH port เพื่อหลีกเลี่ยง bot scan
Port 2222
# อัพเดต UFW ด้วย
sudo ufw allow 2222/tcp

คำถามที่พบบ่อย (FAQ)

SSH Tunneling กับ VPN ต่างกันอย่างไร

SSH Tunneling เข้ารหัสการส่งข้อมูลเฉพาะ port หรือ application ที่กำหนด เหมาะกับการใช้งานเป็นครั้งคราวโดยไม่ต้องติดตั้ง software เพิ่มเติม ส่วน VPN เข้ารหัส traffic ทุกอย่างจากเครื่อง ทำให้ทุก connection ผ่าน server กลาง SSH Tunneling ใช้งานง่ายกว่า ตั้งค่าได้เลยหาก VPS มี SSH อยู่แล้ว แต่ VPN เหมาะกับการใช้ทั้งระบบ

Dynamic Port Forwarding คืออะไร และต่างจาก Local Forwarding อย่างไร

Dynamic Port Forwarding สร้าง SOCKS5 proxy บนเครื่อง local ที่ route traffic ผ่าน SSH ไปยัง VPS ได้หลาย destination พร้อมกัน ต่างจาก Local Forwarding ที่กำหนด destination เพียงอันเดียว (host:port) Dynamic Forwarding เหมาะกับ browser หรือ application ที่ต้องการ proxy โดยใช้คำสั่ง ssh -D 1080 user@vps-ip แล้วตั้ง SOCKS5 proxy ที่ localhost:1080 ใน application นั้น

จะทำให้ SSH Tunnel ทำงานอัตโนมัติเมื่อเปิดเครื่องได้อย่างไร

ใช้ autossh ร่วมกับ systemd service บน Linux โดยสร้างไฟล์ /etc/systemd/system/ssh-tunnel.service แล้วระบุ ExecStart=/usr/bin/autossh -M 0 -o ServerAliveInterval=30 -N -L 3306:localhost:3306 user@vps-ip จากนั้นรัน systemctl enable ssh-tunnel และ systemctl start ssh-tunnel เพื่อให้ tunnel เริ่มต้นอัตโนมัติและ reconnect เองเมื่อขาดการเชื่อมต่อ

SSH Tunnel ปลอดภัยพอสำหรับส่งข้อมูลสำคัญหรือไม่

SSH Tunnel ใช้การเข้ารหัส AES-256 และ authentication ด้วย key-based ซึ่งถือว่าปลอดภัยสูงมากสำหรับการส่งข้อมูล ข้อควรระวังคือต้องปิด Password Authentication และใช้ SSH Key เท่านั้น ตั้ง AllowTcpForwarding yes ในไฟล์ที่ต้องการ และจำกัด IP ที่เข้าถึงได้ด้วย AllowUsers หรือ firewall เพื่อป้องกันการใช้งานโดยไม่ได้รับอนุญาต

VPS KVM ประสิทธิภาพสูงของ AsiaGB

AsiaGB VPS Root Access เต็มรูปแบบ Docker MySQL Python Node.js เริ่มต้น 500 บาท/เดือน

ดูแพ็กเกจ VPS