Skip to content

Commit

Permalink
Demonstrate IP blocking in example
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
gretchenfrage authored and djc committed Apr 3, 2024
1 parent 54d5d60 commit 75c0e01
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
8 changes: 6 additions & 2 deletions quinn/examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use std::{
fs,
io::{self, Write},
net::ToSocketAddrs,
net::{SocketAddr, ToSocketAddrs},
path::PathBuf,
sync::Arc,
time::{Duration, Instant},
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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());
Expand Down
8 changes: 7 additions & 1 deletion quinn/examples/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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!("refusing blocked client IP address");
conn.refuse();
} else if options.stateless_retry && !conn.remote_address_validated() {
info!("requiring connection to validate its address");
conn.retry().unwrap();
} else {
Expand Down

0 comments on commit 75c0e01

Please sign in to comment.