• Thứ Ba, 06/01/2004 09:48 (GMT+7)

    An toàn hơn với Webserver Apache

    Cùng với việc ra đời của các Website trên mạng cũng đồng thời xuất hiện các cuộc tấn công khai thác các lỗ hổng của máy chủ Web ngày một nhiều. Tuy nhiên, phần lớn các lỗ hổng kể trên được tạo ra do sơ xuất hoặc cấu hình sai của người quản trị. Bài viết sau đây giới thiệu một số kỹ năng căn bản về an toàn với Webserver Apache - một trong những Webserver phổ biến nhất trên Internet.

    Giới hạn địa chỉ ip
    Theo thống kê thực tế, 70% các cuộc tấn công xuất phát từ các máy tính trong mạng nội bộ, 30% số còn lại đến từ các máy mạng bên ngoài. Vì vậy, việc giới hạn được các máy tính trong mạng 'dòm ngó' những tài nguyên quan trọng và nhạy cảm trên máy chủ càng nhiều càng tốt. Module mod_access của Apache có khả năng xác định được địa chỉ IP của máy trạm có yêu cầu sử dụng dịch vụ Web, dựa trên đó nó áp dụng các chính sách (policy) mà người quản trị đã khai báo để quyết định máy tính có địa chỉ IP đó có được phép sử dụng dịch vụ hay không.
    Việc khai báo các chính sách được thực hiện bằng việc sửa đổi file cấu hình của Apache (mặc định sẽ được lưu vào file /etc/httpd/conf/httpd.conf) và thêm vào các thẻ.
    Để ngăn hay cho phép một địa chỉ, dải địa chỉ IP xác định, Apache có thẻ Allow và Deny. Cú pháp của hai thẻ này như sau:

    Allow from host-or-network        #Cho phép host hoặc một giải IP truy cập

    Deny from host-or-network       # Cấm  host hoặc một giải IP truy cập

    host-or-network có thể là:

    o Tên host hoặc tên domain (ví dụ: www.foo.com)

    o Một địa chỉ IP xác định (ví dụ: 10.0.72.3),

    o Một địa chỉ IP và địa chỉ mạng con (ví dụ: 10.0.0.0/255.0.0.0 - xác định tất cả các máy tính có địa chỉ IP có byte đầu là 10, bất kể 3 byte sau là gì).


    Hinh 1

    Với hai thẻ trên, Apache khuyến cáo sử dụng địa chỉ IP thay cho tên domain, bởi nếu khai theo tên domain thì Apache phải tốn thời gian chuyển đổi từ domain name sang IP và sau đó mới áp dụng các chính sách giới hạn cho địa chỉ này. Việc này dẫn đến sự tiêu tốn tài nguyên của máy chủ.
    Nếu muốn dùng cả hai thẻ Allow và Deny thì thứ tự của chúng được xác định bằng thẻ Order. Ví dụ: Để cấu hình chỉ cho các máy có địa chỉ IP có byte đầu tiên là 10 được xem nội dung file foo.html thì khai báo như sau:

    <Files foo.html>

    Order Deny,Allow  #không có khoảng trống giữa hai từ khoá

    Deny from All

    Allow from 10.0.0.0/255.0.0.0

    </Files>
    Sau khi thay đổi nội dung file cấu hình (/etc/httpd/conf/httpd.conf), để thay đổi này có hiệu lực bạn phải khởi động lại dịch vụ Web (httpd) bằng lệnh:

    [root@Linux conf]# /etc/initd.d/httpd restart

    Apache sẽ thực thi thẻ Deny trước và thẻ Allow sau. Cách làm này được tiến hành tương tự đối với thư mục.
    Ví dụ: bạn có một  diễn đàn (forum)  đặt tại thư mục vật lý là /usr/local/forum. Và bạn muốn giới hạn cho các máy tính thuộc dải địa chỉ từ 172.16.7.1 đến 172.16.7.64, hoặc máy có địa chỉ 10.0.91.3 thì có thể khai báo như sau: 

    </Directory /usr/local/forum>

    Order Deny,Allow

    Deny from All

    Allow from 172.16.7.1/26

     

    Allow from 10.0.91.3

    </Directory>
    Khi đã khai báo như vậy thì chỉ có các máy tính có địa chỉ IP thoả mãn điều kiện trên mới có thể truy cập vào diễn đàn này. tất cả các máy tính có địa chỉ IP nằm ngoài dải trên sẽ nhận được thông báo 'Access forbidden!' như hình 1.

    Giới hạn truy cập theo tài khỏan sử dụng
    Nếu bạn muốn bảo vệ các trang thông tin của mình trên Website bằng cách yêu cầu người dùng phải nhập vào tên tài khoản (username) và mật khẩu (password) thì Apache cũng có sẵn module mod_auth để đáp ứng yêu cầu này.


    Hình 2

    Apache cung cấp 2 khả năng xác thực người dùng là Basic authentication và Digest authentication. Trong đó, Digest authentication được đánh giá là an toàn hơn nhưng lại ít được phát triển. Cách xác thực được sử dụng phổ biến với các Web server Apache hiện nay là basic authentication, cách xác thực này sử dụng 64 bit để mã hóa tên tài khoản  và mật khẩu trước khi gửi đến server. Điều này còn có nghĩa là việc chặn thông tin trên đường truyền để giải mã lấy tên tài khoản và mật khẩu là công việc hết sức khó khăn.
    Các thông tin về tên tài khoản và mật khẩu được tạo bằng chương trình htpasswd. Các thông tin này sẽ được lưu vào một file text với truờng mật khẩu đã được mã hoá và khi cần xác thực người dùng Apache sẽ giải mã mật khẩu mà người dùng cung cấp sau đó mang so sánh với mật khẩu lưu trữ. Cú pháp của câu lệnh htpasswd như sau (các thông tin trong dấu ngoặc vuông '[]' là tuỳ chọn) :

    htpasswd [options] pwfile username [password]

    options bao gồm:

    m: Chọn thuật toán mã hoá mật khẩu là MD5.

    d: Dùng thuật toán mã hoá của hệ thống để mã hóa mật khẩu.

    s: Mã hóa mật khẩu theo thuật toán SHA.

    b: Nhập mật khẩu trực tiếp vào dòng lệnh.
    Thuật toán mã hóa có thể được áp dụng cho từng bản ghi khác nhau trong một file, điều này có nghĩa là các tài khoản khác nhau có thể có mật khẩu được mã hóa theo các thuật toán khác nhau.

    c: Mặc định htpasswd hiểu rằng file chứa tài khoản và mật khẩu (pwfile) đã tồn tại. Vì vậy để tạo một file mới bạn phải sử dụng tuỳ chọn -c.
    pwfile: Là tên file lưu trữ tên tài khoản và mật khẩu.
    username: Tên tài khoản cần tạo.
    password: Mật khẩu của tài khoản tương ứng (chỉ sử dụng khi có option là '-b').
    Ví dụ: Để tạo ra tài khoản là thanhpt với mật khẩu là REV#32 vào một file mới là /etc/http/conf/passwd thì câu lệnh đầy đủ là:

    #htpasswd -cb /etc/httpd/conf/passwd thanhpt REV#32

    hoặc:

    #htpasswd -c /etc/http/conf/passwd thanhpt

    Sau khi tạo được file chứa tài khoản và mật khẩu của người dùng thì người quản trị sẽ phải sử dụng các thẻ AuthName, AuthType, AuthUserFile và Require để khai báo trong file cấu hình http.conf.
    Ví dụ: Bạn muốn đưa lên một trang sách điện tử có địa chỉ URL là http://10.0.95.15/book/ và yêu cầu mọi người vào trang này đều phải có tên tài khoản và mật khẩu đã được gán định trước. File cấu hình /etc/httpd/conf/http.conf phải thêm vào các dòng sau:

    Alias /book/ '/var/www/book/' #khai báo alias cho subsite http://yoursite/book/

    <Directory '/var/www/book/'>

    AuthName 'Insiders Only'

    AuthType Basic

    AuthUserFile /etc/httpd/conf/passwd

     Require valid-user

    </Directory>
    Lưu ý: Mặc định dịch vụ Web (httpd) sẽ sử dụng account Apache để khởi động cũng như xác định các quyền hạn đọc/ghi cho các file và thư mục trên hệ thống. Vì vậy, tài khoản này phải có quyền đọc file /etc/httpd/conf/passwd để biết được mật khẩu người sử dụng và tài khoản tương ứng. Để làm việc này bạn có thể dùng một trong hai lệnh sau:

    [root@Redhat90 conf]# chmod ugo+r /etc/httpd/conf/passwd

    hoặc

    [root@Redhat90 book]# chown apache /etc/httpd/conf/passwd
    Cũng giống như việc khai báo chính sách cho địa chỉ IP, sau khi khai báo lại file cấu hình cho các thẻ AuthName, AuthType, AuthUserFile và Require Apache, httpd yêu cầu phải được khởi động lại để xác nhận sự thay đổi này. Vì vậy, sau mỗi lần thay đổi bạn phải dùng lệnh:

    [root@Linux conf]# /etc/initd.d/httpd restart

    Với cấu hình như trên, chỉ người sử dụng nào có tài khoản và mật khẩu trong file /etc/httpd/conf/passwd mới có quyền đăng nhập vào trang Web http://yoursite/book/.

    Thẻ Require có các giá trị sau:

    o valid-user: chỉ những người có tài khoản hợp lệ.

    o user userid: chỉ cho phép các tài khoản này đăng nhập nếu cung cấp đúng mật khẩu.

    o group groupid: chỉ có tài khoản thuộc các các nhóm xác định mới có quyền đăng nhập.

    Ví dụ: bạn có 6 người dùng khai báo trong file /etc/ httpd/conf/passwd là 'tienna', 'conghc', 'hiep', 'thanhpt', 'vietvq' và 'dongbt'. Trong số 6 người này bạn chỉ cho phép 3 người là 'tienna', 'vietvq' và 'dongbt' được đăng nhập vào địa chỉ http://10.0.95.15/secure/.

    Alias /secure/ '/var/www/secure/'

    # thẻ này để ánh xạ thư mục '/var/www/secure/ lên http://10.0.95.15/secure/

    <Directory '/var/www/secure/'>

     AuthType Basic

    AuthName '3 Member Only'

    AuthUserFile /etc/httpd/conf/passwd

    Require user tienna dongbt vietvq


    Hình 3

    </Directory>
    Thẻ AuthUserFile chỉ cho phép xác định từng người dùng. Khi muốn xác định cho một nhóm người dùng bạn phải dùng thẻ AuthGroupFile, cú pháp của thẻ này như sau:
    AuthGroupFile Filepath
    Filepath là đường dẫn tới file text chứa tên nhóm và người dùng. Mỗi dòng của file này bao gồm tên nhóm, dấu phân cách hai chấm (:) và người sử dụng trong nhóm đó.
    Ví dụ: Bạn có file /etc/httpd/conf/groups chứa tài khoản 5 người dùng thuộc 2 nhóm Admin và User như sau:

    [root@Linux conf]# cat /etc/httpd/conf/groups

    Admin: tienna vietvq dongbt

    User: hiep thanhpt
    Và để giới hạn chỉ xác thực mật khẩu của các tài khoản trong nhóm Admin khi đăng nhập vào http://10.0.95.15/book/ thì file cấu hình /etc/httpd/conf/httpd.conf được sửa lại tương ứng như sau:

    Alias /book/ '/var/www/book/'

    <Directory '/var/www/book/'>

    AuthName 'Admin group Only'

    AuthType Basic

    AuthUserFile /etc/httpd/conf/passwd

    AuthGroupFile /etc/httpd/conf/groups

    Require group Admin      

    </Directory>
    Với cách cấu hình này bất kỳ ai dùng trình duyệt để mở trang http://10.0.95.15/book/ đều nhận được yêu cầu nhập tên tài khoản và mật khẩu (Hình 2). Những tài khoản không thuộc nhóm Admin sẽ không thể đăng nhập được vào http://10.0.95.15/book/, nếu cố đăng nhập sau 3 lần sẽ nhận được thông báo 'Authentication required!' (Hình 3).
    Đôi khi nhiều người muốn kết hợp cả giới hạn theo địa chỉ IP và người dùng, việc này hoàn toàn có thể triển khai được với Apache, dưới đây là một đoạn file cấu hình ví dụ:

    <Files foo.html>

            Order Deny,Allow

            Deny from All

            Allow from 10.0.0.0/255.0.0.0

            AuthName 'Insiders Only'

            AuthType Basic

            AuthUserFile /usr/local/web/apache/htpasswd

            Require valid-user

        </File>
    Như vậy, để truy cập được file foo.html người sử dụng phải qua được 2 vòng kiểm tra, lần thứ nhất Apache sẽ kiểm tra địa chỉ IP của máy người dùng yêu cầu có nằm trong dải 10.0.0.0/255.0.0.0 hay không, nếu điều kiện này thoả, nó tiếp tục kiểm tra mật khẩu và tài khoản người dùng cung cấp có tương ứng với thông tin lưu trong file /usr/local/web/apache/htpasswd hay không, nếu cả hai đều thoả thì người dùng sẽ đọc được nội dung file này.

    Thống kê lưu lượng người dùng
    Một trong những phần không thể thiếu với bất cứ một trang Web nào là thống kê được lưu lượng người dùng. Giống như các Webserver khác, file log của Apache ghi các sự kiện theo một cấu trúc nhất định. Với Redhat, file log này sẽ được phân tích bởi một chương trình đặc biệt có tên là Webalizer. Chương trình này đọc các file log và hiển thị kết quả phân tích dưới dạng ảnh PNG (Portable Network Graphic). Từ kết quả này có thể đánh giá được lưu lượng người dùng theo từng tháng, từng ngày hoặc theo từng địa chỉ URL cụ thể.
    Webalizer được cài từ gói Webalizer (với bản Redhat 8.0 thì gói này có tên là webalizer-2.01_10-9.rpm). Bạn có thể cài gói Webalizer này với câu lệnh sau:


    Hình 4

    [root@Linux root]# rpm -Uvh  webalizer-2.01_10-9.rpm

    /etc/webalizer.conf là file cấu hình mặc định của Webalizer. Với file này bạn có thể chỉ ra thư mục hoặc trang nào trong Website cần được phân tích, địa chỉ URL nào cần giấu đi và nhiều tính năng khác. Dưới đây là một file cấu hình tiêu biểu:

    [root@Linux root]# cat  /etc/webalizer.conf 

     LogFile /var/log/httpd/access_log

            OutputDir /home/httpd/usage

            Incremental  yes

            PageType  htm*

            PageType  cgi

            PageType  php

            HideURL  *.gif

            HideURL  *.GIF

            HideURL  *.jpg

            HideURL  *.JPG

            HideURL  *.ra

    Ý nghĩa của các thẻ:
    o LogFile: Chỉ định file log của Apache mà Webalizer sẽ phân tích, mặc định là /var/log/httpd/access_log.
    o OutputDir: Chỉ ra thư mục lưu kết quả phân tích của Webalizer.
    o Incremental yes: Thẻ Incremental được gán giá trị bằng 'yes' để báo cho Webalizer biết chỉ xử lý phần gia tăng của file log. Apache cũng khuyến cáo bạn nên chọn tùy chọn này.
    o PageType: Chỉ ra các kiểu file mở rộng cần phân tích. Mỗi chuẩn mở rộng sẽ được khai báo trên từng dòng.
    o HideURL: Chỉ ra loại file nào được phân tích, ví dụ file đồ hoạ (*.gif *.GIF *.jpg *.JPG ), file  audio (*ra). Cũng như thẻ PageType, trên mỗi dòng thẻ HideURL chỉ khai báo một chuẩn file mở rộng nhất định, để khai báo nhiều kiểu file khác nhau buộc phải viết trên nhiều dòng.
    Sau khi cấu hình xong file /etc/webalizer.conf, bạn phải khai báo thư mục chứa kểt quả phân tích với Webserver bằng cách thêm vào file /etc/httpd/conf/httpd.conf các dòng khai báo sau:

    Alias /usage/ '/home/httpd/usage/'

    <Directory '/home/httpd/usage'>

              Options None

              AllowOverride None

              Order deny,allow

              Deny from all

              Allow from 192.168.1.0/24

    </Directory>
    Kế đến bạn phải khởi động lại dịch vụ Web bằng câu lệnh:

    [root@Linux conf]# /etc/initd.d/httpd restart

    Công việc cuối cùng bạn phải làm với Webalizer là sửa lại crontab bằng lệnh

    [root@Linux root]# crontab -e

    và nhập vào nội dung sau:

    */5 * * * * /usr/bin/webalizer
    Như vậy, với cấu hình này của crontab thì cứ sau 5 phút Webalizer sẽ phân tích file log và đưa ra kết quả. Để xem kết quả bạn chỉ cần mở trình duyệt và gõ vào địa chỉ http://yoursite/usage/ (với bài viết này là http://www.tienna.com/usage/) ( Hình 4).
    Trên đây là những kỹ năng căn bản cho việc xây dựng một Webserver Apache an toàn. Tôi  đã triển khai thực tế thành công ba kỹ năng này trên hệ điều hành RedHat 8.0. Hy vọng bài viết này đem đến những thông tin hữu ích giúp bạn thiết lập cho webserver của mình một 'hàng phòng thủ' mạnh, đủ sức chống lại các cuộc tấn công không báo trước.
    Chúc các bạn thành công.

    Nguyễn Anh Tiến
    tienna@vnu.edu.vn

     

     

    ID: A0310_108