Cài đặt LAMP (Linux, Apache, MySQL, PHP) trên Debian Linux

LAMP là một nhóm các phần mềm nguồn mở để xây dựng nên máy chủ Linux Web Hosting.

Cài đặt LAMP (Linux, Apache, MySQL, PHP) trên Debian Linux
Hướng dẫn cài đặt LAMP trên Debian Linux 9

Cài đặt Web Server với Apache2

Cài đặt gói Apache2

$ sudo apt-get install apache2

Thử kiểm tra cài đặt bằng cách truy cập vào địa chỉ http://địa_chỉ_ip_server.

Cài đặt một số module hữu dụng

Tăng tốc tải trang với mod_pagespeed

Pagespeed của Google giúp tự động tối ưu hóa tốc độ tải trang của website.

wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_amd64.deb
sudo dpkg -i mod-pagespeed-stable_current_amd64.deb
sudo apt-get -f install
sudo systemctl restart apache2

Sửa file /etc/apache2/mods-available/pagespeed.conf, thêm một số option sau:

<IfModule pagespeed_module>
...
    # Turn these on to avoid 403 error
    ModPagespeedJsPreserveURLs on
    ModPagespeedImagePreserveURLs on
    ModPagespeedCssPreserveURLs on

    # Remove comments, whitespaces
    ModPagespeedEnableFilters remove_comments
    ModPagespeedEnableFilters collapse_whitespace
</IfModule>

Ngăn chặn DDOS với mod_evasive

Evasive là một module không thể thiếu trong hành trình chống lại DDOS.

sudo apt-get install libapache2-mod-evasive
sudo mkdir -p /var/log/apache2/evasive
sudo chown -R www-data:root /var/log/apache2/evasive

Sửa file cấu hình /etc/apache2/mods-available/evasive.conf.

<IfModule mod_evasive20.c>
    DOSHashTableSize    3097
    DOSPageCount        2
    DOSSiteCount        50
    DOSPageInterval     1
    DOSSiteInterval     1
    DOSBlockingPeriod   10

    DOSEmailNotify      webmaster@example.com
    DOSSystemCommand    "sudo /usr/local/bin/anti_ddos.sh %s"
    DOSLogDir           "/var/log/apache2/evasive"
</IfModule>

Nội dung script sẽ được mod_evasive gọi khi phát hiện traffic “lạ” từ một địa chỉ IP. Cụ thể ví dụ dưới đây sẽ ‘drop’ toàn bộ traffic từ địa chỉ IP đó trong vòng 5 phút.

/usr/local/bin/anti_ddos.sh

#!/bin/bash

SOURCE_IP="$1"
DOS_LOG_DIR="/var/log/apache2/evasive"

# Time-units can be minutes, hours, days, or weeks
BANNED_TIME="5 minute"

# Ban the DDOS IP address
/sbin/iptables -I INPUT -s $SOURCE_IP -j DROP

# Un-ban it after ${BANNED_TIME}
echo "/sbin/iptables -D INPUT -s $SOURCE_IP -j DROP" | at now + ${BANNED_TIME}

# Allow to run the script again with ${SOURCE_IP}
rm -f "${DOS_LOG_DIR}/dos-${SOURCE_IP}"

Cho phép quyền executable với script trên.

sudo chown www-data:root /usr/local/bin/anti_ddos.sh
sudo chmod +x /usr/local/bin/anti_ddos.sh

Cho phép tài khoản www-data quyền sudo đối với lệnh anti_ddos.sh.

sudo visudo
www-data ALL=NOPASSWD: /usr/local/bin/anti_ddos.sh *

Thay đổi thông tin Server trong HTTP header

Thông tin Server trong HTTP Header cho ta biết kha khá thông tin về máy chủ cụ thể là phiên bản Hệ điều hành và Web server.

Đây là một yếu tố bất lợi nếu như máy chủ không thường xuyên cập nhật mà vẫn giữ những phiên bản được biết là đang tồn tại lỗ hổng.

Ta không thể xóa bỏ header này, nhưng may mắn là ta có thể thay đổi nội dung của nó với mod_security, bằng cách thay đổi giá trị của cấu hình SecServerSignature trong /etc/apache2/conf-available/security.conf. Ví dụ như dưới đây

SecServerSignature HTTP_Server/1.0

Cài đặt MariaDB

Cài đặt gói MariaDB.

sudo apt install mariadb-server mariadb-client

Sau khi cài đặt xong, bắt đầu thiết lập bảo mật cho CSDL.

sudo mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none): ⇐ Enter
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.
Set root password? [Y/n] ⇐ y
New password:  ⇐ Tạo mật khẩu root
Re-enter new password: ⇐ Nhập lại mật khẩu root
Password updated successfully!
Reloading privilege tables..
... Success!

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n] ⇐ y
... Success!
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] ⇐ y
... Success!
By default, MariaDB comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n] ⇐ y
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n] ⇐ y
... Success!
Cleaning up...
All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!

Cài đặt PHP

