在《运维排查篇 | 访问nginx出现403错误》中,我列举了四个相关的排障思路以及解决方法(没看过的朋友可以点击链接看一下)
在发布了文章之后,我一直觉得第三个排障思路,也就是在解决nginx工作用户和启动用户不一致的问题上始终没有找到更好的方法
一般来讲,nginx的 master 进程由 root 用户开启,负责管理 worker 进程,而 worker 进程见名知意,就是用来干活工作的,一般由 nginx 用户负责。
[root@salted ~]# ps -aux | grep nginx
root 12340.00.21067845168 ? Ss Jun17 0:00 nginx: master process nginx
nginx 34910.00.21067884212 ? S 15:19 0:00 nginx: worker process
nginx 34920.00.21067884212 ? S 15:19 0:00 nginx: worker process
而这个工作用户是可以定义的,在 nginx 的配置文件里面修改
nginx配置文件:/usr/local/nginx/conf/nginx.conf
在我最初的文章中,我提供的解决办法是将 nginx 的工作用户修改为 root,跟启动用户一致,这样就能解决权限问题,但是这样会产生安全隐患
一旦黑客入侵了80端口,那么他就拥有了 root 权限,所以不建议修改工作用户为root
那么有没有更好的办法呢?在工作用户不是 root 用户的前提下还能使得 nginx 用户可以启动 master 进程
这天早上,我在上班路上看着这本书,突然看到书上有个案例吸引了我,我大致讲一下
错误现象:客户的一台web服务器是基于Apache+JK+Tomcat构建的一个电商平台,客户反映Apache无法启动,但是Tomcat可以启动。并且发现是权限问题导致
作者经过排查后,发现Apache的启动用户是www,监听端口为80,并查到/usr/local/apache2目录所有文件和目录权限都是www,不是读写权限的问题。
最后定位到是Apache的工作用户是www,无法使用80端口,linux做了一些安全限制,使得普通用户无法绑定这类端口
根据定位到的问题,这里有两个解决方法
- 将Apache以 root 用户运行,简单粗暴
- 修改Apache目录下httpd文件的SUID属性
看到这里,我突然想到跟我之前写过的一篇案例中出现的问题有异曲同工之妙,于是有了今天这篇2.0版本
解决方法2.0
上文我说过:有没有更好的解决方法,使得工作用户为 nginx 的前提下还能正常启动 master 进程
除了我一开始写的修改工作用户为 root 之外,现在有更好的方法,那就是:
修改nginx目录下启动文件的SUID属性
我们先来看下如何操作
首先将nginx启动程序赋予s权限
chmod u+s /usr/local/nginx/sbin/nginx
接着将该文件的所有者改为 root
chown root /usr/local/nginx/sbin/nginx
这样就成功解决啦!
看到这里,可能有些小伙伴已经一脸懵逼了,这个SUID属性是啥,s权限又是啥
接下来我们简单介绍下linux系统中的特殊权限
Linux系统中的文件的s权限
我们在linux系统中最常见的文件权限分别是:r、w、x,分别对应着读、写、执行权限,这三个权限相信大家都懂了,这里就不过多介绍。
除此之外,linux还支持另外一系列的权限设置,就比如上文所介绍到的 s 权限
s,表示set UID或set GID。位于user或group权限组的第三位置。
如果在user权限组中设置了s位,则当文件被执行时,该文件是以文件所有者UID而不是用户UID 执行程序。
如果在group权限组中设置了s位,当文件被执行时,该文件是以文件所有者GID而不是用户GID执行程序
需要注意的是,在给文件设置 s 权限的时候,该文件必须已经具备了可执行权限(x),这样 s 权限的设置才有效,并且检查文件权限的时候会出现”s“字样
只给文件赋予s权限,系统是不会自动让该文件具备可执行权限的且检查文件权限的时候会出现”S“字样
回到上面的案例,我们在给nginx启动程序赋予 s 权限并且将启动程序的所有者修改为 root 之后,当 nginx 用户去启动 nginx 的时候,它会去临时获得 root 用户(该文件所有者)的权限去启动 nginx 进程
这样就可以解决启动用户跟工作用户不一致而导致权限问题啦