文章主要分为以下三个部分:

  • LNMP 环境搭建
  • PHP 连接 MySQL
  • Linux服务器加固

LNMP 环境搭建

利用腾讯云服务器搭建LNMP环境。

步骤一:准备工作

操作系统:centOS7

  1. 远程登录Linux实例(我使用的是Xshell配合密钥登录)。
  2. 查看linux发行版本
cat /etc/redhat-release  # 查看centOS版本


步骤二:安装Nginx

  1. 安装Nginx
yum -y install nginx


  1. 查看安装的Nginx版本
nginx -v


返回结果如下所示,表示安装成功。

LNMP环境搭建及服务器加固_nginx

步骤三:安装MySQL

由于之前安装过MySQL,所以需卸载后重新安装一次。(未安装的可以直接从第4步开始)

  1. 查询是否安装了MySQL
rpm -qa |grep mysql


返回结果如下

LNMP环境搭建及服务器加固_mysql_02

  1. 卸载MySQL,将上述查询出来的全部删除
rpm -e --nodeps mysql-community-libs-5.6.51-2.el7.x86_64
rpm -e --nodeps mysql-community-client-5.6.51-2.el7.x86_64
rpm -e --nodeps mysql-community-release-el7-5.noarch
rpm -e --nodeps mysql-community-common-5.6.51-2.el7.x86_64
rpm -e --nodeps mysql-community-server-5.6.51-2.el7.x86_64


使用​​rpm -qa | grep mysql​​ 查询无返回后即卸载成功。

  1. 删除相关目录

查找MySQL相关目录

find / -name mysql


LNMP环境搭建及服务器加固_mysql_03

删除上述查询到的相关目录

rm -rf /etc/selinux/targeted/active/modules/100/mysql
rm -rf /usr/share/mysql
rm -rf /usr/lib64/mysql
rm -rf /var/lib/mysql
rm -rf /var/lib/mysql/mysql

# 删除/etc/my.cnf
rm -rf /etc/my.cnf
# 删除 /var/log/mysqld.log(如果不删除,会导致新安装的mysql无法生成新密码,无法登陆)
rm -rf /var/log/mysqld.log


  1. 运行以下命令更新YUM源
rpm -Uvh http://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm


  1. 安装MySQL(安装时间较长)
yum -y install mysql-community-server


  1. 查看MySQL版本号
mysql -V


返回结果如下,表示安装成功。

LNMP环境搭建及服务器加固_nginx_04

  1. 启动MySQL
systemctl start mysqld


  1. 设置开机启动
systemctl enable mysqld
systemctl daemon-reload


步骤四:安装PHP

  1. 更新 yum 中 PHP 的软件源
rpm -Uvh https://mirrors.cloud.tencent.com/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm


  1. 安装PHP
yum -y install mod_php72w.x86_64 php72w-cli.x86_64 php72w-common.x86_64 php72w-mysqlnd php72w-fpm.x86_64


  1. 查看PHP版本
php -v


返回如下结果,表示安装成功

LNMP环境搭建及服务器加固_服务器_05

步骤五:配置Nginx

  1. 首先备份Nginx配置文件。
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak


  1. 修改Nginx配置文件,添加Nginx对PHP的支持。
  • 打开配置文件
vim /etc/nginx/nginx.conf


  • 按 ​​i​​ 进入编辑模式
  • 在 ​​server​​ 大括号内,添加如下配置信息
        #除下面提及的需要添加的配置信息外,其他配置保持默认值即可。
#将location / 大括号内的信息修改为以下所示,配置网站被访问时的默认首页。
location / {
index index.php index.html index.htm;
}
        #添加下列信息,配置Nginx通过fastcgi方式处理您的PHP请求。
location ~ .php$ {
root /usr/share/nginx/html; #将/usr/share/nginx/html替换为您的网站根目录,本教程使用/usr/share/nginx/html作为网站根目录。
fastcgi_pass 127.0.0.1:9000; #Nginx通过本机的9000端口将PHP请求转发给PHP-FPM进行处理。
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; #Nginx调用fastcgi接口处理PHP请求。
}


添加配置信息后,最终结果如下所示

LNMP环境搭建及服务器加固_php_06

  • 按下 ​​Esc​​ 键后,输入 ​​:wq​​ 并回车保存编辑并关闭配置文件。
  1. 查看与启动Nginx服务
systemctl status nginx
systemctl start nginx


  1. 设置Nginx服务开机自动启动
systemctl enable nginx


  1. 在本地浏览器中访问云服务器IP地址,查看Nginx服务是否正常运行。
http://云服务器IP


显示如下,则说明Nginx安装配置成功

LNMP环境搭建及服务器加固_php_07

步骤六:配置MySQL

  1. 运行以下命令查看/var/log/mysqld.log文件,获取并记录root用户初始密码
grep 'temporary password' /var/log/mysqld.log


返回结果如下:

LNMP环境搭建及服务器加固_nginx_08

  1. 配置MySQL的安全性
mysql_secure_installation


安全性的配置包含以下五个方面:

  • 重置root账号密码
Enter password for user root: #输入上一步获取的root用户初始密码
The 'validate_password' plugin is installed on the server.
The subsequent steps will run with the existing configuration of the plugin.
Using existing password for root.
Estimated strength of the password: 100
Change the password for root ? (Press y|Y for Yes, any other key for No) : Y #是否更改root用户密码,输入Y
New password: #输入新密码,长度为8至30个字符,必须同时包含大小写英文字母、数字和特殊符号。特殊符号可以是()` ~!@#$%^&*-+=|{}[]:;‘<>,.?/
Re-enter new password: #再次输入新密码
Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y


  • 输入 ​​y​​ 删除匿名用户账号
By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL 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? (Press y|Y for Yes, any other key for No) : Y #是否删除匿名用户,输入Y
Success.


  • 输入 ​​y​​ 禁止root账号远程登录
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y #禁止root远程登录,输入Y
Success.


  • 输入 ​​y​​ 删除test库以及对test库的访问权限
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y #是否删除test库和对它的访问权限,输入Y
- Dropping test database...
Success.


  • 输入 ​​y​​ 重新加载授权表
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y #是否重新加载授权表,输入Y
Success.
All done!


步骤七:配置PHP

  1. 新建phpinfo.php文件,用于展示PHP信息
  • 运行以下命令新建文件
vim <网站根目录>/phpinfo.php  #将<网站根目录>替换为您配置的网站根目录。


网站根目录是在nginx.conf文件中​​location ~ .php$​​ 括号内配置的 ​​root​​ 值,本教程配置的网站根目录为/usr/share/nginx/html,因此命令为

vim /usr/share/nginx/html/phpinfo.php


  • 输入以下内容,函数 ​​phpinfo()​​ 会展示PHP的所有配置信息
<?php echo phpinfo(); ?>


保存退出

  1. 启动PHP-FPM
systemctl start php-fpm


  1. 设置开机自启动
systemctl enable php-fpm


步骤八:测试访问LNMP平台

  1. 打开浏览器
  2. 在地址栏输入​​http://<ECS实例公网IP地址>/phpinfo.php​​。

返回结果如下,表示LNMP环境部署成功。

LNMP环境搭建及服务器加固_mysql_09

测试完成后,运行以下命令将phpinfo.php文件删除,消除安全隐患。

rm -rf /usr/share/nginx/html/phpinfo.php

PHP 连接MySQL

PHP 5及以上版本可以使用以下两种方式连接MySQL:

  • MySQLi extension
  • PDO (PHP Data Objects)

两者有自己的优势,PDO应用在多种不同数据库中,如果项目需要在多种数据库中切换,建议使用PDO,MySQLi只针对MySQL数据库。

其中MySQLi和PDO在安装MySQL时已自动安装,可以再phpinfo页面查看

LNMP环境搭建及服务器加固_服务器_10

LNMP环境搭建及服务器加固_nginx_11

包含以上页面即已安装成功。

MySQLi 连接数据库

PHP访问MySQL数据库的步骤如图所示:

LNMP环境搭建及服务器加固_mysql_12

使用扩展中的 ​​mysqli_connct()​​ 函数可以实现 MySQL 数据库的连接,函数语法格式如下:

mysqli_connect(
[string $host = ini_get("mysqli.default_host")
[, string $username = ini_get("mysqli.default_user")
[, string $password = ini_get("mysqli.default_pw")
[, string $dbname = ""
[, int $port = ini_get("mysqli.default_port")
[, string $socket = ini_get("mysqli.default_socket")
]]]]]] )


参数说明如下:

  • $host: 可选参数,要连接的服务器。可以是主机名或IP地址
  • $username: 可选参数,登录MySQL使用的用户名
  • $password: 可选参数,登录密码
  • $dbname: 可选参数,执行查询时使用的默认数据库
  • $port: 可选参数,指定连接到MySQL服务器的端口号
  • $socket: 可选参数,指定socket或要使用的已命名pipe,很少用到

以下通过一个简单的代码实现连接数据库

1)面向过程风格的写法

<?php
$host = 'localhost';
$username = 'root';
$password = 'root';
$dbname = 'test';
$port = '3306';
$link = @mysqli_connect($host,$username,$password,$dbname,$port); //连接到数据库
if($link){
mysqli_set_charset($link,'UTF-8'); //设置数据库字符集
$sql = 'select * from user'; //SQL 语句
$result = mysqli_query($link, $sql); //执行 SQL 语句,并返回结果
$data = mysqli_fetch_all($result); //从结果中获取所有数据
mysqli_close($link);
}else{
die('数据库连接失败!');
}
echo '<pre>';
print_r($data);
?>


