«Trên Linux không cần diệt virus» là một ý kiến phổ biến, và ở dạng nguyên bản thì nó đúng: virus lây nhiễm tệp hệ thống của Linux gần như không tồn tại. ClamAV trên máy chủ có một nhiệm vụ khác, và nó được phát biểu thế này: hãy tìm cái đã được tải lên qua trang web của bạn. Trên hết là web shell.

Chúng ta đang tìm chính xác cái gì

Web shell là một tệp PHP nhỏ cho phép chạy lệnh qua trình duyệt. Nó đến qua biểu mẫu tải lên, qua một plugin có lỗ hổng hoặc qua mật khẩu quản trị bị dò ra, rồi ngồi giữa đám ảnh trong thư mục tải lên và sống ở đó hàng tháng trời. Cả tường lửa lẫn Fail2ban đều không thấy nó: các yêu cầu tới nó trông như những yêu cầu bình thường của trang web.

Ngoài ra ClamAV còn tìm thấy:

  • các tệp độc hại do người dùng tải lên và được phục vụ tiếp từ máy chủ của bạn — thư của nhà cung cấp thường là về chuyện này;
  • tệp đính kèm thư, nếu máy chủ xử lý thư;
  • mã độc Windows trong kho tệp — bản thân máy chủ chẳng bận tâm, nhưng nhân viên tải tệp đó về sẽ lãnh đủ.

Về giới hạn thì nói ngay: ClamAV không ngăn được việc bị đột nhập và tự nó cũng không phát hiện ra việc đó. Nó phát hiện dấu vết. Một cửa hậu tinh vi được nối vào cuối một tệp giao diện có sẵn sẽ lọt qua trình quét chữ ký — đó chính là việc của phần theo dõi tính toàn vẹn tệp.

Cài đặt và một cấu hình duy nhất có ý nghĩa

sudo apt install clamav clamav-daemon
sudo systemctl status clamav-freshclam

Lệnh thứ hai quan trọng hơn lệnh đầu. freshclam là dịch vụ cập nhật chữ ký, và nếu nó không chạy thì ClamAV trở nên vô dụng trong khi vẫn tiếp tục báo cáo các lần quét thành công. Hãy kiểm tra tuổi của cơ sở dữ liệu thế này:

sudo ls -l /var/lib/clamav/*.c?d
sudo freshclam

Cơ sở dữ liệu cũ hơn một tuần nghĩa là cơ chế đã hỏng. Nguyên nhân thường gặp là các kết nối đi ra bị chặn, hoặc freshclam đã được chạy bằng tay dưới quyền root, sau đó dịch vụ không ghi được vào chính tệp của mình vì quyền.

Bộ nhớ: daemon hay chạy một lần

Có hai cách dùng, và lựa chọn nên có ý thức.

clamd là daemon chạy thường trực và giữ cơ sở dữ liệu trong bộ nhớ. Nó trả lời nhanh nhưng chiếm khoảng một gigabyte RAM. Trên VPS có một hai gigabyte thì điều đó không chấp nhận được: daemon sẽ đẩy cơ sở dữ liệu và PHP-FPM ra ngoài, còn máy chủ bắt đầu bò chậm mà không có lý do nhìn thấy được. Chẩn đoán bằng free -m và bằng swap đang hoạt động.

Lựa chọn thay thế là clamscan theo lịch. Nó chậm hơn (nạp cơ sở dữ liệu mỗi lần chạy, khoảng một phút) nhưng chỉ làm việc trong lúc quét:

sudo clamscan -r -i --exclude-dir='^/(proc|sys|dev|run)' /var/www

Cờ -i chỉ in ra những gì tìm thấy; nếu không kết quả sẽ dài hàng trăm nghìn dòng.

Hãy quét thư mục, không phải cả đĩa

Quét toàn đĩa trên một máy chủ yếu mất hàng giờ và tạo tải, vì thế nó bị xếp vào ban đêm rồi bị tắt hẳn. Thực tế hơn là quét cái thực sự thay đổi từ bên ngoài:

0 3 * * * ionice -c3 nice -n19 clamscan -r -i --move=/var/quarantine /var/www/uploads

Trong dòng đó có ba thứ quan trọng. ionicenice loại bỏ ảnh hưởng tới trang web. Dùng --move chứ không phải --remove — tệp đi vào khu cách ly thay vì bị xóa: dương tính giả vẫn xảy ra, và một tệp của khách hàng bị xóa nhầm thì chẳng khôi phục được từ đâu. Còn thư mục để quét là nơi tệp được tải lên, chứ không phải gốc.

Chữ ký cho web shell

Cơ sở dữ liệu chuẩn của ClamAV yếu với cửa hậu PHP — chúng chủ yếu nhắm vào lưu lượng thư. Linux Malware Detect (maldet) làm tốt hơn hẳn ở đây: nó có bộ chữ ký riêng dựng đúng quanh web shell, và nó quét bằng engine của ClamAV nếu ClamAV đã được cài. Sự kết hợp thường dùng là: ClamAV làm engine và cơ sở dữ liệu cập nhật được, maldet làm nguồn chữ ký chuyên biệt.

Làm gì với thứ tìm được

Một web shell tìm thấy không phải là điểm kết thúc của cuộc điều tra mà là điểm bắt đầu. Một tệp trong thư mục tải lên nghĩa là ai đó đã ghi được vào đó, và việc xóa tệp không loại bỏ khả năng ấy.

  1. Đừng xóa nó ngay — hãy giữ một bản sao và ghi lại thời điểm tệp được sửa.
  2. Dùng thời điểm đó tìm trong nhật ký máy chủ web xem yêu cầu nào đã đặt nó vào đó. Đó chính là lỗ hổng.
  3. Hãy tìm những cái bên cạnh: cửa hậu gần như không bao giờ được để lại chỉ một bản.
  4. Kiểm tra xem trong cùng khoảng thời gian còn gì trên đĩa thay đổi, và có tác vụ cron cùng khóa SSH mới nào xuất hiện không.

Nói riêng về dương tính giả. Các thư viện mẫu và JavaScript đã rút gọn đôi khi khớp với chữ ký. Vì thế mới dùng khu cách ly thay vì xóa, và vì thế mới có lời khuyên đừng gắn vào mọi bộ chữ ký của bên thứ ba mà bạn tìm được: niềm tin vào một báo cáo có một nửa số dòng là tiếng ồn sẽ mất trong vòng một tuần, và người ta thôi đọc nó.

Giá trị thực tiễn của một trình quét nằm ở chỗ kết quả của nó đập vào mắt: lần quét gần nhất chạy khi nào, cơ sở dữ liệu cũ đến đâu, đã tìm thấy gì. Đó là một dòng, nhưng việc thiếu nó biến một phần mềm diệt virus đã cài thành một dấu tích trong ô kiểm. Dòng đó trông ra sao — xem ở trang demo bên dưới.