19/09/2018, 09:50

Làm thế nào để thiết lập ModSecurity với Apache trên Ubuntu 14.04 và Debian 8

Giới thiệu ModSecurity là một tường lửa ứng dụng web miễn phí (WAF) hoạt động với Apache, Nginx và IIS. Nó hỗ trợ một công cụ quy tắc linh hoạt để thực hiện các thao tác đơn giản và phức tạp và đi kèm với một bộ quy tắc cốt lõi (CRS) có các quy tắc cho SQL injection, cross scripting, Trojans, các ...

Giới thiệu

ModSecurity là một tường lửa ứng dụng web miễn phí (WAF) hoạt động với Apache, Nginx và IIS. Nó hỗ trợ một công cụ quy tắc linh hoạt để thực hiện các thao tác đơn giản và phức tạp và đi kèm với một bộ quy tắc cốt lõi (CRS) có các quy tắc cho SQL injection, cross scripting, Trojans, các tác nhân người dùng xấu, tấn công session và nhiều khai thác khác. Đối với Apache, nó được nạp như một module bổ sung giúp dễ dàng cài đặt và cấu hình.

Điều kiện tiên quyết

Để làm theo hướng dẫn này, bạn sẽ cần:

  • Một 14.04 Ubuntu hoặc Debian 8 giọt.

  • Tài khoản người dùng chuẩn có đặc quyền sudo, bạn có thể thiết lập bằng cách làm theo hướng dẫn thiết lập máy chủ ban đầu cho Ubuntu 14.04 hoặc là Debian 8.

  • Một LAMP stack, mà bạn có thể cài đặt bằng cách làm theo hướng dẫn cho Ubuntu 14.04 hoặc là Debian 8.

Bước 1 - Cài đặt ModSecurity

Trong bước này, chúng ta sẽ cài đặt ModSecurity.

Đầu tiên, cập nhật các tệp chỉ mục của gói.

sudo apt-get update

Sau đó, cài đặt ModSecurity.

sudo apt-get install libapache2-mod-security2 -y

Bạn có thể xác minh rằng mô-đun ModSecurity đã được nạp bằng lệnh sau đây.

sudo apachectl -M | grep --color security2

Nếu đầu ra đọc security2_module (shared), điều này cho biết rằng mô-đun đã được tải.

Cài đặt của ModSecurity bao gồm tệp cấu hình được đề xuất phải được đổi tên.

sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

Cuối cùng, tải lại Apache.

sudo service apache2 reload

Một tệp nhật ký mới cho ModSecurity sẽ được tạo trong thư mục nhật ký Apache tại /var/log/apache2/modsec_audit.log.

Bước 2 - Cấu hình ModSecurity

Ra khỏi hộp, ModSecurity không làm bất cứ điều gì bởi vì nó cần các quy tắc để làm việc. Trong bước này, trước tiên chúng tôi sẽ bật một số chỉ thị cấu hình.

Để tìm và thay thế các chỉ thị cấu hình trong bước này, chúng tôi sẽ sử dụng sed, trình chỉnh sửa luồng. Bạn có thể đọc sed loạt bài hướng dẫn để tìm hiểu thêm về công cụ.

Chỉ thị cơ bản để bật

Tệp cấu hình ModSecurity mặc định được đặt thành DetectionOnly, ghi nhật ký các yêu cầu theo quy tắc phù hợp và không chặn bất kỳ thứ gì. Điều này có thể được thay đổi bằng cách chỉnh sửa modsecurity.conf tập tin và sửa đổi SecRuleEngine chỉ thị. Nếu bạn đang cố gắng này trên một máy chủ sản xuất, thay đổi chỉ thị này chỉ sau khi kiểm tra tất cả các quy tắc của bạn.

sudo sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /etc/modsecurity/modsecurity.conf

Các SecResponseBodyAccess chỉ thị cấu hình cho dù cơ quan phản ứng được đệm (tức là đọc bởi ModSecurity). Điều này chỉ cần thiết nếu phát hiện và bảo vệ rò rỉ dữ liệu được yêu cầu. Vì vậy, để nó trên sẽ sử dụng hết tài nguyên Droplet và cũng tăng kích thước logfile, vì vậy chúng tôi sẽ tắt nó đi.

sudo sed -i "s/SecResponseBodyAccess On/SecResponseBodyAccess Off/" /etc/modsecurity/modsecurity.conf

Chỉ thị tùy chọn để sửa đổi

Có các chỉ thị khác mà bạn có thể muốn tùy chỉnh bằng cách chỉnh sửa /etc/modsecurity/modsecurity.conf. Các SecRequestBodyLimit và SecRequestBodyNoFilesLimit chỉ thị giới hạn dữ liệu tối đa có thể được đăng lên ứng dụng web của bạn.

Đặc biệt, SecRequestBodyLimit chỉ thị chỉ định kích thước dữ liệu POST tối đa. Nếu bất cứ điều gì lớn hơn được gửi bởi một khách hàng, máy chủ sẽ phản hồi với một 413 Yêu cầu thực thể quá lớn lỗi. Nếu ứng dụng web của bạn không có bất kỳ tệp tải lên nào, giá trị này có thể được để nguyên. Giá trị được cấu hình sẵn được chỉ định trong tệp cấu hình là 13107200 byte (12.5MB). Nếu bạn muốn thay đổi giá trị này, hãy tìm dòng sau modsecurity.conf:

Optional `modsecurity.conf` directive change

SecRequestBodyLimit 13107200

Tương tự, SecRequestBodyNoFilesLimit giới hạn kích thước dữ liệu POST trừ các tệp tải lên. Giá trị này nên được đặt càng thấp càng tốt để giảm tính nhạy cảm đối với tấn công từ chối dịch vụ (DoS) khi ai đó đang gửi các cơ quan yêu cầu có kích thước rất lớn. Giá trị được định cấu hình trước trong tệp cấu hình là 131072 byte (128KB). Nếu bạn muốn thay đổi giá trị này, hãy tìm dòng sau modsecurity.conf:

Optional `modsecurity.conf` directive change

SecRequestBodyNoFilesLimit 131072

Một chỉ thị ảnh hưởng đến hiệu suất máy chủ là SecRequestBodyInMemoryLimit. Chỉ thị này khá tự giải thích; nó chỉ định bao nhiêu dữ liệu "yêu cầu cơ thể" (dữ liệu đã đăng) nên được giữ trong bộ nhớ (RAM), bất cứ thứ gì sẽ được đặt trong đĩa cứng (giống như hoán đổi). Bởi vì Droplets sử dụng SSD, đây không phải là vấn đề lớn. Tuy nhiên, điều này có thể được thay đổi nếu bạn có RAM để rảnh. Giá trị được định cấu hình trước cho chỉ thị này là 128KB. Nếu bạn muốn thay đổi giá trị này, hãy tìm dòng sau modsecurity.conf:

Optional `modsecurity.conf` directive change

SecRequestBodyInMemoryLimit 131072

Bước 3 - Thử nghiệm một SQL Injection

Trước khi định cấu hình một số quy tắc, chúng tôi sẽ tạo một tập lệnh PHP dễ bị tấn công bởi SQL injection để kiểm tra bảo vệ của ModSecurity.

Lưu ý: đây là tập lệnh đăng nhập PHP cơ bản không có xử lý phiên hoặc vệ sinh biểu mẫu. Nó chỉ được sử dụng như một ví dụ để kiểm tra các quy tắc SQL injection và ModSecurity. Nó sẽ bị xóa trước khi kết thúc hướng dẫn.

Đầu tiên, truy cập vào dấu nhắc MySQL.

mysql -u root -p

Ở đây, tạo một cơ sở dữ liệu MySQL có tên mẫu vật và kết nối với nó.

create database sample;

connect sample;

Sau đó tạo một bảng chứa một số thông tin đăng nhập - tên người dùng sammy và mật khẩu mật khẩu.

create table users(username VARCHAR(100),password VARCHAR(100));

insert into users values('sammy','password');

Cuối cùng, thoát khỏi dấu nhắc MySQL.

quit;

Tiếp theo, tạo tập lệnh đăng nhập trong root tài liệu của Apache.

sudo nano /var/www/html/login.php

Dán tập lệnh PHP sau vào tệp. Hãy chắc chắn để thay đổi mật khẩu MySQL trong kịch bản dưới đây để một trong những bạn thiết lập trước đó để kịch bản có thể kết nối với cơ sở dữ liệu:

/var/www/html/login.php

<html>
<body>
<?php
    if(isset($_POST['login']))
    {
        $username = $_POST['username'];
        $password = $_POST['password'];
        $con = mysqli_connect('localhost','root','your_mysql_password','sample');
        $result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'");
        if(mysqli_num_rows($result) == 0)
            echo 'Invalid username or password';
        else
            echo '<h1>Logged in</h1><p>This is text that should only be displayed when logged in with valid credentials.</p>';
    }
    else
    {
?>
        <form action="" method="post">
            Username: <input type="text" name="username"/><br />
            Password: <input type="password" name="password"/><br />
            <input type="submit" name="login" value="Login"/>
        </form>
<?php
    }
?>
</body>
</html>

Tập lệnh này sẽ hiển thị biểu mẫu đăng nhập. Mở trình duyệt của bạn và điều hướng đến http://your_server_ip/login.php để xem nó. Nếu bạn nhập đúng cặp thông tin xác thực, ví dụ: sammy trong Tên người dùng trường và mật khẩu trong Mật khẩu trường, bạn sẽ thấy thông báo Đây là văn bản chỉ được hiển thị khi đăng nhập bằng thông tin đăng nhập hợp lệ. Nếu bạn điều hướng trở lại màn hình đăng nhập và sử dụng thông tin đăng nhập không chính xác, bạn sẽ thấy thông báo Sai username hoặc password.

Công việc tiếp theo là thử một SQL injection để bỏ qua trang đăng nhập. Nhập thông tin sau cho trường tên người dùng.

SQL injection username

' or true -- 

Lưu ý rằng sẽ có một khoảng trống sau -- để tiêm này hoạt động. Để trống trường mật khẩu và nhấn nút đăng nhập. Tập lệnh hiển thị thông báo dành cho người dùng được xác thực! Trong bước tiếp theo, chúng tôi sẽ ngăn chặn điều này.

Bước 4 - Thiết lập quy tắc

Trong bước này, chúng tôi sẽ thiết lập một số quy tắc ModSecurity.

Bật CRS

Để dễ dàng hơn, có rất nhiều quy tắc đã được cài đặt cùng với ModSecurity. Chúng được gọi là CRS (Core Rule Set) và được đặt trong /usr/share/modsecurity-crs danh mục. Để tải các quy tắc này, chúng ta cần phải cấu hình Apache để đọc .conf các tệp trong các thư mục này, vì vậy hãy mở tệp security2.conf tệp để chỉnh sửa.

sudo nano /etc/apache2/mods-enabled/security2.conf

Thêm hai chỉ thị sau đây, được đánh dấu bằng màu đỏ, bên trong trước dòng cuối cùng trong tệp (</IfModule>).

Updated security2.conf

        IncludeOptional /etc/modsecurity/*.conf
        IncludeOptional "/usr/share/modsecurity-crs/*.conf"
        IncludeOptional "/usr/share/modsecurity-crs/activated_rules/*.conf"
</IfModule>

Lưu và đóng tập tin.

Loại trừ Thư mục / Tên miền (Tùy chọn)

Đôi khi nó có ý nghĩa để loại trừ một thư mục cụ thể hoặc một tên miền nếu nó đang chạy một ứng dụng, như phpMyAdmin, như ModSecurity sẽ chặn các truy vấn SQL. Nó cũng là tốt hơn để loại trừ backend quản trị của các ứng dụng CMS như WordPress. Nếu bạn đang làm theo hướng dẫn này trên một máy chủ mới, bạn có thể bỏ qua bước này.

Để vô hiệu hóa ModSecurity cho một VirtualHost hoàn chỉnh, hãy đặt các chỉ thị sau bên trong <VirtualHost>[...]</VirtualHost> chặn trong tệp máy chủ ảo của nó.

<IfModule security2_module>
    SecRuleEngine Off
</IfModule>

Để bỏ qua một thư mục cụ thể (ví dụ: /var/www/wp-admin):

<Directory "/var/www/wp-admin">
    <IfModule security2_module>
        SecRuleEngine Off
    </IfModule>
</Directory>

Nếu bạn không muốn tắt hoàn toàn ModSecurity trong một thư mục, hãy sử dụng SecRuleRemoveById chỉ thị để xóa một quy tắc cụ thể hoặc chuỗi quy tắc bằng cách chỉ định ID của nó.

<LocationMatch "/wp-admin/update.php">
    <IfModule security2_module>
        SecRuleRemoveById 981173
    </IfModule>
</LocationMatch>

Kích hoạt quy tắc SQL Injection

Tiếp theo, chúng tôi sẽ kích hoạt tệp quy tắc chèn SQL. Các tệp quy tắc bắt buộc phải được liên kết với activated_rules thư mục, tương tự như của Apache mods-enabled danh mục. Thay đổi thành activated_rules danh mục.

cd /usr/share/modsecurity-crs/activated_rules/

Sau đó tạo một liên kết tượng trưng từ modsecurity_crs_41_sql_injection_attacks.conf tập tin.

sudo ln -s ../base_rules/modsecurity_crs_41_sql_injection_attacks.conf .

Cuối cùng, tải lại Apache để các quy tắc có hiệu lực.

sudo service apache2 reload

Bây giờ hãy mở trang đăng nhập mà chúng tôi đã tạo trước đó và thử sử dụng cùng một truy vấn SQL injection trên trường tên người dùng. Bởi vì chúng tôi đã thay đổi SecRuleEngine chỉ thị cho On ở bước 2, một 403 Cấm lỗi được hiển thị. (Nếu SecRuleEngine đã được để lại cho DetectionOnly tùy chọn, việc tiêm sẽ thành công nhưng nỗ lực sẽ được đăng nhập modsec_audit.log tập tin.)

Bởi vì kịch bản đăng nhập PHP này chỉ có nghĩa là để kiểm tra ModSecurity, bạn nên loại bỏ nó ngay bây giờ khi thử nghiệm được thực hiện.

sudo rm /var/www/html/login.php

Bước 5 - Viết các quy tắc riêng của bạn

Trong phần này, chúng tôi sẽ tạo một chuỗi quy tắc chặn yêu cầu nếu các từ nhất định thường được liên kết với spam được nhập dưới dạng HTML.

Đầu tiên, chúng ta sẽ tạo một kịch bản PHP ví dụ lấy đầu vào từ một hộp văn bản và hiển thị nó trở lại cho người dùng. Mở tệp có tên form.php để chỉnh sửa.

sudo nano /var/www/html/form.php

Dán mã sau:

/var/www/html/form.php

<html>
    <body>
        <?php
            if(isset($_POST['data']))
                echo $_POST['data'];
            else
            {
        ?>
                <form method="post" action="">
                        Enter something here:<textarea name="data"></textarea>
                        <input type="submit"/>
                </form>
        <?php
            }
        ?>
    </body>
</html>

Quy tắc tùy chỉnh có thể được thêm vào bất kỳ tệp cấu hình nào hoặc được đặt trong thư mục ModSecurity. Chúng tôi sẽ đặt các quy tắc của chúng tôi trong một tệp mới riêng biệt được gọi là modsecurity_custom_rules.conf.

sudo nano /etc/modsecurity/modsecurity_custom_rules.conf

Dán phần sau vào tệp này. Hai từ chúng tôi đang chặn là blockedword1blockedword2.

modsecurity_custom_rules.conf

SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'"
SecRule REQUEST_METHOD "POST" chain
SecRule REQUEST_BODY "@rx (?i:(blockedword1|blockedword2))"

Cú pháp cho SecRule Là SecRule VARIABLES OPERATOR [ACTIONS]. Ở đây chúng tôi đã sử dụng chuỗi hành động để đối sánh biến REQUEST_FILENAME với form.php, REQUEST_METHOD với POSTvà REQUEST_BODY với biểu thức chính quy (@rx) chuỗi (blockedword1|blockedword2). Các ?i: không phù hợp với trường hợp. Trên một kết hợp thành công của tất cả ba quy tắc này, ACTION là từ chối và đăng nhập bằng msg "Spam detected." Chuỗi hành động mô phỏng logic và khớp với tất cả ba quy tắc.

Lưu tệp và tải lại Apache.

sudo service apache2 reload

Mở http://your_server_ip/form.php trong trình duyệt. Nếu nhập văn bản có chứa từ khóa1 hoặc blockedword2, bạn sẽ thấy một trang 403.

Bởi vì kịch bản mẫu PHP này chỉ có nghĩa là để kiểm tra ModSecurity, bạn nên loại bỏ nó ngay bây giờ khi thử nghiệm được thực hiện.

sudo rm /var/www/html/form.php

Phần kết luận

Trong hướng dẫn này, bạn đã học cách cài đặt và cấu hình ModSecurity và thêm các quy tắc tùy chỉnh. Để tìm hiểu thêm, bạn có thể xem tài liệu chính thức của ModSecurity.

0