如何设置 spring-boot 以允许从外部 IP 地址访问网络服务器

Posted

技术标签:

【中文标题】如何设置 spring-boot 以允许从外部 IP 地址访问网络服务器【英文标题】:How to setup spring-boot to allow access to the webserver from outside IP addresses 【发布时间】:2016-09-23 13:25:00 【问题描述】:

我一直在研究如何在spring-boot 中设置tomcat 以允许来自外部IP 地址的访问。目前我可以从 locahost:port 查看 UI,但我无法从其他系统访问它。

http://localhost:8081 

当我登录到本地计算机时,它可以工作。

http://192.168.0.93:8081

当我登录到本地计算机并尝试http://192.168.0.93:8081 时,它不起作用。

我想通过另一台计算机的 IP 地址访问 UI,但它不起作用。

http://192.168.0.93:8081

当我找到springs 文档时,我发现您可以添加您希望 tomcat 设置网络服务器以使用 server.address 的 IP 地址。这应该允许外部系统通过该 IP 地址访问服务器。

server.port=8082
server.address=192.168.0.93

如果我不提供地址,端口工作正常,但是当我提供地址并尝试运行它时,我遇到了绑定到该地址的问题。看起来spring-boot 已经分配了 locahost:8082。

问题:

如何正确设置spring-boot,允许外部地址访问tomact,并在本地访问时识别自己的IP?

谢谢

堆栈跟踪:

java.net.BindException: Cannot assign requested address
  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:340)
  at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:765)
  at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:473)
  at org.apache.catalina.connector.Connector.startInternal(Connector.java:986)
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
  at org.apache.catalina.core.StandardService.addConnector(StandardService.java:239)
  at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.addPreviouslyRemovedConnectors(TomcatEmbeddedServletContainer.java:194)
  at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:151)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:293)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
  at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
  at com.miw.mcb.server.ReactAndSpringDataRestApplication.main(ReactAndSpringDataRestApplication.java:18)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:478)
  at java.lang.Thread.run(Thread.java:745)
2016-05-25 11:24:30 - Failed to start connector [Connector[HTTP/1.1-8081]]
org.apache.catalina.LifecycleException: Failed to start component [Connector[HTTP/1.1-8081]]
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
  at org.apache.catalina.core.StandardService.addConnector(StandardService.java:239)
  at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.addPreviouslyRemovedConnectors(TomcatEmbeddedServletContainer.java:194)
  at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:151)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:293)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
  at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
  at com.miw.mcb.server.ReactAndSpringDataRestApplication.main(ReactAndSpringDataRestApplication.java:18)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:478)
  at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.catalina.LifecycleException: service.getName(): "Tomcat";  Protocol handler start failed
  at org.apache.catalina.connector.Connector.startInternal(Connector.java:993)
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
  ... 19 common frames omitted
Caused by: java.net.BindException: Cannot assign requested address
  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:340)
  at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:765)
  at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:473)
  at org.apache.catalina.connector.Connector.startInternal(Connector.java:986)
  ... 20 common frames omitted
2016-05-25 11:24:30 - Pausing ProtocolHandler ["http-nio-192.168.0.93-8081"]
2016-05-25 11:24:30 - Stopping service Tomcat
2016-05-25 11:24:30 - The stop() method was called on component [StandardServer[-1]] after stop() had already been called. The second call will be ignored.
2016-05-25 11:24:30 - Stopping ProtocolHandler ["http-nio-192.168.0.93-8081"]
2016-05-25 11:24:30 - Destroying ProtocolHandler ["http-nio-192.168.0.93-8081"]
2016-05-25 11:24:30 - Application startup failed
org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat servlet container
  at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:165)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:293)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
  at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
  at com.miw.mcb.server.ReactAndSpringDataRestApplication.main(ReactAndSpringDataRestApplication.java:18)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:478)
  at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Tomcat connector in failed state
  at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:159)
  ... 16 common frames omitted

【问题讨论】:

想了解一下 CORS - spring.io/guides/gs/rest-service-cors。另外,我相信你正在做的是试图告诉应用程序运行目标 IP。 @mugua 在从一个 Web 服务器与另一个 Web 服务器通信时,我按照该指南为我们的 REST Web 服务设置了 CORS。这没有问题,但它通过 localhost:DIFF_PORTS 进行通信。我认为的问题是允许不同的 IP 地址从我认为在 tomcat 中的另一个系统访问 UI。我想我读到如果你不指定 server.address 它将绑定到 0.0.0.0 抱歉,我理解错了。我以为您正试图通过输入远程计算机的 IP 从远程计算机访问应用程序。我认为您没有指定 IP 是正确的,它将默认为 localhost,但仍应包括主机的本地 IP。 @mugua 我在问题中添加了更多细节 我怀疑spring-boot已经分配了地址。如果是这样,我认为它会给你一个更明确的例外,比如“地址已在使用中”。如果是这种情况,您可以终止该进程或重新启动系统并重试。我想知道此时这是否是网络问题,以及某些端口范围是否被阻止。如果可以的话,也许打开你的防火墙,看看会发生什么。在我自己的应用程序上,我什么都没设置,我可以通过网络人员分配的 IP 或域名访问应用程序。 【参考方案1】:

既然有这么多人看过这个问题。解决方法是确保在托管 CentOS 机器上正确配置了防火墙,并且没有明确设置服务器地址。

设置不正确

失败之前防火墙设置不正确

server.port=8081
server.address=192.168.0.93

正确设置防火墙后您无需指定 server.address,只需指定端口

正确设置

server.port=8081

这让我可以使用它的 ip 从其他系统正确访问应用程序。

http://<someip>:<server.port>
http://192.168.0.93:8081

【讨论】:

您对防火墙做了哪些更改?我也面临着类似的问题。 @Harsh 变化如上图,你试过了吗? 是的,我设置了 server.port 和 server.address 但它不起作用。我也打开了8080端口仍然显示404错误。 @Harsh 如上所述,一旦我正确设置了防火墙,我就删除了“server.address”,只使用了“server.port”,它工作正常。 感谢您的回复。您能否详细说明您所做的防火墙设置?我已经打开了8080端口。除此以外我还需要做什么吗?【参考方案2】:

谢谢你,你救了我很多! 我想在 cmets 中发布此内容,但我没有足够的声誉来回复。

想要了解有关防火墙更改信息的人,

我使用 firewalld 在我的 vm(centos7) 中添加我的 springboot 网络服务器端口

我的网络服务器使用的是 8080,所以我这样做了:

firewall-cmd --permanent --reload --zone=public --add-port=8080/tcp*

sudo systemctl restart firewalld*

您需要重新启动/重新加载 firewalld 以应用更改。 如果你,

sudo firewall-cmd --list-all*

你可以发现8080/tcp已经被添加到端口列表中

【讨论】:

firewall-cmd --permanent --zone=public --add-port=8080/tcp 为我工作【参考方案3】:

这可以通过ufw轻松完成

要查看当前打开的端口,请输入:sudo ufw status numbered(为安全起见截屏)

要打开端口,请输入:sudo ufw allow 8080(8080 或您想要的任何端口)

要删除端口,请输入:sudo ufw delete number

记得在删除之前用sudo ufw status numbered仔细检查号码。

:-)

【讨论】:

【参考方案4】:

这个问题是你需要打开端口的防火墙引起的。我正在使用 ubuntu。这个命令为我打开了端口。我的应用程序使用端口 8000,所以我使用下面的命令打开端口

firewall-cmd --permanent --zone=public --add-port=8080/tcp

然后使用命令重启防火墙服务

sudo systemctl restart firewalld

还要检查你是否在springboot应用中设置了server.servlet.context-path知道正确的endpoint。如果没有直接去端口

【讨论】:

以上是关于如何设置 spring-boot 以允许从外部 IP 地址访问网络服务器的主要内容,如果未能解决你的问题,请参考以下文章

如何从外部jar自动运行java任务?

51单片机怎么设置外部中断?

如何从外部 api 读取属性并将其设置为 springboot 中的应用程序上下文以使其全局可用?

spring-boot - 外部 log4j 配置不起作用

从 Twitter API 获取用户的电子邮件以进行外部登录身份验证 ASP.NET MVC C#

外部主机不允许连接Mysql设置的解决