bootstrap project
This commit is contained in:
parent
75ea6f92b1
commit
1a238ea01f
8 changed files with 1777 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/target
|
||||
|
||||
config.toml
|
1433
Cargo.lock
generated
Normal file
1433
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "nomilo"
|
||||
version = "0.1.0-dev"
|
||||
authors = ["Gaël Berthaud-Müller <blacksponge@tuta.io>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
trust-dns-client = "0.20.1"
|
||||
trust-dns-proto = "0.20.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
rocket = "0.4.7"
|
||||
rocket_contrib = { version = "0.4", default-features = false, features = ["json"]}
|
||||
toml = "0.5"
|
2
config.example.toml
Normal file
2
config.example.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
[dns_server]
|
||||
address = "127.0.0.1:53"
|
21
src/config.rs
Normal file
21
src/config.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::fs;
|
||||
|
||||
use serde::{Deserialize};
|
||||
use toml;
|
||||
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Config {
|
||||
pub dns_server: DnsServerConfig
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct DnsServerConfig {
|
||||
pub address: SocketAddr
|
||||
}
|
||||
|
||||
pub fn load(file_name: PathBuf) -> Config {
|
||||
toml::from_str(&fs::read_to_string(file_name).expect("could not read config file")).expect("could not parse config file")
|
||||
}
|
40
src/main.rs
Normal file
40
src/main.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
#![feature(proc_macro_hygiene, decl_macro)]
|
||||
use std::str::FromStr;
|
||||
|
||||
#[macro_use] extern crate rocket;
|
||||
use rocket::State;
|
||||
use rocket_contrib::json::Json;
|
||||
|
||||
use trust_dns_client::client::{Client, SyncClient};
|
||||
use trust_dns_client::tcp::TcpClientConnection;
|
||||
use trust_dns_client::op::DnsResponse;
|
||||
use trust_dns_client::rr::{DNSClass, Name, Record, RecordType};
|
||||
|
||||
mod types;
|
||||
mod config;
|
||||
|
||||
|
||||
#[get("/zones/<zone>/records")]
|
||||
fn zone_records(client: State<SyncClient<TcpClientConnection>>, zone: String) -> Json<Vec<types::dns::Record>> {
|
||||
// TODO: Implement FromParam for Name
|
||||
let name = Name::from_str(&zone).unwrap();
|
||||
|
||||
// TODO: add support for all trust-dns record types
|
||||
// then use AXFR here and filter out dnssec related fields
|
||||
let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::AAAA).unwrap();
|
||||
let answers: &[Record] = response.answers();
|
||||
let records: Vec<types::dns::Record> = answers.to_vec().into_iter().map(|record| record.into()).collect();
|
||||
|
||||
Json(records)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let app_config = config::load("config.toml".into());
|
||||
|
||||
let conn = TcpClientConnection::new(app_config.dns_server.address).unwrap();
|
||||
let client = SyncClient::new(conn);
|
||||
|
||||
rocket::ignite()
|
||||
.manage(client)
|
||||
.mount("/api/v1", routes![zone_records]).launch();
|
||||
}
|
261
src/types/dns.rs
Normal file
261
src/types/dns.rs
Normal file
|
@ -0,0 +1,261 @@
|
|||
use std::net::{Ipv6Addr, Ipv4Addr};
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
pub mod trust_dns_types {
|
||||
pub use trust_dns_client::rr::rdata::{
|
||||
DNSSECRecordType, NULL,
|
||||
};
|
||||
pub use trust_dns_client::rr::{
|
||||
RecordType, RData, DNSClass, Record
|
||||
};
|
||||
pub use trust_dns_proto::rr::Name;
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum RecordType {
|
||||
A,
|
||||
AAAA,
|
||||
ANAME,
|
||||
ANY,
|
||||
AXFR,
|
||||
CAA,
|
||||
CNAME,
|
||||
HINFO,
|
||||
HTTPS,
|
||||
IXFR,
|
||||
MX,
|
||||
NAPTR,
|
||||
NS,
|
||||
NULL,
|
||||
OPENPGPKEY,
|
||||
OPT,
|
||||
PTR,
|
||||
SOA,
|
||||
SRV,
|
||||
SSHFP,
|
||||
SVCB,
|
||||
TLSA,
|
||||
TXT,
|
||||
// dnssec
|
||||
DNSKEY,
|
||||
DS,
|
||||
KEY,
|
||||
NSEC,
|
||||
NSEC3,
|
||||
NSEC3PARAM,
|
||||
RRSIG,
|
||||
SIG,
|
||||
|
||||
Unknown(u16),
|
||||
ZERO,
|
||||
}
|
||||
|
||||
|
||||
impl From<trust_dns_types::RecordType> for RecordType {
|
||||
fn from(record_type: trust_dns_types::RecordType) -> RecordType {
|
||||
match record_type {
|
||||
trust_dns_types::RecordType::A => RecordType::A,
|
||||
trust_dns_types::RecordType::AAAA => RecordType::AAAA,
|
||||
trust_dns_types::RecordType::ANAME => RecordType::ANAME,
|
||||
trust_dns_types::RecordType::ANY => RecordType::ANY,
|
||||
trust_dns_types::RecordType::AXFR => RecordType::AXFR,
|
||||
trust_dns_types::RecordType::CAA => RecordType::CAA,
|
||||
trust_dns_types::RecordType::CNAME => RecordType::CNAME,
|
||||
trust_dns_types::RecordType::HINFO => RecordType::HINFO,
|
||||
trust_dns_types::RecordType::HTTPS => RecordType::HTTPS,
|
||||
trust_dns_types::RecordType::IXFR => RecordType::IXFR,
|
||||
trust_dns_types::RecordType::MX => RecordType::MX,
|
||||
trust_dns_types::RecordType::NAPTR => RecordType::NAPTR,
|
||||
trust_dns_types::RecordType::NS => RecordType::NS,
|
||||
trust_dns_types::RecordType::NULL => RecordType::NULL,
|
||||
trust_dns_types::RecordType::OPENPGPKEY => RecordType::OPENPGPKEY,
|
||||
trust_dns_types::RecordType::OPT => RecordType::OPT,
|
||||
trust_dns_types::RecordType::PTR => RecordType::PTR,
|
||||
trust_dns_types::RecordType::SOA => RecordType::SOA,
|
||||
trust_dns_types::RecordType::SRV => RecordType::SRV,
|
||||
trust_dns_types::RecordType::SSHFP => RecordType::SSHFP,
|
||||
trust_dns_types::RecordType::SVCB => RecordType::SVCB,
|
||||
trust_dns_types::RecordType::TLSA => RecordType::TLSA,
|
||||
trust_dns_types::RecordType::TXT => RecordType::TXT,
|
||||
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::DNSKEY) => RecordType::DNSKEY,
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::DS) => RecordType::DS,
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::KEY) => RecordType::KEY,
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::NSEC) => RecordType::NSEC,
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::NSEC3) => RecordType::NSEC3,
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::NSEC3PARAM) => RecordType::NSEC3PARAM,
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::RRSIG) => RecordType::RRSIG,
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::SIG) => RecordType::SIG,
|
||||
trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::Unknown(r#type)) => RecordType::Unknown(r#type),
|
||||
|
||||
trust_dns_types::RecordType::Unknown(r#type) => RecordType::Unknown(r#type),
|
||||
trust_dns_types::RecordType::ZERO => RecordType::ZERO,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<trust_dns_types::RecordType> for RecordType {
|
||||
fn into(self) -> trust_dns_types::RecordType {
|
||||
match self {
|
||||
RecordType::A => trust_dns_types::RecordType::A,
|
||||
RecordType::AAAA => trust_dns_types::RecordType::AAAA,
|
||||
RecordType::ANAME => trust_dns_types::RecordType::ANAME,
|
||||
RecordType::ANY => trust_dns_types::RecordType::ANY,
|
||||
RecordType::AXFR => trust_dns_types::RecordType::AXFR,
|
||||
RecordType::CAA => trust_dns_types::RecordType::CAA,
|
||||
RecordType::CNAME => trust_dns_types::RecordType::CNAME,
|
||||
RecordType::HINFO => trust_dns_types::RecordType::HINFO,
|
||||
RecordType::HTTPS => trust_dns_types::RecordType::HTTPS,
|
||||
RecordType::IXFR => trust_dns_types::RecordType::IXFR,
|
||||
RecordType::MX => trust_dns_types::RecordType::MX,
|
||||
RecordType::NAPTR => trust_dns_types::RecordType::NAPTR,
|
||||
RecordType::NS => trust_dns_types::RecordType::NS,
|
||||
RecordType::NULL => trust_dns_types::RecordType::NULL,
|
||||
RecordType::OPENPGPKEY => trust_dns_types::RecordType::OPENPGPKEY,
|
||||
RecordType::OPT => trust_dns_types::RecordType::OPT,
|
||||
RecordType::PTR => trust_dns_types::RecordType::PTR,
|
||||
RecordType::SOA => trust_dns_types::RecordType::SOA,
|
||||
RecordType::SRV => trust_dns_types::RecordType::SRV,
|
||||
RecordType::SSHFP => trust_dns_types::RecordType::SSHFP,
|
||||
RecordType::SVCB => trust_dns_types::RecordType::SVCB,
|
||||
RecordType::TLSA => trust_dns_types::RecordType::TLSA,
|
||||
RecordType::TXT => trust_dns_types::RecordType::TXT,
|
||||
|
||||
RecordType::DNSKEY => trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::DNSKEY),
|
||||
RecordType::DS => trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::DS),
|
||||
RecordType::KEY => trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::KEY),
|
||||
RecordType::NSEC => trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::NSEC),
|
||||
RecordType::NSEC3 => trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::NSEC3),
|
||||
RecordType::NSEC3PARAM => trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::NSEC3PARAM),
|
||||
RecordType::RRSIG => trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::RRSIG),
|
||||
RecordType::SIG => trust_dns_types::RecordType::DNSSEC(trust_dns_types::DNSSECRecordType::SIG),
|
||||
|
||||
RecordType::Unknown(r#type) => trust_dns_types::RecordType::Unknown(r#type),
|
||||
RecordType::ZERO => trust_dns_types::RecordType::ZERO,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(tag = "Type")]
|
||||
pub enum RData {
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
A {
|
||||
address: Ipv4Addr
|
||||
},
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
AAAA {
|
||||
address: Ipv6Addr
|
||||
},
|
||||
ANAME(StringName),
|
||||
// CAA(CAA),
|
||||
CNAME(StringName),
|
||||
// HINFO(HINFO),
|
||||
// HTTPS(SVCB),
|
||||
// MX(MX),
|
||||
// NAPTR(NAPTR),
|
||||
NULL(NULL),
|
||||
NS(StringName),
|
||||
// OPENPGPKEY(OPENPGPKEY),
|
||||
// OPT(OPT),
|
||||
PTR(StringName),
|
||||
// SOA(SOA),
|
||||
// SRV(SRV),
|
||||
// SSHFP(SSHFP),
|
||||
// SVCB(SVCB),
|
||||
// TLSA(TLSA),
|
||||
// TXT(TXT),
|
||||
// DNSSEC(DNSSECRData),
|
||||
Unknown {
|
||||
code: u16,
|
||||
rdata: NULL,
|
||||
},
|
||||
// ZERO,
|
||||
}
|
||||
|
||||
impl From<trust_dns_types::RData> for RData {
|
||||
fn from(rdata: trust_dns_types::RData) -> RData {
|
||||
match rdata {
|
||||
trust_dns_types::RData::A(address) => RData::A { address },
|
||||
trust_dns_types::RData::AAAA(address) => RData::AAAA { address },
|
||||
_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct StringName(String);
|
||||
|
||||
|
||||
impl From<trust_dns_types::Name> for StringName {
|
||||
fn from(name: trust_dns_types::Name) -> StringName {
|
||||
StringName(name.to_utf8())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct NULL {
|
||||
pub anything: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl From<trust_dns_types::NULL> for NULL {
|
||||
fn from(null: trust_dns_types::NULL) -> NULL {
|
||||
NULL {
|
||||
anything: null.anything().map(|e| e.to_vec())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum DNSClass {
|
||||
IN,
|
||||
CH,
|
||||
HS,
|
||||
NONE,
|
||||
ANY,
|
||||
OPT(u16),
|
||||
}
|
||||
|
||||
impl From<trust_dns_types::DNSClass> for DNSClass {
|
||||
fn from(dns_class: trust_dns_types::DNSClass) -> DNSClass {
|
||||
match dns_class {
|
||||
trust_dns_types::DNSClass::IN => DNSClass::IN,
|
||||
trust_dns_types::DNSClass::CH => DNSClass::CH,
|
||||
trust_dns_types::DNSClass::HS => DNSClass::HS,
|
||||
trust_dns_types::DNSClass::NONE => DNSClass::NONE,
|
||||
trust_dns_types::DNSClass::ANY => DNSClass::ANY,
|
||||
trust_dns_types::DNSClass::OPT(v) => DNSClass::OPT(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Record {
|
||||
#[serde(rename = "Name")]
|
||||
name: StringName,
|
||||
//#[serde(rename = "Type")]
|
||||
//rr_type: RecordType,
|
||||
#[serde(rename = "Class")]
|
||||
dns_class: DNSClass,
|
||||
#[serde(rename = "TTL")]
|
||||
ttl: u32,
|
||||
#[serde(flatten)]
|
||||
rdata: RData,
|
||||
}
|
||||
|
||||
impl From<trust_dns_types::Record> for Record {
|
||||
fn from(record: trust_dns_types::Record) -> Record {
|
||||
Record {
|
||||
name: StringName(record.name().to_utf8()),
|
||||
//rr_type: record.rr_type().into(),
|
||||
dns_class: record.dns_class().into(),
|
||||
ttl: record.ttl(),
|
||||
rdata: record.into_data().into(),
|
||||
}
|
||||
}
|
||||
}
|
1
src/types/mod.rs
Normal file
1
src/types/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod dns;
|
Loading…
Reference in a new issue