之前我的一个CentOS 7 Apache的站点被攻击,导致流量过载损失了一笔钱,由于也是边学习边部署的,有不少安全隐患,为了避免常见安全隐患再次发生,后来找出大概的原因后决定重新部署一个基于CentOS 8 Nginx的服务器。这也是充分利用Google和自己探索的一些从零部署的技巧和方法。
注意:请按照由上至下的顺序操作,不保证每个人的Linux服务器都没有差错,如果保证服务器系统的纯净,大体上是没有问题的,如果出现问题可以自己根据问题日志谷歌一下寻找原因。我自己也是这么一步一步过来的。
购买完CentOS 8.0版本的服务器之后,就可以正式开始从零部署咯,因为我的主系统是使用WordPress,因此我的配置也是需要支持PHP的,当然Node也是需要的(同理你可以配置支持其它后端语言),我把一些用到的配置和命令都整理成文章,也方便自己未来查阅巩固。同时对于一个从来没有部署过或者使用过其它配置的Linux服务器的你,相信也能够提供不少帮助。目前自己的那个网站运营三个月以上暂没有受到相同的攻击和流量注入,对于一个新人来说我还是比较满意的,不求人,靠自己稳定运营下去:)
服务器需要支持的基础功能关系如下:
整体步骤分为下面的八个:
(一)购买VPS,设置Server Hostname
(二)Point a Domain Name to a Server域名指向
(三)CentOS8系统-进程监控和bandwidth带宽监控
(四)安装解压软件
(五)CentOS 8.0 LEMP (with Nginx, MySQL , and PHP-FPM)安装
(六)增加Nginx维护页面,临时维护使用
(七)完成 LEMP基础配置后,升级性能和安全性,其它配置
(八)Node环境配置(请完成此文档上面所有步骤后再继续)
开始之前,我们先熟悉一些整个过程常用的一些命令:
#VI相关操作: #在用vi创建文件后,点击 i 即可进入编辑文本模式的insert状态,再点击ESC即可退出编辑,然后输入 :wq 即可保存文本并退出 #后面不要有空格,在「命令行模式(command mode)」下,按一下 : 冒号键进入「Last line mode」) #先按 / 键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 n 会往后寻找到您要的关键字为止。 #先按 ? 键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 n 会往前寻找到您要的关键字为止。 #查找后再 i 修改即可 #向下查找关键字,按 n 可继续查找 vi /path/filename.ext #修改/新增文件 : w filename #输入 「w filename」将文章以指定的文件名filename保存 : wq #输入「wq」,存盘并退出vi : q! #输入q!, 不存盘强制退出vi /word #这个是查找文件中“word”这个单词,是从文件上面到下面查找 ?word #这个是查找文件中“word”这个单词,是从文件下上面到面查找 dd #删除游标所在的一整行(非编辑模式) #退出当前正在执行的命令 ctrl z #(字母是L)查看某文件夹内文件或者文件夹的权限 ll /var/lib/nginx/ #(字母是L)查看当前目录的文件夹和文件 ls -d * #根据文件名查找文件路径 find / -xdev -name filename.suffix #查看某属性 cat /etc/vsftpd/vsftpd.conf | grep write_enable #查看centOS版本 (目前版本:CentOS Linux release 7.1.1503 (Core) ) cat /etc/redhat-release #远程连接终端 ssh root@12.34.56.789 ssh -vv root@12.34.56.789 (可查看连接日志错误) 密码:****** #如果无法登陆远程终端,尝试 ssh-keygen -R 12.34.56.789 #然后再登陆 #新建文件夹 mkdir /??? #文件夹改名 mv ??? ??? #列出目录下所有文件 ls #查找安装的程序的路径(比如查看Node) which node #重装系统登录失败要清楚公钥使用命令: sudo rm /Users/mac/.ssh/known_hosts #或者 sudo rm ~/.ssh/known_hosts #若登陆成功后出现” warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory”,则添加一个文件即可: #如果访问被拒绝,可能是IP原因,日本东京无法登陆,轻换VPN。 sudo vi /etc/environment #添加以下代码: LANG=en_US.utf-8 LC_ALL=en_US.utf-8 #出现『Connection closed by 12.34.56.789』错误,尝试修正权限错误: sudo chmod 700 /etc/ssh_host_dsa_key #查看网络进程(比如httpd, mysqld, sshd等) netstat -plntu #查看所有端口的进程 ss -tpln #访问URL获取请求信息 curl -I https://yoursite.com #检查httpd进程状态 systemctl list-unit-files # 输出激活的单元列表 systemctl list-units # 列出Nginx日志文件 ls -laZ /var/log/nginx/ #打开错误或访问日志 cat /var/log/nginx/access.log cat /var/log/nginx/error.log #查看最新100条错误日志 sudo tail -100 /var/log/nginx/error.log #错误日志会占用很多性能,要定期清理(配置 logrotate 来维护日志文件。 #删除日志 find /var/log/nginx/error.log -type f -delete find /var/log/nginx/error.log-* -type f -delete #查看日志及其大小 ls -la /var/log/nginx/ #下载解压 wget https://wordpress.org/latest.tar.gz tar -xzvf latest.tar.gz #删除文件 rm xxxxxx.zip #删除文件夹和文件 (强制删除) rm -rf xxxxx #改名 mv file1.txt file2.txt #查找5天内修改过的文件 find /usr/share/nginx/html/wordpress/ -type f -mtime -5 #5days #查找包含某字符串的文件 grep -r "jqueryeasyui" /usr/share/nginx/html/wordpress/ #将新解压的位于/usr/share/nginx/html/wordpress/目录中的wordpress 文件夹的文件移动 cp -r /usr/share/nginx/html/wordpress/wordpress/* /usr/share/nginx/html/wordpress/
熟悉一下此次从零开始部署服务器过程中我常用的这些命令,好了,接下去我们正式开始。
(一)购买VPS,设置Server Hostname
设置为你的域名比如 yoursite.com
1、每次登录到linux上,就会看到gaofeng@ubuntu:~$ 这样的提示符,@后面的就是hostnamegaofeng@ubuntu:~$ hostname ubuntu
2、hostname有什么用呢?
- 可以知道自己是不是登录错机器了。
- 在本机的/etc/hosts文件中添加经常访问的机器的ip地址和主机名的映射关系,下次访问时,可以ssh gaofeng@ubuntu来登录,不用记住IP地址了(前提是人家的ip没有变)。
比如
点击自助解析DNS(这里我修改为Vultr 的DNS信息)
2.注册商配置NDS (三)CentOS8系统-进程监控和bandwidth带宽监控添加 EPEL 存储库
sudo yum install epel-release安装进程监控软件
sudo yum install htop
运行
htop
安装带宽监控软件iftop
iftop 是一个简单、易用、实时的类似 top 的基于命令行的网络带宽监控工具,用于快速了解界面上的网络活动。 它平均每 2、10 和 40 秒显示一次网络使用带宽更新。
sudo yum install iftop -y
运行 interface top 命令以查看终端上的网络带宽活动。
iftop
运行后如图:
(四)安装解压软件
Tar 不再默认安装在 RHEL 8 / CentOS 8 上,需要安装
yum install -y tar
P7Zip用于zip文件包的解压
dnf install p7zip p7zip-plugins
解压命令如:
tar -zxvf /path/***.tar.gz 7za x /path/***.zip
备份整站压缩命令如:
cd /usr/share/nginx/html/wordpress/ 7za a /usr/share/nginx/html/wordpress/xxx.7z /usr/share/nginx/html/wordpress rm -rf /usr/share/nginx/html/wordpress/xxx.7z #下载后删除
(五)CentOS 8.0 LEMP (with Nginx, MySQL , and PHP-FPM)安装
注意:请严格按1~11的步骤进行
1.安装Nginx
2.安装MariaDB
3.安装PHP7.4
4.配置PHP到Nginx服务器
5.新建WordPress数据库需要的表,测试是否能连接
6.安装WordPress
7.Nginx 基础配置和基本安全配置
8. WordPress命令配置(不通过网址进入UI界面,参考)
9. 安装SFTP
10.配置HTTPS
11.修改Nginx配置,将http跳转到https
12.Nginx配置https支持PHP和常用功能,重装配置WordPress
我们先查看一下CentOS版本
cat /etc/os-release
当前版本:1.14.1
yum install nginx -y
运行:
systemctl start nginx
开机时启动
systemctl enable nginx
状态查看
systemctl status nginx
查看版本(目前使用1.14.1)
nginx -v
RHEL 8 / CentOS 8 默认没有配置 firewalld 来服务 Web 流量,运行以下命令
允许 HTTP 和 https 的 Web 服务器流量的命令,具有永久规则,这些规则将在一段时间后持续存在
重启。
firewall-cmd --permanent --zone=public --add-service=http firewall-cmd --permanent --zone=public --add-service=https
重新加载防火墙守护程序以进行更改
firewall-cmd --reload
重启
systemctl restart nginx
运行绑定好的域名,可以看到:
2.安装MariaDB
使用 dnf 安装 MariaDB 包
sudo dnf install mariadb-server
启动
sudo systemctl start mariadb
检查状态
sudo systemctl status mariadb
设置开机启动
sudo systemctl enable mariadb
保护 MariaDB 服务器,MariaDB 包含一个安全脚本,用于更改一些不太安全的默认选项,例如远程 root 登录和示例用户。 使用此命令运行安全脚本:
sudo mysql_secure_installation
键入 Y 然后按 ENTER 输入 root 数据库用户的密码,然后按照提示操作。更新密码后,我们将通过按 y 然后按 ENTER 接受所有安全建议。 这将删除匿名用户,禁止远程 root 登录,删除测试数据库,并重新加载权限表。现在我们已经保护了安装,我们将通过连接到数据库来验证它是否正常工作。
根据提示设置密码。
测试登录
mysqladmin -u root -p version
重启MariaDB
systemctl restart mariadb.service3.安装PHP7.4
Nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发fastcgi管理进程处理,fascgi管理进程选择cgi子进程处理结果并返回被Nginx。
PHP-FPM是一个PHP FastCGI进程管理器,此版本安装默认就附带。
使用dnf安装
dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
要确认 EPEL 存储库是否存在,请运行以下 rpm 命令
rpm -qa | grep epel
接下来,运行以下命令以添加 Remi 存储库
dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
再次,要验证 Remi 存储库是否存在,请运行该命令
rpm -qa | grep remi
成功添加 EPEL 和 Remi 存储库后,执行以下命令以获取可用 PHP 模块流的列表
dnf module list php
从上面的输出来看,remi-7.4 是合适版本的PHP 流,因此我们将启用模块流,如下所示
dnf module enable php:remi-7.4
启用 PHP remi-7.4 模块后,您可以使用以下命令继续安装 PHP。 这还将安装许多其他软件包,例如 Apache 和 Nginx 模块
dnf install php php-cli php-common
检查版本(目前安装7.4.26)
php -v
安装完核心模块后,继续安装缺失的模块(特别是mysqli数据库模块),解决WordPress无法运行的问题,数据库无法链接的问题
yum install -y php-mysqlnd php-gd
安装服务和模块后,启动 PHP-FPM
systemctl start php-fpm
配置开机启动
systemctl enable php-fpm
检查状态
systemctl status php-fpm
默认的 PHP-FPM 配置文件设置为以 apache 用户身份运行,找到并更改以下内容
条目如下所示(将apache改成nginx):
先备份一个原配置:
cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.bak
修改配置:
vi /etc/php-fpm.d/www.conf
配置如下:
user = nginx group = nginx listen.owner = nginx listen.group = nginx
重新加载 PHP-FPM 以进行更改
systemctl restart nginx php-fpm4.配置PHP到Nginx服务器
首先,使用cat命令找出PHP-FPM FastCGI服务器配置的位置
cat /etc/nginx/conf.d/php-fpm.conf
确保 Unix 套接字已启动并正在运行,运行:
ls -l /run/php-fpm/www.sock
我的 CentOS 8 和 Nginx 的 php-fpm 配置,运行命令行获取到代码
cat /etc/nginx/default.d/php.conf
代码如下:
# pass the PHP scripts to FastCGI server # # See conf.d/php-fpm.conf for socket configuration # index index.php index.html index.htm; location ~ \.php$ { try_files $uri =404; fastcgi_intercept_errors on; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass php-fpm; }
再次运行 systemctl 命令:
sudo systemctl restart nginx.service
新建测试文件:
sudo vi /usr/share/nginx/html/hello.php
内容如下
<?php phpinfo(); ?>运行网址,我们可以看到浏览器如下界面:
注意看数据库连接的模块:
php -m5.新建WordPress数据库需要的表,测试是否能连接
进入 MySQL 脚本(shell,注意要写分号),输入刚才创建的密码
mysql -u root -p具体的命令如下(注意把名称和密码换成你自己的):
数据库名:wpdbname 用户名: membername 密码:password!!here 创建数据库wpdbname CREATE DATABASE wpdbname; 查看数据库列表 SHOW DATABASES; 查看版本状态 STATUS; 针对MySQL 5.7 or MySQL 8的命令,mysql_native_password是插件名,不要去修改它 #目前使用此命令 CREATE USER 'membername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password!!here'; 针对MySQL 5.1, MySQL 5.5, MySQL 5.6的命令(参考): CREATE USER 'membername'@'localhost' IDENTIFIED BY 'password!!here'; 授予此用户 membername 访问您的 wpdbname 数据库的权限 #目前使用此命令 GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON wpdbname.* TO 'membername'@'localhost'; 或者 GRANT ALL ON wpdbname.* TO membername@localhost; (可选)授予此用户 membername FILE 全局权限:(如果启用,由于 LOAD DATA INFILE 功能,报告将被更快地存档) GRANT FILE ON *.* TO 'membername'@'localhost'; 继续刷新权限 FLUSH PRIVILEGES; 退出mysql命令 QUIT;
重启mysql
sudo systemctl restart mysqld
测试数据库连接:
vi /usr/share/nginx/html/data.php
代码为(使用mysqli链接):
<?php // echo "Welcome to Connecting of DB Tutorial!"; // echo " "; // 1. PDO - Php Data Objects // 2. MySQLi extension // Set Connection Variable $server = "localhost"; $username = "membername"; $password = "password!!here"; $database = "dbname"; // Create A Connection $con = mysqli_connect($server, $username, $password, $database); // Check For Connection if(!$con){ die ("Connection Terminated! by Die() function". mysqLi_connect_error()); } else { echo "Connection Succefully Happened! "; }
代码为(使用PDO模块链接数据库):
<?php $servername = "localhost"; $username = "membername"; $password = "password!!here"; $database = "dbname"; try { $conn = new PDO("mysql:host=$servername;dbname=$database", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "Connected successfully"; } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); }
测试成功以后删除它
rm -rf /usr/share/nginx/html/data.php
备份SQL,输入root密码
mysqldump -u root -p mydatabasename > /usr/share/nginx/html/wordpress/data-dump-2022-XXX.sql
6.安装WordPress
注意:5.8以上版本推荐PHP7.4
如果已经存在/usr/share/nginx/html/wordpress/文件夹,要安装根目录的WordPress cd /usr/share/nginx/html/wordpress 下载并解压: wget https://wordpress.org/wordpress-5.8.2.tar.gz 解压: tar -zxvf wordpress-5.8.2.tar.gz 删除文件(删除文件夹是rm -rf xxx) rm -rf wordpress-5.8.2.tar.gz 将/usr/share/nginx/html/wordpress/wordpress/里的所有文件和文件夹 复制到/usr/share/nginx/html/wordpress/里 cp -r /usr/share/nginx/html/wordpress/wordpress/* /usr/share/nginx/html/wordpress/ 删除原文件夹 rm -rf /usr/share/nginx/html/wordpress/wordpress/
切换到 Nginx 根目录
cd /usr/share/nginx/html
下载并解压:
wget https://wordpress.org/wordpress-5.8.2.tar.gz
解压:
tar -zxvf wordpress-5.8.2.tar.gz
删除文件(删除文件夹是rm -rf xxx)
rm -rf wordpress-5.8.2.tar.gz
解压后设置权限(每次安装新的WordPress或者上传新的文件夹时都要执行)
find /usr/share/nginx/html/wordpress -type d -exec chmod 755 {} \; #所有【目录】更新八进制权限 find /usr/share/nginx/html/wordpress -type f -exec chmod 644 {} \; #所有【文件】更新八进制权限
确保您的文档根目录和所有内容都归myftp1和 www-data 所有
①支持FTP上传文件
②wordpress能选择语言/写入文件/创建config.php/在线删除、安装主题插件
sudo chown -R myftp1:www-data /usr/share/nginx/html/wordpress
设置完权限后FTP工具显示如:
打开临时安全通道,可以让其写入,否则就算设置了写入权限和分组也无法执行
sudo setenforce 0
然后就可以看到选择语言界面
【注意:必须是选择语言的界面,才算成功】
安装主题,插件,缓存插件配置后再运行:
关闭临时安全通道,无法在线安装主题插件,无法写入
sudo setenforce 17.Nginx 基础配置和基本安全配置
接下来对于我们的 WordPress LEMP CentOS 8 安装,我们将继续进行 Nginx 和 wpconfig.php 设置,包括一些安全检查。 此配置不适用于 SSL,文档后面会讲述配置SSL。如果您发现自己面临各种与 SSL 相关的错误,Really Simple SSL 插件可能是一个非常有用的工具。
从您的主 nginx.conf 中排除 XML-RPC 支持,因为它是常见的 DOS 攻击位置。
先备份一个原配置:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
先添加一个错误日志到核心配置中
vi /etc/nginx/nginx.conf
默认配置的代码(增加了一行错误日志配置,注释了server{}默认配置,其它未改动,做初始参考):
# For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ # user nginx; user myftp1; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log warn; #这是增加的代码 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; # 这里是注释掉的 server {...} 部分的代码 # 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 { # } # } # Settings for a TLS enabled server. # # server { # listen 443 ssl http2 default_server; # listen [::]:443 ssl http2 default_server; # server_name _; # root /usr/share/nginx/html; # # ssl_certificate "/etc/pki/nginx/server.crt"; # ssl_certificate_key "/etc/pki/nginx/private/server.key"; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 10m; # ssl_ciphers PROFILE=SYSTEM; # ssl_prefer_server_ciphers on; # # # 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 { # } # } }
重要提示:请注释掉 /etc/nginx/nginx.conf 文件中的server{}80端口部分代码,使用独立的配置文件去管理,避免混淆。
新建文件/etc/nginx/conf.d/default.conf(它将默认替代原配置文件-如果存在, 核心服务配置文件/etc/nginx/nginx.conf内的server {...}内容就无效化,包括原来默认存在的80端口代码)
server_name( 请不要写多个) 进行调整,这样就可以把wordpress目录镜像到根目录
vi /etc/nginx/conf.d/default.conf代码如下:
server { listen 80; server_name "~^www\.(.*)$" ; return 301 $scheme://$1$request_uri ; } server { listen 80; server_name yoursite.com; # note that these lines are originally from the "location /" block root /usr/share/nginx/html/wordpress; index index.php index.html index.htm; # MIME sniffing prevention add_header X-Content-Type-Options "nosniff"; # Enable cross-site scripting filter in supported browsers. add_header X-Xss-Protection "1; mode=block"; # Fix WordPress upload error client_max_body_size 100M; # robots support location = /robots.txt { allow all; log_not_found off; access_log off; } # Github source location ~* \/poemkit($|/$) { return 301 https://yoursite.com:3000/index; } # PHP support location ~ \.php$ { try_files $uri =404; fastcgi_intercept_errors on; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass php-fpm; } # -------------------------------------- location / { try_files $uri $uri/ =404; #503 if (-f /usr/share/nginx/html/maintenance.html) { return 503; } } #debug status # location / { # try_files $uri $uri/ /maintenance.html; # } #502 error_page 502 =503 /50x.html; #other page status(Original configuration modification) error_page 404 /404.html; error_page 500 502 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } error_page 503 /maintenance.html; location = /maintenance.html { root /usr/share/nginx/html/wordpress; } # -------------------------------------- }
location ~ \.php$ { ... } 是上面通过 cat /etc/nginx/default.d/php.conf 命令获取的代码
如果/usr/share/nginx/html/wordpress目录中存在404.html页面,网站会渲染自定义404
下面的代码都是可选的,根据情况添加(目前都未添加)
图片防盗链:
#Prevent image hotlinking / stealing from your site with nginx location ~* \.(gif|png|jpe?g)$ { valid_referers none blocked yoursite.com *.yoursite.com; if ($invalid_referer) { rewrite (.*) /path/to/image/hotlinking-denied.jpg redirect; } }测试防盗链的重写效果,修改valid_referers属性,然后直接使用浏览器输出图片地址,即可被重写跳转。
#Prevent image hotlinking / stealing from your site with nginx location ~* \.(gif|png|jpe?g)$ { valid_referers yoursite.com *.yoursite.com; if ($invalid_referer) { rewrite (.*) /path/to/image/hotlinking-denied.jpg redirect; } }禁止访问某些文件:
# Prevent access to hidden files location ~* /\.(?!well-known\/) { deny all; } # Prevent access to certain file extensions location ~\.(ini|log|conf)$ { deny all; }缓存静态文件【注意:此缓存是储存在客户端(浏览器)上的配置,不是直接从服务端读取】
#all content in static and media folders will be cached by browsers during 30 days location ~* \.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|otf|ogg|ogm|opus|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip|glb|obj|usdz|gltf)$ { expires 30d; add_header Pragma public; add_header Cache-Control "public"; }静态文件的重写,rewrite写在 location XXX{} 外面也会生效。当我访问https://xxxxx/abc/navs的时候,实际访问的是 https:/xxxxx/abc/navs.html
# For HTML Files location /abc { rewrite ^/abc/(.*)$ /abc/$1.html break; }某些网址的指定跳转,比如 /abc 跳转到/abc/index
# Github source location ~* \/abc$ { return 301 /abc/index; }
测试配置文件是否正常
nginx -t
确保 Nginx 和 PHP-FPM 接受更改
systemctl restart nginx php-fpm
检测www是否直接301跳转到没有non-www的域名
curl -I http://www.xxxxxx.com
正确运行WordPress!!
8. WordPress命令配置(参考,不使用)由于SELinux模式保留权限问题,WordPress不能访问远程的api,需要设置防火墙,才能允许远程安装插件和主题
【强烈建议不要禁用 SELinux,而是将模式更改为 permissive。 仅在应用程序正常运行需要时禁用 SELinux】
查看错误日志
sudo cat /var/log/audit/audit.log | grep nginx | grep denied下面的代码测试是否可以远程连接:
curl http://api.wordpress.org -I
查看SELinux Mode状态
sestatus
将 SELinux 模式更改为Permissive启用后,SELinux 可以处于强制或许可模式。 您可以使用以下命令暂时将模式从有针对性更改为宽松模式:
下面的代码是临时关闭SELinux安全策略【建议使用,不要永久改变,它可能保护流量的非法攻击,也可以保护网站被黑的风险】
sudo setenforce 0
使用后重新开启
sudo setenforce 0
注意:下面的代码开启后也会运行远程连接(但它不会控制文件读写)。在布尔值关闭的情况下,PHP 代码无法与远程网站通信(就像 curl_ 函数被禁用一样)。
sudo setsebool -P httpd_can_network_connect 1
永久更改:
但是,此更改仅对当前运行时会话有效,并且不会在重新启动之间持续存在。要将 SELinux 模式永久设置为 permissive,请按照以下步骤操作:
打开 /etc/selinux/config 文件并将 SELINUX mod 设置为 permissive:
vi /etc/selinux/config把 SELINUX=enforcing 改为 SELINUX=permissive
保存文件并运行 setenforce 0 命令来更改当前会话的 SELinux 模式,关机重启:
sudo shutdown -r now
进入wordpress目录
cd /usr/share/nginx/html/wordpress
将 wp-config-sample.php 文件复制到 wp-config.php。
sudo cp wp-config-sample.php wp-config.php
将 wp-config.php 的所有权更改为 Nginx
chown nginx.nginx wp-config.php
生成安全密钥
curl -s https://api.wordpress.org/secret-key/1.1/salt/
如下获取匹配的输出并替换您的 wp-config.php 中的相应行文件,打开您的 wp-config.php 并修改以匹配我们配置时使用的凭据MariaDB 服务。
vi wp-config.php
将wp-config.php的内容替换为下面的部分:
define('DB_NAME', 'dbname'); define('DB_USER', 'membername'); define('DB_PASSWORD', 'password!!here');
重新启动 PHP-FPM 和 Nginx 服务以获取最近的更改
systemctl restart php-fpm nginx9. 安装SFTP
运行yum命令安装
yum install -y vsftpd systemctl enable vsftpd systemctl start vsftpd
状态检查
systemctl status vsftpd
生成用于加密连接的 SSL 证书,输入一个CN即可,其它留空生成
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/vsftpd/vsftpd.pem -out /etc/vsftpd/vsftpd.pem
修改配置文件:
vi /etc/vsftpd/vsftpd.conf
确保以下设置,它们应该是默认值
anonymous_enable=NO local_enable=YES write_enable=YES
以下条目将需要手动添加
rsa_cert_file=/etc/vsftpd/vsftpd.pem rsa_private_key_file=/etc/vsftpd/vsftpd.pem ssl_enable=YES
重启sftp
systemctl restart vsftpd
防火墙需要打开端口
firewall-cmd --permanent –add-port=20-21/tcp firewall-cmd –reload
设置 SFTP 用户和权限
创建新的 FTP 用户,其中 /usr/share/nginx/ 是用户的主文件夹 useradd -d /usr/share/nginx/ myftp1 设置密码 passwd myftp1 创建 www-data 组 groupadd www-data 将 myftp1 用户添加到 www-data 组 usermod -aG www-data myftp1
打开 核心nginx.conf 并更新 Nginx 用户
vi /etc/nginx/nginx.confuser myftp1;
测试 Nginx 配置,您可以在设置权限之前避免重新加载
nginx -t
打开 www.conf 并更新 PHP-FPM 用户
vi /etc/php-fpm.d/www.conf
代码如下(注意最后一行):
user = myftp1 group = www-data listen.owner = myftp1 listen.group = www-data listen.acl_users = apache,nginx,myftp1
测试文件
php-fpm -t
使用新用户和组设置所有权
chown -R myftp1:www-data /usr/share/nginx/html
更新 /var/lib/nginx 的所有权
chown -R myftp1:www-data /var/lib/nginx
确保日志权限到位
chown -R myftp1:www-data /var/log/nginx
确认权限和配置通过测试后,继续重启 Nginx 和 PHP-FPM
systemctl restart nginx systemctl restart php-fpm
注意;连接的时候端口使用22,默认远程路径是/html
10. 配置HTTPSStep 1:使用 dnf 命令安装 mod_ssl 模块:
dnf install mod_ssl
Step 2:首先在服务器上生成一个csr文件
如果您选择使用商业上受信任的证书,则可以通过运行以下命令来生成 CSR。 相应地替换密钥和 CSR 的名称。
这里命名为:ca.key
openssl req -new -newkey rsa:4096 -nodes -keyout ca.key -out ca.csr
一次输入自己的证书信息,如下:
生成后,将 CSR 内容提交给签名证书颁发机构。上面的命令会生成私钥和 CSR。 确保私钥安全,因为稍后安装证书时需要。接下去我们查看内容
Step 3:查看csr文件的内容(此内容也用于网站申请发放证书和签名,验证等)
cat ca.csr内容如下:
-----BEGIN CERTIFICATE REQUEST----- ….... -----END CERTIFICATE REQUEST-----
将ca.csr的内容填入到证书商家的表单生成:
Step 4:FTP上传颁发的3个证书文件到根目录
上传到nginx目录/usr/share/nginx/html/中【如果更新证书,必须修改原来的3个证书文件】
新建一个证书目录(因为权限问题,FTP无法直接上传到此):
mkdir /usr/share/nginx/ssl
FTP上传后拷贝3个证书文件到所需要的目录
sudo cp /usr/share/nginx/html/yoursite.com.crt /usr/share/nginx/ssl/ sudo cp /usr/share/nginx/html/yoursite.com.ca-bundle /usr/share/nginx/ssl/ sudo cp /usr/share/nginx/html/yoursite.com.p7b /usr/share/nginx/ssl/
拷贝后删除:
rm -rf /usr/share/nginx/html/yoursite.com.crt rm -rf /usr/share/nginx/html/yoursite.com.ca-bundle rm -rf /usr/share/nginx/html/yoursite.com.p7b
查看私钥ca.key的内容
cat ca.key
内容如下:
-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----
将ca.key的内容,重新创建成一个文件,供nginx配置文件使用
vi /usr/share/nginx/ssl/ca.key
Step 5:创建bundle.crt最终证书文件
nginx中没有证书链的选项,只需连接域的证书文件和 CA 的链文件,用编辑吧yoursite.com.crt和yoursite.com.ca-bundle文件的内容拼接在一起即可,注意顺序要正确。
vi /usr/share/nginx/ssl/bundle.crt
内容为拼接后的内容
Step 6:修改nginx配置文件,新增443端口的代码(将www跳转到non-www):
vi /etc/nginx/conf.d/default.conf
内容如下:
server { listen 443 ssl http2; server_name "~^www\.(.*)$" ; return 301 $scheme://$1$request_uri; ssl on; ssl_certificate /usr/share/nginx/ssl/bundle.crt; ssl_certificate_key /usr/share/nginx/ssl/ca.key; ssl_session_cache shared:SSL:20m; ssl_session_timeout 60m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; ssl_buffer_size 8k; ssl_session_tickets off; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 10s; } server { listen 443 ssl http2; server_name yoursite.com; ssl on; ssl_certificate /usr/share/nginx/ssl/bundle.crt; ssl_certificate_key /usr/share/nginx/ssl/ca.key; ssl_session_cache shared:SSL:20m; ssl_session_timeout 60m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; ssl_buffer_size 8k; ssl_session_tickets off; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 10s; }
检查
nginx -t
重启
systemctl restart nginx
最后测试一下证书的级别
http://stool.chinaz.com/https?url=yoursite.com11. 修改Nginx配置,将http跳转到https
修改配置文件
vi /etc/nginx/conf.d/default.conf
在侦听80端口(非www跳转)的地方增加一行即可:
return 301 https://$host$request_uri;
重启
systemctl restart nginx12.Nginx配置https支持PHP和常用功能,重装配置WordPress
修改Nginx配置,让https支持php等常用配置,代码如下,修改443端口(非www部分)
vi /etc/nginx/conf.d/default.conf
代码如下:
server { listen 443 ssl http2; server_name yoursite.com; ssl on; ssl_certificate /usr/share/nginx/ssl/bundle.crt; ssl_certificate_key /usr/share/nginx/ssl/ca.key; ssl_session_cache shared:SSL:20m; ssl_session_timeout 60m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; ssl_buffer_size 8k; ssl_session_tickets off; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 10s; # note that these lines are originally from the "location /" block root /usr/share/nginx/html/wordpress; index index.php index.html index.htm; # MIME sniffing prevention add_header X-Content-Type-Options "nosniff"; # Enable cross-site scripting filter in supported browsers. add_header X-Xss-Protection "1; mode=block"; # Fix WordPress upload error client_max_body_size 100M; # robots support location = /robots.txt { allow all; log_not_found off; access_log off; } # Github source location ~* \/poemkit($|/$) { return 301 https://yoursite.com:3000/index; } # PHP support location ~ \.php$ { try_files $uri =404; fastcgi_intercept_errors on; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass php-fpm; } # -------------------------------------- location / { try_files $uri $uri/ =404; #503 if (-f /usr/share/nginx/html/maintenance.html) { return 503; } } #debug status # location / { # try_files $uri $uri/ /maintenance.html; # } #502 error_page 502 =503 /50x.html; #other page status(Original configuration modification) error_page 404 /404.html; error_page 500 502 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } error_page 503 /maintenance.html; location = /maintenance.html { root /usr/share/nginx/html/wordpress; } # -------------------------------------- }
重启
systemctl restart nginx
删除WordPress旧的文件夹(看接下去的步骤增加一个维护页面临时使用)
rm -rf /usr/share/nginx/html/wordpress
重新安装和配置WordPress(参看安装步骤),根据需要修改名称
(如果上传到根目录则不需要改名,因设置了 Nginx的root目录/usr/share/nginx/html/wordpress/)
cd /usr/share/nginx/html/wordpress/{NEW_FOLDER_NAME}这时候安装后需要改名
mv /usr/share/nginx/html/wordpress /usr/share/nginx/html/wordpress/{NEW_FOLDER_NAME}
修改Nginx配置443端口(非www部分)
vi /etc/nginx/conf.d/default.conf
WP 配置(1)
由于nginx不支持.htaccess文件重写,当使用了Permalink功能重写网址的功能后,需要配置nginx来适配你的重写功能。如果您在 /blog 等子目录(即/usr/share/nginx/html/wordpress/blog) URL 下运行您的博客,如:
# -------------------------------------- For WordPress Settings begin # WordPress Permalink location /blog { index index.php index.html index.htm; try_files $uri $uri/ /blog/index.php?$args; #503 if (-f /usr/share/nginx/html/maintenance.html) { return 503; } } # -------------------------------------- For WordPress Settings end如果是默认的网站根目录,就写成注意:如果有重复的location / { ... }代码段,请删除它
# -------------------------------------- For WordPress Settings begin # WordPress Permalink location / { index index.php index.html index.htm; try_files $uri $uri/ /index.php?$args; #503 if (-f /usr/share/nginx/html/maintenance.html) { return 503; } } # -------------------------------------- For WordPress Settings endWP 配置(2)
WordPress EDD插件需要的配置保护:
# -------------------------------------- For WordPress Plugin-EDD Settings begin # To protect your EDD files while using EDD location ~* \/wp-content\/uploads\/edd\/(.*?)\.(gz|zip|tar|rar)$ { rewrite (.*) / permanent; } # -------------------------------------- For WordPress Plugin-EDD Settings endWP 配置(3)
WordPress安全保护:
# -------------------------------------- For WordPress Security begin # DDos prevent location = /xmlrpc.php { deny all; access_log off; log_not_found off; return 444; } location = /blog/xmlrpc.php { deny all; access_log off; log_not_found off; return 444; } # -------------------------------------- For WordPress Security endWP 配置(4)(可选 ,不需要使用)
WordPress网站地图重写(如果已经增加了WordPress Permalink配置,就不用增加):last标记告诉 NGINX 跳过当前服务器或位置块中的任何后续 Rewrite-module 指令,并开始搜索与重写的 URL 匹配的新位置。
# -------------------------------------- For WordPress Sitemap begin rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/index.php?xml_sitemap=params=$2" last; rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last; rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last; rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last; # -------------------------------------- For WordPress Sitemap begin
重启
systemctl restart nginx
即可看到目录/usr/share/nginx/html/wordpress/blog 内的wordpress系统的效果:
(六)增加Nginx维护页面,临时维护使用
新建一个目录
mkdir /usr/share/nginx/html/wordpress
在Nginx根目录上传一个文文件用来识别维护状态(作为保留备用)
vi /usr/share/nginx/html/maintenance.html
不需要维护模式时记得改名:
mv /usr/share/nginx/html/maintenance.html /usr/share/nginx/html/maintenance-no.htmlmaintenance.html 和 404.html 的HTML代码请自己搞定)
在/usr/share/nginx/html/wordpress/目录新建2个文件:maintenance.html和404.html
vi /usr/share/nginx/html/wordpress/maintenance.html vi /usr/share/nginx/html/wordpress/404.html
设置权限(每次安装新的WordPress或者上传新的文件夹时都要执行)
find /usr/share/nginx/html/wordpress -type d -exec chmod 755 {} \; #所有【目录】更新八进制权限 find /usr/share/nginx/html/wordpress -type f -exec chmod 644 {} \; #所有【文件】更新八进制权限
确保您的文档根目录和所有内容都归myftp1和 www-data 所有,
①支持FTP上传文件
②wordpress能选择语言/写入文件/创建config.php/在线删除、安装主题插件
sudo chown -R myftp1:www-data /usr/share/nginx/html/wordpress
如果只是调试状态【当网站有正式内容时才使用】,并不是真正的全站维护返回503,按下面的步骤进行:
(1)先改名
mv /usr/share/nginx/html/maintenance.html /usr/share/nginx/html/maintenance-no.html(2)再在Nginx配置中增加维护页面判断代码(在443端口非www的部分):
vi /etc/nginx/conf.d/default.conf修改方法:
注释代码: location / { try_files $uri $uri/ =404; #503 if (-f /usr/share/nginx/html/maintenance.html) { return 503; } } 执行代码(只强制跳转根目录的,子目录不会强制跳转): #debug status location / { try_files $uri $uri/ /maintenance.html; }
检查
nginx -t
重启
systemctl restart nginx
(七)完成 LEMP基础配置后,升级性能和安全性,其它配置
下面这些配置是保证WordPress能够更好的运行
1. Mariadb和Nginx服务断开后自动重启
2. PHP配置修改
3. 启用GZIP压缩
4. 创建交换空间swap space
5. 进一步优化Mariadb
6. 静态文件缓存和PHP缓存
7. 配置Redis缓存mysql数据
8. 学会检查内存占用的程序
这一部分篇幅有有点分量,当您完成第(一)到(六)步骤后,服务器就可以使用了,此部分性能和安全提升的内容,我会在下一篇相关文章中进行归纳整理。
(八)Node环境配置(请完成此文档上面所有步骤后再继续)
Step1: Node环境
安装Node16+ (目前安装后版本为 16.13.1)
curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash - sudo yum install -y nodejs node -v
全局安装pm2
sudo npm install pm2@latest -g
全局安装babel
sudo npm install -g babel-cli
全局安装最新babel
sudo npm install -g @babel/core @babel/cli @babel/preset-env
全局安装ts-node
sudo npm install -g ts-node
Step2: 防火墙设置
设置Node应用需要的防火墙(这里需要3000端口):
firewall-cmd --permanent --zone=public --add-port=3000/tcp firewall-cmd --reload
如果是同一个域名挂载反向代理,可能会被阻止访问,这时需要考虑远程连接的问题:
SELinux 提供了一个安全层,用于在 Linux 内核中实现强制访问控制 (MAC)。 每个操作系统对象(进程、文件描述符、文件等)都标有一个 SELinux 上下文,该上下文定义了对象可以执行的权限和操作。setsebool命令是用来修改SElinux策略内各项规则的布尔值。
Nginx 被标记为 httpd_t 上下文,因此,除非明确允许,否则有许多配置被 SELinux 阻止。 为了演示这一点,请运行以下命令以确认 Nginx 服务标记为 httpd_t:
ps -eZ
该命令提供进程状态信息,搜索Nginx特定进程信息可以看到标签。 您将看到 httpd_t,类似于以下内容:
... system_u:system_r:httpd_t:s0 10208 ? 00:00:00 nginx system_u:system_r:httpd_t:s0 10209 ? 00:00:00 nginx ...
查看安全策略列表(按q退出)
getsebool -a | less修改SELinux 中httpd对外访问的状态,httpd_can_network_connect默认是off的。请改为on,这样才能访问。
注意:下面的代码开启后也会运行远程连接(但它不会控制文件读写)。在布尔值关闭的情况下,PHP 代码无法与远程网站通信(就像 curl_ 函数被禁用一样)。sudo setsebool -P httpd_can_network_connect 1
Step3: 部署node应用测试端口
测试一下是不是成功用pm2挂载上了,使用IP能正常访问 https://yoursite.com:3000
部署express的https端口,需要再原来的服务器文件中增加以下代码:
// Supprt https const cert = fs.readFileSync('/usr/share/nginx/ssl/bundle.crt'); const key = fs.readFileSync('/usr/share/nginx/ssl/ca.key'); import https from 'https'; const server = https.createServer({key: key, cert: cert }, app); ... app.get('/', (req, res) => { res.send('this is an secure server') }); ... server.listen(port, () => console.log(`Frontend service listening on port: ${port}, access https://localhost:${port} in the web browser`));
下面的代码可以查看使用端口的程序
sudo netstat -pan | grep ":3000"
Step4: 反向代理配置(不同域名的时候才使用)
vi /etc/nginx/conf.d/default.conf代码如下:
server { listen 443 ssl; server_name backend1.example.com; ... location / { proxy_set_header Host $http_host; proxy_pass http://{YOUR_IP}:3000; } }
检查
nginx -t
重启
systemctl restart nginx
结语
好咯,这漫长的一篇文章终于OK了,下一次我们会继续完成第七部分性能和安全的内容,如果文章对你有帮助,也可以继续关注我。希望看完它,你可以从零开始部署配置你自己的Linux服务器:)其他语言同理可以扩展到Nginx中,可以自由发挥。
由于文字较多,如果这里阅读体验不佳,推荐直接到我的博客浏览:)
没位道|xizon小站,专注互联网产品 www.c945.com