Skip to content

Window 10 Getting tomcat 9 to work on https

My goal is to use javascript webkitGetUserMedia to access the webcam and use java WebSocket on my LAN Network. I using apache-tomcat-9.0.20 with apache-maven-3.6.3 and eclipse ide. I am able to access the http on my network just fine. However, with https I’m only able to access on the server itself. I have tried turning off my firewall changing the default host name to the server computer name. But nothing see to work. Please remember the webcam needs https to be use and I was able to use my code in my web with apache service by only change jsp to php so I really doubt it a firewall issue.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
--><!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 --><Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
    <!-- A "Connector" using the shared thread pool-->
  
    <Connector connectionTimeout="20000" executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
  
    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the
         AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
  
    <Connector SSLEnabled="true" maxThreads="150" port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol">
    </Connector>

    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
   
    <Connector SSLEnabled="true" maxThreads="150" port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol">
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"/>
        <SSLHostConfig>
            <Certificate certificateChainFile="C:UsersspjpiDesktoplocalhost.pkipath" certificateFile="C:UsersspjpiDesktoplocalhost.cer" certificateKeyFile="C:UsersspjpiDesktoplocalhost.pem" type="RSA"/>
        </SSLHostConfig>
    </Connector>
  

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>


    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine defaultHost="localhost" name="Catalina">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>

      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt"/>

      <Context docBase="camera" path="/camera" reloadable="true" source="org.eclipse.jst.j2ee.server:camera"/></Host>
    </Engine>
  </Service>
</Server>

Answer

First, in your sample configuration you are registering multiple times same ports (2×8080 and 2×8443), so your server will be throwing errors in your console.

Make sure to register only one connector for every port. In another way, you will be getting an exeption like this:

27-Feb-2020 01:56:22.744 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]<br>
27-Feb-2020 01:56:22.783 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]<br>
27-Feb-2020 01:56:22.795 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector[HTTP/1.1-8080]]<br>
    org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:983)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:533)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1059)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:584)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:621)
        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.apache.catalina.startup.Bootstrap.start(Bootstrap.java:344)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:475)
    Caused by: java.net.BindException: Address already in use
        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.initServerSocket(NioEndpoint.java:248)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:222)
        at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1119)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1132)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:557)
        at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:980)<br>
        ... 13 more

So, you should select one of this configuration for port 8080:

    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
    <!-- A "Connector" using the shared thread pool-->
  
    <!--<Connector connectionTimeout="20000" executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>-->

Or With a shared thread pool:
  
    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <!--<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>-->
    <!-- A "Connector" using the shared thread pool-->
  
    <Connector connectionTimeout="20000" executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

Similar case, with your SSL port 8443:

        <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 This connector uses 
            the NIO implementation. The default SSLImplementation will depend on the 
            presence of the APR/native library and the useOpenSSL attribute of the AprLifecycleListener. 
            Either JSSE or OpenSSL style configuration may be used regardless of the 
            SSLImplementation selected. JSSE style configuration is used below. -->

        <Connector SSLEnabled="true" maxThreads="150" port="8443"
            protocol="org.apache.coyote.http11.Http11NioProtocol">
            <SSLHostConfig>
                <Certificate
                    certificateChainFile="C:UsersspjpiDesktoplocalhost.pkipath"
                    certificateFile="C:UsersspjpiDesktoplocalhost.cer"
                    certificateKeyFile="C:UsersspjpiDesktoplocalhost.pem"
                    type="RSA" />
            </SSLHostConfig>
        </Connector>

        <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2 This 
            connector uses the APR/native implementation which always uses OpenSSL for 
            TLS. Either JSSE or OpenSSL style configuration may be used. OpenSSL style 
            configuration is used below. -->

        <!--<Connector SSLEnabled="true" maxThreads="150" port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol">
            <UpgradeProtocol
                className="org.apache.coyote.http2.Http2Protocol" />
            <SSLHostConfig>
                <Certificate
                    certificateChainFile="C:UsersspjpiDesktoplocalhost.pkipath"
                    certificateFile="C:UsersspjpiDesktoplocalhost.cer"
                    certificateKeyFile="C:UsersspjpiDesktoplocalhost.pem"
                    type="RSA" />
            </SSLHostConfig>
        </Connector>-->

With Http/2 protocol:

        <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 This connector uses 
            the NIO implementation. The default SSLImplementation will depend on the 
            presence of the APR/native library and the useOpenSSL attribute of the AprLifecycleListener. 
            Either JSSE or OpenSSL style configuration may be used regardless of the 
            SSLImplementation selected. JSSE style configuration is used below. -->

        <!--<Connector SSLEnabled="true" maxThreads="150" port="8443"
            protocol="org.apache.coyote.http11.Http11NioProtocol">
            <SSLHostConfig>
                <Certificate
                    certificateChainFile="C:UsersspjpiDesktoplocalhost.pkipath"
                    certificateFile="C:UsersspjpiDesktoplocalhost.cer"
                    certificateKeyFile="C:UsersspjpiDesktoplocalhost.pem"
                    type="RSA" />
            </SSLHostConfig>
        </Connector>-->

        <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2 This 
            connector uses the APR/native implementation which always uses OpenSSL for 
            TLS. Either JSSE or OpenSSL style configuration may be used. OpenSSL style 
            configuration is used below. -->

        <Connector SSLEnabled="true" maxThreads="150" port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol">
            <UpgradeProtocol
                className="org.apache.coyote.http2.Http2Protocol" />
            <SSLHostConfig>
                <Certificate
                    certificateChainFile="C:UsersspjpiDesktoplocalhost.pkipath"
                    certificateFile="C:UsersspjpiDesktoplocalhost.cer"
                    certificateKeyFile="C:UsersspjpiDesktoplocalhost.pem"
                    type="RSA" />
            </SSLHostConfig>
        </Connector>

