Linux架构08 nginx多虚拟主机, 日志, 日志目录模块, 访问限制模块, nginx中的变量, favicon图标
方式一:基于主机多IP方式
[root@web01 conf.d]# cat chess.conf server { listen 10.0.0.7:80; server_name localhost; location / { root /code/chess; index index.html; } } [root@web01 conf.d]# cat snake.conf server { listen 172.16.1.7:80; server_name localhost; location / { root /code/snake; index index.html; } } # 注意: 修改完配置,nginx重启才生效,重新加载没生效。通过 netstat -lntp 判断 [root@web01 conf.d]# systemctl restart nginx [root@web01 conf.d]# netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 5632/rpcbind tcp 0 0 172.16.1.7:80 0.0.0.0:* LISTEN 11113/nginx: master tcp 0 0 10.0.0.7:80 0.0.0.0:* LISTEN 11113/nginx: master
[root@web01 conf.d]# cat chess.conf server { listen 81; server_name localhost; location / { root /code/chess; index index.html; } } [root@web01 conf.d]# cat snake.conf server { listen 80; server_name localhost; location / { root /code/snake; index index.html; } } [root@web01 conf.d]# systemctl restart nginx # 检查 [root@web01 conf.d]# netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 5632/rpcbind tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 11178/nginx: master tcp 0 0 0.0.0.0:81 0.0.0.0:* LISTEN 11178/nginx: master
[root@web01 conf.d]# cat chess.conf server { listen 80; server_name www.chess.com; location / { root /code/chess; index index.html; } } [root@web01 conf.d]# cat snake.conf server { listen 80; server_name www.snake.com; location / { root /code/snake; index index.html; } } [root@web01 conf.d]# systemctl restart nginx # 修改本地hosts C:\Windows\System32\drivers\etc\hosts 10.0.0.7 www.chess.com www.snake.com
# 注: 可以通过修改访问域名实现 [root@web01 conf.d]# vim chess.conf server { listen 80; server_name localhost; location / { root /code/chess; index index.html; } location /snake { # 这块不写,10.0.0.7/snake访问/code/chess/snake下的index.html root /code; # 相当于把域名追加到/code后面,等于在/code/snake中找 index index.html; } }
一般测试环境使用多端口的方式;
公司内部或者生产环境使用基于域名的方式;
[root@web01 conf.d]# cat chess.conf server { listen 80; server_name www.chess.com; access_log /var/log/nginx/www.chess.com.log main; location / { root /code/chess; index index.html; } } [root@web01 conf.d]# cat snake.conf server { listen 80; server_name www.snake.com; access_log /var/log/nginx/www.snake.com.log main; location / { root /code/snake; index index.html; } } [root@web01 conf.d]# systemctl restart nginx [root@web01 conf.d]# cd /var/log/nginx/ [root@web01 nginx]# ll total 48 -rw-r----- 1 nginx adm 9308 Aug 2 23:47 access.log -rw-r----- 1 nginx adm 31749 Aug 3 00:43 error.log -rw-r--r-- 1 root root 575 Aug 3 00:43 www.chess.com.log -rw-r--r-- 1 root root 0 Aug 3 00:42 www.snake.com.log
Nginx有非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志。日志格式通过log_format命令定义格式。
# 配置语法: 包含: error.log access.log Syntax: log_format name [escape=default|json] string ...; Default: log_format combined "..."; Context: http
自定义错误日志
默认路径: access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; 错误日志,级别默认是error error_log file [level]; #指定保存错误日志的文件和记录级别,错误级别可参考syslog那一课 的内容 #如果不需要记录日志,值可以写在 /dev/null #默认值 error_log logs/error.log error server{ listen 80; server_name www.m99-magedu.com; root /var/www/html/www.m99-magedu.com; error_log /var/log/nginx/www.m99-magedu.com.error.log; #为当前 server 配置定义单独的 error_log location = /abc { #此资源报错不记 录日志 error_log /dev/null; } }
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
$remote_addr # 记录客户端IP地址 $remote_user # 记录客户端用户名 $time_local # 记录通用的本地时间 $time_iso8601 # 记录ISO8601标准格式下的本地时间 $request # 记录请求的方法以及请求的的http协议 $status # 记录请求状态码(用于定位错误信息) $body_bytes_sent # 发送给客户端的资源 字节数,不包括响应头的大小 $bytes_sent # 发送给客户端的总字节数 $msec # 日志写入时间。单位为秒,精度是毫秒。 $http_referer # 记录从哪个网页链接访问过来的 $http_user_agent # 记录客户端浏览器相关信息 $http_x_forwarded_for # 记录用户真实IP地址 $request_length # 请求的长度(包含请求行,请求头和请求正文)。 $request_time # 请求话费的时间,单位为秒,精度毫秒 # 注:如果Nginx位于负载均衡器,nginx反向代理之后,web服务器无法直接获取客户端真实的IP地址。 # $remote_addr获取的是反向代理的IP地址。反向代理服务器在转发请求的http头信息中, # 增加X-Forwarded-For信息,用来记录客户端IP地址和客户端请求的服务器地址。
自定义日志格式
#自定义访问日志格式 - 字符串 log_format basic '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; #自定义访问日志格式 - json 字符串 log_format json_basic '{"remote_addr": "$remote_addr", ' '"remote_user": "$remote_user", ' '"time_local": "$time_local", ' '"request": "$request", ' '"status": "$status", ' '"body_bytes_sent": "$body_bytes_sent", ' '"http_referer": "$http_referer", ' '"http_user_agent": "$http_user_agent", ' '"http_x_forwarded_for": "$http_x_forwarded_for"}'; server{ listen 80; server_name www.m99-magedu.com; root /var/www/html/www.m99-magedu.com; access_log /var/log/nginx/${host}_access.log basic; location /json{ access_log /var/log/nginx/${host}_json_access.log json_basic; #记录json 格式 return 200 "json"; } location /test{ access_log off; #不记录access log return 200 "test"; } }
使用logrotate切割日志 [root@web01 ~]# cat /etc/logrotate.d/nginx # 要切割的日志存放位置 /var/log/nginx/*.log { #每天切割日志 daily #日志丢失忽略 missingok #日志保留时间(天) rotate 52 #日志文件压缩 compress #延时压缩 delaycompress #不切割空文件 notifempty #指定日志文件权限 属主nginx 数组adm create 640 nginx adm #脚本起始 sharedscripts #标注脚本内容 postrotate if [ -f /var/run/nginx.pid ]; then #判断是否有pid文件 kill -USR1 `cat /var/run/nginx.pid` #日志重读(重新生成日志文件) fi #脚本结束 endscript }
限制固定路径跳转才能访问
server { listen 80; server_name www.host2.com; set $domain "10.0.0.1"; if ($remote_addr != $domain){ # 如果不是该地址,不能访问 return 403; } location / { root /codehost2; index index.html; } }
ngx_http_autoindex_module模块处理以斜杠字符('/')结尾的请求,并生成目录列表。 当ngx_http_index_module模块找不到索引文件时,通常会将请求传递给ngx_http_autoindex_module模块。 # ngx_http_index_module模块就是配置文件中index配置
Syntax: autoindex on | off; #是否显示目录内容列表,默认 off Default: autoindex off; Context: http, server, location # 常用参数 charset utf-8; 默认中文是乱码,添加该参数可以解决乱码问题(推荐设置在http层,但也可以设置在server层) autoindex_exact_size off; # 可设置在http层,或server层 默认为on,显示出文件的确切大小,单位是bytes。 修改为off,显示出文件的大概大小,单位是KB或者MB或者GB。 autoindex_localtime on; # 显示文件最后修改时间 默认为off,显示的文件时间为GMT时间。 修改为on,显示的文件时间为本地时间。
#如果改成其他格式,那么请求返回的就是其他格式数据(json方便代码查询数据)
autoindex_format html|xml|json|jsonp; #数据显示格式,默认 html
例:
[root@web01 conf.d]# vim chess.conf server { listen 80; server_name localhost; access_log /var/log/nginx/www.chess.com.log main; location / { root /code; autoindex on; # 找不到index配置文件,会改为目录列表显示 autoindex_exact_size off; autoindex_localtime on; #index index.html; } }
如目录列表中有中文文件名,显示乱码,修改nginx配置文件中的字符编码
[root@web01 centos]# vim /etc/nginx/nginx.conf # 这里在http层进行设置 user www; ... http { include /etc/nginx/mime.types; default_type application/octet-stream; charset utf-8; ... }
# 允许访问 Syntax: allow address | CIDR | unix: | all; Default: — Context: http, server, location, limit_except #拒绝访问语法 Syntax: deny address | CIDR | unix: | all; Default: — Context: http, server, location, limit_except
官网示例
location / { deny 192.168.1.1; allow 192.168.1.0/24; # 除了192.168.1.1外,192.168.1这个网段都可以访问 }
# 允许10.0.0.1访问,其他网址不允许 server { listen 80; server_name localhost; access_log /var/log/nginx/www.chess.com.log main; location / { root /code; autoindex on; allow 10.0.0.1; # 配置从上往下读,要先允许在拒绝。如果先deny all,就不会往下读了 deny all; } } # 也可以通过其他文件引入访问控制 server { listen 80; server_name localhost; access_log /var/log/nginx/www.chess.com.log main; location / { root /code; autoindex on; include /access/*.sh; # 把要禁止的内容写入该路径下 } } vim /access/1.sh allow 10.0.0.1; deny all; # 拒绝10.0.0.1访问,其他都可以访问 server { listen 80; server_name localhost; access_log /var/log/nginx/www.chess.com.log main; location / { root /code; autoindex on; deny 10.0.0.1; allow all; } } # 允许10.0.0.0网段访问,其他网段不允许 server { listen 80; server_name localhost; access_log /var/log/nginx/www.chess.com.log main; location / { root /code; autoindex on; allow 10.0.0.0/24; deny all; } }
server { listen 80; server_name localhost; access_log /var/log/nginx/www.chess.com.log main; location / { root /code; index index.html; } location /download { root /code; autoindex on; autoindex_exact_size off; autoindex_localtime on; allow 172.16.1.0/24; deny all; } }
Nginx 中的变量
Nginx 内置变量
$remote_addr # 客户端公网IP,如果经多层Nginx代理,那最后的Nginx 通过此变量无法获取客户端IP $proxy_add_x_forwarded_for # 代理IP和真实客户端IP $args # URL中的所有参数 $is_args # 是否有参数,有参数该变量值为 ?,没有参数值为空 $document_root # 当前资源的文件系统路径 $document_uri # 当前资源不包含参数的URI $host # 请求头中的host值 $remote_port # 客户端随机问口 $remote_user # 经过 auth basic 验证过的用户名 $request_body_file # 作为反向代理发给后端服务器的本地资源名称 $request_method # 当前资源的请求方式 GET/PUT/DELETE 等 $request_filename # 当前资源在文件系统上的绝对路径 $request_uri # 不包含的主机名的URI,包含请求的资源和参数 $scheme # 请求协议, HTTP/HTTPS/FTP 等 $server_protocol # 客户端请求的协议版本 HTTP/1.0, HTTP/1.1, HTTP/2.0 等 $server_addr # 服务器IP $server_name # 服务器主机名 $server_port # 服务器端口号 $http_user_agent # 客户端UA $http_cookie # 客户端所有COOKIE $cookie_<name> # 获取指定COOKIE $http_<name> # 获取指定的请求头中的字段,如果字段有中划线要替换成下划线,大写转成小写 $sent_http_<name> # 获取指定的响应头中的字段,如果字段有中划线要替换成下划线,大写转成小写 $arg_<name> # 获取指定参数
用户自定义变量
在 Nginx 中,除了内置变量外,我们还可以使用 set 指令来自定义变量 set $variable value; # 自定义变量,变量名以$开头,变量值可以从其它变量中获取,也可以直接指定 # 作用域 server, location, if 例: server { listen 80; server_name www.m99-magedu.net; root /apps/nginx/html/www.m99-magedu.net; set $var1 1234; #直接赋值,数字 set $var2 "hello world"; #直接赋值,字符串,中间有空格 set $var3 $host; #间接赋值,从内置变量中获得值 location /set{ set $var4 $var1; #间接赋值,从内置变量中获得值 echo $var1; echo $var2; echo $var3; echo $var4; } } #测试 [root@ubuntu ~]# curl www.m99-magedu.net/set 1234 hello world www.m99-magedu.net 1234
favicon图标
favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发
起请求获取页面的 favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404
日志,而且浏览器也会显示404报错
#解决办法 服务器不记录访问日志 server{ listen 80; server_name www.m99-magedu.com; root /var/www/html/www.m99-magedu.com; location = /favicon.ico { log_not_found off; #没找到文件不记录错误日志 access_log off; #不记录访问日志 } } 或者 #解决办法 给出文件,并设置有效期 #默认会在项目路径下找favicon.ico文件 server{ listen 80; server_name www.m99-magedu.com; root /var/www/html/www.m99-magedu.com; location = /favicon.ico { root /var/www/html/www.m99-magedu.com/static; expires 7d; #首次请求缓存后,7天内不再发起请求,但服务端更新后客户端有 可能要7天后才更新 access_log off; } }