eclipse:远程调试防火墙后面的tomcat服务器
Posted
技术标签:
【中文标题】eclipse:远程调试防火墙后面的tomcat服务器【英文标题】:eclipse: remote debugging a tomcat server behind a firewall 【发布时间】:2011-10-06 17:45:27 【问题描述】:在使用 jpda 启动 tomcat 后,在我的公司,我可以在 eclipse 中远程调试一堆 Web 应用程序。由于多种原因,我现在需要从公司防火墙外部开发和远程调试这些相同的 web 应用程序,并且我只能通过端口 22 上的 ssh 访问该服务器。
我通过隧道将最需要的端口(svn、nexus、tomcat 本身、从服务器或通过服务器)连接到 localhost,这些服务工作正常,但我无法以任何方式启动 eclipse 调试器;从我第二次尝试开始,我收到“等待数据包 XXX 时连接超时”或“连接被拒绝”。 使用服务器上的 nmap 检查,它会在第一次连接尝试之前报告端口打开,然后它会关闭。我在 catalina.out 中没有得到有趣的输出日志
我用来启动隧道的命令是:
ssh -L 8000:localhost:8000 user@mycompany.com
iptables 在服务器和本地机器上都被暂时停止进行测试。
我错过了什么吗?我需要将其他端口转发到本地主机吗?还是以某种方式涉及名称解析?
编辑
在 eclipse 连接尝试之前打开端口:
root@lnxulisse:/opt/apache-tomcat-6.0.32/bin# lsof -p 2147 -n |grep TCP
java 2147 root 4u IPv4 640850 0t0 TCP *:8000 (LISTEN)
java 2147 root 38u IPv6 640859 0t0 TCP *:http-alt (LISTEN)
java 2147 root 40u IPv6 640865 0t0 TCP *:https (LISTEN)
java 2147 root 46u IPv6 640908 0t0 TCP 127.0.0.1:18005 (LISTEN)
java 2147 root 48r IPv6 642625 0t0 TCP 172.24.0.82:48347->172.24.0.82:mysql (ESTABLISHED)
java 2147 root 181u IPv6 640891 0t0 TCP 172.24.0.82:60353->172.24.0.82:mysql (ESTABLISHED)
之后:
java 2147 root 4u IPv6 642769 0t0 TCP 172.24.0.82:48956->172.24.0.82:mysql (ESTABLISHED)
java 2147 root 5u IPv4 640851 0t0 TCP 127.0.0.1:8000->127.0.0.1:34193 (ESTABLISHED)
java 2147 root 38u IPv6 640859 0t0 TCP *:http-alt (LISTEN)
java 2147 root 40u IPv6 640865 0t0 TCP *:https (LISTEN)
java 2147 root 46u IPv6 640908 0t0 TCP 127.0.0.1:18005 (LISTEN)
java 2147 root 181u IPv6 640891 0t0 TCP 172.24.0.82:60353->172.24.0.82:mysql (ESTABLISHED)
返回的确切 eclipse 错误是:
Exception occurred during launch
Failed to connect to remote JVM. Connection timed out.
Timeout occurred while waiting for packet 204.
(每次尝试的数据包编号都不同)。
在workspace/.metadata/.log
我得到:
!ENTRY org.eclipse.osgi 2 0 2011-07-17 18:43:53.024
!MESSAGE While loading class "org.eclipse.core.net.proxy.IProxyService", thread "Thread[main,6,main]" timed out waiting (5000ms) for thread "Thread[Thread-6,5,main]" to finish starting bundle "org.eclipse.core.net_1.2.1.r35x_20090812-1200 [232]". To avoid deadlock, thread "Thread[main,6,main]" is proceeding but "org.eclipse.core.net.proxy.IProxyService" may not be fully initialized.
!STACK 0
org.osgi.framework.BundleException: State change in progress for bundle "reference:file:plugins/org.eclipse.core.net_1.2.1.r35x_20090812-1200.jar" by thread "Thread-6".
at org.eclipse.osgi.framework.internal.core.AbstractBundle.beginStateChange(AbstractBundle.java:1073)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:278)
[...]
!ENTRY org.eclipse.ui.ide 4 4 2011-07-17 18:43:53.028
!MESSAGE Proxy service could not be found.
eclipse 配置为直接连接互联网。
编辑 2
我认为解决方案可能在这里:
http://blog.cantremember.com/debugging-with-jconsole-jmx-ssh-tunnels/
但我无法理解他的 JNDI/RMI 设置,以及在多大程度上适用于我的配置。
编辑 3
这是对那些回答“使用<lan|local ip address>
而不是<localhost>
”的人的澄清
B 和 C 位于同一网络基础设施中的两个不同子网络中;只允许从外部连接到 C 的端口 22(并且有点“代理”,我不知道网络内部情况)。
A 是“外部”(我的 dsl 连接与动态 IP 地址)。
Debugging on C from B via ssh tunnel -> works
Debugging on C from A via ssh tunnel -> connection timed out while waiting for packet XXX
【问题讨论】:
@ram 你看到我的问题“EDIT 2”了吗?答案应该在那里 【参考方案1】:This article 建议远程 Java 虚拟机 (JVM) 在调试模式下侦听的默认端口是 1044。您也应该隧道运行远程 JVM 的端口。
更一般地说,您可以运行 wireshark/tcpdump 来查看在启动调试器时尝试连接到哪些端口。
编辑:
我会尝试更多的事情:
检查远程主机(例如,如果是Linux,则使用ps auxwww
)带有哪些参数(查找-Xrunjdwp
后面的内容或使用lsof -p PID_OF_JVM_TO_BE_DEBUGGED
它侦听的TCP 端口(查找带有TCP
和LISTEN
在lsof
输出中)
确保远程主机上的 JVM 侦听 lo
接口,而不是网络接口(这是您在 ssh 的 -L
选项中使用 localhost
指定的)。
在使用jdb -attach localhost:8000
启动eclipse 的机器上手动启动调试器是否有效? (您也可以在远程主机上尝试此操作,以确保调试器在端口 8000 上运行)
确保 eclipse 尝试连接到localhost
(当没有在第一个 8000 之前使用-L
选项指定绑定地址时,ssh 在lo
接口上侦听)
【讨论】:
我在 tomcat 启动脚本中明确将端口设置为 8000(并且确实在公司网络内进行远程调试);将尝试使用 tcpdump 来查看是否有其他连接尝试,但在这种情况下,我得到的错误(“等待数据包超时”)会产生误导。connection timed out
可能是由于防火墙简单地忽略(丢弃)连接尝试的数据包(而不是发送一个数据包,说明此端口上没有运行任何内容并立即拒绝连接尝试)。
感谢您的帮助;实际上连接在超时前运行了几秒钟,并且错误报告了哪个数据包号“迟到”(或从未到达)。请查看我在问题中的编辑以获取更多详细信息
你了解18005端口的服务是什么吗? (我只是想知道这是否是您还需要隧道的东西)
是的,它是用于关闭的 tomcat 端口,在 您能否给出-Xrunjdwp参数的确切参数?
您是否也尝试过不同的调试方法(server=y/n,suspend=y/n)?
也许反转连接(让 tomcat 连接到调试器而不是让调试器连接到 tomcat)可能会有所帮助。
【讨论】:
【参考方案3】:假设远程 Tomcat 实例已使用 -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n
之类的内容启动,请尝试以下命令:
在我的 Mac 上,我在本地尝试了 ssh -L 10701:<b>localhost</b>:10700 user@localhost -N
,其中一个 Tomcat 实例以 -Xrunjdwp:transport=dt_socket,server=y,address=10700,suspend=n
启动,并尝试在 Eclipse 中连接端口 10701,我一直看到“无法连接到远程 VM com.sun。 jdi.connect.spi.ClosedConnectionException”。通过将隧道命令更改为ssh -L 10701:<b>0.0.0.0</b>:10700 user@localhost -N
,Eclipse 能够附加。
【讨论】:
在我的 linux 系统上,我在公司网络内使用 localhost 连接到服务器没有问题;尝试从外部附加到“内部”IP 地址时会出现问题,防火墙只允许连接到端口 22。另请注意,您得到的异常是不同的,当我得到一个超时异常。【参考方案4】:我在进行远程调试时经常遇到这个问题。我不知道这个问题的确切原因,但我使用了以下解决方案,也许它也适合你:
而不是
ssh -L 8000:localhost:8000 user@remotehost
被使用
ssh -L 8000:remotehost:8000 user@remotehost
用于创建 SSH 隧道(请注意第二个示例中端口号之间的 remotehost 而不是 localhost)。除了远程主机的名字,你也可以使用远程主机的普通IP地址(不是环回地址127.0.0.1,而是真正的本地网络IP地址)。
希望对你有帮助,祝你好运!
【讨论】:
好点,但这并不能解决我的问题;在丹尼尔答案中查看评论 对于 Google Cloud 上的用户:使用gcloud compute ssh --ssh-flag="-L 8787:INTERNAL_IP:8787" INSTANCE
。 %INSTANCE%
根据cloud.google.com/sdk/gcloud/reference/compute/ssh 对我不起作用,但内部对我有用。【参考方案5】:
好吧,我在很长一段时间后回答自己;在我的具体情况下,解决方案是将 eclipse JVM 置于监听模式:
Connection Type: "Standard (Socket Listen)"
并反转隧道的方向:
ssh -L 8001:localhost:8001 user@work (run on server (S), "localhost" is W)
ssh -R 8001:localhost:8001 user@work (run at home (H), "localhost" is W)
一些解释:在问题中,我的情况是:
H -------------------> S not working ( ssh -L 8001:S:8001 user@S from H)
H W -------> S working ( ssh -L 8001:S:8001 user@S from W)
home work server
像这样倒车时:
H <------- W S ssh -R 8001:localhost:8001 user@W (from H)
H W <------- S ssh -L 8001:localhost:8001 user@W (from S)
home work server
成功了。换句话说,任何写在 S:8001 上的东西都会被转发到 W:8001,而任何写到 W:8001 的东西都会被转发到 H:8001,我的 eclipse JVM 正在那里监听。
S 上的 tomcat JVM 应该以 server=n 启动,带参数:
-agentlib:jdwp=transport=dt_socket,server=n,suspend=n,address=8001
【讨论】:
以上是关于eclipse:远程调试防火墙后面的tomcat服务器的主要内容,如果未能解决你的问题,请参考以下文章