为什么nginx用户使用的nginx不能监听80端口?

前段时间在面试的时候,本来面的一切顺利,但是在聊到nginx的时候,面试官突然提问到:"你平时nginx都是用什么用户启动的?",我一愣,猜想肯定有坑,但也只能见招拆招了,"nginx用户",果不其然,面试官立马接下一招:"那你用nginx用户启动nginx,这时候nginx还能监听80端口嘛?"我一愣,就这?按照平时使用nginx的经验,我回答到:"能"。但是面试官一叹气:"再回去多看看吧"。我脑海中模糊的闪过一些系统端口和系统用户的知识,但为时已晚,一结束面试,马上开始查漏补缺。

为什么我会有nginx用户能用80端口的印象?

一下面试,我赶紧打开了虚拟机,一查nginx配置文件:user nginx,没错,配置的是nginx用户,ps -ef|grep nginx一下,认真查看之下,我发现了为什么我会觉得nginx用户能监听80端口了。

bash 复制代码
[root@192 ~]# ps -ef|grep nginx
root       58200       1  0 11月03 ?      00:00:00 nginx: master process /usr/sbin/nginx
nginx      58201   58200  0 11月03 ?      00:00:01 nginx: worker process
nginx      58202   58200  0 11月03 ?      00:00:00 nginx: worker process

nginx的worker进程是用来处理实际的网络请求的,但是配置文件是由master进程读取再来创建worker进程,也就是说我们在配置文件中配置的user nginx实际上是为worker进程设置的 。master进程所属者为执行nginx命令的用户,实际上的端口绑定也是由master进程负责的,但是平时在nginx配置文件设置完后一般喜欢直接用root用户启动nginx,所以平时的把nginx的用户设置为nginx,nginx也能监听80端口的错误印象就是从这里来的。

bash 复制代码
[nginx@192 sbin]$ ./nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

事实也确实是这样,用普通用户去执行nginx,就会报权限被拒绝的错误。

为什么80端口不给普通用户监听?

了解了现象之后,就得去了解原理了,为什么在Linux中,nginx用户不能去使用80端口呢?那这就得去了解一下系统用户和系统端口的知识了

用户

Linux中系统分为三种:

  • 超级用户:root,具有一切特权,UID为0
  • 系统用户:系统正常工作所必须的内建用户,为了满足相应的系统进程而建立,不能用来登录,如bin、daemon、adm、lp等,UID一般为1-499
  • 普通用户:为了让使用者能够使用系统资源而建立的,UID为500-60000

1-499的uid是系统自留的,所以当我们创建用户时,如果不使用-u参数指定uid,那么uid是一定大于等于500的

端口

端口的范围:端口号的范围是从0到65535。这些端口号,根据用途可分为三个类别(范围):

  • 系统端口(0 - 1023):这些端口是众所周知的端口,由IANA(互联网数字分配机构,Internet Assigned Numbers Authority)分配给特定服务。
  • 注册端口(1023 - 49151):这些端口被称为用户端口,可用于注册IANA。注册是为了避免端口冲突。
  • 动态端口(49152-65535):动态端口可以分配给服务一段时间,主要由客户端程序使用

系统端口可不是给系统用户用的,事实上系统端口只有超级用户能使用,其他用户边都别来挨。

bash 复制代码
[root@192 App]# useradd test -u100 
[root@192 App]# id test
uid=100(test) gid=1002(test) 组=1002(test)
[root@192 App]# su test
[test@192 App]$ cd nginx-1.24.0/
[test@192 nginx-1.24.0]$ sbin/nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

经过测试得知,系统端口只能由超级管理员使用,其他用户就别想用了。

普通用户使用系统端口的方法

一个用户占用这么多端口,其他用户肯定嫉妒的眼红,那有没有什么办法让普通用户也能用上系统端口呢?肯定是有的,而且不只一种。

1.useradd

bash 复制代码
[root@192 App]# useradd t -u0 -o # 把用户id指定位0
[root@192 App]# id t
uid=0(root) gid=0(root) 组=0(root)
[root@192 App]# nginx-1.24.0/sbin/nginx # 忽悠成功

事实上,我们在创建用户的时候,可以用-u参数指定uid,然后使用-o参数指定用户可以使用已被使用的uid,这样就能成功骗过系统,让系统认为这个用户也是超级管理员(虽然就是)。因为Linux系统中判断用户是根据用户uid来判断的,所以Linux中名字不重要,uid才重要。

2.使用s权限

在Linux中,除了rwx权限之外,还有一种特殊权限s,这种权限只对二进制可执行文件有效,如/usr/bin/passwd就加上了suid权限,当一个普通用户在执行这个命令的时候,其实是root用户在执行命令

bash 复制代码
[root@localhost sbin]# file /usr/bin/passwd
/usr/bin/passwd: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=87e17c1d9b2e20d7e8aeab9115074375eec5e8e1, stripped
[root@localhost sbin]# ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 33600 4月   7 2020 /usr/bin/passwd

只有在这里有ELF的才是二进制文件,suid权限对其他文件没有效果

3.setcap

setcap命令是Linux命令,用来设置文件的能力(capabilities)。在Linux系统中,能力是一种比权限模型更细粒度的权限控制机制。通过将root用户的特权分割成不同的能力,每种能力代表一定的特权操作。如:CAP_SYS_MODULE表示能加载内核模块的特权,CAP_SETUID表示用户能够修改用户身份。

  • setcap命令格式
bash 复制代码
setcap [-q] [-n <rootuid>] [-v] { capabilities|-|-r} filename
# capabilities:设置的能力
# 可以使用man setcap来查看更多信息
bash 复制代码
[root@localhost sbin]# setcap 'CAP_NET_BIND_SERVICE=+ep' nginx
[root@localhost sbin]# getcap nginx
nginx = cap_net_bind_service+ep
# 使用getcap查看能力

4.sudo

在Linux中,任何用户都能提权为root,可以使用visudo进行设置,也可以直接对/etc/sudoers文件进行修改

bash 复制代码
# root表示用户名
# 第一个ALL表示适用的主机
# 第二个ALL为提权为什么用户
# 第三个ALL为可以执行什么命令
root    ALL=(ALL)       NOPASSWD: ALL

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL
相关推荐
川石课堂软件测试几秒前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
pk_xz1234562 小时前
Shell 脚本中变量和字符串的入门介绍
linux·运维·服务器
小珑也要变强2 小时前
Linux之sed命令详解
linux·运维·服务器
Lary_Rock4 小时前
RK3576 LINUX RKNN SDK 测试
linux·运维·服务器
云飞云共享云桌面6 小时前
8位机械工程师如何共享一台图形工作站算力?
linux·服务器·网络
Peter_chq6 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
一坨阿亮7 小时前
Linux 使用中的问题
linux·运维
dsywws8 小时前
Linux学习笔记之vim入门
linux·笔记·学习
幺零九零零9 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
wclass-zhengge9 小时前
Docker篇(Docker Compose)
运维·docker·容器