A valid sample configuration (with my own keystore) could be:

    <?xml version="1.0" encoding="UTF-8"?>
    <!--
      Licensed to the Apache Software Foundation (ASF) under one or more
      contributor license agreements.  See the NOTICE file distributed with
      this work for additional information regarding copyright ownership.
      The ASF licenses this file to You under the Apache License, Version 2.0
      (the "License"); you may not use this file except in compliance with
      the License.  You may obtain a copy of the License at
    
          http://www.apache.org/licenses/LICENSE-2.0
    
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
    -->
    <Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <!--APR library loader. Documentation at /docs/apr.html -->
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <!-- Prevent memory leaks due to use of particular java/javax APIs-->
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
    
      <GlobalNamingResources>
        <!-- Editable user database that can also be used by
             UserDatabaseRealm to authenticate users
        -->
        <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">
    
        <!--The connectors can use a shared executor, you can define one or more named thread pools-->
        <!--
        <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="150" minSpareThreads="4"/>
        -->
    
        <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
        
        <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
                   maxThreads="150" SSLEnabled="true">
            <SSLHostConfig>
                <Certificate certificateKeystoreFile="/Users/myuser/dev/keystore/keystore-dev.jks"
                  certificateKeyAlias="localhost" certificateKeystorePassword="localhost"
                             type="RSA" />
            </SSLHostConfig>
        </Connector>
    
        <!-- Define an AJP 1.3 Connector on port 8009 -->
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    
        <Engine name="Catalina" defaultHost="localhost">
    
          <!-- Use the LockOutRealm to prevent attempts to guess user passwords
               via a brute-force attack -->
          <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 &quot;%r&quot; %s %b" />
          </Host>
        </Engine>
      </Service>
    </Server>

If everything is configured ok, start your server and you will see in your logs something like this:

27-Feb-2020 02:15:14.234 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
27-Feb-2020 02:15:14.268 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-jsse-nio-8443"]
27-Feb-2020 02:15:14.473 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
27-Feb-2020 02:15:14.475 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [828] milliseconds
27-Feb-2020 02:15:14.500 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
27-Feb-2020 02:15:14.500 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.20]
....
27-Feb-2020 02:15:15.144 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
27-Feb-2020 02:15:15.158 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-jsse-nio-8443"]
27-Feb-2020 02:15:15.164 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
27-Feb-2020 02:15:15.166 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [690] milliseconds

After that, test your server locally from a browser or command line (with curl, wget, etc):

  1. https://localhost:8443/

  2. https://127.0.0.1:8443/

  3. https://YOUR_IP:8443/ (where YOUR_IP is your server IP, e.g. 192.168.0.1)

If your certificate is a self-signed certificate (for develop use) or is not signed by a trusted authority, you will get an error in your browser like this: “Your connection is not private” (e.g. ERR_CERT_AUTHORITY_INVALID). So you need to put your certificate in the trusted certificate store, accept to follow with your unsecure-certificate, or use a production ready certificate signed by a trusted authority (for more information about this: solve invalid SSL/TLS issue).

Bear in mind that by default the tomcat connector will listen all local server addresses.

For your information, if you want to restrict the binding IP addresses, the connector has an ‘address’ attribute that you can specify with the IP.

From Tomcat reference: docs

address

For servers with more than one IP address, this attribute specifies which address will be used for listening on the specified port. By default, the connector will listen all local addresses. Unless the JVM is configured otherwise using system properties, the Java based connectors (NIO, NIO2) will listen on both IPv4 and IPv6 addresses when configured with either 0.0.0.0 or ::. The APR/native connector will only listen on IPv4 addresses if configured with 0.0.0.0 and will listen on IPv6 addresses (and optionally IPv4 addresses depending on the setting of ipv6onlyv6) if configured with ::.

If you can’t access to your server locally with this urls provided, please provide your logs and error message.

Otherwise, if you are success accessing all this urls locally, try from a remote host:

  1. Check that server IP is accessible from remote terminal (e.g. ping)
  2. Try to access https://YOUR_IP:8443/ (and http://YOUR_IP:8080/) in a browser
  3. If you receive an error message “Your connection is not private”, press to see more details and accept to proceed unsafe. In this case, as commented before, check that your certificate is valid/not expired and the authority is in your trusted certificates.
  4. If you get another kind of error, check that your server and your remote client/pc has disabled firewall rules (both side) and check remote port access with telnet.
  5. Check your /etc/hosts and iptables configuration.
  6. If the problem persist, provide more info please.

Hope it helps,