Skip to content

Instantly share code, notes, and snippets.

@alserom
Created February 27, 2019 17:22
Show Gist options
  • Save alserom/bfacbbd9f3e20c245848da3845c1c64b to your computer and use it in GitHub Desktop.
Save alserom/bfacbbd9f3e20c245848da3845c1c64b to your computer and use it in GitHub Desktop.
Certbot. Pre and Post Validation Hooks for https://www.ukraine.com.ua
<?php
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/sendRequest.function.php';
$domain = getenv('CERTBOT_DOMAIN');
$validation = getenv('CERTBOT_VALIDATION');
if ($domain === false || $validation === false) {
throw new \Exception('CERTBOT_DOMAIN or CERTBOT_VALIDATION does not exists in environment');
}
function createRecord()
{
global $validation;
$data = [
'subdomain' => '_acme-challenge',
'type' => 'TXT',
'data' => $validation
];
return sendRequest('dns_record', 'create', $data);
}
function getNs()
{
return sendRequest('dns_ns', 'info');
}
function dnsIsUpdated($nsList)
{
global $domain, $validation;
$hosts = [];
foreach ($nsList as $host) {
$values = [];
$cmd = sprintf('dig @%s -t txt _acme-challenge.%s +short', $host, $domain);
exec($cmd, $values);
array_walk($values, function(&$value) {
$value = trim($value, '"');
});
$isUpdated = in_array($validation, $values, true);
echo sprintf('%s: %s%s', $host, $isUpdated ? 'Yes' : 'No', PHP_EOL);
$hosts[$host] = $isUpdated;
}
return in_array(false, $hosts, true) === false;
}
try {
$id = createRecord();
$nsList = getNs();
$checksNum = 0;
echo 'Checking that DNS record was updated on authority NS server...' . PHP_EOL;
do {
sleep(WAITING_PERIOD);
$checksNum++;
echo sprintf('Trying #%s from %s:%s', $checksNum, MAX_CHEKS, PHP_EOL);
$isUpdated = dnsIsUpdated($nsList);
if ($checksNum === MAX_CHEKS) {
break;
}
} while (!$isUpdated);
echo json_encode(['status' => 'ok', 'data' => $id]) . PHP_EOL;
} catch (\Exception $ex) {
echo json_encode(['status' => 'error', 'data' => $ex->getMessage()]) . PHP_EOL;
}
?>
<?php
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/sendRequest.function.php';
$domain = getenv('CERTBOT_DOMAIN');
$authOutput= getenv('CERTBOT_AUTH_OUTPUT');
if ($domain === false || $authOutput === false) {
throw new \Exception('CERTBOT_DOMAIN or CERTBOT_AUTH_OUTPUT does not exists in environment');
}
function deleteRecord()
{
global $authOutput;
$lines = explode(PHP_EOL, $authOutput);
$lastOutput = end($lines);
$authResult = json_decode($lastOutput, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Exception('Error: ' . json_last_error_msg());
}
if ($authResult['status'] === 'error') {
throw new \Exception('Error: ' . $authResult['data']);
}
$data = [
'stack' => [$authResult['data']]
];
return sendRequest('dns_record', 'delete', $data);
}
try {
deleteRecord();
} catch (\Exception $ex) {
echo $ex->getMessage() . PHP_EOL;
}
?>
<?php
const API_URL = 'https://adm.tools/api.php';
const AUTH_LOGIN = '';
const AUTH_TOKEN = '';
const WAITING_PERIOD = 20;
const MAX_CHEKS = 6;
?>
<?php
function sendRequest($class, $method, $additional = [])
{
global $domain;
$fields = array_merge($additional, [
'auth_login' => AUTH_LOGIN,
'auth_token' => AUTH_TOKEN,
'format' => 'json',
'class' => $class,
'method' => $method,
'domain' => $domain
]);
$ch = curl_init(API_URL);
curl_setopt_array($ch, [
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($fields)
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new \Exception($error);
}
if (200 !== $status) {
throw new \Exception('Bad request: ' . $status);
}
$response = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Exception('Error: ' . json_last_error_msg());
}
if ('error' === $response['status']) {
throw new \Exception('Error: ' . $response['message']);
}
return $response['data'];
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment