Skip to content

Instantly share code, notes, and snippets.

@wttw
Created March 26, 2017 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wttw/8f075763f0fbd01352c3d8a85ef67249 to your computer and use it in GitHub Desktop.
Save wttw/8f075763f0fbd01352c3d8a85ef67249 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
use DBI;
use Net::DNS;
my @slaves = ('216.189.157.158');
my $cmd = $ARGV[0];
if($cmd eq 'deploy_challenge') {
my $dom = $ARGV[1];
my $token = $ARGV[3];
my $key = "_acme-challenge.$dom";
my $dbh = DBI->connect("dbi:Pg:dbname=pdns", "steve", "", {RaiseError => 1, AutoCommit => 0}) or die $DBI::errstr;
eval {
my ($domid, $domname) = $dbh->selectrow_array("select id, name from domains where ? like '%' || name order by length(name) desc limit 1", {}, $dom);
die "Domain $dom not found\n" unless defined $domid;
$dbh->do("delete from records where domain_id=? and type='TXT' and name=?", {}, $domid, $key);
my $ordername = substr($key, 0, -length($domname));
$ordername =~ s/\./ /;
$dbh->do("insert into records (domain_id, name, type, content, ttl, ordername) values (?, ?, 'TXT', ?, 60, ?)", {}, $domid, $key, $token, $ordername);
$dbh->commit;
};
if($@) {
my $err = $@;
$dbh->rollback;
$dbh->disconnect;
die $err;
}
$dbh->disconnect;
warn "Update done\n";
SLAVE: foreach my $slave (@slaves) {
my $res = new Net::DNS::Resolver(
nameservers => [$slave],
recurse => 0
);
my $attempts = 300;
while($attempts--) {
warn "attempt: $attempts\n";
my $reply = $res->query($key, 'TXT');
if ($reply) {
foreach my $rr (grep {$_->type eq 'TXT'} $reply->answer) {
if($rr->txtdata eq $token) {
warn "Got valid token from slave\n";
next SLAVE;
}
}
}
sleep 1;
}
}
}
if($cmd eq 'clean_challenge') {
exit 0;
my $dom = $ARGV[1];
my $token = $ARGV[3];
my $key = "_acme-challenge.$dom";
my $dbh = DBI->connect("dbi:Pg:dbname=pdns", "steve", "", {RaiseError => 1, AutoCommit => 0}) or die $DBI::errstr;
eval {
my ($domid, $domname) = $dbh->selectrow_array("select id, name from domains where ? like '%' || name order by length(name) desc limit 1", {}, $dom);
die "Domain $dom not found\n" unless defined $domid;
$dbh->do("delete from records where domain_id=? and type='TXT' and name=?", {}, $domid, $key);
$dbh->commit;
};
if($@) {
my $err = $@;
$dbh->rollback;
$dbh->disconnect;
die $err;
}
$dbh->disconnect;
}
if($cmd eq 'deploy_cert') {
my $dom = $ARGV[1];
my $keyfile = $ARGV[2];
my $certfile = $ARGV[3];
my $fullchainfile = $ARGV[4];
my $chainfile = $ARGV[5];
exit 0 if $dom =~ /^satsuke/;
my @args=('/usr/bin/ssh', '-o', 'StrictHostKeyChecking=no', 'certmaster@' . $dom, 'mkdir', '-p', $dom);
system(@args) == 0 or die "system @args failed: $?\n";
@args=('/usr/bin/scp', $keyfile, 'certmaster@' . "$dom:$dom/privkey.pem");
system(@args) == 0 or die "system @args failed: $?\n";
@args=('/usr/bin/scp', $fullchainfile, 'certmaster@' . "$dom:$dom/fullchain.pem");
system(@args) == 0 or die "system @args failed: $?\n";
@args=('/usr/bin/ssh', '-t', 'certmaster@' . $dom, 'sudo', '/bin/bash', '/home/certmaster/certcopy.sh');
system(@args) == 0 or die "system @args failed: $?\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment