- สิ่งที่จะได้เรียนรู้
- 1. สถาปัตยกรรม iptables เบื้องต้น
- 2. เตรียม Lab Environment
- Lab 1: สำรองและอ่านกฎเดิม
- Lab 2: สร้าง Stateful Firewall สำหรับ SSH / HTTP / HTTPS
- Lab 3: จำกัดบริการด้วย IP Address และ Subnet
- Lab 4: บันทึก Firewall ถาวรหลัง Reboot
- Lab 5: IPv6 Firewall — อย่าป้องกันแค่ IPv4
- Lab 6 (เสริม): iptables กับ Docker Compose
- 3. Troubleshooting ที่พบบ่อย
- 4. การกู้คืน (Recovery) และ Cleanup
- 5. แบบฝึกหัดท้าย Workshop
- 6. สรุปแนวปฏิบัติที่ดี (Best Practices)
- แหล่งข้อมูลอ้างอิง

ระบบทดลอง: 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 ที่ระบุ
#สิ่งที่จะได้เรียนรู้
- อธิบายความสัมพันธ์ระหว่าง Netfilter, Tables, Chains, Rules และ Targets
- ติดตั้งและตรวจสอบกฎ
iptablesบน Ubuntu Server - สร้าง Stateful Firewall ที่อนุญาต SSH, HTTP และ HTTPS แต่ปิดพอร์ตขาเข้าอื่น
- ทดลองบล็อก IP และอนุญาต MySQL เฉพาะ IP ที่ระบุ
- ใช้
iptables-applyเพื่อตั้งกฎพร้อมระบบ Rollback อัตโนมัติเมื่อยืนยันไม่ได้ - บันทึกกฎด้วย
iptables-persistentและตรวจสอบหลัง Reboot - เข้าใจข้อจำกัดของ 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 ได้ |
#คำถามอภิปราย
- เพราะเหตุใดต้องอนุญาต
ESTABLISHED,RELATEDก่อนบล็อก Traffic ที่ไม่ต้องการ? - เหตุใด
INPUT DROPจึงไม่เพียงพอต่อการป้องกัน Docker Published Ports? - Firewall ของระบบปฏิบัติการแตกต่างจาก Security Group ของ Cloud อย่างไร?
- ถ้า Server เปิด IPv6 แต่กำหนดกฎเฉพาะ IPv4 จะเกิดความเสี่ยงอย่างไร?
- เมื่อใดควรเลือกใช้
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
#แหล่งข้อมูลอ้างอิง
- Ubuntu Security Documentation — Firewall: https://documentation.ubuntu.com/security/security-features/network/firewall/
- Ubuntu Security Documentation — nftables: https://documentation.ubuntu.com/security/security-features/network/firewall/nftables/
- Linux Manual Page —
iptables-apply(8): https://man7.org/linux/man-pages/man8/iptables-apply.8.html - Linux Manual Page —
iptables-restore(8): https://man7.org/linux/man-pages/man8/iptables-restore.8.html - Ubuntu Manual —
netfilter-persistent(8): https://manpages.ubuntu.com/manpages/noble/man8/netfilter-persistent.8.html - Docker Docs — Docker with iptables: https://docs.docker.com/engine/network/firewall-iptables/
- Docker Docs — Docker with nftables: https://docs.docker.com/engine/network/firewall-nftables/
- Docker Docs — Port publishing and mapping: https://docs.docker.com/engine/network/port-publishing/
เผยแพร่: 16 ตุลาคม 2026 — ตัวอย่างจัดทำสำหรับการเรียนรู้ใน VM ทดสอบ ควรตรวจสอบรายละเอียดตามเวอร์ชันของระบบปฏิบัติการและ Docker ที่ติดตั้งจริง