SnapOverflow

SnapOverflow Logo SnapOverflow Logo

SnapOverflow Navigation

  • Home
  • Server
  • Ubuntu

Mobile menu

Close
  • Home
  • System Administrators
    • Hot Questions
    • New Questions
    • Tags
  • Ubuntu
    • Hot Questions
    • New Questions
    • Tags
  • Help
Home / server / Questions / 112795
In Process
Deepak Mittal
Deepak Mittal
Asked: 2008-11-11 06:31:11 +0800 CST2008-11-11 06:31:11 +0800 CST 2008-11-11 06:31:11 +0800 CST

How to run a server on port 80 as a normal user on Linux?

  • 772

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.

linux
  • 20 20 Answers
  • 407974 Views

20 Answers

  • Voted
  1. Sunny
    2008-11-11T06:41:10+08:002008-11-11T06:41:10+08:00

    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:

    # iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
    

    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):

    # iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
    

    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:

    # iptables -t nat --line-numbers -n -L
    

    This will output something like:

    Chain PREROUTING (policy ACCEPT)
    num  target     prot opt source               destination         
    1    REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8080 redir ports 8088
    2    REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 redir ports 8080
    

    The rule you are interested in is nr. 2, so to delete it:

    # iptables -t nat -D PREROUTING 2
    
    • 416
  2. geocar
    2008-11-15T05:12:48+08:002008-11-15T05:12:48+08:00

    Use authbind.

    It even works with Java if you enable Java's IPv4-only stack. I use:

    authbind --deep $JAVA_HOME/bin/java -Djava.net.preferIPv4Stack=true …
    
    • 87
  3. Otto Kekäläinen
    2012-05-31T12:32:19+08:002012-05-31T12:32:19+08:00

    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:

    sudo apt-get install libcap2-bin 
    sudo setcap 'cap_net_bind_service=+ep' /path/to/program
    
    • 85
  4. CosmicB
    2012-11-21T06:30:07+08:002012-11-21T06:30:07+08:00

    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:

    server {
            listen  80;
            server_name some.domain.org;
            location / {
                proxy_set_header    Host $host;
                proxy_set_header    X-Real-IP   $remote_addr;
                proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass  http://127.0.0.1:8081;
            }
    }
    
    • 50
  5. Paul Tomblin
    2008-11-11T06:44:10+08:002008-11-11T06:44:10+08:00

    Another solution is to make your app setuid so that it can bind with port 80. As root, do the following

    chown root ./myapp
    chmod +S ./myapp
    

    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 command

    setcap 'cap_net_bind_service=+ep' /path/to/program
    
    • 47
  6. Misha
    2010-02-21T08:19:54+08:002010-02-21T08:19:54+08:00

    Approach proposed by Sunny and CesarB:

    iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
    

    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:

    80  ---> 8080
    443 ---> 8181
    

    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:

    • Some users would bookmark the https://host:8181/ URL and we would need to maintain this URL to avoid breaking their bookmarks.
    • Other users would not be able to connect because their proxy servers do not support non-standard SSL ports.

    I use the following approach:

    iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1
    iptables -t mangle -A PREROUTING -p tcp --dport 443 -j MARK --set-mark 1
    iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
    iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8181
    iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -m mark --mark 1 -j ACCEPT
    iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8181 -m mark --mark 1 -j ACCEPT
    

    Combined with default REJECT rule on the INPUT chain this approach prevents users from connecting directly to ports 8080, 8181

    • 38
  7. CesarB
    2008-11-11T06:36:44+08:002008-11-11T06:36:44+08:00

    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.

    • 33
  8. WMR
    2008-11-11T08:27:54+08:002008-11-11T08:27:54+08:00

    If your system supports it you could maybe use capabilities. See man capabilities, the one you need would be CAP_NET_BIND_SERVICE. No, I`ve never used them myself and I don't know if they really work :-)

    • 23
  9. Giovanni Toraldo
    2011-10-19T07:36:38+08:002011-10-19T07:36:38+08:00

    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:

    • Load-balancing
    • Restarting your application servers with users receiving a fancy error page
    • Speed up things with cache
    • Fine-grained settings that you normally do with a reverse-proxy and not with an application server
    • 12
  10. user340994
    2012-11-28T04:48:36+08:002012-11-28T04:48:36+08:00

    You can use redir program:

    sudo redir --lport=80 --laddr=192.168.0.101 --cport 9990 --caddr=127.0.0.1
    
    • 7

Sidebar

Stats

  • Questions 681965
  • Answers 980273
  • Best Answers 280204
  • Users 287326
  • Popular
  • Answers
  • Marko Smith

    Restrict Apache to only allow access using SSL for some directories

    • 6 Answers
  • Marko Smith

    How do I tell Apache which PHP to use?

    • 5 Answers
  • Marko Smith

    How to forcibly close a socket in TIME_WAIT?

    • 7 Answers
  • Marko Smith

    How do you copy a physical hard drive to a Vmware virtual hard disk?

    • 11 Answers
  • Marko Smith

    Increase number of allowed remote desktop connections

    • 9 Answers
  • Marko Smith

    How to dump a Microsoft SQL Server database to a SQL script?

    • 9 Answers
  • Marko Smith

    How can I port forward with iptables?

    • 8 Answers
  • Marko Smith

    How to bind MySQL server to more than one IP address?

    • 8 Answers
  • Marko Smith

    How to run a server on port 80 as a normal user on Linux?

    • 20 Answers
  • Marko Smith

    Run Oracle SQL script and exit from sqlplus.exe via command prompt

    • 11 Answers
  • Martin Hope
    DrStalker Restrict Apache to only allow access using SSL for some directories 2008-09-19 17:19:55 +0800 CST
  • Martin Hope
    Sam McAfee How do I tell Apache which PHP to use? 2008-12-23 18:15:17 +0800 CST
  • Martin Hope
    Rehan How to forcibly close a socket in TIME_WAIT? 2008-09-04 04:57:26 +0800 CST
  • Martin Hope
    Nick Berardi How do you copy a physical hard drive to a Vmware virtual hard disk? 2008-10-23 14:38:49 +0800 CST
  • Martin Hope
    Matt Sheppard How to dump a Microsoft SQL Server database to a SQL script? 2008-08-25 17:47:52 +0800 CST
  • Martin Hope
    Stu How can I port forward with iptables? 2008-12-06 13:06:59 +0800 CST
  • Martin Hope
    BlaM How to bind MySQL server to more than one IP address? 2008-09-03 08:04:18 +0800 CST
  • Martin Hope
    Deepak Mittal How to run a server on port 80 as a normal user on Linux? 2008-11-11 06:31:11 +0800 CST
  • Martin Hope
    JoshL Run Oracle SQL script and exit from sqlplus.exe via command prompt 2008-09-23 15:33:09 +0800 CST
  • Martin Hope
    Joel Spolsky Is there a site that can track all the domain names I own? 2008-08-02 08:37:51 +0800 CST

Related Questions

Trending Tags

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Home
  • Questions
    • Hot Questions
    • New Questions
  • Tags
  • Help

Footer

SnapOverflow

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Help

© 2022 SOF-TR. All Rights Reserve