unifi-utilities / unifios-utilities

A collection of enhancements for UnifiOS based devices
GNU General Public License v3.0
3.9k stars 417 forks source link

DoH/DoT Support #58

Closed 1activegeek closed 3 years ago

1activegeek commented 3 years ago

Is your feature request related to a problem? Please describe. Not a problem per se, but a lack of baked support. I imagine there may be ways to do it with others, but I had a similar type of configuration in the official container previously. Looking for the ability to leverage DoH or DoT configurations for more secure DNS. (DNS over HTTPS or DNS over TLS).

Describe the solution you'd like I believe it should just be an update/include of the dnsmasq functionality within the container and/or something such as the cloudflared component. The difficulty will really be around interoperability between the container, the router, and the dueling dnsmasq systems. At this level, I'm not skilled enough in the network portion to ensure I can safely, securely, and properly set this up.

Describe alternatives you've considered Only other alternative is just NOT supporting it. The alternative is a technical task that I don't understand well enough to do on my own as I'd be mixing DNSMASQ environments I believe to handle the DoH portion.

Additional context NA

SamErde commented 3 years ago

Love the idea. Nothing will be "out of the box" because you need a certificate, but the easiest way to achieve this is to install both AdGuard Home and the UDM-LE (Let's Encrypt) containers. AGH can support secure DNS once you have a certificate, and this approach also can provide a way to assign an SSL certificate to your UDM web interface.

The Pi-Hole approach to using DoH/DoT usually involves setting up DNSCrypt-Proxy and using that as the upstream DNS resolver for the Pi-Hole. It would definitely be interesting to see DNSCrypt-Proxy added to the dns-common package or added as another option to go with the udm-utilities "suite."

SamErde commented 3 years ago

Any thoughts on using cloudflared vs dnscrypt-proxy? I've never done a close comparison of the two myself.

1activegeek commented 3 years ago

I'm not sure the specifics between them, but I imagine adding cloudflared config isn't terribly hard. Reference link (https://bendews.com/posts/implement-dns-over-https/) as to how I had set this up originally (using cloudflared) when I was running it on a Pi. Now that its running as a container on the UDM, it makes the networking a bit more complex, and the container needs to have cloudflared included as any restart will wipe it out if I do it manually.

I would imagine it should be as simple as including cloudflared as part of the container build to get cloudflared "working" inside this. The part that is more difficult to me is getting the configuration right so that all the requests and information flow the right way.

jhoward321 commented 3 years ago

For what it's worth, I think dnscrypt-proxy is the recommended route when combining with pihole at least on a raspberry pi. There's a bug with cloudflared timing out often, and dnscrypt-proxy has great built in support for additional upstream providers. I'd personally love to see a dnscrypt-proxy implementation with the pihole container. The tricky part would be the networking but I imagine that wouldn't be too difficult. Could even include it inside the pihole container which I've seen some containers do

boostchicken commented 3 years ago

Hey everyone,

I am about to move away from NextDNS.

I am going to develop PiHole with cloudflared as one Docker Image. This will allow encryption of all DNS requests out to the world being encrypted

I briefly considers messing with dnsmasq locally on the udmp and hijacking their DNS infrastructure. The problem is those configs get re-written on whacky schedules. While in some non-critical use cases I have a cron that modified them. This would not work here because if DNS goes down for even a second you are impacted.

Would that solve the functionality you are looking for?

SamErde commented 3 years ago

+1 for leaving the unifi dnsmasq alone and baking cloudflared or dnscrypt-proxy (preferred) into Pi-Hole. Pretty sure there are containers that already have the two combined, but will have to search. I liked AdGuard Home because it includes support for DoT, DoH, and now DoQ[uic] without needing additional containers.

SamErde commented 3 years ago

I'll actually hold off on the AdGuard info for this issues, though. Can agree that encryption is a very worthwhile addition for those who want to run Pi-Hole.

1activegeek commented 3 years ago

Would that solve the functionality you are looking for?

Ya that would be perfect! I know some people may not use or want to use it, but it's certainly a great option to enable for people. Obviously CFD is a popular implementation, but as mentioned a dnscrypt-proxy can also work. Any of the above for me works as I was using DoH w/ CFD previously.

nicholas-c commented 3 years ago

Would that solve the functionality you are looking for?

Bumping this issue as I'm interested.

I've been playing around with getting pihole to run over DoH to no luck as I'm not 100% clued up on the issues with dnsmasq.

I did find a few docker containers which contain DoH with Pihole on dockerhub (https://hub.docker.com/r/testdasi/pihole-with-doh) - These containers seem to have Cloudflared included.

sjdmd commented 3 years ago

Actually not for me as NextDNS rolls DDNS into its package and I find it easier to manage than keeping a pihole instance running on a raspberry pi. I suppose a docker instance on my UDMP which you all support will be more manageable than the rpi.

Thank you for asking.

/Steve

Steven Davidson davidson@pobox.com http://www.twitter.com/sjdmd

On Sun, Feb 14, 2021 at 1:25 PM Nicholas Carter notifications@github.com wrote:

Would that solve the functionality you are looking for?

Bumping this issue as I'm interested.

I've been playing around with getting pihole to run over DoH to no luck as I'm not 100% clued up on the issues with dnsmasq.

I did find a few docker containers which contain DoH with Pihole on dockerhub (https://hub.docker.com/r/testdasi/pihole-with-doh) - These containers seem to have Cloudflared included.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/boostchicken/udm-utilities/issues/58#issuecomment-778818952, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEA6ZW3FHOIYCQNPC3DLPGTS7AIP5ANCNFSM4SNCCVWQ .

SamErde commented 3 years ago

For those who want to have encrypted DNS over [HTTPS || TLS] while using Pi-hole, additional components will be required. For some reason, I've always looked at this request and thought we should find/create one Docker image that contains both Pi-hole and either cloudflared or dnscrypt-proxy. In a massive 'duh' moment, I just realized that the install script for Pi-hole on udm-utilities could simply be expanded to install two containers: pi-hole and one of the two DNS proxies. Network clients would still point to the Pi-hole container IP for DNS recursion, but the Pi-hole itself would point to the new DNS proxy to encrypt the outbound requests.

A couple of examples that use both containers on a Linux platform:

1activegeek commented 3 years ago

For those who want to have encrypted DNS over [HTTPS || TLS] while using Pi-hole, additional components will be required. For some reason, I've always looked at this request and thought we should find/create one Docker image that contains both Pi-hole and either cloudflared or dnscrypt-proxy. In a massive 'duh' moment, I just realized that the install script for Pi-hole on udm-utilities could simply be expanded to install two containers: pi-hole and one of the two DNS proxies. Network clients would still point to the Pi-hole container IP for DNS recursion, but the Pi-hole itself would point to the new DNS proxy to encrypt the outbound requests.

This is true of course, but the magic is in the actual traffic flow within the UDM ecosystem. I'm no pro in understanding how the containers tap into the network interfaces and components that make up the actual routing/switching functions on the UDM. For that reason, I've not tried to simply add another container to perform this capability. If someone has the right guidance on how to establish the paths, the traffic flows, etc - then this could certainly be a short term solution.

SamErde commented 3 years ago

Great. Out of curiosity, what would you consider to be a long-term solution?

1activegeek commented 3 years ago

Great. Out of curiosity, what would you consider to be a long-term solution?

I would say the comment by the creator of this set of tools/docs indicates the long term option up above:

I am about to move away from NextDNS.

I am going to develop PiHole with cloudflared as one Docker Image. This will allow encryption of all DNS requests out to the world being encrypted

SamErde commented 3 years ago

Anybody want to test this one container that runs Pi-Hole + Unbound? https://hub.docker.com/r/cbcrowe/pihole-unbound / https://github.com/chriscrowe/docker-pihole-unbound

There's also the wirehold project, which uses one docker-compose.yml file to configure 3 containers for unbound, WireGuard, and Pi-Hole. https://github.com/IAmStoxe/wirehole

chriscpritchard commented 3 years ago

I had it working with 2 containers, one runing unbound and one running pihole. Unbound only responds to queries from the pihole IP.

1activegeek commented 3 years ago

I had it working with 2 containers, one runing unbound and one running pihole. Unbound only responds to queries from the pihole IP.

Can you share what container you were using and potentially what configurations were necessary if any? I'm mostly curious if there were specific configs needed to ensure the traffic was routed properly, or specifics of the container run command to be sure we operate proper on the UDM setup.

chriscpritchard commented 3 years ago

I used klutchell/unbound.

I added a new CNI macvlan static IP to the same subnet as the pihole - 10-unbound.conflist:

{
  "cniVersion": "0.4.0",
  "name": "unbound",
  "plugins": [
    {
      "type": "macvlan",
      "mode": "bridge",
      "master": "br[VLANID]",
      "mac": "[CUSTOM MAC ADDRESS]",
      "ipam": {
        "type": "static",
        "addresses": [
          {
            "address": "[DESIRED IP]/24",
            "gateway": "[GATEWAY]"
          }
        ],
        "routes": [
          {"dst": "0.0.0.0/0"}
        ]
      }
    }
  ]
}

I also modified 10-DNS.sh:

# ...
IPV4_IP="[PIHOLE IP]"
UNBOUND_IPV4_IP="[UNBOUND IP]"
# ...
IPV6_IP=""
UNBOUND_IPV6_IP=""
# ...
CONTAINER=pihole
UNBOUND_CONTAINER=unbound
#Removed Extraneous Lines
ip route add ${IPV4_IP}/32 dev br${VLAN}.mac
ip route add ${UNBOUND_IPV4_IP}/32 dev br${VLAN}.mac
# ...
if [ -n "${IPV6_IP}" ]; then
  ip -6 route add ${IPV6_IP}/128 dev br${VLAN}.mac
fi

if [ -n "${UNBOUND_IPV6_IP}" ]; then
  ip -6 route add ${UNBOUND_IPV6_IP}/128 dev br${VLAN}.mac
fi
# ...
if podman container exists ${UNBOUND_CONTAINER}; then
  podman start ${UNBOUND_CONTAINER}
else
  logger -s -t podman-dns -p ERROR Container $UNBOUND_CONTAINER not found, make sure you set the proper name, you can ignore this error if it is your first time setting it up
fi

if podman container exists ${CONTAINER}; then
  podman start ${CONTAINER}
else
  logger -s -t podman-dns -p ERROR Container $CONTAINER not found, make sure you set the proper name, you can ignore this error if it is your first time setting it up
fi
# ...

Finally, I have created the directory /mnt/data/unbound, in it I have unbound.conf and the various key files needed for unbound-control (these can be created by unbound-control-setup), unbound.conf is as follows:

server:
    verbosity: 1
    interface: 0.0.0.0
    interface: ::0
    # The container doesn't seem to support using a privileged port - I'm sure it probably could with the right capabilities enabled, but it doesn't really matter so I've not looked into it
    port: 5353
    prefer-ip6: no
    do-ip4: yes
    do-ip6: no
    access-control: 0.0.0.0/0 refuse
    access-control: 127.0.0.0/8 allow
    access-control: 192.168.2.2/24 allow # IP address of piHole
    access-control: ::0/0 refuse
    access-control: ::1 allow
    # This is better for security
    private-address: 10.0.0.0/8
    private-address: 172.16.0.0/12
    private-address: 192.168.0.0/16
    private-address: 169.254.0.0/16
    private-address: fd00::/8
    private-address: fe80::/10
    private-address: ::ffff:0:0/96
    # Set to your internal domain
    private-domain: "int.example.com"
    # Enable if your domain uses DNSSEC
    domain-insecure: "int.example.com"
    # this allows for reverse DNS lookups of local IP addresses, might need the others uncommented and changed to transparent if needed or if using IPv6
    local-zone: "10.in-addr.arpa." transparent
    local-zone: "16.172.in-addr.arpa." transparent
    local-zone: "17.172.in-addr.arpa." transparent
    local-zone: "18.172.in-addr.arpa." transparent
    local-zone: "19.172.in-addr.arpa." transparent
    local-zone: "20.172.in-addr.arpa." transparent
    local-zone: "21.172.in-addr.arpa." transparent
    local-zone: "22.172.in-addr.arpa." transparent
    local-zone: "23.172.in-addr.arpa." transparent
    local-zone: "24.172.in-addr.arpa." transparent
    local-zone: "25.172.in-addr.arpa." transparent
    local-zone: "26.172.in-addr.arpa." transparent
    local-zone: "27.172.in-addr.arpa." transparent
    local-zone: "28.172.in-addr.arpa." transparent
    local-zone: "29.172.in-addr.arpa." transparent
    local-zone: "30.172.in-addr.arpa." transparent
    local-zone: "31.172.in-addr.arpa." transparent
    local-zone: "168.192.in-addr.arpa." transparent
    # local-zone: "0.in-addr.arpa." nodefault
    # local-zone: "254.169.in-addr.arpa." nodefault
    # local-zone: "2.0.192.in-addr.arpa." nodefault
    # local-zone: "100.51.198.in-addr.arpa." nodefault
    # local-zone: "113.0.203.in-addr.arpa." nodefault
    # local-zone: "255.255.255.255.in-addr.arpa." nodefault
    # local-zone: "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault
    # local-zone: "d.f.ip6.arpa." nodefault
    # local-zone: "8.e.f.ip6.arpa." nodefault
    # local-zone: "9.e.f.ip6.arpa." nodefault
    # local-zone: "a.e.f.ip6.arpa." nodefault
    # local-zone: "b.e.f.ip6.arpa." nodefault
    # local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault
    tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt"
python:

dynlib:

# Set to your UDM's IP, enabled DNS lookups for your local domain, and RDNS lookups for private IPs
forward-zone:
    name: "int.example.com."
    forward-addr: 192.168.1.1
forward-zone:
    name: "10.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "16.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "17.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "18.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "19.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "20.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "21.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "22.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "23.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "24.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "25.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "26.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "27.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "28.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "29.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "30.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "31.172.in-addr.arpa."
    forward-addr: 192.168.1.1
forward-zone:
    name: "168.192.in-addr.arpa."
    forward-addr: 192.168.1.1

# This uses cloudflare's DoT servers
forward-zone:
    name: "."
    forward-tls-upstream: yes
    forward-addr: 1.1.1.1@853#cloudflare-dns.com
    forward-addr: 1.0.0.1@853#cloudflare-dns.com

# Enables remote control, not strictly needed - can control using podman exec unbound unbound-control
remote-control:
    control-enable: yes
    control-interface: 127.0.0.1
    control-port: 8953
    server-key-file: "/opt/unbound/etc/unbound/unbound_server.key"
    server-cert-file: "/opt/unbound/etc/unbound/unbound_server.pem"
    control-key-file: "/opt/unbound/etc/unbound/unbound_control.key"
    control-cert-file: "/opt/unbound/etc/unbound/unbound_control.pem"

my podman command was: podman run -d -it --network unbound --restart always --name unbound -v "/mnt/data/unbound/:/opt/unbound/etc/unbound" -v "/etc/ssl/certs/:/etc/ssl/certs:ro" --hostname unbound.int.example.com klutchell/unbound:latest

1activegeek commented 3 years ago

Thanks for this - I had a feeling there was a few things to do at play, but having this listed out now means multiple of us can start testing and validating as well. Much appreciated!!

boostchicken commented 3 years ago

Added cloudflared to run-pihole