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.";
|
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 {
|
domain = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "Domain under which this host is registered.";
|
description = "Domain under which this host is registered.";
|
||||||
|
@ -55,6 +61,8 @@ in {
|
||||||
description = "Interface with which this host communicates with the larger internet.";
|
description = "Interface with which this host communicates with the larger internet.";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# FIXME: take the relevant SSH package
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -85,8 +93,9 @@ in {
|
||||||
StandardOutput = "journal";
|
StandardOutput = "journal";
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
};
|
};
|
||||||
|
path = [ pkgs.openssh ];
|
||||||
script = ''
|
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 = {
|
||||||
users = {
|
users = {
|
||||||
backplane-powerdns = {
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
backplane-dns = {
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
fudo-client = {
|
fudo-client = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
groups = {
|
|
||||||
backplane-powerdns = {
|
|
||||||
members = [ "backplane-powerdns" ];
|
|
||||||
};
|
|
||||||
backplane-dns = {
|
|
||||||
members = [ "backplane-dns" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fudo = {
|
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 = {
|
client.dns = {
|
||||||
enable = true;
|
enable = true;
|
||||||
ipv4 = true;
|
ipv4 = true;
|
||||||
ipv6 = true;
|
ipv6 = true;
|
||||||
domain = "dyn.fudo.org";
|
|
||||||
user = "fudo-client";
|
user = "fudo-client";
|
||||||
external-interface = "eno2";
|
external-interface = "eno2";
|
||||||
password-file = "/srv/client/secure/client.passwd";
|
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 = {
|
secure-dns-proxy = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 3535;
|
port = 3535;
|
||||||
|
|
|
@ -42,6 +42,11 @@ OptionParser.new do |opts|
|
||||||
"Check for a public IPv6 and register with the backplane.") do
|
"Check for a public IPv6 and register with the backplane.") do
|
||||||
options[:ipv6] = true
|
options[:ipv6] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
opts.on("-f", "--sshfp",
|
||||||
|
"Register host SSH key fingerprints with the backplane.") do
|
||||||
|
options[:sshfp] = true
|
||||||
|
end
|
||||||
end.parse!
|
end.parse!
|
||||||
|
|
||||||
def error(msg)
|
def error(msg)
|
||||||
|
@ -98,10 +103,12 @@ class XMPPClient
|
||||||
def send(msg_content)
|
def send(msg_content)
|
||||||
msg_id = SecureRandom::uuid
|
msg_id = SecureRandom::uuid
|
||||||
encoded_payload = payload(msg_content, msg_id).to_json
|
encoded_payload = payload(msg_content, msg_id).to_json
|
||||||
|
puts "payload: #{encoded_payload}"
|
||||||
msg = Jabber::Message.new(@service_jid, encoded_payload)
|
msg = Jabber::Message.new(@service_jid, encoded_payload)
|
||||||
msg.type = :chat
|
msg.type = :chat
|
||||||
@client.send(msg)
|
@client.send(msg)
|
||||||
response = receive_response(msg_id)
|
response = receive_response(msg_id)
|
||||||
|
puts "response: #{response}"
|
||||||
response and response["status"] == "OK"
|
response and response["status"] == "OK"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -109,6 +116,10 @@ class XMPPClient
|
||||||
send(ip_payload(ip))
|
send(ip_payload(ip))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_sshfp(fps)
|
||||||
|
send(sshfp_payload(fps))
|
||||||
|
end
|
||||||
|
|
||||||
def payload(req, msg_id)
|
def payload(req, msg_id)
|
||||||
{
|
{
|
||||||
version: 1,
|
version: 1,
|
||||||
|
@ -126,6 +137,14 @@ class XMPPClient
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sshfp_payload(fp)
|
||||||
|
{
|
||||||
|
request: :change_sshfp,
|
||||||
|
domain: @domain,
|
||||||
|
sshfp: fp
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def register_response_callback
|
def register_response_callback
|
||||||
@client.add_message_callback do |msg|
|
@client.add_message_callback do |msg|
|
||||||
enqueue_message(JSON.parse(msg.body))
|
enqueue_message(JSON.parse(msg.body))
|
||||||
|
@ -198,6 +217,13 @@ def interface_addresses(interface)
|
||||||
end
|
end
|
||||||
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],
|
client = XMPPClient::new(options[:domain],
|
||||||
Socket::gethostname,
|
Socket::gethostname,
|
||||||
options[:server],
|
options[:server],
|
||||||
|
@ -243,6 +269,21 @@ begin
|
||||||
puts "#{options[:server]}: no valid public IPv6 found on the local host"
|
puts "#{options[:server]}: no valid public IPv6 found on the local host"
|
||||||
end
|
end
|
||||||
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
|
ensure
|
||||||
client.disconnect
|
client.disconnect
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue