Working backplane dns client/server
This commit is contained in:
parent
3165c259bc
commit
80be04edd5
|
@ -20,6 +20,12 @@ in {
|
|||
description = "Report host external IPv6 address to Fudo DynDNS server.";
|
||||
};
|
||||
|
||||
sshfp = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Report host SSH fingerprints to the Fudo DynDNS server.";
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = "Domain under which this host is registered.";
|
||||
|
@ -55,6 +61,8 @@ in {
|
|||
description = "Interface with which this host communicates with the larger internet.";
|
||||
default = null;
|
||||
};
|
||||
|
||||
# FIXME: take the relevant SSH package
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
@ -85,8 +93,9 @@ in {
|
|||
StandardOutput = "journal";
|
||||
User = cfg.user;
|
||||
};
|
||||
path = [ pkgs.openssh ];
|
||||
script = ''
|
||||
${pkgs.backplane-dns-client}/bin/backplane-dns-client ${optionalString cfg.ipv4 "-4"} ${optionalString cfg.ipv6 "-6"} ${optionalString (cfg.external-interface != null) "--interface=${cfg.external-interface}"} --domain=${cfg.domain} --server=${cfg.server} --password-file=${cfg.password-file}
|
||||
${pkgs.backplane-dns-client}/bin/backplane-dns-client ${optionalString cfg.ipv4 "-4"} ${optionalString cfg.ipv6 "-6"} ${optionalString cfg.sshfp "-f"} ${optionalString (cfg.external-interface != null) "--interface=${cfg.external-interface}"} --domain=${cfg.domain} --server=${cfg.server} --password-file=${cfg.password-file}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
|
@ -100,146 +100,22 @@ in {
|
|||
|
||||
users = {
|
||||
users = {
|
||||
backplane-powerdns = {
|
||||
isSystemUser = true;
|
||||
};
|
||||
backplane-dns = {
|
||||
isSystemUser = true;
|
||||
};
|
||||
fudo-client = {
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
|
||||
groups = {
|
||||
backplane-powerdns = {
|
||||
members = [ "backplane-powerdns" ];
|
||||
};
|
||||
backplane-dns = {
|
||||
members = [ "backplane-dns" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fudo = {
|
||||
password.file-generator = {
|
||||
dns_backplane_powerdns = {
|
||||
file = "/srv/backplane/dns/secure/db_powerdns.passwd";
|
||||
user = config.services.postgresql.superUser;
|
||||
group = "backplane-powerdns";
|
||||
restart-services = [
|
||||
"backplane-dns-config-generator.service"
|
||||
"postgresql-password-setter.service"
|
||||
"backplane-powerdns.service"
|
||||
];
|
||||
};
|
||||
dns_backplane_database = {
|
||||
file = "/srv/backplane/dns/secure/db_backplane.passwd";
|
||||
user = config.services.postgresql.superUser;
|
||||
group = "backplane-dns";
|
||||
restart-services = [
|
||||
"backplane-dns.service"
|
||||
"postgresql-password-setter.service"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
backplane.dns = {
|
||||
enable = true;
|
||||
port = 353;
|
||||
listen-addresses = [ "10.0.0.1" ];
|
||||
required-services = [ "fudo-passwords.target" ];
|
||||
user = "backplane-dns";
|
||||
group = "backplane-dns";
|
||||
database = {
|
||||
username = "backplane_powerdns";
|
||||
database = "backplane_dns";
|
||||
# Uses an IP to avoid cyclical dependency...not really relevant, but
|
||||
# whatever
|
||||
host = "127.0.0.1";
|
||||
password-file = "/srv/backplane/dns/secure/db_powerdns.passwd";
|
||||
};
|
||||
backplane = {
|
||||
host = "backplane.fudo.org";
|
||||
role = "service-dns";
|
||||
password-file = "/srv/backplane/dns/secure/backplane.passwd";
|
||||
database = {
|
||||
username = "backplane_dns";
|
||||
database = "backplane_dns";
|
||||
host = "127.0.0.1";
|
||||
password-file = "/srv/backplane/dns/secure/db_backplane.passwd";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
client.dns = {
|
||||
enable = true;
|
||||
ipv4 = true;
|
||||
ipv6 = true;
|
||||
domain = "dyn.fudo.org";
|
||||
user = "fudo-client";
|
||||
external-interface = "eno2";
|
||||
password-file = "/srv/client/secure/client.passwd";
|
||||
};
|
||||
|
||||
postgresql = {
|
||||
enable = true;
|
||||
ssl-private-key = "/srv/nostromo/certs/private/privkey.pem";
|
||||
ssl-certificate = "/srv/nostromo/certs/cert.pem";
|
||||
keytab = "/srv/nostromo/keytabs/postgres.keytab";
|
||||
required-services = [ "fudo-passwords.target" ];
|
||||
|
||||
local-networks = [
|
||||
"10.0.0.1/24"
|
||||
"127.0.0.1/8"
|
||||
];
|
||||
|
||||
users = {
|
||||
backplane_powerdns = {
|
||||
password-file = "/srv/backplane/dns/secure/db_powerdns.passwd";
|
||||
databases = {
|
||||
backplane_dns = {
|
||||
access = "CONNECT";
|
||||
entity-access = {
|
||||
"ALL TABLES IN SCHEMA public" = "SELECT";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
backplane_dns = {
|
||||
password-file = "/srv/backplane/dns/secure/db_backplane.passwd";
|
||||
databases = {
|
||||
backplane_dns = {
|
||||
access = "CONNECT";
|
||||
entity-access = {
|
||||
"ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE";
|
||||
"ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
niten = {
|
||||
databases = {
|
||||
backplane_dns = {
|
||||
access = "ALL PRIVILEGES";
|
||||
entity-access = {
|
||||
"ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
|
||||
"ALL SEQUENCES IN SCHEMA public" = "ALL PRIVILEGES";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
local-users = ["niten"];
|
||||
|
||||
databases = {
|
||||
backplane_dns = {
|
||||
users = ["niten"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
secure-dns-proxy = {
|
||||
enable = true;
|
||||
port = 3535;
|
||||
|
|
|
@ -42,6 +42,11 @@ OptionParser.new do |opts|
|
|||
"Check for a public IPv6 and register with the backplane.") do
|
||||
options[:ipv6] = true
|
||||
end
|
||||
|
||||
opts.on("-f", "--sshfp",
|
||||
"Register host SSH key fingerprints with the backplane.") do
|
||||
options[:sshfp] = true
|
||||
end
|
||||
end.parse!
|
||||
|
||||
def error(msg)
|
||||
|
@ -98,10 +103,12 @@ class XMPPClient
|
|||
def send(msg_content)
|
||||
msg_id = SecureRandom::uuid
|
||||
encoded_payload = payload(msg_content, msg_id).to_json
|
||||
puts "payload: #{encoded_payload}"
|
||||
msg = Jabber::Message.new(@service_jid, encoded_payload)
|
||||
msg.type = :chat
|
||||
@client.send(msg)
|
||||
response = receive_response(msg_id)
|
||||
puts "response: #{response}"
|
||||
response and response["status"] == "OK"
|
||||
end
|
||||
|
||||
|
@ -109,6 +116,10 @@ class XMPPClient
|
|||
send(ip_payload(ip))
|
||||
end
|
||||
|
||||
def send_sshfp(fps)
|
||||
send(sshfp_payload(fps))
|
||||
end
|
||||
|
||||
def payload(req, msg_id)
|
||||
{
|
||||
version: 1,
|
||||
|
@ -126,6 +137,14 @@ class XMPPClient
|
|||
}
|
||||
end
|
||||
|
||||
def sshfp_payload(fp)
|
||||
{
|
||||
request: :change_sshfp,
|
||||
domain: @domain,
|
||||
sshfp: fp
|
||||
}
|
||||
end
|
||||
|
||||
def register_response_callback
|
||||
@client.add_message_callback do |msg|
|
||||
enqueue_message(JSON.parse(msg.body))
|
||||
|
@ -198,6 +217,13 @@ def interface_addresses(interface)
|
|||
end
|
||||
end
|
||||
|
||||
def host_sshfp
|
||||
keys = `ssh-keygen -r hostname`.split("\n").map do |k|
|
||||
k.match(/[0-9] [0-9] [a-fA-F0-9]{32,64}$/)[0]
|
||||
end
|
||||
keys.compact
|
||||
end
|
||||
|
||||
client = XMPPClient::new(options[:domain],
|
||||
Socket::gethostname,
|
||||
options[:server],
|
||||
|
@ -243,6 +269,21 @@ begin
|
|||
puts "#{options[:server]}: no valid public IPv6 found on the local host"
|
||||
end
|
||||
end
|
||||
|
||||
if options[:sshfp]
|
||||
fps = host_sshfp
|
||||
if not fps.empty?
|
||||
puts "#{options[:server]}: #{Socket::gethostname}.#{options[:domain]} IN SSHFP => #{fps}"
|
||||
if client.send_sshfp(fps)
|
||||
puts "OK"
|
||||
else
|
||||
puts "ERROR"
|
||||
success = false
|
||||
end
|
||||
else
|
||||
puts "#{options[:server]}: no valid sshfps found"
|
||||
end
|
||||
end
|
||||
ensure
|
||||
client.disconnect
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue