บันทึกชีวิตที่สะดวกสบายขึ้นด้วย VS Code Remote SSH

ทำความรู้จักกับ VS Code Remote SSH ที่ช่วยชีวิตสะดวกขึ้นมากๆ โดยทดลองเชื่อมต่อกับ Azure VM Linux เพื่อเข้าไปลองสร้าง PostgreSQL ด้วย Docker Compose ครับ

Ponggun
T. T. Software Solution
8 min readOct 13, 2023

--

สวัสดีผู้อ่านทุกท่านนะครับ ช่วงท่ีผ่านมา ผมมีโอกาสต้อง Setup Azure VM Linux แล้วเริ่มอยากหาประสบการณ์คล้ายๆกับการที่เรา Remote เข้าไปที่ Server สักเครื่องแล้วสามารถจัดการไฟล์ต่างๆได้อย่างสะดวก โดยเฉพาะการอ่านและการแก้ไขไฟล์ครับ

สมัยก่อนผมจะต้องเปิด Terminal รัน SSH เพื่อเข้าถึง Server และจัดการทุกสิ่งอย่างผ่าน Command-line ครับ ซึ่งผมต้องสารภาพว่าโดยส่วนตัวแล้วผมไม่ถนัดการทำงานในลักษณะนี้เลยเพราะผมเป็นคนจำพวกคำสั่งต่างๆไม่ค่อยได้ครับ ถ้ายิ่งเป็นการแก้ไขไฟล์ยิ่งยากเข้าไปใหญ่เลยสำหรับผม

ลองดูภาพตัวอย่างการใช้โปรแกรม MobaXterm ใน Windows เพื่อ SSH เข้าไปจัดการ Server นะครับ ถึงแม้จะมี UI ช่วยในการแสดงผลไฟล์ แต่เวลาต้องแก้ไขก็ต้อง Download ลงมาที่เครื่องเพื่อแก้ไขและ Upload กลับเข้าไป ทำให้ทำงานค่อนข้างลำบากครับ

หลังจากนั้นผมได้มีโอกาสมาลองติดตั้ง WSL2 บน Windows แล้วใช้ VS Code ในการเข้าถึง Linux ในนั้น ซึ่งผมค้นพบว่าชีวิตสะดวกสบายมากๆเลยครับ เพราะเราใช้ VS Code ที่เราชินมืออยู่แล้วในการจัดการไฟล์ได้เลย Highlight Syntax ต่างๆก็ดูได้สะดวก เช่นในตัวอย่างข้างล่างนะครับที่ผมลองแก้ไขไฟล์ docker-compose.yaml

พิมพ์แค่ `code .` ก็เปิด VS Code มาแก้ที่ Windows ของเราอย่างสะดวกสุดๆ

ท่านใดสนใจการติดตั้งและใช้งาน WSL2 บน Windows สามารถดูได้ที่บทความนี้นะครับ

ในปัจจุบันนี้ เราสามารถใช้ VS Code Extension ที่ชื่อ Remote SSH ในการเข้าถึง Server และใช้ GUI ของ VS Code ในการจัดการแก้ไขไฟล์ต่างๆได้เหมือนกันครับผมลองกดติดตั้งกันได้ตามลิ้งนี้นะครับ

Introduction to Encryption

ก่อนที่จะเริ่มพาลงมือทำ อยากขอกลับมาเกริ่นในเรื่องพื้นฐานของการเข้ารหัสกันไวๆนิดนึงนะครับ โดยหลักๆจะพูดการเข้ารหัส 2 แบบดังนี้

1. Symmetric Encryption

เข้าและถอดรหัสด้วย Key เดียวกัน ทำงานเร็ว ตัวอย่างเช่นการใช้ Key เดียวกันในการเข้าและถอดรหัสข้อมูลในฐานข้อมูล MSSQL

ภาพจาก clickssl.net

2. Asymmetric Encryption

เป็นการเข้าและถอดรหัสด้วย Key-Pair คือเข้าด้วย Key นึง และถอดรหัสด้วย Key อีกอันนึง เช่น Public Key, Private key

ภาพจาก clickssl.net

แถมเรื่องของ Public Key / Private Key ในมุม Digital Signature, Digital Envelop น่ะครับ เป็นบทความจาก ODDS ที่ทำให้ผมเห็นภาพของ Public Key, Private Key และการนำไปใช้ประโยน์มากขึ้นครับ

SSH คืออีหยังน้อ

