Remote & local Access
Access your home services via a secure URL from anywhere in the world. This guide covers setting up AdGuard Home for custom DNS, Nginx Proxy Manager for wildcard SSL certificates via Cloudflare and Tailscale for a zero-config VPN mesh.
References
-
Tailscale
Install and configure the Tailscale client to establish a secure mesh network and manage node connectivity.
-
Install
Terminal window curl -fsSL https://tailscale.com/install.sh | sh -
Optimizations for subnet routers and exit nodes (optional)
Enable IP forwarding and adjust network interface offloading to maximize throughput for routed traffic.
Network performance
Terminal window NETDEV=$(ip -o route get 1.1.1.1 | cut -f 5 -d " ")sudo ethtool -K $NETDEV rx-udp-gro-forwarding on rx-gro-list offPersist on reboot
Terminal window printf '#!/bin/shethtool -K %s rx-udp-gro-forwarding on rx-gro-list off' "$(ip -o route get 1.1.1.1 | cut -f 5 -d " ")" | sudo tee /etc/networkd-dispatcher/routable.d/50-tailscalesudo chmod 755 /etc/networkd-dispatcher/routable.d/50-tailscaleEnable IP forwarding
Terminal window echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.confecho 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.confsudo sysctl -p /etc/sysctl.d/99-tailscale.conf -
Start
Terminal window sudo tailscale up --advertise-routes={{SUBNET_VAR}} --accept-dns=false --advertise-exit-node --accept-routes=false -
Admin console
- Go to https://login.tailscale.com/admin/machines.
- Approve
exit nodeandsubnet routesfor your device. - Go to DNS > Nameservers.
- Add Nameserver: Select
Custom. - IP address: Enter your
Tailscale IP(100.x.y.z). - Override Local DNS: toggle to
ON.
-
-
Docker
Deploy AdGuard Home and Nginx Proxy Manager as containerized services for network filtering and reverse proxying.
-
Make directory
Terminal window mkdir -p {{DOCKER_PATH_VAR}}/dns-proxy && cd {{DOCKER_PATH_VAR}}/dns-proxy -
compose.yml
Terminal window nano compose.ymlcompose.yml services:adguard:image: adguard/adguardhomecontainer_name: adguardrestart: unless-stoppedvolumes:- ./adguard/work:/opt/adguardhome/work- ./adguard/conf:/opt/adguardhome/confnetwork_mode: hostnpm:image: "jc21/nginx-proxy-manager:latest"container_name: npmrestart: unless-stoppednetwork_mode: hostvolumes:- ./npm/data:/data- ./npm/letsencrypt:/etc/letsencryptenvironment:- DB_SQLITE_FILE=/data/database.sqlitecompose.yml services:adguard:image: adguard/adguardhomecontainer_name: adguardrestart: unless-stoppedvolumes:- ./adguard/work:/opt/adguardhome/work- ./adguard/conf:/opt/adguardhome/confnetwork_mode: hostadguardhome-sync:image: ghcr.io/bakito/adguardhome-sync:latestcontainer_name: adguardhome-synccommand: runenvironment:ORIGIN_URL: ${ORIGIN_URL}ORIGIN_USERNAME: ${ORIGIN_USERNAME}ORIGIN_PASSWORD: ${ORIGIN_PASSWORD}REPLICA_URL: ${REPLICA_URL}REPLICA_USERNAME: ${REPLICA_USERNAME}REPLICA_PASSWORD: ${REPLICA_PASSWORD}CRON: "*/10 * * * *"RUN_ON_START: "true"npm:image: "jc21/nginx-proxy-manager:latest"container_name: npmrestart: unless-stoppednetwork_mode: hostvolumes:- ./npm/data:/data- ./npm/letsencrypt:/etc/letsencryptenvironment:- DB_SQLITE_FILE=/data/database.sqlitekeepalived:image: osixia/keepalived:latestcontainer_name: keepalivedrestart: unless-stoppednetwork_mode: hostcap_add:- NET_ADMIN- NET_BROADCAST- NET_RAWvolumes:# optional- ./keepalived/keepalived.conf:/etc/keepalived/keepalived.conf:roenvironment:- KEEPALIVED_STATE=MASTER # MASTER | BACKUP- KEEPALIVED_INTERFACE=enp3s0 # eth0 | enp3s0 | wlan0- KEEPALIVED_VIRTUAL_ROUTER_ID=51- KEEPALIVED_PRIORITY=101- KEEPALIVED_UNICAST_PEERS={{CLIENT_IP_VAR}} # Peers/other devices- KEEPALIVED_VIRTUAL_IPS={{VIRTUAL_IP_VAR}}/24- KEEPALIVED_PASSWORD=${KEEPALIVED_PASSWORD}Terminal window nano .env.env ORIGIN_URL=http://{{SERVER_IP_VAR}}:8080ORIGIN_USERNAME=adminORIGIN_PASSWORD=passwordREPLICA_URL=http://{{CLIENT_IP_VAR}}:8080REPLICA_USERNAME=adminREPLICA_PASSWORD=passwordKEEPALIVED_PASSWORD=passwordkeepalived.conf (Optional)
Terminal window mkdir -p ./keepalived && nano ./keepalived/keepalived.conf./keepalived/keepalived.conf global_defs {enable_script_securityscript_user root}vrrp_script check_adguard {script "/usr/bin/killall -0 adguardhome"interval 2weight 2}vrrp_instance VI_1 {state MASTER # MASTER | BACKUPinterface enp3s0 # eth0 | enp3s0 | wlan0virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass password # Change max 8 characters}virtual_ipaddress {{{VIRTUAL_IP_VAR}}/24}track_script {check_adguard}}
-
Fix port conflict (53)
Disable the stub listener
Terminal window sudo nano /etc/systemd/resolved.confSet
DNSStubListener=noRestart systemd-resolved
Terminal window sudo systemctl restart systemd-resolved -
Start container
Terminal window docker compose up -d
-
-
Cloudflare
Generate a scoped API token to automate DNS record management and SSL certificate validation.
- Go to Dashboard > My Profile > API Tokens.
- Create Token: Use the
Edit zone DNS template. - Permissions: Select
Zone|DNS|Edit. - Zone Resources: Select
Include|Specific zone|your-domain.tld.
-
AdGuard Home
Complete the initial web setup to manage network-wide DNS filtering and security rules.
-
Initial setup
- Go to http://localhost:3000 or http://{{SERVER_IP_VAR}}:3000
- Admin Web Interface.
- Listen interface: Select
All interfaces. - Port: Change to
8080.
-
DNS rewrites
- Go to http://localhost:8080 or http://{{SERVER_IP_VAR}}:8080
- Go to Filters > DNS Rewrites.
- Click Add DNS rewrite.
- Domain name:
*.lan.your-domain.tld. - IP address: Enter your device IP
{{SERVER_IP_VAR}}or virtual IP{{VIRTUAL_IP_VAR}}.
-
Blocklists (optional)
- Go to Filters > DNS Blocklists > Add Blocklist:
Choose from the list.- AdGuard DNS filter
- AdAway Default Blocklist
- HaGeZi’s Pro++ Blocklist
- OISD Blocklist Small
- OISD Blocklist Big
- HaGeZi’s Samsung Tracker Blocklist
- Go to Filters > DNS Blocklists > Add Blocklist:
-
General settings (optional)
- Go to Settings > General Settings.
- Use AdGuard
browsing securityweb service. - Use AdGuard
parental controlweb service. - Use
Safe Search.
- Use AdGuard
- Go to Settings > General Settings.
-
DNS settings (optional)
-
Go to Settings > DNS settings.
-
Upstream DNS servers.
https://dns.quad9.net/dns-queryhttps://dns.cloudflare.com/dns-queryhttps://dns.adguard-dns.com/dns-query- Enter the DNS providers above.
- Click
apply.
-
DNS server configuration.
- Enable DNSSEC.
- Click
save.
-
Access Settings > Allowed clients.
100.64.0.0/10{{SUBNET_VAR}}- Add Tailscale and device IP ranges above.
- Leave blank to allow all.
- Click
Save configuration.
-
-
-
Filters (optional)
-
Go to Filters > Custom filtering rules.
@@||tailscale.com^@@||tailscale.io^@@||log.tailscale.io^- Add Tailscale domains to allow.
- Click
Apply.
-
-
-
Nginx Proxy Manager
Access the administrative dashboard to route incoming traffic and manage SSL certificates for your services.
-
Certificate
- Go to http://localhost:81 or http://{{SERVER_IP_VAR}}:81
- Go to Certificates > Add Certificate > Let’s Encrypt via DNS.
- Domain Names: Enter
*.lan.your-domain.tld. - DNS Provider: Select
Cloudflare. - Credentials File Content: Replace
dns_cloudflare_api_token=YOUR_CLOUDFLARE_API_KEY. - Agree to terms and click
Save.
-
Proxy host
- In NPM, go to Hosts > Proxy Hosts > Add Proxy Host.
- Domain Names:
adguard.lan.your-domain.tld. - Scheme:
http. - Forward IP:
{{SERVER_IP_VAR}}. - Forward Port:
8080. - Block common exploits and Websockets support: toggle to
ON. - SSL Tab: Select the certificate you created.
- Force SSL and HTTP/2 Support: toggle to
ON. - Click
Save.
-
-
Router config
Update the Primary DNS, often located under LAN, DHCP or DNS Settings.
- Primary DNS:
{{SERVER_IP_VAR}}or{{VIRTUAL_IP_VAR}}(Your device’s Local LAN IP or virtual IP, not the Tailscale one). - Secondary DNS:
1.1.1.1(Fail-safe so your internet still works if your device is turned off).
- Primary DNS: