คำตอบสั้น ๆ: เขียนไฟล์ cloud-config ให้เครื่องใหม่สร้างผู้ใช้ วาง SSH Key ติดตั้งแพ็กเกจ และตั้ง Firewall ให้เสร็จตั้งแต่บูตครั้งแรก
คู่มือนี้อธิบาย cloud-init ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
ทุกครั้งที่สร้างเซิร์ฟเวอร์ใหม่ มีชุดงานเดิมที่ต้องทำซ้ำเสมอ สร้างผู้ใช้ วาง SSH Key ปิดการล็อกอินด้วยรหัสผ่าน ตั้ง Timezone ติดตั้งแพ็กเกจพื้นฐาน และเปิด Firewall การทำด้วยมือทุกครั้งกินเวลาและพลาดได้ง่าย โดยเฉพาะขั้นตอนด้านความปลอดภัยที่ลืมแล้วเครื่องเปิดโล่งอยู่หลายชั่วโมง
cloud-init คือระบบที่อ่านคำสั่งตอนเครื่องบูตครั้งแรกแล้วทำให้ทั้งหมดโดยอัตโนมัติ มันติดตั้งมาพร้อมกับอิมเมจ Ubuntu, Debian, AlmaLinux และ Rocky Linux สำหรับคลาวด์อยู่แล้ว
สิ่งที่ต้องเตรียม
- ผู้ให้บริการคลาวด์ที่มีช่องให้ใส่ User Data ตอนสร้างเครื่อง
- Public Key ของคุณ ดูได้จาก
cat ~/.ssh/id_ed25519.pub
ตรวจว่าอิมเมจรองรับ cloud-init หรือไม่ โดย SSH เข้าเครื่องที่มีอยู่แล้วรัน
cloud-init --version
sudo cloud-init status
ขั้นตอนที่ 1: เขียนไฟล์ cloud-config พื้นฐาน
ไฟล์ต้องขึ้นต้นด้วย #cloud-config บรรทัดแรกเสมอ ถ้าขาดบรรทัดนี้ cloud-init จะไม่อ่านเลย
#cloud-config
hostname: web1
fqdn: web1.example.com
timezone: Asia/Bangkok
locale: en_US.UTF-8
users:
- name: deploy
groups: [sudo]
shell: /bin/bash
sudo: "ALL=(ALL) NOPASSWD:ALL"
lock_passwd: true
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your-name@company
package_update: true
package_upgrade: true
packages:
- ufw
- fail2ban
- unattended-upgrades
- htop
- curl
- git
- nftables
lock_passwd: true ทำให้ผู้ใช้นี้ล็อกอินด้วยรหัสผ่านไม่ได้เลย เข้าได้เฉพาะด้วย SSH Key ซึ่งเป็นสิ่งที่ควรเป็นสำหรับเซิร์ฟเวอร์ที่เปิดสู่อินเทอร์เน็ต
ขั้นตอนที่ 2: ปิดช่องทางที่ไม่ปลอดภัย
ssh_pwauth: false
disable_root: true
write_files:
- path: /etc/ssh/sshd_config.d/99-hardening.conf
permissions: '0644'
content: |
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 3
X11Forwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
การเขียนลงไฟล์ในโฟลเดอร์ sshd_config.d ดีกว่าการแก้ไฟล์หลัก เพราะไม่ถูกเขียนทับเมื่ออัปเดตแพ็กเกจ
ขั้นตอนที่ 3: สั่งคำสั่งที่ต้องรันหลังติดตั้งเสร็จ
runcmd:
# Firewall
- ufw --force reset
- ufw default deny incoming
- ufw default allow outgoing
- ufw allow 22/tcp
- ufw allow 80/tcp
- ufw allow 443/tcp
- ufw --force enable
# เปิดอัปเดตความปลอดภัยอัตโนมัติ
- dpkg-reconfigure -f noninteractive unattended-upgrades
# ปรับค่าเคอร์เนลพื้นฐาน
- sysctl -w vm.swappiness=10
- echo 'vm.swappiness = 10' > /etc/sysctl.d/99-swappiness.conf
# โหลดคอนฟิก SSH ใหม่
- sshd -t && systemctl reload ssh
- systemctl enable --now fail2ban
คำสั่งใน runcmd รันด้วยสิทธิ์ root และรันครั้งเดียวตอนบูตแรกเท่านั้น เรียงตามลำดับที่เขียน
ขั้นตอนที่ 4: เพิ่ม Swap และตั้งค่าดิสก์
swap:
filename: /swapfile
size: 2G
maxsize: 2G
disk_setup:
/dev/sdb:
table_type: gpt
layout: true
overwrite: false
fs_setup:
- device: /dev/sdb1
filesystem: ext4
label: data
overwrite: false
mounts:
- ["LABEL=data", "/srv/data", "ext4", "defaults,noatime,nofail", "0", "2"]
ระวังตัวเลือก overwrite ให้เป็น false เสมอ เพื่อไม่ให้ฟอร์แมตทับดิสก์ที่มีข้อมูลอยู่ในกรณีที่คอนฟิกถูกนำไปใช้ซ้ำ