Vấn đề thực tế gặp phải: “2 giờ sáng và server không kết nối được ra ngoài!”
Hai giờ sáng. Bạn đang say giấc nồng thì PagerDuty réo gọi. Một ứng dụng quan trọng trên server Linux đột ngột mất kết nối Internet. Log ứng dụng ngập tràn lỗi Connection timed out khi gọi API bên thứ ba. Thậm chí, server không thể cập nhật gói phần mềm hay đồng bộ thời gian NTP. Khách hàng bắt đầu than phiền, và áp lực đè nặng lên vai bạn.
Vội vàng SSH vào server. Điều đầu tiên mình làm luôn là kiểm tra kết nối cơ bản nhất:
ping google.com
Bạn nhận được kết quả ping: google.com: Name or service not known. Rõ ràng, DNS đang gặp trục trặc, hoặc tệ hơn là server mất hoàn toàn kết nối Internet. Tiếp theo, mình thử ping một địa chỉ IP công cộng:
ping 8.8.8.8
Lần này, bạn thấy Destination Host Unreachable hoặc connect: Network is unreachable. Rõ ràng server đang gặp vấn đề nghiêm trọng khi kết nối ra bên ngoài. Liệu có phải tất cả kết nối đều bị chặn? Mình thử ping gateway nội bộ của mình:
ping 192.168.1.1 # Thay bằng địa chỉ gateway thực tế của bạn
May mắn thay, lệnh ping thành công. Đây là một manh mối quan trọng: server vẫn giao tiếp được trong mạng nội bộ, nhưng không thể ra ngoài Internet. Vậy, đâu là nguyên nhân?
Phân tích nguyên nhân: Đi từ những điều cơ bản nhất
Mỗi khi đối mặt với sự cố mạng, mình luôn tuân thủ mô hình OSI, đi từ lớp dưới lên lớp trên. Cách tiếp cận này giúp mình hệ thống hóa quá trình gỡ lỗi và không bỏ sót bất kỳ khả năng nào.
1. Lớp Mạng (Network Layer – Layer 3): IP, Gateway, Định tuyến
Đây là điểm khởi đầu cho hành trình của gói tin ra khỏi server. Nếu server không biết đường đi hoặc địa chỉ IP sai, mọi thứ sẽ tắc nghẽn ngay lập tức.
- Server đã có địa chỉ IP hợp lệ chưa? Card mạng có đang hoạt động (trạng thái UP) không?
- Server có biết gửi gói tin ra ngoài qua đâu không (default gateway)?
- Bảng định tuyến có chỉ định đường đi chính xác cho gói tin không?
2. Lớp Vận chuyển (Transport Layer – Layer 4): Tường lửa (Firewall)
Ngay cả khi gói tin đã tìm được đường đi, chúng vẫn có thể bị tường lửa (như iptables, firewalld) chặn lại, dù là trên server hay trên các thiết bị mạng trung gian. Tường lửa chặn kết nối đi (outbound) hoặc đến (inbound) dựa trên cổng (port) và địa chỉ IP nguồn/đích.
3. Lớp Ứng dụng (Application Layer – Layer 7): Phân giải tên miền (DNS)
Nếu bạn ping được một địa chỉ IP công cộng nhưng lại không ping được tên miền (ví dụ: google.com), thì thủ phạm chính là DNS. Khi đó, server không thể phân giải tên miền thành địa chỉ IP, dẫn đến lỗi kết nối.
Các cách giải quyết và công cụ chẩn đoán chuyên sâu
Giờ là lúc chúng ta đi sâu vào các công cụ để kiểm tra từng lớp một.
1. Kiểm tra cấu hình IP và trạng thái interface với ip
Lệnh ip là công cụ hiện đại và mạnh mẽ để quản lý mạng trên Linux, dần thay thế cho lệnh ifconfig cũ. Mình sẽ dùng `ip` để kiểm tra địa chỉ IP, trạng thái card mạng và nhiều thông số khác.
ip a show
Lệnh này hiển thị tất cả interface mạng cùng cấu hình IP của chúng. Bạn cần kiểm tra:
- Interface chính (ví dụ:
eth0,ens33,enp0s3) có địa chỉ IP hợp lệ trong dải mạng của server không. - Trạng thái của interface đó có phải là
UPkhông. Nếu làDOWN, bạn cần kích hoạt nó bằng lệnh:
sudo ip link set dev eth0 up # Thay eth0 bằng tên interface của bạn
Đôi khi, địa chỉ IP có thể bị mất hoặc cấu hình sai. Nếu vậy, bạn có thể thử gán lại địa chỉ IP (lưu ý: chỉ tạm thời, cho đến khi dịch vụ mạng khởi động lại hoặc file cấu hình được cập nhật):
sudo ip addr add 192.168.1.100/24 dev eth0
2. Phân tích bảng định tuyến với ip route
Đây là bước cực kỳ quan trọng để xác định server có biết đường ra Internet hay không. Lệnh ip route (viết tắt ip r) hiển thị bảng định tuyến của hệ thống.
ip r show
Hãy tìm dòng bắt đầu bằng default via. Đây chính là default gateway – nơi mọi gói tin không có đường đi cụ thể sẽ được chuyển hướng tới. Ví dụ:
default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.100 metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 metric 100
Nếu không thấy dòng default via hoặc nó trỏ đến một địa chỉ sai, đó chính là nguyên nhân. Server hoàn toàn không biết cách gửi gói tin ra bên ngoài. Để khắc phục tạm thời vấn đề này:
sudo ip r add default via 192.168.1.1 dev eth0 # Thay bằng gateway và interface của bạn
Sau đó, hãy thử ping 8.8.8.8 một lần nữa. Nếu thành công, bạn đã xác định được vấn đề. Để thiết lập vĩnh viễn, bạn cần kiểm tra cấu hình NetworkManager hoặc các file cấu hình interface phù hợp.
3. Kiểm tra phân giải tên miền với dig
Nếu bạn đã ping được 8.8.8.8 nhưng vẫn không thể ping google.com, thì thủ phạm chính là DNS. Lệnh dig (Domain Information Groper) là công cụ mạnh mẽ để chẩn đoán các vấn đề DNS.
dig google.com
Nếu bạn thấy ;; connection timed out; no servers could be reached hoặc thiếu phần ANSWER SECTION, điều đó có nghĩa là server không thể truy vấn các DNS server. Đầu tiên, hãy kiểm tra file cấu hình DNS của hệ thống:
cat /etc/resolv.conf
Bạn sẽ thấy các dòng nameserver. Hãy đảm bảo các địa chỉ IP này hợp lệ và có thể truy cập được. Thử truy vấn trực tiếp một DNS server công cộng như Google DNS (8.8.8.8):
dig @8.8.8.8 google.com
Nếu lệnh này thành công, nghĩa là DNS server đang được cấu hình trong /etc/resolv.conf có vấn đề (hoặc không thể truy cập được từ server của bạn). Bạn có thể chỉnh sửa /etc/resolv.conf để tạm thời sử dụng DNS server công cộng:
echo 'nameserver 8.8.8.8' | sudo tee /etc/resolv.conf
echo 'nameserver 8.8.4.4' | sudo tee -a /etc/resolv.conf
Lưu ý quan trọng: Trên các hệ thống sử dụng systemd-resolved hoặc NetworkManager, file /etc/resolv.conf thường là symlink và sẽ bị ghi đè khi khởi động lại. Để thay đổi vĩnh viễn, bạn cần cấu hình thông qua systemd-resolved hoặc NetworkManager.
4. Kiểm tra kết nối TCP/UDP với netcat (nc)
Ngay cả khi IP, định tuyến và DNS đều ổn, ứng dụng vẫn có thể báo lỗi kết nối tới một dịch vụ cụ thể trên một cổng nào đó (ví dụ: cổng 443 cho HTTPS, cổng 80 cho HTTP). Lúc này, netcat là công cụ đắc lực để kiểm tra xem có tường lửa nào đang chặn kết nối hay không.
Để kiểm tra xem server của bạn có thể kết nối tới cổng 443 của Google hay không:
nc -zv google.com 443
Nếu bạn nhận được Connection to google.com 443 port [tcp/https] succeeded!, điều đó có nghĩa là kết nối TCP từ server của bạn đến Google trên cổng 443 hoàn toàn ổn định. Ngược lại, nếu bạn thấy Connection timed out hoặc Connection refused, khả năng cao là có tường lửa chặn ở đâu đó, hoặc dịch vụ đích không chạy.
Mình cũng thường dùng netcat để kiểm tra kết nối hai chiều giữa hai server. Ví dụ, trên Server A, mình sẽ lắng nghe một cổng:
nc -lvp 12345
Trên Server B, mình kết nối tới Server A:
nc -zv <IP_Server_A> 12345
Nếu kết nối thành công, bạn có thể gõ tin nhắn từ Server B và thấy chúng xuất hiện trên Server A. Điều này giúp loại trừ các vấn đề về tường lửa hoặc đường truyền giữa hai server.
5. Xác định đường đi gói tin với traceroute (hoặc mtr)
Nếu các bước trên vẫn chưa giúp bạn tìm ra vấn đề, hoặc bạn nghi ngờ có sự cố trên đường đi của gói tin (ví dụ: một router bị lỗi), traceroute là công cụ không thể thiếu.
traceroute google.com
Lệnh này hiển thị từng hop (router) mà gói tin đi qua để đến đích. Nếu gói tin dừng lại ở một hop hoặc có độ trễ cao bất thường tại một điểm, bạn có thể khoanh vùng vấn đề. Mình nhớ có lần, một dịch vụ chỉ thỉnh thoảng mới không kết nối được đến một API bên ngoài.
Hóa ra là do mất gói tin (packet loss) không liên tục trên một router trung gian vào giờ cao điểm. Lúc đó, mtr (My Traceroute) là cứu tinh. Nó liên tục gửi gói tin và hiển thị thống kê mất gói theo thời gian thực, giúp mình dễ dàng phát hiện vấn đề chỉ xảy ra vào những khung giờ nhất định.
mtr google.com
6. Kiểm tra Tường lửa (Firewall) trên Linux
Cuối cùng, đừng bỏ qua việc kiểm tra tường lửa trên chính server của bạn. Các hệ thống Linux hiện đại thường sử dụng firewalld hoặc iptables.
Với firewalld (trên CentOS/RHEL/Fedora):
sudo firewall-cmd --list-all
Với iptables (trên Debian/Ubuntu hoặc hệ thống cũ hơn):
sudo iptables -nvL
Hãy tìm kiếm các rule có thể chặn kết nối đi (OUTPUT chain) hoặc các rule liên quan đến FORWARD nếu server của bạn hoạt động như một router. Nếu bạn nghi ngờ tường lửa là nguyên nhân, hãy thử tắt tạm thời (CHỈ trong môi trường thử nghiệm!) để xác nhận:
sudo systemctl stop firewalld # Hoặc iptables.service
Sau khi xác nhận, hãy nhớ bật lại và cấu hình đúng rule thay vì tắt hẳn!
Cách tốt nhất để tiếp cận một sự cố mạng
Gỡ lỗi mạng là cả một nghệ thuật và khoa học. Dưới đây là những kinh nghiệm mình đã đúc kết được sau nhiều lần “vật lộn” với các vấn đề mạng:
- Bắt đầu từ những điều cơ bản nhất: Luôn bắt đầu kiểm tra từ Layer 1 (Physical) lên Layer 7 (Application) của mô hình OSI. Đừng bao giờ nhảy ngay vào kiểm tra DNS nếu chưa chắc chắn về IP và định tuyến.
- Sử dụng phương pháp loại trừ: Với mỗi lệnh chạy và mỗi kết quả nhận được, hãy cố gắng loại trừ một khả năng. Ví dụ, nếu
ping 8.8.8.8thành công, bạn có thể loại trừ các vấn đề cơ bản ở Layer 3 và 4. - Kiểm tra logs: Luôn kiểm tra các log hệ thống.
journalctl -u NetworkManagerhoặcjournalctl -u systemd-networkdcó thể cung cấp manh mối về lỗi cấu hình hoặc trạng thái interface.dmesgcũng rất hữu ích cho các vấn đề liên quan đến driver card mạng. - Đừng ngại hỏi và tìm kiếm: Nếu bạn đã thử mọi cách mà vẫn bế tắc, đừng ngần ngại hỏi đồng nghiệp, tìm kiếm trên Stack Overflow hoặc các diễn đàn chuyên ngành. Rất có thể ai đó đã gặp vấn đề tương tự trước đây.
- Ghi lại các bước đã làm: Việc ghi lại không chỉ giúp bạn theo dõi quá trình gỡ lỗi mà còn là tài liệu quý giá cho những lần sau.
- Giữ bình tĩnh: Đặc biệt vào lúc 2 giờ sáng. Áp lực có thể khiến bạn bỏ sót những chi tiết nhỏ nhất. Hít thở sâu và tiếp cận vấn đề một cách hệ thống.
Chẩn đoán và khắc phục sự cố mạng trên Linux có thể phức tạp. Tuy nhiên, với các công cụ và phương pháp tiếp cận đúng đắn, bạn hoàn toàn có thể tìm và giải quyết vấn đề. Hãy luyện tập thường xuyên để những lệnh này trở thành phản xạ tự nhiên của bạn!

