Lỗi Gặp Phải
Bạn mở trình duyệt hoặc gửi một request và nhận được:
This site can't be reached. ERR_CONNECTION_TIMED_OUT
Lỗi này khác với ERR_CONNECTION_REFUSED. Refused có nghĩa là có gì đó chủ động từ chối kết nối. Timeout có nghĩa là quá trình bắt tay TCP chưa bao giờ hoàn thành — gói tin của bạn đã được gửi đi, không có gì trả về, và cuối cùng client bỏ cuộc chờ đợi.
Nguyên Nhân Gốc Rễ
- Firewall (phía server hoặc cấp mạng) âm thầm loại bỏ gói tin trên cổng đích
- Tiến trình server không lắng nghe trên cổng được chỉ định
- Sai IP hoặc DNS phân giải sang máy chủ không đúng
- Security group / cloud ACL chặn lưu lượng đến
- Sự cố định tuyến — gói tin không bao giờ đến được server
- Server quá tải và không chấp nhận kết nối mới
Bước 1 — Xác Nhận Server Có Truy Cập Được Không
Đầu tiên, thử ping đơn giản để xem host có truy cập được ở tầng mạng không:
ping your-server-ip
Ping bị timeout có nghĩa là vấn đề nằm ở tầng mạng hoặc định tuyến — trước khi ứng dụng của bạn kịp tham gia. Ping thành công nhưng cổng vẫn thất bại thì vấn đề nằm ở firewall hoặc service.
Tiếp theo, kiểm tra xem cổng cụ thể có mở không:
# Kiểm tra xem cổng 80 hoặc 443 có truy cập được không
telnet your-server-ip 80
# Hoặc dùng netcat
nc -zv your-server-ip 443
Treo không có output? Cổng đang bị lọc — firewall đang âm thầm loại bỏ gói tin. Connection refused thực ra là tin tốt hơn: có nghĩa là cổng có thể truy cập được, nhưng không có service nào đang lắng nghe trên đó.
Bước 2 — Kiểm Tra Những Gì Đang Lắng Nghe Trên Server
SSH vào và xác nhận service của bạn đang chạy và liên kết đúng địa chỉ:
# Kiểm tra các cổng đang lắng nghe
ss -tlnp
# Hoặc dùng netstat
netstat -tlnp | grep LISTEN
Đây là nơi nhiều cấu hình hay gặp sai sót. Một service liên kết với 127.0.0.1:80 chỉ chấp nhận kết nối cục bộ — nó bỏ qua mọi kết nối từ bên ngoài. Bạn cần 0.0.0.0:80 để chấp nhận lưu lượng bên ngoài.
Sửa cấu hình binding trong nginx:
server {
listen 0.0.0.0:80; # Trước đây: listen 127.0.0.1:80;
...
}
Với ứng dụng Node.js:
// Sai — chỉ localhost
app.listen(3000, '127.0.0.1');
// Đúng — tất cả interface
app.listen(3000, '0.0.0.0');
Bước 3 — Kiểm Tra Firewall
Linux (iptables / ufw)
# Kiểm tra trạng thái ufw
sudo ufw status
# Cho phép HTTP và HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
# Kiểm tra các rule iptables trực tiếp
sudo iptables -L INPUT -n -v
# Cho phép cổng 80 nếu thiếu
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Lưu các rule
sudo iptables-save > /etc/iptables/rules.v4
CentOS / RHEL (firewalld)
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Cloud Provider — Security Groups
Trên AWS, GCP, Azure hoặc DigitalOcean, firewall của hệ điều hành có thể đã mở hoàn toàn — nhưng security group ở cấp cloud vẫn đang chặn lưu lượng. Đây là hai tầng riêng biệt và cả hai đều cần cho phép cổng đó. Kiểm tra inbound rules trong bảng điều khiển cloud:
- AWS: EC2 → Security Groups → Inbound Rules → Thêm cổng 80/443 từ
0.0.0.0/0 - GCP: VPC Network → Firewall → Thêm rule cho
tcp:80,443 - DigitalOcean: Networking → Firewalls → Inbound Rules
Bước 4 — Kiểm Tra Phân Giải DNS
Một bản ghi DNS cũ có thể gửi lưu lượng đến IP server cũ — một IP không còn tồn tại hoặc thuộc về người khác:
# Xem IP mà domain phân giải thành
nslookup yourdomain.com
dig yourdomain.com A
# So sánh với IP server thực tế
curl ifconfig.me # chạy trên server
IP không khớp có nghĩa là bản ghi DNS A của bạn cần được cập nhật. Quá trình lan truyền thường mất dưới một giờ với TTL thấp (300 giây hoặc ít hơn), mặc dù trong trường hợp xấu nhất có thể kéo dài đến 48 giờ.
Bước 5 — Truy Vết Đường Đi
Vẫn bị mắc kẹt? Traceroute sẽ cho bạn thấy chính xác gói tin dừng nhận phản hồi ở đoạn nào trong đường đi mạng:
# Linux/macOS
traceroute your-server-ip
# Windows
tracert your-server-ip
Chú ý đến nơi các hop ngừng phản hồi. Đó là điểm bị chặn của bạn. Dù là ISP, nhà cung cấp transit, hay chính interface mạng của server — traceroute sẽ thu hẹp phạm vi nhanh chóng.
Bước 6 — Kiểm Tra Tải Server và Giới Hạn Tài Nguyên
Một server quá tải có thể âm thầm loại bỏ kết nối mới — không có lỗi, chỉ là im lặng:
# Kiểm tra CPU và bộ nhớ
top
free -m
# Kiểm tra xem hàng đợi kết nối có đầy không (cho nginx)
ss -s
# Kiểm tra error log của nginx/apache
tail -f /var/log/nginx/error.log
tail -f /var/log/apache2/error.log
Thấy accept4() failed (24: Too many open files) trong log? Đó là giới hạn file descriptor của Linux đang bị chạm tới. Mặc định là 1024 trên nhiều hệ thống — quá thấp cho một server bận rộn. Hãy tăng nó lên:
# /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
# Cũng trong nginx.conf
worker_rlimit_nofile 65536;
Xác Minh
Sau khi thực hiện các thay đổi, hãy kiểm tra từ máy client — không phải từ chính server:
# Kiểm tra phản hồi HTTP
curl -v http://your-server-ip
curl -v https://yourdomain.com
# Kiểm tra thời gian phản hồi
curl -w "Connect: %{time_connect}s\nTotal: %{time_total}s\n" -o /dev/null -s https://yourdomain.com
Nhận được HTTP/1.1 200 OK là bạn đã thành công. Thời gian kết nối dưới 200ms là bình thường cho server gần đó — nếu vẫn còn một giây hoặc hơn, có gì đó ở thượng nguồn vẫn đang chậm.
Mẹo Phòng Ngừa
- Mở rule firewall trước khi triển khai service, không phải sau khi đã mất thời gian debug
- Bind service với
0.0.0.0(hoặc interface ngoài cụ thể) khi cần truy cập từ bên ngoài — không bao giờ dùng127.0.0.1 - Đặt timeout kết nối rõ ràng trên reverse proxy của bạn (ví dụ:
proxy_connect_timeout 10strong nginx) để client thất bại nhanh thay vì treo 30+ giây - Giám sát hàng đợi kết nối và giới hạn file descriptor của server — đặt cảnh báo trước khi chúng trở thành sự cố
Khi chia mạng con hoặc cố gắng xác định xem một IP có nằm trong dải CIDR được phép trong rule firewall của bạn hay không, Subnet Calculator trên ToolCraft rất tiện dụng — nó chạy hoàn toàn trên trình duyệt mà không tải dữ liệu lên đâu, nên an toàn khi dán các dải IP nội bộ vào.

