acmesh-official / acme.sh

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

DNS TXT records automatically inserted by dns_ispconfig.sh have wrong serial #1198

Open tschachtner opened 6 years ago

tschachtner commented 6 years ago

Dear all,

i found some strange phenomenon when using the DNS API functions to automatically do a domain validation for my certificates using an ISPConfig DNS server.

When enrolling for a new certificate, the dns_ispconfig.sh script automatically inserts validation DNS TXT records on my ISPConfig DNS server which is hosting the DNS domain the certificate is meant for. Unfortunately, the following log entries are generated on the ISPConfig server after insertion:

named[xxxxx]: zone example.com/IN: zone serial (2018011622) unchanged. zone may fail to transfer to slaves.

After some debugging I found out, that the dns_ispconfig.sh is generating a serial based on the UNIX timestamp value of the current time. While this would be a perfect mechanism to generate a zone serial, ISPConfig is using a different method. They use YYYYMMDDxx (with xx being an automatically increasing rolling number) as serial number. ISPConfig's serial number starts with 2018..... whereas the serial inserted by dns_ispconfig.sh starts with 151.... which is smaller and thus the serial number of the zone is not increased. This means that the zone updates are not transferred to the slaves and the domain validation will fail in some cases (if acme.sh contacts one of the slave name servers).

I can think of two different solutions:

Steps to reproduce

  1. enroll a new certificate using acme.sh and DNS API script dns_ispconfig.sh for a zone that is managed by an ISPConfig DNS server

    /root/.acme.sh/acme.sh --issue --force --dns dns_ispconfig -d domain.example.com --test --debug

  2. check the syslog on the ISPConfig server. You will see above mentioned warning which means that the new zone updates are not sent to the slaves

  3. check the zone file's serial number. You will see that it was not changed by the dns_ispconfig.sh record insertion.

Debug log

ISPConfig syslog entry:
` named[xxxxx]: zone example.com/IN: zone serial (2018011622) unchanged. zone may fail to transfer to slaves. `

