Ubuntu

Tomcat 和 Java 不監聽 IPv6

  • July 1, 2014

我們有一個執行 Ubuntu 12.04 LTS、Tomcat 7 和 Oracle Java 的網路伺服器。到目前為止,我們一直在埠 80 和 443(80 重定向到 443)上的 IPv4 地址上為 Web 應用程序提供服務。

我正在嘗試使tomcat也通過IPv6在相同的埠上提供相同的應用程序。作業系統已正確配置 IPv6,它有自己的 IPv6 地址,範圍為全域。

不起作用的是 Tomcat/Java 沒有監聽 IPv6。這是 netstat -tlpn 的輸出:

tcp        0      0 0.0.0.0:2222            0.0.0.0:*               LISTEN      957/sshd
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2686/java
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      1058/postgres
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1243/master
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      2686/java
tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN      2686/java
tcp6       0      0 :::2222                 :::*                    LISTEN      957/sshd
tcp6       0      0 :::5432                 :::*                    LISTEN      1058/postgres
tcp6       0      0 ::1:25                  :::*                    LISTEN      1243/master

如您所見,Java 只監聽 tcp 連接,而 postgres 和 ssh 也接受與 IPv4 相同埠上的 tcp6 連接。

我在 Tomcat 啟動腳本中找到了 java.net.preferIPv4Stack=true 屬性,但是當我將其設置為 false 時,tomcat 開始僅在 tcp6 本地埠 8005 上偵聽。我還需要它來偵聽 :::443 和: ::80。它也從 IPv4 連接中消失了,但我相信 ::: 可以綁定 IP v4 和 v6。

我應該提一下,我不是 Java 程序員,我的職責只是伺服器本身。另外我不想做太多的實驗,因為這是一個生產伺服器。

任何幫助是極大的讚賞!乾杯

  • 編輯 -

這是完整的 server.xml 文件,去掉了預設註釋:

<?xml version='1.0' encoding='utf-8'?>

<Server port="8005" shutdown="SHUTDOWN">

 <Listener className="org.apache.catalina.core.JasperListener" />
 <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
 <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
 <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

 <GlobalNamingResources>

   <Resource name="UserDatabase" auth="Container"
             type="org.apache.catalina.UserDatabase"
             description="User database that can be updated and saved"
             factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
             pathname="conf/tomcat-users.xml" />
 </GlobalNamingResources>
 <Service name="Catalina">
   <Connector port="80" protocol="HTTP/1.1"
          connectionTimeout="20000"
          URIEncoding="UTF-8"
          redirectPort="443" />

<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
          maxThreads="150" scheme="https" secure="true"
          clientAuth="false" sslProtocol="TLS"
      keystoreFile="/etc/tomcat7/ssl/tomcat.keystore" 
      keystorePass="secretpass"/>

<Engine name="Catalina" defaultHost="localhost">

 <Realm className="org.apache.catalina.realm.LockOutRealm">

   <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
          resourceName="UserDatabase"/>
 </Realm>

 <Host name="localhost"  appBase="webapps"
       unpackWARs="true" autoDeploy="true">

   <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
          prefix="localhost_access_log." suffix=".txt"
          pattern="%h %l %u %t "%r" %s %b" />

 </Host>
</Engine>

經過數小時的研究,我發現問題出在 authbind 上。它只能為 IPv4 將 tomcat 綁定到低於 1024 的埠,並且不適用於 IPv6(它應該在較新的核心上,但在這台機器上使用 3.2 核心)。

當我在 /etc/default/tomcat7 中打開 authbind 並修改我的 server.xml 以在 8080 上偵聽,然後重定向到 443 並在 8443 上偵聽時,tomcat 開始像它應該的那樣偵聽 IPv6。

通過 iptables 重定向埠也僅適用於 IPv4,因為 ip6tables 支持 nat 並僅從核心 3.7 重定向。

然後,我使用了一個名為 xinetd 的守護程序將流量從 80 重定向到 8080,從 443 重定向到 8443。現在一切正常。

引用自:https://serverfault.com/questions/605684