# 基础介绍

Nginx是一款高性能的http服务器、反向代理服务器、电子邮件服务器,官方测试能够支撑5万并发

  • Nginx做http服务器,只提供静态网页服务
  • 可以实现在一台服务器虚拟出多个网站
  • 反向代理,负载均衡

# Linux安装nginx

# 先安装gcc-c++编译器

yum install gcc-c++
yum install -y openssl openssl-devel

# 再安装pcre包

yum install -y pcre pcre-devel

# 再安装zlib包

yum install -y zlib zlib-devel

# 再安装OpenSSL包

yum install -y openssl openssl-devel

# 安装nginx

下载地址 (opens new window)

tar -zxvf nginx-1.19.9.tar.gz  解压
cd nginx-1.19.9                并进入nginx目录

执行命令 考虑到后续安装ssl证书 添加两个模块
./configure --with-http_stub_status_module --with-http_ssl_module

执行make命令
make
执行make install命令
make install

# 启动nginx服务

 ​​​​​​​/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

# 配置nginx.conf

vi /usr/local/nginx/conf/nginx.conf

# 重启nginx

/usr/local/nginx/sbin/nginx -s reload

# 启动,关闭,重启

在/usr/local/nginx/sbin目录下

./nginx 启动
./nginx -s stop 关闭
./nginx -s reload 重启

# 配置文件

# 运行用户,默认是nginx,可以不进行设置		
user  nginx;
# Nginx进程,一般设置和cpu核数一样
worker_processes  1;

# 错误日志存放位置
error_log  /var/log/nginx/error.log warn;
# 进程pid存放位置
pid        /var/run/nginx.pid;

events {
	# 单个后台进程的最大并发数
    worker_connections  1024;
	
	# 用于限制客户端请求的最大消息体大小
	client_max_body_size 100m;
}

http {
	# 文件扩展名和类型映射表
    include       /etc/nginx/mime.types;
	
	# 默认的文件类型
    default_type  application/octet-stream;
	
    # 设置日志模式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
					  
    # nginx访问日志的存放位置
    access_log  /var/log/nginx/access.log  main;
	
    # 是否开启高效传输模式 on开启 off关闭
    sendfile        off; 
	
	# 减少网络报文段的数量
    #tcp_nopush     on;  
	
    # 保持连接的时间,也叫超时时间
    keepalive_timeout  65; 
	
    # 开启gzip压缩模式
    #gzip  on;
	
    # 包含的子配置项的位置和文件
    #include /etc/nginx/conf.d/*.conf;
	
	server {
	    listen       80;  
		# 配置域名
	    server_name  localhost;  
	    #charset koi8-r;     
	    #access_log  /var/log/nginx/host.access.log  main;
	    location / {
			# 服务默认启动目录
	        root   html; 
			# 默认访问文件
	        index  index.html index.htm;    
	    }
		# 同个端口多个站点
		location /font {
			alias  /usr/nginx/html/font;
			index index.html index.htm;
		}
		
		# 配置404页面
	    #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   /usr/share/nginx/html;
	    }
	    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
	    #
	    #location ~ \.php$ {
	    #    proxy_pass   http://127.0.0.1;
	    #}
	    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
	    #
	    #location ~ \.php$ {
	    #    root           html;
	    #    fastcgi_pass   127.0.0.1:9000;
	    #    fastcgi_index  index.php;
	    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
	    #    include        fastcgi_params;
	    #}
	    # deny access to .htaccess files, if Apache's document root
	    # concurs with nginx's one
	    #
	    #location ~ /\.ht {
	    #    deny  all;
	    #}
	}
	# 不同端口多个站点
	server {
	    listen       81;  
		# 配置域名
	    server_name  www.baidu.com;  
	    location / {
			# 服务默认启动目录
	        root   html; 
			# 默认访问文件
	        index  index.html index.htm;    
	    }
		
		# 错误状态码的显示页面,配置后需要重启
	    error_page   500 502 503 504  /50x.html;   
	    location = /50x.html {
	        root   /usr/share/nginx/html;
	    }
	}
}

注意

  • 部署多个前端项目,可以配置多个server模块
  • 配置二级目录访问 vue 项目
location /font {
	alias  /usr/nginx/html/font;
	index index.html index.htm;
}

# 安全配置(漏扫出现的问题)

http {
    autoindex off;
    server_tokens off;
    client_max_body_size 64m;
    
    # -----------------------------------------
    #  1、此处省略其他 http 节点配置
    #  2、下面的配置也可以写在 server {} 中
    # -----------------------------------------
    
	# 检测到目标X-Content-Type-Options响应头缺失
    add_header X-Content-Type-Options "nosniff"  always;
	
	# 检测到目标X-XSS-Protection响应头缺失
	add_header X-XSS-Protection "1; mode=block"  always;
	
	# 检测到目标Content-Security-Policy响应头缺失
	add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval'" always;
	
	# 检测到目标Referrer-Policy响应头缺失
	add_header Referrer-Policy "origin" always;
	
	# 检测到目标X-Permitted-Cross-Domain-Policies响应头缺失
	add_header X-Permitted-Cross-Domain-Policies  "master-only" always;
	
	# 检测到目标X-Download-Options响应头缺失
    add_header X-Download-Options "noopen" always;
	
	# 点击劫持:X-Frame-Options未配置
	add_header X-Frame-Options "sameorigin" always;
	
	# 检测到目标Strict-Transport-Security响应头缺失
	add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" always;
}

# 反向代理

# 正向代理

局域网内的机器通过某台可以上网的机器上网,比如翻墙软件

正向代理代理的客户端,反向代理代理的服务端

# 反向代理

反向代理方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从内部网络服务器上得到的结果返回给Internet上的客户端,此时代理服务器对外就表现为一个反向代理服务器

# 配置反向代理

http {
    # 配置反向代理、负载均衡
	upstream  sylone-agent{
		server 192.168.177.129:8080 weight=2;
		server 192.168.177.129:8081 weight=1;
		server 192.168.177.129:8082 weight=1;
	}
	server {
		listen       81;  
		# 配置域名
		server_name  www.baidu.com;  
		location / {
			# 服务默认启动目录
			# root   html;
			# 使用反向代理
			proxy_pass http://sylone-agent;
			# 默认访问文件
			index  index.html index.htm;    
		}
		# 或者这样设置
		location /api/ {
			proxy_pass http://192.168.177.129:8081/;
		}
		
		# 错误状态码的显示页面,配置后需要重启
		error_page   500 502 503 504  /50x.html;   
		location = /50x.html {
			root   /usr/share/nginx/html;
		}
	}
}

# 内网访问高德地图nginx代理

在项目部署过程中,若部署服务器处于内网环境,则无法调用高德服务。需要通过搭建代理实现请求的转发,从而获取到在线服务内容。下面的记录解决了内网服务器访问高德地图服务的问题。

# 所需设备

  • 内网服务器(项目所需部署环境,不通公网)
  • 外网服务器(前置机),需要一台能够访问公网的服务器转发我们的请求
  • 内网服务器与外网服务器(前置机)之间的通信

# 代理流程

  • 修改前端:地图服务请求地址
    //原地址
    <script src="https://webapi.amap.com/maps?v=1.4.15&key=****&plugin=AMap.MarkerClusterer,AMap.Geocoder"></script>
    
    //把指向高德服务的地址修改为:内网服务器地址。此时接口请求仍然不通,因为内网服务器没有此地图服务
    <script src="http://171.11.12.121:60000/web1maps?v=1.4.15&key=****&plugin=AMap.MarkerClusterer,AMap.Geocoder"></script>
    

# 内网服务器配置nginx

前端请求发送到内网服务器后,通过nginx反向代理,监听请求端口60000,将请求转发至前置机,此时请求仍然不通,因为前置机同样没有地图服务。注意保持端口通信正常,内网服务器nginx配置如下:

server {
	listen       60000;  //通过端口监听前端请求
	server_name  localhost;

	location /web1 {
		proxy_pass http://130.12.11.23:10010/web1; //转发请求至前置机地址
	}
	location /web2 {
		proxy_pass http://130.12.11.23:10010/web2;
	}
	location /web3 {
		proxy_pass http://130.12.11.23:10010/web3;
	}
	location /web4 {
		proxy_pass http://130.12.11.23:10010/web4;
	}
	location /web5 {
		proxy_pass http://130.12.11.23:10010/web5;
	}
} 

# 前置机配置nginx

请求转发至前置机后,再通过前置机的nginx做反向代理,把请求转发到高德服务器上,从而获取高德官方的服务数据。前置机nginx配置如下:

server {
	listen       10010;
	server_name  localhost;
	location /web1 {
			proxy_pass https://webapi.amap.com/;
	}
	location /web2 {
			proxy_pass http://vdata.amap.com/;
	}
	location /web3 {
			proxy_pass http://restapi.amap.com/;
	}
	location /web4 {
				proxy_pass http://vector.amap.com/;
	}
	location /web5 {
			proxy_pass http://lbs.amap.com/;
	}
}

# 高德自调用接口拦截

在启用高德地图服务的过程中,高德会自调用一些高德服务,非前端主动请求。此时,我们需要把这些自调用的请求拦截下来,转发到我们的内网服务器上。然后按照前面的流程再走一遍。
这里我们会用到拦截器:ajaxhook.js (opens new window),高德自调用的接口地址常用的就是下面拦截的这些,全部做了代理基本上就够了。
前端添加拦截器,全局拦截所有请求,筛选出高德的接口,并做转发。代码如下:

<script src="../static/js/ajaxhook.min.js"></script>
<script>
    ah.proxy({
        onRequest: (config, handler) => {
            // console.log(config.url)
            if (config.url.toString().search('https://vdata.amap.com') != -1) {
                config.url = 'http://171.11.12.121:60000/web2' + config.url.split('vdata.amap.com/')[1];
                console.log(config.url)
            } else if (config.url.toString().search('http://restapi.amap.com') != -1) {
                config.url = 'http://171.11.12.121:60000/web3' + config.url.split('restapi.amap.com/')[1];
                console.log(config.url)
            } else if (config.url.toString().search('http://vector.amap.com') != -1) {
                config.url = 'http://171.11.12.121:60000/web4' + config.url.split('vector.amap.com/')[1];
                console.log(config.url)
            } else if (config.url.toString().search('http://lbs.amap.com') != -1) {
                config.url = 'http://171.11.12.121:60000/web5' + config.url.split('lbs.amap.com/')[1];
                console.log(config.url)
            }
            handler.next(config);
        },
        onError: (err, handler) => {
            console.log(err.type)
            handler.next(err)
        },
        onResponse: (response, handler) => {
            // console.log(response.response)
            handler.next(response)
        }
    })
</script>