Is there a way for non-root processes to bind to “privileged” ports on Linux?

后端 未结 24 1289
予麋鹿
予麋鹿 2020-11-22 02:04

It\'s very annoying to have this limitation on my development box, when there won\'t ever be any users other than me.

I\'m aware of the standard workarounds, but non

相关标签:
24条回答
  • 2020-11-22 02:52

    There is also the 'djb way'. You can use this method to start your process as root running on any port under tcpserver, then it will hand control of the process to the user you specify immediately after the process starts.

    #!/bin/sh
    
    UID=$(id -u username)
    GID=$(id -g username)
    exec tcpserver -u "${UID}" -g "${GID}" -RHl0 0 port /path/to/binary &
    

    For more info, see: http://thedjbway.b0llix.net/daemontools/uidgid.html

    0 讨论(0)
  • 2020-11-22 02:53

    Or patch your kernel and remove the check.

    (Option of last resort, not recommended).

    In net/ipv4/af_inet.c, remove the two lines that read

          if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
                  goto out;
    

    and the kernel won't check privileged ports anymore.

    0 讨论(0)
  • 2020-11-22 02:53

    Linux supports capabilities to support more fine-grained permissions than just "this application is run as root". One of those capabilities is CAP_NET_BIND_SERVICE which is about binding to a privileged port (<1024).

    Unfortunately I don't know how to exploit that to run an application as non-root while still giving it CAP_NET_BIND_SERVICE (probably using setcap, but there's bound to be an existing solution for this).

    0 讨论(0)
  • 2020-11-22 02:55

    My "standard workaround" uses socat as the user-space redirector:

    socat tcp6-listen:80,fork tcp6:8080
    

    Beware that this won't scale, forking is expensive but it's the way socat works.

    0 讨论(0)
  • 2020-11-22 02:55

    With systemd, you just need to slightly modify your service to accept preactivated sockets.

    You can later use systemd socket activate.

    No capabilities, iptables or other tricks are needed.

    This is content of relevant systemd files from this example of simple python http server

    File httpd-true.service

    [Unit]
    Description=Httpd true 
    
    [Service]
    ExecStart=/usr/local/bin/httpd-true
    User=subsonic
    
    PrivateTmp=yes
    

    File httpd-true.socket

    [Unit]
    Description=HTTPD true
    
    [Socket]
    ListenStream=80
    
    [Install]
    WantedBy=default.target
    
    0 讨论(0)
  • 2020-11-22 02:59

    The standard way is to make them "setuid" so that they start up as root, and then they throw away that root privilege as soon as they've bound to the port but before they start accepting connections to it. You can see good examples of that in the source code for Apache and INN. I'm told that Lighttpd is another good example.

    Another example is Postfix, which uses multiple daemons that communicate through pipes, and only one or two of them (which do very little except accept or emit bytes) run as root and the rest run at a lower privilege.

    0 讨论(0)
提交回复
热议问题