LNMP 环境的搭建与些许讲解

CentOS7.3+Nginx1.12.2+Mariadb10.2+PHP7.2 环境安装与简单修改配置的相关讲解


1、简介

一个新手 WordPress 站长最需要什么?那就是一份 LNMP 一键包。这样可以让他不明白 Linux 怎么配置的时候,可以成功的部署一个最基本的 WordPress 站点。

然而实际上,由于 LNMP 一键包版本太多,很多人用完感觉有问题的时候,却不知道修改的方法。这种雾里看花的感觉,也遏制了很多人玩一玩的想法。

本讲解内容主要包含:LNMP 最简单的搭建,PHP 编译,一些限制的修改。


1.1、目录

1、简介
1.1、目录
2、准备
3、操作
3.1、LNMP 最简单的搭建
3.1.2、使用 Yum 安装 LNMP
3.1.3、部署 wordpress 与修改 nginx 配置文件
3.2、Mariadb 的 10.2 版本安装
3.3、PHP7.2 的编译安装
3.3.1、编译 PHP7.2
3.3.2、配置编译好的 PHP7
3.3.3、运行与管理
3.4、CentOS 内核升级为 Google-BBR 的安装
3.4.1、安装 BBR
3.4.2、检查 BBR
4、讲解
4.1、LNMP 讲解
4.1.1、yum 的一些小程序
4.1.2、EPEL 源的手动安装方法
4.1.3、Mariadb 数据库的基本初始化
4.1.4、Mariadb 数据库的基本管理
4.1.5、文件和数据库的备份与还原
4.1.6、文件上传时的限制配置
4.1.7、系统文件最大打开数等一些上限的限制
4.1.8、服务和防火墙的一些操作命令
4.2、PHP7.2 关于 Socket 讲解
4.3、后台运行命令讲解
4.4、权限错误和 su 和 sudo 相关
4.5、查看系统版本和内核的命令
4.6、创建 Swap 虚拟内存
4.7、使用 History 查阅历史命令
4.8、文件权限与使用 Find 过滤修改权限
5、后期修订
6、相关链接


2、准备

由于本人实在对于 Ubuntu 不够熟练,在此就不献丑了,所以本讲解全程 CentOS,并且都以最新的 CentOS7 最小化安装版为基础环境。

提前准备的工具

1、BitviseSSH 类似的 SSH 连接工具,需要支持 SFTP 传输。
2、Notepad++类似的能编辑 json 格式的文本编辑器,因为 Windows 和 Linux 的文件格式有明显差异
3、一片能让你静心下来学习实验的地方。

安装的前提环境

1、一个至少 512MB 的 VPS 或者虚拟机,当然实体机也没问题,不过实体机可能出现硬件相关的冲突需要自行处理
2、CentOS7,正常联网,关闭 SELinux。关于 SELinux 本人了解不深就不讲解了。
3、可能会需要的科学上网工具去下载 yum 安装速度特别慢的东西,如果你的 VPS 在国外那么就不需要了
4、以 Root 方式登陆机器,如果无法使用 Root 登陆,则需要在每条命令前输入 sudo 使命令以最高权限执行。


3、操作

3.1、LNMP 最简单的搭建

3.1.1、安装所需要的环境组件和常用的工具组件

CentOS 有 Yum 作为包管理工具,就像安卓市场,你可以凭借程序名称,通过 yum 的方式安装。
这种方式的有点在于,简单,快捷,易部署,你可以理解为别人编译好的文件,复制一份,你直接拿来就用。

yum install epel-release
安装 EPEL 源 (可能部分国家默认不支持 EPEL 源如俄罗斯)
安装时会提示你,是否通过一份 GPG-KEY,默认选择 Yes,具体可以访问 EPEL 官网查看校验 GPG-KEY

yum update -y
更新 CentOS 到最新版
由于时间差距,可能你的很多软件已经过时了,通过此命令让软件更新到最新版。

yum install -y git vim wget curl unzip net-tools
安装基本的软件。参照下方讲解


3.1.2、使用 Yum 安装 LNMP

要简单,当然是最简单的方式安装了。

yum install -y nginx mariadb mariadb-server

安装 nginx 和 mariadb 数据库 (mariadb ~ mysql 两者 2017 年的 v5.*基本一致,具体请查阅相关文档)

yum install -y php php-cli php-common php-devel php-fpm php-gd php-mbstring php-mcrypt php-mysql php-pdo php-pear php-process php-opcache php-xml

安装 PHP 并附带相关组件如 php-mysql,php-gd 等等。上列组件足够一般的 WordPress 用户使用 (默认 PHP5)

firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload

三条命令,允许 Firewall 防火墙放行 http 的 80 端口和 https 的 443 端口,成功后会返回信息 success
此处写的协议是 firewall 默认协议配置文件名,里面包含了端口。

systemctl enable nginx
systemctl enable mariadb
systemctl enable php-fpm

三条命令,开机允许 nginx,mariadb 和 php-fpm 运行
成功运行后显示 Created symlink from *** .service.

systemctl restart nginx
systemctl restart mariadb
systemctl restart php-fpm

三条命令,重新启动 nginx,mariadb 和 php-fpm,由于之前并没有启动,所以等同于 start 注意,如果出于配置文件更新,可以使用 reload 参数动态重新加载配置文件。查看状态可以使用 status 参数

此时,LNMP 环境就可以使用了。打开以 VPS 的 IP 为网址的网页,可以看到 Nginx 默认生成的页面

相关配置文件位置如下
Nginx 位于 /etc/nginx/nginx.conf
Mariadb 位于 /etc/my.cnf
PHP 位于 /etc/php.ini

编辑配置文件使用 vim 编辑器,如 vim /etc/nginx/nginx.conf 的方式


3.1.3、部署 wordpress 与修改 nginx 配置文件

我们需要去 wordpress 下载最新版的 wordpress,中文版可以访问 [ 链接 ]

使用 wget 下载最新版的文件到 VPS 中,你可以使用 cd 命令进入到所需的目录。
在这里,如果选择 tar.gz 则使用命令 tar -xf 解压,如果选择 zip 则使用命令 unzip 解压。

cd /var/www/
wget -c https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz -O wordpress.tar.gz
tar xf wordpress.tar.gz

解压后,可以使用命令 ls -al 查看到 wordpress 的文件夹,再次使用 ls -al wordpress 则可以看到所有文件。
此时我们需要配置文件夹的权限,允许 nginx 访问

chown -R nginx:nginx wordpress
ls -al wordpress
drwxr-xr-x 2 nginx nginx 4096 Nov 30 16:00 wordpress

再次查看时,可以看到原来的两个 root 换为了 nginx。
然后关于 wordpress 的配置待会继续。我们调试 nginx

默认情况,Nginx 会存在一份初始站点文件在 nginx.conf 最下面(还有一份 https 的默认被注释),如下所示

vim /etc/nginx/nginx.conf
******
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
******

可以将此内容全部注释掉,防止 Nginx 的默认页面泄露信息。方式是在这段文字每行前面(注意是 {} 圈住的区域),添加一个 # 的符号。
编辑方式为 按一下键盘的字母 i 键,左下角出现 — INSERT — 时为输入状态,退出则按一下 Esc  变为标准状态。
VIM 编辑器如何使用可以参照

简明 VIM 练级攻略  [ 链接 ]

然后我们添加一个默认页面,此页面匹配的所有非本服务器的 hostname 访问进来时的页面,文字输入在此备注段的上方即可

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        return 404;
    }

接着,保存并退出。(按两下 Esc,然后输入一个 : 符号 (英文冒号),接着在左下角输入 wq 保存并退出)
仅退出使用 :q 如果修改过但是不想保存使用 :q! 如果文件没允许写入但是你有文件所有权,可以用 wq! 强制保存
然后,在关于刚刚那份备注的默认配置上方,可以看到一个调用 include 配置

include /etc/nginx/conf.d/*.conf;

于是我们进入这个/etc/nginx/conf.d 文件夹中,创建我们真正的站点文件,如下所示

vim /etc/nginx/conf.d/wordpress.conf

server {
    listen   80;
    listen   [::]:80;
    server_name  your.domain.name;
    root         /var/www/wordpress;
    access_log  /var/log/nginx/wordpress.log  main;

    location / {
        try_files $uri $uri/ /index.php?$args;
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;
        index  index.php;
    }

    location ~ \.php$ {
         fastcgi_pass   127.0.0.1:9000;
         fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
         include        fastcgi_params;
    }
}

配置输入完毕后,我们就可以访问了。( 注意后缀 ; 符号 )
注意:上方 server_name your.domain.name; 这条信息,需要修改为你的 url 的域名,或者是 IP 地址。
相关配置可以参考 WordPress 官方文章

Nginx 关于 WordPress 的配置文件 [ 链接 ]

如果你想将站点改为 https 加密访问,可以参考本站的两篇文章

使用 Let’s Encrypt 生成 SSL 证书 [ 链接 ]
增强 Nginx 的 SSL 安全性 [ 链接 ]

此时,你可以开始 WordPress 的 5 分钟安装流程,安装完毕后进入 wordpress。
备注:可能 nginx 没有权限创建新的文件,此时手动创建 wp-config.php 即可


3.2、Mariadb 的 10.2 版本安装

上面,你看完了一份最简单的 LNMP 安装流程,你可能觉得,就这么简单?我拿脚本跑一次都没有问题。

但是,现在,有人和你说,Mysql 的 5.4 版本有重大漏洞,赶紧升级,输入 mysql –version 查看自己的版本号正好时 5.4。但是你会发现,哎?yum 安装的怎么升级啊,我尝试 yum update 但是没有更高的版本啊

所以我们需要更换 yum 源了,Mariadb 有很简单的 yum 源更换方法 [ 链接 ]

vim /etc/yum.repos.d/MariaDB.repo

# MariaDB 10.2 CentOS repository list - created 2018-03-21 08:45 UTC
# http://downloads.mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

然后我们需要清理 yum 的缓存,使用命令 yum clean all 清除所有缓存。
接着我们就可以安装最新版的 mariadb 了

yum install -y MariaDB-server MariaDB-client

3.3、PHP7.2 的编译安装

3.3.1、编译 PHP7.2

上面的 LNMP 环境你也搭建好了。wordpress 也正常使用了,但是你看到 php7 新版本有很多特性,其中最主要的一条就是稳定性提升。并且 yum 安装的 php 版本也有些许问题 (其实还是版本太低的锅),于是该怎么升级呢?

其实 PHP 我们可以使用编译的方式安装,一方面组件可控,一方面可以随意复制出去重复部署。还可以保证版本的固定不会随时升级到新的版本。
不过安装前,首先还是要做好编译环境。

yum -y groupinstall "Development Tools"
yum install -y gcc gcc-c++ autoconf libmcrypt libmcrypt-devel libjpeg libjpeg-devel libpng libpng-devel libxml2 libxml2-devel curl curl-devel openssl openssl-devel freetype freetype-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses gdbm-devel db4-devel libXpm-devel libX11-devel gd-devel gmp-devel readline-devel libxslt-devel expat-devel xmlrpc-c xmlrpc-c-devel

wget http://cn2.php.net/distributions/php-7.2.3.tar.gz
代码解释:下载 php-7.2.3.tar.gz 文件
tar xf php-7.2.3.tar.gz && cd php-7.2.3
代码解释:解压缩 php-7.2.3.tar.gz 文件并进入解压后的文件夹
./buildconf --force
代码解释:清空编译配置

完事后,我们正式调整编译参数,下方的这个很全面的参数来源于 [ 链接 ]

./configure --prefix=/usr/local/php7 --exec-prefix=/usr/local/php7 --bindir=/usr/local/php7/bin --sbindir=/usr/local/php7/sbin --includedir=/usr/local/php7/include --libdir=/usr/local/php7/lib/php --mandir=/usr/local/php7/php/man --with-config-file-path=/usr/local/php7/etc --with-mysql-sock=/var/lib/mysql/mysql.sock --with-mcrypt --with-mhash --with-openssl --with-mysql=shared,mysqlnd --with-mysqli=shared,mysqlnd --with-pdo-mysql=shared,mysqlnd --with-iconv --with-zlib --enable-zip --with-bz2 --enable-inline-optimization --disable-debug --disable-rpath --enable-shared --enable-xml --enable-bcmath --enable-shmop --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-mbregex --enable-mbstring --enable-ftp --with-readline --with-gd --enable-gd-native-ttf --enable-gd-jis-conv --with-libxml-dir --enable-pcntl --enable-sockets --with-xmlrpc --enable-soap --without-pear --with-gettext --enable-session --with-curl --with-jpeg-dir --with-freetype-dir --enable-opcache --enable-fpm --enable-fastcgi --with-fpm-user=nginx --with-fpm-group=nginx --without-gdbm --disable-fileinfo

这个命令运行可能需要 1~5 分钟,运行完毕后的结果如下

Generating files
configure: creating ./config.status
creating main/internal_functions.c
creating main/internal_functions_cli.c
+--------------------------------------------------------------------+
| License: |
| This software is subject to the PHP License, available in this |
| distribution in the file LICENSE. By continuing this installation |
| process, you are bound by the terms of this license agreement. |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point. |
+--------------------------------------------------------------------+

Thank you for using PHP.

config.status: creating php7.spec
config.status: creating main/build-defs.h
config.status: creating scripts/phpize
config.status: creating scripts/man1/phpize.1
config.status: creating scripts/php-config
config.status: creating scripts/man1/php-config.1
config.status: creating sapi/cli/php.1
config.status: creating sapi/fpm/php-fpm.conf
config.status: creating sapi/fpm/www.conf
config.status: creating sapi/fpm/init.d.php-fpm
config.status: creating sapi/fpm/php-fpm.service
config.status: creating sapi/fpm/php-fpm.8
config.status: creating sapi/fpm/status.html
config.status: creating sapi/cgi/php-cgi.1
config.status: creating ext/phar/phar.1
config.status: creating ext/phar/phar.phar.1
config.status: creating main/php_config.h
config.status: executing default commands
configure: WARNING: unrecognized options: --with-mcrypt, --with-mysql, --enable-gd-native-ttf, --enable-fastcgi

在这里说明,不要出现 Error,出现 Error 代表参数配置失败,一般很容易是因为内存不足,还有可能是其他原因。
如果内存不足可以创建 swap 分区并挂载,即可解决。

configure: WARNING: unrecognized options: –with-mcrypt, –with-mysql, –enable-gd-native-ttf, –enable-fastcgi
这段信息中,代表着这些参数已经被废弃,在 PHP7.2 中 –enable-gd-native-ttf, –enable-fastcgi 两个参数被额外废弃。

接着我们开始编译,使用命令如下

make clean
代码解释:清空历史的编译记录

make -j2
代码解释:使用双线程编译,可以不输入直接 make 单线程编译

编译时间估计是 3~20 分钟 (单核),编译后请仔细注意结果,一定要无错误。正常结果如下

Build complete.
Don't forget to run 'make test'.

确认没问题后,我们开始安装编译后的文件,使用命令如下

make install

安装好后的结果可以参考下面

/bin/sh /root/make/php/php-7.2.3/libtool --silent --preserve-dup-deps --mode=install cp ext/mysqli/mysqli.la /root/make/php/php-7.2.3/modules
/bin/sh /root/make/php/php-7.2.3/libtool --silent --preserve-dup-deps --mode=install cp ext/pdo_mysql/pdo_mysql.la /root/make/php/php-7.2.3/modules
/bin/sh /root/make/php/php-7.2.3/libtool --silent --preserve-dup-deps --mode=install cp ext/opcache/opcache.la /root/make/php/php-7.2.3/modules
Installing shared extensions: /usr/local/php7/lib/php/extensions/no-debug-non-zts-20170718/
Installing PHP CLI binary: /usr/local/php7/bin/
Installing PHP CLI man page: /usr/local/php7/php/man/man1/
Installing PHP FPM binary: /usr/local/php7/sbin/
Installing PHP FPM defconfig: /usr/local/php7/etc/
Installing PHP FPM man page: /usr/local/php7/php/man/man8/
Installing PHP FPM status page: /usr/local/php7/php/php/fpm/
Installing phpdbg binary: /usr/local/php7/bin/
Installing phpdbg man page: /usr/local/php7/php/man/man1/
Installing PHP CGI binary: /usr/local/php7/bin/
Installing PHP CGI man page: /usr/local/php7/php/man/man1/
Installing build environment: /usr/local/php7/lib/php/build/
Installing header files: /usr/local/php7/include/php/
Installing helper programs: /usr/local/php7/bin/
    program: phpize
    program: php-config
Installing man pages: /usr/local/php7/php/man/man1/
    page: phpize.1
    page: php-config.1
/root/make/php/php-7.2.3/build/shtool install -c ext/phar/phar.phar /usr/local/php7/bin
ln -s -f phar.phar /usr/local/php7/bin/phar
Installing PDO headers: /usr/local/php7/include/php/ext/pdo/

3.3.2、配置编译好的 PHP7

光编译,不安装,等于没用。仅仅相当于你获得了一堆能在你电脑跑的代码,但是怎么用得去手动配置。

首先我们需要在编译的文件夹内,复制出 php-fpm 的进程文件 php-fpm
还有和 php 的配置文件 php.ini 也要复制出来

cp php.ini-production /usr/local/php7/etc/php.ini
代码解释:复制 php 配置文件
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
代码解释:复制 php-fpm 服务文件到系统进程中中并重命名为 php-fpm
chmod +x /etc/init.d/php-fpm
代码解释:赋予 php-fpm 运行权限
chkconfig --add php-fpm
代码解释:添加 php-fpm 到服务
chkconfig php-fpm on
代码解释:设置 php-fpm 开机启动
(此时可以同样使用 systemctl enable php-fpm 进行配置开机启动操作)

接着,我们进入到/usr/local/php7/etc/目录下,创建 php-fpm 的配置文件

cd /usr/local/php7/etc/
代码解释:进入 PHP 的配置文件目录
cp php-fpm.conf.default php-fpm.conf
代码解释:复制 php-fpm 配置文件
cp php-fpm.d/www.conf.default php-fpm.d/www.conf
代码解释:复制 php-fpm 调用的站点配置文件

此时文件已经生成完毕了,我们开始修改配置文件。

首先我们编辑 php.ini 文件,加载一下所需要的模块(以下内容,左侧标记中 < 为原配置,> 为新配置 ,前面 ; 代表原来是注释)

< expose_php = On 
> expose_php = Off
< ;extension_dir = 
> extension_dir = "/usr/local/php7/lib/php/extensions/no-debug-non-zts-20170718/"
备注:这个需要根据你编译时 make install 里面第一条 Installing shared extensions 修改,主要是日期有变化。

< ;extension=mysqli
> zend_extension=opcache.so
> extension=mysqli.so
> extension=pdo_mysql.so
备注:这个是关联上面那条内容的,代表动态加载这些文件,所以是必须的

< upload_max_filesize = 2M 
> upload_max_filesize = 8M
备注:这个配置代表着上传单个文件最大大小的限制,默认 2MB,建议改为 8MB

< date.timezone = 
> date.timezone = PRC
备注:这个配置代表着 PHP 所在时区,PRC 中国时区

< pdo_mysql.default_socket= 
> pdo_mysql.default_socket = "/var/lib/mysql/mysql.sock"
备注:这个配置指定了 mariadb 的 socket 文件
< mysqli.default_socket = 
> mysqli.default_socket = "/var/lib/mysql/mysql.sock"
备注:这个配置指定了 mariadb 的 socket 文件

< ;opcache.enable=1 
> opcache.enable=1
备注:这个配置开启了 opcache 支持。

注意! 以下两条内容为提高安全, 如果不理解请不要添加
< open_basedir = 
> open_basedir = "/var/www/:/tmp/"
此命令为限制 PHP 工作目录,限制 PHP 命令可访问的范围
< disable_functions = 
> disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,dl,pfsockopen
此命令为限制 PHP 使用的参数,为防止网站注入 PHP 后门导致渗透

然后我们编辑 php-fpm.d/www.conf 这个被调用的站点文件,添加以下内容

php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
备注:直接在最后面添加 session 配置,这样所有的会话都保存为文件,保证了会话的稳定性。
(当然你还可以到 php.ini 中修改 session 持续时间等参数)

同时,改好这个配置后,你需要创建 session 文件夹

mkdir -p /var/lib/php/session
代码解释:创建文件夹
chown -R nginx:nginx /var/lib/php
代码解释:配置文件夹所有者为 nginx

配置文件修改好后,我们需要增加一下环境变量,让 php-fpm 命令可以执行

echo -e '\nexport PATH=/usr/local/php7/bin:/usr/local/php7/sbin:$PATH\n' >> /etc/profile && source /etc/profile
代码解释:在/etc/profile 结尾添加一段文字,并刷新 /etc/profile(执行一次就足够了,执行多了最好去把多余的信息删掉只留下一个)

以上一切内容都修改完毕后,我们可以开始测试 php-fpm 配置是否正常,如下则为正常结果

php-fpm -t

NOTICE: configuration file /usr/local/php7/etc/php-fpm.conf test is successful


3.3.3、运行与管理

当配置文件都测试通过后,我们可以运行 php-fpm 了

systemctl start php-fpm

实际上支持以下参数,可以对应输入命令。
{start|stop|force-quit|restart|reload|status|configtest}
命令意义对应:开启、关闭、速停、重启、重载、状态、配置测试


3.4、CentOS 内核升级为 Google-BBR 的安装

3.4.1、安装 BBR

现在我们又有了新想法,centos 内核太老了很多功能不支持,速度也慢,那么我们换一个最新的内核怎么样?(参考 秋水逸冰)

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
安装 elrepo 源,支持最新版 linux 内核
yum --enablerepo=elrepo-kernel -y install kernel-ml kernel-ml-devel
安装最新版 linux 内核
sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf
sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf
echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
sysctl -p >/dev/null 2>&1
修改内核配置支持 bbr 协议
grub2-set-default 0
修改启动项为新安装的 Linux 内核
reboot
重启并加载新的 Linux 内核版本,重启后检查是否开启了 BBR 即可。

如果你有想法将内核整个更换为新的内核,则还需要更换 headers 和 tools 还有 tools-libs 这三个内核组件

yum remove kernel-headers kernel-tools kernel-tools-libs
删除 CentOS 自带内核的组件。

执行命令后 请注意都卸载了哪些东西 (在 Removing for dependencies: 下面的所有东西),如果按照上方操作,默认会卸载 gcc 和 gcc-c++和 glibc-devel 和 glibc-headers 这四个。
卸载的东西之后要重新安装回去,不用担心,重安装的版本是一样的,而且重安装的都是编译的工具。

yum --enablerepo=elrepo-kernel -y install kernel-ml-headers kernel-ml-tools kernel-ml-tools-libs kernel-ml-tools-libs-devel
安装新版本内核的扩展组件。
yum --enablerepo=elrepo-kernel -y install kernel-ml kernel-ml-devel kernel-ml-headers kernel-ml-tools kernel-ml-tools-libs kernel-ml-tools-libs-devel
安装最新版 BBR 内核与组件

而如果将来更新内核导致内核版本过多,可以使用 rpm 卸载对应的内核减少空间占用


3.4.2、检查 BBR
uname -r
 查看内核版本号,注意字段"4.15.10-1.el7.elrepo.x86_64"类似的,版本大于 4.13 以上即可。
sysctl net.ipv4.tcp_available_congestion_control
 查看系统支持的 TCP 拥塞算法,在输出结果中查看到有 bbr 即可
sysctl net.ipv4.tcp_congestion_control
 查看系统现在设置的 TCP 拥塞算法,在输出结果中查看到仅为 bbr 即可
sysctl net.core.default_qdisc
 返回值为 fq 字样即可
lsmod | grep bbr
 最后查看系统加载的模块,返回结果中有 tcp_bbr 模块即可

4、讲解

4.1、LNMP 讲解

4.1.1、yum 的一些小程序

git  是一份包管理工具,可以使用 git clone 从 github 上获取到对应的软件。
vim 是 linux 的文件编辑器,由于各方面功能都比 vim 强大,并且可以对代码添加色彩方便区分。
wget 是 linux 的文件下载工具,使用 wget -c 命令可以断点续传。额外使用 -O 参数可以修改下载下来的文件名称。
有些时候,可能由于时间,或者中间人攻击等方式导致证书失效,可以使用另一个参数 –no-check-certificate 忽略证书。
curl 是 linux 的下载工具和 url 相关的工具,当然我们一般用 curl 模拟提交 url 访问。
unzip 是 linux 的解压 zip 的软件。
net-tools 是 linux 的网络调试工具包,里面包含了 ifconfig 和 netstat 等所需的命令
rpm 是包管理的命令 (重要),-q 参数可以查询相关的包,-l 参数输出所有关联文件,-a 参数输出所有 rpm 包名,-e 卸载指定的包


4.1.2、EPEL 源的手动安装方法

rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-7.noarch.rpm
代码解释:RPM 下载并安装 EPEL 源
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
代码解释:导入 EPEL 源的 GPG-KEY
yum repolist
代码解释:重新加载 Yum 源


4.1.3、Mariadb 数据库的基本初始化

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):
请输入 Root 的密码,初次使用可以直接回车 (空密码)
Change the root password? [Y/n] y
是否修改 Root 的密码
Remove anonymous users? [Y/n] y
是否删除匿名用户
Disallow root login remotely? [Y/n] y
是否禁止 root 用户的远程登陆
Remove test database and access to it? [Y/n] y
是否删除默认安装的测试数据库
Reload privilege tables now? [Y/n] y
是否刷新数据库

4.1.4、Mariadb 数据库的基本管理

mysql -uroot -p
代码解释:使用 [email protected] 登陆 Mysql (默认本机登陆源为 localhost)
MariaDB [(none)]> show databases;
代码解释:查看当前用户可访问的所有的数据库
MariaDB [(none)]> create database wordpress;
代码解释:创建数据库,名称为 wordpress
MariaDB [(none)]> drop database wordpress;
代码解释:删除数据库,名称为 wordpress
MariaDB [(none)]> use wordpress;
代码解释:打开数据库,名称为 wordpress
MariaDB [(none)]> create user 'hello'@'localhost' identified by 'Welcome';
代码解释:创建用户 hello,登录源 localhost,登录密码为 Welcome
MariaDB [(none)]> GRANT ALL ON wordpress.* TO 'hello'@'localhost';
代码解释:赋予 [email protected] 关于 wordpress 数据库的所有权限
MariaDB [(none)]> flush privileges;
代码解释:刷新 Mysql 的数据库表
MariaDB [(none)]> exit
代码解释:退出 Mysql 的 Shell


4.1.5、文件和数据库的备份与还原

mysqldump -uroot -p wordpress > wp.sql
代码解释:将 wordpress 数据库信息保存到 wp.sql 文件中 (输入密码)
可以添加 --default-character-set=utf8 参数强制字符格式为 utf8 (有些数据库默认是 utf8mb4 格式)

mysql -uroot -p wordpress < wp.sql
代码解释:将 wp.sql 文件的信息导入到 wordpress 数据库中 (输入密码)

tar zcvpf /root/wordpress.tgz wordpress
代码解释:将 wordpress 目录所有文件打包到 /root/wordpress.tgz 中 (保留权限+高压缩)

tar zxvpf wordpress.tgz -C /website/wordpress
代码解释:将 wordpress.tgz 解压到 /website/wordpress 中

zip -r /root/wordpress.zip wordpress
代码解释:将 wordpress 目录所有文件打包到 /root/wordpress.zip 中 (不保留权限)

unzip wordpress.zip -d /website/wordpress
代码解释:将 wordpress.zip 解压到 /website/wordpress 中

如果你想自动化备份,可以参考本站以前的文章
用 Shell 脚本备份服务器 [ 链接 ]


4.1.6、文件上传时的限制配置

Nginx 也有针对文件上传时的限制配置,如下两条,包含在/etc/nginc/nginx.conf 中

http {
  sendfile on;
  client_max_body_size 10m;
}

第一条是否开启文件上传,第二条限制最大上传文件大小,默认 1MB,建议修改为 10MB


4.1.7、系统文件最大打开数等一些上限的限制

linux 存在最大文件打开数和最大进程数,默认 Linux 设置为 1024,这远远不够。
我们可以使用命令临时修改此值 ulimit -SHn 50000 将最大文件数改为 50000

如果需要永久,则需要编辑/etc/security/limits.conf 文件,添加两条信息 (#为注释)

#<domain> <type> <item> <value>
#
* hard nofile 50000
* soft nofile 50000

然后查看/etc/pam.d/login 文件是否含有以下字段,如果没有则添加

session required pam_limits.so

之后重启系统,输入 ulimit -n 检查是否成功修改。
还有一种懒办法 vi /etc/rc.local 在 exit 0 上面添加 ulimit -n 50000 一行内容并保存即可 (Centos7 还需要 chmod +x /etc/rc.local 赋予开机启动权限)

Nginx 也有限制最大文件打开数,包含在/etc/nginc/nginx.conf 的最前面一部分

worker_processes 1;  #工作进程数,和内核数相等最好
worker_rlimit_nofile 40960;  #单进程最大文件打开数,手动指定后可以小于系统设置 (无法超过)

Nginx 也有限制最大并发连接数,包含在/etc/nginc/nginx.conf 中

gevents {
 worker_connections 1024;
 }

默认值 1024,建议修改大一些,比如 4096,看 nginx 实际有多少访问量而定。


4.1.8、服务和防火墙的一些操作命令

systemctl enable nginx
配置 Nginx 开机启动
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

systemctl disable nginx
取消 Nginx 开机启动
Removed symlink /etc/systemd/system/multi-user.target.wants/nginx.service.

systemctl status nginx -l
查看 Nginx 服务状态,并显示详细信息
● nginx.service – The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: inactive (dead)

此时可以看到服务脚本文件的位置 “/usr/lib/systemd/system/nginx.service” 此时如果有修改 PID 等信息就可以改了

Firewall 防火墙是一个动态防火墙,作为替代 iptables 的存在,可以 firewall-cmd 动态管理网络。服务名 Firewalld,底层仍然使用 iptables 管理网络。

Firewall 声明的协议文件在 /usr/lib/firewalld/services/ 中,每个文件里包含了对应的端口,并以文件名为协议名
(如果 Firewall 通过 yum 更新,则会复写所有自带配置文件将其恢复原样,但是可以通过新增其他名称的协议避免)

firewall-cmd --add-service=http --permanent
允许服务器被 http 协议访问 (以后永久生效,当前无效,默认 public)

firewall-cmd --add-service=http
允许服务器被 http 协议访问 (当前临时生效,重启失效,默认 public)

firewall-cmd --zone=work --add-service=http
允许服务器指定区域 work 被 http 协议访问

firewall-cmd --remove-service=http --permanent
禁止服务器被 http 协议访问 (以后永久生效,当前无效)

firewall-cmd --add-port=1080/tcp --permanent
允许服务器的 1080 端口被访问

firewall-cmd --remove-port=1080/tcp --permanent
禁止服务器的 1080 端口被访问

firewall-cmd --reload
重新加载 Firewall 所有配置文件 (包括协议文件夹)

firewall-cmd --list-all
查看当前 Firewall 防火墙的规则列表 (默认区域 public)

firewall-cmd --query-service=ssh
查询指定协议 SSH 是否开启

firewall-cmd --query-port=1080/tcp
查询指定 TCP 端口 1080 是否开启 (不在协议中查询)

firewall-cmd --get-zones
查询当前服务器存在哪些区域

firewall-cmd --get-active-zones
查询所有区域信息并显示区域所对应控制的物理端口
(默认区域 public,并绑定所有物理接口)

其实 public 区域的配置文件在 /etc/firewalld/zones/ 中,默认区域 public 的就是 public.xml


4.2、PHP7.2 关于 Socket 讲解

 默认情况下,php-fpm 采用端口 9000 作为监听端口,此时其他程序通过 tcp/ip 的方式访问进来,当多个同时访问时采用 tcp/ip 的拥塞管理。
但是,这种方式存在几个问题,一个是安全问题,如果有人使用外网访问到 9000 端口则产生攻击,一个是拥塞导致的不稳定。
但是 PHP 等各类软件,还有另一种方式通讯,那就是 UNIX,使用 sock 文件进行通讯,俗称套接字 socket
此方式避免了上面的问题,稳定性提升很高,并且可以独立配置每个套接字的属性。缺点则是最高负载承担没有端口的多。

配置参考 [ 链接 ]

而在 php-fpm.d/www.conf 这个站点配置文件中,就可以修改为 socket 方式通讯,当然你要是喜欢配多个站点完全没有问题。
但是实际上,仅改为 socket 方式,仍然存在高并发卡死的现象,所以我们需要继续修改。

listen.backlog = 10240  ; 总队列容量限制
pm = dynamic  ; 将 php-fpm 进程管理改为动态管理
pm.max_children = 50  ; 最大同时进程数量
pm.start_servers = 20  ; 服务启动时运行的进程数量
pm.min_spare_servers = 10  ; 空闲最小进程数
pm.max_spare_servers = 30  ; 空闲最大进程数
rlimit_files = 5000  ; 单进程最大相应数量,超过则进程重启

4.3、后台运行命令讲解

当你编译 PHP 时,不小心断了 SSH 链接会发生什么?那就是你之前的等待都白等了,重头再来。
对于这种中断事件,我们当然要尽力避免,

yum install -y screen

安装好后,我们可以使用 screen -S 窗口名 创建一个新的会话窗口,此窗口在 SSH 断开后仍然存在。

screen -S screenname

在 ps -auxf 中可以观察到,SSH 链接的父进程是 SSH 登陆用户的 shell。但是断开后,父进程变为 init。
如果我们断开后想连回去怎么办?我们输入 screen -r 窗口名就可以恢复回去了

screen -r screenname

如果不小心创建了多个相同名称的会话窗口,或者此窗口已被其他人占用,则此时会弹出提示。

There is a screen on:
 9144.screenname (Attached)
There is no screen to be resumed matching screenname.

这时候我们需要使用参数 -xr 进入指定进程 ID 的会话窗口,9144 是此会话窗口的进程 ID

screen -xr 9144.screenname

实际上,我们可以做一个小脚本,每次想进入会话窗口的时候就使用此脚本即可

#!/bin/bash
scname=screenname
ps -ef | grep $scname | grep -v grep
if [ $? -ne 0 ]
then
screen -S "$scname"
else
sc=$(screen -r $scname | grep "Attached" | awk '{print $1}')
screen -xr $sc
fi

4.4、权限错误和 su 和 sudo 相关

当你在 Linux 中输入一些命令发生错误时,有一种情况代表权限问题

(比如 /usr/bin/cd /root )
-bash: cd: /root: Permission denied 
此错误含义是权限不足 (Permission denied),属于命令执行主体对文件的权限不足 (包括 SElinux)

(比如  firewall-cmd --list-all )
Authorization failed.
此错误含义是权限不足 (Authorization failed.),属于命令执行主体被此命令本身审核后的权限不足

(比如 systemctl restart network )
 ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or units.
Authenticating as: user
Password:
polkit-agent-helper-1: pam_authenticate failed: Authentication failure
==== AUTHENTICATION FAILED ===
Failed to restart network.service: Access denied
See system logs and ‘systemctl status network.service’ for details.
[FAILED]
此错误含义是身份验证失败 (Access denied),属于系统权限的限制。

平时情况下,我们可以去修改一些权限,配置等方式解决。但是如果此命令或文件需要的是 root 权限怎么办?
这时候我们就需要提升到 root 权限了。此时有两种方式

1、使用 su 命令切换到 root 用户,并需要输入 root 用户密码 (root 切换其他用户无需密码)

切换后,可以观察到 [[email protected] ~]$变为了 [[email protected] ~]$此时再输入命令就都没问题了
注意: 由于 root 拥有最高权限,即使是删除系统内核都是被允许的,所以请小心操作。

2、使用 sudo 命令提升单条命令为最高执行权限,并需要输入本账户密码

使用此命令前提是用户允许执行 sudo 命令,前提是用户加入到 wheel 用户组中
gpasswd -a username wheel
此命令也很重要,因为可以使用 sudo su root 切换到 root 用户中,并且不需要 root 密码。

所以,如果需要权限时,可以使用这些命令提升自己的权限,但是请注意 权限越高危险越大

最后额外说一点,如果你的账户的 Shell 是 /sbin/nologin 则你使用此账户登陆 Linux 系统后无任何 Shell。一般是用来限制运行程序的用户权限级别。(如 Nginx,Mysql 这些用户)

如果你想创建一个这样的用户,可以使用此命令创建(无 Shell 并且用户文件夹为空)
useradd -s /usr/sbin/nologin -r -M -d /dev/null username


4.5、查看系统版本和内核的命令

uname -a
输出当前系统的内核信息
Linux localhost.localdomain 3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

cat /etc/redhat-release
查看当前系统的 Redhat 系列版本号
CentOS Linux release 7.4.1708 (Core)

cat /proc/version
查看当前系统的内核信息
Linux version 3.10.0-693.21.1.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) ) #1 SMP Wed Mar 7 19:03:37 UTC 2018

lsb_release -a
查看当前系统 LSB 和版本信息

LSB Version: :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.4.1708 (Core)
Release: 7.4.1708
Codename: Core

如果没有 lsb_release 命令,可以使用 yum 安装
yum install redhat-lsb-core

而如果想降版本,比如由 CentOS7.3 降为 CentOS7.2 可以参考下列命令

第一步安装 3.10.0-327 内核
rpm -ivh http://vault.centos.org/7.2.1511/os/x86_64/Packages/kernel-tools-libs-3.10.0-327.el7.x86_64.rpm --force
rpm -ivh http://vault.centos.org/7.2.1511/os/x86_64/Packages/kernel-tools-3.10.0-327.el7.x86_64.rpm --force
rpm -ivh http://vault.centos.org/7.2.1511/os/x86_64/Packages/kernel-3.10.0-327.el7.x86_64.rpm --force
rpm -qa | grep -i kernel

第二步加载 Release7.2 版本
wget ftp://ftp.icm.edu.pl/vol/rzm5/linux-slc/centos/7.1.1503/updates/x86_64/Packages/centos-release-7-2.1511.el7.centos.2.10.x86_64.rpm
rpm -ivh centos-release-7-2.1511.el7.centos.2.10.x86_64.rpm --force
rpm -qa | grep -i centos-release

第三步卸载 Release7.3 版本与 3.10.0-514 内核
rpm -ev centos-release-7-3.1611.el7.centos.x86_64
rpm -ea kernel-3.10.0-514.el7.x86_64
rpm -ea kernel-3.10.0-514.10.2.el7.x86_64

操作完毕,重启检查内核 (可能会需要修改启动项)
reboot

uname -r 
cat /etc/redhat-release

4.6、创建 Swap 虚拟内存

dd if=/dev/zero of=/swap bs=1024 count=512000
创建 swap 文件,在根目录/下,分区单位 1024,大小 512MB(count=size(MB)*1024)
mkswap /swap
格式化/swap 文件为 Swap 虚拟内存格式
swapon /swap
开启 Swap 虚拟内存挂载/swap
swapoff /swap
关闭 Swap 虚拟内存挂载/swap

4.7、使用 History 查阅历史命令

有时候我们需要查阅历史命令,这时候可以使用 History 命令查阅

默认 History 读取的是用户目录下的 .bash_history  文件,相同的历史记录文件还有 .mysql_history 和 .viminfo 记录的数据库所有命令和 VIM 修改文件记录

我们可以使用下列命令让 History 显示时间戳(仅限当前会话)

HISTTIMEFORMAT="%F %T `whoami` "

如果想永久让 History 显示时间戳,可以将此写入到/etc/profile 文件中

echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/profile

History 命令默认按顺序显示当前 Shell 的所有命令记录,记录是保存在当前 shell 进程内存中,但是他可能会因为 SSH 的多 Shell,或者异常断开等多种原因导致存在内存的记录没有保存到硬盘,所以经常容易丢掉记录。并且由于存储时不会保存时间戳,所以你读取历史的记录时会发现时间戳是写入到硬盘时的时间戳。


4.8、文件权限与使用 Find 过滤修改权限

文件权限分为 读取 R 写入 W 执行 X
文件夹权限分为 列出 R 删除 W 打开 X

而对于 RWX 在 Linux 中是可以使用数字标记的,将这三位作为二进制,则 R=4/W=2/X=1
所以如果一个文件的权限是 6 代表这个文件是 可读取 可写入 不可执行

而对于一个文件/文件夹,在 Linux 的权限中有三种区分,所属用户,所属用户组,其他人
所以,对于一个文件,是存在三个 8 进制数字,分别对应用户权限,用户组权限,其他人权限

默认 Linux 给予文件夹 755 权限,给予文件 644 权限。

例如,我们使用 ls -al 查看到一个文件信息如下
-rwxrw-r– 1 user group 432 Apr 10 10:00 hello.txt
这个 hello.txt 文件的权限就是 764,而后面它属于 user 用户,属于 group 用户组,文件大小 432B

例如,我们使用 ls -al 查看到一个文件信息如下
drwxr-xr-x 2 root root 4096 Nov 12 10:00 hello.txt
这个 hello.txt 文件夹的权限就是 755,而后面它属于 root 用户,属于 root 用户组
前面的  代表这个文件类型是文件夹,所以你能看到文件夹在 linux 中是当作一个文件处理的

以上信息理解之后,现在我们想修改一个文件权限需要怎么修改?

我们使用命令 chmod 修改权限,如 chmod 744 hello.txt 修改一个文件权限
我们使用命令 chown 修改所有者,如 chown user:group hello.txt 修改一个文件的所有者为 user,所有组为 group

而如果我们要修改一个文件夹下的所有文件权限,我们可以使用 -R 参数递归修改,如 chmod -R 744 hello* 修改所有前缀为 hello 的文件和文件夹的权限。

但是此时,我们有了一个问题,那就是如果这个文件夹下面还有文件夹,由于文件夹和文件的权限代表的意义不同,我们应该如何区分修改?

这时我们可以使用 Find 过滤文件类型,指定文件类型进行修改

find ./ -type f -exec chmod 644 {} \;
将当前目录下的所有文件(递归)设置为 644
find ./ -type d -exec chmod 755 {} \;
将当前目录下的所有文件夹(递归)设置为 755

如果不太理解,可以参考这两篇文章

Linux 用户和用户组基本概念 [ 链接 ]
Linux 基础知识之文件权限详解 [ 链接 ]


5、后期修订

2018/03/28 增加 su 和 sudo 相关介绍、VIM 使用参考链接

2018/04/10 增加 kernel 查阅、swap 创建与挂载、文件权限与使用 Find 过滤修改


6、相关链接

Mariadb 最新的官方 yum 源更换方法 [ 链接 ]

TypeCodes 的 PHP 编译配置 [ 链接 ]

简明 VIM 练级攻略 [ 链接 ]

秋水逸冰的 BBR 脚本 [ 链接 ]

使用 socket 管道套接字进行通信 [ 链接 ]

Nginx 关于 WordPress 的配置文件 [ 链接 ]

使用 Let’s Encrypt 生成 SSL 证书 [ 链接 ]

增强 Nginx 的 SSL 安全性 [ 链接 ]

Linux 服务器使用密钥登录 [ 链接 ]

用 Shell 脚本备份服务器 [ 链接 ]

Linux 用户和用户组基本概念 [ 链接 ]

Linux 基础知识之文件权限详解 [ 链接 ]

点赞