linux使用非root用户配置程序使用1024端口

一、声明

本文为学习笔记,转载请标明原文链接、作者、参考博文链接。


二、前言

在使用服务器运行程序时,为了保证安全性,要禁止使用root账户运行程序。

linux非root用户是禁止注册1024以下端口的。

当想使用普通用户注册1024以下端口的时候,比如http程序需要注册80端口,则可以进行一些配置来实现。

三、目前有两种方式:

  1. 设置suid
  2. setcap

1. 设置suid

1.1 suid简介

特殊权限-SUID,SGID,SBIT:

1.1.1 SUID:Set UID,只对二进制程序有效。

设置此权限的二进制程序,当有运行者对此程序有执行权限的时候,在运行程序的期间,会拥有此程序拥有者的权限。

示例:/usr/bin/passwd 拥有者权限为-rwsr-xr-x,拥有者为root。

现在有用户test对/usr/bin/passwd有执行权限,当test运行passwd的期间,则test此用户拥有/usr/bin/passwd程序拥有者root的权限。

1.1.2 SGID:SGID,针对文件和目录都有效。

针对文件:
对二进制程序有用。当有运行者对此程序有执行权限时,运行者在运行的过程中会拥有该程序群组的权限。

针对目录:
使用者在此目录下具有读写执行权限时,创建的文件或目录,所属群组为此目录的所属群组。

1.1.3 SBIT:Sticky Bit,只针对目录有限。

设置此权限后,使用者对此目录具有w,x的权限时,在此目录下创建的文件或者目录,只有创建者和root才可以删除。

示例:目前有目录test,权限为-rwxr-xr-t时。现在有A、B两个用户,A创建了A1文件,B创建了B1文件。则A1文件只能由A和root用户删除。B1文件只能有B和root用户删除。

2. 设置suid

以nginx程序为例

chmod u+x /usr/local/nginx/sbin/nginx

四、setcap

1. setcap简介

Capabilities是Linux内核2.2版本以后新增加的概念与机制。

Capabilities主要用来分割root用户的特权,将root用户的特权分割为不同的能力,每一种能力对应一项特权操作。

在Capilities中,只有进程和可执行文件才具有能力。

每个进程拥有三组能力集,分别称为cap_effective, cap_inheritable, cap_permitted(分别简记为:pE,pI,pP)。

  • cap_permitted表示进程所拥有的最大能力集;
  • cap_effective表示进程当前可用的能力集,可以看做是cap_permitted的一个子集;
  • cap_inheitable则表示进程可以传递给其子进程的能力集。

系统根据进程的cap_effective能力集进行访问控制,cap_effective为cap_permitted的子集,进程可以通过取消cap_effective中的某些能力来放弃进程的一些特权。

可执行文件也拥有三组能力集,对应于进程的三组能力集。分别称为cap_effective, cap_allowed 和 cap_forced(分别简记为fE,fI,fP)。

  • cap_allowed表示程序运行时可从原进程的cap_inheritable中集成的能力集
  • cap_forced表示运行文件时必须拥有才能完成其服务的能力集
  • cap_effective则表示文件开始运行时可以使用的能力。

2. Capabilities的29种能力:

  • capability 名称 描述
  • CAPAUDITCONTROL 启用和禁用内核审计;改变审计过滤规则;检索审计状态和过滤规则
  • CAPAUDITREAD 允许通过 multicast netlink 套接字读取审计日志
  • CAPAUDITWRITE 将记录写入内核审计日志
  • CAPBLOCKSUSPEND 使用可以阻止系统挂起的特性
  • CAP_CHOWN 修改文件所有者的权限
  • CAPDACOVERRIDE 忽略文件的 DAC 访问限制
  • CAP_FOWNER 忽略文件属主 ID 必须和进程用户 ID 相匹配的限制
  • CAP_FSETID 允许设置文件的 setuid 位
  • CAPIPCLOCK 允许锁定共享内存片段
  • CAPIPCOWNER 忽略 IPC 所有权检查
  • CAP_KILL 允许对不属于自己的进程发送信号
  • CAP_LEASE 允许修改文件锁的 FL_LEASE 标志
  • CAPLINUXIMMUTABLE 允许修改文件的 IMMUTABLE 和 APPEND 属性标志
  • CAPMACADMIN 允许 MAC 配置或状态更改
  • CAPMACOVERRIDE 忽略文件的 DAC 访问限制
  • CAP_MKNOD 允许使用 mknod() 系统调用
  • CAPNETADMIN 允许执行网络管理任务
  • CAPNETBIND_SERVICE 允许绑定到小于 1024 的端口
  • CAPNETBROADCAST 允许网络广播和多播访问
  • CAPNETRAW 允许使用原始套接字
  • CAP_SETGID 允许改变进程的 GID
  • CAP_SETFCAP 允许为文件设置任意的 capabilities
  • CAP_SETPCAP 参考 capabilities man page
  • CAP_SETUID 允许改变进程的 UID
  • CAPSYSADMIN 允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等
  • CAPSYSBOOT 允许重新启动系统
  • CAPSYSCHROOT 允许使用 chroot() 系统调用
  • CAPSYSMODULE 允许插入和删除内核模块
  • CAPSYSNICE 允许提升优先级及设置其他进程的优先级
  • CAPSYSPACCT 允许执行进程的 BSD 式审计
  • CAPSYSPTRACE 允许跟踪任何进程
  • CAPSYSRAWIO 允许直接访问 /devport、/dev/mem、/dev/kmem 及原始块设备
  • CAPSYSRESOURCE 忽略资源限制
  • CAPSYSTIME 允许改变系统时钟
  • CAPSYSTTY_CONFIG 允许配置 TTY 设备
  • CAP_SYSLOG 允许使用 syslog() 系统调用
  • CAPWAKEALARM 允许触发一些能唤醒系统的东西(比如 CLOCKBOOTTIMEALARM 计时器)

3. 使用setcap配置

以nginx程序为例,假设nginx路径为/usr/local/nginx/sbin/nginx。

setcap cap_net_bind_service=+eip /usr/local/nginx/sbin/nginx

五、java设置了Capabilities无法使用问题

为了安全需求,需要将应用程序的运行用户修改为非root用户时,非root用户启动程序使用1024以下的端口需要设置Capabilities。

给java赋值了Capabilities以后,使用普通用户运行java命令。出现如下报错java : error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory错误。

这是由于当一个可执行文件提升了权限后,运行时加载程序(rtld)— ld.so,它不会与不受信任路径中的库链接。Linux 会为使用了 setcap 或 suid 的程序禁用掉 LD_LIBRARY_PATH。所以就出现了 java 程序加载不到 libjli.so 的情况了,这是 JDK 的一个 bug。

1. 解决方式:

在/etc/ld.so.con.d下面创建java.conf文件,并将java的jli目录绝对路径写入里面。

echo '/usr/java/jdk1.8.0_261-amd64/lib/amd64/jli' > /etc/ld.so.conf.d/java.conf
cat /etc/ld.so.conf.d/java.conf

六、参考博客

setcap详解
Linux之特殊权限(SUID/SGID/SBIT)
java libjli.so_解决setcap导致Java加载libjli.so 失败问题
man.org-capabilities.7
Linux Capabilities 入门教程:概念篇

Previous Post

linux修改Inodes

Next Post

linux系统限速

Related Posts