2

I've been following the official guide to setting up Springboot as an init.d service on an Amazon Linux ec2 instance. Before I got to this setup, I was running into the problem where I could not start the server on port 80 when I executed the jar manually. The solution to this was to execute the jar as root, and I moved on.

Now, I have finished making the necessary changes to my project's gradle.build and created the symlink to my executable jar, and I can do

sudo service myapp start

and I get some indication that the process is running just fine. However, the process exits after a few seconds. If I check the logs in /var/log/myapp.log, it contains the same error I was getting before when trying to start the server manually as a non-root user

2018-04-13 13:01:31.793  INFO 23583 --- [           main] 
o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2018-04-13 13:01:31.816  INFO 23583 --- [           main] 
ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run 
your application with 'debug' enabled.
2018-04-13 13:01:31.817 ERROR 23583 --- [           main] 
o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

The Tomcat connector configured to listen on port 80 failed to start. The 
port may already be in use or the connector may be misconfigured.

Action:

Verify the connector's configuration, identify and stop any process that's 
listening on port 80, or configure this application to listen on another 
port.

2018-04-13 13:01:31.818  INFO 23583 --- [           main] 
ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4c3e4790: startup date [Fri Apr 13 13:01:26 UTC 2018]; root of context hierarchy
2018-04-13 13:01:31.820  INFO 23583 --- [           main] 
o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

So when I start the service as root, it doesn't have the same permissions as though I just manually executed the jar.

Tl;dr: how do I start Springboot to listen to port 80 (requires sudo) as an init.d service?

Note this is my first time dealing with Linux in anything more than a testing capacity, so I half-expect the solution to be really obvious due to my lack of experience.

1

You have to know the following facts:

  • Ports below 1024 can be opened only by root.

  • Running a Spring Boot web application with root privileges is a bad idea. Because, if the application is compromised the attacker gain root privileges.

One solution is to run an httpd Apache server as a reverse proxy and redirect request on port 80 to a port higer than 1024 on localhost. For this you can use the ProxyPass Apache directive.

Here is an article about this technique: Using Apache as a Reverse Proxy for Spring Boot Embedded Tomcat

The main Apache configuration looks like this:

ProxyPreserveHost on
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
0

I wasn't really looking for a secure answer, as this was just an experience project.

The solution I found for myself was to set the owner of the symlink to root.

sudo chown root myapp

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.