Cài đặt gói PHP và các thư viện liên kết với Apache2 và MySQL. Dưới đây tôi cài đặt PHP 7.0, bạn có thể thay thế 7.0 bằng phiên bản khác.

sudo apt install php libapache2-mod-php

Cài đặt một số extension thường dùng cho PHP

sudo apt install php-pear php7.0-{common,cli,curl,gd,imagick,intl,json,mcrypt,mysql,pdo,pspell,sqlite3,tidy,xmlrpc,xsl,zip}

Ghi chú

Nếu bạn cần cài đặt các phiên bản PHP khác, hãy tham khảo bài Hướng dẫn cài đặt nhiều phiên bản PHP.

Tăng tốc PHP bằng cache.

sudo apt install -y php7.0-{memcache,opcache,apcu}

Bật opcache bằng các sửa file php.ini.

Nếu PHP được thông dịch bằng Apache Module thì file này nằm tại /etc/php/7.0/apache/php.ini, nếu thông dịch qua PHP-FPM thì là /etc/php/7.0/fpm/php.ini.

Tìm hoặc sửa biến opcache.enable để đặt giá trị 1. Sau đó khởi động lại Apache hoặc PHP-FPM service.

Tăng tốc PHP bằng Apache2 FastCGI với FPM

Cài đặt FPM (FastCGI Process Manager) giúp tăng tốc xử lý PHP chỉ trong một process bằng FastCGI thay vì fork ra nhiều process như CGI.

Cài đặt FastCGI:

sudo apt-get install libapache2-mod-fcgid
sudo a2enmod actions fcgid alias proxy_fcgi

Cài đặt module php-fpm.

sudo apt-get install php7.0-fpm

Khởi động lại Apache2 và FPM service.

sudo systemctl restart php7.0-fpm apache2

Thêm phần thiết lập dưới đây vào cấu hình Apache VirtualHost nếu bạn muốn dùng FPM.

<VirtualHost *:80>
...
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php7.0-fpm.sock|fcgi://localhost/"
    </FilesMatch>
...
</VirtualHost>

Hoặc thiết lập sử dụng FPM cho tất cả VirtualHost

sudo a2enconf php7.0-fpm

Sử dụng MPM Event thay cho MPM Prefork

MPM (Multi-Processing Module) là module kiểm soát cách web server xử lý nhiều request từ client.

Cài đặt mặc định của Apache2 là sử dụng MPM Pre-fork, nhưng thực ra Apache HTTP có đến 3 loại MPM như sau:

Pre-fork sẽ tạo (fork) ra một process (/usr/sbin/apache2) mới cho mỗi kết nối từ client. Do thiết kế sandbox của Linux, các process này không có liên hệ gì với nhau nên về lý thuyết là tốt về bảo mật nhưng lại tốn tài nguyên.

Worker sẽ có một process cha (parent process) chịu trách nhiệm tạo và quản lý một loạt các process con (pool of child processes). Mỗi process con lại hỗ trợ multi-threading tức là 1 process con có thể xử lý nhiều kết nối từ client. Cách làm này khá hiệu quả về sử dụng tài nguyên do tạo ra ít process hơn.

Event là một bước cải tiến của Worker đó là cho phép process cha tối ưu các tác vụ (task) của các process con. Một kết nối sẽ bị “đóng” sau 5 giây (thiết lập mặc định) nếu trên kết nối đó không có “sự kiện” gì và có thể được sử dụng cho kết nối khác. Vì thế lại càng tối ưu tài nguyên hơn.

Để sử dụng MPM Event thì ta phải tắt MPM Pre-fork, mà để tắt MPM Pre-fork thì ta phải tắt PHP module. Như vậy muốn dùng PHP ta buộc phải dùng PHP-FPM. Thế đâm ra lại hay!

Để thay MPM Pre-fork bằng MPM Event ta dùng các lệnh sau:

sudo systemctl stop apache2
sudo a2dismod php7.0
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event

Cài đặt PHP FPM như trên rồi cấu hình Apache HTTP mặc định sử dụng FPM.

sudo a2enconf php7.0-fpm

Khởi động lại Apache service

sudo systemctl restart apache2

Kiểm tra lại bằng lệnh a2query xem kết quả có đúng là event không.

sudo a2query -M

Cài đặt PHPMyAdmin

Có hai cách cài đặt PHPMyAdmin.

Cài từ repository

Hình như Debian 10 không còn cho cài từ repository nữa.

sudo apt-get install phpmyadmin

Tải và cài từ mã nguồn PHPMyAdmin

Ta có thể tải phpMyAdmin từ trang Download trên website về. Ví dụ tôi tải phiên bản mới nhất về như sau.

wget -O phpMyAdmin.tar.gz https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz

sudo mkdir /var/www/html/phpmyadmin
sudo tar xf phpMyAdmin.tar.gz --strip-components=1 -C /var/www/html/phpmyadmin

Tạo file cấu hình mặc định cho phpMyAdmin

cd /var/www/html/phpmyadmin
sudo cp config.sample.inc.php config.inc.php

Mở file config.inc.php để sửa giá trị của biến $cfg['blowfish_secret'] bằng một chuỗi ngẫu nhiên 32 kí tự (có thể chứa chữ cái hoa-thường, số và cả ký tự đặc biệt thì càng tốt). Ví dụ (nhưng đừng copy nhé):

$cfg['blowfish_secret'] = 'D{hgPd]CshM2Olycdb8LuTi:rvOVBs=X';

Thế là xong.

Cho phép tài khoản root đăng nhập (khuyến cáo là không nên).

Nếu tài khoản root mặc định không đăng nhập được vào PHPMyAdmin, ta có thể cho phép với lệnh sau;

echo "UPDATE mysql.user SET plugin = 'mysql_native_password' WHERE user = 'root' AND plugin = 'unix_socket'; FLUSH PRIVILEGES;" | mysql -u root -p

Chỉ cho phép truy cập từ xa từ địa chỉ IP xác định

Tạo một file cấu hình Apache HTTP trong /etc/apache2/sites-available như sau:

/etc/apache2/sites-available/phpmyadmin.conf

<Directory "/var/www/html/phpmyadmin">
    ErrorDocument 403 /403.html
    Order Allow,Deny
    # localhost
    Allow from 127.0.0.1
    # PC in LAN
    Allow from 192.168.1.0/24
    # Specific IP
    Allow from 1.2.3.4
</Directory>
sudo a2ensite phpmyadmin
sudo systemctl reload apache2

Cài đặt chứng chỉ SSL của Let’s Encrypt

Bật module SSL của Apache2.

sudo a2enmod ssl
sudo 2ensite default-ssl
sudo systemctl restart apache2

Cài đặt python-certbot-apache là công cụ hỗ trợ lấy chứng chỉ SSL miễn phí từ dịch vụ Let’s Encrypt.

sudo apt-get install python-certbot-apache

Cấu hình tên miền (ví dụ example.com) trỏ đến địa chỉ IP của server. Sau đó yêu cầu SSL certificate từ Let’s Encrypt.

sudo certbot certonly -d example.com --manual --preferred-challenges dns

Đọc kỹ output, bạn sẽ phải thêm một TXT record vào cấu hình tên miền để tiếp tục.

Sau khi tạo được chứng chỉ SSL thành công, sửa default-ssl.conf để sử dụng chứng chỉ mới thay cho chứng chỉ mặc định (snakeoil). Đường dẫn của chứng chỉ thường là /etc/letsencrypt/live/DOMAIN/*

/etc/apache2/sites-available/default-ssl.conf

<IfModule mod_ssl.c>
  <VirtualHost _default_:443>
    ServerName example.com
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
...
        SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
...
  </VirtualHost>
</IfModule>

Mẫu VirtualHost

Tạo VirtualHost cho mỗi domain trỏ vào server của bạn. Dưới đây là một mẫu cấu hình VirtualHost mà tôi thường sử dụng trên các máy chủ của mình. Với mỗi (danh sách) domain ta chỉ cần thay đổi giá trị các biến VAR_ rồi Include file này là được.

/etc/apache2/sites-available/template.conf

<VirtualHost *:80>
    ServerName ${VAR_DOMAIN}
    ServerAlias ${VAR_ALIASES}
    ServerAdmin ${VAR_EMAIL}
    DocumentRoot ${VAR_ROOT}

    # Remove www.
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [R=301,QSA,NC,L]

    # Redirect HTTP to HTTPS
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName ${VAR_DOMAIN}
    ServerAlias ${VAR_ALIASES}
    ServerAdmin ${VAR_EMAIL}
    DocumentRoot ${VAR_ROOT}

    <Directory ${VAR_ROOT}>
        AllowOverride FileInfo AuthConfig Limit
        Options MultiViews SymLinksIfOwnerMatch IncludesNoExec
        Require method GET POST OPTIONS
        #php_admin_flag engine On
    </Directory>

    <IfModule mod_alias.c>
        <IfModule mod_cgi.c>
            Define VAR_CGI_BIN
        </IfModule>
        <IfModule mod_cgid.c>
            Define VAR_CGI_BIN
        </IfModule>
        <IfDefine VAR_CGI_BIN>
            ScriptAlias /cgi-bin/ ${VAR_ROOT}/cgi-bin/
            <Directory ${VAR_ROOT}/cgi-bin>
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Require all granted
            </Directory>
        </IfDefine>
    </IfModule>

    # Remove www.
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [R=301,QSA,NC,L]

    # Let's Encrypt SSL Certificate
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/${VAR_DOMAIN}/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/${VAR_DOMAIN}/privkey.pem

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
</IfModule>

/etc/apache2/sites-available/hainh.me.conf

Define VAR_DOMAIN  hainh.me
Define VAR_ALIASES www.hainh.me
Define VAR_EMAIL   webmaster@hainh.me
Define VAR_ROOT    /home/icreativ/public_html

Include ./template.conf

Phản hồi về bài viết

Cùng thảo luận chút nhỉ!

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.