SSH (Secure Shell) เป็นโปรโตคอลที่ใช้สำหรับการสื่อสารระหว่างเครื่องคอมพิวเตอร์ผ่านเครือข่ายโดยมีการเข้ารหัสเพื่อเพิ่มความปลอดภัย ซึ่งเราจำเป็นต้องมี 2 สิ่งข้างล่างนี้ในการเข้ารหัสนะครับ

The public key เราจะทำการสร้างจากเครื่องเราและนำไปวางยัง Server ปลายทาง เพื่อใช้ในการทำ public-key cryptography

The private key คือการพิสูจน์ตัวตนว่าเรามีสิทธิที่จะเข้าถึงเครื่อง Server จริงๆ เมื่อทำการต่อด้วย SSH connection เราจะสร้างมาพร้อมกับตอนที่สร้าง public key แต่จะต่างกันตรงที่ public จะวางที่ server ปลายทาง แต่ private key เราจะเก็บไว้ในเครื่องของเราเท่านั้น แชร์ให้คนนอกไม่ได้น่ะครับ

How Passwordless SSH Login Works. Security is my passion | by Michael Krasnov | Better Programming

สร้าง Public Key และ Private Key กันครับ

ถ้าใครใช้ Linux/ Mac ก็ข้ามไปรันคำสั่งถัดไปได้เลยนะครับ

ส่วนท่านใดที่ใช้ Windows ผมแนะนำให้ลองติดตั้ง Linux สัก Distro ใน WSL2 แล้วเข้าไปรันคำสั่งในนั้นนะครับ

หรืออีกวิธีง่ายๆก็ใช้ MobaXterm ตามขั้นตอนนี้ได้ครับ

สร้าง public, private key ด้วยคำสั่ง

ssh-keygen -m PEM -t rsa -b 4096

Azure รองรับ SSH protocol 2 (SSH-2) RSA public-private key pairs with a ที่ขนาดขั้นต่ำคือ 2048 bits นะครับ.
แต่แอบเศร้าที่ไม่รองรับ Format อื่นๆ เช่น ED25519, ECDSA (T______T)

ใส่ Filename เพื่อใช้เก็บ key

/Users/ponggun/.ssh/ponggun-linux

เพื่อความปลอดภัยที่มากขึ้น ให้เราใส่ passphrase เพื่อเพิ่มขั้นตอนที่ใช้ในการยืนยันการ login

ponggun-poc

ถ้าทำสำเร็จจะได้ผลลัพธ์ดังนี้น่ะครับ

File จะอยู่ที่ Path ที่เราระบุนะครับ เช่น

/Users/ponggun/.ssh/

Public key อยู่ใน ponggun-linux.pub

Private key is in ponggun-linux

เท่านี้เราก็จะได้ Public Key, Private Key ไว้ใช้ในขั้นตอนถัดไปแล้วครับ

ทำไมถึงควรใช้ Key Pair (Public/Private Key) แทน Password สำหรับ SSH Login

ข้อดีคือ ป้องกันการถูก Brute Force Attack หรือ Key Logger ดัก keyboard และยังสามารถตั้งรหัส Passphrase เพื่อความปลอดภัยที่มากขึ้นในกรณีที่ Key ของเราหลุดไปก็ยังไม่สามารถใช้งานได้ถ้าไม่รู้ Passphrase

ใช้ Algorithm อะไรดี
ตอนนี้ Ed25519 คือ Public Key Algorithm ที่แนะนำให้ใช้แทน RSA น่ะครับ เพราะมีความปลอดภัยที่สูงกว่า

ความปลอดภัยของ RSA จะขึ้นอยู่กับ Key Size ครับ ถ้า Key Size 3072-bit หรือ 4096-bit จะยังถือว่าปลอดภัย แต่ถ้าน้อยกว่านั้นจะถือว่าไม่ปลอดภัยแล้ว เช่น 1024-bit, 2048-bit)

อ้างอิงเพิ่มเติม

ทำไมต้องใช้ Azure VM Linux

เหตุผลหลักๆคือขึ้นอยู่กับลูกค้าเลยครับผม เนื่องจากบริษัทของผมเราเน้นเตรียม Development Server ให้ใกล้เคียงกับ Production ของลูกค้าที่สุดครับ

ซึ่งถ้าลูกค้าสามารถใช้ Azure ได้ เราก็จะพยายามใช้ PaaS (Platform as a Service) บน Azure ให้มากที่สุดเพราะลดเวลาในการดูแลเรื่องของ OS, ติดตั้ง Application ต่างๆ, Security Patch ลงได้มากเลยครับ

แต่ถ้าลูกค้าไม่สะดวกให้ใช้ Azure, ทางเราจะ Provision Windows Server หรือ Linux Server ซึ่งเป็น IaaS (Infrastructure as a Service) และทำการติดตั้ง Software ที่จำเป็นแทนนะครับ

แผนผังคร่าวๆในการเลือกว่าจะใชิบริการอะไรบน Azure เพื่อติดตั้ง Development Server ให้ลูกค้านะครับ

ถ้าผู้อ่านยังใหม่กับ Cloud Computing ผมอยากขอแนะนำบทความนี้เพื่อเรียนรู้คำศัพท์พื้นฐานต่างๆที่เกี่ยวข้องก่อนนะครับ มีทั้งหมด 6 บทเลย ^^

หรือถ้าสนใจอยากลองติดตั้ง Azure Windows VM — สามารถดูได้ที่บทความนี้นะครับ

แต่ถ้าอยากไปสุดทางฝั่ง PaaS เลย ผมแนะนำบทความน

สร้าง Azure VM — Ubuntu

ขั้นตอนแรกให้เราทำการ Pin Menu Virtual machines เพื่อความสะดวกในการเข้าถึงบ่อยๆนะครับ โดยเลือก Menu All services -> พิมพ์คำว่า Virtual machine แล้วกดที่รูปดาวได้เลยครับ

กด Create -> Azure virtual machine เพื่อเริ่มสร้าง VM กันนะครับ

ในส่วนของ Tab Basic ข้อมูลหลักๆที่เราสนใจจะมีดังนี้นะครับ

  1. Availability options -> เนื่องจากเราใช้เป็นแค่ Dev Server ถ้าพังเรากฌสร้างขึ้นมาใหม่ เลยไม่ได้ต้องการ Option อะไรเพิ่มครับ ผมเลยเลือกเป็น No ไปก่อน
  2. Security type -> ความปลอดภัยเป็นเรื่องจำเป็นถึงแม้ตจะเป็นแค่ Dev Server นะครับ เพราะเราก็ไม่อยากให้เกิดช่องโหว่ขึ้นในระบบที่อาจจะเกินผลเสียกับงานได้ เลยแนะนำให้เลือก Trusted lanuch virtual machines จะปลอดภัยกว่าครับ
  3. Image -> เลือก Ubuntu Server 20.04 LTS พระเอกของเราได้เลย
  4. Size -> ผมเลือก Standard D2S V3 จะได้ 2 VCPUs, Ram 8GB ที่ราคา
    96.36 USD ต่อเดือนนะครับ (ถ้าเราปิด Server ใน Mode Stopped (deallocated) ก็จะประหยัดค่าใช้จ่ายลงได้นะครับ)

ขั้นตอนถัดไปให้เรานำ Pubic Key ของเราไปใส่ลงไปใน Azure นะครับ และเปิด Port 22 เพื่อใช้ในการ SSH

ส่วนข้อมูลอื่นๆเลือกตาม Default ได้เลยครับ แล้วกด Create เพื่อสร้าง VM

รอจนทำงานเสร็จให้กลับไปที่ Resource Group ที่เราสร้าง ซึ่งจะพบว่านอกจาก Virtual Machine แล้วยังมี Resources อื่นๆที่ต้องใช้งานร่วมกันอีกหลายตัวเลยครับ

ให้ทำการเลือก VM ที่เราพึ่งสร้างครับ จากภาพบนจะเห็นว่าสถานะกำลังทำงานอยู่ น่ะครับ

ถ้าเราต้องการประหยัดเงิน เราสามารถที่จะปิดเครื่องให้อยู่ในสถานะดังนี้น่ะครับ (กดที่ปุ่ม Stop)

Stopped (deallocated) = Server ถูก Shutdown, Azure ไม่หักค่าใช้จ่ายในสถานะนี้ เสียเฉพาะค่า Disk  และอื่นๆ

เมื่อเลือก VM แล้ว, เราจะทำการกำหนด DNS name เพื่อที่จะอ้างอิงได้สะดวกและข้อมูลไม่เปลี่ยนเหมือนใช้ IP Address น่ะครับ มีขั้นตอนดังนี้

Setting > เลือก Configuration > ระบุ DNS name ที่ไม่ซ้ำกับคนอื่น >
กด Save

จะพบว่าตอนนี้เราได้ทำการแก้ไข DNS name เรียบร้อยแล้ว

ttss-linux.eastasia.cloudapp.azure.com

ต่อ Ubuntu ด้วย SSH Remote Desktop

อันดับแรกให้เราติดตั้ง Remote SSH ให้เรียบร้อยก่อนนะครับ โดยกดที่ลิ้งข้างล่างได้เลย

เปิด VS Code Remote SSH โดยจะเป็นสัญญลักษณ์สีฟ้าๆที่มุมซ้ายล่างนะครับ จิ้มรัวๆ แล้วเลือก Connect to Host

เสร็จแล้วกด Configure SSH Hosts

ทำการระบุรายละเอียด User, Host, Private Key Location ครับ

  • Hostname = DNS ของ VM ที่เรา Setup ไว้ก่อนหน้านี้นะครบ
  • User = User ของ VM
  • IdentityFile = Private Key ของเราครับ
Host ttss-linux
HostName ttss-linux.eastasia.cloudapp.azure.com
User ttss
IdentityFile /Users/ponggun/.ssh/ponggun-linux

กดต่อใหม่ได้เยย คราวนี้จะมีชื่อมาให้เลือกด้วย

เข้ามาได้แล้วครับน้ำตาจะไหล เพราะไม่เห็นอะไรเลย

หยอกๆๆๆ ให้เราลองกด Open Folder แล้วระบุ Path ที่เราต้องการทำงานนะครับ ผมเลือก Home Directory ละกัน

ติดตั้ง Docker

ขั้นตอนทั้งหมดผมนำมาจากต้นทางของ Docker Official นะครับ

ยกเลิกการติดตั้ง Docker Version ก่อนหน้า

สำหรับใครที่เคยติดตั้ง Docker ไปก่อนหน้านี้แล้ว ให้ทำการรัน Script เพื่อยกเลิกการติดตั้งก่อนนะครับ เพื่อป้องกันปัญหาการติดตั้งใหม่ที่อาจจะไม่สมบูรณ์

for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

ติดตั้ง Repository

เริ่มด้วยการ Upgrage apt package, ติดตั้ง Packages เพื่อใช้งาน Repository, เพิ่ม Docker’s GPG key, ติดตั้ง Docker’s Apt repository (ค่อยๆรันทีละคำสั่งนะครับ)

# Add Docker's official GPG key:
sudo apt-get update

sudo apt-get install ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

ติดตั้ง Docker

ติดตั้ง Docker Engine — Community version ล่าสุด

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

ทดสอบว่า Docker Engine — Community ได้รับการติดตั้งแล้วด้วยการรัน Docker Image hello-world

sudo docker run hello-world

สิ่งที่เกิดขึ้นจากคำสั่ง docker run hello-world

1. Docker client ต่อไปที่ Docker daemon.
2. Docker daemon ดึง hello-world image จาก Docker Hub.
3. Docker daemon สร้าง container จาก hello-world image และแสดงผลลัพธ์ไปที่ terminal.

ผลลัพธ์

Hello from Docker!

แสดงว่าตอนนี้เราติดตั้ง Docker เรียบร้อยครับ แต่ยังเหลืออีก 1 ขั้นตอนที่ต้องทำครับ

ติดตั้งให้รันคำสั่ง Docker ด้วย non-root user

จากขั้นตอนข้างบนจะเห็นว่า เมื่อเราจะรันคำสั่ง docker run นั้นต้องมีคำสั่ง sudo เพื่อรันคำสั่งในฐานนะ root user ครับ

ถ้าเราต้องการรันคำสั่ง Docker ด้วย User ทั่วไป ให้ทำตามขั้นตอนนี้น่ะครับ

Docker daemon จำเป็นต้องรันด้วย root user เพราะว่าต้องใช้ Unix socket แทนที่ TCP port ซึ่ง ตัว Unix socket นั้นต้องการสิทธิระดับ root user นั้นเองครับ

เพิ่ม User เข้า docker group

sudo usermod -aG docker $USER

Restart server 1 ครั้งบน Azure Portal

ทดลองรันคำสั่ง Docker อีกครั้งโดยที่ไม่มีคำสั่ง sudo

docker run hello-world

ผลลัพธ์

แสดงว่าตอนนี้เราติดตั้ง Docker ครบถ้วนพร้อมใช้แล้วครับ ^^

สร้าง Backing Services ด้วย Docker Compose

Backing service ในมุมของ 12 factors app คือ บริการที่ให้ฐานข้อมูล, ระบบข้อความ, caching, หรือเครื่องมืออื่น ๆ ที่ระบบต้องการเพื่อทำงานได้อย่างถูกต้อง

The Twelve-Factor App (12factor.net)

สิ่งสำคัญคือ 12 factors app จะเน้นว่า backing services ควรถูกจัดการการเชื่อมต่อให้เราสามารถเปลี่ยน Configure เพื่อชี้ไปยังบริการเครื่องอื่นได้โดยไม่ต้องทำการเปลี่ยนแปลงโค้ด

ตัวอย่างเช่น ถ้าเรามีระบบที่ใช้ฐานข้อมูล PostgreSQL สำหรับ Dev, Test, Production การที่เราติดตั้งใน Environment ที่แตกต่างกันนี้ เราควรจะเปลี่ยนแค่ Configuration ในการเชื่อมต่อ ไม่ใช่การเข้าไปแก้ไข Code นะครับ

เพื่อให้สะดวกและยืดหยุ่นมากขึ้น, 12 factors app แนะนำให้เก็บข้อมูลการกำหนดค่าบริการเหล่านี้ในรูปแบบของ Environment Variables หรือ Configuration File นะครับ

TT Software Docker Compose

บริษัทผมพยายามเก็บรวบรวม Docker Compose ที่ได้ใช้บ่อยๆ เพื่อให้ทีมติดตั้งลงไปในเครื่องกันได้สะดวกครับผม เลยอยากนำมาแบ่งปันให้กับคนอื่นด้วยครับ โดยสามารถดูรายละเอียดที่ลิ้งนี้นะครับ

มาเริ่มติดตั้งกันนะครับ โดยให้ทำการ Clone Repository นี้ลงมาที่เครื่องครับ

git clone https://github.com/T-T-Software-Solution/docker-compose.git

เมื่อรันเสร็จจะพบว่ามี Folder docker-compose มาเรียบร้อยครับ เราสนใจอยากรันบริการไหนก็รันได้ด้วยคำสั่ง docker compose up ได้เลย

ตัวอย่างนะครับ ผมจะทดลองรัน PostgreSQL ครับ

cd docker-compose/PostgreSQL/
docker compose up
รันขึ้นเรียบร้อยดีนะครับ

แต่เราจะพบว่าจะยังไม่สามารถเข้าถึงแบบ Public ได้ ซึ่งเราต้องทำการ
เปิด port 5432 ของ server ให้เข้าถึงได้จากภายนอก ซึ่งตรงนี้ต้องทำที่ Azure

เลือก Network settings -> Network security group

เลือก Inbound security rules -> Add -> Service -> PostgreSQL (Azure เตรียม Port รอแว้ว สบายจัดๆๆๆ)

คราวนี้เข้าทดลองใช้งานผ่านตัวตุ่น Dbeaver ของเรา (ใครไม่เคยใช้ ผมแนะนำเลยฮะ ติดตั้งได้ทั้ง Windows, Mac ฟรีด้วย ดีงาม)

เลือก New Connection → PostgreSQL -> ระบุ Server ของเราครับ (User/Pass ดูใน docker-compose.yaml น้าาา)

มาแหล่วววว

สรุป

จุดประสงค์จริงๆของบทความคือผมแค่อยากจแสดงให้เห็นว่า Remote SSH ช่วยให้การทำงานสะดวกขึ้นมากด้วย GUI ของ VS Code ครับ แต่ก็คิดว่าไหนๆแล้วเผื่อใครอยากจะทดลองเล่นบ้างแต่ไม่รู้จะ Remote ไป Server ไหน

งั้นเรามาทดลองสร้างกันเองเลยดีว่า แถมสร้างแล้วก็อยากแนะนำคำศัพท์ต่างๆที่เกี่ยวข้อง เผื่อคนที่พึ่งเคยได้ใช้งาน จะได้พอมองเห็นภาพนะครับ โดยผมตั้งใจแทรกบทความที่เกี่ยวข้องเป็นระยะๆ เพื่อใช้ในการศึกษาเพิ่มเติมได้สะดวกยิ่งขึ้นครับผม

เลยเป็นที่มาของบทความนี้นะครับ

ขอบคุณผู้อ่านมากๆครับ ^^

นายป้องกัน

--

--

T. T. Software Solution

Development Manager, Web Developer with ASP.Net, ASP.net Core, Azure and Microsoft Technologies