I have Googled about a solution for quite some time, but couldn't find an answer.
I am on Ubuntu Linux and want to run a server on port 80, but due to security mechanism of Ubuntu, I get the following error:
java.net.BindException: Permission denied:80
I think it should be simple enough to either disable this security mechanism so that port 80 is available to all users or to assign required privileges to the current user to access port 80.
Short answer: you can't. Ports below 1024 can be opened only by root. As per comment - well, you can, using CAP_NET_BIND_SERVICE, but that approach, applied to java bin will make any java program to be run with this setting, which is undesirable, if not a security risk.
The long answer: you can redirect connections on port 80 to some other port you can open as normal user.
Run as root:
As loopback devices (like localhost) do not use the prerouting rules, if you need to use localhost, etc., add this rule as well (thanks @Francesco):
NOTE: The above solution is not well suited for multi-user systems, as any user can open port 8080 (or any other high port you decide to use), thus intercepting the traffic. (Credits to CesarB).
EDIT: as per comment question - to delete the above rule:
This will output something like:
The rule you are interested in is nr. 2, so to delete it:
Use authbind.
It even works with Java if you enable Java's IPv4-only stack. I use:
If your system supports it you could maybe use capabilities. See man capabilities, the one you need would be CAP_NET_BIND_SERVICE.
On newer Debian/Ubuntu you can run:
I simply use Nginx in front. It can run on localhost too.
apt-get install nginx
.. or ..
pkg_add -r nginx
.. or what ever suits your OS.
All you need in nginx.conf, if running on localhost, is:
Another solution is to make your app setuid so that it can bind with port 80. As root, do the following
Keep in mind that doing this, unless it's done absolutely right, will expose you to potential security holes, because your app will be talking to the network, and will be running with full root priviledges. If you take this solution, you should look at the source code for Apache or Lighttpd or something similar, where they use the root privileges to open up the port, but then immediately give up those privs and "become" a lower privileged user so that a hijacker can't take over your whole computer.
Update: As seen in this question, it appears that Linux kernels since 2.6.24 have a new capability that allow you to mark an executable (but not a script, of course) as having the "
CAP_NET_BIND_SERVICE
" capability. If you install the debian package "libcap2-bin", you can do that by issuing the commandApproach proposed by Sunny and CesarB:
works fine but it has a small drawback -- it does not prevent user from connecting directly to port 8080 instead of 80.
Consider the following scenario when this can be a problem.
Let's say we have a server which accepts HTTP connections on port 8080 and HTTPS connections on port 8181.
We use iptables to establish the following redirections:
Now, let's suppose our server decides to redirect user from a HTTP page to a HTTPS page. Unless we carefully rewrite the response, it would redirect to
https://host:8181/
. At this point, we are screwed:https://host:8181/
URL and we would need to maintain this URL to avoid breaking their bookmarks.I use the following approach:
Combined with default REJECT rule on the INPUT chain this approach prevents users from connecting directly to ports 8080, 8181
Traditionally on Unix, only root can bind to low ports (<1024).
The simplest way to work around this is to run your server on a high port (for instance, 8080) and use a simple iptables rule to forward the connections from port 80 to port 8080. Note that with this you lose the extra protection from the low ports; any user on your machine can bind to port 8080.
If your system supports it you could maybe use capabilities. See
man capabilities
, the one you need would beCAP_NET_BIND_SERVICE
. No, I`ve never used them myself and I don't know if they really work :-)Use a reverse proxy (nginx, apache+mod_proxy) or a caching reverse proxy (Squid, Varnish) in front of your application servers!
With a reverse proxy you can achieve a lot of interesting things like:
You can use redir program: