4

我有一个绑定到端口 8080 (http) 和 8888 (https) 的工作 spring boot + tomcat8 嵌入式应用程序。现在我正在寻找一种方法来配置应用程序以运行

a) 在特权端口上,即低于 1024 的端口,即端口 80 和 443

b) 应用程序应在非 root 用户帐户下运行。

c) 操作系统环境可以是任何 Linux 发行版,例如:debian/ubuntu 或 OpenBSD 发行版。

d) 解决方案最好稍后通过 Web 界面(即一些脚本)进行配置。

到目前为止,我在 INTERNET 上找到的只是一个配置非嵌入式 tomcat 实例和“authbind”的手册。但是我有一个嵌入式tomcat。“authbind”的手册页说:

“您必须使用 authbind 调用该程序。authbind 将设置一些环境变量,包括一个 LD_PRELOAD,如果系统配置为允许,它将允许程序(包括它可能运行的任何子进程)绑定到低编号(<512)端口。“</p>

我发出“ps - aux”,我得到了运行应用程序的用户名。我已将嵌入式 tomcat 配置为在端口 80 和 443 上运行,即在 cli 中发出命令:

sudo touch /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80
chown tito /etc/authbind/byport/80
sudo touch /etc/authbind/byport/443
sudo chmod 500 /etc/authbind/byport/443
chown tito /etc/authbind/byport/443

现在我如何调用“authbind”下的嵌入式tomcat。如果“authbind”不是这个问题的正确解决方案,那么如何使用 spring boot 解决这个问题。

我收到的错误消息是:

2014-05-09 09:46:48.403  INFO 7880 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 80
2014-05-09 09:46:48.604 ERROR 7880 --- [           main] o.a.coyote.http11.Http11NioProtocol      : Failed to initialize end point associated with ProtocolHandler ["http-nio-80"]

java.net.SocketException: Permission denied
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:414)
    at sun.nio.ch.Net.bind(Net.java:406)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:351)
    at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:683)
    at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:456)
    at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:120)
    at org.apache.catalina.connector.Connector.initInternal(Connector.java:960)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.core.StandardService.initInternal(StandardService.java:567)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:826)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:139)
    at org.apache.catalina.startup.Tomcat.start(Tomcat.java:340)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:79)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:69)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:270)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:145)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:159)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:132)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:476)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
    at org.syncServer.core.Application.main(Application.java:123)

2014-05-09 09:46:48.606 ERROR 7880 --- [           main] o.apache.catalina.core.StandardService   : Failed to initialize connector [Connector[HTTP/1.1-80]]

org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-80]]
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:106)
    at org.apache.catalina.core.StandardService.initInternal(StandardService.java:567)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:826)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:139)
    at org.apache.catalina.startup.Tomcat.start(Tomcat.java:340)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:79)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:69)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:270)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:145)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:159)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:132)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:476)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
    at org.syncServer.core.Application.main(Application.java:123)
Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
    at org.apache.catalina.connector.Connector.initInternal(Connector.java:962)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    ... 19 common frames omitted
Caused by: java.net.SocketException: Permission denied
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:414)
    at sun.nio.ch.Net.bind(Net.java:406)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:351)
    at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:683)
    at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:456)
    at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:120)
    at org.apache.catalina.connector.Connector.initInternal(Connector.java:960)
    ... 20 common frames omitted

2014-05-09 09:46:48.840  INFO 7880 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2014-05-09 09:46:48.841  INFO 7880 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.3
2014-05-09 09:46:48.913  INFO 7880 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-05-09 09:46:48.913  INFO 7880 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1898 ms
SERVLET REGISTRATION
DISPATCHER INIT

ADDTION 1 我找到了一种如何从命令行执行此操作的方法,即从 spring 我做 maven build,目标设置为“package”,然后我转到我的 jar/war 文件所在的目标文件夹,然后我做

exec authbind --deep java -jar application.jar 

该应用程序绑定到端口 80 和 443,但不知何故我的 mvc thymeleaf 模板搞砸了。我需要通过 spring sts 自动化这个过程

4

2 回答 2

2

在您尝试在端口 80/443 上公开您的 Spring Boot 应用程序的行之间阅读,但您实际上并不需要让它监听这些端口之一本身。相反,您应该使用反向代理,例如HAProxy,它将以 root 身份启动,但随后将自己囚禁在 chroot 中,因此它没有 root 权限。

然后,您将代理配置为将请求转发到您的应用程序正在侦听的任何端口。

除了安全性之外,这还具有其他优势,例如能够基于用于多个服务的 URL 进行转发。这对于 Spring Boot 微服务来说非常棒,因为它允许您在同一服务器上的端口 80/443 上公开多个服务,而无需授予任何这些应用程序的 root 权限。它还可以用于提供应用程序实例之间的热切换,这可以帮助您实现零停机部署。

HAProxy的流行替代品是Apache HTTPDNginx

于 2014-05-09T14:21:22.647 回答
0

您想要的所有人员都在Apache Daemon Tools中实现。

它为 java 应用程序提供 chroot。因此,您可以以 root 身份启动它并绑定到特权端口,然后将其降级为非特权用户。

于 2014-10-05T20:16:39.760 回答