Compare commits

...

31 commits

Author SHA1 Message Date
Frank Denis
f0242354d3 Update deps 2025-03-20 00:43:38 +01:00
Frank Denis
25fa6946e6 tar cJpf -> tar cjpf in order to build bz2 archives
Fixes #103
2025-03-20 00:37:34 +01:00
Frank Denis
2254632d33 Update deps 2025-02-20 20:37:23 +01:00
Frank Denis
672d1a11f1 2025 2025-02-20 20:33:01 +01:00
Frank Denis
9e4a931bce Nits 2025-02-20 20:32:42 +01:00
Frank Denis
40b0b02972 Add issues.yml 2024-12-31 14:54:55 +01:00
Frank Denis
bf443c33b9 Switch to mlugg/setup-zig@v1 2024-11-04 00:11:49 +01:00
Frank Denis
1a0a0566c4 Back to Zig 0.10.1 2024-07-03 14:38:16 +02:00
Frank Denis
890a74276f Downgrade to Zig 0.12.0 2024-07-03 14:26:44 +02:00
Frank Denis
34f614e938 0.13 -> 0.13.0 2024-07-03 14:17:17 +02:00
Frank Denis
d6635eebb7 up 2024-07-03 14:16:01 +02:00
Frank Denis
c79501aea3 Use Zig 0.13 2024-07-03 14:03:51 +02:00
Frank Denis
e73964fa1d Update deps 2024-07-03 13:52:56 +02:00
Frank Denis
bafbdc0926 Try creating RPM packages
Fixes #98
2024-07-03 13:27:29 +02:00
Frank Denis
30a55a0f2f Merge branch 'master' of github.com:jedisct1/rust-doh
* 'master' of github.com:jedisct1/rust-doh:
  Add Let's Encrypt R10
  Update common hashes
2024-07-03 12:33:38 +02:00
Frank Denis
7bb8293c28 package.metadata.generate-rpm 2024-07-03 12:33:29 +02:00
Frank Denis
a6517472d5
Merge pull request #97 from demarcush/patch-1
Update common hashes
2024-07-03 00:11:22 +02:00
demarcush
3511672d49
Add Let's Encrypt R10 2024-07-02 20:47:53 +00:00
demarcush
bd85572368
Update common hashes 2024-05-14 03:44:17 +00:00
Frank Denis
02b3a67a00 Update hyper to 0.14.28 2024-05-06 12:22:21 +02:00
Frank Denis
66c66c7a28 Update mimalloc 2024-05-05 18:01:19 +02:00
Frank Denis
1165fab90c Update a few deps 2024-03-06 18:25:38 +01:00
Frank Denis
c92308ccbb Update deps 2023-09-02 00:20:06 +02:00
Frank Denis
78c47830ff Update deps 2023-07-15 21:18:46 +02:00
Frank Denis
9e2853da86 Update deps 2023-05-03 17:35:23 +02:00
Frank Denis
e5f6f2a5d6 Bump 2023-04-14 12:44:40 +02:00
Frank Denis
e8df0458ac Bump hyper. Again. 2023-04-14 12:38:08 +02:00
Frank Denis
19040f1e88 Nits 2023-04-14 09:45:20 +02:00
Frank Denis
6f9f63e754 Update deps, especially hyper 2023-04-13 17:13:03 +02:00
Frank Denis
678bd04bed Update deps 2023-04-13 17:12:29 +02:00
Frank Denis
ffa0828515 Update tokio 2023-03-02 19:05:11 +01:00
11 changed files with 141 additions and 69 deletions

17
.github/workflows/issues.yml vendored Normal file
View file

@ -0,0 +1,17 @@
name: Close inactive issues
on:
schedule:
- cron: "30 1 * * *"
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
with:
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
repo-token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v3
- uses: goto-bus-stop/setup-zig@v2
- uses: mlugg/setup-zig@v1
with:
version: 0.10.1
@ -33,6 +33,9 @@ jobs:
- name: Install cargo-deb
run: cargo install cargo-deb
- name: Install cargo-generate-rpm
run: cargo install cargo-generate-rpm
- name: Install cargo-zigbuild
run: cargo install cargo-zigbuild
@ -43,7 +46,7 @@ jobs:
mkdir doh-proxy
mv target/x86_64-unknown-linux-musl/release/doh-proxy doh-proxy/
cp README.md localhost.pem doh-proxy/
tar cJpf doh-proxy_${{ steps.get_version.outputs.VERSION }}_linux-x86_64.tar.bz2 doh-proxy
tar cjpf doh-proxy_${{ steps.get_version.outputs.VERSION }}_linux-x86_64.tar.bz2 doh-proxy
rm -fr doh-proxy
- name: Release build Linux-aarch64
@ -53,7 +56,7 @@ jobs:
mkdir doh-proxy
mv target/aarch64-unknown-linux-musl/release/doh-proxy doh-proxy/
cp README.md localhost.pem doh-proxy/
tar cJpf doh-proxy_${{ steps.get_version.outputs.VERSION }}_linux-aarch64.tar.bz2 doh-proxy
tar cjpf doh-proxy_${{ steps.get_version.outputs.VERSION }}_linux-aarch64.tar.bz2 doh-proxy
rm -fr doh-proxy
- name: Release build Windows-x86_64
@ -73,6 +76,16 @@ jobs:
rustup target add aarch64-unknown-linux-musl
env RUSTFLAGS="-C strip=symbols" cargo deb --no-strip --cargo-build=zigbuild --target=aarch64-unknown-linux-musl
- name: RPM packages
run: |
rustup target add x86_64-unknown-linux-gnu
env RUSTFLAGS="-C strip=symbols" cargo-zigbuild build --target=x86_64-unknown-linux-gnu.2.17 --release
mv target/x86_64-unknown-linux-musl/release/doh-proxy target/release/
cargo generate-rpm --target x86_64-unknown-linux-gnu
rustup target add aarch64-unknown-linux-gnu
env RUSTFLAGS="-C strip=symbols" cargo-zigbuild build --target=aarch64-unknown-linux-gnu.2.17 --release
cargo generate-rpm --target aarch64-unknown-linux-gnu
- name: Create release
id: create_release
uses: actions/create-release@v1
@ -91,10 +104,32 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_name: "doh-proxy_${{ steps.get_version.outputs.VERSION }}_amd64.deb"
asset_path: "target/x86_64-unknown-linux-musl/debian/doh-proxy_${{ steps.get_version.outputs.VERSION }}_amd64.deb"
asset_name: "doh-proxy_${{ steps.get_version.outputs.VERSION }}-1_amd64.deb"
asset_path: "target/x86_64-unknown-linux-musl/debian/doh-proxy_${{ steps.get_version.outputs.VERSION }}-1_amd64.deb"
asset_content_type: application/x-debian-package
- name: Upload RPM package for x86_64
id: upload-release-asset-rpm-x86_64
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_name: "doh-proxy-${{ steps.get_version.outputs.VERSION }}-1.x86_64.rpm"
asset_path: "target/x86_64-unknown-linux-gnu/generate-rpm/doh-proxy-${{ steps.get_version.outputs.VERSION }}-1.x86_64.rpm"
asset_content_type: application/x-redhat-package-manager
- name: Upload RPM package for aarch64
id: upload-release-asset-rpm-aarch64
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_name: "doh-proxy-${{ steps.get_version.outputs.VERSION }}-1.aarch64.rpm"
asset_path: "target/aarch64-unknown-linux-gnu/generate-rpm/doh-proxy-${{ steps.get_version.outputs.VERSION }}-1.aarch64.rpm"
asset_content_type: application/x-redhat-package-manager
- name: Upload tarball for linux-x86_64
id: upload-release-asset-tarball-linux-x86_64
uses: actions/upload-release-asset@v1

View file

@ -1,6 +1,6 @@
[package]
name = "doh-proxy"
version = "0.9.8"
version = "0.9.11"
authors = ["Frank Denis <github@pureftpd.org>"]
description = "A DNS-over-HTTPS (DoH) and ODoH (Oblivious DoH) proxy"
keywords = ["dns", "https", "doh", "odoh", "proxy"]
@ -16,10 +16,16 @@ default = ["tls"]
tls = ["libdoh/tls"]
[dependencies]
libdoh = { path = "src/libdoh", version = "0.9.8", default-features = false }
libdoh = { path = "src/libdoh", version = "0.9.9", default-features = false }
clap = { version = "4", features = ["std", "cargo", "wrap_help", "string"] }
dnsstamps = "0.1.9"
mimalloc = { version = "0.1.34", default-features = false }
dnsstamps = "0.1.10"
mimalloc = { version = "0.1.44", default-features = false }
[package.metadata.generate-rpm]
assets = [
{ source = "target/release/doh-proxy", dest = "/usr/bin/doh-proxy", mode = "755" },
{ source = "README.md", dest = "/usr/share/doc/doh-proxy/README.md", mode = "644", doc = true },
]
[package.metadata.deb]
extended-description = """\

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018-2023 Frank Denis
Copyright (c) 2018-2025 Frank Denis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -136,7 +136,7 @@ This can be achieved with the `--allow-odoh-post` command-line switch.
* When using DoH, DNS stamps should include a resolver IP address in order to remove a dependency on non-encrypted, non-authenticated, easy-to-block resolvers.
* Unlike DNSCrypt where users must explicitly trust a DNS server's public key, the security of DoH relies on traditional public Certificate Authorities. Additional root certificates (required by governments, security software, enterprise gateways) installed on a client immediately make DoH vulnerable to MITM. In order to prevent this, DNS stamps should include the hash of the parent certificate.
* TLS certificates are tied to host names. But domains expire, get reassigned and switch hands all the time. If a domain originally used for a DoH service gets a new, possibly malicious owner, clients still configured to use the service will blindly keep trusting it if the CA is the same. As a mitigation, the CA should sign an intermediate certificate (the only one present in the stamp), itself used to sign the name used by the DoH server. While commercial CAs offer this, Let's Encrypt currently doesn't.
* Make sure that the front-end supports HTTP/2 and TLS 1.3.
* Make sure that the front-end supports at least HTTP/2 and TLS 1.3.
* Internal DoH servers still require TLS certificates. So, if you are planning to deploy an internal server, you need to set up an internal CA, or add self-signed certificates to every single client.
## Example usage with `encrypted-dns-server`
@ -195,10 +195,14 @@ This [Go code snippet](https://gist.github.com/d6cb41742a1ceb54d48cc286f3d5c5fa)
### Common certificate hashes
* Let's Encrypt R3:
* `444ebd67bb83f8807b3921e938ac9178b882bd50aadb11231f044cf5f08df7ce`
* Let's Encrypt E1:
* `cc1060d39c8329b62b6fbc7d0d6df9309869b981e7e6392d5cd8fa408f4d80e6`
* Let's Encrypt R3:
* `444ebd67bb83f8807b3921e938ac9178b882bd50aadb11231f044cf5f08df7ce`
* Let's Encrypt R10:
* `e644ba6963e335fe765cb9976b12b10eb54294b42477764ccb3a3acca3acb2fc`
* ZeroSSL:
* `9a3a34f727deb9bca51003d9ce9c39f8f27dd9c5242901c2bab1a44e635a0219`
## Clients

View file

@ -240,39 +240,42 @@ pub fn parse_opts(globals: &mut Globals) {
.or_else(|| globals.tls_cert_path.clone());
}
if let Some(hostname) = matches.get_one::<String>("hostname") {
let mut builder =
dnsstamps::DoHBuilder::new(hostname.to_string(), globals.path.to_string());
if let Some(public_address) = matches.get_one::<String>("public_address") {
builder = builder.with_address(public_address.to_string());
}
if let Some(public_port) = matches.get_one::<String>("public_port") {
let public_port = public_port.parse().expect("Invalid public port");
builder = builder.with_port(public_port);
}
println!(
"Test DNS stamp to reach [{}] over DoH: [{}]\n",
hostname,
builder.serialize().unwrap()
);
match matches.get_one::<String>("hostname") {
Some(hostname) => {
let mut builder =
dnsstamps::DoHBuilder::new(hostname.to_string(), globals.path.to_string());
if let Some(public_address) = matches.get_one::<String>("public_address") {
builder = builder.with_address(public_address.to_string());
}
if let Some(public_port) = matches.get_one::<String>("public_port") {
let public_port = public_port.parse().expect("Invalid public port");
builder = builder.with_port(public_port);
}
println!(
"Test DNS stamp to reach [{}] over DoH: [{}]\n",
hostname,
builder.serialize().unwrap()
);
let mut builder =
dnsstamps::ODoHTargetBuilder::new(hostname.to_string(), globals.path.to_string());
if let Some(public_port) = matches.get_one::<String>("public_port") {
let public_port = public_port.parse().expect("Invalid public port");
builder = builder.with_port(public_port);
}
println!(
"Test DNS stamp to reach [{}] over Oblivious DoH: [{}]\n",
hostname,
builder.serialize().unwrap()
);
let mut builder =
dnsstamps::ODoHTargetBuilder::new(hostname.to_string(), globals.path.to_string());
if let Some(public_port) = matches.get_one::<String>("public_port") {
let public_port = public_port.parse().expect("Invalid public port");
builder = builder.with_port(public_port);
}
println!(
"Test DNS stamp to reach [{}] over Oblivious DoH: [{}]\n",
hostname,
builder.serialize().unwrap()
);
println!("Check out https://dnscrypt.info/stamps/ to compute the actual stamps.\n")
} else {
println!(
println!("Check out https://dnscrypt.info/stamps/ to compute the actual stamps.\n")
}
_ => {
println!(
"Please provide a fully qualified hostname (-H <hostname> command-line option) to get \
test DNS stamps for your server.\n"
);
}
}
}

View file

@ -1,13 +1,13 @@
[package]
name = "libdoh"
version = "0.9.8"
version = "0.9.11"
authors = ["Frank Denis <github@pureftpd.org>"]
description = "DoH and Oblivious DoH library for the rust-doh app"
keywords = ["dns","https","doh","odoh","proxy"]
keywords = ["dns", "https", "doh", "odoh", "proxy"]
license = "MIT"
homepage = "https://github.com/jedisct1/rust-doh"
repository = "https://github.com/jedisct1/rust-doh"
categories = ["asynchronous", "network-programming","command-line-utilities"]
categories = ["asynchronous", "network-programming", "command-line-utilities"]
edition = "2018"
[features]
@ -15,18 +15,31 @@ default = ["tls"]
tls = ["tokio-rustls"]
[dependencies]
anyhow = "1.0.69"
arc-swap = "1.6.0"
base64 = "0.21.0"
byteorder = "1.4.3"
bytes = "1.4.0"
futures = "0.3.26"
hyper = { version = "0.14.24", default-features = false, features = ["server", "http1", "http2", "stream"] }
odoh-rs = "1.0.1"
rand = "0.8.5"
tokio = { version = "1.25.0", features = ["net", "rt-multi-thread", "time", "sync"] }
tokio-rustls = { version = "0.23.4", features = ["early-data"], optional = true }
rustls-pemfile = "1.0.2"
anyhow = "1.0.97"
arc-swap = "1.7.1"
base64 = "0.22.1"
byteorder = "1.5.0"
bytes = "1.10.1"
futures = "0.3.31"
hyper = { version = "^0.14.32", default-features = false, features = [
"server",
"http1",
"http2",
"stream",
"runtime",
] }
odoh-rs = "1.0.3"
rand = "^0.8.5"
tokio = { version = "1.44.1", features = [
"net",
"rt-multi-thread",
"time",
"sync",
] }
tokio-rustls = { version = "^0.24.1", features = [
"early-data",
], optional = true }
rustls-pemfile = "^1.0.4"
[profile.release]
codegen-units = 1

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018-2023 Frank Denis
Copyright (c) 2018-2025 Frank Denis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -257,10 +257,7 @@ impl DoH {
content_types: &[&'static str],
) -> Option<&'static str> {
let accept = headers.get(hyper::header::ACCEPT);
let accept = match accept {
None => return None,
Some(accept) => accept,
};
let accept = accept?;
for part in accept.to_str().unwrap_or("").split(',').map(|s| s.trim()) {
if let Some(found) = part
.split(';')

View file

@ -77,7 +77,7 @@ impl ODoHPublicKey {
impl ODoHQueryContext {
pub fn encrypt_response(self, response_body: Vec<u8>) -> Result<Vec<u8>, DoHError> {
let response_nonce = rand::thread_rng().gen::<ResponseNonce>();
let response_nonce = rand::thread_rng().r#gen::<ResponseNonce>();
let response_body_ = ObliviousDoHMessagePlaintext::new(response_body, 0);
let encrypted_response = odoh_rs::encrypt_response(
&self.query,

View file

@ -87,12 +87,9 @@ where
let server_config_builder = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth();
if let Ok(found_config) =
server_config_builder.with_single_cert(certs.clone(), certs_key)
{
Some(found_config)
} else {
None
match server_config_builder.with_single_cert(certs.clone(), certs_key) {
Ok(found_config) => Some(found_config),
_ => None,
}
})
.ok_or_else(|| {