Unable to satisfy acme challenges for domain: no viable challenge type found

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. crt.sh | example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:
www.elephorum.com

I ran this command:
sudo go run . &
then try to connect to the server through my browser

It produced this output:
2022/05/25 23:02:24 http: TLS handshake error from 185.169.255.84:39716: acme/autocert: unable to satisfy "https://acme-v02.api.letsencrypt.org/acme/authz-v3/112566445456" for domain "elephorum.com": no viable challenge type found
2022/05/25 23:02:24 http: TLS handshake error from 185.169.255.84:40034: acme/autocert: missing certificate

My web server is (include version):
go 1.17

The operating system my web server runs on is (include version):
ubuntu-2004-focal-v20220419

My hosting provider, if applicable, is:
Google GCP Compute Engine

I can login to a root shell on my machine (yes or no, or I don't know):
yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel):
no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot):
no

sudo go run what exactly?

Also, I don't fully understand autocert.. The authorization is deactivated, which is something only an ACME client can do (if the ACME server disabled the authz, it would have been called "revoked"). But all the challenges of the authz are still "pending", so nothing has been done with them! They were apparently not triggered to perform the challenge at all. And all three possible challenges are there: there are no other challenges currently available.

So I don't understand why autocert is complaining. It should either have used the authz and not deactivate it and use one of the challenges. Or ignore the deactivated authz and generate a new one?

3 Likes

Thanks for the reply.

sudo go run . is kind of the same as sudo go run main.go, which is to run the func main() {...} found in the current directory.

So now the problem is to figure out how to tell autocert to activate authorization.

...and what is "the current directory"? How would you expect any of us to have any idea what software you're trying to run?

No, it isn't. Go is a programming language, not a web server.

4 Likes

Well, I'd have to hack the server of OP, search for every main.go file present and check every file manually to see if it has any relationship with Let's Encrypt at all :roll_eyes: Surely not impossible.

2 Likes

Looking at https://cs.opensource.google/go/x/crypto/+/793ad666:acme/autocert/autocert.go;l=731-739, it's hard for me to think of a situation where that error condition would realistically be raised. The tls-alpn-01 challenge should always available, and it's present in that deactivated authz.

I wonder if something went horribly wrong with the assumption that code makes about nextTyp being consistent between authorizations. My memory is very foggy but I think Boulder deletes unused challenges once an authorization becomes valid. An order which was created with mixed cached valid/pending authorizations may break autocert's assumptions.

I'm gonna vote for "autocert bug", not that it especially helps OP.

4 Likes

Sorry guys, I am new to go and developing websites.

So when I have logged in to the VM instance I have created on GCP, and connected to it through ssh, I just run sudo go run . & in the directory containing the code of the server, and a main.go file.
In the main.go, I have imported "golang.org/x/crypto/acme/autocert", created an autocert.Manager with Prompt, HostPolicy, and Cache fields filled in.
Then I created two threads, one with HTTPHandler(nil), listening and serving at port 80, another thread listening and serving the real content of my website with at port 443.

So I have no idea what web server I am running except it is written in go 1.17.
Would you mind giving me some example of what you are expecting for My web server is (include version):? Is it something like Apache, or Nginx? I am not using any of those.

"None" is also a valid answer.

So the application ultimately raising this error is a main.go file written by yourself? That would have been helpful from the start.

It might not reveal anything, but could you please share the contents of main.go and any relevant other code?

4 Likes

I see.

Yes, of course, thanks for taking time to read my code.

main.go code:

package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"net/http"

	"golang.org/x/crypto/acme/autocert"
)

func MyGetCertificate(man *autocert.Manager) func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
	return func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
		hello.ServerName = "www.elephorum.com"
		fmt.Printf("https ClientHelloInfo's ServerName: %s\n", hello.ServerName)
		return man.GetCertificate(hello)
	}
}

func main() {
	dir := "./certs"
	certMan := &autocert.Manager{
		Prompt:     autocert.AcceptTOS,
		HostPolicy: autocert.HostWhitelist("www.elephorum.com"),
		Cache: autocert.DirCache(dir),
	}
	go func() {
		httpServer := MakeServer()
		httpServer.Addr = ":80"
		httpServer.Handler = certMan.HTTPHandler(nil)

		err := httpServer.ListenAndServe()
		if err != nil {
			log.Fatal(err)
		}
	}()

	mux := http.NewServeMux()
	mux.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets"))))
	mux.Handle("/",RateLimiter(HomeHandler))

	httpsServer := MakeServer()
	httpsServer.Addr = ":443"
	httpsServer.Handler = mux

	// write a custom GetCertificate func and put a ServerName into the ClientHelloInfo
	manTlsConfig := certMan.TLSConfig()
	manTlsConfig.GetCertificate = MyGetCertificate(certMan)
	httpsServer.TLSConfig = manTlsConfig

	fmt.Println("Starting server at port 443")
	err := httpsServer.ListenAndServeTLS("", "")
	if err != nil {
		log.Fatal(err)
	}
}

MakeServer code:

import (
	"net/http"
	"time"
)

func MakeServer() http.Server {
	return http.Server{
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 5 * time.Second,
		IdleTimeout:  120 * time.Second,
	}
}

What's this about?:

curl -Ii www.elephorum.com
HTTP/1.1 301 Moved Permanently
Location: https://35.246.110.156/
Date: Thu, 26 May 2022 18:16:11 GMT
Content-Type: text/html; charset=UTF-8
Server: ghs
Content-Length: 220
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

curl -Ii www.elephorum.com/.well-known/acme-challenge/Test_File-1234
HTTP/1.1 301 Moved Permanently
Location: https://35.246.110.156/
Date: Thu, 26 May 2022 18:17:01 GMT
Content-Type: text/html; charset=UTF-8
Server: ghs
Content-Length: 220
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

LE won't follow redirects to IP addresses

3 Likes

Oh, that maybe the cause of the problem.
Thanks, will try to fix this and mark it as the solution if it is really the problem!

1 Like

Yes, this is the problem, thank you very much!!

But now I am presented with another errors:
tls handshake error connection reset by peer
and
tls: client requested unsupported application protocols

2022/05/27 13:40:54 http: TLS handshake error from 107.178.231.244:52963: read tcp 10.154.0.4:443->107.178.231.244:52963: read: connection reset by peer
2022/05/27 13:40:54 http: TLS handshake error from 107.178.231.244:22025: read tcp 10.154.0.4:443->107.178.231.244:22025: read: connection reset by peer
2022/05/27 13:40:55 http: TLS handshake error from 107.178.231.244:33103: read tcp 10.154.0.4:443->107.178.231.244:33103: read: connection reset by peer
2022/05/27 13:40:55 http: TLS handshake error from 107.178.231.244:46247: tls: client requested unsupported application protocols ([http/0.9 http/1.0 spdy/1 spdy/2 spdy/3 h2c hq])
2022/05/27 13:40:55 http: TLS handshake error from 107.178.231.244:39541: tls: client requested unsupported application protocols ([hq h2c spdy/3 spdy/2 spdy/1 http/1.0 http/0.9])
1 Like

Oh it's fine now!
Everything's working
Thanks everyone!

1 Like