info-iptables-ubuntu-server-workshop

ระบบทดลอง: Ubuntu Server 24.04 LTS หรือ 26.04 LTS บน VM เครื่องใหม่

iptables เป็นเครื่องมือกำหนดกฎกรองแพ็กเก็ต (Packet Filtering) ในระบบ Linux ผ่าน Netfilter ใช้จำกัดการเข้าถึงบริการ เช่น SSH, HTTP และ HTTPS ตลอดจนกรองตาม IP Address หรือเครือข่ายย่อย (Subnet) ได้อย่างละเอียด

Workshop นี้ออกแบบสำหรับการเรียนการสอนและการทดลองแบบทำตามได้จริง โดยให้ความสำคัญกับ การสำรองกฎ การทดสอบก่อนใช้จริง และการกู้คืนเมื่อ SSH หลุด มากกว่าการสั่ง DROP ทันที

⚠️ ขอบเขตสำคัญ: คำสั่งที่โหลดไฟล์กฎในบทความนี้เขียนขึ้นสำหรับ VM ทดลองที่ไม่มี Docker, Kubernetes, UFW, firewalld, VPN หรือ Firewall Rules สำคัญอยู่ก่อน ห้ามนำไฟล์กฎตัวอย่างไปใช้ทับ Firewall ของเครื่อง Production โดยตรง เพราะ iptables-restore อาจลบ/แทนที่กฎเดิมใน Table ที่ระบุ

#สิ่งที่จะได้เรียนรู้

  1. อธิบายความสัมพันธ์ระหว่าง Netfilter, Tables, Chains, Rules และ Targets
  2. ติดตั้งและตรวจสอบกฎ iptables บน Ubuntu Server
  3. สร้าง Stateful Firewall ที่อนุญาต SSH, HTTP และ HTTPS แต่ปิดพอร์ตขาเข้าอื่น
  4. ทดลองบล็อก IP และอนุญาต MySQL เฉพาะ IP ที่ระบุ
  5. ใช้ iptables-apply เพื่อตั้งกฎพร้อมระบบ Rollback อัตโนมัติเมื่อยืนยันไม่ได้
  6. บันทึกกฎด้วย iptables-persistent และตรวจสอบหลัง Reboot
  7. เข้าใจข้อจำกัดของ IPv6 และ Docker Published Ports

#1. สถาปัตยกรรม iptables เบื้องต้น

#1.1 แนวคิดหลัก

องค์ประกอบ ความหมาย ตัวอย่าง
Table กลุ่มการทำงานของ Firewall filter, nat, mangle, raw
Chain จุดตรวจสอบแพ็กเก็ต INPUT, OUTPUT, FORWARD
Rule เงื่อนไขที่แพ็กเก็ตต้องตรง TCP Destination Port 22
Target ผลลัพธ์ของกฎ ACCEPT, DROP, REJECT, LOG
Policy พฤติกรรมเมื่อไม่ตรงกฎใดใน Built-in Chain INPUT DROP

Chain ที่พบบ่อยใน filter Table

  • INPUT: แพ็กเก็ตที่มีปลายทางเป็นตัว Server เอง
  • OUTPUT: แพ็กเก็ตที่ส่งออกจากโปรเซสบน Server
  • FORWARD: แพ็กเก็ตที่ Server ทำหน้าที่ส่งต่อให้เครื่องอื่น เช่น Router หรือ Container

Targets ที่ควรรู้

  • ACCEPT — อนุญาตแพ็กเก็ตให้ผ่าน Chain นี้
  • DROP — ทิ้งแพ็กเก็ตเงียบ ๆ
  • REJECT — ปฏิเสธและส่งสัญญาณตอบกลับตามประเภทแพ็กเก็ต/กฎ
  • LOG — บันทึกข้อมูลแล้วประมวลผล Rule ถัดไปต่อ (ไม่ใช่การอนุญาตหรือปฏิเสธในตัวเอง)

#1.2 Data Flow

flowchart LR
    C[Client] --> N[Network Interface]
    N --> F{iptables INPUT}
    F -->|SSH 22 Allowed| S[SSH Service]
    F -->|HTTP 80 Allowed| H[Web Server]
    F -->|HTTPS 443 Allowed| T[HTTPS Service]
    F -->|Other Incoming Traffic| D[DROP]
    S --> R[Response via OUTPUT]
    H --> R
    T --> R

Ubuntu รุ่นใหม่มักใช้ iptables-nft เป็น Backend ของคำสั่ง iptables ซึ่งหมายถึงคำสั่งรูปแบบเดิมสามารถทำงานผ่านโครงสร้าง nftables ได้ อย่างไรก็ตาม ไม่ควรให้หลายเครื่องมือแก้ไขกฎ Netfilter ชุดเดียวกันโดยไม่มีการวางแผน


#2. เตรียม Lab Environment

#2.1 สภาพแวดล้อมที่แนะนำ

รายการ ค่าที่แนะนำ
Host OS Ubuntu Server 24.04 LTS / 26.04 LTS
VM 1 vCPU, RAM 2 GB ขึ้นไป
การเชื่อมต่อ VM Console หรือ SSH ที่มีช่องทาง Console กู้คืนได้
บริการ OpenSSH Server, Nginx
เครื่อง Client เครื่องอื่นในเครือข่ายสำหรับทดสอบ SSH/HTTP
พอร์ตทดลอง TCP 22, 80, 443

ตัวอย่างต่อไปใช้ <SERVER_IP> แทน IP Address ของ VM และ <ADMIN_IP> แทน IP Address ของผู้ดูแล ให้เปลี่ยนเป็นค่าจริงก่อนใช้งาน

#2.2 ตรวจสอบการตั้งค่าเดิม

lsb_release -a
ip -br addr
ip route
sudo ss -lntup
sudo iptables --version
sudo iptables -S
sudo iptables -t nat -S
sudo ip6tables -S
sudo ufw status

ตรวจสอบ Backend

sudo update-alternatives --display iptables

เกณฑ์ก่อนเริ่ม: ใช้ VM ทดลองที่ยังไม่มีบริการที่ต้องพึ่งพา Firewall Rules เฉพาะทาง เช่น Docker/Kubernetes หากมีกฎเดิมที่ไม่ทราบวัตถุประสงค์ ต้องหยุดและตรวจสอบก่อน

#2.3 ติดตั้งแพ็กเกจและ Web Server

sudo apt update
sudo apt install -y iptables openssh-server nginx curl

ตรวจสอบ SSH และ Nginx

sudo systemctl status ssh --no-pager
sudo systemctl status nginx --no-pager
sudo ss -lntp | grep -E ':(22|80|443)\b' || true
curl -I http://127.0.0.1

พอร์ต 443: กฎ Firewall เปิดทางให้ HTTPS ได้ แต่ Nginx ที่เพิ่งติดตั้งอาจยังไม่ได้ตั้งค่า TLS/Certificate ดังนั้น curl https://<SERVER_IP> อาจไม่สำเร็จจนกว่าจะกำหนด HTTPS ให้ Web Server จริง

ตรวจสอบว่า SSH ใช้พอร์ต 22 จริงหรือไม่

sudo sshd -T | grep '^port '

หากใช้พอร์ตอื่น ให้แก้พอร์ต SSH ในไฟล์กฎด้านล่าง ก่อน นำกฎไปใช้


#Lab 1: สำรองและอ่านกฎเดิม

เป้าหมาย: ตรวจสอบสถานะ Firewall และมีไฟล์สำหรับกู้คืน

#ขั้นตอน 1 — สำรองกฎ IPv4 และ IPv6

sudo sh -c 'iptables-save > /root/iptables-before-lab.v4'
sudo sh -c 'ip6tables-save > /root/ip6tables-before-lab.v6'

#ขั้นตอน 2 — อ่านกฎปัจจุบัน

sudo iptables -L -n -v --line-numbers
sudo iptables -S
sudo iptables-save

อธิบาย Options

Option ความหมาย
-L แสดงกฎใน Chains
-n ไม่แปลง IP เป็นชื่อ Host และ Port เป็นชื่อบริการ
-v แสดงสถิติ/รายละเอียดเพิ่มเติม
--line-numbers แสดงหมายเลข Rule เพื่อใช้อ้างอิง
-S แสดงกฎในรูปแบบคำสั่ง
iptables-save ส่งออกกฎไปยังรูปแบบที่ iptables-restore อ่านได้

ผลลัพธ์ที่คาดหวัง: มีไฟล์ Backup และสามารถระบุ Default Policy ของ INPUT, OUTPUT และ FORWARD ได้


#Lab 2: สร้าง Stateful Firewall สำหรับ SSH / HTTP / HTTPS

เป้าหมาย: อนุญาตการใช้งานที่จำเป็น พร้อมปิดการเชื่อมต่อขาเข้าอื่นด้วย Default Policy DROP

#ขั้นตอน 1 — สร้างไฟล์กฎ

ไฟล์ต่อไปนี้กำหนด เฉพาะ IPv4 filter Table และมีสมมติฐานว่า SSH ใช้พอร์ต 22

cat > "$HOME/iptables-lab.v4" <<'RULES'
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# Internal host communication
-A INPUT -i lo -j ACCEPT

# Keep established connections and related packets
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow remote management over SSH
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# Allow web traffic
-A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# Allow ICMPv4 echo requests for troubleshooting
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT

COMMIT
RULES

หมายเหตุ: iptables-restore รองรับบรรทัด Comment ที่ขึ้นต้นด้วย # และลำดับ Rule มีผลต่อการตัดสินใจ

#ขั้นตอน 2 — ตรวจสอบ Syntax โดยยังไม่เปิดใช้

sudo iptables-restore --test "$HOME/iptables-lab.v4"

หากคำสั่งคืนค่า Exit Code 0 แปลว่าไม่มีข้อผิดพลาดที่ตรวจพบในขั้น Parse/Construct แต่ ไม่ได้ยืนยันว่ากฎเปิดพอร์ตถูกต้องหรือจะไม่ตัด SSH

echo $?

#ขั้นตอน 3 — เปิดใช้แบบ Rollback อัตโนมัติ

อย่าปิด Terminal SSH เดิม และควรมี VM/Cloud Console สำรองเสมอ

command -v iptables-apply
sudo iptables-apply -t 90 "$HOME/iptables-lab.v4"

iptables-apply จะทดลองใช้ Rule File และถามยืนยัน หากไม่สามารถยืนยันภายใน 90 วินาที โปรแกรมจะพยายามคืนค่า Ruleset ก่อนหน้าโดยอัตโนมัติ จึงปลอดภัยกว่าการใช้ iptables-restore ตรง ๆ ขณะเชื่อมต่อผ่าน SSH

ระหว่างที่รอคำถามยืนยัน ให้เปิด Terminal อีกหน้าต่าง จาก Client แล้วทดสอบ:

ssh <USER>@<SERVER_IP>
curl -I http://<SERVER_IP>

หาก SSH และ HTTP ใช้งานได้ตามที่ต้องการจึงตอบยืนยันใน Terminal แรก หากไม่ได้ ให้ปล่อย Timeout เพื่อให้ Rollback ทำงาน แล้วใช้ VM Console ตรวจสอบ

ข้อจำกัด: การ Rollback ของ iptables-apply เป็นเครื่องช่วยลดความเสี่ยง ไม่ใช่การรับประกัน 100% โดยเฉพาะในระบบที่มีหลาย Firewall Managers หรือ Network Policy ภายนอก

#ขั้นตอน 4 — ตรวจสอบกฎที่ใช้งานจริง

sudo iptables -L INPUT -n -v --line-numbers
sudo iptables -S INPUT

ควรพบ -P INPUT DROP และกฎอนุญาต Loopback, Established/Related, TCP 22, TCP 80/443 และ ICMP Echo Request

#ขั้นตอน 5 — ทดสอบพอร์ต

บน Client ที่มีเส้นทางเชื่อมต่อถึง VM:

curl -I --max-time 5 http://<SERVER_IP>
ssh <USER>@<SERVER_IP>

ทดสอบพอร์ตที่ไม่ได้เปิด (ตัวอย่าง 3306):

nc -vz -w 3 <SERVER_IP> 3306

ถ้า Client ยังไม่มี nc ให้ติดตั้ง netcat-openbsd บน Client ก่อน

การตีความ: เมื่อ INPUT DROP และไม่มีกฎอนุญาต TCP 3306 การเชื่อมต่อใหม่จากภายนอกจะถูกทิ้ง หากไม่มีบริการฟังอยู่ด้วยก็ต้องแยกวิเคราะห์ระหว่าง Firewall กับ Service ด้วย ss -lntp

หากติดตั้งบน Cloud ต้องตรวจสอบ Security Group, Network ACL หรือ Cloud Firewall ด้วย เพราะนโยบายภายนอกอาจบล็อก Traffic ก่อนถึง iptables


#Lab 3: จำกัดบริการด้วย IP Address และ Subnet

เป้าหมาย: ใช้ Source IP Filtering และเข้าใจผลของลำดับ Rules

#3.1 อนุญาต MySQL เฉพาะ IP ของ Application Server

ตัวอย่างสมมติให้เครื่อง Application Server มี IP 192.168.1.50 และ MySQL อยู่บน VM เครื่องนี้

sudo iptables -I INPUT 3 \
  -p tcp -s 192.168.1.50 --dport 3306 \
  -m conntrack --ctstate NEW -j ACCEPT

กฎนี้เพิ่มสิทธิ์เฉพาะ Source IP ที่ระบุ ส่วน IP อื่นยังอยู่ภายใต้ Default Policy DROP หากไม่มีกฎอื่นเปิด 3306 ให้กว้างกว่า

การเปิดกฎ Firewall ไม่เท่ากับการเปิด MySQL ให้รับการเชื่อมต่อ ต้องตรวจสอบ bind-address, การตั้งค่าผู้ใช้ฐานข้อมูล และการเข้ารหัสการเชื่อมต่อด้วย

#3.2 ทดลองอนุญาตเครือข่ายย่อยบนพอร์ต 8080

sudo iptables -I INPUT 3 \
  -p tcp -s 192.168.1.0/24 --dport 8080 \
  -j ACCEPT

ตัวอย่างนี้อนุญาต Subnet 192.168.1.0/24 (เมื่อพิจารณาตาม Ruleset นี้และไม่มี Rule ที่ขัดแย้ง)

#3.3 ทดลองบล็อก IP ที่กำหนด

sudo iptables -I INPUT 1 -s 203.0.113.50 -j DROP

203.0.113.50 เป็นที่อยู่ สงวนไว้สำหรับตัวอย่างเอกสาร ให้เปลี่ยนเป็น IP จำลองที่ต้องการทดสอบจริง และอย่าใช้ IP ของเครื่องผู้ดูแลที่กำลังเชื่อมต่อผ่าน SSH

การเพิ่มไว้ที่ตำแหน่ง 1 ทำให้ Rule บล็อกถูกตรวจสอบก่อน Rule ESTABLISHED,RELATED; ลำดับจึงสำคัญ

sudo iptables -L INPUT -n -v --line-numbers

#3.4 ลบกฎที่ทดลองเพิ่ม

ใช้รูปแบบเต็มเพื่อลดความผิดพลาดจากหมายเลข Rule ที่เปลี่ยนแปลง:

sudo iptables -D INPUT -s 203.0.113.50 -j DROP
sudo iptables -D INPUT -p tcp -s 192.168.1.0/24 --dport 8080 -j ACCEPT
sudo iptables -D INPUT -p tcp -s 192.168.1.50 --dport 3306 \
  -m conntrack --ctstate NEW -j ACCEPT

เมื่อลบ ให้ใช้ค่า IP และ Rule ตรงกับรายการที่เพิ่มไว้จริง และตรวจสอบผลด้วย iptables -S INPUT อีกครั้ง


#Lab 4: บันทึก Firewall ถาวรหลัง Reboot

เป้าหมาย: ทำให้ Ruleset ที่ยืนยันแล้วถูกโหลดเมื่อบูตเครื่อง

ทำ Lab นี้เมื่อทดสอบการเชื่อมต่อผ่าน SSH และ HTTP สำเร็จแล้วเท่านั้น

#ขั้นตอน 1 — ติดตั้ง iptables-persistent

sudo apt install -y iptables-persistent

ระหว่างติดตั้งอาจมีหน้าต่างถามว่าต้องการบันทึกกฎ IPv4/IPv6 ปัจจุบันหรือไม่ ให้ตรวจสอบนโยบายก่อนตอบ โดยเฉพาะกฎ IPv6

#ขั้นตอน 2 — บันทึกกฎปัจจุบัน

sudo netfilter-persistent save

ไฟล์ที่เกี่ยวข้อง:

/etc/iptables/rules.v4
/etc/iptables/rules.v6

คำสั่งนี้บันทึก กฎที่กำลังใช้งานในขณะนั้น หากมีกฎทดลองที่ไม่ต้องการ ให้ลบก่อนบันทึก และตรวจสอบไฟล์ rules.v6 เสมอ

#ขั้นตอน 3 — ตรวจสอบ Service

sudo systemctl enable netfilter-persistent
sudo systemctl status netfilter-persistent --no-pager
sudo iptables -S INPUT

หากมี Console สำรองและอยู่ใน VM Lab สามารถทดสอบ Restart ได้:

sudo reboot

หลัง VM กลับมาแล้ว:

sudo iptables -S INPUT
sudo systemctl status netfilter-persistent --no-pager

ผลลัพธ์ที่คาดหวัง: Default Policy ยังเป็น DROP และ Rules ที่อนุญาตบริการจำเป็นยังอยู่


#Lab 5: IPv6 Firewall — อย่าป้องกันแค่ IPv4

iptables ควบคุม IPv4 เป็นหลัก ส่วน IPv6 ใช้ ip6tables หากเครื่องมี Global IPv6 Address การเปิดเฉพาะ IPv4 Firewall ไม่ได้ป้องกันบริการเดียวกันบน IPv6 โดยอัตโนมัติ

ตรวจสอบ IPv6:

ip -6 addr show scope global
sudo ip6tables -S

หาก Server เปิดใช้งาน IPv6 และต้องรับการเชื่อมต่อผ่าน IPv6 ให้เตรียม Rule File สำหรับ IPv6 เพิ่มเติม โดยตัวอย่างนี้ อนุญาต ICMPv6 ซึ่งจำเป็นต่อการทำงานด้านเครือข่าย เช่น Neighbor Discovery และ Path MTU Discovery

cat > "$HOME/ip6tables-lab.v6" <<'RULES'
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

COMMIT
RULES

ตรวจสอบก่อนเปิดใช้:

sudo ip6tables-restore --test "$HOME/ip6tables-lab.v6"
command -v ip6tables-apply

กรณีทดสอบบน VM ที่มี Console กู้คืนได้ และได้ปรับพอร์ต SSH ให้ถูกต้องแล้ว:

sudo ip6tables-apply -t 90 "$HOME/ip6tables-lab.v6"

ระหว่าง Prompt ยืนยัน ให้ทดสอบจาก IPv6 Client อีก Terminal หนึ่งก่อนตอบยืนยัน และบันทึกด้วย sudo netfilter-persistent save หลังสำเร็จ

นี่คือ Ruleset เริ่มต้นสำหรับการสอน ไม่ใช่นโยบาย IPv6 ที่ละเอียดสำหรับทุกระบบ หากเครื่องทำหน้าที่ Router, ใช้ DHCPv6 หรือมีบริการเฉพาะ ต้องออกแบบ ICMPv6 และ Traffic เพิ่มให้สอดคล้องกับระบบ ไม่ควรปิด ICMPv6 ทั้งหมดโดยไม่เข้าใจผลกระทบ


#Lab 6 (เสริม): iptables กับ Docker Compose

เป้าหมาย: เข้าใจว่าการเผยแพร่พอร์ต Container ไม่เหมือนกับบริการที่รันบน Host

แนะนำให้ใช้ VM อีกเครื่องหนึ่งสำหรับ Lab นี้ ที่มี Docker Engine ติดตั้งแล้ว ไม่ให้นำไฟล์ iptables-lab.v4 จาก Lab 2 ไป Restore ทับ เพราะ Docker สร้างกฎ NAT/FORWARD เอง

#6.1 ทดลอง Web Container ที่เข้าถึงได้เฉพาะ Localhost

docker run -d --name iptables-web-lab \
  -p 127.0.0.1:8080:80 nginx:alpine

curl -I http://127.0.0.1:8080

docker ps

รูปแบบ 127.0.0.1:8080:80 จำกัดการ Publish ที่ IPv4 Loopback บน Host เหมาะกับบริการภายในที่ไม่ควรเข้าจากภายนอกโดยตรง

#6.2 เปรียบเทียบกับการ Publish สู่ทุก Interface

รูปแบบต่อไปนี้ เป็นตัวอย่างประกอบ ไม่ต้องเปิดจริงบน Server สาธารณะ:

# docker run -p 8080:80 nginx:alpine

เมื่อใช้ -p 8080:80 โดยไม่ระบุ Host IP Docker อาจทำให้บริการเข้าถึงจากภายนอกได้ผ่านกฎ NAT/FORWARD แม้ผู้ดูแลตั้ง INPUT DROP ไว้ก็ตาม

#6.3 ตรวจสอบ DOCKER-USER (เฉพาะ Docker ที่ใช้ iptables Backend)

sudo iptables -S DOCKER-USER
sudo iptables -L FORWARD -n -v
sudo iptables -t nat -S

สำหรับ Docker Engine ที่ใช้ iptables Firewall Backend Chain DOCKER-USER เป็นจุดสำหรับเพิ่มกฎกรอง Traffic ก่อนกฎ Forward ของ Docker อย่างไรก็ตาม Docker Engine สามารถใช้ nftables Backend ได้เช่นกัน ซึ่ง ไม่มี DOCKER-USER Chain ในรูปแบบเดียวกัน ต้องออกแบบ Native nftables Rules แทน

คำเตือนสำคัญ: อย่าปิดการจัดการ iptables ของ Docker ด้วย "iptables": false โดยไม่ออกแบบกฎทดแทน เพราะอาจทำให้ Container Networking ผิดปกติ

#6.4 Cleanup

docker rm -f iptables-web-lab

#3. Troubleshooting ที่พบบ่อย

อาการ สาเหตุที่เป็นไปได้ วิธีตรวจสอบ
SSH เข้า Server ไม่ได้ พอร์ตไม่ตรง, Rule ตัด, Cloud Firewall บล็อก ตรวจผ่าน Console, sudo sshd -T, iptables -S
เว็บพอร์ต 80 ไม่ตอบ Nginx หยุด, Firewall, Cloud ACL systemctl status nginx, ss -lntp, curl -I localhost
HTTPS 443 ไม่ขึ้น ยังไม่ได้ตั้ง TLS หรือ Web Server ไม่ฟังพอร์ต ss -lntp, ตรวจ Config Nginx/Certificate
IPv4 ปลอดภัยแต่ IPv6 ยังเข้าได้ ยังไม่ได้ตั้ง ip6tables ip -6 addr, ip6tables -S
Docker Container ยังเข้าจากภายนอก Published Port ใช้ FORWARD/NAT docker ps, iptables -t nat -S, Docker Backend
หลัง Reboot กฎหาย ไม่ได้บันทึก Persistent Rules netfilter-persistent save, systemctl status
กฎไม่ตรงตามที่คาด ลำดับ Rule ไม่ถูกต้อง iptables -L INPUT --line-numbers -n -v

ใช้ Packet/Byte Counters ช่วยยืนยันว่ากฎถูก Match หรือไม่:

sudo iptables -L INPUT -n -v --line-numbers

หากต้องตรวจ Log ควรใช้กฎ LOG อย่างระมัดระวังพร้อม Rate Limiting ไม่เช่นนั้นอาจเกิด Log ปริมาณมากจาก Network Scan


#4. การกู้คืน (Recovery) และ Cleanup

#กรณี A — กฎทดสอบทำให้เชื่อมต่อผิดปกติ

ใช้ VM Console หรือช่องทาง Recovery ของ Cloud Provider แล้วคืนค่าจาก Backup

sudo sh -c 'iptables-restore < /root/iptables-before-lab.v4'
sudo sh -c 'ip6tables-restore < /root/ip6tables-before-lab.v6'

ไฟล์ Backup เก็บสภาพ ณ เวลาก่อนเริ่ม Lab หากมี Service เพิ่มหรือมี Rules เปลี่ยนภายหลัง การ Restore จะย้อนกลับสภาพดังกล่าว ให้ตรวจสอบอย่างรอบคอบ

#กรณี B — ยังไม่ได้ยืนยันจาก iptables-apply

ปล่อย Timeout ตามที่กำหนดเพื่อให้โปรแกรม Rollback แล้วตรวจสอบกฎอีกครั้งเมื่อเชื่อมต่อได้

#กรณี C — บันทึกกฎ Persistent ไปแล้ว

หลังคืนค่า Ruleset ที่ต้องการและยืนยันว่าบริการยังทำงาน ให้บันทึกใหม่:

sudo netfilter-persistent save

ไม่แนะนำ ให้ใช้ iptables -F หรือ netfilter-persistent flush เพื่อแก้ปัญหาเฉพาะหน้าบน Server ที่ใช้งานจริง เพราะอาจทำให้เครือข่ายเปิดกว้างหรือบริการ Docker/Router เสียหาย


#5. แบบฝึกหัดท้าย Workshop

ข้อ โจทย์ เกณฑ์ตรวจ
1 อธิบายความต่างระหว่าง INPUT และ FORWARD จำแนก Traffic Host กับ Container ได้
2 เปลี่ยน SSH จาก 22 เป็น 2222 ในไฟล์กฎทดลอง เปิด SSH พอร์ตใหม่บน SSHD ก่อนปรับ Firewall และทดสอบผ่าน Console
3 อนุญาต TCP 8080 เฉพาะ Subnet 192.168.1.0/24 Network อื่นไม่ผ่านกฎดังกล่าว
4 จำกัด MySQL ให้รับจาก IP ที่กำหนดเท่านั้น Rule ถูกต้องและ MySQL Config สอดคล้อง
5 จำลอง Rule ที่ตัด SSH และทดลอง iptables-apply ระบบ Rollback ได้หลังหมดเวลา
6 บันทึกกฎและทดสอบ Reboot Firewall Policy ไม่หาย
7 อธิบายความเสี่ยงของ docker run -p 8080:80 อธิบาย NAT/FORWARD และ Published Port ได้

#คำถามอภิปราย

  1. เพราะเหตุใดต้องอนุญาต ESTABLISHED,RELATED ก่อนบล็อก Traffic ที่ไม่ต้องการ?
  2. เหตุใด INPUT DROP จึงไม่เพียงพอต่อการป้องกัน Docker Published Ports?
  3. Firewall ของระบบปฏิบัติการแตกต่างจาก Security Group ของ Cloud อย่างไร?
  4. ถ้า Server เปิด IPv6 แต่กำหนดกฎเฉพาะ IPv4 จะเกิดความเสี่ยงอย่างไร?
  5. เมื่อใดควรเลือกใช้ nftables โดยตรงแทนคำสั่ง iptables?

#6. สรุปแนวปฏิบัติที่ดี (Best Practices)

  • ใช้หลัก Least Privilege เปิดเฉพาะ Port, Protocol และ Source Address ที่จำเป็น
  • สำรอง Ruleset ก่อนแก้ไข และทดสอบ Syntax ด้วย iptables-restore --test
  • ใช้ iptables-apply หรือช่องทาง Rollback ที่เชื่อถือได้ โดยเฉพาะเมื่อแก้ไข Firewall ผ่าน SSH
  • ตรวจสอบบริการจริงด้วย ss, curl, ssh และทดสอบจากเครื่อง Client ไม่ใช่ดู Rule อย่างเดียว
  • จัดการ IPv4 และ IPv6 ให้สอดคล้องกัน อย่าปิด ICMPv6 ทั้งหมดแบบเหมารวม
  • เลือก Firewall Manager ให้ชัดเจน หลีกเลี่ยงการผสม UFW, firewalld, native nftables และ iptables โดยไม่มีแผน
  • สำหรับ Docker/Kubernetes ศึกษา Firewall Backend, NAT และ FORWARD Chain ก่อนแก้ไขกฎ
  • ก่อน Reboot หรือ Deploy จริง ให้ตรวจสอบ Rules ที่ Persisted, Cloud Firewall, Recovery Access และการเข้าถึง SSH

#เมื่อใดควรใช้ iptables, UFW หรือ nftables?

เครื่องมือ เหมาะกับ
UFW ดูแล Firewall ของ Ubuntu Server ทั่วไปแบบเรียบง่าย
iptables เรียนรู้และจัดการกฎ Netfilter แบบละเอียด รวมถึงระบบเดิมที่ใช้ iptables
nftables พัฒนานโยบาย Firewall สมัยใหม่ มีความยืดหยุ่นสำหรับ IPv4/IPv6

ข้อสรุป: iptables เป็นพื้นฐานสำคัญของ Linux Network Security แต่การตั้งค่าให้ปลอดภัยต้องคำนึงถึงลำดับกฎ, Stateful Connections, IPv6, การบันทึกข้าม Reboot และการทำงานร่วมกับ Container Networking


#แหล่งข้อมูลอ้างอิง

  1. Ubuntu Security Documentation — Firewall: https://documentation.ubuntu.com/security/security-features/network/firewall/
  2. Ubuntu Security Documentation — nftables: https://documentation.ubuntu.com/security/security-features/network/firewall/nftables/
  3. Linux Manual Page — iptables-apply(8): https://man7.org/linux/man-pages/man8/iptables-apply.8.html
  4. Linux Manual Page — iptables-restore(8): https://man7.org/linux/man-pages/man8/iptables-restore.8.html
  5. Ubuntu Manual — netfilter-persistent(8): https://manpages.ubuntu.com/manpages/noble/man8/netfilter-persistent.8.html
  6. Docker Docs — Docker with iptables: https://docs.docker.com/engine/network/firewall-iptables/
  7. Docker Docs — Docker with nftables: https://docs.docker.com/engine/network/firewall-nftables/
  8. Docker Docs — Port publishing and mapping: https://docs.docker.com/engine/network/port-publishing/

เผยแพร่: 16 ตุลาคม 2026 — ตัวอย่างจัดทำสำหรับการเรียนรู้ใน VM ทดสอบ ควรตรวจสอบรายละเอียดตามเวอร์ชันของระบบปฏิบัติการและ Docker ที่ติดตั้งจริง