Nginx之常用基本配置(三)

  前面我们聊了下了Nginx作为WEB服务器对客户端请求相关配置,文件操作优化、Nginx访问控制、basic验证,、状态模块状态页、gzip压缩配置;回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12381331.html;今天我们来聊一聊日志模块、ssl模块、rewrite模块;

  一、ngx_http_log_module:此模块作用是指定nginx的访问日志格式;

    log_format name [escape=default|json|none] string ...;此指令就是用来定义ngxin访问日志的格式,其中escape这个参数允许设置在变量中转义的json或默认字符,默认情况下使用默认转义,none表示禁止转义。string可以使用nginx核心模块及其它模块内嵌的变量;注意这个指令只用于http配置段中,用于定义日志格式,后面对所有虚拟主机都可以在定义日志文件时可以调用定义的日志格式;

    access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];指定日志文件路径,其中buffer=size表示指定日志缓冲区大小,gzip=level表示指定日志压缩级别,fulsh=time表示指定日志每隔多久就把缓冲区的日志内容存到磁盘文件中去;

  示例:

   提示:以上配置表示定义一个日志格式其名称是 main ,后面用单引号引起来的部分就是日志格式内容,其中$remote_addr表示客户端ip这个值不一定是客户端ip,这个要看应用环境,如果nginx服务器前面有代理服务器,这个变量就会记录前端代理的ip,如果nginx是直接面向客户端,那么这个值就是记录客户端ip,具体它记录那个ip 这个要看应用环境;$remote_user表示远端用户,如果我们配置的网站有验证的话,这个值就是记录的是用于验证的用户名,如果没有则默认就是“-”;$time_local表示本地服务器时间;$request表示客户端使用的方法请求资源路径,以及http协议版本;$status这个变量记录客户端请求服务器资源时的响应状态码;$body_bytes_sent这个变量记录客户端访问服务器时响应体的字节数,这个字节数不包含响应头部;$http_referer此变量记录客户端的referer信息;referer是http头部的一部分,通常情况下客户端浏览器访问web服务器时,都会把这个referer信息带上,目的是告诉服务器本次请求是从那个页面链接过来的;$http_user_agent此变量记录客户端的User_Agent信息,User_Agent也是http头部的一部分,客户端访问web服务器时会带上这个信息,目的就是告诉服务器客户端的操作系统类型,版本,浏览器信息等;$http_x_forwarded_for这个变量用于记录客户端真实IP,如果客户端是通过代理访问本服务器,那么这个值不是记录代理客户端的IP,而是客户端真实IP信息;更多内建变量可参考http://nginx.org/en/docs/http/ngx_http_core_module.html#variables,其他变量请参考官方文档http://nginx.org/en/docs/varindex.html

  定义好上面的日志格式,我们可以通过access_log 来指定存放日志的文件路径并明确指定用我们定义的日志格式“main”,当我们浏览器访问web服务器时,服务端就会以我们定义的格式记录日志,如下所示

     open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];指定缓存各日志文件相关的元数据信息;其中max=N表示缓存的最大文件描述符数量,如果满了就用LRU算法清理缓存;inactive=time表示指定非活动时长,默认情况下,10秒;min_user=N表示在inactive指定的时长内访问大于等于此值方可被当作活动项;;vaild=time指定验正缓存中各缓存项是否为活动项的时间间隔;

  二、ngx_http_ssl_module:此模块实现nginx基于https提供web服务

    ssl on | off;启用或禁用ssl功能

    ssl_certificate file;设置当前虚拟主机的证书

    ssl_certificate_key file;设置当前虚拟主机证书私钥文件

    ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];支持ssl协议版本,默认为后三个;

    ssl_session_cache off | none | [builtin[:size]] [shared:name:size];其中builtin[:size]表示使用OpenSSL内建的缓存,此缓存为每worker进程私有;[shared:name:size]:表示在各worker之间使用一个共享的缓存;

    ssl_session_timeout time;客户端一侧的连接可以复用ssl session cache中缓存 的ssl参数的有效时长;

  示例:

    要让nginx工作为https服务器,首先我们要对其申请证书,有关CA服务器搭建,以及证书申请相关原理说明请参考https://www.cnblogs.com/qiuhom-1874/p/12237944.html,这里说下过程,首先我们要准备一台CA(可以是本机),然后在nginx服务器上生成证书申请文件,然后把该文件发送给CA服务器,然后CA服务器签发证书申请文件生成对应的证书,然后CA把签好的证书文件发给nginx服务器,然后nginx服务器拿到证书后在配置文件中配置使用证书即可,当然以上步骤也可以直接在CA上做,最后把生成的私钥文件和证书发送给nginx服务器,过程入下;

    1、搭建CA,其实很简单,所谓CA就是生成一个自签名证书即可

[root@test ~]# cd /etc/pki/CA/
[root@test CA]# tree
.
├── certs
├── crl
├── newcerts
└── private

4 directories, 0 files
[root@test CA]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus
...+++
...................+++
e is 65537 (0x10001)
[root@test CA]# tree
.
├── certs
├── crl
├── newcerts
└── private
    └── cakey.pem

4 directories, 1 file
[root@test CA]#

  提示:以上是生成CA私钥

  2、生成自签名证书

[root@test CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SICHUAN
Locality Name (eg, city) [Default City]:GUANGYUAN
Organization Name (eg, company) [Default Company Ltd]:TEST
Organizational Unit Name (eg, section) []:DEVOPS
Common Name (eg, your name or your server's hostname) []:ca.ilinux.io
Email Address []:
[root@test CA]# touch index.txt
[root@test CA]# echo 01 >serial
[root@test CA]# tree
.
├── cacert.pem
├── certs
├── crl
├── index.txt
├── newcerts
├── private
│   └── cakey.pem
└── serial

4 directories, 4 files
[root@test CA]# 

  提示:到此CA就准备好了

  3、准备nginx服务器证书私钥和服务器证书申请文件

[root@www ~]# mkdir /etc/nginx/ssl
[root@www ~]# cd /etc/nginx/ssl
[root@www ssl]# ls
[root@www ssl]# (umask 077;openssl genrsa -out nginx.key 2048)
Generating RSA private key, 2048 bit long modulus
.........................................+++
.......+++
e is 65537 (0x10001)
[root@www ssl]# ll
total 4
-rw------- 1 root root 1679 Mar  2 23:06 nginx.key
[root@www ssl]# openssl req -new -key nginx.key -out nginx.csr 
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SICHUAN
Locality Name (eg, city) [Default City]:GUANGYUAN
Organization Name (eg, company) [Default Company Ltd]:TEST
Organizational Unit Name (eg, section) []:DEVOPS
Common Name (eg, your name or your server's hostname) []:www.ilinux.io
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@www ssl]# ll
total 8
-rw-r--r-- 1 root root 1009 Mar  2 23:07 nginx.csr
-rw------- 1 root root 1679 Mar  2 23:06 nginx.key
[root@www ssl]#

  提示:到此nginx服务器的证书申请文件就做好了,我们只需要把这个申请文件发送给CA

[root@www ssl]# scp -P 41319 nginx.csr qiuhom@192.168.0.99:/tmp/
qiuhom@192.168.0.99's password: 
nginx.csr                                                     100% 1009   225.4KB/s   00:00    
[root@www ssl]# 

  提示:如果SSH没有工作在标准端口,用scp命令时需要用-P(大写)指定ssh端口

  4、CA签发nginx证书

[root@test CA]# openssl ca -in /tmp/nginx.csr -out certs/nginx.pem -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Mar  2 15:11:02 2020 GMT
            Not After : Mar  2 15:11:02 2021 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = SICHUAN
            organizationName          = TEST
            organizationalUnitName    = DEVOPS
            commonName                = www.ilinux.io
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                F7:76:62:31:04:D8:CE:0E:6E:CD:C5:14:05:EF:7F:E4:A5:AD:A0:91
            X509v3 Authority Key Identifier: 
                keyid:D5:61:A5:2F:BF:67:51:78:D7:5D:F8:51:F4:3C:FB:22:F9:E5:A7:3B

Certificate is to be certified until Mar  2 15:11:02 2021 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@test CA]# tree
.
├── cacert.pem
├── certs
│   └── nginx.pem
├── crl
├── index.txt
├── index.txt.attr
├── index.txt.old
├── newcerts
│   └── 01.pem
├── private
│   └── cakey.pem
├── serial
└── serial.old

4 directories, 9 files
[root@test CA]# 

  提示:我们只需要把签好的证书发送给nginx服务器即可

[root@test CA]# scp certs/nginx.pem 192.168.0.30:/etc/nginx/ssl/
The authenticity of host '192.168.0.30 (192.168.0.30)' can't be established.
ECDSA key fingerprint is SHA256:EG9nua4JJuUeofheXlgQeL9hX5H53JynOqf2vf53mII.
ECDSA key fingerprint is MD5:57:83:e6:46:2c:4b:bb:33:13:56:17:f7:fd:76:71:cc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.30' (ECDSA) to the list of known hosts.
root@192.168.0.30's password: 
nginx.pem                                                             100% 4464     2.1MB/s   00:00    
[root@test CA]# 

  提示:到此CA的工作就完成了,接下来我们直接在nginx服务器上直接配置ngxin使用证书

[root@www conf.d]# cat login.conf 
server {
        listen 443 ssl;
        server_name 192.168.0.30;
        root /data/web/html;
        gzip on;
        gzip_types text/xml text/plain;
        gzip_disable Firefox;
        location /basic_status {
                stub_status;
                auth_basic "please input you username and passwd login";
                auth_basic_user_file /etc/nginx/conf.d/.ngxpasswd;
        }
        ssl_certificate "/etc/nginx/ssl/nginx.pem";
        ssl_certificate_key "/etc/nginx/ssl/nginx.key";
        ssl_protocols sslv2 sslv3 tlsv1 tlsv1.1 tlsv1.2;
        ssl_session_cache shared:SSL:10m;


}
[root@www conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@www conf.d]# nginx -s reload
[root@www conf.d]# 

  验证:用浏览器访问下看看我们配置的证书是否生效

   提示:出现这个界面上正常的,因为我们的CA是自己搭建的,浏览器默认不认识,我们可以把CA证书导入浏览器就不会存在这个问题了,接下来我们把CA证书导入浏览器吧

  提示:windows默认是通过后缀来识别文件,所以把CA证书放到windows上后需要更改为.crt为后缀即可.

  导入CA的证书后,我们再来用浏览器访问下我们的网站是否还会提示不是私密连接呢?

 

  我们导入CA证书后,我们重新打开浏览器访问网站,就没有提示不是私密连接了,同时我们访问我们网站也是基于https访问,不再是http;以上就是nginx工作成https服务器搭建过程;

   三、ngx_http_rewrite_module:此模块用于使用PCRE正则表达式查找匹配用户请求的URI,返回重定向和有条件地选择配置来更改请求URI。本质上就是查找替换的过程,用户请求的url通过正则匹配,然后用其他url或uri进行替换,随后把新的url或uri返回给客户端,由客户端重新对新的URL或URI发送请求;

  1、rewrite regex replacement [flag]:将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI;注意:如果在同一级配置块中存在多个rewrite规则,那么会自上而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,因此,隐含有循环机制;[flag]所表示的标志位用于控制此循环机制;如果replacement是以http://或https://开头,则替换结果会直接以重向返回给客户端;其中flag有四种,last表示重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环; 这个也是默认行为,有点类似continue指令的意思,不退出循环,只是退出当次循环,提前进入下次循环;break表示重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环;这个我们可以理解为循环里的break指令,直接跳出循环,进行下面的配置指令;redirect表示重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头;permanent表示重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;这四个值的区别是,前两个浏览器上都看不到跳转(用户是看不到明确的跳转),后两者者看得到;

  示例:

rewrite /(.*)$ https://www.ilinux.io/basic_status;

  提示:以上配置表示客户端访问我们服务器的任何uri都给重写为https://www.ilinux.io/basic_status这个url

  提示:之所以能够看到302的响应码是因为我们在规则里把用户的rul重写成https://www.ilinux.io/basic_status ,浏览器看到重写后的URL是以https开头的,它就会拿着这个url去请求新的URL,所以我们这里可以看到302响应码;

   提示:以上配置表示,用户访问.jpg结尾的URL时,我们都对它重写为访问/test/test.html

  提示:我们对用户请求的url进行替换时,没有用到http或https去替换时,我们在浏览器上是看不到后面浏览器重新对新的url发起请求的请求信息,这是我们重写规则默认使用了last,last和break如果都不以http或https去替换用户的rul,在浏览器是看不到跳转的响应码,要想看到该过程我们可以在后面加redirect或者permanent,它俩的区别在于,一个是临时重定向,响应码是302,一个是永久重定向响应码是301;如下

 rewrite /(.*)\.jpg  /test/ redirect;

  提示:我们只在上面的配置上在rewrite规则上加了一个redirect标记,加上它,浏览器就会对新的uri发起新的请求,如下

  2、return:停止处理并将指定的响应码或URL返回给客户端

    return code [text];表示返回状态码或简短原因短语

    return code URL;返回状态码和url

    return URL;返回url

  3、rewrite_log on | off;是否开启重写日志

  4、if(condition) {……};引入一个新的配置上下文;条件满足时执行配置块中的配置指令;可用在server和location配置段中;这里的条件可以是变量,如果变量是字符串,非空为真,空为假;如果变量是数字则非0为真,0为假;当然条件也可以是一个比较表达式,所谓表达式就是由操作符连接起来的式子,常用的操作符有比较操作符,文件及目录存在性判断;比较操作符有:== 、!= 、~表示模式匹配,区分字符大小写;~*表示模式匹配,不区分字符大小写;!~表示模式不匹配,区分字符大小写;!~*表示模式不匹配,不区分字符大小写;文件及目录存在性判断的有 -e,!-e、-f,!-f、-d,!-d,、-x,!-x,这里的文件或目录存在性判断同shell里面的文件或目录存在性判断是一样的;

  5、set $variable value;设置用户指定以变量;

  示例:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
}

if ($request_method = POST) {
    return 405;
}

if ($slow) {
    limit_rate 10k;
}

if ($invalid_referer) {
    return 403;
}

  提示:第一个if表示判断用户浏览器类型,如果匹配MSIE 则进行url重写,重写为/msie/$1 ,这里的$1表示rewrite规则里匹配到第一个括号里的内容的引用,和sed命令里的\1类似;第二个if表示判断变量$http_cookie 里的值是否匹配后面的正则表达式,如果匹配则设置$id变量的值为$1,这里的$1表示正则表达式里括号分组匹配到的内容;第三个if表示判断用户请求的方法是否是POST,如果是就返回405,意思就是不让用户用POST方法提交数据;第五个if表示判断$slow是否为空,不为空就设置limit_rate 10k,意思就是如果$slow的值为真,则限制客户端的响应;最后一个if表示判断$invalid_referer 是否为空,为空表示没有非法的referer,没有非法referer就不做处理,如果有非法referer,即不为空,则返回403,这是一个防盗链的配置;通常我们要先定义合法的referer,然后再来判断非法referer来实现防盗链(定义了合法的referer后相对的不在合法的referer列表里就表示非法的referer);合法referer的定义可以用valid_referers来指定;

posted @ 2020-03-04 00:44  Linux-1874  阅读(2196)  评论(0编辑  收藏  举报