Kiểm tra port đang mở trên Linux là một trong những công việc đầu tiên cần làm khi ta muốn sửa lỗi kết nối mạng hay cấu hình firewall cho hệ thống. Bài viết này sẽ hướng dẫn các cách kiểm tra port đang mở trên Linux nhanh nhất.
Port đang mở trên Linux là gì?
Port (cổng) đang mở là một cổng mạng mà ứng dụng lắng nghe, đóng vai trò là điểm cuối giao tiếp. Ta có thể xem danh sách port đang mở trên hệ thống bằng cách truy vấn stack mạng với các câu lệnh như ss
, netstat
hoặc lsof
. Mỗi port đang nghe có thể được mở hoặc đóng (lọc) bằng một tường lửa.
Nói chung, port đang mở là một cổng mạng chấp nhận những gói tin (packet) đi đến từ các vị trí ở xa. Chẳng hạn ta có một web server nghe trên port 80 và port 443, thì những port này sẽ được mở trên tưởng lửa, bất kỳ ai (ngoại trừ các ip bị chặn) đều có quyền truy cập vào trang web host trên web server này thông qua trình duyệt web. Khi đó, ta nói 80 và 443 là các port đang mở.
Các port đang mở có thể bị lợi dụng bởi các hacker để khai thác lỗ hổng bảo mật, vì vậy chúng có thể dẫn đến những rủi ro bảo mật nghiêm trọng. Đây cũng là lý do ta chỉ nên mở những port cần thiết cho các chức năng của ứng dụng, và luôn đóng những port khác khi không sử dụng.
Cách kiểm tra port đang mở trên Linux
Kiểm tra bằng nmap
Nmap là một công cụ quét mạng vô cùng mạnh mẽ, có khả năng quét các host đơn lẻ hoặc cả những mạng lớn. Nmap chủ yếu được sử dụng để kiểm tra bảo mật hoặc pen test. Đây cũng là lý do nmap nên là ưu tiên hàng đầu khi bạn cần kiểm tra port đang mở trên Linux. Bên cạnh đó, nmap còn có thể phát hiện địa chỉ Mac, loại hệ điều hành, phiên bản kernel,…
Câu lệnh dưới đây giúp xác định port nào đang lắng nghe các kết nối TCP từ mạng:
sudo nmap -sT -p- 10.10.8.8
Trong đó, -sT
yêu cầu nmap quét các port TCP và -p-
có nhiệm vụ scan mọi port (tổng cộng là 65535 cổng). Nếu không dùng -p-
thì nmap sẽ chỉ scan 1000 port phổ biến nhất.
Output:
Starting Nmap 7.60 ( https://nmap.org ) at 2019-07-09 23:10 CEST
Nmap scan report for 10.10.8.8
Host is up (0.0012s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
MAC Address: 08:00:27:05:49:23 (Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 0.41 seconds
Dựa vào output, có thể thấy rằng port 22, 80 và 8069 là những cổng đang mở trên hệ thống.
Để quét cổng UDP, ta có thể dùng -sU
thay cho -sT
:
sudo nmap -sU -p- 10.10.8.8
Kiểm tra bằng netcat
Netcat (nc) là một công cụ command-line có khả năng đọc và viết dữ liệu thông qua kết nối mạng bằng giao thức TCP hoặc UDP. Netcat cũng cho phép scan một cổng duy nhất hoặc một nhóm cổng.
Chẳng hạn bây giờ ta muốn scan các port TCP đang mở trên một máy ở xa, có địa chỉ IP 10.10.8.8, ở khoảng 20-80 thì có thể sử dụng lệnh như dưới đây:
nc -z -v 10.10.8.8 20-80
Trong đó, -z
yêu cầu nc chỉ scan những port đang mở mà không gửi bất kỳ dữ liệu nào. Còn -v
để hiển thị thông tin ở dạng đầy đủ (verbose).
Output:
nc: connect to 10.10.8.8 port 20 (tcp) failed: Connection refused
nc: connect to 10.10.8.8 port 21 (tcp) failed: Connection refused
Connection to 10.10.8.8 22 port [tcp/ssh] succeeded!
...
Connection to 10.10.8.8 80 port [tcp/http] succeeded!
Nếu chỉ muốn xem các dòng hiển thị những port đang mở thì bạn có thể lọc kết quả bằng lệnh grep như sau:
nc -z -v 10.10.8.8 20-80 2>&1 | grep succeeded
Output:
Connection to 10.10.8.8 22 port [tcp/ssh] succeeded!
Connection to 10.10.8.8 80 port [tcp/http] succeeded!
Để quét các port UDP, hãy truyền option -u
vào lệnh nc
như sau:
nc -z -v -u 10.10.8.8 20-80 2>&1 | grep succeeded
Kiểm tra bằng Bash Pseudo Device
Một cách khác để kiểm tra port đang mở trên Linux là sử dụng pseudo-device (giả thiết bị) Bash shell /developer/tcp/..
hoặc /developer/udp/..
Khi thực thi một lệnh trên pseudo-device /developer/$PROTOCOL/$HOST/$IP
thì Bash sẽ mở một kết nối TCP hoặc UDP đến host được chỉ định trên một port cho sẵn.
Câu lệnh if..else
dưới đây được dùng để kiểm tra xem port 443 trên kernel.org có đang mở hay không:
if timeout 5 bash -c '</dev/tcp/kernel.org/443 &>/dev/null'
then
echo "Port is open"
else
echo "Port is closed"
fi
Output:
Port is open
Ở đoạn code trên, khi thực hiện kết nối đến một cổng bằng pseudo-device thì thời gian timeout mặc định sẽ rất lớn. Do đó ta dùng lệnh timeout để tự động dừng lệnh sau 5 giây. Nếu kết nối được thiết lập đến kernel.org trên cổng 443 thì câu lệnh sẽ trả về kết quả true.
Để kiểm tra một khoảng port xem có đang mở không, ta cót thể dùng vòng lặp for như sau:
for PORT in {20..80}; do
timeout 1 bash -c "</dev/tcp/10.10.8.8/$PORT &>/dev/null" && echo "port $PORT is open"
done
Output:
port 22 is open
port 80 is open
Kiểm tra port đang mở trên Ubuntu
Đối với Ubuntu, người dùng còn có thể dùng lệnh ss
hoặc ufw firerwall
để kiểm tra port đang mở trên Linux.
Kiểm tra bằng lệnh ss
Lệnh ss
được dùng để hiển thị những port đang lắng nghe kết nối, đồng thời còn hiển thị những mạng đang chấp nhận kết nối đến.
Vietnix khuyến khích bạn đọc nên sử dụng option -ltn
trong lệnh để xem kết quả đầy đủ trên hệ thống:
sudo ss -ltn
Output:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 5 127.0.0.1:631 0.0.0.0:*
LISTEN 0 70 127.0.0.1:33060 0.0.0.0:*
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:*
LISTEN 0 5 [::1]:631 [::]:*
LISTEN 0 511 *:80 *:*
Có thể thấy rằng server đang nghe kết nối trên port 80, 3306 và 33060. Đây là những port phổ biến liên quan đến HTTP và MySQL.
Ngoài ra, output cũng cho bết rằng port 53 và 631 cũng đang ở trạng thái nghe, đây là hai cổng dành cho DNS và Internet Printing Protocol.
Để kiểm tra xem các port này thuộc tiến trình (process) nào, chèn thêm option -p
vào lệnh như sau:
sudo ss -ltnp
Output:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=530,fd=13))
LISTEN 0 5 127.0.0.1:631 0.0.0.0:* users:(("cupsd",pid=572,fd=7))
LISTEN 0 70 127.0.0.1:33060 0.0.0.0:* users:(("mysqld",pid=2320,fd=32))
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=2320,fd=34))
LISTEN 0 5 [::1]:631 [::]:* users:(("cupsd",pid=572,fd=6))
LISTEN 0 511 *:80 *:* users:(("apache2",pid=2728,fd=4),("apache2",pid=2727,fd=4),("apache2",pid=2725,fd=4))
Kiểm tra bằng ufw firewall
Khi sử dụng lệnh ss
hoặc nmap
trên hệ thống thì về cơ bản là ta đang bypass tường lửa. Bởi vì những lệnh này chỉ hiển thị xem port nào đang ở trạng thái lắng nghe, và điều này không đồng nghĩa với việc port này đang được mở trên internet vì tường lửa có thể đang chặn kết nối.
Do đó, bạn có thể kiểm tra trạng thái của tường lửa ufw như sau:
sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
Có thể thấy rằng ufw đang từ chối kết nối đến. Port 80 và 3306 chưa được thêm vào ngoại lệ, nên HTTP và MySQL cũng không thể nhận được kết nối mặc dù lệnh ss
cho biết nó đang ở trạng thái lắng nghe.
Bây giờ ta có thể thêm ngoại lệ cho những port này như sau:
sudo ufw allow 80/tcp
Output:
Rule added
Rule added (v6)
$ sudo ufw allow 3306/tcp
Rule added
Rule added (v6)
Kiểm tra lại:
$ sudo ufw status verbose
# output
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
80/tcp ALLOW IN Anywhere
3306/tcp ALLOW IN Anywhere
80/tcp (v6) ALLOW IN Anywhere (v6)
3306/tcp (v6) ALLOW IN Anywhere (v6)
Lời kết
Qua bài viết này, Vietnix đã cung cấp một số công cụ phổ biến nhất để kiểm tra port đang mở trên Linux, và cụ thể có cả Ubuntu. Ngoài ra vẫn còn nhiều công cụ khác hỗ trợ kiểm tra port như module socket của Python, curl
, telnet
hay wget
.