0%

Nginx使用

本文介绍Nginx的基本安装及使用

环境配置

我这里演示在 centos7.9 下, 通过源码编译的方式安装 nginx, 步骤如下

在正式开始安装之前, 我们要先配置好我们的linux环境, 先安装以下依赖

yum -y install zip unzip gcc gcc-c++ automake autoconf libtool make glibc gd-devel pcre-devel libmcrypt-devel mhash-devel libxslt-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel libevent libevent-devel

源码包下载

接下来就开始我们的安装流程了, 首先在我们的centos下随便找个目录, 接着去nginx官网找到源码包, 点击前往官网 nginx: download

我们选中 stable 下, 中间那个, 这是长期支持版, 然后鼠标右键, 复制下载链接

image-20211220141730418

复制好下载链接后, 回到我们的centos, 执行以下命令, 下载源码包到当前目录下

wget https://nginx.org/download/nginx-1.20.2.tar.gz

当下载好后, 我们会看到当前目录下有一个压缩包, 我们执行以下命令进行解压

tar zxvf ./nginx-1.20.2.tar.gz

解压好后, 我们cd进解压后的文件夹内

cd ./nginx-1.20.2

configure配置

随后, 我们对nginx源码编辑进行一下配置

./configure --prefix=/opt/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_v2_module --with-http_gzip_static_module --with-http_sub_module
  • --prefix=/opt/nginx 代表nginx要安装在哪个目录
  • --with-http_stub_status_module 可以展示nginx的状态
  • --with-http_ssl_module 可以让nginx支持ssl, 也就是支持https
  • --with-http_image_filter_module 可以让nginx处理图片的裁剪及缩放等功能
  • --with-http_v2_module 可以让nginx支持http2
  • --with-http_gzip_static_module 可以让nginx支持Gzip压缩
  • --with-http_sub_module 可以让nginx支持字符串替换

以上这几个是我们常用的模块, 你也可以根据自己的需求, 加装别的模块


编译

接下来, 执行源码编译操作,直接执行以下命令即可

make

安装

源码编译好之后, 编译成品位于objs目录下, 里面有一个nginx可执行文件

到上面那一步后, 我们仅仅是完成了编译的步骤, 并没有开始安装, 如果大家想要安装nginx的话, 可以再执行 以下命令

make install

如果你不想要安装, 你也可以复制objs/nginx去替换你以前旧的nginx


基本命令

nginx中, 常用的命令不多, 来来去去也就这几个

  • nginx -t 检查配置文件是否正确
  • nginx -s reload 重启nginx
  • nginx -s stop 强行停止nginx
  • nginx -s quit 正常停止nginx
  • nginx -s reopen 重新生成新的日志文件
  • nginx 启动nginx

如果你想要把nginx配置成全局命令, 可以把nginx的可执行文件, 软连接到/usr/bin目录下

ln -s /opt/nginx/sbin/nginx /usr/bin/nginx

配置软链接需要使用root权限, 并且源路径和目标路径都必须是绝对路径

如果我们修改了nginx的配置文件,需要重启nginx才会生效,建议采用 nginx -s reload 进行平滑重启


基本配置

打开我们nginx的安装目录, Nginx的基本配置如下(nginx.conf)

user  root; # 采用root用户运行
worker_processes 4; # cpu核心数, 根据你自己电脑/服务器的配置来定

events {
# 采用epoll事件模型
use epoll;
# 单个worker进程客户端最大连接数
worker_connections 65535;
# 连接数低时on(一个请求只唤醒一个进程), 连接数多时off(进程全部唤醒)
multi_accept off;
}


