nginx 学习1-基础-安装/配置/加密/log

387 阅读5分钟

1.介绍

Nginx的4大特征

  1. 反向代理
  2. 动静分离
  3. 负载均衡
  4. api服务

1. 反向代理

  1. 实现缓存
  2. 性能与访问效率提升
  3. 实现tcp udp http socket转发
  4. 可以转发内网服务器,以提供外部服务

2 动静分离

  • 静态: 留给nginx
  • 动态: 反向代理给动态服务,如tomcat

3 负载均衡

  1. 实现动态容灾与扩容
  2. 请求均衡或指定转发

4 api服务

  1. 提供openRestry lua定制化编程

优势

  1. 高并发和高性能: 支持同时100万请求,tomcat 500左右
  2. 高可靠性:用久了不会出现内存满问题
  3. 支持热部署: 无需重启
  4. 开源: 免费 5.可扩展性: 支持各种模块

发布历史版本

  • 2004年 10月 0.1.0 第一版
  • 2005年 重写http反向代理
  • 2011年 0.7.52 支持 window系统
  • 2011年 1.0 正式版 支持 keepalive http 长连接 成立公司
  • 2013年 支持socket
  • 2015年 支持http2 thread pool stream四层方向代理 reuseport 特征
  • 2016年 支持动态模块
  • 2018年 支持TLS v1.3

组成文件

  1. 二进制文件
  2. conf配置
  3. access访问日志
  4. error错误日志

开源版本

tengine

阿里巴巴定制的开源版本 github.com/alibaba/ten…

openRestry

支持lua 第三方语言编程的 开源nginx版本

源码文件夹分析

configure # 编译时使用命令,可以定制使用哪个模块
objs # 存放 编译后的nginx运行文件
contrib # 高亮文字使用
html # 静态资源文件夹
conf # nginx配置文件夹

下载 安装

# 下载源码
wget http://nginx.org/download/nginx-1.15.8.tar.gz  
# 解压文件
tar -zxvf  nginx-1.15.8.tar.gz 
# 创建 /usr/local/download 文件夹
mkdir /usr/local/download
# 剪切文件夹到 /usr/local/download/ 下
mv nginx-1.15.8 /usr/local/download/
#切换到 /usr/local/download/nginx-1.15.8/下面
cd /usr/local/download/nginx-1.15.8/

# 覆盖高亮文字提示 ### 文字高亮
cp contrib/vim/indent/nginx.vim  vimrc 
cp -r vimrc /etc/vimrc
# 查看支持的模块命令
./configure --help

# 执行命令
./configure
make
make install

#查看nginx是否正常安装
whereis nginx 

常用命令

#nginx常用命令
#先进入nginx目录
cd /usr/local/nginx/sbin
#启动服务
./nginx
#测试配置是否正常
./nginx -t
#重新加载
./nginx -s reload
#关闭服务
./nginx -s stop

# 查看nginx服务是否启动成功
ps -ef | grep nginx 

conf配置语法

  1. 配置文件由指令与指令块构成
  2. 每条指令以;分号结尾,指令与参数间以空格符号分隔指令块以 {}大括号将多条指令组织在一起
  3. include语句允许组合多个配置文件以提升可维护性
  4. 使用#符号添加注释,提高可读性
  5. 使用$符号使用变量
  6. 部分指令的参数支持正则表达式

常用命令

nginx -h # 帮助
nginx -c  # 指定配置文件
nginx -g # 指定配置指令 
nginx -p prefix #设置 指定运行目录:(默认是:/usr/share/nginx/)
nginx  -t  # 检查语法
nginx  -v   # 打印版本 
nginx  -V   # 编译时的模块信息
nginx  -s  # 发送命令  

nginx -s reopen #重新开始记录日志文件 
# 等价于 
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`


# 信号与 命令 对照表
nginx -s stop # TERM INT
nginx -s quit # QUIT 优雅地停止Nginx服务(即处理完所有请求后再停止服务)
nginx -s reload # HUP 等价于重新启动 
nginx -s reopen  # USR1

# 升级新的nginx二级制 
kill -USR2 PID # 平滑升级nginx 等价于  kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
kill -WINCH PID # 平滑关闭worker工作进程 
kill -QUIT PID # 杀死进程老的master

# 回滚老master操作
kill -HUP 老PID # 相当于执行 nginx -s reload 重新分派worker进程
kill -WINCH 新PID #  平滑关闭新master的 所有worker工作进程 
kill -QUIT 新PID #  杀死 新master 需谨慎操作
ps -ef  grep nginx # 查看进程 

日志切割

方法1 直接备份+重新生成

# 备份
cp /usr/local/nginx/logs/access.log access.log.20230324
# 重新打开
nginx -s reopen  # 重新打开日志 写入access.log

方法2 crontab 方案

vi /home/scripts/cut_del_nginx_logs.sh

#!/bin/bash
#初始化
LOGS_PATH=/usr/local/nginx/logs
YESTERDAY=$(date -d "yesterday" +%Y%m%d)
 
#按天切割日志 切割access 和 error
mv ${LOGS_PATH}/access.log ${LOGS_PATH}/access.log.${YESTERDAY}
mv ${LOGS_PATH}/error.log ${LOGS_PATH}/error.log.${YESTERDAY}
 
#向nginx主进程发送USR1信号,重新打开日志文件,否则会继续往mv后的文件写数据的。原因在于:linux系统中,内核是根据文件描述符来找文件的。如果不这样操作导致日志切割失败。
# grep -v grep是过滤掉不包含grep的内容
# awk '{print $2}' 找到最后匹配的 第二个参数 则为 pid
# root      11151  0.0  0.0  49772   948 ?        Ss    2022   0:00 nginx: master process ./sbin/nginx
# root     114498  0.0  0.0 112816   976 pts/1    S+   09:30   0:00 grep --color=auto nginx: master process
kill -USR1 `ps axu | grep "nginx: master process" | grep -v grep | awk '{print $2}'`
 
#删除2个月前的日志
cd ${LOGS_PATH}
find . -mtime +60 -name "*20[1-9][3-9]*" | xargs rm -f
 
exit 0

# 写入 crontab
#执行命令
crontab -e
#写入文件并保存
59 23 * * * /home/scripts/cut_del_nginx_logs.sh
# 查看配置
crontab -l

# 检测 crond
service crond status
# 检测 开机启动状态  图形界面
yum intall ntsysv 
ntsysv
# 加入开机自动启动:
chkconfig –-level 35 crond on
# 重启服务
service crond restart #重启服务

# 其他命令
service crond start # 启动服务
service crond stop # 关闭服务
service crond restart #  重启服务
service crond reload # 重新载入配置

方法3 使用logrotate 备份和生成

logratate介绍

-d或--debug  详细显示指令执行过程,便于排错或了解程序执行的情况。  
-f或--force  强行启动记录文件维护操作,纵使logrotate指令认为没有需要亦然。  
-s<状态文件>或--state=<状态文件>  使用指定的状态文件。  
-v或--version  显示指令执行过程。  
-usage  显示指令基本用法。

常用命令

yum -y install logrotate anacron

vim /etc/logrotate.d/nginx

/var/log/nginx/*.log
{
  daily #指定转储周期为每天
  rotate 60  #保留总文件数,由于一天一个所以就是总天数
  create
  dateext #日志压缩文件以当天日期做后缀
  dateformat -%Y%m%d_%S
  missingok
  copytruncate
  nocompress
  sharedscripts
}

logrotate -vf /etc/logrotate.d/nginx #测试语法

rm -rf /etc/cron.daily/logrotate # 删除系统默认规则,先检测有没有其他有用的配置
crontab -e
# 新增下面规则  这样每天凌晨0点0分就会执行nginx日志切割
59 23 * * * logrotate -f /etc/logrotate.d/nginx

# 检测是否生效 查看日志
tail -f 100  /var/log/cron
# 最终生成的记录地址 如果是root用户编辑 则保存为root
cat /var/spool/cron/crontabs/root

# 重启服务
service crond restart

调试是否生效与注意事项

# 注意点:

# 1. 使用-vf 如果有error 就是异常,没有生成文件
logrotate -vf /etc/logrotate.d/nginx #如果提示下面信息则有问题

Potentially dangerous mode on /etc/logrotate.d/nginx: 0777  
error: Ignoring /etc/logrotate.d/nginx because it is writable by group or others.  
Creating stub state file: /var/lib/logrotate.status  
Reading state from file: /var/lib/logrotate.status  
Allocating hash table for state file, size 64 entries

# 修复方法:
chmod -R 644 /etc/logrotate.d


# 1. 配置crontab -e 注意 不能使用/usr/sbin/logrotate  只能使用全局命令
# 2. 不能使用-vf 只能使用 -f  

# 2. 使用-f 情况
logrotate -f /etc/logrotate.d/nginx #如果提示下面信息则其实已经生成 只打印了错误提示

error: /etc/logrotate.d/nginx:1 lines must begin with a keyword or a filename (possibly in double quotes)
error: /etc/logrotate.d/nginx:11, unexpected text after }

# 调试方法:
## 设置为每分钟执行一次 
* * * * * logrotate -f /etc/logrotate.d/nginx 
## 通过不断输入date查看是否跨分钟
date
date
date

## 查看日志是否生成
ls -l /usr/local/nginx/logs/


## 设置为每天晚上整点 执行一次 
## 由于使用了 daily 指定转储周期为每天属性,所以当天生成一次后,需要修改系统时间才能查看后面其他天效果
## 注意调整系统时间必须提前1分钟左右,可能linux调度是按1分钟执行,第一次可以立马有效,后面都要一分钟。
## 当前已经生成的不能再重新设置,只能延后一天,不能往前设置。
# 修改为 第一次 
date -s "2023-05-12 23:58:00" 
# 修改为 第二次 
date -s "2023-05-13 23:58:00" 
# 还原系统时间 
yum install ntpdate
ntpdate ntp.ubuntu.com

插件安装后 nginx二进制升级

# make生成
make #这里不要进行make install,否则就是覆盖安装

# 然后备份原有已安装好的nginx
cp /usr/local/nginx/sbin/nginx  /usr/local/nginx/sbin/nginx.bak
# 再进行覆盖
cp ./objs/nginx /usr/local/nginx/sbin/

# 平滑升级 nginx ,此时 系统会有两个master 
kill -USR2 13195

# 通过 WINCH 关闭老master上所有worker ,但master 依然保留,已被恢复使用
kill -WINCH 13195

2.日志分析 goacess

goaccess.io/

要注意参数 --log-format COMBINED

安装版

# 下载
wget https://tar.goaccess.io/goaccess-1.3.tar.gz
# 解压
tar -xzvf goaccess-1.3.tar.gz $ cd goaccess-1.3/

./configure --enable-utf8 --enable-geoip=legacy

make && make install
# 命令行显示
goaccess access.log
# 生成一个HTML报告: 
goaccess -a -d -f /srv/logs/access.log --port=7891 -p /srv/data/goaccess.conf > /srv/report/report.html --real-time-html 

docker版

allinurl/goaccess

tail -f  /docker_workspace/docker-compose/docker_compose_ylzs/logs/nginx/access.log | docker run -p 7890:7890 --rm -i -e LANG=$LANG allinurl/goaccess -a -o html --log-format COMBINED --real-time-html - > /docker_workspace/docker-compose/docker_compose_ylzs/dist/html/report/index.html

启动一个nginx 读取report.html

server {
    listen       8086;
    server_name localhost;
    location / {
        root   /usr/share/nginx/html/report;
        try_files $uri $uri/ /report.html;
    } 
}

3.配置指令块

  • upstream : 上游服务器配置
  • http:本地全局的http配置
  • server:单个server的服务配置
  • location:单个请求的配置

4.单位

## 时间单位
y  # 年
M  # 月
w  # 周
d  # 天

h # 小时
m # 分钟
s # 秒
ms # 毫秒 


## 传输单位 
不写单位 # 字节 byte
k/K # kb
m/M # mb
g/G # gb

5. error_log 与 debug调试

5.1debug定位问题:出现错误时的应对方案

debug_points abort | stop; 

功能: 某些Nginx模块可能存在代码Bug,在生产环境则忽略问题,打开debug points后则遇到问题后停止服务方便定位问题

工作方式

abort #生成核心转储coredump文件并结束进程
stop # 结束进程

生效时刻

  • 任何Nginx模块调用ngx_debug_point()函数的位置,例如
  • ssi模块中输出“the same bufwas used in ssi”日志后
  • 共享内存分配出错,输出“ngx_slab_alloc(): page is busy”日志后

5.2控制debug级别error.log日志的输出

配置error错误日志格式

error_log级别分为debug、info、notice、warn、error、crit,

默认为error,crit记录的日志最少,而debug记录的日志最多,

debug级别需要 编译进入nginx ./configure --with-debug ...

支持范围配置


error_log  logs/error.log  notice;  # 全局
http{
    server {
        error_log  logs/error1.log  notice;   # 某个server
         # 用于验证具体问题的 uri地址
        location /app/mymodule/add {
           error_log  logs/error2.log  debug; #只针对某个请求做debug处理
           proxy_pass http://xx.xx.xx.xx:12091; 
         }

        location /app { 
          proxy_pass http://172.17.0.1:12091; 
        }
    }
}

限制指定ip debug

Syntax: debug_connection address | CIDR | unix:;
Default: —
Context: events

针对特定客户端打印DEBUG级别日志,其他日志仍然遵从error log指令后设置的日志级别

注意: configure中必须加--with-debug编译选项

events{
    debug_connection 127.0.0.1;
}

DEBUG日志流程

  • 建立连接
    • SSL握手
  • 接收请求的HTTP头部
    • 请求行解析
    • 请求头部解析
  • 11个阶段的处理
    • 寻找处理请求的location
    • 反向代理构造上游请求
    • 接收客户端请求包体
  • 构造出的响应头部
  • 发送响应:过滤模块

6.实战

文件夹目录访问

server {
	server_name localhost;
	listen 8001;
	location / {
		alias html/;
		autoindex on;
		index a.html; # 当与 autoindex 同时设置 index优先于autoindex
        # set $limit_rate 1k; # 限制访问速度
		autoindex_exact_size off;
		autoindex_format html;
		autoindex_localtime on;
	} 
    error_page   500 502 503 504  /50x.html;  # 当服务器异常返回50的错误页面
}

配置日志格式

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  logs/access.log  main; # 全局配置
  server { # 支持不同代码块写入日志
        listen       8888;
        server_name  localhost; 
        access_log  logs/host.access.log  main;
  }
}

7.加密相关

TLS 与SSL 发展历史

  • SSL:Secure Sockets Layer
  • TLS:Transport Layer Security
  • 1995 SSL3.0
  • 1999 TLS1.0 微软重新命名
  • 2006 TLS1.1
  • 2008 TLS1.2
  • 2018 TLS1.3

ssl 属于 表示层的内容。在http 与 tcp 应用层与传输层之间

TLS 安全密码套件

  1. 密钥交互算法
  2. 身份验证算法
  3. 对称加密算法,强度 分组模式
  4. 签名hash算法

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

对称与非对称

对称逻辑

明文 1110 
密钥 0010 
密文 1100
密文 =  明文 + 密钥    # 位运算求与

非对称

通过公钥进行加密,私钥进行解密。 即使暴露了 公钥也无法破解密文。

PKI 公钥基础设施

  1. CA机构颁发证书
  2. 服务配置证书
  3. 客户端访问拿到证书先去CA验证
  4. 每一个CA上都还有上一个CA 直到根的CA 也就是操作系统内置信任的CA

证书类型

  • EV 证书 扩展验证 extended validated 收费 适合银行证券 地址栏有绿标和 文字描述
  • OV 证书 组织验证 org validated 收费 适合政府机构 地址栏有绿标
  • DV 证书 域名验证 domain validated 人业务 无绿标 型证书不包含企业名称信息

tls 通讯过程

  1. 验证身份
  2. 达成安全套件共识
  3. 传递秘钥
  4. 加密通讯

自动生成秘钥

使用 python2-certbot-nginx 生成配置

# 安装
yum -y install yum-utils 
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
# 获取证书
certbot --nginx 
# 或者输入完整信息
certbot --nginx --nginx-server-root=/usr/local/nginx/conf/ -d www.test.pub

# conf文件自动生成秘钥配置
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

# 配置定时更新
1 1 * * 6 certbot renew --renew-hook "nginx -s reload"

参考

time.geekbang.org/course/intr…