Skip to content

programingjd/firewall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Firewall   LICENSE crates.io Version Documentation

The Firewall trait is meant to be used by servers to abstract the logic of blocking incoming requests.

Its accept method is provided an ip address (v4 or v6) and if the connection is over TLS, access to the server name from the SNI extension, and the client supported protocols from the ALPN extension.

The ClientHello trait is used to make the Firewall trait agnostic over the TLS implementation.


For servers who only need/want those 2 traits, the default features should be disabled.

Cargo.toml

[dependencies.firewall]
version = "0.1"
default-features = false

The rustls feature provides an implementation of the ClientHello trait for rustls.

The openssl feature provides an implementation of the ClientHello trait for openssl.


The builder feature provides an implementation of the Firewall trait.

let firewall = Firewall::default()
    .require_sni()
    .allow_server_name("example.com")
    .allow_ip_range("1.2.3.4/30");

You can have a list of allowed ip ranges, and a list of denied ip ranges (both ipv4 and ipv6).

You can also add an exception based on the TLS ClientHello content.

A good use case for this is if you want to renew Let's Encrypt certificates with the TLS-ALPN-01 challenge. Let's Encrypt doesn't provide a list of ips that they use to validate the challenges. You can add an exception to bypass the allow list if the acme-tls/1 protocol is listed in the TLS ALPN extension.

struct AcmeTlsSni01Exception {}

impl TlsAccept for AcmeTlsSni01Exception {
    fn accept(&self, client_hello: impl ClientHello) -> AcceptDenyOverride {
        if client_hello.has_alpn(b"acme-tls/1") {
            AcceptDenyOverride::AcceptAndBypassAllowList
        } else if client_hello.has_alpn(b"http/1.1") {
            AcceptDenyOverride::Accept
        } else {
            AcceptDenyOverride::Deny
        }
    }
}

let firewall = firewall
    .with_exception(AcmeTlsSni01Exception {});

The cloudflare feature adds a method on Firewall to apply the official allow list for Cloudflare servers.

let firewall = Firewall::default()
    .try_allow_cloudflare_ips()
    .await
    .unwrap();

This is useful if your server is behind the Cloudflare CDN and you don't want to allow any other server to contact your origin server directly.

There's a public fetch_cloudflare_ip_ranges() function available if you want to make sure that the list is up to date.


The github_webhook feature adds a method on Firewall to apply the official allow list for Github webhook servers.

let firewall = Firewall::default()
    .try_allow_github_webhook_ips()
    .await
    .unwrap();

There's a public fetch_github_webhook_ip_ranges() function available if you want to make sure that the list is up to date.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages