acmesh-official / acme.sh

A pure Unix shell script implementing ACME client protocol
https://acme.sh
GNU General Public License v3.0
38.64k stars 4.91k forks source link

On OpenBSD acme.sh fails to tell nc/socat to listen for IPv6 traffic #5065

Open stolendata opened 6 months ago

stolendata commented 6 months ago

When the domain requested for issuing/renewal has an AAAA (IPv6) record, Let's Encrypt will proceed using IPv6 connectivity instead of IPv4. Consequently, acme.sh must be told to accept inbound IPv6 connections, but on OpenBSD the --listen-v6 option doesn't seem to have any effect. Providing a --local-address ..., whether ::/0 or the host's actual IPv6 address, makes no difference either. Instead acme.sh still tells nc/socat to do only IPv4 and fails to accommodate Let's Encrypt's connection attempts, causing the issuing/renewal to fail.

Temporarily removing the AAAA record from the domain solves the problem, but this is obviously disruptive and not an acceptable or sustainable solution.

Add.: when the invocation below is running I've confirmed with netstat/fstat that acme.sh is indeed listening on an IPv4 TCP socket, but nothing on IPv6, contrary to what it has explicitly been told to do.

Steps to reproduce

./acme.sh --standalone --listen-v6 --local-address '2601:56:XXXX:XXXX::1234' --httpport 1080 --renew --domain some.domain

Debug log

[Sat Mar 23 19:24:26 UTC 2024] Le_LocalAddress='0.0.0.0,'   <--
[Sat Mar 23 19:24:26 UTC 2024] d='my.domain'
[Sat Mar 23 19:24:26 UTC 2024] Check for domain='some.domain'
[Sat Mar 23 19:24:26 UTC 2024] _currentRoot='no'
[Sat Mar 23 19:24:26 UTC 2024] Standalone mode.
[Sat Mar 23 19:24:27 UTC 2024] _checkport='1080'
[Sat Mar 23 19:24:27 UTC 2024] _checkaddr='0.0.0.0'   <--
[Sat Mar 23 19:24:27 UTC 2024] Using: netstat
...
[Sat Mar 23 19:24:27 UTC 2024] seg='some'
[Sat Mar 23 19:24:27 UTC 2024] _is_idn_d='some.domain'
[Sat Mar 23 19:24:27 UTC 2024] _idn_temp
[Sat Mar 23 19:24:27 UTC 2024] d
[Sat Mar 23 19:24:27 UTC 2024] _identifiers='{"type":"dns","value":"some.domain"}'
...
[Sat Mar 23 19:24:34 UTC 2024] Standalone mode server
[Sat Mar 23 19:24:34 UTC 2024] content='<<REMOVED>>'
[Sat Mar 23 19:24:34 UTC 2024] ncaddr='0.0.0.0'   <--
[Sat Mar 23 19:24:34 UTC 2024] startserver: 46283
[Sat Mar 23 19:24:34 UTC 2024] Le_HTTPPort='1080'
[Sat Mar 23 19:24:34 UTC 2024] Le_Listen_V4='1'
[Sat Mar 23 19:24:34 UTC 2024] Le_Listen_V6='1'
[Sat Mar 23 19:24:34 UTC 2024] _content_len='      87'
[Sat Mar 23 19:24:34 UTC 2024] _NC='socat -4 -d -d -v TCP-LISTEN:1080,crlf,reuseaddr,fork,bind=0.0.0.0'   <--
2024/03/23 19:24:34 socat[45575] N listening on LEN=16 AF=2 0.0.0.0:1080   <--
[Sat Mar 23 19:24:35 UTC 2024] serverproc='45575'

...

socat:
socat by Gerhard Rieger and contributors - see www.dest-unreach.org
socat version 1.7.4.1 on Oct  5 2023 16:07:08
   running on OpenBSD version GENERIC.MP#2, release 7.4, machine amd64
features:
  #define WITH_STDIO 1
  #define WITH_FDNUM 1
  #define WITH_FILE 1
  #define WITH_CREAT 1
  #define WITH_GOPEN 1
  #define WITH_TERMIOS 1
  #define WITH_PIPE 1
  #define WITH_UNIX 1
  #undef WITH_ABSTRACT_UNIXSOCKET
  #define WITH_IP4 1
  #define WITH_IP6 1
  #define WITH_RAWIP 1
  #define WITH_GENERICSOCKET 1
  #undef WITH_INTERFACE
  #define WITH_TCP 1
  #define WITH_UDP 1
  #define WITH_SCTP 1
  #define WITH_LISTEN 1
  #define WITH_SOCKS4 1
  #define WITH_SOCKS4A 1
  #undef WITH_VSOCK
  #define WITH_PROXY 1
  #define WITH_SYSTEM 1
  #define WITH_EXEC 1
  #define WITH_READLINE 1
  #undef WITH_TUN
  #define WITH_PTY 1
  #define WITH_OPENSSL 1
  #undef WITH_FIPS
  #undef WITH_LIBWRAP
  #define WITH_SYCLS 1
  #define WITH_FILAN 1
  #define WITH_RETRY 1
  #define WITH_MSGLEVEL 0 /*debug*/
github-actions[bot] commented 6 months ago

Please upgrade to the latest code and try again first. Maybe it's already fixed. acme.sh --upgrade If it's still not working, please provide the log with --debug 2, otherwise, nobody can help you.

stolendata commented 6 months ago

It looks like --local-address doesn't populate _ncaddr correctly, so the setting never makes it into _startserver().