我一直在遵循官方指南将 Springboot 设置为 init.d 服务在 Amazon Linux ec2 实例上。在进行此设置之前,我遇到了以下问题:我无法在端口 80 上启动服务器当我手动执行 jar 时。解决方案是以 root 身份执行 jar,然后我继续前进。
现在,我已经完成了对项目的 gradle.build 进行必要的更改,并创建了可执行 jar 的符号链接,我可以做
sudo service myapp start
我得到一些迹象表明该过程运行得很好。但是,该进程会在几秒钟后退出。如果我检查 /var/log/myapp.log 中的日志,它包含同样的错误我之前尝试以非 root 用户身份手动启动服务器时遇到过
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
因此,当我以 root 身份启动服务时,它没有与我手动执行 jar 相同的权限。
Tl;dr: 如何启动 Springboot 以作为 init.d 服务监听 80 端口(需要 sudo)?
请注意,这是我第一次以超出测试能力的方式处理 Linux,因此由于我缺乏经验,我预计解决方案会非常明显。
答案1
您必须了解以下事实:
1024以下的端口只能由root用户打开。
使用 root 权限运行 Spring Boot Web 应用程序是一个坏主意。因为,如果应用程序遭到破坏,攻击者就会获得 root 权限。
一种解决方案是运行 httpd Apache 服务器作为反向代理,并将端口 80 上的请求重定向到本地主机上高于 1024 的端口。为此,您可以使用ProxyPass
阿帕奇指令。
这是一篇关于该技术的文章:使用 Apache 作为 Spring Boot 嵌入式 Tomcat 的反向代理
Apache 的主要配置如下所示:
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/
答案2
我并不是真的在寻找一个安全的答案,因为这只是一个体验项目。
我自己找到的解决方案是将符号链接的所有者设置为 root。
sudo chown root myapp