1. Nginx服务器基础配置实例
前面我们已经对Nginx服务器默认配置文件的结构和涉及的基本指令做了详细的阐述。通过这些指令的合理配置,我们就可以让一台Nginx服务器正常工作,并且提供基本的web服务器功能。
接下来我们将通过一个比较完整和最简单的基础配置实例,来巩固下前面所学习的指令及其配置。
需求如下:
(1)有如下访问:
http://192.168.200.133:8081/server1/location1
访问的是: index_sr1__1ocation1.htm1
http://192.168.200.133:8081/server1/location2
访问的是: index_sr1__1ocation2.htm1
http://192.168.200.133:8082/server2/location1
访问的是: index_sr2_location1.htm1
http://192.168.200.133:8082/server2 /location2
访问的是: index_sr2_location2.htm1
(2)如果访问的资源不存在,
返回自定义的404页面
(3)将/server1和/server2的配置使用不同的配置文件分割
将文件放到/home/www/conf.d目录下,然后使用include进行合并
(4)为/server1和/server2各自创建一个访问日志文件
2. Nginx服务操作的问题
经过前面的操作,我们会发现,如果想要启动、关闭或重新加载nginx配置文件,都需要先进入到nginx的安装目录的sbin目录,然后使用nginx的二级制可执行文件来操作,相对来说操作比较繁琐,这块该如何优化?另外如果我们想把Nginx设置成随着服务器启动就自动完成启动操作,又该如何来实现?这就需要用到接下来我们要讲解的两个知识点:
Nginx配置成系统服务
Nginx命令配置到系统环境
2.1 Nginx 配置成系统服务
把Nginx应用服务设置成为系统服务,方便对Nginx服务的启动和停止等相关操作,具体实现步骤:
(1)在/usr/lib/systemd/system在目录下添加nginx.service,内容如下:
vim usr/lib/systemd/system/nginx.service
[unit]# 该区域主要对应一些文档描述等信息,可以不用管
Description=nginx web service
Documentation=http://nginx.org/en/ docs/
After=network.target
[service]
Type=forking
PIDFi1e=/usr/loca1/nginx/logs/nginx.pid #指向自己Nginx的相关pid配置文件注意是自己的路径不是现在写的,以下所有的路径都是自己安装Nginx时配置的路径,如果通过yum安装的话就直接在/usr/sbin目录下输入./nginx -V进行查找
ExecstartPre=/usr/1oca1/nginx/sbin/nginx -t -c/usr/local/nginx/ conf/nginx.confI #执行开始之前需要对nginx进行测试 -t 时开始测试,-c是配置文件的路径
Execstart=/usr/ local/nginx/sbin/nginx
ExecReload=/usr/ local/nginx/sbin/nginx -s reload
Execstop=/usr / local/nginx/sbin/nginx -s stop
PrivateTmp=true
[Insta11]
wantedBy=default.target
(2)添加完成后如果权限有问题需要进行权限设置
chmod 755 /usr/lib/systemd/system/nginx.service
注意:如果是通过yum安装可以省去上面的步骤。yum安装直接配置好了系统服务。
(3)使用系统命令来操作Nginx服务(在执行这些命令之前需要把ngixn关掉)
启动:systemctl start nginx
停止:systemctl stop nginx
重启:systemctl restart nginx
重新加载配置文件:systemctl relaod nginx
查看nginx状态:systemctl status nginx
开机启动:systemctl enable nginx
注意:如果是通过yum安装可以省去上面的步骤。yum安装直接配置好了系统服务。
2.2 Nginx命令配置到系统环境
前面我们介绍过Nginx安装目录下的二级制可执行文件nginx的很多命令,要想使用这些命令前提是需要进入sbin目录下才能使用,很不方便,如何去优化,我们可以将该二进制可执行文件加入到系统的环境变量,这样的话在任何目录都可以使用nginx对应的相关命令。具体实现步骤如下:
(1)修改/etc/profile文件
vim /etc/profile
# 打开该文件后在最后一行添加如下命令
export PATH=$PATH:/usr/sbin #注意/usr/sbin路径是Nginx安装目录下的二级制可执行文件所在的目录,不同的安装方式,该路径不同,我这写的是yum安装时的二级可执行文件所在的目录
(2)使之立即生效
source /etc/profile # 该命令是在Nginx安装目录下的二级制可执行文件所在的目录下执行的
注意配置成功后使用的是nginx而非./nginx
3. Nginx静态资源部署
3.1 Nginx静态资源概述
上网去搜索访问资源对于我们来说并不陌生,通过浏览器发送一个HTTP请求实现从客户端发送请求到服务器端获取所需要内容后并把内容回显展示在页面的一个过程。这个时候,我们所请求的内容就分为两种类型,一类是静态资源、一类是动态资源。
静态资源即指在服务器端真实存在并且能直接拿来展示的一些文件,比如常见的html页面、css文件、js文件、图片、视频等资源;
动态资源即指在服务器端真实存在但是要想获取需要经过一定的业务逻辑处理,根据不同的条件展示在页面不同这一部分内容,比如说报表数据展示、根据当前登录用户展示相关具体数据等资源;
Nginx处理静态资源的内容,我们需要考虑下面这几个问题:
(1)静态资源的配置指令
(2)静态资源的配置优化
(3)静态资源的压缩配置指令
(4)静态资源的缓存处理
(5)静态资源的访问控制,包括跨域问题和防盗链问题
3.2 Nginx静态资源的配置指令
3.2.1 listen指令
listen:用来配置监听端口
语法 | listen address[:port] [default_server]…; listen port [default_server]…; |
---|---|
默认值 | listen *:80 | *:8000 |
位置 | server |
listen的设置比较灵活,比如:
listen 127.0.0.1:8000; //listen localhost:8000 # 监听指定的IP和端口
listen 127.0.0.1; # 监听指定IP的所有端口
listen 8000; # 监听指定端口上的连接
listen *:8000; # 监听指定端口上的连接
default_server属性是标识符,用来将此虚拟主机设置成默认主机。所谓的默认主机指的是如果没有匹配到对应的address:port ,则会默认值执行的。如果不指定默认使用的是第一个server。
3.2.2 server_name指令
server_name:用来设置虚拟主机服务名称。
比如:127.0.0.1 localhost ;域名[www.baidu.com]等
语法 | server_name name…; name可以提供多个中间用空格分隔 |
---|---|
默认值 | server_name “” |
位置 | server |
关于server_name的配置方式有三种,分别是:
精确匹配
通配符匹配
正则表达式匹配
配置方式一:精确匹配
如:
server {
listen 80;
server_name www.123.com www.456.cn;
}
补充小知识点:
hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析。
widows系统所在目录:C:\Window\System32\drivers\etc
centos系统所在目录:/etc/hosts
因为域名是要收取一定的费用,所以我们可以使用修改hosts文件来制作一些虚拟域名来使用。需要修改/etc/hosts文件来添加
vim /etc/hosts
127.0.0.1 www.itcast.cn www.itheima.cn
配置方式二:使用通配符配置
server_name中支持通配符"*",但需要注意的是通配符不能出现在域名中间,只能出现在首段或尾段,如:
server {
listen 80;
server_name *.123.cn www.123.*;
}
下面的配置就会报错
server {
listen 80;
server_name www.*.cn www.123.c*
}
配置三:使用正则表达式配置
server_name中可以使用正则表达式,并且使用~作为正则表达式字符串的开始标记。
常见的正则表达式
代码 | 说明 |
---|---|
^ | 匹配搜索字符串开始位置 |
$ | 匹配搜索字符串结束位置 |
. | 匹配除换行符\n之外的任何单个字符 |
\ | 转义字符,将下一个字符标记为特殊字符 |
[xyz] | 字符集,与任意一个指定字符匹配 |
[a-z] | 字符范围,匹配指定范围内的任何字符 |
\w | 与以下任意字符匹配A-Z a-z0-9和下划线,等效于[A-Za-z0-9_] |
\d | 数字字符匹配,等效于[0-9] |
{n} | 正好匹配n次 |
{n,} | 至少匹配n次 |
{n,m} | 匹配至少n次至多m次 |
* | 零次或多次,等效于{0,} |
+ | —次或多次,等效于{1,} |
? | 零次或一次,等效于{0,1} |
配置如下:
server {
listen 80;
server_name ~^www\.(\w+)\.com$;
location / {
default_type text/plain;
return 200 $1;
}
}
注意 ~后面不能加空格,括号可以取值
匹配执行顺序
No1:准确匹配server_name
NO2:通配符在开始时匹配server_name
NO3:通配符在结束时匹配server_name
NO4:正则表达式匹配server_name
NO5:被默认的default_server处理,如果没有指定默认找第一个server
3.2.3 location指令
server {
listen 80;
server_name localhost;
location / {
}
location /abc {
}
...
}
location:用来设置请求URI
语法 | location [= | ~ | ~* | ^~ | @] uri{…} |
---|---|
默认值 | - |
位置 | server,location |
uri变量是待匹配的请求字符串,可以不包含正则表达式,也可以包含正则表达式,那么nginx服务器在搜索匹配location的时候,是先使用不包含正则表达式进行匹配,找到一个匹配度最高的一个,然后在通过包含正则表达式的进行匹配,如果能匹配到直接访问,匹配不到,就使用刚才匹配度最高的那个location来处理请求。
属性介绍:
不带符号,要求必须以指定模式开始
server {
listen 80;
server_name 127.0.0.1;
location /abc{
default_type text/plain;
return 200 "access success";
}
}
# 一下访问都是正确的
http://192.168.200.133/abc
http://192.168.200.133/abc?p1=TOM
http://192.168.200.133/abc/
http://192.168.200.133/abcde
=:用于不包含正则表达式的uri前,必须与指定的模式精确匹配
server {
listen 80;
server_name 127.0.0.1;
location =/abc{
default_type text/plain;
return 200 "access success";
}
}
# 可以匹配到
http://192.168.200.133/abc
http://192.168.200.133/abc?p1=TOM #注意问好后面的不参与匹配,代表的是携带参数
# 不可以匹配到
http://192.168.200.133/abc/
http://192.168.200.133/abcde
~:用于表示当前uri中包含了正则表达式,并且区分大小写
~*:用于表示当前uri中包含了正则表达式,并且不区分大小写
server {
listen 80;
server_name 127.0.0.1;
location ~^/abc\w${
default_type text/plain;
return 200 "access success";
}
}
server {
listen 80;
server_name 127.0.0.1;
location ~*/abc\w${
default_type text/plain;
return 200 "access success";
}
}
^~:用于不包含正则表达式的uri前,功能和不加符号一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了。
server {
listen 80;
server_name 127.0.0.1;
location ^~/abc {
default_type text/plain;
return 200 "access success";
}
}
3.2.4 设置请求资源的目录root/alias
root:设置请求的根目录
语法 | root path; |
---|---|
默认值 | root html; |
位置 | http、server、location |
path为Nginx服务器接收到请求以后查找资源的根目录路径。
alias:用来更改location的URI
语法 | alias path; |
---|---|
默认值 | - |
位置 | location |
path为修改后的根路径。
以上两个指令都可以来指定访问资源的路径,那么这两者之间的区别是什么?
举例说明:
(1)在usr/local/nginx/html目录创建一个images目录,并在目录下放入一张图片mv.png图片
location /images {
root /usr/local/nginx/html;
}
访问图片的路径为:
http://192.168.200.133/images/mv.png
(2)如果把root改为alias
location /images {
alias /usr/local/nginx/html;
}
再次访问上述地址,页面会出现404的错误,查看错误日志会发现是因为地址不对,所以验证了:
root的处理结果是:root路径+location路径
也就是/usr/local/nginx/html+/images/mv.png
alias的处理结果是:使用alias路径替换location路径
也就是/usr/local/nginx/html+/images
在使用alias的时候在location所在行的目录后面要加上“/”,也要在alias后面目录的最后面加上“/”。
3.2.5 index指令
index:设置网站的默认首页
语法 | index file…; |
---|---|
默认值 | index index.html |
位置 | http、server、location |
index后面可以跟多个设置,如果访问的时候没有指定具体访问的资源,则会依次进行查找,找到第一个为止。
举例说明:
location / {
root /usr/local/nginx/html;
index index.html index.htm;
}
访问该location的时候,可以通过 http://ip:port/,地址后面如果不添加任何内容,则默认一次访问index.html和index.htm,找到第一个来进行返回
3.2.6 error_page指令
error_page:设置网站的错误页面
语法 | error_page code…[=[response]] uri; |
---|---|
默认值 | - |
位置 | http、server、location… |
举例说明:
(1)可以指定具体跳转的地址
server {
error_page 404 http://www.123.cn
}
(2)可以指定重定向地址
server {
error_page 404 /50x.html;
error_page 500 502 503 504 50x.html;
location = /50x.html{
root html;
}
}
(3)使用location的@符合完成错误信息展示
server {
error_page 404 @jump_to_error;
location @jump_to_error {
default_type text/plain;
return 404 'Not Found Page...';
}
}
可选项=[response]的作用是用来将相应的代码更改为另一个
server {
error_page 404 =200 /50x.html;
location =/50x.html {
root html;
}
}
这样的话,当返回404找不到对应的资源的收,在浏览器上可以看到,最终返回的状态码是200,这块需要注意下,编写error_page后面的内容,404后面需要加空格,200前面不能加空格
3.3 静态资源优化配置语法
Nginx对静态资源如何进行优化配置。这里从三个属性进行优化:
sendfile on;
tcp_nopush on;
tcp_nodeplay on;
(1)sendfile,用来开启高效的文件传输模式。
语法 | sendfile on | off |
---|---|
默认值 | sendfile off |
位置 | http、server、location |
请求静态资源的过程:客户端通过网络接口向服务端发送请求,操作系统将这些客户端的请求传递给服务器端应用程序,服务器端应用程序会处理这些请求,请求处理完成以后,操作系统还需要将处理得到的结果通过网络适配器传递回去。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MUok41eP-1629097155341)(https://upload-images.jianshu.io/upload_images/17760521-bae2b0a7bab96c5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ljBWdFlv-1629097155344)(https://upload-images.jianshu.io/upload_images/17760521-5a94c769e9ca60e2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XE4JP83P-1629097155347)(https://upload-images.jianshu.io/upload_images/17760521-4c7c1e89d7c9bb8d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
(2)tcp_nopush:该指令必须在sendfile打开的状态下才会生效,主要是用来提升网络包的传输‘效率’
语法 | tcp_nopush on | off; |
---|---|
默认值 | tcp_nopush off; |
位置 | http、server、location |
(3)tcp_nodelay:该指令必须在keep-alive连接开启的情况下才生效,来提高网络包的传输‘实时性’
语法 | tcp_nodelay on | off |
---|---|
默认值 | tcp_nodelay on |
位置 | http、server、location |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2VvuziY-1629097155350)(https://upload-images.jianshu.io/upload_images/17760521-7f0602bb8c1047b0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
“tcp_nopush"和"tcp_nodelay"看起来是"互斥的”,那么为什么要将这两个值都打开,这个大家需要知道的是在linux2.5.9以后的版本中两者是可以兼容的,三个指令都开启的好处是,sendfile可以开启高效的文件传输模式,tcp_nopush开启可以确保在发送到客户端之前数据包已经充分"填满",这大大减少了网络开销,并加快了文件发送的速度。然后,当它到达最后一个可能因为没有"填满"而暂停的数据包时,Nginx会忽略tcp_nopush参数,然后,tcp_nodelay强制套接字发送数据。由此可知,TCP_NOPUSH可以与TCP_NODELAY一起设置,它比单独配置TCP_NODELAY具有更强的性能。所以我们可以使用如下配置来优化Nginx静态资源的处理
4. Nginx反向代理
4.1 Nginx反向代理配置语法
Nginx反向代理模块的指令是由ngx_http_proxy_module模块进行解析,该模块在安装Nginx的时候已经自己加装到Nginx中了,接下来我们把反向代理中的常用指令一—介绍下:
proxy_pass
proxy_set_header
proxy_redirect
4.1.1 proxy_pass指令
该指令用来设置被代理服务器的地址,可以是主机名称、IP地址加端口号的形式
语法 | proxy_pass URL; |
---|---|
默认值 | - |
位置 | location |
URL:为要设置的被代理服务器地址,包含传输协议(http,https://)、主机名称或IP地址加端口号,URI等要素。
在编写proxy_pass的时候,后面的值要不要加“/”?
用例子来说明问题
server {
listen 80;
server_name localhost;
location /{
#proxy_pass http://192.168.200.146;
proxy_pass http://192.168.146/
}
}
# 当location后面只有一个“/”的时候加与不加效果一样
server {
listen 80;
server_name localhost;
location /server {
#proxy_passs http://192.168.200.146;
proxy_pass http://192.168.200.146/;
}
}
当客户端访问http://1ocalhost/server/index.htm1
这个时候,第一个proxy_pass就变成了http: / /localhost/server/index.htm1第二个proxy_pass就变成了http: / /localhost/index.htm1效果就不一样了。
4.1.2 proxy_set_header指令
该指令可以更改Nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给代理服务器
语法 | proxy_set_header field value; |
---|---|
默认值 | proxy_set_header Host $ proxy_host; proxy_set_header Connection close; |
位置 | http、server、location |
需要注意的是,如果想要看到结果,必须在被代理的服务器上来获取添加的头信息。
被代理服务器:[192.168.200.146]
server {
listen 8080;
server_name localhost;
default_type text/plain;
return 200 $http_username;
}
代理服务器:[192.168.200.133]
server {
listen 8080;
server_name localhost;
location /server {
proxy_pass http://192.168.200.146:8080/;
proxy_set_header username TOM;
}
}
4.1.3 proxy_redirect
该指令是用来重置头信息中“Location”和“Refresh”的值。
语法 | proxy_redirect redirect replacement; proxy_redirect default; proxy_redirect off; |
---|---|
默认值 | proxy_redirect default; |
位置 | http、server、location |
为什么要使用该指令?
服务端[192.168.200.146]
server {
listen 8081;
server_name localhost;
if (!-f $request_filename) {
return 302 http://192.168.200.146;
}
}
代理服务端[192.168.200.133]
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://192.168.200.146:8081/;
proxy_redirect http:/192.168.200.146 http://192.168.200.133;
}
}
该指令的几组选项
proxy_redirect redirect replacement;
redirect:目标;Location的值
replacement:要替换的值
proxy_redirect default;
default;
将location块的uri变量作为replacement,
将proxy_pass变量作为redirect进行替换
proxy_redirect off;
关闭proxy_redirect的功能
4.2 Nginx的安全控制
关于web服务器的安全是比较大的一个话题,里面所涉及的内容很多,Nginx反向代理是如何来提升web服务器的安全呢?
安全隔离
什么是安全隔离?
通过代理分开了客户端到应用程序服务器端的连接,实现了安全措施。在反向代理之前设置防火墙,仅留一个入口供代理服务器访问。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B3KwerB5-1629097155352)(https://upload-images.jianshu.io/upload_images/17760521-63e3a38c3c6bb230.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
4.2.1 如何使用SSL对流量进行加密
翻译成大家能熟悉的说法就是将我们常用的http请求转变成https请求,那么这两个之间的区别简单的来说两个都是HTTP协议,只不过https是身披SSL外壳的http.
HTTPS是一种通过计算机网络进行安全通信的传输协议。它经由HTTP进行通信,利用SsL/TLS建立全通信,加密数据包,确保数据的安全性。
SSL(Secure Sockets Layer)安全套接层
TLS(Transport Layer Security)传输层安全
上述这两个是为网络通信提供安全及数据完整性的一种安全协议,TLS和SSL在传输层和应用层对网络连接进行加密。
总结来说为什么要使用htups:
http协议是明文传输数据,存在安全问题,而https是加密传输,相当于http+ss1,并且可以防止流量劫持。
Nginx要想使用SSL,需要满足一个条件即需要添加一个模块```–with-http_ss1_module``,而该模块在编译的过程中又需要OpenSSL的支持,这个我们之前已经准备好了。
4.2.2 Nginx的SSL相关指令
SSL:该指令用来指定的服务器开启HTTPS,可以使用listen 443 ssl,后面这种方式更通过用些。
语法 | ssl on | off |
---|---|
默认值 | ssl off |
位置 | http、server |
server {
listen 443 ssl;
}
ssl_certificate:为当前这个虚拟主机指定一个带有PEM格式证书。
语法 | ssl_certificate file; |
---|---|
默认值 | - |
位置 | http、server |
ssl_certificate_key:该指令用来指定PEM secret key文件的路径
语法 | ssl_certificate_key file; |
---|---|
默认值 | - |
位置 | http、server |
ssl_session_cache:该指令用来配置用于SSL会话的缓存
语法 | ssl_session_cache off | none | [builtin[:size]] [share:name:size] |
---|---|
默认值 | ssl_session_cache none; |
位置 | http、server |
off:禁用会话缓存,客户端不得重复使用会话
none:禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数
builtin:内置OpenSSL缓存,仅在一个工作进程中使用。
shared:所有工作进程之间共享缓存,缓存的相关信息用name和size来指定
ssl_session_timeout:开启SSL会话功能后,设置客户端能够反复使用存储在缓存中的会话参数时间
语法 | ssl_session_timeout time |
---|---|
默认值 | ssl_session_timeout 5m |
位置 | http、server |
ssl_ciphers:指出允许的密码,密码指定为Open SSL支持格式
语法 | ssl_ciphers ciphers |
---|---|
默认值 | ssl_ciphers HIGH:!aNULL:!MD%; |
位置 | http、server |
可以使用openssl ciphers
查看openssl支持的格式
ssl_prefer_server_ciphers:该指令指定是否服务器密码优先客户端密码
语法 | ssl_perfer_server_ciphers on | off; |
---|---|
默认值 | ssl_perfer_server_ciphers off; |
位置 | http、server |
4.2.3 生成SSL证书
使用openssl生成证书
先确认当前系统是否安装openssl
openssl version
安装下面的命令进行生成
mkdir /root/cert
cd /root/cert
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
开启SSL实例
server {
listen 443 ss;
server_name localhost;
ssl_certificate server.cert;
ssl_certificate_key server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}