http {
include mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

# 高效文件传输模式
sendfile on;
# 减少网络报文段的数量
tcp_nopush on;

# 超过这个时间,服务器断开这个链接
keepalive_timeout 65;
# 一个 HTTP 长连接最多可以处理完成的最大请求数
keepalive_requests 10240;
# 防止网络阻塞
tcp_nodelay on;
# 请求头部的缓冲区大小
client_header_buffer_size 4k;
open_file_cache max=102400 inactive=20s;
# 多长时间检查一次缓存的有效信息
open_file_cache_valid 30s;
open_file_cache_min_uses 1;
# 设置请求头的超时时间
client_header_timeout 15;
# 设置请求体的超时时间
client_body_timeout 15;
# 关闭不响应的客户端连接
reset_timedout_connection on;
# 响应客户端超时时间
send_timeout 15;
# 隐藏nginx版本号
server_tokens off;
# 上传文件大小限制
client_max_body_size 10m;

# Gzip压缩配置
gzip on;
gzip_min_length 2k;
gzip_buffers 4 32k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
gzip_vary on;
gzip_proxied any;

# SSL配置
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!ADH:!MD5; # 注意我中间的是!ADH
ssl_prefer_server_ciphers on;

# 错误页
error_page 500 502 503 504 /opt/nginx/html/50x.html;

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

# 导入我们自己的conf配置
include ../app/*.conf;
}


conf配置

在上面的配置文件中,我们注意到最后一行

# 导入我们自己的conf配置
include ../app/*.conf;

如果我们把所有web应用的配置都写到nginx.conf中的话, 这个文件就太大了, 也不好看, 因此, 我们可以把每一个应用的配置单独写到一个conf文件中, 然后再在nginx.conf中统一引入

那么上面那行的意思就是, 引入上一级app目录下, 所有以.conf为后缀的文件

既然是引入这个路径, 那么我们就必须先有这个目录, 行吧, 回到上一级目录, 创建app目录

mkdir /opt/nginx/app

然后, 我们创建一个自己的web应用配置

touch /opt/nginx/app/my-app.conf

配置参考

写入以下内容

# /opt/nginx/app/my-app.conf

# http重定向到https
server {
listen 80;
server_name "你这个应用访问的域名, 如baidu.com";
return 301 https://$server_name$request_uri;
}

# server_name 可以是域名, 也可以是ip地址

server {
# 监听xxx.com的443端口, ssl协议, 开启http2
listen 443 ssl http2;
listen [::]:443 ssl http2;

server_name "你这个应用访问的域名, 如baidu.com";

root /usr/local/web1;

index index.html;

# SSL证书配置
ssl_certificate "/xxx/xxx.crt"; # 可以是crt或pem
ssl_certificate_key "/xxx/xxx.key";

# alias静态资源转发
location /static/ {
# 如 https://xxx.com/static/girl.png => /aaa/bbb/girl.png
alias /aaa/bbb/; # 注意要以/结尾
}

# root静态资源转发
location /public/ {
# 如 https://xxx.com/public/girl.png => /ccc/ddd/public/girl.png
root /ccc/ddd; # 注意, 末尾没有/
}

# 反向代理web应用1: 3000
location /api/demo/ {
# 以下2条是配置支持websocket反向代理,可选
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 所有以/api/demo开头的请求, 都会被转发到 localhost:3000
proxy_pass http://localhost:3000;
# 重写请求头 /api/demo/users => /api/users
rewrite "^/api/demo/(.*)" /api/$1 break;
}

# 静态资源缓存
location ^~ \.(ico|jpe?g|gif|png|webp|bmp)$ {
expires 365d; # 缓存365天
access_log off;
}

# 静态资源缓存
location ~* \.(js|css)$ {
expires 30d; # 缓存30天
log_not_found off;
access_log off;
}

# 如果前面的规则都没有被匹配上,那么就会来到这里
location / {
# try_files 尝试访问
# $uri 文件
# $uri/ 文件夹
# /index.html 如果前面的文件和文件夹都没有找到, 那么默认返回index.html
try_files $uri $uri/ /index.html;
# 假如你的是web应用,并且是vue或react或angular构建的单页应用,采用了history路由方式,那么上面这行你就必须得写
}
}

限流

所谓限流就是限制用户的请求数量, 这同时也是防范爬虫的一种手段之一, 当某个时间段内监测到同一个ip的大量请求时, 将禁止其继续请求

限流的指令为以下2个, 我们只需要将其写到http块下即可

# 定义限流策略, IP限流, 每个ip每秒4次请求
limit_req_zone $binary_remote_addr zone=mylimit:20m rate=4r/s;

# 采用限流策略, nodelay代表burst缓冲区满时直接返回503, 如果不写nodelay则请求会进入排队状态
# 这行如果写在http块下, 则对所有web应用有效, 你也可以单独写到某个server块下
limit_req zone=mylimit burst=50 nodelay;
  • mylimit: 仅仅只是我们随便写的一个策略名称, 大家可以随便起

  • rate:4r/s代表每秒处理4个请求

  • burst:50 代表50个请求缓冲区

    • 假如一瞬间来了10个请求,我们1s只能处理4个请求,还剩下6个没有得到处理,那么这6个请求,就会被塞进burst这个缓冲区排队等候服务
    • 假如一瞬间来了100个请求,nginx是先处理前4个,剩余的96个会被放到burst,但burst只有50个位置,因此多出的46个请求 会根据nodelay的设置执行不同的处理
  • nodelay:代表当请求数超出burst时,超出的请求如何处理,是放弃还是保留

    • 设置:nginx请求频率扩充为(rate + burst),请求数超过(burst + rate)的时候就会直接返回503
    • 不设置:请求数超过(burst + rate)的时候,超出的请求进入排队等待状态,等待进入burst缓冲区

安全

服务器安全是重中之重,我们要防范各种web安全攻击,非法请求,网络爬虫等,除了前后端人员都做好响应处理之外

我们也可以在nginx中做一层处理,强化服务器的安全配置

为防范上述说的这些问题, 我们可以在server块增加如下配置

你也可以单独写到一个conf文件中, 然后在每一个server块中通过include引入进来

# 禁止浏览器资源类型猜测
add_header X-Content-Type-Options "nosniff";
# 开启浏览器XSS防护, 如果被攻击,阻止脚本执行
add_header X-XSS-Protection "1; mode=block";
# 禁止iframe
add_header X-Frame-Options deny;
# 告诉浏览器在接下来的一年, 只允许通过https协议访问
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
# 不允许浏览器在下载资源时,直接打开资源文件, 例如图片,pdf等
add_header X-Download-Options noopen;

# 禁止非http2的请求
if ($server_protocol !~* "HTTP/2.0|HTTP/1.1")
{
return 444;
}

# 如果url出现php字样,则拒绝访问
if ($uri ~* (php|phpmyadmin))
{
return 444;
}

# 禁止这些头字段请求, 不区分大小写 (1)
if ($http_user_agent ~* "Scrapy|wget|curl|Bytespider|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Feedly|UniversalFeedParser|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|python|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|heritrix|EasouSpider|Ezooms|^$" )
{
return 403;
}

# 禁止这些头字段请求, 不区分大小写 (2)
if ($http_user_agent ~* "java|perl|ruby|bash|echo|uname|base64|decode|md5sum|select|concat|httprequest|nmap|scan" )
{
return 403;
}

# 禁止这些头字段请求, 不区分大小写 (3)
if ($http_user_agent ~* "YisouSpider|ApacheBench|WebBench|Jmeter|JoeDog|Havij|GetRight|TurnitinBot|GrabNet|masscan|mail2000" )
{
return 403;
}

# 禁止访问下列后缀的文件
location ~* \.(bak|save|sh|sql|mdb|svn|git|old|py|php|jsp|txt|cgi|exe|bat|vb?s)$
{
deny all;
}

# 禁止除这3个以外的请求方法
if ($request_method !~ ^(GET|HEAD|POST)$)
{
return 403;
}

if ( $allowed_country = yes) {
return 404;
}

# 以下的均为防止SQL注入
if ($query_string ~* (\$|'|--|[+|(%20)]union[+|(%20)]|[+|(%20)]insert[+|(%20)]|[+|(%20)]drop[+|(%20)]|[+|(%20)]truncate[+|(%20)]|[+|(%20)]update[+|(%20)]|[+|(%20)]from[+|(%20)]|[+|(%20)]grant[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]where[+|(%20)]|[+|(%20)]select[+|(%20)]|[+|(%20)]and[+|(%20)]|[+|(%20)]or[+|(%20)]|[+|(%20)]count[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]chr[+|(%20)]|[+|(%20)]mid[+|(%20)]|[+|(%20)]like[+|(%20)]|[+|(%20)]iframe[+|(%20)]|[\<|%3c]script[\>|%3e]|javascript|alert|webscan|dbappsecurity|style|confirm\(|innerhtml|innertext)(.*)$) { return 555; }
if ($uri ~* (/~).*) { return 501; }
if ($uri ~* (\\x.)) { return 501; }
if ($query_string ~* "[;'<>].*") { return 509; }
if ($request_uri ~ " ") { return 509; }
if ($request_uri ~ (\/\.+)) { return 509; }
if ($request_uri ~ (\.+\/)) { return 509; }
if ($uri ~* (insert|select|delete|update|count|master|truncate|declare|exec|\*|\')(.*)$ ) { return 503; }
if ($request_uri ~* "(cost\()|(concat\()") { return 504; }
if ($request_uri ~* "[+|(%20)]union[+|(%20)]") { return 504; }
if ($request_uri ~* "[+|(%20)]and[+|(%20)]") { return 504; }
if ($request_uri ~* "[+|(%20)]select[+|(%20)]") { return 504; }
if ($request_uri ~* "[+|(%20)]or[+|(%20)]") { return 504; }
if ($request_uri ~* "[+|(%20)]delete[+|(%20)]") { return 504; }
if ($request_uri ~* "[+|(%20)]update[+|(%20)]") { return 504; }
if ($request_uri ~* "[+|(%20)]insert[+|(%20)]") { return 504; }
if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { return 505; }
if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") { return 505; }
if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") { return 505; }
if ($query_string ~ "proc/self/environ") { return 505; }
if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") { return 505; }
if ($query_string ~ "base64_(en|de)code\(.*\)") { return 505; }
if ($query_string ~ "[a-zA-Z0-9_]=http://") { return 506; }
if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") { return 506; }
if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { return 506; }
if ($query_string ~ "b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)b") { return 507; }
if ($query_string ~ "b(erections|hoodia|huronriveracres|impotence|levitra|libido)b") {return 507; }
if ($query_string ~ "b(ambien|bluespill|cialis|cocaine|ejaculation|erectile)b") { return 507; }
if ($query_string ~ "b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)b") { return 507; }

关于http2.0, 这块启用的前提是, 你的nginx支持http2.0协议

目前大部分浏览器几乎都支持http2.0了, 而大多数爬虫工具还未支持http2.0

因此, 封杀非http2.0可以缓解大部分的爬虫流量, 但同时也会误杀友军

因为某些人的浏览器可能是上古遗留下来的, 不支持http2.0

当然,上面这些配置大家看着来设置就好了,不强求

网络安全上的配置还有很多,例如防火墙设置,文件传输限制,禁止国外IP等等,这些操作太多了,就不在此展开描述了,感兴趣的大家可以去百度。


日志备份

当我们采用nginx来代理我们的web应用时, 外界的每一个请求, 在经过nginx时, 都会被nginx给记录在日志中

nginx的日志分为2种

  1. access.log:访问日志
  2. error.log:错误日志

access.log代表的是正常的http访问日志

error.log代表nginx出现错误,崩溃等日志,它主要指nginx自身出现的问题

随着nginx长时间运行,以及用户访问量的不断加大,日志文件也会相应的越来越大,那么,由于日志文件变大了,自然而然地,写入日志的速度也就变慢了。

在这种情况下,我们就可以选择定时对日志文件做切割及备份操作

这里我们的流程是:

每天凌晨00:00的时候, 在指定路径下创建一个文件夹, 以日期时间来命名该文件夹, 随后把昨天的日志文件拷贝到该文件夹下, 最后, 生成新的日志文件

由于需要定时执行, 我们可以在nginx的日志目录下, 创建一个shell脚本文件, 命名为split_log.sh, 内容如下

#! /bin/bash
# 现在的时间
NOW=$(date +"%Y-%m-%d-%H-%M-%S")
# 日志所在的位置
LOG_PATH=/opt/nginx/logs
# 日志存放的位置
HISTORY_LOG_PATH=$LOG_PATH/history/${NOW}
# 创建该文件夹
mkdir ${HISTORY_LOG_PATH}
# 移动日志
mv ${LOG_PATH}/access.log ${HISTORY_LOG_PATH}/access.log
# 移动日志
mv ${LOG_PATH}/error.log ${HISTORY_LOG_PATH}/error.log
# 重新打开日志文件
kill -USR1 $(cat /opt/nginx/logs/nginx.pid)

然后赋予该脚本文件执行权限

chmod +x ./split_log.sh

那么, 我们这个脚本文件的作用就是:

  1. 得到当前的日期, 格式为 %Y-%m-%d-%H-%M-%S
  2. /opt/nginx/logs/history/下创建一个文件夹, 文件夹的名称就是上面得到的日期
  3. 通过 mv 指令移动access.log和error.log
  4. 最后, 通过 kill -USR1 让nginx生成新的日志文件并使用

我们接下来做最后一个步骤, 我们要求的是定时执行, 因此我们需要在linux中配置一条定时任务

我们在命令行输入 crontab -e 编辑定时任务配置文件, 在这个文件内加入下面的命令

0 0 * * * /bin/bash /opt/nginx/split_log.sh
  • 0 0 * * * 代表每天的0点0分, 从左到右分别代表分、时、日、月、周,星号代表任意数字
  • /bin/bash 代表你要执行谁
  • /opt/nginx/split_log.sh 就是我们要执行的文件了

新人可能会疑惑,我不是要执行split_log.sh吗?为什么上面写了我要执行/bin/bash?

因为,split_log.sh是一个shell脚本文件,shell脚本都是由/bin/bash来帮我们执行的

效果图:

image-20211221110136280


图像裁剪

我们在做web应用时,经常会由这么一个需求,前端访问同一张图片,有时需要得到不同的尺寸,例如缩略图和原图

这一个步骤虽然说可以交给我们的后端来完成,但如果nginx能做的话,也能为我们剩下不少力呢

在nginx中也是可以实现对图片的裁剪的,前提时你的nginx要有 image_filter_module 这个模块,参考最前面的configure配置教程

假设我要访问的路径是以下2个

那么我们在location中就可以这么来配置

# 静态资源转发
location ~* /pictures\/(.+)\.(jpe?g|png|gif|webp)(!(\d+)x(\d+))? {
# 通过set定义变量,$filepath = 图片所在的路径,$n是指正则表达式中括号的匹配结果,不懂的去复习正则表达式
# $1代表第一个括号匹配到的内容,$2代表第二个括号匹配到的内容,其他同理
# 那么,$1匹配到文件名,$2匹配到文件后缀
set $filepath /root/project/image_server/static/$1.$2;
# 得到尺寸参数$3
set $size $3;
# 声明变量width,默认值是 -
set $width -;
# 声明变量height,默认值是 -
set $height -;
# 如果尺寸参数存在,则将其复制给width和height
if ( $size ) {
set $width $4;
set $height $5;
}
# 设置图片的宽和高
image_filter crop $width $height;
# 图片缓冲大小
image_filter_buffer 100M;
# 图片裁剪质量75,越高越清晰,越低约模糊
image_filter_jpeg_quality 75;
# 通过alias来转发图片
alias $filepath;
# 图片缓存365天
expires 365d;
# 不记录到日志文件中
access_log off;
}

静态资源转发

通常我们会采用nginx来处理前端的静态资源,其基本原因在于nginx处理静态资源的效率非常高

前端同学也知道,nodejs同样可以转发静态资源,但是呢,效率是真的没有nginx高,完全输给nginx,因为二者的传输原理是不一样的

那么,在nginx中如何转发静态资源呢?可以采用 root 或者 alias 来转发,来看个例子

location /static/ {
root /opt/project/image;
}

location /picture/ {
alias /opt/project/image/;
}

如果我访问的链接是 http://xxx.com/static/beautiful-girl.png

那么,会被/static/这个规则匹配到

然后真实的访问地址是:/opt/project/image/static/beautiful-girl.png

如果我访问的链接是http://xxx.com/picture/beautiful-girl.png

那么,会被/picture/这个规则匹配到

然后真实的访问地址是:/opt/project/image/beautiful-girl.png

看出来区别了吗?

  • root: 真实路径 = root路径 + 匹配路径
  • alias: 真实路径 = alias路径

如何取舍呢?我该用哪个呢?看你自己咯!


路径重写

在前后端开发中,我们在写接口时,经常会有这种情况

开发模式下,所有接口以 /api 开头

生产模式下,删掉 /api

写过前端proxy的同学应该都了解过一个叫rewrite的东西,就算没用过,也肯定见过,它的作用就是重写我们的请求路径

简单来说,就是修改一下请求的路径,然后,就没了

那么,这个步骤在nginx中同样可以做到,怎么做呢?在location内写

location /api/ {
proxy_pass http://localhost:6666;
rewrite "^/api/(.+)" /$1 brealk;
}

当我们配置以上规则后,那么,产生的效果就如下

http://xxx.com/api/users  =>  http://xxx.com/users

那假如我要重写的是路径中间的部分,又该怎么办呢?同理

location /api/aaa/ {
proxy_pass http://localhost:6666;
rewrite "^/api/aaa/(.+)" /bbb/$1 brealk;
}

当我们配置以上规则后,那么,产生的效果就如下

http://xxx.com/api/aaa/users  =>  http://xxx.com/bbb/users

rewrite语法规则

共有3个参数,每个参数用空格隔开

  • 第一个参数:正则表达式,用来做匹配的
  • 第二个参数:新的内容
  • 第三个参数:可选,值有break, last, redirect, permanent,具体区别自己去百度,这里不详写

如果第二个参数是一个链接,则第三个参数就相当于redirect重定向,浏览器访问到时,会重定向(跳转)到你指定的链接

以上就是rewrite的内容了,它除了可以重写反向代理的路径,也可以重写静态资源的访问路径,这些由大家自己去尝试了


变更用户

正常情况下,我们不建议采用root用户来运行nginx,这里所说的用户,是指你在nginx.conf中的user字段

我们应当使用其他用户,或创建其他用户来进行执行

创建用户

执行以下命令,创建一个nginx用户

useradd nginx

设置密码

执行以下命令,设置nginx用户的密码,然后根据提示输入2次密码即可

passwd nginx

修改conf

创建好用户并设置密码后,我们就要去修改nginx.conf中的user字段

# nginx.conf
user nginx; #就是这行

event {...}

http {...}

然后执行 nginx -s reload 重新启动就可以了

目录权限

新创建的nginx这个用户没有啥权限,nginx要访问的静态资源文件等都需要给它赋予相应的权限,否则nginx没法读取

假设你有一个静态博客站点,所在的文件夹是 /opt/blog

那么你就要把 /opt/blog 文件夹(包括子文件夹和文件)的权限都赋予给nginx用户,否则可能会没法访问这里面的东西

执行以下命令,将 /opt/blog 文件夹的所属用户和所属组都改为nginx

chown -R  nginx:nginx /opt/blog

执行以下命令,修改blog文件夹所属用户和所属组为 766 权限

chmod -R 766 /opt/blog

766:三个数字表示三种权限

第一个数字代表所属用户权限

第二个数字代表所属组权限

第三个数字代表其他用户权限

  • 只读:4

  • 只写:2

  • 执行:1

所属用户权限 :7 = 4+2+1

所属组权限:6 = 4+2

其他用户权限:6 = 4+2

上面的目录权限配置很重要,要是没有配置好,会出现403无法访问的情况

sudo权限

配置好目录权限后,我们接下来要为nginx这个用户配置sudo权限

因为,我们nginx代理了我们的80和443端口,而nginx有一个限制,假如代理的端口小于1024,就必须以超级管理员的身份启动

而我们为了安全起见,肯定不会使用root用户来执行的,所以我们可以给nginx用户配置sudo权限,让它可以采用超级管理员身份运行某些命令

用root用户登录,执行以下命令,编辑权限

visudo

然后找到下面这个位置,添加我们的nginx用户

## Allow root to run any commands anywhere
root ALL=(ALL) ALL
# 就是这里,在这里添加nginx用户,并写好后面的参数
nginx ALL=(ALL) ALL

最后我们 :wq 保存并退出

重点:最后的最后,我们再用root用户执行以下命令,重置nginx用户环境变量及工作目录等数据,否则nginx用户几乎啥命令也用不了

su -l nginx

有些同学在创建好用户后会发现,几乎啥命令也用不了,连最基础的cd, ll 等命令都没法用,就是因为你没有执行这条命令,要登录root,然后执行

到这里,我们的用户创建到权限配置就已经完成了

启动nginx

执行以下命令,切换到nginx用户空间

su nginx

执行以下命令,输入nginx用户的密码,然后回车,启动nginx

sudo nginx

结语

到此,我们的nginx配置流程大致都讲完了,这些配置不算很多,花点时间是可以学的来的,其中比较复杂的估计就是切换nginx的启动用户了

在这一块上不熟悉的同学还需得多练习练习,也不是说写多了就会了,其实你看多了你会的

本片文章并没有把nginx的内容完全讲完,包括负载均衡等,这些在网上大把大把的,大家花点时间去看看就好

这篇文章适合有一丢丢nginx和linux经验的人看,主讲一些外界教程较少的知识吧

-------------本文结束    感谢阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!