add deny networks config option and examples

This commit is contained in:
Benjamin Fry 2024-01-07 11:47:20 -08:00
parent 09bd66ec3c
commit d6a927aba8
6 changed files with 65 additions and 4 deletions

View File

@ -391,11 +391,12 @@ fn main() {
.iter()
.flat_map(|x| (*x, listen_port).to_socket_addrs().unwrap())
.collect();
let deny_networks = config.get_deny_networks();
let allow_networks = config.get_allow_networks();
// now, run the server, based on the config
#[cfg_attr(not(feature = "dns-over-tls"), allow(unused_mut))]
let mut server = ServerFuture::with_access(catalog, allow_networks);
let mut server = ServerFuture::with_access(catalog, deny_networks, allow_networks);
// load all the listeners
for udp_socket in &sockaddrs {

View File

@ -402,3 +402,35 @@ fn test_deny_networks_toml_startup() {
query_a_refused(&mut io_loop, &mut client);
})
}
#[test]
fn test_deny_allow_networks_toml_startup() {
named_test_harness("example_deny_allow_networks.toml", |socket_ports| {
let mut io_loop = Runtime::new().unwrap();
let tcp_port = socket_ports.get_v4(Protocol::Tcp);
let addr: SocketAddr = SocketAddr::new(
Ipv4Addr::new(127, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
hickory_proto::spawn_bg(&io_loop, bg);
// ipv4 should succeed
query_a(&mut io_loop, &mut client);
let tcp_port = socket_ports.get_v6(Protocol::Tcp);
let addr: SocketAddr = SocketAddr::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).into(),
tcp_port.expect("no tcp_port"),
);
let (stream, sender) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::new(Box::new(stream), sender, None);
let (mut client, bg) = io_loop.block_on(client).expect("client failed to connect");
hickory_proto::spawn_bg(&io_loop, bg);
// ipv6 should be refused
query_a_refused(&mut io_loop, &mut client);
})
}

View File

@ -69,6 +69,9 @@ pub struct Config {
/// Certificate to associate to TLS connections (currently the same is used for HTTPS and TLS)
#[cfg(feature = "dnssec")]
tls_cert: Option<dnssec::TlsCertConfig>,
/// Networks denied to access the server
#[serde(default)]
deny_networks: Vec<IpNet>,
/// Networks allowed to access the server
#[serde(default)]
allow_networks: Vec<IpNet>,
@ -165,6 +168,11 @@ impl Config {
}
}
/// get the networks denied access to this server
pub fn get_deny_networks(&self) -> &[IpNet] {
&self.deny_networks
}
/// get the networks allowed to connect to this server
pub fn get_allow_networks(&self) -> &[IpNet] {
&self.allow_networks

View File

@ -50,12 +50,13 @@ pub struct ServerFuture<T: RequestHandler> {
impl<T: RequestHandler> ServerFuture<T> {
/// Creates a new ServerFuture with the specified Handler.
pub fn new(handler: T) -> Self {
Self::with_access(handler, &[])
Self::with_access(handler, &[], &[])
}
/// Creates a new ServerFuture with the specified Handler and Access
pub fn with_access(handler: T, allowed_networks: &[IpNet]) -> Self {
pub fn with_access(handler: T, denied_networks: &[IpNet], allowed_networks: &[IpNet]) -> Self {
let mut access = Access::default();
access.insert_deny_all(denied_networks);
access.insert_allow_all(allowed_networks);
Self {

View File

@ -40,8 +40,15 @@
## directory: path on the host filesystem to where zone files are stored.
# directory = "/var/named"
## Denied networks, a list of CIDRs in IPv4 or IPv6 formats,
## any request that does not originate from the specified networks will be allowed
# deny_networks = ["127/8", "::1/128"]
## Allowed networks, a list of CIDRs in IPv4 or IPv6 formats,
## any request that does not originate from the specified networks will be denied
## any request that does not originate from the specified networks will be denied, unless
## there are deny_networks specified, in that case, the allow list will be processed as
## an override to the deny_networks. That is, if there is a deny_list and the network does
## not appear there, even if does not appear in the allow list the request will be allowd.
# allow_networks = ["127/8", "::1/128"]
## Default zones, these should be present on all nameservers, except in rare

View File

@ -0,0 +1,12 @@
listen_addrs_ipv4 = ["0.0.0.0"]
listen_addrs_ipv6 = ["::0"]
## Half o the 127 ipv4 space is denied, but there are no denied ipv6 addresses
deny_networks = ["127.0.0.0/8"]
## The 127.0.0.1 address is allowed, overriding the deny, but the ipv6 allow is effectively none, so all are denied
allow_networks = ["127.0.0.1/32", "::/128"]
[[zones]]
zone = "example.com"
zone_type = "Primary"
file = "example.com.zone"