在命令行中可以使用​​php -l phptest.php​​来检查语法错误。

2)面向对象风格写法

<?php
$host = 'localhost';
$username = 'root';
$password = 'root';
$dbname = 'test';
$mysql = new mysqli($host,$username,$password,$dbname);
if($mysql -> connect_errno){
die('数据库连接失败:'.$mysql->connect_errno);
}else{
$mysql -> set_charset('UTF-8');
$sql = 'select * from user';
$result = $mysql -> query($sql);
$data = $result -> fetch_all();
$mysql -> close();
}
echo '<pre>';
print_r($data);
?>


PDO 连接MySQL数据库

使用PDO连接数据库流程入下:

LNMP环境搭建及服务器加固_php_13

代码如下

<?php
$servername = 'localhost';
$username = 'root';
$password = 'root';

try {
$conn = new PDO("mysql:host=$servername;",$username,$password);
echo "连接成功";
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>


参考:

​PHP连接数据库​

​PHP使用PDO连接数据库​

​PHP 连接 MySQL​

服务器加固

Linux系统被应用与大部分企业的服务器上,因此在等保测评中主机加固也是必须要完成的一项环节。

Linux的主机加固可以分为:账号安全,认证安全,协议安全,审计安全。

账号安全

1. 口令生存期

修改文件 ​​/etc/login.defs​

  • PASS_MAX_DAYS 90 密码最长有效期
  • PASS_MIN_DAYS 10 密码修改之间的最小天数
  • PASS_MIN_LEN 8 密码最小长度
  • PASS_WARN_AGE 7 口令失效前多少天开始通知用户修改密码

LNMP环境搭建及服务器加固_nginx_14

2. 口令复杂度

编辑文件 ​​/etc/pam.d/password-auth​​ ,修改如下

password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=  difok=1 minlen=8 ucredit=-1 lcredit=-1 dcredit=-1


  • difok 定义新密码中必须要有几个字符和旧密码不同
  • minlen 新密码的最小长度
  • ucredit 新密码中可以包含的大写字母的最大数目。-1 至少一个
  • lcredit 新密码中可以包含的小写字母的最大数
  • dcredit 新密码中可以包含的数字的最大数目

LNMP环境搭建及服务器加固_mysql_15

注:这个密码强度的设定只对"普通用户"有限制作用,root用户无论修改自己的密码还是修改普通用户的时候,不符合强度设置依然可以设置成功

3. 对用户登录次数进行限制

编辑文件 ​​/etc/pam.d/sshd​

auth required pam_tally2.so deny=3 unlock_time=150 even_deny_root root_unlock_time300


LNMP环境搭建及服务器加固_nginx_16

  • pam_tally2 查看被锁定的用户
  • pam_tally2 --reset -u username 将被锁定的用户解锁

4. 禁止root用户远程登录(看是否需要)

编辑文件 ​​/etc/ssh/sshd_config​

PermitRootLogin   no


  • PermitRootLogin no 不允许root登陆
  • Protocol 2 修改ssh使用的协议版本
  • MaxAuthTries 3 修改允许密码错误次数

生效要重启sshd进程

5. 设置历史命令保存条数和账户超时时间

打开 ​​/etc/profile​​ ,修改如下

HISTSIZE=1000
TMOUT=600


LNMP环境搭建及服务器加固_nginx_17

6. 禁用无用账户

​cat /etc/passwd​​ 命令查看口令文件,确认不必要的账号

使用 ​​passwd -l user​​ 锁定不必要的账号

协议安全

1. openssh升级(按需做)

yum update openssh


2. 定时任务(防止病毒感染)

定时任务检查:

crontab -l


一次性任务检查:

at -l


3. 防止flood攻击

vim /etc/sysctl.conf


增加 ​​net.ipv4.tcp_sysncookies = 1​​ ,然后 ​​sysctl -p​

4. 检查异常进程

# 检查cpu占用前10
ps aux|sort -rn -k +3|head
# 检查内存占用前10
ps aux|sort -rn -k +4|head


认证权限

1. 配置用户最小权限

chmod 644 /etc/passwd
chmod 400 /etc/shadow
chmod 644 /etc/group


2. 文件与目录缺省权限 控制

cp /etc/profile /etc/profile.bak #备份
vim /etc/profile


增加如下内容

umask 027
source /etc/profile


日志审计

1. 定期查看系统日志

cat /var/log/messages
cat /var/log/secure


重要服务器可以将日志定向传输到指定服务器进行分析

2. 启用远程日志功能

vim /etc/rsyslog.conf


你想把哪种类型的日志文件发送给服务端,你就把它原来对应的目录改为: @日志服务器IP

把所有日志文件都发送给服务器的话,在文件最后加上

*.* @@syslog日志服务器IP


注意:*和@之间是tab键。