Nginx基本配置和模块

Nginx基本配置

#user  nobody;	 #设置nginx服务的系统使用用户
worker_processes  1; 	#工作进程数,一般跟电脑cpu保持一致

#error_log  logs/error.log; 	#nginx错误日志
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info; #错误日志级别

#pid        logs/nginx.pid; 	#nginx服务启动的pid


events {
    worker_connections  1024; 	#每个进程允许最大连接数
    #use;	#工作进程数
}


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

      #日志语法,main表示格式名称
    #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; #日志位置,与上面的main对应

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65; #连接超时时间

    #gzip  on;
    # 每个服务配置一个server
    server {
        listen       8080; 	#监听端口
        server_name  localhost;	#服务器名称

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
    
    #路径控制(加“/”表示控制首页路径)
        location / {
            root   html;	#首页文件路径
            index  index.html index.htm;
        }

        #error_page  404              /404.html; #统一错误页面,指定错误码定位到错误路径

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;

    # 将上面指定的错误路径指定到特定的路径页面
        location = /50x.html {
            root   html;
        } 
    }
    include servers/*; #导入其他子配置文件
}

Nginx日志类型

包括:error.logaccess_log
error.log:错误日志
access_log:每次请求的状态
日志的形式可以在配置文件中进行配置

nginx变量

在配置日志格式时,可以使用以下变量进行配置;

  • HTTP请求变量:arg_PARAMETER,http_HEADER,sent_http_HEADER
  • 内置变量:Nginx有内置的许多变量,可以上官网查看
  • 自定义变量

配置语法

参考上面基础配置示例,在变量前加上美元符,同时使用单引号扩起来

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

Nginx模块

http_stub_status_module配置

用于展示Nginx处理当前连接的客户端状态,默认没有配置,可以在配置文件的server,location中配置

location /mystatus{
        stub_status;
}

更改完配置之后可以先测试文件是否出错:

nginx -tc /usr/local/etc/nginx/nginx.conf

测试成功之后重新加载配置文件:

nginx -s reload -c /usr/local/etc/nginx/nginx.conf

访问定义的mystatus页面:出现以下内容:

Active connections: 2 //当前活跃连接数
server accepts handled requests
 41 41 40 //握手总次数,处理连接数,总的请求数(通常握手数=连接数,表示数据无丢失)
Reading: 0 Writing: 1 Waiting: 1 (状态,正在读,正在写,等待)

http_random_index_module模块

用于从目录中选择一个作为随机主页(一般较少用到)
配置时在location中配置:

location / {
        root   某个目录; #该目录下有多个html文件随机作为主页
      #index  index.html index.htm;
      random_index on
}

http_sub_module模块

用于HTTP中html内容替换,一般也比较少用
配置时同样在http,server,location中配置:

sub_filter '要替换的内容‘ ’替换后的内容‘;
sub_filter_last_modified on|off; #用于服务端和浏览器端每一次请求时校验服务端内容是否发生变更,默认是off
sub_filter_once on|off; #替换全部还是第一个,默认on,表示只替换第一个

Nginx请求限制模块

连接频率限制:limit-conn-module
请求频率限制:limit-req_module

HTTP1.0 TCP不能复用,一次连接对应一次请求;HTTP1.1支持TCP顺序性服用,一个连接可以顺序性发起多个连接;HTTP2.0之后TCP连接可以多路复用

配置语法:

  • 连接限制:
# 首先需要申请连接限制空间,用于存储连接状态,需要定义在http中
# key:以连接哪个变量作为key,作为每次连接的标识
# name:空间名
# size:空间大小
limit_conn_zone key zone=name:size;

# 指明具体使用的限制空间,可以定义在http,server,location中
# zone:空间名,表示使用哪一块空间
# number:同一时间允许的连接并发数
limit_conn zone number
  • 请求频率限制:
# 同样需要先定义一个空间,同样只能在http中
# rate为限制请求的速率
limit_req_zone key zone=name:size rate=rate

# 指明具体的限制空间,可以定义在http,server,location中
# burst表死延迟处理,如果请求数超过rate,剩下的请求(注意是全部请求)将被延迟下一秒/分处理,如果请求数超过burst定义的数量,多余的请求则直接返回503错误。
# 如果开启nodelay,则处理burst数量的请求延迟,超过rate的请求直接返回503,不再延迟处理。
limit_req zone=name [burst=number] [nodelay]

配置示例:

http{
    # 使用ip地址作为key标识每一次链接,同时加上binary该变量更节省内存空间
    limit_conn_zone $binary_remote_addr zone=conn_zone:1m
    # 1r/s表示一秒之内最多1次请求,也可以用5r/m,表示一分钟之内最多5次请求
    limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;

    server{
        location / {
            limit_conn conn_zone 3;
            limit_req zone=req_zone burst=3 nodelay;
        }
    }
}

Nginx访问控制模块

基于ip的访问控制:http_access_module
基于用户的信任登录:http_auth_basic_module

http_access_module

配置语法:

# 配置在http,server,location,limit_except中

# 配置允许哪些访问
# 可以按照ip,网段,unix中的socket,所有配置
allow address|CIDR|unix:|all;
# 配置禁止哪些访问
deny address|CIDR|unix:|all;

allow和den可以成对配置,比如只禁止某一个ip,可以配置deny ip;allow all,注意先后顺序

局限性
使用ip访问控制,一旦客户端有中间件代理,则Nginx最终读取到的是代理的ip地址,而无法对预设的ip做限制,此时有以下几种解决方法:

  1. http_x_forwarded_for,会同时记录源地址IP和代理ip:

    http_x_forwarded_for = Client IP,Proxy(1)IP,Proxy(2)IP,…

  2. 结合geo模块

  3. 听过HTTP自定义变量传递

http_auth_basic_module

配置语法:

# 配置在http,server,location,limit_except,默认是off
# string:即表示配置开启,又会在前端显示相应的字符串信息
auth_basic string|off;

# 配置在http,server,location,limit_except
# file:文件路径,作为认证存储用户名,密码等信息的文件
auth_basic_user_file file;

对于存储用户认证信息的文件有指定的格式:

comment

name1:password1
name2:password2:comment
name3:password3

可以使用htpasswd工具进行文件编辑:

» htpasswd                                                                                    
Usage:
    htpasswd [-cimBdpsDv] [-C cost] passwordfile username
    htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password

    htpasswd -n[imBdps] [-C cost] username
    htpasswd -nb[mBdps] [-C cost] username password
 -c  Create a new file.
 -n  Don't update file; display results on stdout.
 -b  Use the password from the command line rather than prompting for it.
 -i  Read password from stdin without verification (for script usage).
 -m  Force MD5 encryption of the password (default).
 -B  Force bcrypt encryption of the password (very secure).
 -C  Set the computing time used for the bcrypt algorithm
     (higher is more secure but slower, default: 5, valid: 4 to 31).
 -d  Force CRYPT encryption of the password (8 chars max, insecure).
 -s  Force SHA encryption of the password (insecure).
 -p  Do not encrypt the password (plaintext, insecure).
 -D  Delete the specified user.
 -v  Verify password for the specified user.
On other systems than Windows and NetWare the '-p' flag will probably not work.
The SHA algorithm does not use a salt and is less secure than the MD5 algorithm.

输入下面指令然后输入两次密码即可生成文件

htpasswd -c [文件路径] [用户名]

location / {
      root   html;
      auth_basic "请输入用户名和密码以访问该页面。。。";
      auth_basic_user_file auth.conf;
        index  index.html index.htm;
}

局限性

  • 用户信息依赖文件方式
  • 操作管理繁琐,效率低下

可以通过结合LUA实现高效验证,或者和LDAP打通
安全模块

  1. 制定并允许检查请求的链接的真实性以及保护资源免遭未经授权的访问
  2. 限制链接生效周期

配置语法

# 配置在http,server,location中
secure_link expression

# 配置在http,server,location中
secure_link_md5 expression
  • 对于secure_link:
    expression由校验值过期时间组成,其中校验值将会与 secure_link_md5中的指定参数的MD5哈希值进行对比,如果两个值不一致,$secure_link变量的值是空(empty),如果两个值一致,则进行过期检查,如果过期了,则$secure_link变量值是0,如果没过期,则为1 ;如果链接是有时效性的,那么过期时间用时间戳进行设置,在MD5哈希值后面声明,用逗号隔开。如果没有设置过期时间,该链接永久有效。
  • 对于secure_link_md5:
    expression指定计算md5哈希值的参数,该md5值将会和url中传递的md5值进行对比校验。expression一般包含uri(如demo.com/s/link, uri则为/s/link)以及加密密钥secret,如果该链接具有时效,则expression需包含$secure_link_expires,expression还可以加入客户端信息,如访问IP,浏览器版本信息等

配置示例

location / {
        # 此处会获取参数名为md5和参数名为expires的值
        secure_link $arg_md5,$arg_expires;
        # 将会根据参数计算出md5的值与上面的校验值$arg_md5进行比较,xm是服务端规定的标识信息
        secure_link_md5 "$secure_link_expiress$uri xm";

        if($secure_link = ""){
                return 403;
        }
        if($secure_link = "0"){
                return 410;
        }
}

利用shell产生的链接示例:

servername="xiao-ming9.github.io"
download_file="/download/file.img"
time_num=$($date -d "2019-7-23 00:00:00" +%s)
secret_num="imooc"

res=$(echo -n "${time_num}${download_file} ${secret_num}" |openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =)

echo "https://${servername}${download_file}?md5=${res}&expires=${time_num}"