最近使用 openresty + 制做网站 lua-resty-template 做了个网站, 这个框架的优点就是一个字"快", 但部署到linux服务器上时却遇到了用户权限的问题,在这记录下解决的方法.
痛点:
1.nginx 用户分两个 "启动用户" 和 "工作用户" , 如果以root启用,并且不指定工作用户的话,那么默认使用一个叫 "nobody" 的用户,这个用户的权限比较低,对一些文件是没有访问权限的.
2.如果建立一个用户并同时设置为"工作用户"和"启动用户" 那么将会将整个网站中所有的文件暴露出去,包括项目中的各种敏感配置文件,比如所连接的数据数密码.另外以普通用户启动nginx的话是无法设置"工作用户"的.会收到提示:
the "user" directive makes sense only if the master process runs with super-user privileges, ignored in ...
意思就是以普通用户启动的nginx,再设置工作用户是没有意义的.
那我怎么才能即让用户访问到特点的资源,而又不把整个网站都暴露出去呢!
解决方法:
总体来说就是使用 openresty 的 init_by_lua_file 加 ngx.shared.configCache
原理 :
init_by_lua_file 是在 nginx 的 master process 上 worker process 之前运行的, 所以说它是以 "启动用户"来运行的, 那么在init_by_lua_file阶段把配置读到ngx.shared.configCache中去,然后再在各worker process中取得就好了.
示例:
把项目的 conf 目录和资源目录分配给不同的用户, 如 把conf 目录分给用户 "root" , 把资源目录分给用户 "www"
nginx.conf
user www www;
worker_processes 2;
events {
worker_connections 1024;
}
http {
... 省略其它配置
lua_package_path '/home/www/website/app_name/lua/?.lua;;';
init_by_lua_file "/opt/app_name/lua/init.lua";
server {
set $site_root "/home/www/website/app_name";
set $template_root "$site_root/html";
... 省略其它配置
location / {
content_by_lua_file $site_root/lua/dispatch/mvc.lua;
header_filter_by_lua_block {
ngx.header["Content-Type"] = 'text/html;charset=UTF-8'
}
}
# 你的资源
location ~ ^/img/* {
root $site_root/html;
expires 365d;
}
}
}
把你的敏感信息写写一个properties文件放入nginx.conf同目录
resources.properties
{
"debug.mode" : "false",
"db_password" : "XXXX"
}
写一个装载配置的 lua
init.lua
local cjson = require "cjson";
local configCache = ngx.shared.configCache;
if configCache:get('isload') then
return
end
local resourcesFile = io.open("/opt/app_name/conf/resources.properties", "r");
local resourcesStr = resourcesFile:read("*a");
resourcesFile:close();
configCache:set('isload', 1)
使用配置
local configCache = ngx.shared.configCache
local pwd = configCache:get("password")
最后使用root启动nginx
nginx -p /opt/app_name
当然也可以做成一个service
/etc/systemd/system/app_name.service
[Unit]
Description=The nginx HTTP and reverse proxy servers
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/opt/app_name/logs/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /opt/app_name/logs/nginx.pid
ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -t -p /opt/app_name
ExecStart=/usr/local/openresty/nginx/sbin/nginx -p /opt/app_name
ExecStop=/usr/local/openresty/nginx/sbin/nginx -p /opt/app_name -s stop
ExecReload=/usr/local/openresty/nginx/sbin/nginx -p /opt/app_name -s reload
KillMode=process
KillSignal=SIGQUIT
TimeoutStopSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target