nginx学习笔记

一、Nginx的安装

1.1 源码编译

Nginx官网下载对应版本的源码包并解压

wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar xvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
git clone http://github.com/simpl/ngx_devel_kit.git ## 扩展模块
git clone http://github.com/calio/form-input-nginx-module.git ## 扩展模块
./configure \
    --prefix=/usr \ ## 应用默认根路径
    --without-http_memcached_module \
    --with-http_stub_status_module \
    --with-http_ssl_module --with-pcre \
    --add-module=ngx_devel_kit \
    --add-module=form-input-nginx-module \
    --add-module=echo-nginx-module \
    --add-module=lua-nginx-module \
    --pid-path=/usr/local/nginx/nginx.pid \  ## 指定PID路径
    --error-log-path=/usr/local/nginx/error.log \ ##指定error-log路径
    --conf-path=/etc/nginx/nginx.conf \## 指定conf路径
    --sbin-path=/usr/sbin/nginx ## 指定nginx文件路径
make && make install

一般而言,上述后面几个参数在指定prefix后不用指定。但对于只是出于更新原有nginx的binary文件目的,需要指定原先的相应配置目录。对于重新编译nginx,可以通过nginx -V查看之前的编译信息。

注意,lua模块务必使用文档所说版本。
make upgrade可以让nginx进行平滑升级,参见文档

一、反向代理与正向代理

1.1 反向代理

简单来说,是一个服务端通过一个统一的门户(反向代理服务器,用户可见)处理所有请求,并转发至对应的具体业务服务器(用户不可见)。这个过程是请求转发的过程,对用户来说是透明的。在URL上体现为代理服务器地址。
反向代理

1.2 正向代理

是通过一个正向代理服务器将请求转发到目标服务器,目标服务器记录的请求源是代理服务器,故服务端不会知道真正的客户端。URL上体现为目标服务器地址,用户对此是清楚的。有此需求的主要原因是客户端无法访问目标服务器,也就是常说的“翻墙”。

正向代理

1.3 反向代理VS端口转发

端口转发的本质在于将某端口监听收到的数据包原封不动地转发给指定服务器端口,例如ssh隧道转发。因此,服务器A的a端口只能绑定服务器的b端口,并不支持一个端口指向多个服务器。但反向代理的本质在于代理服务器进行请求分析并发起二次请求,故而可以实现多个服务器共享端口。

1.4 总结

反向代理隐藏真实服务端,常用于大型网站建设、校园网络对外接口等业务,如百度、浙大校园网RVPN等。

正向代理隐藏真实客户端,常用于VPN翻墙。

二、Nginx安装

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。

三、Nginx反向代理

VScode server的反向代理

VScode server是基于WebSocket。Nginx现在已经支持这一协议,用法参见文档

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。WebSocket协议和http协议、https协议一样,都属于应用层协议。传统的http/https协议想要实现内容的动态更新,必须实时地发送请求给服务器进行垂询,因为协议中规定了必须是“客户端请求-服务端响应”这种单向通信模式。WebSocket协议则允许建立TCP连接后进行双向通信,就行QQ那样可以聊天。当然,它们的基础都是TCP/IP协议以及其具体实现Socket通信(套接字)。

不过WebSocket协议的TLS握手还是借助http协议,因此会在http协议中加入切换协议的响应头与请求头来更替为webSocket,参见文档

Jupyter notebook的反向代理

由于Jupyter notebook中引入了大量的不含host信息的绝对路径重定向,以及body中含有的src路径均为绝对路径。因此是不适合用二级目录例如http://10.71.128.68/jupyter进行反向代理的,而适合直接进行端口转发。此外,notebook和vscode server一样也基于WebSocket,因为两者作为一个在线编辑工具,都需要主动向用户发送推送。

Location: /tree
src="/static/js/main.js"

或者利用location /进行反向代理URL通配,也就等效于端口转发。

location / {
    proxy_pass http://172.16.10.41:1997/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

反向代理中的重定向

nginx在使用非标准端口80/443时,不会自动将响应头的302重定向URL设定为正确的监听端口,从而导致重定向出错,如果需要进行纠正,可以进行如下配置

location / {
    proxy_pass https://git.zju.edu.cn;
    # 对返回的响应头的重定向信息设定端口
    proxy_redirect https://$host https://$host:$server_port;
    proxy_set_header Host $host:$server_port;
}

四、配置https安全证书

证书生成

# 创建证书目录
 mkdir /etc/nginx/ssl
# 生成RSA私钥
 openssl genrsa -des3 -out nginx_zhn.key 1024
# 创建csr证书
openssl req -new -key nginx_zhn.key -out nginx_zhn.csr
# 创建crt证书
openssl x509 -req -days 365 -in nginx_zhn.csr -signkey nginx_zhn.key -out nginx_zhn.crt

配置证书

nginx.conf中添加或修改配置

listen       443 ssl;

ssl_certificate      /etc/nginx/ssl/nginx_zhn.crt;
ssl_certificate_key  /etc/nginx/ssl/nginx_zhn.key;
ssl_session_cache    shared:SSL:1m;
ssl_session_timeout  5m;
ssl_ciphers  HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers  on;

nginx证书免密

openssl rsa -in server.key -out server.key.unsecure
将nginx配置的key替换为上述unsecure版。

五、Nginx反向代理详解

5.1 location

对于一个互联网的统一资源定位符(URL),主主要结构如下,其中SCHEME是所用协议(ftp/http/https等),DOMAIN表示域名(如www.baidu.com),PORT表示服务端网络端口,缺省值由协议类型决定(http: 80, https: 443),URI则表示所求资源对应的网站位置LOCATION和请求参数等,如/vscode/?folder=root表示请求vscode这个资源目录,请求附带get参数folder,值为root。当location结尾不是定界符“/”,如/index.html,代表请求资源是文件,否则是目录(起源于unix文件系统的设定)。一般而言,web服务器如tomcat会在文件不存在时进行重定向资源为目录,当两者都不存在时,会返回404。但作为规范,还是最好文件按文件url,目录按目录url。

URL = <SCHEME>://<IP|DOMAIN>:<PORT><URI>
URI = <LOCATION>?<PARAMETER>

因此,Nginx的location的匹配是针对资源位置LOCATION的匹配。

  • 精确匹配 location = /vscode 请求的location完全等于它,不能是子目录,当然更不会是父目录。
  • 一般匹配 location /vscode 允许请求的子目录被匹配
  • 正则匹配 location ~ ^/(validate|login)/? 按正则表达式语法进行的匹配,如示例匹配了/validate,/validate/,/login,/login/及子目录。
  • 忽略大小写正则匹配 将匹配符“”改为“*”。
  • 常规字符匹配 location ^~ /vscode/ /a 示例能匹配/vscode/%20/a,即不对URL编码。

六、Lua模块

lua模块安装参见前文。在nginx配置文件中,可以如下使用输出信息到网站。不同的指令下可以使用lua库api不完全一样。

  • content_by_lua用于嵌入lua脚本
  • lua_code_cache指令用于选择开启或关闭代码缓存,开发时建议关闭方便调试,生产环境建议开启而提高效率。
  • set_by_lua_file指令用于lua脚本创建nginx变量
  • content_by_lua_file指令用于加载lua脚本文件
location /lua {
    default_type 'text/html';
    content_by_lua 'ngx.say("Hello world! This is LuaJIT")';
}

location /redis {
    default_type 'text/html';
    lua_code_cache off;
    set $sessionid "";
    #content_by_lua_file /etc/nginx/conf.d/tools/dev/lua/redisGet.lua;
    set_by_lua_file $msg /etc/nginx/conf.d/tools/dev/lua/redisGet2.0.lua;
}

redisGet2.0.lua中利用管道获取redis的值,并将值return给$msg。因为set_by_lua_file中不支持一些API。下面例子中从nginx读取了sessionid变量,并用它作为redis的哈希field名,读取对应的value,并返回给msg。

local f = io.popen(string.format("redis-cli hget session %s", ngx.var.sessionid))
return tostring(f:read()) --值传给前面的$msg

access_by_lua、access_by_lua_block和access_by_lua_file用于获取并处理nginx数据,并可以修改nginx变量,但是nginx的if、rewrite指令会比这个模块先执行,故无法获取修改后的变量,而proxy_pass、echo指令可以获取修改后的变量。

resty.redis模块是lua的nginx插件库,需要放在安装在默认的库目录下。还可以通过配置LUA_PATH来指定lua库路径。

    export LUA_PATH="/usr/local/LuaJIT/lib/?.lua;/usr/local/LuaJIT/lib/5.1/?.lua;;"

多条路径用分号隔开,?代表该目录及子目录下的通配,如require('resty.redis')会在/usr/local/LuaJIT/lib/resty/redis.lua。两个连续分号代表追加默认路径在最后。

在nginx中,还可以通过lua_package_path指令来指定。

参考文献

[1] 知乎-反向代理为何叫反向代理

[2] oschina-nginx实现请求转发例子

[3] csdn-linux下nginx配置证书

[4] 使用nginx+lua脚本读写redis缓存(一)

[5] 在set_by_lua_file阶段操作redis

[6] 基于nginx + lua实现的反向代理动态更新

[7] nginx lua 中赋值变量返回

[8] nginx反向代理跳转带端口

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值