Skip to content

Commit

Permalink
Add support for mx records on subdomains
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-hellhake authored and benfrancis committed Oct 8, 2024
1 parent 3b2aada commit d2f3b59
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 16 deletions.
5 changes: 4 additions & 1 deletion config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ caa_records = [
"0 issue \"letsencrypt.org\"",
]
mx_records = [
"10 inbound-smtp.us-west-2.amazonaws.com",
# mydomain.org
["@", "10 inbound-smtp.us-west-2.amazonaws.com"],
# mail.mydomain.org
["mail", "10 mail.inbound-smtp.us-west-2.amazonaws.com"],
]
ns_records = [
[ "ns1.mydomain.org.", "5.6.7.8" ],
Expand Down
5 changes: 4 additions & 1 deletion src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ fn test_args() {
assert_eq!(args.pdns.caa_records, ["0 issue \"letsencrypt.org\"",]);
assert_eq!(
args.pdns.mx_records,
["10 inbound-smtp.us-west-2.amazonaws.com"]
[
("@".to_owned(), "10 inbound-smtp.us-west-2.amazonaws.com".to_owned()),
("mail".to_owned(), "10 mail.inbound-smtp.us-west-2.amazonaws.com".to_owned())
]
);
assert_eq!(
args.pdns.ns_records,
Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub struct PdnsOptions {
pub tunnel_ttl: u32,
pub api_ttl: u32,
pub caa_records: Vec<String>,
pub mx_records: Vec<String>,
pub mx_records: Vec<(String,String)>,
pub ns_records: Vec<Vec<String>>,
pub txt_records: Vec<Vec<String>>,
pub cname_records: Vec<Vec<String>>,
Expand Down
56 changes: 43 additions & 13 deletions src/pdns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,18 +217,20 @@ fn build_ns_response(qname: &str, config: &Config) -> Vec<PdnsLookupResponse> {
}

// Returns an MX record for a given qname.
fn build_mx_response(qname: &str, config: &Config) -> Vec<PdnsLookupResponse> {
fn build_mx_response(qname: &str, is_bare_domain: bool, subdomain: &str, config: &Config) -> Vec<PdnsLookupResponse> {
let mut records = vec![];
for mx in &config.options.pdns.mx_records {
records.push(PdnsLookupResponse {
qtype: "MX".to_owned(),
qname: qname.to_owned(),
content: mx.to_owned(),
ttl: config.options.pdns.dns_ttl,
domain_id: None,
scope_mask: None,
auth: None,
});
for (domain, mx) in &config.options.pdns.mx_records {
if domain == subdomain || (domain == "@" && is_bare_domain) {
records.push(PdnsLookupResponse {
qtype: "MX".to_owned(),
qname: qname.to_owned(),
content: mx.to_owned(),
ttl: config.options.pdns.dns_ttl,
domain_id: None,
scope_mask: None,
auth: None,
});
}
}

records
Expand Down Expand Up @@ -452,6 +454,7 @@ fn handle_lookup(req: PdnsRequest, config: &Config) -> Result<PdnsResponse, Stri
return handle_pagekite_query(&qname, &qtype, config);
}
let bare_domain = format!("{}.", domain);
let is_bare_domain = qname == bare_domain;

// If the qname starts with `_acme-challenge.` this is a DNS-01 challenge verification, so
// remove that part of the domain to retrieve our record.
Expand Down Expand Up @@ -479,9 +482,9 @@ fn handle_lookup(req: PdnsRequest, config: &Config) -> Result<PdnsResponse, Stri
}
}

if qname == bare_domain && (qtype == "MX" || qtype == "ANY") {
if qtype == "MX" || qtype == "ANY" {
// Add "MX" records.
for record in build_mx_response(&original_qname, config) {
for record in build_mx_response(&original_qname, is_bare_domain, subdomain, config) {
result.push(PdnsResponseParams::Lookup(record));
}
}
Expand Down Expand Up @@ -995,6 +998,33 @@ mod tests {
})
);

// MX query
let request = build_lookup(
"lookup",
Some("MX"),
Some("mail.mydomain.org."),
None,
);
let body = serde_json::to_string(&request).unwrap();
stream.write_all(body.as_bytes()).unwrap();
stream.write_all(b"\n").unwrap();

let len = stream.read(&mut answer).unwrap();
let response: serde_json::Value = serde_json::from_slice(&answer[..len]).unwrap();
assert_json_eq!(
response,
json!({
"result": [
{
"qtype": "MX",
"qname": "mail.mydomain.org.",
"content": "10 mail.inbound-smtp.us-west-2.amazonaws.com",
"ttl": 86400,
}
],
})
);

// PSL query
let request = build_lookup("lookup", Some("TXT"), Some("_psl.mydomain.org."), None);
let body = serde_json::to_string(&request).unwrap();
Expand Down

0 comments on commit d2f3b59

Please sign in to comment.