0

Lab 8 — Firewall & Network Troubleshooting

1. Mục tiêu

Ở Lab 6 và Lab 7, chúng ta đã biết:

Domain
 ↓
DNS
 ↓
IP
 ↓
Port
 ↓
HTTP
 ↓
Application

Nhưng trong thực tế, request có thể bị Firewall chặn.

Sau lab này, bạn cần:

  • Hiểu Firewall là gì.
  • Hiểu inbound/outbound traffic.
  • Biết ufw và cách quản lý rule.
  • Phân biệt Connection refusedConnection timed out.
  • Biết cách xác định port bị chặn ở đâu.
  • Biết debug lỗi network theo từng tầng.

2. Firewall là gì?

Firewall là một lớp kiểm soát traffic:

Ảnh Minh hoạ
Screenshot 2026-08-06 at 15.56.23.png image.png Screenshot 2026-08-06 at 15.56.23.png

Firewall quyết định:

ALLOW
hoặc
DENY

Ví dụ server có:

22    SSH
80    HTTP
443   HTTPS
8080  Application

Bạn có thể chỉ cho phép:

22
80
443

và chặn:

8080

3. Inbound và Outbound

Inbound

Traffic đi vào server:

Client
   │
   ▼
Server

Ví dụ:

Client → Server:22 là inbound traffic đối với server.

Outbound

Traffic đi ra khỏi server:

Server
   │
   ▼
Internet

Ví dụ:

Server → Database:5432 là outbound traffic đối với server.


4. UFW

Trên Ubuntu, một công cụ firewall đơn giản và dễ học là:

ufw

Kiểm tra trạng thái:

sudo ufw status

Ví dụ:

Status: inactive

Hoặc:

Status: active

5. Enable Firewall an toàn

Cẩn thận: Nếu bạn đang SSH vào server, đừng bật UFW trước khi cho phép SSH.

Sai:

sudo ufw enable

Bạn có thể tự khóa mình khỏi server.

Đúng:

sudo ufw allow 22/tcp
sudo ufw enable

Sau đó:

sudo ufw status

6. Allow Port

Cho phép HTTP:

sudo ufw allow 80/tcp

HTTPS:

sudo ufw allow 443/tcp

Application:

sudo ufw allow 8080/tcp

Kiểm tra:

sudo ufw status numbered

Ví dụ:

[ 1] 22/tcp
[ 2] 80/tcp
[ 3] 443/tcp

7. Xóa Rule

Ví dụ:

sudo ufw delete allow 8080/tcp

Hoặc theo số:

sudo ufw status numbered
sudo ufw delete 3

Trick

Khi firewall có nhiều rule:

sudo ufw status numbered

rất tiện để kiểm tra và xóa rule.


8. Thực hành — Tạo Web Server

Trên server:

mkdir ~/lab8
cd ~/lab8
echo "Hello Firewall" > index.html
python3 -m http.server 8080

Kiểm tra local:

curl http://localhost:8080

Kết quả:

Hello Firewall

Kiểm tra port:

sudo ss -lntp | grep 8080

Bạn có thể thấy:

0.0.0.0:8080

Điều này có nghĩa application đang listen trên các IPv4 interface phù hợp.


9. Test từ máy khác

Từ Client:

nc -vz <SERVER_IP> 8080

Nếu firewall cho phép:

Connection to <SERVER_IP> 8080 port [tcp/*] succeeded!

Sau đó:

curl http://<SERVER_IP>:8080

Kết quả:

Hello Firewall

10. Chặn Port

Trên server:

sudo ufw deny 8080/tcp

Kiểm tra:

sudo ufw status

Từ Client:

nc -vz <SERVER_IP> 8080

Bạn có thể nhận:

Connection timed out

Đây là tình huống rất quan trọng để hiểu.


11. Connection refused vs Timeout

Hai lỗi này không giống nhau.

Connection refused

Client
  │
  │ TCP
  ▼
Server
  │
  X
Port không có service

Ví dụ:

Connection refused

Thường cần kiểm tra:

sudo ss -lntp

Có service listen trên port không?


Connection timed out

Client
  │
  │ TCP
  ▼
Firewall
  │
  X
DROP

Client chờ nhưng không nhận được response.

Thường cần kiểm tra:

Firewall
Routing
Security Group
Network ACL

12. Tư duy quan trọng

Không nên suy luận:

Connection refused
→ Firewall

hay:

Timeout
→ chắc chắn Firewall

Đó chỉ là dấu hiệu.

Hãy kiểm tra từng tầng.


13. Debug Flow

Khi:

curl http://server:8080

không hoạt động:

1. DNS
   ↓
2. IP
   ↓
3. Routing
   ↓
4. Server reachable?
   ↓
5. Firewall?
   ↓
6. Port có listen?
   ↓
7. Application?

Các command:

dig +short server.example.com
ip route get <SERVER_IP>
ping <SERVER_IP>
nc -vz <SERVER_IP> 8080
sudo ufw status
sudo ss -lntp
curl -v http://<SERVER_IP>:8080

14. Ping không kiểm tra TCP Port

Ví dụ:

ping <SERVER_IP>

thành công.

Nhưng:

nc -vz <SERVER_IP> 8080

thất bại.

Điều này hoàn toàn có thể xảy ra:

ICMP
  ✓

TCP :8080
  ✗

Vì firewall có thể cho phép ICMP nhưng chặn TCP 8080.

Vì vậy ping OK không có nghĩa application OK.


15. Kiểm tra Firewall

sudo ufw status verbose

Bạn cần chú ý:

22/tcp
80/tcp
443/tcp
8080/tcp

Ví dụ:

22/tcp    ALLOW
80/tcp    ALLOW
443/tcp   ALLOW
8080/tcp  DENY

Khi đó:

SSH       ✓
HTTP      ✓
HTTPS     ✓
Application:8080 ✗

16. Cho phép lại Port

sudo ufw delete deny 8080/tcp
sudo ufw allow 8080/tcp

Hoặc:

sudo ufw allow 8080/tcp

Sau đó:

sudo ufw status

Test lại:

nc -vz <SERVER_IP> 8080

và:

curl http://<SERVER_IP>:8080

17. Allow từ một IP cụ thể

Trong production, không nên mở mọi port cho toàn Internet nếu không cần.

Ví dụ:

sudo ufw allow from 192.168.1.10 to any port 8080 proto tcp

Ý nghĩa:

192.168.1.10
      │
      │ TCP :8080
      ▼
   Server

Chỉ IP đó được phép truy cập port 8080.

Đây là tư duy:

Least Privilege — chỉ cấp quyền cần thiết.


18. Không nên mở SSH cho toàn Internet nếu không cần

Ví dụ:

sudo ufw allow 22/tcp

đơn giản nhưng có nghĩa SSH có thể được truy cập từ mọi nơi nếu các lớp khác không chặn.

Trong môi trường production, có thể giới hạn:

VPN
Bastion Host
Private Network
Trusted IP

Ví dụ:

sudo ufw allow from <TRUSTED_IP> to any port 22 proto tcp

19. Firewall nhiều lớp

Trong cloud, firewall không chỉ nằm trên server.

Có thể có:

Ảnh Minh hoạ
Screenshot 2026-08-06 at 15.56.23.png image.png Screenshot 2026-08-06 at 15.56.23.png

Vì vậy:

"Server đã mở port" chưa có nghĩa Internet có thể truy cập port đó.

Đây là lỗi troubleshooting rất phổ biến trên AWS/Azure/GCP.


20. Ví dụ thực tế

Bạn deploy API:

api.example.com
  ↓
203.0.113.10
  ↓
TCP 443
  ↓
Nginx
  ↓
Spring Boot :8080

User nhận:

502 Bad Gateway

Đừng vội restart Spring Boot.

Có thể:

Internet
 ↓
443 ✓
 ↓
Nginx ✓
 ↓
8080 ✗
 ↓
Spring Boot

Hãy kiểm tra từ server:

curl http://localhost:8080

Nếu thành công:

Spring Boot ✓

Sau đó kiểm tra Nginx → Backend.

Nếu fail:

Spring Boot / Network / Firewall

mới là nơi cần điều tra.


21. Challenge 1 — Port bị chặn

Tạo server:

python3 -m http.server 8080

Kiểm tra:

ss -lntp | grep 8080

Cho phép:

sudo ufw allow 8080/tcp

Test từ Client:

nc -vz <SERVER_IP> 8080

Sau đó chặn:

sudo ufw deny 8080/tcp

Test lại.

Bạn cần giải thích:

Application vẫn chạy
        ↓
Port vẫn LISTEN
        ↓
Nhưng Client không kết nối được
        ↓
Firewall đang chặn

22. Challenge 2 — Service không chạy

Xóa firewall rule:

sudo ufw delete deny 8080/tcp
sudo ufw allow 8080/tcp

Tắt HTTP server.

Sau đó:

nc -vz <SERVER_IP> 8080

Bạn có thể nhận:

Connection refused

Kiểm tra:

sudo ss -lntp | grep 8080

Không có kết quả.

Kết luận:

Firewall ✓
Network ✓
Port ✗
Service không chạy

23. Challenge 3 — Bind localhost

Chạy:

python3 -m http.server 8080 --bind 127.0.0.1

Trên server:

curl http://localhost:8080

→ OK.

Từ Client:

curl http://<SERVER_IP>:8080

→ Fail.

Kiểm tra:

sudo ss -lntp | grep 8080

Bạn sẽ thấy:

127.0.0.1:8080

Nguyên nhân:

Application
    ↓
127.0.0.1
    ↓
Chỉ local

Không phải firewall.


24. Challenge 4 — Debug hoàn chỉnh

Giả sử:

curl http://api.example.com

không hoạt động.

Hãy debug theo thứ tự:

dig +short api.example.com
ip route get <IP>
ping <IP>
nc -vz <IP> 80

Trên server:

sudo ufw status verbose
sudo ss -lntp

Cuối cùng:

curl -v http://localhost:80

Mục tiêu không phải là chạy thật nhiều command.

Mục tiêu là:

Mỗi command phải giúp loại trừ một nguyên nhân.


25. Trick thực tế — nc trước curl

Nếu:

curl http://server:8080

fail, đừng chỉ thử lại nhiều lần.

Hãy:

nc -vz server 8080

Nếu nc fail:

Network / Firewall / Port

Nếu nc thành công nhưng curl fail:

HTTP / Application

Cách này giúp thu hẹp phạm vi rất nhanh.


26. Trick thực tế — Kiểm tra từ bên trong server

Giả sử user không truy cập được:

https://api.example.com

SSH vào server và thử:

curl http://localhost:8080

Nếu:

localhost → OK
external → FAIL

thì application có thể vẫn khỏe.

Hãy tập trung vào:

Bind address
Firewall
Routing
Security Group
Load Balancer
Reverse Proxy

27. Trick thực tế — Không mở port tùy tiện

Trong lab bạn có thể:

sudo ufw allow 8080

Nhưng production không nên có:

Internet
   │
   ├── 22
   ├── 3000
   ├── 5432
   ├── 6379
   ├── 8080
   └── 9000

mà không có lý do.

Một server production thường chỉ expose những port cần thiết:

Internet
   │
   ▼
  443
   │
   ▼
Reverse Proxy
   │
   ▼
Private Application

Database như PostgreSQL:

5432

thường không nên public Internet.


28. Security Principle

Hãy ghi nhớ:

Public Internet
      │
      ▼
     443
      │
      ▼
Reverse Proxy
      │
      ▼
Application Network
      │
      ▼
  Database

Không nên:

Internet
   │
   ├── 5432 PostgreSQL
   ├── 6379 Redis
   ├── 27017 MongoDB
   └── 9200 Elasticsearch

nếu không có yêu cầu đặc biệt và các lớp bảo vệ phù hợp.


29. Checklist

Sau Lab 8, bạn cần tự trả lời được:

  • Firewall là gì?
  • Inbound và outbound khác nhau thế nào?
  • UFW dùng để làm gì?
  • Làm sao kiểm tra firewall?
  • Làm sao allow một port?
  • Làm sao delete rule?
  • Connection refused thường gợi ý điều gì?
  • Connection timed out thường gợi ý điều gì?
  • Vì sao ping OK nhưng TCP port fail?
  • Vì sao curl localhost OK nhưng remote client fail?
  • ss -lntp giúp kiểm tra gì?
  • nc -vz giúp kiểm tra gì?
  • Tại sao không nên expose database ra Internet?
  • Tại sao production thường chỉ public port 443?

30. Kết quả cần đạt

Sau 3 lab:

Lab 6

IP
 ↓
Routing
 ↓
Port
 ↓
Service

Lab 7

Domain
 ↓
DNS
 ↓
IP
 ↓
Port
 ↓
HTTP
 ↓
Application

Lab 8

Domain
 ↓
DNS
 ↓
IP
 ↓
Routing
 ↓
Firewall
 ↓
Port
 ↓
Service
 ↓
HTTP
 ↓
Application

Đây chính là network troubleshooting foundation.

Khi một service không truy cập được, thay vì:

"Không vào được → restart server"

hãy suy nghĩ:

DNS?
 ↓
Route?
 ↓
Firewall?
 ↓
Port?
 ↓
Process?
 ↓
Bind address?
 ↓
HTTP?
 ↓
Application?

Nếu bạn có thể debug theo flow này, bạn đã có nền móng rất tốt để bước sang Docker Networking, Kubernetes Networking, Load Balancer, Ingress và Azure Application Gateway.

Lab tiếp theo — Lab 9: Web Server & Reverse Proxy sẽ ghép tất cả lại thành mô hình thực tế:

Client
   ↓
DNS
   ↓
Nginx :80/:443
   ↓
Spring Boot :8080
   ↓
Application

và chúng ta sẽ thực hành Nginx → Reverse Proxy → Backend, một kiến thức xuất hiện rất thường xuyên trong môi trường production.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí