44

I can't start an application on port 80.

I have tried on my local computer (using my IDE, and on a local server), no luck.

I have checked other similar posts and make sure that I run jar on server with root.

This is the error:

 till here all ok
...
java.net.SocketException: Permission denied
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:338)
at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:760)
at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:472)
at org.apache.catalina.connector.Connector.startInternal(Connector.java:986)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardService.addConnector(StandardService.java:237)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.addPreviouslyRemovedConnectors(TomcatEmbeddedServletContainer.java:186)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:149)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at com.andirod.StartApplication.main(StartApplication.java:20)
...
...
...
Exception in thread "main" java.lang.IllegalStateException: Tomcat connector in failed state
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:157)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at com.andirod.StartApplication.main(StartApplication.java:20)
Joris Schellekens
  • 8,483
  • 2
  • 23
  • 54
5er
  • 2,506
  • 7
  • 32
  • 49

6 Answers6

83

On linux ports below 1024 can be opened only by root, so the port 80 is restricted by default

if you want to publish your app on 80 port you need to redirect request from port 80 to the port you gonna run your springapp (e.g 8080) port

Solution 1: HTTP Proxy server

You can use Apache2 server which is allowed by default to work on port 80 and can forward requests for you to Tomcat

Example configuration for Debian

sudo apt-get install apache2

a2enmod proxy
a2enmod proxy_http   

cd /etc/apache2/sites-enabled
sudo nano 000-default.conf

Edit file:

<VIRTUALHOST *:80>

    ProxyPreserveHost On

    # ...

    ProxyPass / http://localhost:8080/
</VIRTUALHOST>

Save file: Ctrl+O, ENTER, Ctrl+X

Note: To learn more about virtual host configurations, you can check out the detailed Apache manual on the subject by clicking here.

Restart Apache2 to apply changes:

sudo service apache2 restart

or

sudo systemctl restart apache2

Solution 2: Port forwarding

Use iptables for redirects

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

if you need to use localhost also add this

iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
PhoneixS
  • 10,574
  • 6
  • 57
  • 73
Oskar Dajnowicz
  • 1,700
  • 12
  • 16
16

Use sudo on linux.

I was running a Spring Boot application on Ubuntu and java -jar app.jar --server.port=80 gave me the same error. Since ports below 1024 can only be opened by root access, so use"sudo": sudo java -jar app.jar --server.port=80.

This way of deployment is only suggested for local tests due to security concerns. See comments for details.

PhoenixPan
  • 536
  • 7
  • 19
  • 6
    This is not a great idea from a security point of view: Now your java app runs with super user permissions. The `iptables` solution neatly avoids this. – dirkjot Mar 20 '18 at 03:44
  • 2
    @dirkjot Yeah true, thanks for pointing that out. The `iptables` part in the accepted answer was not there by the time I wrote my solution, so I just put this up as a quick solution for testing locally. This is definitely not good for production deployment. – PhoenixPan Mar 20 '18 at 04:39
  • 1
    Although not suitable for prd this is a quick solution for testing and investigation purposes ... – Rafael Feb 14 '20 at 18:23
6

Here are steps I followed on centos.

Step 1 (Optional): Set port

By default spring boot app run on port 8080, if you wish to change this you can change on your src/main/resources/application.properties file

server.port = 8082 // any port above than 1024

Step 2: Install apache if not installed already

On Centos 7

sudo yum install httpd

Step 3: Edit your virtual host

/etc/httpd/conf.d/vhost.conf

Your config should look like this

<VirtualHost *:80>
   ServerName yourdomin.com
   #DocumentRoot /var/www/html

   ProxyPreserveHost On
   ProxyPass / http://localhost:8082/
   ProxyPassReverse / http://localhost:8082/
</VirtualHost>

And restart apache

sudo service httpd restart
VK321
  • 5,768
  • 3
  • 44
  • 47
2

In the case of using macOs, it is now possible to run on port 80 without any changes on macOs Mojave Version 10.14.

aydinugur
  • 1,208
  • 2
  • 14
  • 21
0

If you're running spring boot with docker.

Dockerfile:

FROM adoptopenjdk/openjdk13 AS server
ADD /target/AppServer-1.0.jar AppServer-1.0.jar
ENTRYPOINT ["java", "-jar" , "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:9000", "-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.local.only=false", "-Dcom.sun.management.jmxremote.port=1099", "-Dcom.sun.management.jmxremote.rmi.port=1099", "-Djava.rmi.server.hostname=127.0.0.1", "-Dlog4j.configurationFile=log4j2-docker.xml", "AppServer-1.0.jar", "--server.port=80"]

(*) Scroll right until the end and see --server.port=80 after the jar name.

Build the image and run with:

docker run -it -p 8080:80 --cap-drop all --cap-add net_bind_service <image-name>:<tag>

(!) Please notice that I dropped all capabilities for this process / container and added only the relevant one - net_bind_service which bind a socket to privileged ports (port numbers less than 1024).

Rot-man
  • 18,045
  • 12
  • 118
  • 124
-2

Add -Djava.net.preferIPv4Stack=true to the VM options

JavaMail API to iMail -- java.net.SocketException: Permission denied: connect

Community
  • 1
  • 1
sunysen
  • 2,265
  • 1
  • 12
  • 13