Cấu hình HTTP Security Headers: ‘Áo giáp’ cho Nginx và Apache đạt chuẩn A+

Security tutorial - IT technology blog
Security tutorial - IT technology blog

Tại sao chỉ SSL thôi là chưa đủ?

Nhiều người mặc định cứ hiện ổ khóa xanh SSL là website đã an toàn 100%. Thực tế, SSL chỉ mã hóa đường truyền giữa người dùng và máy chủ. Nó hoàn toàn bó tay trước việc hacker nhúng trang web của bạn vào một khung hình (iframe) lừa đảo hoặc tiêm mã độc Javascript từ bên thứ ba.

Bản thân mình từng thức trắng đêm xử lý một vụ tấn công brute-force. Sau bài học đó, mình nhận ra bảo mật phải là một hệ thống đa lớp. HTTP Security Headers chính là những lớp bảo vệ ‘nhỏ nhưng có võ’ đó. Chúng là bộ chỉ dẫn mà máy chủ gửi kèm để ra lệnh cho trình duyệt: ‘Đừng chạy script bậy bạ’ hoặc ‘Chỉ được phép kết nối qua HTTPS thôi’.

Thiếu các header này, website của bạn cực kỳ mong manh trước Clickjacking hay Cross-Site Scripting (XSS). Theo thống kê, XSS chiếm tới gần 40% các vụ tấn công ứng dụng web. Thiết lập chúng chỉ mất 5 phút nhưng giá trị mang lại là cực kỳ lớn.

Cài đặt và chuẩn bị

Trước khi bắt tay vào cấu hình, hãy xác định bạn đang dùng Nginx hay Apache. Đây là hai cái tên thống trị thế giới web server hiện nay.

Với Nginx

Nginx xử lý các header rất nhẹ nhàng qua module ngx_http_headers_module. Bạn chỉ cần quyền sudo để chỉnh sửa file cấu hình tại /etc/nginx/sites-available/.

Với Apache

Trên Apache, hãy chắc chắn bạn đã kích hoạt module headers. Nếu quên bước này, server sẽ báo lỗi 500 ngay lập tức. Hãy chạy lệnh sau trên terminal:

sudo a2enmod headers
sudo systemctl restart apache2

6 Security Headers ‘vàng’ bạn cần cài đặt ngay

Dưới đây là danh sách những ‘vệ sĩ’ mình luôn cài cho mọi dự án, từ landing page đơn giản đến hệ thống thương mại điện tử phức tạp.

1. HTTP Strict Transport Security (HSTS)

Header này ép trình duyệt chỉ được dùng HTTPS. Ngay cả khi người dùng gõ http://, trình duyệt cũng tự động chuyển sang https:// trước khi gửi yêu cầu đi. Nó loại bỏ hoàn toàn các cuộc tấn công hạ cấp (downgrade attacks).

  • Nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
  • Apache: Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

Mẹo nhỏ: max-age=31536000 tương đương 1 năm. Hãy chỉ thêm preload khi bạn chắc chắn SSL của mình luôn hoạt động ổn định.

2. X-Frame-Options

Header này là khắc tinh của Clickjacking. Nó ra lệnh cho trình duyệt: ‘Cấm tuyệt đối việc nhúng trang web này vào iframe của kẻ lạ’.

  • Nginx: add_header X-Frame-Options "SAMEORIGIN" always;
  • Apache: Header always set X-Frame-Options "SAMEORIGIN"

Sử dụng SAMEORIGIN giúp bạn vẫn có thể nhúng iframe của chính mình trên cùng một domain.

3. X-Content-Type-Options

Nhiều trình duyệt có tính năng ‘đoán’ định dạng file (MIME sniffing). Hacker có thể đánh lừa bằng cách tải lên một file ảnh chứa mã độc Javascript. Header nosniff sẽ ép trình duyệt tuân thủ đúng định dạng mà máy chủ khai báo.

  • Nginx: add_header X-Content-Type-Options "nosniff" always;
  • Apache: Header always set X-Content-Type-Options "nosniff"

4. Referrer-Policy

Khi người dùng bấm vào link từ web bạn sang web khác, trình duyệt thường gửi kèm URL gốc. Điều này có thể làm lộ thông tin nhạy cảm. Mình thường dùng strict-origin-when-cross-origin để vừa bảo mật, vừa không làm hỏng dữ liệu SEO.

  • Nginx: add_header Referrer-Policy "strict-origin-when-cross-origin" always;
  • Apache: Header always set Referrer-Policy "strict-origin-when-cross-origin"

5. Permissions-Policy

Đây là header giúp bạn kiểm soát quyền truy cập phần cứng. Nếu blog của bạn chỉ để đọc chữ, hãy tắt hết Camera hay Microphone để tránh bị lợi dụng ngầm.

# Ví dụ trên Nginx để tắt Camera và Mic
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

6. Content Security Policy (CSP) – ‘Lá chắn thép’

CSP là header mạnh nhất nhưng cũng khó cấu hình nhất. Nó quy định cụ thể những nguồn (domain) nào được phép tải script, ảnh, hay CSS. Một CSP chặt chẽ có thể chặn đứng 99% các cuộc tấn công XSS.

Dưới đây là một bộ khung CSP cơ bản nhưng an toàn để bạn bắt đầu:

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.google-analytics.com; img-src 'self' data:; style-src 'self' 'unsafe-inline';" always;

File cấu hình mẫu cho Nginx

Để dễ áp dụng, bạn có thể sao chép đoạn mã sau vào block server trong Nginx:

server {
    listen 443 ssl;
    server_name itfromzero.com;

    # Bảo mật Headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
}

Kiểm tra thành quả

Cấu hình xong rồi, làm sao để biết đã chuẩn chưa? Hãy sử dụng các công cụ sau để ‘chấm điểm’:

  1. SecurityHeaders.com: Chỉ cần nhập domain, công cụ sẽ quét và chấm điểm. Mục tiêu của bạn là điểm A hoặc A+.
  2. DevTools (F12): Mở tab Network, chọn một request bất kỳ và xem phần Headers. Nếu thấy các dòng vừa cấu hình hiện ra là bạn đã thành công.

Việc bảo mật không bao giờ có điểm dừng. Tuy nhiên, với 5 phút cấu hình các header này, website của bạn đã an toàn hơn hẳn so với phần lớn các trang web hiện nay. Đừng để ‘mất bò mới lo làm chuồng’. Chúc các bạn cấu hình thành công!

Share: