mirror of
https://github.com/anikeen-com/yaac.git
synced 2026-03-19 00:26:14 +00:00
Merge branch 'master' of https://github.com/lordelph/yaac into lordelph-master
This commit is contained in:
47
README.md
47
README.md
@@ -116,6 +116,53 @@ foreach ($authorizations as $authorization) {
|
|||||||
The method above will perform 15 attempts to ask LetsEncrypt to validate the challenge (with 1 second intervals) and
|
The method above will perform 15 attempts to ask LetsEncrypt to validate the challenge (with 1 second intervals) and
|
||||||
retrieve an updated status (it might take Lets Encrypt a few seconds to validate the challenge).
|
retrieve an updated status (it might take Lets Encrypt a few seconds to validate the challenge).
|
||||||
|
|
||||||
|
### Alternative ownership validation via DNS
|
||||||
|
|
||||||
|
You can also use DNS validation - to do this, you will need access to an API for your DNS
|
||||||
|
provider to create TXT records for the target domains.
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
//store a map of domain=>TXT record we can use to wait with
|
||||||
|
$dnsRecords[];
|
||||||
|
|
||||||
|
foreach ($authorizations as $authorization) {
|
||||||
|
$challenge = $authorization->getDnsChallenge();
|
||||||
|
|
||||||
|
$txtRecord = $authorization->getTxtRecord($challenge);
|
||||||
|
|
||||||
|
$domain=$authorization->getDomain();
|
||||||
|
$validationDomain='_acme-challenge.'.$domain;
|
||||||
|
|
||||||
|
//remember the record we're about to set
|
||||||
|
$dnsRecords[$validationDomain] = $txtRecord;
|
||||||
|
|
||||||
|
//set TXT record for $validationDomain to $txtRecord value
|
||||||
|
//--
|
||||||
|
//-- you need to add code for your DNS provider here
|
||||||
|
//--
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
A helper is included which will allow you to wait until you can see the
|
||||||
|
DNS changes before asking Let's Encrypt to validate it, e.g.
|
||||||
|
|
||||||
|
```php
|
||||||
|
//wait up to 60 seconds for all our DNS updates to propagate
|
||||||
|
if (!Helper::waitForDNS($dnsRecords, 60)) {
|
||||||
|
throw new \Exception('Unable to verify TXT record update');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Once this passes we can ask Let's Encrypt to do the same...
|
||||||
|
|
||||||
|
```php
|
||||||
|
foreach ($authorizations as $authorization) {
|
||||||
|
$ok = $client->validate($authorization->getDnsChallenge(), 15);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Get the certificate
|
### Get the certificate
|
||||||
|
|
||||||
Now to know if validation was successful, test if the order is ready as follows:
|
Now to know if validation was successful, test if the order is ready as follows:
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ class Client
|
|||||||
*/
|
*/
|
||||||
const VALIDATION_HTTP = 'http-01';
|
const VALIDATION_HTTP = 'http-01';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DNS validation
|
||||||
|
*/
|
||||||
|
const VALIDATION_DNS = 'dns-01';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace Afosto\Acme\Data;
|
namespace Afosto\Acme\Data;
|
||||||
|
|
||||||
use Afosto\Acme\Client;
|
use Afosto\Acme\Client;
|
||||||
|
use Afosto\Acme\Helper;
|
||||||
|
|
||||||
class Authorization
|
class Authorization
|
||||||
{
|
{
|
||||||
@@ -78,6 +79,20 @@ class Authorization
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Challenge|bool
|
||||||
|
*/
|
||||||
|
public function getDnsChallenge()
|
||||||
|
{
|
||||||
|
foreach ($this->getChallenges() as $challenge) {
|
||||||
|
if ($challenge->getType() == Client::VALIDATION_DNS) {
|
||||||
|
return $challenge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Challenge $challenge
|
* @param Challenge $challenge
|
||||||
* @return File|bool
|
* @return File|bool
|
||||||
@@ -90,4 +105,15 @@ class Authorization
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Challenge $challenge
|
||||||
|
* @return string containing TXT record for DNS challenge
|
||||||
|
*/
|
||||||
|
public function getTxtRecord(Challenge $challenge)
|
||||||
|
{
|
||||||
|
$raw=$challenge->getToken() . '.' . $this->digest;
|
||||||
|
$hash=hash('sha256', $raw, true);
|
||||||
|
return Helper::toSafeString($hash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,4 +135,37 @@ class Helper
|
|||||||
|
|
||||||
return $accountDetails;
|
return $accountDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait until a set of DNS records return specific TXT record values
|
||||||
|
*
|
||||||
|
* @param array mapping domain to desired TXT record value
|
||||||
|
* @param $txtRecord
|
||||||
|
* @param int $maxSeconds to wait
|
||||||
|
* @return bool true if record found, false otherwise
|
||||||
|
*/
|
||||||
|
public static function waitForDNS(array $records, $maxSeconds=60)
|
||||||
|
{
|
||||||
|
$waitUntil = time() + $maxSeconds;
|
||||||
|
|
||||||
|
do {
|
||||||
|
//validate all remaining records..
|
||||||
|
foreach($records as $domain=>$txtRecord) {
|
||||||
|
$record=dns_get_record($domain, DNS_TXT);
|
||||||
|
if (isset($record[0]['txt']) && ($record[0]['txt']===$txtRecord)) {
|
||||||
|
unset($records[$domain]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//did we find them all?
|
||||||
|
if (empty($records)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//otherwise still domains to check...have a short sleep
|
||||||
|
sleep(1);
|
||||||
|
} while(time() < $waitUntil);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user