非root用户监听特权端口方案

背景

特权端口是指1~1023之间的端口,这些区间范围端口通常需要管理员权限才能监听。非管理员权限只能监控特权端口(1024以上的端口)。通常这些是运维岗的常识。

那么,如果我非要使用普通用户监听1024以下的端口,有没有什么奇技淫巧能实现?

那当然。管上。

方案实现

方案1: 使用内核参数

举例:用一个普通用户监控80端口

  1. 使用root添加内核参数,值是我们需要使用普通用户所监听的端口
# sysctl -w net.ipv4.ip_unprivileged_port_start=80

2. 切换到普通用户并开启监听端口

# su - zhang3
[zhang3@c1 ~]$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

方案2:使用setcap命令添加权限

为程序赋予 CAP_NET_BIND_SERVICE 权限,即使服务程序运行在非root帐户下,也能够 binding 到低位端口。以Nginx为例:

# setcap 'cap_net_bind_service=+eip' /usr/sbin/nginx

此时就可以使用普通用户来运行nginx,即使是监控1024以下的端口。

假如哪一天我想将这权限进行回收,使用以下命令来实现:

# setcap -r /usr/sbin/nginx

方案3: 使用 authbind工具

  1. 为Linux系统安装 authbind
  • RHEL/CentOS
# wget https://s3.amazonaws.com/aaronsilber/public/authbind-2.1.1-0.1.x86_64.rpm
# rpm -vih uthbind-2.1.1-0.1.x86_64.rpm
Verifying...                          ################################# [100%]
准备中...                          ################################# [100%]
正在升级/安装...
   1:authbind-2.1.1-0.1               ################################# [100%]
  • Debian/Ubuntu
# apt install authbind

2. 分配特定端口

# touch /etc/authbind/byport/80
# chown zhang3 /etc/authbind/byport/80
# chmod 500 /etc/authbind/byport/80

3. 启动端口

# su - zhang3
$ authbind --deep python3 -m http.server 80
$ ps -ef |grep python3
zhang3    114803  114741  2 23:47 pts/1    00:00:00 python3 -m http.server 80

那我如果监听一个没有指定的端口呢?

$ authbind --deep python3 -m http.server 88
Traceback (most recent call last):
  File "/usr/lib64/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib64/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/lib64/python3.6/http/server.py", line 1211, in <module>
    test(HandlerClass=handler_class, port=args.port, bind=args.bind)
  File "/usr/lib64/python3.6/http/server.py", line 1185, in test
    with ServerClass(server_address, HandlerClass) as httpd:
  File "/usr/lib64/python3.6/socketserver.py", line 456, in __init__
    self.server_bind()
  File "/usr/lib64/python3.6/http/server.py", line 136, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/usr/lib64/python3.6/socketserver.py", line 470, in server_bind
    self.socket.bind(self.server_address)
PermissionError: [Errno 1] Operation not permitted
果然不得行!

方案4: 防火墙NAT表PREROUTING跳转

<略>