Nhớ lại cách đây một vài năm, tôi đã từng nhận được một cuộc gọi vào lúc gần 2 giờ sáng để xử lý sự cố cho một website bán hàng của khách bị hack. Hacker không xóa dữ liệu, không thay đổi giao diện của trang web. Họ chỉ lặng lẽ cài một backdoor nhỏ trong server và dùng nó để gửi spam, đào coin, và pivot sang các hệ thống khác. Điều đáng nói là: Server đó đã được cấu hình và bật firewall, đã đổi port SSH, đã disable root login. Thực tế thì chỉ cần một cấu hình nhỏ trong hệ thống Linux Server sai vậy toàn bộ production server vẫn bị xuyên thủng.
Sau hơn 20 năm làm vận hành & quản trị hệ thống và triển khai phát triển các hạ tầng Networks, Servers System, ứng dụng dịch vụ từ đơn giản đến phức tạp trong môi trường thực tế cho doanh nghiệp, tôi rút ra một điều:
80% servers bị hack không phải vì zero-day.
Mà vì những lỗi cấu hình rất cơ bản mà người quản trị hay quản lý “ có thể chủ quan và nghĩ là như vậy đã ổn rồi ”.
Trong bài viết này, tôi không nói về lý thuyết bảo mật.
Tôi chỉ chia sẻ 10 nguyên tắc bảo mật Linux thực chiến nhất mà tôi luôn áp dụng cho các production servers thật — những nguyên tắc giúp bạn giảm ngay 80–90% rủi ro bị tấn công mà trong khi bạn chỉ cần mất một vài giờ chịu khó ngồi cấu hình server.
Nếu bạn đang vận hành Linux server cho website, API, ERP, hay bất kỳ hệ thống production nào,
thì bài viết này..tôi nghĩ rằng có thể giúp bạn tránh được một cuộc gọi vào lúc 2 giờ sáng giống như tôi đã từng nhận.
Vậy chúng ta hãy bắt đầu với nguyên tắc đầu tiên nhé!
Contents
- 1 1. Vô hiệu hóa đăng nhập trực tiếp bằng root – Phải làm
- 2 2. Nguyên tắc ít đặc quyền – Chỉ cấp quyền vừa đủ
- 3 3. Thường xuyên cập nhật hệ thống
- 4 4. Quản lý tài khoản người dùng – Tránh “tài khoản ma”
- 5 5. Tắt các dịch vụ không dùng
- 6 6. Firewall – Chỉ mở các cổng cần thiết
- 7 7. Chống tấn công dò mật khẩu (Brute-force)
- 8 8. Yêu cầu mật khẩu mạnh
- 9 9. Quản lý chu kỳ thay đổi mật khẩu
- 10 10. Ghi log và tập trung log – Đôi mắt của hệ thống
- 11 Kết luận
1. Vô hiệu hóa đăng nhập trực tiếp bằng root – Phải làm
Vì cổng SSH là tuyến đầu của cuộc chiến, đừng để nó mở toang cho kẻ địch. Trên Linux server nói chung, SSH thường cho phép đăng nhập bằng mật khẩu và đôi khi cả root user. Do vậy việc đầu tiên và quan trọng nhất là cấm cho phép đăng nhập SSH trực tiếp với tài khoản root. Tài khoản root có toàn quyền trên hệ thống Linux, nên cũng là mục tiêu ưa thích của tin tặc – như để ngỏ cửa hậu vậy. Vậy chúng ta không cho phép root login trực tiếp trong file cấu hình /etc/ssh/sshd_config
Cách thực hiện: chúng ta mở file cấu hình SSH:
Trong file này, tìm và thêm dòng sau:
Điều này có nghĩa là dù ai đó có biết mật khẩu root, cũng sẽ không thể SSH vào server trực tiếp với quyền root.

Tiếp theo, bạn nên tắt tính năng socket activation của SSH để tránh hiện tượng dịch vụ tự động bật tắt không kiểm soát:
Sau đó, đảm bảo dịch vụ SSH được bật và khởi động lại:
Mình luôn ưu tiên sự rõ ràng: “mỗi dịch vụ – một nhiệm vụ” để dễ kiểm soát và dễ kiểm tra (audit) hệ thống.

Chuyển sang SSH Key thay vì mật khẩu
Ngay sau khi chặn quyền đăng nhập của root, chúng ta không dùng mật khẩu nữa, mà chuyển sang xác thực bằng SSH key – như dùng cặp khóa bí mật và công khai. Trên máy client dành cho việc quản trị hệ thống, hãy tạo key mới:

Sau đó, copy public key lên server:
Giải thích nhanh: file id_ed25519 là private key (không được chia sẻ cho bất cứ ai!), còn id_ed25519.pub là public key được phép upload lên Linux Server.

Bây giờ chúng ta có thể đăng nhập mà không cần mật khẩu, đơn giản chỉ cần sử dụng lệnh sau (nhớ thay đổi IP trong lệnh dưới bằng IP của Linux server của bạn):
Đầu tiên hệ thống sẽ yêu cầu mật khẩu của private key trên máy bạn (nếu bạn đặt mật khẩu), nhưng sau đó sẽ sử dụng cặp key để xác thực.

Đổi cổng SSH – giảm quét tự động
Theo mặc định dịch vụ SSH của Linux Server dùng cổng 22, đây là mục tiêu bị quét tự động nhiều nhất trên Internet. Chúng ta đổi sang một cổng khác, ví dụ cổng 2222:
Trong file cấu hình SSH, sửa dòng Port:
Xác nhận lại cấu hình:

Sau đó, thử login từ client với cổng 2222:
Việc này không hẳn khiến server “bất khả xâm phạm” , nhưng sẽ giảm được đến một mức VD trên 90% các bot quét tự động trên Internet – do hầu hết chúng chỉ dò cổng 22.

Tắt hoàn toàn đăng nhập bằng mật khẩu
Sau khi SSH key đã được thiết lập xong như trong bước trên, nên tắt hẳn việc đăng nhập bằng mật khẩu. Mở lại file SSH config:
Tìm dòng cấu hình PasswordAuthentication và sửa như sau (nếu không thấy dòng này hãy thêm vào dòng như bên dưới):

Sau đó khởi động lại SSH để dịch vụ nhận cấu hình mới:
Từ giờ chỉ các key hợp lệ mới vào được server, cơ bản cắt đứt cách tấn công brute-force thông qua mật khẩu.
2. Nguyên tắc ít đặc quyền – Chỉ cấp quyền vừa đủ
Hệ thống chỉ cho phép người dùng có quyền cần thiết nhất, ít nhất có thể. Mỗi người chỉ được phép làm đúng việc mình cần. Để làm điều này, ta chỉnh sửa cấu hình file sudoers qua visudo:
Ví dụ, nếu có user chỉ cần quyền khởi động lại Apache, chúng ta giới hạn cho user này chỉ dùng đúng lệnh đó:
Giải thích ví dụ myuser ALL=(ALL) /usr/bin/systemctl restart apache2:
-
myuser: Là user được cấp quyền
-
ALL: Được áp dụng trên mọi host
-
(ALL): user này được chạy lệnh với quyền root
-
/usr/bin/systemctl restart apache2: chỉ lệnh duy nhất mà user được phép chạy với quyền root.

Sau khi lưu lại cấu hình xong, hãy test thử xem có giống như cấu hình mong muốn hay không: Đăng nhập với myuser, chạy lệnh cho phép:
Lệnh sẽ chạy thành công do lệnh này chúng ta đã cấu hình cấp phép. Nếu user thử chạy các lệnh khác VD như:
Chúng ta sẽ thấy kết quả báo bị cấm chạy lệnh và báo lỗi – chứng tỏ chúng ta đã phân quyền chính xác.

❌ Lưu ý nguy hiểm không nên áp dụng cấu hình này: không bao giờ viết cấu hình myuser ALL=(ALL) ALL trong sudoers! Câu lệnh đó biến user thành “root trá hình”, cực kỳ nguy hiểm vì cấp cho user mọi quyền trong Linux Server.
Ngoài ra, theo mặc định, Linux không ghi lại đầy đủ mọi lệnh sudo mà user chạy, khiến việc:
-
Điều tra sự cố
-
Kiểm tra an toàn hệ thống
-
Truy vết xem ai đã chạy các lệnh nguy hiểm ảnh hưởng xấu đến hệ thống
-
Phân tích vấn đề production gặp khó khăn.
Vì thế, hãy bật việc ghi log sudo trong môi trường Production Server:

Bất kỳ lệnh nào chạy qua quyềnsudo sẽ được lưu vào file /var/log/sudo.log. Để kiểm tra, bạn có thể chạy thử một lệnh sudo:
Nội dung file log sẽ có dòng tương tự thể hiện việc ghi tất cả các logs:
Bây giờ các bạn có thể thấy chúng ta đã có nhật ký log rõ ràng, để biết ai chạy lệnh gì, vào lúc nào.
3. Thường xuyên cập nhật hệ thống
Rất nhiều server bị hacker xâm nhập chỉ vì quá lâu không cập nhật hệ thống Servers. Lỗi bảo mật của phần mềm thường được nhà phát triển vá khi cập nhật, nên chúng ta phải thường xuyên phải chạy:
Mình có thể diễn giải với bạn theo kinh nghiệm hơn 20 năm của mình: Nếu không cập nhật Server, chúng ta như không có được một tuyến phòng thủ mới nhất. Nhiều hệ thống bị tổn hại bởi virus hay hackers thực ra rất đơn giản là chỉ vì quên quét và cập nhật các bản vá lỗi. Hãy coi việc cập nhật định kỳ cho hệ thống như “tiêm vắc-xin” cho server, tăng cường các bản vá lỗi phần mềm giúp cho server có “hệ miễn dịch tốt hơn”.
4. Quản lý tài khoản người dùng – Tránh “tài khoản ma”
Trên các server tồn tại chạy một thời gian khá dài, thường có thể có nhiều tài khoản gồm các users không còn sử dụng hoặc bị lãng quên. Mỗi tài khoản dư thừa là một “cánh cửa phụ” có thể bị hacker lợi dụng. Ví dụ, khi người cũ nghỉ việc hay users của khách hàng cũ của công ty mà admin quên xóa tài khoản của họ.
Giải pháp: định kỳ kiểm tra danh sách các users và xóa hoặc khóa các tài khoản này. Ví dụ, liệt kê tất cả user với lệnh:
Nếu thấy user cũ không dùng nữa, xóa chúng:
và khóa các tài khoản dịch vụ (service accounts) không cần có quyền đăng nhập vào server:
Một lời cảnh báo: “Tài khoản bị lãng quên có thể trở thành cánh cửa hậu cho hacker.” Trong thực tế có nhiều vụ tai nạn như do vô ý xóa các files quan trọng, hay tắt dịch vụ sai do quyền sudo quá rộng đều xuất phát từ việc quá nhiều tài khoản và quyền không có kiểm soát. Hãy coi việc quản lý tài khoản như dọn dẹp vệ sinh hệ thống, luôn loại bỏ “tài khoản ma” để giảm rủi ro.
5. Tắt các dịch vụ không dùng
Một nguyên nhân rất phổ biến nữa khiến server bị tấn công là chạy quá nhiều dịch vụ dư thừa. Mỗi dịch vụ đang chạy là một cổng mở ra cho hacker vào. Vì vậy, hãy check danh sách các dịch vụ đang chạy và tắt những dịch vụ không cần thiết, dư thừa:
Sau đó, nếu thấy dịch vụ không dùng, tắt nó ngay. Ví dụ, server không cần các dịch vụ như avahi-daemon hay cups, chúng ta chạy lệnh sau để disable:
Lưu ý: Tắt dịch vụ không dùng sẽ:
-
Giảm bề mặt tấn công (attack surface) – hacker có ít ngách tấn công hơn
-
Tiết kiệm tài nguyên máy chủ
-
Giúp hệ thống ổn định hơn, và dễ quản lý
-
Là best practice trong hardening Linux
Tóm lại, bất cứ dịch vụ nào “không rõ đang làm gì, chưa dùng đến” thì chúng ta cần đóng gói lại cho nó gọn gàng cho hệ thống của chúng ta chạy mượt hơn.
6. Firewall – Chỉ mở các cổng cần thiết
Luật an toàn mạng cổ điển: Chỉ cho phép các cổng dịch vụ thực sự cần thiết được mở. Ví dụ, nếu server của bạn chỉ phục vụ trên các cổng SSH, HTTP và HTTPS, hãy thiết lập firewall (ví dụ dùng UFW) như sau:


Lưu ý, mặc định UFW cho phép mọi kết nối từ bên trong server ra bên ngoài (outgoing) cho tiện. Nhưng trong môi trường production, bạn nên hạn chế hơn: Đó là chặn hết outgoing tức là không cho server truy cập được ra bên ngoài và chỉ mở khi cần. Ví dụ:
Như vậy, server chỉ có thể chủ động kết nối ra ngoài đến những dịch vụ thiết yếu, giảm nguy cơ bị mã độc hay attacker sử dụng băng thông vô tội vạ.
Lưu ý: Nhớ kiểm tra kỹ rule: tuyệt đối phải ufw allow ssh rồi mới ufw enable, nếu không bạn sẽ bị khóa luôn cả đường ssh vào server.

7. Chống tấn công dò mật khẩu (Brute-force)
Nếu hệ thống của bạn còn cho phép đăng nhập bằng mật khẩu, nhất thiết phải có cơ chế chống đoán mật khẩu liên tục. Ở đây mình áp dụng PAM module để khóa user sau một vài lần nhập sai mật khẩu. Các bước làm như sau:
-
Bắt buộc phải chuyển sang quyền root (không dùng sudo):
-
Backup file cấu hình PAM mặc định:
-
Tạo file cấu hình mới:
-
Thêm vào nội dung sau (hệ thống sẽ cài đặt module
pam_faillock):Giải thích ngắn: Sau 5 lần nhập sai liên tiếp, user sẽ bị khóa 900 giây (15 phút) hoặc đến khi admin giải khoá.

-
Lưu lại và chạy lệnh reset để PAM tạo thư mục theo dõi việc users đăng nhập vào hệ thống:
-
Để test thử, mở file SSH config một lần nữa:
Tìm dòng
PasswordAuthentication yesvà thêm#ở đầu (đã comment) để tái kích hoạt cho phép đăng nhập ssh bằng password để kiểm tra. Sau đó khởi động lại SSH: -
Bây giờ, thử SSH vào server với user nào đó, gõ sai mật khẩu 5 lần. Bạn sẽ thấy user bị khóa và không thể đăng nhập được nữa.
-
Trên máy chủ, kiểm tra:
Lệnh trên sẽ hiển thị thông tin user bị khóa.
-
Nếu muốn mở lại quyền đăng nhập cho user, chạy:
User
myusersẽ được bỏ khóa. Kiểm tra lại bằng cách đăng nhập thử với mật khẩu đúng.
Qua quy trình trên, dù hacker cố brute-force dò mật khẩu, sau vài lần sai liên tiếp, họ sẽ bị tự động “bốc hơi” và không thể tiếp tục.

8. Yêu cầu mật khẩu mạnh
Người dùng thường đặt mật khẩu dễ đoán, dễ nhớ (như 123456, password). Để phòng kẻ gian, ta cần ép buộc người dùng phải đặt mật khẩu mạnh. Mở file cấu hình PAM cho việc cấu hình mật khẩu:
Tìm dòng có pam_pwquality.so và sửa thành:
Giải thích các tham số chính cho việc đặt mật khẩu của users :
-
minlen=14: ít nhất phải có 14 ký tự -
ucredit=-1: ít nhất 1 chữ hoa -
lcredit=-1: ít nhất 1 chữ thường -
dcredit=-2: ít nhất 2 chữ số -
ocredit=-1: ít nhất 1 ký tự đặc biệt -
retry=3: nhập sai mật khẩu có thể thử lại 3 lần trước khi hủy.

Sau đó, hãy kiểm tra. Ví dụ thử test đổi mật khẩu cho một user nào đó:
Và thử các mật khẩu dưới đây:
-
password123→ ❌ (quá ngắn, chỉ chữ thường và số) -
Password1234!→ ❌ (bị báo thiếu độ dài) -
Abcdef1234!→ ❌ (vẫn chưa đủ ký tự, chỉ 11 ký tự) -
StrongPass!2024→ ✅ (thỏa mãn trên 14 ký tự, có chữ hoa, chữ thường, chữ số và ký tự đặc biệt)
Quá trình này cho thấy nếu không có việc cấu hình ràng buộc kỹ thuật, người dùng hay tái sử dụng mật khẩu cũ, đặt mật khẩu yếu. Cuối cùng, chính hệ thống phải bắt người dùng tuân thủ – đừng tin vào việc tự nhận thức bảo mật của người dùng!

9. Quản lý chu kỳ thay đổi mật khẩu
Trong nhiều môi trường doanh nghiệp, việc quản lý tuổi thọ mật khẩu thường bị lơ là, nhưng lại rất quan trọng. Ví dụ, nếu ai đó biết mật khẩu cũ, họ có thể chờ thời điểm để truy cập sau này. Vì thế, chúng ta cần cấu hình để bắt buộc phải thay đổi theo định kỳ. Mở file /etc/login.defs:
Tìm và chỉnh sửa các giá trị:
Ý nghĩa:
-
PASS_MAX_DAYS: mật khẩu sẽ hết hạn sau 60 ngày kể từ lần thay đổi cuối cùng -
PASS_WARN_AGE: hệ thống sẽ cảnh báo 7 ngày trước khi hết hạn
Ví dụ minh họa:
-
Ngày 1: user đặt mật khẩu mới.
-
Từ ngày 53–59: khi login vào, hệ thống nhắc user cần thay đổi mật khẩu.
-
Đến ngày 60: nếu user chưa đổi mật khẩu, hệ thống sẽ bị buộc phải thay và không thể đăng nhập thêm vào hệ thống được nữa nếu bỏ qua.
Mục tiêu là không để người dùng dùng một “mật khẩu cố định” mãi mãi.

Sau khi cập nhật cấu hình, bạn tạo user thử nghiệm:
Lệnh chage -l test sẽ hiển thị chính sách mật khẩu áp dụng, và bạn sẽ thấy password của user test sẽ hết hạn sau 60 ngày, với cảnh báo bắt đầu từ 7 ngày trước. Như vậy, mọi account mới đều được áp dụng quy tắc bắt buộc phải đổi mật khẩu theo định kỳ.

10. Ghi log và tập trung log – Đôi mắt của hệ thống
Cuối cùng nhưng không kém phần quan trọng: Cần phải ghi log đầy đủ và tập trung. Việc không có log thì giống như xem phim mà tắt tiếng – cực kì thiếu thông tin và là lỗ hổng lớn. Linux tự động lưu hầu hết các sự kiện quan trọng trong thư mục /var/log. Ví dụ, file /var/log/auth.log ghi lại tất cả sự kiện liên quan đến xác thực – từ đăng nhập thành công/thất bại đến việc dùng sudo. Hãy thường xuyên theo dõi file này để phát hiện sớm kẻ lạ:
Ngoài ra còn có /var/log/syslog (ghi chung nhiều thông tin), /var/log/kern.log (thông tin kernel), /var/log/dmesg… mỗi file như một cuốn “phim tài liệu” ghi chép mọi hoạt động. Bạn cũng có thể dùng công cụ như logwatch hoặc goaccess để tổng hợp và gửi email đến cho bạn hàng ngày.
Một bước nâng cao là chuyển log về một máy chủ log tập trung. Đừng để log chỉ nằm trên server đang bảo vệ: nếu server đó hỏng vật lý chẳng hạn, thì log cũng bị mất đi. Cấu hình rsyslog hoặc systemd-journald để đẩy log về một server chuyên dụng.
Tóm lại, log giống như “phim giám sát” của hệ thống. Hãy đọc kỹ từng log, đặt cảnh báo khi phát hiện bất thường (ví dụ nhiều lần đăng nhập thất bại liên tiếp, truy cập từ IP lạ, hay việc thay đổi cấu hình …), và xử lý kịp thời. Bạn hãy như một thám tử giỏi, bạn sẽ phát hiện ra kẻ đột nhập trước khi chúng kịp gây hại.

Kết luận
Bảo mật không đến từ một lệnh đơn lẻ nào; nó đến từ một tư duy đúng đắn, cấu hình chính xác và vận hành kỷ luật. Hãy tuân thủ nghiêm ngặt bắt đầu với 10 nguyên tắc trên, vì mỗi một nguyên tắc như trong bài viết này ít nhất cũng là một lớp phòng thủ cho server của bạn. Môi trường production không cho phép sơ hở – chỉ cần một lỗ hổng cũng đủ để tạo ra các hậu quả lớn. Nhớ rằng việc củng cố an toàn hệ thống là cả một quá trình liên tục, không chỉ dừng lại sau một ngày làm việc.
Chúc các bạn xây dựng được hệ thống Linux an toàn và mạnh mẽ! Vì sự thành công của bạn!
#LinuxSecurity #UbuntuServer #Sysadmin #DevOps #AnToanHeThong



