创建的websocket服务,可以直接使用 http://192.168.11.199:21899/ 访问,如下
但现在不想对外暴露websocket的端口号,通过nginx反向代理:待访问的url为 http://192.168.11.199:81/?destip=192.168.11.199:21899 destip参数即为websocket服务的ip与port
location / {
#echo_before_body $remote_addr; # 192.168.11.201
#echo_before_body $args; # destip=192.168.11.199:21899
#echo_before_body $arg_destip; # 192.168.11.199:21311
proxy_pass http://$arg_destip/; # 带变量不可以
#proxy_pass http://192.168.11.199:21899/; # 网址固定可以
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
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;
}
客户端:
Webssh网页要打开需要如下请求:
当请求 1到达nginx层,$arg_destip会将这个请求代理到 http://192.168.11.199:21899/,请求ok。
当请求2、3、4、5到达nginx层,它会先在本地找有没有静态文件,没有才会去在代理的服务器上查找,我已经把代理服务器上的静态文件存放到本地,所以该请求ok;
但当请求6到达nginx层,请求中没有destip参数,根本就不会代理到 http://192.168.11.199:21899/,协议转换失败。
而当写成固定url是, proxy_pass http://192.168.11.199:21311/ ,请求 1、2、3、4、5、6都会代理到代理服务器上,请求ok。
根据章节1.2中的分析原因,我们只需要在访问请求2、3、4、5、6时,能够保证代理到 http://192.168.11.199:21899/,就可以。
那我们可以将接口 http://192.168.11.199:81/?destip=192.168.11.199:21899 中的destip值写入某个文件,等接口2、3、4、5、6请求时,读取这个文件下的destip值,用于反向代理,这样不就解决了嘛。
server {
listen 81;
server_name localhost;
location / {
add_header Cache-Control no-store; # 不使用缓存,解决多webssh容器页面访问交叉感染
set_by_lua_file $desturl '/etc/nginx/lua/dest_url.lua';
#echo_before_body $desturl;
proxy_pass http://$desturl; # 后面不加“/”,否则js文件无法代理下载成功
proxy_read_timeout 300s;
proxy_set_header Origin ''; # 解决访问/ws 接口403错误
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
ngx.log(ngx.NOTICE, "request uri:", ngx.var.request_uri) --日志
if ngx.re.match(ngx.var.request_uri, "^(.*)destip=(.*)$") then
local file, err = io.open ('/etc/nginx/lua/dest_url.txt',"w") --nginx使用root用户,否则无法创建
if file==nil then
ngx.log(ngx.ERR, "Couldn't open file:"..err)
else
local desturl = ngx.var.arg_destip
file:write(desturl)
file:close()
return desturl
end
else
local f1, errormsg = io.open("/etc/nginx/lua/dest_url.txt", "r")
if f1 == nil then
ngx.log(ngx.ERR, "error:"..errormsg)
else
local desturl = f1:read()
f1:close()
ngx.log(ngx.NOTICE, "desturl:"..desturl)
return desturl
end
end
成功将端口号写入到文件:
若想在nginx的日志文件中看到nginx日志,需要注意以下几点:
- access_log是无法更改日志级别的,指的是访问日志,用于记录客户端的请求(包含请求 IP、时间、访问 url等等),不会保存lua里的日志;
- error_log并不是仅仅记录错误日志,它的level 可以是:debug、info、notice、warn、error、crit、alert、emerg 中的任意值,可以记录所有的日志记录。
- 这里,为了使errer.log里不包括access.log的日志,设置成notice级别(error_log /var/log/nginx/error.log notice;),同时Lua脚本中使用如下方式记录日志(ngx.log(ngx.NOTICE, "request uri:", ngx.var.request_uri) --日志)