Open vdias opened 4 days ago
The premise of DoH (DNS-over-HTTPS) is that it wraps the DNS lookup as regular HTTPS requests, making it more difficult for interception and forgery by attackers. Whereas DoT and regular unencrypted DNS can be identified by the target (e.g. port), DoH is impossible to differentiate from the outside.
Separation of DoH from non-DoH HTTPS defeats one of the key benefits of it. If you wanted that, you may as well just use DoT (DNS-over-TLS).
You can configure the HTTPS port for your admin interface and DoH, as well as the DNS-over-TLS port, in 'Settings -> Encryption Settings':
As you can see, the /dns-query
endpoint is where a DNS lookup will be sent to. You may be able to use that to determine if a DoT request is being routed to the DNS resolver, or if it's being routed to the admin interface.
You can use a reverse proxy like Nginx, Caddy, or Traefik to separate the domain for DoH and the Dashboard.
For example, you can use the domain dns.example.com only to handle /dns-query (DNS over HTTPS) and block access to the dashboard on dns.example.com or redirect to error 404. Use the domain dns-dashboard.example.com for dashboard access.
If you expand this outside of HTTPS, and also look towards TLS and QUIC (and H3?), the same problems are realised without the (IMO flawed) argument of "well ahhckshully …you're directing queries to a URL rather than a domain with a port suffix".
You can use a reverse proxy like Nginx, Caddy, or Traefik to separate the domain for DoH and the Dashboard.
For example, you can use the domain dns.example.com only to handle /dns-query (DNS over HTTPS) and block access to the dashboard on dns.example.com or redirect to error 404. Use the domain dns-dashboard.example.com for dashboard access.
Any nginx conf example?
@vdias Maybe you can try this:
server {
listen 443 ssl http2; # Enable HTTP/2
listen [::]:443 ssl http2; # Enable HTTP/2 for IPv6
server_name dns.example.com;
ssl_certificate /etc/letsencrypt/live/dns.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dns.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5; # Simplified for strong ciphers
# Proxy for /dns-query
location = /dns-query {
proxy_pass https://adguardhome-ip:port;
proxy_set_header Host $host;
proxy_ssl_server_name on;
proxy_ssl_name dns.example.com;
}
# Proxy for /dns-query/*
location ~ ^/dns-query/.*$ {
proxy_pass https://adguardhome-ip:port;
proxy_set_header Host $host;
proxy_ssl_server_name on;
proxy_ssl_name dns.example.com;
}
# Respond with 404 for all other routes
location / {
return 404;
}
}
server {
listen 443 ssl http2; # Enable HTTP/2
listen [::]:443 ssl http2; # Enable HTTP/2 for IPv6
server_name dns-dashboard.example.com;
ssl_certificate /etc/letsencrypt/live/dns.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dns.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5; # Simplified for strong ciphers
# Proxy all other requests to adguardhome
location / {
proxy_pass https://adguardhome-ip:port;
}
# Respond with 404 for /dns-query and /dns-query/*
location = /dns-query {
return 404;
}
location ~ ^/dns-query/.*$ {
return 404;
}
}
I’m not sure whether this is the correct configuration or not. I got this config from ChatGPT. It might need to be checked again to ensure it meets the requirements.
One last question... if adgurad already have the certificate part... do i need to offload it again to nginx...
It seems so. Just try to match the certificate with the one in AdGuardHome.
This is completely no sense... nginx do not work...
Even something as simple as this do not work...
nginx.conf
server {
listen 443 ssl;
server_name XXXXXXX.com;
ssl_certificate /etc/letsencrypt/live/XXXXXXX/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/XXXXXXX/privkey.pem;
location / {
proxy_pass https://localhost:4443/;
proxy_set_header Host $host;
allow PUBLIC-IP-HOME/32;
deny all;
}
location /dns-query {
proxy_pass https://localhost:4443/dns-query;
}
}
AdGuardHome.yaml
tls:
enabled: true
server_name: XXXXXXX.com
force_https: false
port_https: 4443
port_dns_over_tls: 853
port_dns_over_quic: 853
port_dnscrypt: 0
dnscrypt_config_file: ""
allow_unencrypted_doh: true
certificate_chain: ""
private_key: ""
certificate_path: ""
private_key_path: ""
strict_sni_check: false
And as I attempted to point out, the web interface would still be accessible via QUIC, so it's mostly a moot point I think.
it a product design limitation... completely no sense...
admin should use one port DOH another one and so on...
Sharing ports isn't ultimately the issue I don't think. The issue is resolution capabilities and web administration interface listening address/interface not being able to be decoupled, and/or the lack of IP/CIDR based access control for the web interface.
Being able to disable/enable the web interface entirely would also be quite nice.
@vdias Try searching for issues related with filter here https://github.com/AdguardTeam/AdGuardHome/issues. I previously used Nginx for something similar, but I have forgotten the details. Now I use Caddy for this, and it works well for me.
This is my config with caddy.
AdGuardHome.yaml
tls:
enabled: true
server_name: dns.example.com
force_https: false
port_https: 443
port_dns_over_tls: 853
port_dns_over_quic: 853
port_dnscrypt: 0
dnscrypt_config_file: ""
allow_unencrypted_doh: false
certificate_chain: ""
private_key: ""
certificate_path: /etc/letsencrypt/live/dns.example.com/fullchain.pem
private_key_path: /etc/letsencrypt/live/dns.example.com/privkey.pem
strict_sni_check: false
Caddyfile
dns.example.com {
tls /etc/letsencrypt/live/dns.example.com/fullchain.pem /etc/letsencrypt/live/dns.example.com/privkey.pem
log {
output file /log/dns-ads.log {
roll_size 2MiB
}
level INFO
}
handle /dns-query {
reverse_proxy https://adguardhome {
trusted_proxies 10.1.1.0/24
header_up Host {upstream_hostport}
transport http {
tls
tls_server_name dns.example.com
}
}
}
handle /dns-query/* {
reverse_proxy https://adguardhome {
trusted_proxies 10.1.1.0/24
header_up Host {upstream_hostport}
transport http {
tls
tls_server_name dns.example.com
}
}
}
handle / {
respond 404
}
}
dns-dashboard.example.com {
tls /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem
reverse_proxy https://adguardhome {
transport http {
tls_insecure_skip_verify
}
}
handle /dns-query {
respond 404
}
handle /dns-query/* {
respond 404
}
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
X-XSS-Protection "1; mode=block"
Referrer-Policy "no-referrer"
}
}
And as I attempted to point out, the web interface would still be accessible via QUIC, so it's mostly a moot point I think.
In my case, the web interface still blocked even when using the H3/QUIC protocol.
This is the image when I try to access dashboard from the DoH subdomain.
Prerequisites
[X] I have checked the Wiki and Discussions and found no answer
[X] I have searched other issues and found no duplicates
[X] I want to request a feature or enhancement and not ask a question
The problem
Whys use same port for DNS service and Administration portal.
How can we filter public VPS access to the administration portal? There is no sense of having this like this.
Proposed solution
Different port for different services
Alternatives considered and additional information
No response