root@sv-zr02:~# /root/.acme.sh/acme.sh --issue --force --dns dns_ispconfig -d domain.example.com --test --debug
[Wed Jan 17 10:28:00 CET 2018] Lets find script dir.
[Wed Jan 17 10:28:00 CET 2018] _SCRIPT_='/root/.acme.sh/acme.sh'
[Wed Jan 17 10:28:00 CET 2018] _script='/root/.acme.sh/acme.sh'
[Wed Jan 17 10:28:00 CET 2018] _script_home='/root/.acme.sh'
[Wed Jan 17 10:28:00 CET 2018] Using config home:/root/.acme.sh
https://github.com/Neilpang/acme.sh
v2.7.6
[Wed Jan 17 10:28:00 CET 2018] Using config home:/root/.acme.sh
[Wed Jan 17 10:28:00 CET 2018] Using stage ACME_DIRECTORY: https://acme-staging.api.letsencrypt.org/directory
[Wed Jan 17 10:28:00 CET 2018] DOMAIN_PATH='/root/.acme.sh/domain.example.com'
[Wed Jan 17 10:28:00 CET 2018] Using ACME_DIRECTORY: https://acme-staging.api.letsencrypt.org/directory
[Wed Jan 17 10:28:00 CET 2018] _init api for server: https://acme-staging.api.letsencrypt.org/directory
[Wed Jan 17 10:28:00 CET 2018] GET
[Wed Jan 17 10:28:00 CET 2018] url='https://acme-staging.api.letsencrypt.org/directory'
[Wed Jan 17 10:28:00 CET 2018] timeout
[Wed Jan 17 10:28:01 CET 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header '
[Wed Jan 17 10:28:01 CET 2018] ret='0'
[Wed Jan 17 10:28:01 CET 2018] ACME_KEY_CHANGE='https://acme-staging.api.letsencrypt.org/acme/key-change'
[Wed Jan 17 10:28:01 CET 2018] ACME_NEW_AUTHZ='https://acme-staging.api.letsencrypt.org/acme/new-authz'
[Wed Jan 17 10:28:01 CET 2018] ACME_NEW_ORDER='https://acme-staging.api.letsencrypt.org/acme/new-cert'
[Wed Jan 17 10:28:01 CET 2018] ACME_NEW_ACCOUNT='https://acme-staging.api.letsencrypt.org/acme/new-reg'
[Wed Jan 17 10:28:01 CET 2018] ACME_REVOKE_CERT='https://acme-staging.api.letsencrypt.org/acme/revoke-cert'
[Wed Jan 17 10:28:01 CET 2018] ACME_AGREEMENT='https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf'
[Wed Jan 17 10:28:01 CET 2018] Le_NextRenewTime
[Wed Jan 17 10:28:01 CET 2018] _on_before_issue
[Wed Jan 17 10:28:01 CET 2018] Le_LocalAddress
[Wed Jan 17 10:28:01 CET 2018] Check for domain='domain.example.com'
[Wed Jan 17 10:28:01 CET 2018] _currentRoot='dns_ispconfig'
[Wed Jan 17 10:28:01 CET 2018] _saved_account_key_hash is not changed, skip register account.
[Wed Jan 17 10:28:01 CET 2018] Read key length:
[Wed Jan 17 10:28:01 CET 2018] _createcsr
[Wed Jan 17 10:28:02 CET 2018] Single domain='domain.example.com'
[Wed Jan 17 10:28:02 CET 2018] Getting domain auth token for each domain
[Wed Jan 17 10:28:02 CET 2018] Getting webroot for domain='domain.example.com'
[Wed Jan 17 10:28:02 CET 2018] _w='dns_ispconfig'
[Wed Jan 17 10:28:02 CET 2018] _currentRoot='dns_ispconfig'
[Wed Jan 17 10:28:02 CET 2018] Getting new-authz for domain='domain.example.com'
[Wed Jan 17 10:28:02 CET 2018] _init api for server: https://acme-staging.api.letsencrypt.org/directory
[Wed Jan 17 10:28:02 CET 2018] Try new-authz for the 0 time.
[Wed Jan 17 10:28:02 CET 2018] url='https://acme-staging.api.letsencrypt.org/acme/new-authz'
[Wed Jan 17 10:28:02 CET 2018] payload='{"resource": "new-authz", "identifier": {"type": "dns", "value": "domain.example.com"}}'
[Wed Jan 17 10:28:02 CET 2018] RSA key
[Wed Jan 17 10:28:02 CET 2018] GET
[Wed Jan 17 10:28:02 CET 2018] url='https://acme-staging.api.letsencrypt.org/directory'
[Wed Jan 17 10:28:02 CET 2018] timeout
[Wed Jan 17 10:28:02 CET 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header '
[Wed Jan 17 10:28:02 CET 2018] ret='0'
[Wed Jan 17 10:28:02 CET 2018] POST
[Wed Jan 17 10:28:02 CET 2018] url='https://acme-staging.api.letsencrypt.org/acme/new-authz'
[Wed Jan 17 10:28:02 CET 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header '
[Wed Jan 17 10:28:04 CET 2018] _ret='0'
[Wed Jan 17 10:28:04 CET 2018] code='201'
[Wed Jan 17 10:28:04 CET 2018] The new-authz request is ok.
[Wed Jan 17 10:28:04 CET 2018] entry='"type":"dns-01","status":"pending","uri":"https://acme-staging.api.letsencrypt.org/acme/challenge/9V3H6KvxQUpKL8J_ezmrw68XgaQC8UEeKGBV2j4jitQ/93368416","token":"7EaWvyXjNrZO_3dI0pFxtXA0TKqI4wFKf-YMrBPdoyE"'
[Wed Jan 17 10:28:04 CET 2018] token='7EaWvyXjNrZO_3dI0pFxtXA0TKqI4wFKf-YMrBPdoyE'
[Wed Jan 17 10:28:04 CET 2018] uri='https://acme-staging.api.letsencrypt.org/acme/challenge/9V3H6KvxQUpKL8J_ezmrw68XgaQC8UEeKGBV2j4jitQ/93368416'
[Wed Jan 17 10:28:04 CET 2018] keyauthorization='7EaWvyXjNrZO_3dI0pFxtXA0TKqI4wFKf-YMrBPdoyE.Go-_B8GpoC0r37tlUzkzAqsAswvY0jJXkll1XVHAyHE'
[Wed Jan 17 10:28:04 CET 2018] dvlist='domain.example.com#7EaWvyXjNrZO_3dI0pFxtXA0TKqI4wFKf-YMrBPdoyE.Go-_B8GpoC0r37tlUzkzAqsAswvY0jJXkll1XVHAyHE#https://acme-staging.api.letsencrypt.org/acme/challenge/9V3H6KvxQUpKL8J_ezmrw68XgaQC8UEeKGBV2j4jitQ/93368416#dns-01#dns_ispconfig'
[Wed Jan 17 10:28:04 CET 2018] vlist='domain.example.com#7EaWvyXjNrZO_3dI0pFxtXA0TKqI4wFKf-YMrBPdoyE.Go-_B8GpoC0r37tlUzkzAqsAswvY0jJXkll1XVHAyHE#https://acme-staging.api.letsencrypt.org/acme/challenge/9V3H6KvxQUpKL8J_ezmrw68XgaQC8UEeKGBV2j4jitQ/93368416#dns-01#dns_ispconfig,'
[Wed Jan 17 10:28:04 CET 2018] txtdomain='_acme-challenge.domain.example.com'
[Wed Jan 17 10:28:04 CET 2018] txt='TVieanMCfqkqRSgqy_3m_nXKVQc64b6efxl2zSchHfw'
[Wed Jan 17 10:28:04 CET 2018] d_api='/root/.acme.sh/dnsapi/dns_ispconfig.sh'
[Wed Jan 17 10:28:04 CET 2018] Found domain api file: /root/.acme.sh/dnsapi/dns_ispconfig.sh
[Wed Jan 17 10:28:04 CET 2018] Calling: dns_ispconfig_add() '_acme-challenge.domain.example.com' 'TVieanMCfqkqRSgqy_3m_nXKVQc64b6efxl2zSchHfw'
[Wed Jan 17 10:28:04 CET 2018] Getting Session ID
[Wed Jan 17 10:28:04 CET 2018] POST
[Wed Jan 17 10:28:04 CET 2018] url='https://url.of.ispconfig.com:8080/remote/json.php?login'
[Wed Jan 17 10:28:04 CET 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  --insecure  '
[Wed Jan 17 10:28:04 CET 2018] _ret='0'
[Wed Jan 17 10:28:04 CET 2018] Calling _ISPC_login: '{"username":"USERNAME","password":"PASSWORD","client_login":false}' 'https://url.of.ispconfig.com:8080/remote/json.php?login'
[Wed Jan 17 10:28:04 CET 2018] Result of _ISPC_login: '{"code":"ok","message":"","response":"511b0098b044e080e1a342277772ef14"}'
[Wed Jan 17 10:28:04 CET 2018] Retrieved Session ID.
[Wed Jan 17 10:28:04 CET 2018] Session ID: '511b0098b044e080e1a342277772ef14'
[Wed Jan 17 10:28:04 CET 2018] Getting Zoneinfo
[Wed Jan 17 10:28:04 CET 2018] POST
[Wed Jan 17 10:28:04 CET 2018] url='https://url.of.ispconfig.com:8080/remote/json.php?dns_zone_get'
[Wed Jan 17 10:28:04 CET 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  --insecure  '
[Wed Jan 17 10:28:05 CET 2018] _ret='0'
[Wed Jan 17 10:28:05 CET 2018] Calling _ISPC_getZoneInfo: '{"session_id":"511b0098b044e080e1a342277772ef14","primary_id":{"origin":"domain.example.com."}}' 'https://url.of.ispconfig.com:8080/remote/json.php?login'
[Wed Jan 17 10:28:05 CET 2018] Result of _ISPC_getZoneInfo: '{"code":"ok","message":"","response":[]}'
[Wed Jan 17 10:28:05 CET 2018] POST
[Wed Jan 17 10:28:05 CET 2018] url='https://url.of.ispconfig.com:8080/remote/json.php?dns_zone_get'
[Wed Jan 17 10:28:05 CET 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  --insecure  '
[Wed Jan 17 10:28:05 CET 2018] _ret='0'
[Wed Jan 17 10:28:05 CET 2018] Calling _ISPC_getZoneInfo: '{"session_id":"511b0098b044e080e1a342277772ef14","primary_id":{"origin":"dvintern.de."}}' 'https://url.of.ispconfig.com:8080/remote/json.php?login'
[Wed Jan 17 10:28:05 CET 2018] Result of _ISPC_getZoneInfo: '{"code":"ok","message":"","response":[{"id":"8","sys_userid":"3","sys_groupid":"3","sys_perm_user":"riud","sys_perm_group":"ru","sys_perm_other":"","server_id":"1","origin":"dvintern.de.","ns":"ns1.dvgruppe.de.","mbox":"server.it.dvimmobilien.de.","serial":"2018011621","refresh":"7200","retry":"540","expire":"604800","minimum":"3600","ttl":"3600","active":"Y","xfer":"212.77.180.2","also_notify":"","update_acl":"","dnssec_initialized":"Y","dnssec_wanted":"Y","dnssec_last_signed":"1516181281","dnssec_info":"DS-Records:\ndvintern.de.\t\tIN DS 15723 7 1 46EDB35C956BB83FE455E1EA2EEB6A876E1DB83B\ndvintern.de.\t\tIN DS 15723 7 2 6716E6C47F265AAB1F74241973F31B92F719E3C49F3B05FD5225167C B737E26D\n\n------------------------------------\n\nDNSKEY-Records:\n; This is a key-signing key, keyid 15723, for dvintern.de.\n; Created: 20170913080702 (Wed Sep 13 10:07:02 2017)\n; Publish: 20170913080702 (Wed Sep 13 10:07:02 2017)\n; Activate: 20170913080702 (Wed Sep 13 10:07:02 2017)\ndvintern.de. IN DNSKEY 257 3 7 AwEAAczAwVIcsJv1bv3ewLi4btvUoJBzNzekD4Ixx5VN0XK3OVBkyB0Z qVTj5vdl1GBfgrMsyb5JllbVnNxdIZJjpUcFERCe8KEdFNMFALqUMFrU B1baXpQRhZ2tpemBBX5kOn9uI2Y7xucNqbf6SdF7qwTsvhb3QV9NsCZ4 FSz2dHoNSiJFQjiDWjQPAqdvdjhZAH1fgwkQXkM+wkYMvh7lTxkJ7Aua W1Iw804r3DG24J6BoVDjxDO6RnZll26832UxzWlZFRMP44SijBWchf8a 5Iods74WJJUZsCjzxZj4ccgHHf1i0vsAEguXxcUfgXiURKwzbAFjGcsX m0XxdEb5ZY6frIxi9EOZW8dLjNZ2j7y3shJw\/ZHwQfIkwqi+dr8Fmfce D9nfyvyJNd5Sh6Q3PKzXLo1\/14OIFs4aeEhszREnGNcS4lDMSbbbviBc d6fwFRRR0LWRFPzOAK0t4JiVrCfWsPifwfRCSXiSv8m41Vq+yTduGK36 LPVM8i8BjgoQRKQR+jxtZ232ocqeSr2BU1g4aMZ7tyAXZ3+Rxp9KZHsx qcxDpKXPIfBt9JTRdv2XJN7h2KnVFPy2q4sSRPg3a7QpcoewwZxsnIP6 Y1X8eM8zR0QWynvbyrh0cH11CjeYUz7qTk01Aw98VaABQYDHDTxPn\/LK F41BprxZboDRgtt1\n\n\n; This is a zone-signing key, keyid 37223, for dvintern.de.\n; Created: 20170913080701 (Wed Sep 13 10:07:01 2017)\n; Publish: 20170913080701 (Wed Sep 13 10:07:01 2017)\n; Activate: 20170913080701 (Wed Sep 13 10:07:01 2017)\ndvintern.de. IN DNSKEY 256 3 7 AwEAAdAKDJHXPYzcSZq885MP34JMNC35hlnCnrBcGSK1jafYIzJ40B6+ zkc+Q76xFwfs8mqeen2PhmtYBlXNCXHsi8YskCE\/Poi0xhmnj9dRZQmx PrjKYCioI5E6qGjd1tD2RY+AROE5YEjpPAQbJnOULe75h99acjHrYJ6a 0lur\/l7BO7+XX828R5GqOtf2\/KXKMbN2mFLc593NG4qf\/84rLewjIkUd 6Kz0GVz5QsWx3cklFFMgMm+P+kU7rQ5wKHHTxllTYLNzeJPuQcd7S5AK \/tuumtbaIsI2iP+7Muif\/PDG6r50JUvOnirveolsIMI0sgH\/CmsSKU4A 2rLY7Po8iQs=\n\n\n"}]}'
[Wed Jan 17 10:28:05 CET 2018] Retrieved zone data.
[Wed Jan 17 10:28:05 CET 2018] Zone data: '{"code":"ok","message":"","response":[{"id":"8","sys_userid":"3","sys_groupid":"3","sys_perm_user":"riud","sys_perm_group":"ru","sys_perm_other":"","server_id":"1","origin":"dvintern.de.","ns":"ns1.dvgruppe.de.","mbox":"server.it.dvimmobilien.de.","serial":"2018011621","refresh":"7200","retry":"540","expire":"604800","minimum":"3600","ttl":"3600","active":"Y","xfer":"212.77.180.2","also_notify":"","update_acl":"","dnssec_initialized":"Y","dnssec_wanted":"Y","dnssec_last_signed":"1516181281","dnssec_info":"DS-Records:\ndvintern.de.\t\tIN DS 15723 7 1 46EDB35C956BB83FE455E1EA2EEB6A876E1DB83B\ndvintern.de.\t\tIN DS 15723 7 2 6716E6C47F265AAB1F74241973F31B92F719E3C49F3B05FD5225167C B737E26D\n\n------------------------------------\n\nDNSKEY-Records:\n; This is a key-signing key, keyid 15723, for dvintern.de.\n; Created: 20170913080702 (Wed Sep 13 10:07:02 2017)\n; Publish: 20170913080702 (Wed Sep 13 10:07:02 2017)\n; Activate: 20170913080702 (Wed Sep 13 10:07:02 2017)\ndvintern.de. IN DNSKEY 257 3 7 AwEAAczAwVIcsJv1bv3ewLi4btvUoJBzNzekD4Ixx5VN0XK3OVBkyB0Z qVTj5vdl1GBfgrMsyb5JllbVnNxdIZJjpUcFERCe8KEdFNMFALqUMFrU B1baXpQRhZ2tpemBBX5kOn9uI2Y7xucNqbf6SdF7qwTsvhb3QV9NsCZ4 FSz2dHoNSiJFQjiDWjQPAqdvdjhZAH1fgwkQXkM+wkYMvh7lTxkJ7Aua W1Iw804r3DG24J6BoVDjxDO6RnZll26832UxzWlZFRMP44SijBWchf8a 5Iods74WJJUZsCjzxZj4ccgHHf1i0vsAEguXxcUfgXiURKwzbAFjGcsX m0XxdEb5ZY6frIxi9EOZW8dLjNZ2j7y3shJw\/ZHwQfIkwqi+dr8Fmfce D9nfyvyJNd5Sh6Q3PKzXLo1\/14OIFs4aeEhszREnGNcS4lDMSbbbviBc d6fwFRRR0LWRFPzOAK0t4JiVrCfWsPifwfRCSXiSv8m41Vq+yTduGK36 LPVM8i8BjgoQRKQR+jxtZ232ocqeSr2BU1g4aMZ7tyAXZ3+Rxp9KZHsx qcxDpKXPIfBt9JTRdv2XJN7h2KnVFPy2q4sSRPg3a7QpcoewwZxsnIP6 Y1X8eM8zR0QWynvbyrh0cH11CjeYUz7qTk01Aw98VaABQYDHDTxPn\/LK F41BprxZboDRgtt1\n\n\n; This is a zone-signing key, keyid 37223, for dvintern.de.\n; Created: 20170913080701 (Wed Sep 13 10:07:01 2017)\n; Publish: 20170913080701 (Wed Sep 13 10:07:01 2017)\n; Activate: 20170913080701 (Wed Sep 13 10:07:01 2017)\ndvintern.de. IN DNSKEY 256 3 7 AwEAAdAKDJHXPYzcSZq885MP34JMNC35hlnCnrBcGSK1jafYIzJ40B6+ zkc+Q76xFwfs8mqeen2PhmtYBlXNCXHsi8YskCE\/Poi0xhmnj9dRZQmx PrjKYCioI5E6qGjd1tD2RY+AROE5YEjpPAQbJnOULe75h99acjHrYJ6a 0lur\/l7BO7+XX828R5GqOtf2\/KXKMbN2mFLc593NG4qf\/84rLewjIkUd 6Kz0GVz5QsWx3cklFFMgMm+P+kU7rQ5wKHHTxllTYLNzeJPuQcd7S5AK \/tuumtbaIsI2iP+7Muif\/PDG6r50JUvOnirveolsIMI0sgH\/CmsSKU4A 2rLY7Po8iQs=\n\n\n"}]}'
[Wed Jan 17 10:28:05 CET 2018] Server ID: '1'
[Wed Jan 17 10:28:05 CET 2018] Retrieved Server ID
[Wed Jan 17 10:28:05 CET 2018] Zone: '8'
[Wed Jan 17 10:28:05 CET 2018] Retrieved Zone ID
[Wed Jan 17 10:28:05 CET 2018] Client ID: '3'
[Wed Jan 17 10:28:05 CET 2018] Retrieved Client ID.
[Wed Jan 17 10:28:05 CET 2018] POST
[Wed Jan 17 10:28:06 CET 2018] url='https://url.of.ispconfig.com:8080/remote/json.php?dns_txt_add'
[Wed Jan 17 10:28:06 CET 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  --insecure  '
[Wed Jan 17 10:28:06 CET 2018] _ret='0'
[Wed Jan 17 10:28:06 CET 2018] Calling _ISPC_addTxt: '{"session_id":"511b0098b044e080e1a342277772ef14","client_id":"3","params":{"server_id":"1","zone":"8","name":"_acme-challenge.domain.example.com.","type":"txt","data":"TVieanMCfqkqRSgqy_3m_nXKVQc64b6efxl2zSchHfw","aux":"0","ttl":"3600","active":"y","stamp":"2018-01-17 10:28:05","serial":"1516181285"}}' 'https://url.of.ispconfig.com:8080/remote/json.php?dns_txt_add'
[Wed Jan 17 10:28:06 CET 2018] Result of _ISPC_addTxt: '{"code":"ok","message":"","response":"454"}'
[Wed Jan 17 10:28:06 CET 2018] Record ID: '454'
[Wed Jan 17 10:28:06 CET 2018] Added ACME Challenge TXT record to zone.
Neilpang commented 6 years ago

@sjau do you have any comments ?

sjau commented 6 years ago

DNS Zone Serial is not handled by the API so nothing to change there... never encountered that issue but I don't use multi-server setup.

Please also post your complete zone file info. I noticed when there's already an acme txt entry it doesn't work.

tschachtner commented 6 years ago

We've seen that the serial number that is used when inserting the TXT record using ISPConfig's remote API is not used for the DNS zone's serial creation. We've already filed a bug report to the ISPConfig team and wait for their response.

sjau commented 6 years ago

Does the master reload the zone with the new added TXT record?

tschachtner commented 6 years ago

Yes, exactly. The master is reloading the zone including the newly created records. But as the zone serial number is not increased, the changes are not replicated to the slave servers. Depending on whether the acme.sh script checks the master or the slave server, the DNS-01 domain check either succeeds or fails. I guess that everything is working fine in a “one DNS server only” scenario.

sjau commented 6 years ago

acme.sh does not have any influence which NS server is being checked by Let's Encrypt. They check one of the NS servers listed in the zone file IIRC.

tschachtner commented 6 years ago

that explains what we currently see. But if this is not fixed and the zone update is not transferred to the slave DNS servers, one cannot reliably use the automated dns registration on ISPConfig systems. I hope the ISPConfig guys are taking care of this quite soon. IMO, DNS update functions do not really make sense if the zone's serial number is not updated.

sjau commented 6 years ago

Well, I also set the limit to 120 seconds before telling LE because ISPC does run it's updater every minute and 1 minute might just not be enough to propagate everything. But for the rest it's up to Timmo Falke and the ISPC Team.

AlphaDE commented 6 years ago

I have the same problem since switching to a master-slave structure of my dns servers. Before, having ispconfig in control of all name servers, the serial did not affect the slaves. But with that above change, the serial needs to be increased so the slave name servers recognize the change in the zone. If I run acme and make a web interface based change to that zone during the wait time, the TXT record gets transmitted and acme finishes sucessful. The api allows to update the zone record including the serial. As the serial should (in case of several changes) only changed once and not everytime, a record change does not automatically trigger a serial change. That's up to the developer of the program using the api.

The zone update function allows to change the serial. The serial is already available, it just needs to get incremented and written back into the zone record again.

I found this elsewhere to properly update the serial but I am more a c/php and not a bash developer.

DATE=$(date +%Y%m%d)
# we're looking line containing this comment
NEEDLE="Serial"
curr=$(/bin/grep -e "${NEEDLE}$" $ZONES_PATH/${ZONE} | /bin/sed -n "s/^\s*\([0-9]*\)\s*;\s*${NEEDLE}\s*/\1/p")
    # replace if current date is shorter (possibly using different format)
    if [ ${#curr} -lt ${#DATE} ]; then
      serial="${DATE}00"
    else
      prefix=${curr::-2}
      if [ "$DATE" -eq "$prefix" ]; then # same day
        num=${curr: -2} # last two digits from serial number
        num=$((10#$num + 1)) # force decimal representation, increment
        serial="${DATE}$(printf '%02d' $num )" # format for 2 digits
      else
        serial="${DATE}00" # just update date
      fi
    fi
    /bin/sed -i -e "s/^\(\s*\)[0-9]\{0,\}\(\s*;\s*${NEEDLE}\)$/\1${serial}\2/" ${ZONES_PATH}/${ZONE}

In php it would look like

function increase_serial($serial) {
                $serial_date = intval(substr($serial, 0, 8));
                $count = intval(substr($serial, 8, 2));
                $current_date = date("Ymd");
                if($serial_date >= $current_date){
                        $count += 1;
                        if ($count > 99) {
                                $serial_date += 1;
                                $count = 0;
                        }
                        $count = str_pad($count, 2, "0", STR_PAD_LEFT);
                        $new_serial = $serial_date.$count;
                } else {
                        $new_serial = $current_date.'01';
                }
                return $new_serial;
        }

and

$soa = $client->dns_zone_get($session_id, ID);

$soa['serial']=increase_serial($soa['serial']);

<updates in the zone>

$client->dns_zone_update($session_id, CLIENT_ID, ID, $soa); 

the zone get is already performed by the script, so it just needs to increment the zone and write it back, leaving the rest (ns, email, ...) unchanged.

Neilpang commented 6 years ago

@sjau

AlphaDE commented 6 years ago

@Neilpang Any chance to add the update of the serial?

Neilpang commented 6 years ago

@AlphaDE Sorry, I'm not familiar with ispconfig at all. Let's see what @sjau comment.

Thanks.

tschachtner commented 6 years ago

@Neilpang @sjau I'm not an expert on ispconfig or acme.sh, either, but I've proposed a change which might not be the final solution, but maybe help @sjau to update the script...

Please feel free to delete my change request if it does not make sense at all... here's the proposal

Thanks Tom

sjau commented 6 years ago

I only had a brief look at it but looks good so far.

This would only be a temporary suggestion. It seems the the devs at ISPC are also willing to add a zone incremental thing directly through the api:

https://www.howtoforge.com/community/threads/remote-user-api-what-does-dns-zone-functions-do.78079/#post-370541 & https://www.howtoforge.com/community/threads/remote-user-api-what-does-dns-zone-functions-do.78079/#post-370548

AlphaDE commented 6 years ago

@tschachtner One remark...

newZoneSerial=$((curSerialOld + 1))

will mostly work... but you should add a check for the casse that the last two digits are 99. In the case the new serial is composed by increasing to the following day (based on the day presently in the serial) and the counter is 00.

kordianbruck commented 6 years ago

An serial update option was just added to ispconfig 3.1.12: https://git.ispconfig.org/ispconfig/ispconfig3/issues/4806

So a fix for this should be easy now.

Edit: PR is up :tada: