Letsencrypt certificate with Tomcat and Certbot connection refused

Thanks :slight_smile:

So I tried to use

sudo certbot certonly --standalone --preferred-challenges http-01 -d nombritech.pl -d www.nombritech.pl

and I get something like this:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for nombritech.pl
http-01 challenge for www.nombritech.pl
Cleaning up challenges
Problem binding to port 80: Could not bind to IPv4 or IPv6.

I would like Certbot to create the mentioned temporary web server on port 80. Is my Tomcat configuration now messing something with this or the command I’m using is wrong?

Hello,

The command is correct, but it looks like something may already be listening on port 80.

You can list what is listening with:

sudo ss -tlnp

You can try check what the reason for the inability to listen is by installing netcat/nc and trying:

sudo nc -vvv -l -p80

It’s also possible that Tomcat is already listening on port 80, but you have a firewall rule blocking access to it from the outside internet.

Hello and thank you :slight_smile:

I think that Tomcat is listening:

LISTEN 0 100 :::80 :::* users:(("java",pid=7199,fd=37))

Maybe it is then blocked by firewall, I’ve already tried to unlock ports in iptables, but maybe I did something wrong:

root@vps366782:~# sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8443 -j ACCEPT
-A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A FORWARD -i virbr0 -o virbr0 -j ACCEPT
-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT

Your firewall is definitely misconfigured. For example, your Postgres server is currently exposed to the internet, which I am guessing is not consistent with your intent.

I can suggest firewalld or ufw as high level/user-friendly alternatives to using iptables raw.

Okay, thanks I choose UFW :wink:

I reset my rules and added some basic just for now to do this certificate. This is my configuration:

root@vps366782:~# sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
443/tcp                    ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
22                         ALLOW IN    Anywhere
443/tcp (v6)               ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
22 (v6)                    ALLOW IN    Anywhere (v6)

I also changed Tomcat configuration to the previous one as I still had the same error as previous with port binding and now I have this again:

Failed authorization procedure. www.nombritech.pl (http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching https://www.nombritech.pl:8443/.well-known/acme-challenge/LerD9kbZV3mJmqVftnPinrrb0FBgJ4eFLcSU9mspmnY: Invalid port in redirect target. Only ports 80 and 443 are supported, not 8443, nombritech.pl (http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching https://nombritech.pl:8443/.well-known/acme-challenge/pf5jkeqBKOW4Ibw1rXUma6qwWguX45Z68_V_qEuMXRY: Invalid port in redirect target. Only ports 80 and 443 are supported, not 8443

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: www.nombritech.pl
   Type:   connection
   Detail: Fetching
   https://www.nombritech.pl:8443/.well-known/acme-challenge/LerD9kbZV3mJmqVftnPinrrb0FBgJ4eFLcSU9mspmnY:
   Invalid port in redirect target. Only ports 80 and 443 are
   supported, not 8443

   Domain: nombritech.pl
   Type:   connection
   Detail: Fetching
   https://nombritech.pl:8443/.well-known/acme-challenge/pf5jkeqBKOW4Ibw1rXUma6qwWguX45Z68_V_qEuMXRY:
   Invalid port in redirect target. Only ports 80 and 443 are
   supported, not 8443

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

My Tomcat server.xml right now:

<?xml version="1.0" encoding="UTF-8"?>

<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />

  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />

  <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="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
	
	    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" 
               KeystoreFile="/home/tomcat/.keystore"
	       keystorePass="pass" />
		   
		   <Connector executor="tomcatThreadPool" port="443" protocol="HTTP/1.1" 
		   redirectPort="8443" scheme="https" secure="true" SSLEnabled="true" KeystoreFile="/home/tomcat/.keystore"
	       keystorePass="pass">
			</Connector>

    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <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 &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

What should I do now? :frowning: Something is missconfigured, that was not only the firewall I guess…

With your current error, the problem is the redirect to port 8443 - it is not acceptable for Let’s Encrypt:

$ curl -i nombritech.pl/.well-known/acme-challenge/haha
HTTP/1.1 302
Cache-Control: private
Expires: Thu, 01 Jan 1970 01:00:00 CET
Location: https://nombritech.pl:8443/.well-known/acme-challenge/haha

You may only redirect to port 80 or 443 if you want the webroot challenge to succeed.

I believe the solution would be to configure Tomcat to instead redirect to the 443 HTTPS listener.

I think this is the problem:

redirectPort="8443"

Change that to port 80 443, restart Tomcat, and run a curl test to ensure that it is correctly redirecting to 443.

should have searched JKS :wink:

walk through the whole article

Andrei

Still nothing, I’m getting only this:

Problem binding to port 80: Could not bind to IPv4 or IPv6.

For the last few hours I’ve been trying to configure Tomcat properly, this is what I ended with right now:

  <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000"/>
	  
  <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" KeystoreFile="/home/tomcat/.keystore" keystorePass="pass" />
  
root@vps366782:/opt/tomcat/bin# curl -i nombritech.pl/.well-known/acme-challenge/haha
HTTP/1.1 302
Cache-Control: private
Expires: Thu, 01 Jan 1970 01:00:00 CET
Location: https://nombritech.pl/.well-known/acme-challenge/haha
Content-Length: 0
Date: Tue, 19 Dec 2017 02:34:39 GMT

And when I’m checking what is on this port it says that Tomcat… I don’t understand what is going on at all

@ahaw021 This is my last certificate that has already expired, thank you for the article I’m looking at it just now

I had no idea that it is so hard to configure it with only Tomcat aboard :frowning:

With tomcat properly configured you will need to use your original command:

sudo certbot certonly --webroot -w /opt/tomcat/webapps -d domain.pl -d www.domain.pl

Additionally, most examples use /opt/tomcat/webapps/ROOT as the webroot. Both should work but using the ROOT webapp makes sure tomcat doesn’t waste time spinning up a .well-known webapp.

Hey, thanks, I’ve just came up with the same idea and tried that:

root@vps366782:/opt/tomcat/bin# sudo certbot certonly --webroot -w /opt/tomcat/webapps -d nombritech.pl -d www.nombritech.pl --staging
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for nombritech.pl
http-01 challenge for www.nombritech.pl
Using the webroot path /opt/tomcat/webapps for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. nombritech.pl (http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://nombritech.pl/.well-known/acme-challenge/owdPQNAyRJPiWt7hE4HIWxQ4Oi9siZMgHOJdYlPbznA: Timeout

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: nombritech.pl
   Type:   connection
   Detail: Fetching
   http://nombritech.pl/.well-known/acme-challenge/owdPQNAyRJPiWt7hE4HIWxQ4Oi9siZMgHOJdYlPbznA:
   Timeout

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

EDIT:

With ROOT like this?:

root@vps366782:/opt/tomcat/bin# sudo certbot certonly --webroot -w /opt/tomcat/webapps/ROOT -d nombritech.pl -d www.nombritech.pl --staging
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for nombritech.pl
http-01 challenge for www.nombritech.pl
Using the webroot path /opt/tomcat/webapps/ROOT for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. www.nombritech.pl (http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://www.nombritech.pl/.well-known/acme-challenge/Xd_JkF5-GC_bNFon9-6Ls1Ec8PCnX6V1CQrJduMB5YA: Timeout, nombritech.pl (http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://nombritech.pl/.well-known/acme-challenge/49T3ia5rKl9GOtJU-3ioE1KTKVa1j2dNVg01fynZWPQ: Timeout

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: www.nombritech.pl
   Type:   connection
   Detail: Fetching
   http://www.nombritech.pl/.well-known/acme-challenge/Xd_JkF5-GC_bNFon9-6Ls1Ec8PCnX6V1CQrJduMB5YA:
   Timeout

   Domain: nombritech.pl
   Type:   connection
   Detail: Fetching
   http://nombritech.pl/.well-known/acme-challenge/49T3ia5rKl9GOtJU-3ioE1KTKVa1j2dNVg01fynZWPQ:
   Timeout

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.
root@vps366782:/opt/tomcat/bin#

Tomcat doesn’t seem to be running/listening on port 80 anymore - I can’t curl it.

Tomcat needs to be running when you run that Certbot command.

I’m restarting it right now because I found out I have something like this in web.xml:

	<security-constraint>
  <web-resource-collection>
    <web-resource-name>Viewpoint Secure URLs</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
<user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

I change it to NONE maybe this is stopping http but I think this connector with 80 simply doesn’t work…

I’m getting something like this in catalina.out:

19-Dec-2017 03:59:27.040 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-80"]
19-Dec-2017 03:59:27.075 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector[HTTP/1.1-80]]
 org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:935)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:530)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:852)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:622)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:645)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:309)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: java.net.BindException: Address already in use
        at java.base/sun.nio.ch.Net.bind0(Native Method)
        at java.base/sun.nio.ch.Net.bind(Net.java:433)
        at java.base/sun.nio.ch.Net.bind(Net.java:425)
        at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:225)
        at java.base/sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
        at org.apache.tomcat.util.net.NioEndpoint.initServerSocket(NioEndpoint.java:227)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:202)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1042)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:540)
        at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:70)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:932)
        ... 13 more

19-Dec-2017 03:59:27.080 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-jsse-nio-443"]
19-Dec-2017 03:59:27.085 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector[HTTP/1.1-443]]
 org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:935)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:530)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:852)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:622)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:645)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:309)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: java.net.BindException: Address already in use
        at java.base/sun.nio.ch.Net.bind0(Native Method)
        at java.base/sun.nio.ch.Net.bind(Net.java:433)
        at java.base/sun.nio.ch.Net.bind(Net.java:425)
        at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:225)
        at java.base/sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
        at org.apache.tomcat.util.net.NioEndpoint.initServerSocket(NioEndpoint.java:227)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:202)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1042)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:540)
        at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:70)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:932)
        ... 13 more

but Tomcat is starting and working despite of this

my 5 cents

leave tomcat configs alone

8080 pointing to 8443 and 8443 confgured with SSL

run the standalone version of certbot which will temporarily stand up a web server to answer the challenge on port 80 or 443 (which are not in use by tomcat)

Tomcat roots are a bit harder then what patches describes which is whyI usually use the DNS challenge or standalone

Andrei

I don’t know why but it worked when I did like this:

root@vps366782:/opt/tomcat/bin# sudo certbot certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
-------------------------------------------------------------------------------
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
Plugins selected: Authenticator standalone, Installer None
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): nombritech.pl www.nombritech.pl
Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for nombritech.pl
tls-sni-01 challenge for www.nombritech.pl
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/nombritech.pl/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/nombritech.pl/privkey.pem
   Your cert will expire on 2018-03-19. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

So using certbot certonly command without arguments seems to be working… now I have to figure it out how to connect this with Tomcat and check if it’s working :slight_smile:

@ahaw021 I don’t know if it had any impact but I changed it like you said, but it didn’t work any other way

when you are feeling bored read up on this: https://www.digitalocean.com/community/tutorials/how-to-use-certbot-standalone-mode-to-retrieve-let-s-encrypt-ssl-certificates

Andrei

FINALLY WORKED :smile:

Thank all of you very very much :slight_smile: I spent the whole night trying to set this up and I’m so happy I finally managed to do it with your help

@ahaw021 I used your tutorial to convert .pem to .keystore and added this to tomcat :slight_smile:

I would like to give the exact solution what was wrong with the configuration at the beginning in case someone came across something similar to this, but I don’t know it myself why it did work when I called the Certbot without any arguments… Maybe the problem was complex and many factors had impact on that: firewall, tomcat configuration and so on… :slight_smile:

read the whole chain

sounds like a mixture of many parts not working as well as they could have been

its always worthwhile getting this kind of feedback as it helps others help you

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.