Permission denied error when binding a port

Posted in :

80,443 預設會被系統鎖住, 一般程式無法bind,

How to make Tomcat run on 443 instead of its default port 8080?

比簡單的解法:

You need to use the OUTPUT chain as the packets meant for the loopback interface do not pass via the PREROUTING chain. The following should work; run as root:

iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A OUTPUT -o lo -p tcp --dport 443 -j REDIRECT --to-port 8443

Cause

Ports below 1024 are called Privileged Ports and in Linux (and most UNIX flavors and UNIX-like systems), they are not allowed to be opened by any non-root user. This is a security feature originally implemented as a way to prevent a malicious user from setting up a malicious service on a well-known service port.

Resolution

There are a few different solutions to work around this:

  1. Install and configure Apache or nginx as a reverse proxy server, which can be started as root to open the port, and then downgrade its privileges back to a normal user.
  2. Set up a firewall on the server using iptables or an alternative, so that the lower port number is forwarded internally to a higher port number listened by Confluence.
  3. Use jsvc, which is able to open ports as root, and then downgrade privileges.
  4. Use authbind to grant privileges for a non-root user to open a privileged port.
  5. If using Linux 2.6.24 or later, you can set up a file capability on the java executable, to give elevated privileges to allow opening privileged ports only, and no other superuser privileges:
    # setcap cap_net_bind_service+ep /path/to/bin/javaAfter setting this you may notice errors when starting Java like this, for example:
    $ java -version /path/to/bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directoryThis means that the library is being imported from a dynamic path, and not in the trusted ld.so path. See http://bugs.sun.com/view_bug.do?bug_id=7157699 for details. To fix this, you need to locate the library, and add its path to the ld.so configuration. Note that the below is an example, and this may differ depending on Linux distribution. Replace JAVA_HOME with the correct location:
    $ find JAVA_HOME -name 'libjli.so' JAVA_HOME/lib/amd64/jli/libjli.so   # echo "JAVA_HOME/lib/amd64/jli" > /etc/ld.so.conf.d/java-libjli.conf # ldconfig -vAfter setting this all up, you need to make sure that Confluence only starts java with the direct binary path, and not via a symbolic link, otherwise the capability will not be picked up.
    Setting this up means that any user can open privileged ports using Java, which may or may not be acceptable for you

Whilst it may get things working, it is not recommended to run Confluence as root. If there is ever any security vulnerability where an attacker may execute arbitrary code as the running user, then they will gain root access.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *