Demonstrate IP blocking in example

This commit adds a new --block option to the server example to
illustate in a simplified way the general structure one would use to
implement IP address blocking with the new accept/reject/retry API.

For example:

    cargo run --example server ./ --listen 127.0.0.1:4433 --stateless-retry --block 127.0.0.1:8065
    cargo run --example client https://127.0.0.1:4433/Cargo.toml --host localhost --bind 127.0.0.1:8065

One thing to note is that that example places the reject condition
before the retry condition. This expends slightly less effort rejecting
connections, but does create a blocked IP address oracle for an attacker
who can do address spoofing.
This commit is contained in:
Phoenix Kahlo
2024-02-15 19:26:45 -06:00
committed by Dirkjan Ochtman
parent 736f87bcdc
commit d34b375da6
2 changed files with 13 additions and 3 deletions
+6 -2
View File
@@ -5,7 +5,7 @@
use std::{
fs,
io::{self, Write},
net::ToSocketAddrs,
net::{SocketAddr, ToSocketAddrs},
path::PathBuf,
sync::Arc,
time::{Duration, Instant},
@@ -39,6 +39,10 @@ struct Opt {
/// Simulate NAT rebinding after connecting
#[clap(long = "rebind")]
rebind: bool,
/// Address to bind on
#[clap(long = "bind", default_value = "[::]:0")]
bind: SocketAddr,
}
fn main() {
@@ -97,7 +101,7 @@ async fn run(options: Opt) -> Result<()> {
}
let client_config = quinn::ClientConfig::new(Arc::new(client_crypto));
let mut endpoint = quinn::Endpoint::client("[::]:0".parse().unwrap())?;
let mut endpoint = quinn::Endpoint::client(options.bind)?;
endpoint.set_default_client_config(client_config);
let request = format!("GET {}\r\n", url.path());
+7 -1
View File
@@ -37,6 +37,9 @@ struct Opt {
/// Address to listen on
#[clap(long = "listen", default_value = "[::1]:4433")]
listen: SocketAddr,
/// Client address to block
#[clap(long = "block")]
block: Option<SocketAddr>,
}
fn main() {
@@ -142,7 +145,10 @@ async fn run(options: Opt) -> Result<()> {
eprintln!("listening on {}", endpoint.local_addr()?);
while let Some(conn) = endpoint.accept().await {
if options.stateless_retry && !conn.remote_address_validated() {
if Some(conn.remote_address()) == options.block {
info!("rejecting blocked client IP address");
conn.reject();
} else if options.stateless_retry && !conn.remote_address_validated() {
info!("requiring connection to validate its address");
conn.retry().unwrap();
} else {