Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why use same https port for DNS and Web Portal #7424

Open
3 tasks done
vdias opened this issue Nov 8, 2024 · 13 comments
Open
3 tasks done

Why use same https port for DNS and Web Portal #7424

vdias opened this issue Nov 8, 2024 · 13 comments

Comments

@vdias
Copy link

vdias commented Nov 8, 2024

Prerequisites

  • I have checked the Wiki and Discussions and found no answer

  • I have searched other issues and found no duplicates

  • 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

@ChronSyn
Copy link

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':

image

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.

@Marcus1Pierce
Copy link

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.

@saint-lascivious
Copy link

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".

@vdias
Copy link
Author

vdias commented Nov 11, 2024

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?

@Marcus1Pierce
Copy link

@vdias Maybe you can try this:

Configuration for dns.example.com

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;
    }
}

Configuration for dns-dashboard.example.com

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.

@vdias
Copy link
Author

vdias commented Nov 11, 2024

One last question... if adgurad already have the certificate part... do i need to offload it again to nginx...

@Marcus1Pierce
Copy link

It seems so. Just try to match the certificate with the one in AdGuardHome.

@vdias
Copy link
Author

vdias commented Nov 12, 2024

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

@saint-lascivious
Copy link

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.

@vdias
Copy link
Author

vdias commented Nov 12, 2024

it a product design limitation... completely no sense...

admin should use one port
DOH another one
and so on...

@saint-lascivious
Copy link

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.

@Marcus1Pierce
Copy link

@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"
        }
}

@Marcus1Pierce
Copy link

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.
DNS Block

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants