众所周知,在 Linux
系统下,只允许 Root
用户运行的程序才可以使用特权端口 ( 1024
以下的端口 )。如果在普通用户下使用特权端口将会报错。
在一些特定的环境下,我们可能考虑到程序运行在 Root
帐户下,可能会给 Linux
系统带来安全风险。希望能让普通用户启动的程序运行在特权端口上,比如:Web 服务器。
那如何能够让普通用户启动的程序运行在特权端口呢?本文将介绍一些方法,让你能够解决这个问题。
通过设置 CAP_NET_BIND_SERVICE 实现
Linux
内核从 2.6.24 版本开始就有了能力的概念,这使得普通用户也能够做只有超级用户才能完成的工作。
使用 setcap
命令让指定程序拥有绑定端口的能力,这样即使程序运行在普通用户下,也能够绑定到 1024 以下的特权端口上。
1 | # 给指定程序设置 CAP_NET_BIND_SERVICE 能力 |
下面我们来看一个实例,以 Nginx
为例:
如果你的程序不再需要使用这个能力,你可以使用以下命令来清除。
1 | $ setcap -r /path/to/application |
这个方法并不是所有
Linux
系统通用,Linux
内核在 2.6.24 之前的并没有提供此项能力,因此你需要检查要使用此方法所在系统是否支持。另外需要注意的是,如果要运行的程序是一个脚本,这个方法是没有办法正常工作的。
通过端口转发实现
如果要运行的程序有权限监听其他端口,那么这个方法是可以使用的。首先让程序运行在普通用户下,并绑定高于 1024 的端口。在确保能正常工作的时候,我们将通过端口转发将低端口的请求转到应用所在的高端口,从而实现普通用户启动的程序绑定到低端口。要使用此方法可以使用下面的方式。
- 配置内核参数以启用转发功能
1 | # Enable the IP FORWARD kernel parameter. |
以上方法是临时性设置,重启之后将会被重置。如果你想长期保存,需要在 /etc/sysctl.conf
文件内修改:
1 | $ vim /etc/sysctl.conf |
然后,使用 sysctl
命令从文件中加载新的配置,并使其生效。
1 | # load new sysctl.conf |
- 配置转发规则
这里我们使用 Iptables
来配置的转发规则,以实现端口转发到程序所在的端口。
1 | # 将 80 端口转发到 8088 |
此种方法能够比较好的达到我们的目的,我们的程序可以通过普通用户来运行,并能够对外提供低端口号的服务。
通过 authbind 实现
authbind
是一个支持普通用户就能绑定系统特权端口的程序,你只需要使用 authbind
程序来调用需要使用特权端口的程序就可以了。
- 安装 authbind
- Debian / Ubuntu
1 | $ sudo apt-get install authbind |
- CentOS / RHEL
CentOS 系列的系统安装起来相对就要麻烦一些,因为官方仓库并没有提供编译好的软件包。不过幸运的是,已经有人编译好了对应的软件包,我们只需要直接安装就可以了。
1 | $ sudo rpm -ivh https://s3.amazonaws.com/aaronsilber/public/authbind-2.1.1-0.1.x86_64.rpm |
- 配置 authbind
authbind
默认的配置文件在 /etc/authbind
目录下,里面有三个目录:byport
、byaddr
、byuid
。
假如我们有一个 test 的普通账号,想运行一个程序并绑定在 80 端口上。我们需要配置以下内容:
1 | # 在 byport 目录下建立 80 文件 |
- 使用 authbind 运行指定程序
在你要启动的命令前加上 authbind --deep
命令即可。例如:要用 test 这个普通用户启动 Nginx
并绑定在 80 端口,只需执行以下命令即可:
1 | $ authbind --deep "/usr/bin/nginx" -c "/etc/nginx/nginx.conf" |
我们也可以直接在 IP 地址上直接绑定端口,只需在 byaddr
目录下建立 ip:port
文件就可以了。
通过 SetUID 实现
SetUID
这一特性可以让只有普通用户权限的应用程序用 Root 权限来运行,我们可以看到系统下 /usr/bin/passwd
这个文件,就使用了 SetUID
。这样就使得系统的每个普通用户都能用 passwd
来修改密码,因为修改密码需要更改 /etc/passwd
文件,而默认这个文件只有 Root 用户才有权限访问。
1 | # 将程序的所有者更改为 root |
既然要使用普通用户运行程序,目的就是要降低程序本身给系统带来的安全风险。因此,本方法使用的时候需要特别谨慎,特别是当要执行的程序本身存在安全风险。
参考文档
- https://www.cnblogs.com/chenjunjie12321/p/9226279.html
- https://blog.csdn.net/Becivells/article/details/52842019
- https://my.oschina.net/guol/blog/186430
- https://github.com/tootedom/authbind-centos-rpm
- https://dzone.com/articles/running-tomcat-port-80-user
- http://blog.useasp.net/archive/2015/07/09/non-root-user-application-bind-to-ports-less-than-1024-without-root-access.aspx
- https://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged-ports-on-linux
- https://aaronsilber.me/2016/04/24/install-authbind-on-centos-7-x86_64-download-the-rpm/
- https://blog.webhosting.net/how-to-get-tomcat-running-on-centos-7-2-using-privileged-ports-1024/