├── .gitattributes ├── .gitignore ├── .whitesource ├── README.md ├── dnscrypt ├── docker-compose.yml ├── gateway.sh └── guide │ ├── DHCP.md │ ├── diagram.md │ └── main.md ├── gateway.service ├── guide ├── PiVPN.md └── update.md ├── images ├── dhcp-helper │ └── Dockerfile ├── dnscrypt-proxy │ ├── Dockerfile │ └── entrypoint.sh ├── dnsmasq │ └── Dockerfile └── unbound │ ├── Dockerfile │ ├── entrypoint.sh │ └── unbound.conf ├── legacy ├── Advanced.md ├── DNSCrypt.md ├── Pi-Hole.md ├── PiVPN.md ├── VPNGateway.md └── main.md ├── set-route.sh └── unbound ├── docker-compose.yml ├── gateway-firewall.service ├── gateway-firewall.sh ├── gateway.sh ├── guide ├── DHCP.md ├── diagram.md └── main.md ├── setup.sh └── unbound.conf /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text eol=lf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "scanSettings": { 3 | "baseBranches": [] 4 | }, 5 | "checkRunSettings": { 6 | "vulnerableCheckRunConclusionLevel": "failure", 7 | "displayMode": "diff" 8 | }, 9 | "issueSettings": { 10 | "minSeverityLevel": "LOW" 11 | } 12 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## General 2 | The goal is to set up Pi-Hole to filter the DNS queries, DNSCrypt-Proxy or Unbound as DNS resolver, a VPN gateway (and a VPN server). 3 | I assume that all commands are executed as root and Raspberry Pi OS is used as operating system. Most other Debian distributions should be fine though with some minor changes. 4 | 5 | You might have to change some names and addresses. Depending on your environment you may have to adjust: 6 | - The name of your network interface (eth0) 7 | - The subnet and IP of your network interface (192.168.178.0/24 and 192.168.178.2) 8 | 9 | ## Variants 10 | 11 | - ### [Unbound](unbound/guide/main.md) [(Network diagram)](unbound/guide/diagram.md) 12 | 13 | - ### [DNSCrypt](dnscrypt/guide/main.md) [(Network diagram)](dnscrypt/guide/diagram.md) 14 | 15 | - ### [Legacy](legacy/main.md) 16 | I won't actively work on it anymore but keep it for anyone looking for a reference to maintain their existing setup. 17 | 18 | ## Issues etc. 19 | - If you encounter any issues please checkout the [Known-Issues](https://github.com/Trigus42/Private-LAN/wiki/Known-Issues) page in the wiki before you open up a new issue. 20 | - If anything is unclear to you, please feel free to ask using 'Discussions'. 21 | -------------------------------------------------------------------------------- /dnscrypt/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | wireguard-gw: 5 | image: linuxserver/wireguard 6 | container_name: wireguard-gw 7 | volumes: 8 | - '/etc/private-lan/volumes/wireguard-gw/:/config' 9 | networks: 10 | net: 11 | ipv4_address: 172.16.238.2 12 | restart: unless-stopped 13 | privileged: true 14 | cap_add: 15 | - NET_ADMIN 16 | - SYS_MODULE 17 | 18 | dnsmasq: 19 | build: images/dnsmasq 20 | container_name: dnsmasq 21 | networks: 22 | net: 23 | ipv4_address: 172.16.238.3 24 | expose: 25 | - "67/udp" 26 | - "68/tcp" 27 | volumes: 28 | - '/etc/private-lan/volumes/dnsmasq/:/etc/dnsmasq.d/' 29 | restart: unless-stopped 30 | cap_add: 31 | - NET_ADMIN 32 | depends_on: 33 | - dhcp-helper 34 | 35 | pihole: 36 | image: pihole/pihole:latest 37 | container_name: pihole 38 | networks: 39 | net: 40 | ipv4_address: 172.16.238.4 41 | ports: 42 | - "192.168.178.2:53:53/tcp" 43 | - "192.168.178.2:53:53/udp" 44 | - "192.168.178.2:80:80/tcp" 45 | - "192.168.178.2:443:443/tcp" 46 | environment: 47 | DNS1: '172.16.238.5' 48 | DNS2: 'no' 49 | DNSMASQ_LISTENING: 'all' 50 | volumes: 51 | - '/etc/private-lan/volumes/pihole/:/etc/pihole/' 52 | cap_add: 53 | - NET_ADMIN 54 | - SYS_NICE 55 | restart: unless-stopped 56 | depends_on: 57 | - dnscrypt-proxy 58 | 59 | dnscrypt-proxy: 60 | build: images/dnscrypt-proxy 61 | container_name: dnscrypt-proxy 62 | networks: 63 | net: 64 | ipv4_address: 172.16.238.5 65 | expose: 66 | - "53/udp" 67 | - "53/tcp" 68 | volumes: 69 | - '/etc/private-lan/volumes/dnscrypt-proxy/:/config/' 70 | restart: always 71 | cap_add: 72 | - NET_ADMIN 73 | 74 | dhcp-helper: 75 | build: images/dhcp-helper 76 | container_name: dhcp-helper 77 | restart: unless-stopped 78 | network_mode: "host" 79 | command: -s 172.16.238.3 80 | cap_add: 81 | - NET_ADMIN 82 | 83 | networks: 84 | net: 85 | driver: bridge 86 | driver_opts: 87 | com.docker.network.enable_ipv6: "true" 88 | ipam: 89 | driver: default 90 | config: 91 | - subnet: 172.16.238.0/24 92 | gateway: 172.16.238.1 93 | - subnet: 2001:3984:3989::/64 94 | gateway: 2001:3984:3989::1 -------------------------------------------------------------------------------- /dnscrypt/gateway.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get default interface with lowest metric 4 | lan_if="$(ip route | awk 'FNR == 1 {print $(5)}')" 5 | # Overwrite interface 6 | #lan_if="eth0" 7 | 8 | # Get environment variables 9 | docker_if="br-$(docker network ls | grep private-lan_net | cut -d' ' -f1)" 10 | docker_if_ip="$(ip -4 addr show "$docker_if" | grep -oP '(?<=inet\s)\d+(\.\d+){3}')" 11 | docker_if_subnet="$(ip -o -f inet addr show "$docker_if" | awk '/scope global/ {print $4}' | perl -ne 's/(?<=\d.)\d{1,3}(?=\/)/0/g; print;')" 12 | lan_subnet="$(ip -o -f inet addr show "$lan_if" | awk '/scope global/ {print $4}' | perl -ne 's/(?<=\d.)\d{1,3}(?=\/)/0/g; print;')" 13 | wireguard_gateway_ip="$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' wireguard-gw)" 14 | #default_gateway="$(ip route show default dev "$lan_if" | awk '/default/ { print $3 }')" 15 | 16 | # Default route in a new routing table via the VPN Gateway 17 | ip route add default via "$wireguard_gateway_ip" table 200 18 | # Use new table for all packets from lan_if 19 | ip rule add from all iif "$lan_if" lookup 200 20 | # Use main routing table first but only match if at least the first bit of an IP range in it is matching the destination IP. It won't match 0.0.0.0/0 ("default") 21 | ip rule add from all lookup main suppress_prefixlength 0 22 | 23 | # Uncomment if you want the host to use the VPN tunnel too 24 | # Route all traffic trough the Wireguard tunnel except for the the "wireguard_gateway" container traffic 25 | # ip route add default via $default_gateway table 201 26 | # ip rule add from $wireguard_gateway_ip lookup 201 27 | # ip route replace default via $wireguard_gateway_ip 28 | 29 | # Allow forwarding from lan_if trough the docker interface to the Wireguard gateway 30 | if ! eval "iptables -C FORWARD -i "$lan_if" -o $docker_if -d $wireguard_gateway_ip -j ACCEPT &> /dev/null"; then 31 | iptables -I FORWARD -i "$lan_if" -o "$docker_if" -d "$wireguard_gateway_ip" -j ACCEPT 32 | fi 33 | 34 | # Replace the source IP of packets going out trough the docker interface to the Wireguard container 35 | if ! eval "iptables -t nat -C POSTROUTING ! -s $docker_if_subnet -d $wireguard_gateway_ip -o $docker_if -j MASQUERADE &> /dev/null"; then 36 | iptables -t nat -I POSTROUTING ! -s "$docker_if_subnet" -d "$wireguard_gateway_ip" -o "$docker_if" -j MASQUERADE 37 | fi 38 | 39 | # Wait until the pihole container finished start up 40 | until eval "/usr/bin/docker inspect -f {{.State.Running}} pihole"; do 41 | sleep 0.1; 42 | done; 43 | 44 | # Set the default route of the "pihole" container to the "wireguard_gateway" container and add an exception for packets addressed to the LAN or Wireguard clients 45 | bash /etc/private-lan/set-route.sh pihole "$wireguard_gateway_ip" "$docker_if_ip" "$lan_subnet" 10.6.0.0/24 46 | 47 | # Reconfigure the routing table each time the container "pihole" is restarted 48 | docker events --filter "container=pihole" | awk '/container (start|restart)/ { system("/etc/private-lan/set-route.sh pihole '"$wireguard_gateway_ip"' '"$docker_if_ip"' '"$lan_subnet"' 10.6.0.0/24") }' 49 | -------------------------------------------------------------------------------- /dnscrypt/guide/DHCP.md: -------------------------------------------------------------------------------- 1 | #### DHCP config 2 | 3 | Create a .conf file like ```/etc/private-lan/volumes/dnsmasq/dhcp.conf```. 4 | To configure your DHCP server refer to the [official documentaion](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html). 5 | 6 | Just for orientation, here is how my config looks like: 7 | 8 | ```xml 9 | dhcp-authoritative 10 | 11 | ## New devices default ## 12 | dhcp-range=192.168.178.200,192.168.178.254,24h 13 | # Gateway 14 | dhcp-option-force=3,192.168.178.2 15 | # DNS1 and DNS2 16 | dhcp-option-force=6,192.168.178.2,192.168.178.2 17 | 18 | ## Known devices (static IP address) default ## 19 | # Devices in the IP range .20 - .199 are assigned to tag '0' 20 | dhcp-range=set:0,192.168.178.20,192.168.178.199,24h 21 | dhcp-option-force=tag:0,3,192.168.178.1 22 | dhcp-option-force=tag:0,6,192.168.178.2,192.168.178.2 23 | 24 | ## Settings for devices which were assigned the 'VPN' tag ## 25 | dhcp-option-force=tag:VPN,3,192.168.178.2 26 | dhcp-option-force=tag:VPN,6,192.168.178.2,192.168.178.2 27 | 28 | dhcp-leasefile=/etc/dnsmasq.d/dhcp.leases 29 | #quiet-dhcp 30 | 31 | domain=lan 32 | dhcp-rapid-commit 33 | ``` 34 | 35 | Example for the static DHCP leases: 36 | 37 | ```xml 38 | # /etc/private-lan/volumes/dnsmasq.d/static-leases.conf 39 | 40 | dhcp-host=81:7d:22:a2:3e:7d,192.168.178.20,PC-VPN,set:VPN 41 | dhcp-host=81:7d:22:a2:3e:7e,192.168.178.21,PC 42 | ``` 43 | 44 | #### Restart dnsmasq 45 | 46 | $ docker restart dnsmasq 47 | 48 | #### Disable other DHCP servers 49 | 50 | Most likely you have to disable the DHCP server of your router. How to do this depends on the router but while some may not allow you to configure a custom DNS server, there is almost always an option to turn off it's DHCP server. 51 | -------------------------------------------------------------------------------- /dnscrypt/guide/diagram.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LAN 3 | +---------------------------------------------------------------------------------------------------------------------+ 4 | | Docker Host | 5 | | +-----------+ +-------------------------------------------------------------------------------------------+ | 6 | | | | | | | 7 | | | Router | | +-----------+ | | 8 | | | WAN | | | | | | 9 | | | | | Gateway | Docker | | | 10 | | | | <----------------------------+ | Interface | | | 11 | | | | | | | Docker | | 12 | | | | | +---------------------------------------------------------------------+ | | 13 | | | | | | | | | | | 14 | | +-----------+ | | | | Gateway +-------------------------+ | | | 15 | | | | | | <-------+ | | <--+ | | | 16 | | +-----------+ | | +-----------+ | Wireguard-Gateway | | | | | 17 | | | | Gateway | Static Route | | | <+ | | | | 18 | | | | +----------------------------------------------------> +-------------------------+ | | | | | 19 | | | | | | | | | | | 20 | | | | | | +-------------------------+ | | | | | 21 | | | | | | | | | | | | | 22 | | | | | | | DNSCrypt-Proxy | + | Gateway | | | 23 | | | | | | +> | | | | | | 24 | | | | | | | +-------------------------+ | | | | 25 | | | | | | DNS | | | | | 26 | | | | | | + +-------------------------+ | | | | 27 | | | | DNS | DNAT | | | | | | | 28 | | | Clients | +-------------------> +-----------------------------> | Pi-Hole | +--+ | | | 29 | | | | | | | | | | | 30 | | | | | | +> +-------------------------+ | | | 31 | | | | | | | | | | 32 | | | | | | DHCP | +-------------------------+ | | | 33 | | | | | | | | | | | | 34 | | | | | | + | DHCP-Helper | | | | 35 | | | | DHCP | | | | | | | 36 | | | | +----------------------------------------------------> +-------------------------+ | | | 37 | | | | | | | | | 38 | | | | | +---------------------------------------------------------------------+ | | 39 | | | | | | | 40 | | +-----------+ +-------------------------------------------------------------------------------------------+ | 41 | | | 42 | +---------------------------------------------------------------------------------------------------------------------+ 43 | ``` -------------------------------------------------------------------------------- /dnscrypt/guide/main.md: -------------------------------------------------------------------------------- 1 | # Download files: 2 | 3 | $ git clone https://github.com/Trigus42/Private-LAN /etc/private-lan 4 | 5 | #### Create volume directories: 6 | 7 | $ mkdir -p /etc/private-lan/volumes/{unbound,dnsmasq,wireguard-gw,pihole/{gravity,pihole/{dnsmasq,pihole}}} 8 | 9 | #### Move compose file to /etc/private-lan: 10 | 11 | $ mv /etc/private-lan/dnscrypt/docker-compose.yml /etc/private-lan/ 12 | 13 | #### Edit docker-compose file: 14 | 15 | Edit the IPs in the port section of the pihole and pihole-vpn container in /etc/private-lan/docker-compose.yml to match your network environment. 16 | 17 | # Network configuration 18 | 19 | Add this to /etc/network/interfaces to set a static IP: 20 | 21 | ``` 22 | auto eth0 23 | allow-hotplug eth0 24 | iface eth0 inet static 25 | address 192.168.178.2 26 | netmask 255.255.255.0 27 | gateway 192.168.178.1 28 | dns-nameservers 8.8.8.8 1.1.1.1 29 | dns-search domain-name 30 | ``` 31 | 32 | #### Disable DHCP: 33 | 34 | $ systemctl disable dhcpcd 35 | 36 | #### Apply network changes: 37 | 38 | $ systemctl restart networking.service 39 | 40 | # Setup Docker 41 | 42 | #### Install Docker Engine: 43 | 44 | $ curl -fsSL https://get.docker.com | bash 45 | 46 | #### Install Docker Compose: 47 | 48 | $ apt install python3-pip -y && pip3 install docker-compose 49 | 50 | #### Enable Docker to start on boot: 51 | 52 | $ systemctl enable docker 53 | 54 | # Install Wireguard 55 | #### Install the Wireguard kernel module if your are on Debain Buster or lower : 56 | 57 | ``` 58 | $ echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list 59 | $ wget -O - https://ftp-master.debian.org/keys/archive-key-$(lsb_release -sr).asc | sudo apt-key add - 60 | $ printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable 61 | $ apt update 62 | ``` 63 | On Rapberry PI OS run: 64 | 65 | $ apt install raspberrypi-kernel-headers wireguard -y 66 | 67 | On any standard Debian installation run: 68 | 69 | $ apt install linux-headers-$(uname -r) wireguard -y 70 | 71 | #### If you are on Bullseye or higher run: 72 | 73 | $ apt install wireguard -y 74 | 75 | #### Wireguard config 76 | 77 | Download your config file and place it in ```/etc/private-lan/volumes/wireguard-gw``` as ```wg0.conf```. 78 | Insert the following lines in the Wireguard config file below `[Interface]`: 79 | ``` 80 | # Don't allow forwarding from eth0 to eth0 (bypassing the VPN gateway) 81 | PreUp = iptables -I FORWARD -i eth0 -o eth0 -j REJECT 82 | # Replace the source IP of packets going out trough the Wireguard interface AND add a route to your subnet (https://unix.stackexchange.com/questions/615255/docker-container-as-network-gateway) 83 | PostUp = iptables -t nat -A POSTROUTING -o %i -j MASQUERADE && ip route add via 172.16.238.1 84 | PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE && ip route delete via 172.16.238.1 85 | ``` 86 | 87 |
88 | Example 89 | 90 | ``` 91 | [Interface] 92 | PrivateKey = ... 93 | Address = 100.64.67.64/32 94 | DNS = 10.255.255.3 95 | 96 | PreUp = iptables -I FORWARD -i eth0 -o eth0 -j REJECT 97 | PostUp = iptables -t nat -A POSTROUTING -o %i -j MASQUERADE && ip route add 192.168.178.0/24 via 172.16.238.1 98 | PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE && ip route delete 192.168.178.0/24 via 172.16.238.1 99 | 100 | [Peer] 101 | PublicKey = ... 102 | AllowedIPs = 0.0.0.0/0 103 | Endpoint = lon-229-wg.whiskergalaxy.com:443 104 | PresharedKey = ... 105 | ``` 106 |
107 | 108 | Assign permissions and ownership (No one but root should be able to see Private Key and PSK): 109 | 110 | $ chown -R root:root /etc/private-lan/volumes/wireguard-gw 111 | $ chmod 600 -R /etc/private-lan/volumes/wireguard-gw 112 | 113 | # DNSCrypt-Proxy: 114 | 115 | $ wget https://raw.githubusercontent.com/DNSCrypt/dnscrypt-proxy/release/dnscrypt-proxy/example-dnscrypt-proxy.toml -O /etc/private-lan/volumes/dnscrypt-proxy/dnscrypt-proxy.toml 116 | 117 | Change in ``/etc/private-lan/volumes/dnscrypt-proxy/dnscrypt-proxy.toml``: 118 | ```yaml 119 | listen_addresses = ['0.0.0.0:53'] 120 | ``` 121 |
122 | Examples for some optional settings 123 | 124 | ```xml 125 | server_names = [’ ’, ’ ’] ## If you want to use specific servers 126 | ipv6_servers = false ## “true” if your VPN service supports IPv6 127 | require_dnssec = true # I would recommend it for security reasons 128 | require_nolog = true ## I would recommend it for privacy reasons 129 | 130 | ## Insert below “[sources]”: 131 | [sources.’’] 132 | urls = [’’, ‘’] 133 | minisign_key = ‘’ 134 | cache_file = ‘’ 135 | 136 | ## No really needed because the request are already sent over the VPN 137 | ## Insert below “[anonymized_dns]”: 138 | routes = [ 139 | { server_name=’ ’, via=[’ ’,<…>] }, 140 | { server_name=’’, via=[’ ’,<…>] } 141 | ] 142 | ``` 143 | [Server/Relay lists ("Sources")](https://github.com/DNSCrypt/dnscrypt-resolvers/tree/master/v3) 144 | [More info about the servers](https://github.com/dyne/dnscrypt-proxy/blob/master/dnscrypt-resolvers.csv) 145 |
146 | 147 | # Setup routing and NAT 148 | 149 | ``` 150 | $ mv /etc/private-lan/dnscrypt/gateway.sh /etc/init.d/ 151 | $ mv /etc/private-lan/gateway.service /etc/systemd/system/ 152 | ``` 153 | 154 | #### Make the scripts executable 155 | ``` 156 | $ chmod +x /etc/init.d/gateway.sh 157 | $ chmod +x /etc/private-lan/set-route.sh 158 | ``` 159 | 160 | #### Enable as a new service 161 | ``` 162 | $ systemctl daemon-reload 163 | $ systemctl enable gateway.service 164 | ``` 165 | 166 | #### Edit kernel parameters to enable IP forwarding and enhance security: 167 | Uncomment/paste in /etc/sysctl.conf: 168 | ```yaml 169 | #IP Forwarding 170 | net.ipv4.ip_forward = 1 171 | #IP Spoofing protection 172 | net.ipv4.conf.all.rp_filter = 1 173 | net.ipv4.conf.default.rp_filter = 1 174 | #Ignore ICMP broadcast requests 175 | net.ipv4.icmp_echo_ignore_broadcasts = 1 176 | #Ignore ICMP redirects 177 | net.ipv4.conf.all.accept_redirects = 0 178 | net.ipv6.conf.all.accept_redirects = 0 179 | #Ignore send redirects 180 | net.ipv4.conf.all.send_redirects = 0 181 | net.ipv4.conf.default.send_redirects = 0 182 | #Disable source packet routing 183 | net.ipv4.conf.all.accept_source_route = 0 184 | net.ipv6.conf.all.accept_source_route = 0 185 | net.ipv4.conf.default.accept_source_route = 0 186 | net.ipv6.conf.default.accept_source_route = 0 187 | # Block SYN attacks 188 | net.ipv4.tcp_syncookies = 1 189 | net.ipv4.tcp_max_syn_backlog = 2048 190 | net.ipv4.tcp_synack_retries = 2 191 | net.ipv4.tcp_syn_retries = 5 192 | # Log Martians 193 | net.ipv4.conf.all.log_martians = 1 194 | net.ipv4.conf.default.log_martians=1 195 | ``` 196 | Load these changes: 197 | 198 | $ sysctl -p /etc/sysctl.conf 199 | 200 | *More info about these settings: 201 | [IP Spoofing](http://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.kernel.rpf.html) 202 | [ICMP broadcast requests](https://www.cloudflare.com/learning/ddos/smurf-ddos-attack/) 203 | [ICMP redirects](https://askubuntu.com/questions/118273/what-are-icmp-redirects-and-should-they-be-blocked) 204 | [Source packet routing](https://www.ccexpert.us/basic-security-services/disable-ip-source-routing.html) 205 | [SYN attacks](https://www.symantec.com/connect/articles/hardening-tcpip-stack-syn-attacks)* 206 | 207 | # Start everything up 208 | 209 | $ docker-compose -f /etc/private-lan/docker-compose.yml up -d 210 | $ systemctl start gateway.service 211 | 212 | #### Set the Pi-Hole web interface password 213 | 214 | $ docker exec -it pihole pihole -a -p 215 | 216 | #### Client setup 217 | 218 | You can now manually configure your server as network gateway and DNS server. 219 | However it's much more convenient to simply activate the DHCP server build into Pi-Hole. 220 | 221 | # Optional 222 | 223 | - ### [DHCP server](./DHCP.md) 224 | - ### [PiVPN](/guide/PiVPN.md) 225 | - ### [Updating](/guide/update.md) 226 | -------------------------------------------------------------------------------- /gateway.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=adding routes and rules to enable the Docker Wireguard gateway 3 | After=docker.service 4 | 5 | [Service] 6 | ExecStart=/etc/init.d/gateway.sh 7 | 8 | [Install] 9 | WantedBy=default.target -------------------------------------------------------------------------------- /guide/PiVPN.md: -------------------------------------------------------------------------------- 1 | #### Install PiVPN: 2 | $ curl -L https://install.pivpn.io | bash 3 | - Choose Wireguard as VPN type 4 | - If you got a changing public IP use a [DynDNS](https://wiki.archlinux.org/index.php/Dynamic_DNS) provider like [dynv6](https://dynv6.com/) 5 | - Don't change your interface config from what you configured before (/etc/dhcpcd.conf) 6 | 7 | #### Adjust routes: 8 | In ```/etc/init.d/gateway.sh``` uncomment: 9 | 10 | ip route add 10.6.0.0/24 via 10.6.0.1 table 200 11 | 12 | Reboot or execute the command above yourself. 13 | 14 | #### Add clients: 15 | 16 | Now you can add clients by using `pivpn add`. 17 | 18 | #### Additional Step for Windows Clients: 19 | 20 | If you use WireGuard for Windows you may not be able to access your LAN right away. 21 | In that case you first need to add a route to your LAN via the tunnel: 22 | 23 | Execute as admin in the Windows Command Prompt: 24 | 25 | route ADD MASK 26 | 27 | e.g.: 28 | 29 | route ADD 192.168.178.0 MASK 255.255.255.0 10.6.0.1 30 | -------------------------------------------------------------------------------- /guide/update.md: -------------------------------------------------------------------------------- 1 | #### Update all containers: 2 | 3 | $ docker-compose -f /etc/private-lan/docker-compose.yml pull 4 | $ docker-compose -f /etc/private-lan/docker-compose.yml build --no-cache 5 | $ docker-compose -f /etc/private-lan/docker-compose.yml up -d 6 | $ systemctl restart gateway -------------------------------------------------------------------------------- /images/dhcp-helper/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.14 2 | 3 | RUN apk update; \ 4 | apk add --no-cache dhcp-helper; \ 5 | # clean up 6 | rm -rf /var/cache/apk/* /tmp/* 7 | 8 | EXPOSE 67 67/udp 9 | ENTRYPOINT ["dhcp-helper", "-n"] -------------------------------------------------------------------------------- /images/dnscrypt-proxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.14 2 | 3 | RUN apk update; \ 4 | apk add --no-cache dnscrypt-proxy bind-tools; \ 5 | # clean up 6 | rm -rf /var/cache/apk/* /tmp/* 7 | 8 | # add entrypoint file 9 | COPY entrypoint.sh / 10 | RUN chmod +x /entrypoint.sh 11 | ENTRYPOINT ["/entrypoint.sh"] 12 | 13 | # set build date 14 | RUN date >/build-date.txt 15 | -------------------------------------------------------------------------------- /images/dnscrypt-proxy/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "Starting dnscrypt-proxy, build date $(cat /build-date.txt)" 3 | 4 | # Start dnscrypt-proxy 5 | /usr/bin/dnscrypt-proxy -config /config/dnscrypt-proxy.toml 6 | -------------------------------------------------------------------------------- /images/dnsmasq/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.14 2 | 3 | RUN apk update; \ 4 | apk add --no-cache dnsmasq 5 | 6 | ENTRYPOINT ["/usr/sbin/dnsmasq", "-k"] 7 | 8 | # set build date 9 | RUN date >/build-date.txt -------------------------------------------------------------------------------- /images/unbound/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.14 2 | 3 | RUN apk update; \ 4 | apk add --no-cache bash ca-certificates bind-tools wget unbound 5 | 6 | RUN chown -R unbound:unbound /usr/share/dnssec-root/; \ 7 | chmod -R 744 /usr/share/dnssec-root/; \ 8 | chown -R unbound:unbound /etc/unbound/; \ 9 | chmod -R 744 /etc/unbound/; \ 10 | wget https://www.internic.net/domain/named.root -O /etc/unbound/root.hints 11 | 12 | EXPOSE 53/udp 53/tcp 13 | 14 | ADD unbound.conf /etc/unbound/ 15 | 16 | ADD entrypoint.sh / 17 | RUN chmod +x entrypoint.sh 18 | ENTRYPOINT ["/bin/sh","-c","/entrypoint.sh"] 19 | 20 | # set build date 21 | RUN date >/build-date.txt -------------------------------------------------------------------------------- /images/unbound/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Start unbound 4 | /usr/sbin/unbound -d -c /etc/unbound/unbound.conf -------------------------------------------------------------------------------- /images/unbound/unbound.conf: -------------------------------------------------------------------------------- 1 | # For further information read: https://nlnetlabs.nl/documentation/unbound/unbound.conf/ 2 | 3 | server: 4 | # Listen on all interfaces 5 | interface: 0.0.0.0 6 | interface: ::0 7 | 8 | # The port number, default 53, on which the server responds to queries. 9 | port: 53 10 | 11 | # If given, after binding the port the user privileges are dropped. 12 | # Default is "unbound". If you give username: "" no user change is performed. 13 | username: "unbound" 14 | 15 | # The netblock is given as an IP4 or IP6 address with /size appended for a 16 | # classless network block. The action can be deny, refuse, allow or allow_snoop. 17 | # Here 0.0.0.0/0 is used cause we run it in a container and access to it should 18 | # controlled by the host. 19 | access-control: 0.0.0.0/0 allow 20 | 21 | # If "" is given, logging goes to stderr, or nowhere once daemonized. 22 | logfile: "" 23 | 24 | # The verbosity number, level 0 means no verbosity, only errors. 25 | # Level 1 gives operational information. 26 | # Level 2 gives detailed operational information. 27 | # Level 3 gives query level information, output per query. 28 | # Level 4 gives algorithm level information. 29 | # Level 5 logs client identification for cache misses. 30 | # Default is level 1. The verbosity can also be increased from the commandline. 31 | verbosity: 0 32 | 33 | # Read the root hints from this file. Default is nothing, using 34 | # builtin hints for the IN class. The file has the format of zone 35 | # files, with root nameserver names and addresses only. The 36 | # default may become outdated, when servers change, therefore it 37 | # is good practice to use a root-hints file. 38 | root-hints: /etc/unbound/root.hints 39 | 40 | # File with trust anchor for one zone, which is tracked with RFC5011 probes. 41 | # The probes are several times per month, thus the machine must be online frequently. 42 | # The initial file can be one with contents as described in trust-anchor-file. 43 | # The file is written to when the anchor is updated, so the unbound user must 44 | # have write permission. 45 | auto-trust-anchor-file: /usr/share/dnssec-root/trusted-key.key -------------------------------------------------------------------------------- /legacy/Advanced.md: -------------------------------------------------------------------------------- 1 | # Optional settings 2 | 3 | ## Leak testing 4 | 5 | ### Command line: 6 | 7 | #### IP: 8 | ``` 9 | curl ifconfig.me 10 | ``` 11 | Output: 12 | ```xml 13 | 14 | ``` 15 | #### DNS: 16 | ``` 17 | dig whoami.akamai.net 18 | ``` 19 | Output: 20 | ```xml 21 | ; <<>> DiG 9.11.5-P4-5.1+deb10u1-Raspbian <<>> whoami.akamai.net 22 | ;; global options: +cmd 23 | ;; Got answer: 24 | ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45507 25 | ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 26 | 27 | ;; OPT PSEUDOSECTION: 28 | ; EDNS: version: 0, flags:; udp: 512 29 | ;; QUESTION SECTION: 30 | ;whoami.akamai.net. IN A 31 | 32 | ;; ANSWER SECTION: 33 | whoami.akamai.net. 180 IN A 34 | 35 | ;; Query time: 114 msec 36 | ;; SERVER: 127.0.0.1#53(127.0.0.1) 37 | ;; WHEN: Fri Jul 31 17:03:53 BST 2020 38 | ;; MSG SIZE rcvd: 62 39 | ``` 40 | 41 | ### Browser: 42 | 43 | #### IP and DNS: 44 | https://ipleak.net 45 | 46 | #### DNS - More detailed : 47 | https://dnsleaktest.com 48 | 49 | ## System: 50 | 51 | ### **unattended-upgrades:** 52 | 53 | Once the server is set up you shouldn't have to worry about security updates. 54 | "unattended-upgrades" frequently checks for - and installs - security updates. 55 | ``` 56 | apt install unattended-upgrades apt-listchanges 57 | dpkg-reconfigure -plow unattended-upgrades 58 | ``` 59 | 60 | ## [dnsmasq:](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html) 61 | 62 | ### **Exclude Devices**: 63 | 64 |
65 | Using different IP Ranges 66 | 67 | /etc/dnsmasq.d/02-pihole-dhcp.conf: 68 | ```xml 69 | dhcp-authoritative 70 | 71 | #Default IP Range 72 | dhcp-range=,,24h 73 | 74 | #IP Range 2 75 | dhcp-range=set:tag0,,,24h 76 | 77 | #Settings of Default IP Range 78 | dhcp-option=3, 79 | dhcp-option=6, 80 | 81 | #Settings of IP Range 2 82 | dhcp-option=tag:tag0,3, 83 | dhcp-option=tag:tag0,6, 84 | 85 | dhcp-leasefile=/etc/pihole/dhcp.leases 86 | #quiet-dhcp 87 | domain=lan 88 | 89 | dhcp-rapid-commit 90 | ``` 91 | 92 | Write-protect this file so you can't accidentally overwrite it using the Pi-Hole DHCP configurator. 93 | To unlock the file replace the '+' by a '-'. 94 | 95 | chattr +i 02-pihole-dhcp.conf 96 | 97 | Align IP addresses in the IP range's to the devices. 98 | 99 | 04-pihole-static-dhcp.conf: 100 | ```xml 101 | dhcp-host=,, 102 | ``` 103 | 104 |
105 | Example 106 | 107 | /etc/dnsmasq.d/02-pihole-dhcp.conf: 108 | ``` 109 | dhcp-authoritative 110 | #VPN 111 | dhcp-range=set:tag0,92.168.0.10,192.168.178.99,24h 112 | dhcp-option-force=tag:tag0,3,192.168.178.2 113 | dhcp-option=tag:tag0,6,192.168.178.2 114 | 115 | #Direct 116 | dhcp-range=set:tag1,192.168.178.100,192.168.178.199,24h 117 | dhcp-option=tag:tag1,3,192.168.178.1 118 | dhcp-option=tag:tag1,6,192.168.178.2 119 | 120 | dhcp-leasefile=/etc/pihole/dhcp.leases 121 | #quiet-dhcp 122 | domain=lan 123 | 124 | dhcp-rapid-commit 125 | ``` 126 | 04-pihole-static-dhcp.conf: 127 | ``` 128 | dhcp-host=81:7d:22:a2:3e:7d,192.168.178.10,VPN-Computer 129 | dhcp-host=81:7d:22:a2:3e:7e,192.168.178.100,Computer 130 | ``` 131 |
132 |
133 | 134 |
135 | Using tags only 136 | 137 | Insert in /etc/dnsmasq.d/02-pihole-dhcp.conf: 138 | ```xml 139 | dhcp-option=tag:,3, 140 | ``` 141 | 142 | 04-pihole-static-dhcp.conf: 143 | ```xml 144 | dhcp-host=,,,set: 145 | ``` 146 | 147 |
148 | Example 149 | 150 | In /etc/dnsmasq.d/02-pihole-dhcp.conf: 151 | ``` 152 | dhcp-option=tag:Direct,3,192.168.178.1 153 | dhcp-option=tag:VPN,3,192.168.178.2 154 | ``` 155 | 156 | 04-pihole-static-dhcp.conf: 157 | ``` 158 | dhcp-host=81:7d:22:a2:3e:7d,192.168.178.10,VPN-Computer,set:VPN 159 | dhcp-host=81:7d:22:a2:3e:7e,192.168.178.10,Computer,set:Direct 160 | ``` 161 |
162 |
163 | 164 | ## [iptables:](https://linux.die.net/man/8/iptables) 165 | **Important:** 166 | - IP-Tables rules are processed in the given order. To block a request for example, the corresponding rule must be set before the rule that generally allows requests of this type. 167 | - If you are using OpenVPN you have to replace wg0 by tun0 in the rules. 168 | 169 | ### **Set up a simple firewall:** 170 | 171 | Thanks to iptables-persistent, editing the configuration is simple. 172 | Depending on the configuration you edit (rules.v4/rules.v6) you just need to use the correct IP format (IPv4/IPv6) when it comes to your LAN IP range. 173 | 174 | /etc/iptables/rules.v*: 175 | ```xml 176 | *filter 177 | :INPUT DROP 178 | :TRUSTED_IP DROP 179 | :FORWARD DROP 180 | :OUTPUT ACCEPT 181 | 182 | -A INPUT -i lo -j ACCEPT 183 | -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 184 | -A INPUT -p icmp --icmp-type 8 -j ACCEPT 185 | -A INPUT -p udp --dport 67:68 -j ACCEPT 186 | -A INPUT -s -j TRUSTED_IP 187 | 188 | -A TRUSTED_IP -p udp --dport 53 -j ACCEPT 189 | -A TRUSTED_IP -p icmp -j ACCEPT 190 | -A TRUSTED_IP -p tcp --dport 80 -j ACCEPT 191 | -A TRUSTED_IP -p tcp --dport -j ACCEPT 192 | -A TRUSTED_IP -j REJECT 193 | 194 | -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 195 | #-A FORWARD --match multiport ! --dports -o wg0 -j REJECT 196 | -A FORWARD -s -o wg0 -j ACCEPT 197 | 198 | COMMIT 199 | 200 | *nat 201 | :PREROUTING ACCEPT 202 | :INPUT ACCEPT 203 | :POSTROUTING ACCEPT 204 | :OUTPUT ACCEPT 205 | 206 | -A POSTROUTING -o wg0 -j MASQUERADE 207 | 208 | COMMIT 209 | ``` 210 | *Example IP ranges: 211 | IPv4: 192.168.178.0/24 212 |          [192.168.178.1 - 192.168.178.255] 213 | IPv6: 2001:db8::/32 214 |          [2001:db8:0:0:0:0:0:0 - 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff]* 215 | 216 |
217 | What does it do? 218 | 219 | ## filter: 220 | - Drop incoming connections by default 221 | 222 | INPUT: 223 | - Allow packets being sent to the loopback interface 224 | - Allow packets of self-established connections or connections related to those 225 | - Allow pings 226 | - Allow DHCP packets 227 | - Pass packets coming from your LAN IP range to the "TRUSTED_IP" chain 228 | 229 | TRUSTED_IP: 230 | - Allow packets of incoming DNS requests (UDP) 231 | - Allow ICMP packets 232 | - Allow http connections (Pi-Hole web interface) 233 | - Allow SSH connections 234 | - REJECT other packets (no timeout on the client side) 235 | 236 | FORWARD: 237 | - Allow packets of self-established connections or connections related to those 238 | - Drop all packets not sent over one of the specified ports 239 | - Allow packet forwarding from your LAN to the VPN interface 240 | 241 | ## nat: 242 | - Accept all packets by default 243 | - Replace your clients local by your RPi's public IP and the other way around (Essentially how all routers work) 244 |
245 | 246 | ### **Rules for specific devices:** 247 | 248 | Since the devices connect to the internet over the Raspberry your routers filters are being bypassed. 249 | The safest way is to use the module 'mac', because the MAC is usually (Windows, Android, IOS, Linux) either not changeable at all, or only with root access. 250 | 251 | This rule blocks requests to the RPi. 252 | 253 | -A INPUT -m mac --mac-source -j REJECT 254 | 255 | This rule blocks the devices internet connection over the RPi. 256 | 257 | -A FORWARD -m mac --mac-source -j REJECT 258 | 259 | Of course if you use static IP you could also specify the device by its IP: 260 | 261 | -A INPUT -s -j REJECT 262 | 263 | ### **Timed rules:** 264 | 265 | The most direct solution is via the 'time' module. 266 | This rule blocks a request between 22:00 and 06:00, Sunday to Thursday: 267 | 268 | -A INPUT -m time --timestart 22:00 --timestop 06:00 --weekdays Sun,Mon,Tue,Wed,Thu -j REJECT 269 | 270 | 271 | If you want whole rule sets to change, you could also load them via cron. 272 | Sample configuration for /etc/cron.d/iptables: 273 | ``` 274 | 00 00 * * * root /usr/sbin/iptables-restore /etc/iptables/rules.v4 275 | 00 00 * * * root /usr/sbin/ip6tables-restore ip6tables-restore /etc/iptables/rules.v6 276 | 00 12 * * * root /usr/sbin/iptables-restore /etc/iptables/rules2.v4 277 | 00 12 * * * root /usr/sbin/ip6tables-restore ip6tables-restore /etc/iptables/rules2.v6 278 | ``` 279 |
280 | Cron syntax 281 | 282 | ``` 283 | 284 | * * * * * Command to be executed 285 | - - - - - 286 | | | | | | 287 | 288 | | | | | +----- Weekday (0 - 7) (Sunday corresponds to 0 and 7) 289 | 290 | | | | +------- month (1 - 12) 291 | 292 | | | +--------- day (1 - 31) 293 | 294 | | +----------- hour (0 - 23) 295 | 296 | +------------- minute (0 - 59) 297 | ``` 298 |
299 | 300 | PS: Don't forget to set your time-zone first. 301 | 302 | ### **Block certain Domains:** 303 | **Pi-Hole 5 supports specifying black and whitelists for individual devices so there is no need to use iptables anymore if you don't need to filter by MAC or want to set timed rules.** 304 | 305 | This rule discards all UDP DNS requests other than "wikipedia.com": 306 | 307 | -A INPUT -p upd --dport 53 -m string ! --string "wikipedia.com" --algo bm -j DROP 308 | 309 | It is also possible to filter using Regex. To do this, you must first [install DKMS](https://github.com/smcho-kr/kpcre/wiki/Step-by-step-installation-guide). 310 | However the algorithm for regex matching is much more complex than the Boyer-Moore algorithm. The rule should therefore be as precise as possible so that the regex matching can be skipped for non-applicable packets. 311 | 312 | This rule filters all UDP DNS requests for "*.googlevideo.*" and "googlevideo.*". The syntax of the string is "/[<*REGEX*>](https://regex101.com/)/". 313 | 314 | -A INPUT -p udp --dport 53 -m string --string "/(.*\.|)googlevideo\..*/" --algo regex -j DROP 315 | 316 | 317 | 318 | ### **Sample configuration:** 319 |
320 | 321 | 322 | ``` 323 | *filter 324 | :INPUT DROP 325 | :TRUSTED_IP DROP 326 | :DNS DROP 327 | :FORWARD DROP 328 | :DNS_FORWARD DROP 329 | :OUTPUT ACCEPT 330 | 331 | -A INPUT -i lo -j ACCEPT 332 | -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 333 | -A INPUT -p icmp --icmp-type 8 -j ACCEPT 334 | -A INPUT -p udp --dport 67:68 -j ACCEPT 335 | -A INPUT -s 192.168.178.0/24 -j TRUSTED_IP 336 | 337 | -A TRUSTED_IP -p udp --dport 53 -j DNS 338 | -A TRUSTED_IP -p icmp -j ACCEPT 339 | -A TRUSTED_IP -p tcp --dport 80 -j ACCEPT 340 | -A TRUSTED_IP -p tcp --dport 22 -j ACCEPT 341 | -A TRUSTED_IP -j REJECT 342 | 343 | -A DNS -m mac --mac-source 81:7d:22:a2:3e:7d -m time --timestart 00:00 --timestop 06:00 --weekdays Sun,Mon,Tue,Wed,Thu -m string ! --string "/(.*\.|)whatsapp\.(net|com)|(.*\.|)(signal|whispersystems)\.org/" --algo regex -j REJECT 344 | -A DNS -j ACCEPT 345 | 346 | -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 347 | -A FORWARD -p udp --dport 53 -j DNS_FORWARD 348 | -A FORWARD -p tcp --dport 53 -j DNS_FORWARD 349 | #-A FORWARD --match multiport ! --dports 80,443,53,20,115,143,993 -o wg0 -j REJECT 350 | -A FORWARD -s 192.168.178.0/24 -o wg0 -j ACCEPT 351 | 352 | -A DNS_FORWARD -m mac --mac-source 81:7d:22:a2:3e:7d -j REJECT 353 | -A DNS_FORWARD -j ACCEPT 354 | 355 | COMMIT 356 | 357 | *nat 358 | :PREROUTING ACCEPT 359 | :INPUT ACCEPT 360 | :POSTROUTING ACCEPT 361 | :OUTPUT ACCEPT 362 | 363 | -A POSTROUTING -o wg0 -j MASQUERADE 364 | 365 | COMMIT 366 | ``` 367 | 368 |
369 | -------------------------------------------------------------------------------- /legacy/DNSCrypt.md: -------------------------------------------------------------------------------- 1 | ## Install DNSCrypt-Proxy: 2 | 3 | ### **Download and extract DNSCrypt-Proxy:** 4 | Newest release: https://github.com/jedisct1/dnscrypt-proxy/releases/ 5 | For the RPi you need the "linux-arm" version. Otherwise you probably need "linux_x86_64". 6 | ```xml 7 | cd /etc 8 | wget 9 | tar -xf dnscrypt-proxy-linux_*-*.tar.gz 10 | mv linux-arm dnscrypt-proxy 11 | rm dnscrypt-proxy-linux_*-*.tar.gz 12 | ``` 13 | 14 | ### **Configure DNSCrypt-Proxy:** 15 | ``` 16 | cd /etc/dnscrypt-proxy 17 | cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml 18 | ``` 19 | Change in dnscrypt-proxy.toml: 20 | ```yaml 21 | ## Pi-Hole already uses Port 53 22 | listen_addresses = ['127.0.0.1:5300', '[::1]:5300'] 23 | ## Pi-Hole is our system resolver, which uses DNSCrypt-Proxy itself 24 | ignore_system_dns = true 25 | ``` 26 |
27 | Some optional settings 28 | 29 | ```xml 30 | server_names = [’ ’, ’ ’] ## If you want to use specific servers 31 | ipv6_servers = false ## “true” if your VPN service supports IPv6 32 | require_dnssec = true # I would recommend it for security reasons 33 | require_nolog = true ## I would recommend it for privacy reasons 34 | fallback_resolver = ‘176.126.70.119:53’ ## OpenNIC; You can use any server you trust 35 | 36 | ##Insert below “[sources]”: 37 | [sources.’’] 38 | urls = [’’, ‘’] 39 | minisign_key = ‘’ 40 | cache_file = ‘’ 41 | 42 | ##Insert below “[anonymized_dns]”: 43 | routes = [ 44 | { server_name=’ ’, via=[’ ’,<…>] }, 45 | { server_name=’’, via=[’ ’,<…>] } 46 | ] 47 | ``` 48 | [Server/Relay lists ("Sources")](https://github.com/DNSCrypt/dnscrypt-resolvers/tree/master/v3) 49 | [More info about the servers](https://github.com/dyne/dnscrypt-proxy/blob/master/dnscrypt-resolvers.csv) 50 |
51 | 52 | ### **Install the service:** 53 | ./dnscrypt-proxy -service install 54 | 55 | ### **Check your configuration:** 56 | ./dnscrypt-proxy -resolve google.com 57 | The output should look something like this: 58 | ``` 59 | Resolving [google.com] 60 | Domain exists: yes, 4 name servers found 61 | Canonical name: google.com. 62 | IP addresses: 172.217.23.110, 2a00:1450:4001:800::200e 63 | TXT records: v=spf1 include:_spf.google.com ~all facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95 docusign=1b0a6754-49b1-4db5-8540-d2c12664b289 globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8= docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e 64 | Resolver IP: 45.87.212.50 65 | ``` 66 | 67 | ### **Allow the service to bind to the specified port as non-root user:** 68 | setcap cap_net_bind_service=+pe dnscrypt-proxy 69 | 70 | ### **Start the service on boot:** 71 | systemctl enable dnscrypt-proxy 72 | -------------------------------------------------------------------------------- /legacy/Pi-Hole.md: -------------------------------------------------------------------------------- 1 | ## Install Pi-Hole: 2 | > Our code is completely open, but piping to bash can be dangerous. For a safer install, review the code and then run the installer locally. 3 | 4 | curl -sSL https://install.pi-hole.net | bash 5 | 6 | For this guide it's irrelevant what you choose in the installer. 7 | 8 | ### **Configure the Interface:** 9 | In case you didn't already set up your interface during the Pi-Hole installation, paste and overwrite any existing configuration for eth0 in /etc/dhcpcd.conf: 10 | ```yaml 11 | interface eth0 12 | static ip_address= ##The IP address you want your server to have 13 | static routers= ##The IP address of your router 14 | static domain_name_servers=127.0.0.1 15 | ``` 16 | 17 | #### DHCP config 18 | **Turn off the DHCP server of your router first.** 19 | 20 | Create the file ```/etc/dnsmasq.d/dhcp.conf``` with the following content: 21 | ```xml 22 | dhcp-authoritative 23 | domain=lan 24 | dhcp-rapid-commit 25 | 26 | dhcp-range=,,24h 27 | 28 | # Default Gateway (VPN or your Router) 29 | dhcp-option=3, 30 | # Default DNS 31 | dhcp-option=6, 32 | 33 | # Tag for assigning individual devices to other Gateway 34 | dhcp-option=tag:,3, 35 | 36 | dhcp-leasefile=/etc/pihole/dhcp.leases 37 | ``` 38 | 39 | Now you can assign individual devices by adding them in /etc/private-lan/volumes/etc-dnsmasq.d/static-leases.conf: 40 | 41 | ```xml 42 | dhcp-host=,,,set: 43 | ``` 44 |
45 | Example 46 | 47 | ```xml 48 | dhcp-authoritative 49 | dhcp-range=192.168.178.20,192.168.178.254,24h 50 | 51 | # Router 52 | dhcp-option=3,192.168.178.1 53 | # Pi-Hole 54 | dhcp-option=6,192.168.178.2 55 | 56 | # VPN 57 | dhcp-option=tag:VPN,3,192.168.178.2 58 | 59 | dhcp-leasefile=/etc/pihole/dhcp.leases 60 | #quiet-dhcp 61 | 62 | domain=lan 63 | dhcp-rapid-commit 64 | ``` 65 | 66 | ``` 67 | dhcp-host=81:7d:22:a2:3e:7d,192.168.178.10,PC-VPN,set:VPN 68 | dhcp-host=81:7d:22:a2:3e:7e,192.168.178.11,PC 69 | ``` 70 |
71 | -------------------------------------------------------------------------------- /legacy/PiVPN.md: -------------------------------------------------------------------------------- 1 | ### **Install PiVPN:** 2 | curl -L https://install.pivpn.io | bash 3 | - Choose Wireguard as VPN type 4 | - If you got a changing public IP use a [DynDNS](https://wiki.archlinux.org/index.php/Dynamic_DNS) provider 5 | - Don't change your interface config from what you configured before (/etc/dhcpcd.conf) 6 | 7 | ### **Configure Routes:** 8 | 9 | *This seems like a duct tape solution to me. If you know a better/cleaner way of achieving this, please let me know by opening an issue.* 10 | 11 | Because your server also is a Wireguard client the request goes into eth0 but the response is sent over the Wireguard tunnel (wg0) and is reaching the client with a different IP. Also, you probably want the clients to be able to access the local network. 12 | 13 | Insert in /etc/wireguard/wg0.conf below `[Interface]`: 14 | 15 | PostUp = ip rule add from lookup main && ip rule add from 10.6.0.0/24 lookup main 16 | PostDown = ip rule delete from lookup main && ip rule delete from 10.6.0.0/24 lookup main 17 | 18 | ### **Add clients:** 19 | 20 | Now you can add clients by using `pivpn add`. 21 | 22 | ### **Additional Step for Windows Clients:** 23 | 24 | If you use WireGuard for Windows you may not be able to access your LAN right away. 25 | In that case you first need to add a route to your LAN via the tunnel: 26 | 27 | Execute as admin in the Windows Command Prompt: 28 | 29 | route ADD MASK 30 | 31 | e.g.: 32 | 33 | route ADD 192.168.178.0 MASK 255.255.255.0 10.6.0.1 34 | -------------------------------------------------------------------------------- /legacy/VPNGateway.md: -------------------------------------------------------------------------------- 1 | ## Setup the VPN gateway: 2 | 3 | ### Interface names: 4 | With **Bullseye** we've got "predictable" interface names. But those are just hampering for our purposes. 5 | To assign static interface names you have to create this file: 6 | ```xml 7 | #/etc/systemd/network/10-persistent-net.link 8 | [Match] 9 | MACAddress= 10 | 11 | [Link] 12 | Name= 13 | ``` 14 |
15 | Example 16 | 17 | ```xml 18 | [Match] 19 | MACAddress=01:23:45:67:89:ab 20 | 21 | [Link] 22 | Name=eth0 23 | ``` 24 |
25 | 26 | ### Unstable Repos 27 | If you want to use Wireguard on **Buster** you have to add the "Debian Unstable" repository to your apt sources first: 28 | ``` 29 | echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list 30 | wget -O - https://ftp-master.debian.org/keys/archive-key-$(lsb_release -sr).asc | sudo apt-key add - 31 | printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable 32 | apt update 33 | ``` 34 | 35 | ### **Edit kernel parameters to enable IP forwarding and enhance security:** 36 | Uncomment/paste in /etc/sysctl.conf: 37 | ```yaml 38 | #IP Forwarding 39 | net.ipv4.ip_forward = 1 40 | net.ipv6.conf.all.forwarding=1 ##If your VPN supports IPv6 41 | #IP Spoofing protection 42 | net.ipv4.conf.all.rp_filter = 1 43 | net.ipv4.conf.default.rp_filter = 1 44 | #Ignore ICMP broadcast requests 45 | net.ipv4.icmp_echo_ignore_broadcasts = 1 46 | #Ignore ICMP redirects 47 | net.ipv4.conf.all.accept_redirects = 0 48 | net.ipv6.conf.all.accept_redirects = 0 49 | #Ignore send redirects 50 | net.ipv4.conf.all.send_redirects = 0 51 | net.ipv4.conf.default.send_redirects = 0 52 | #Disable source packet routing 53 | net.ipv4.conf.all.accept_source_route = 0 54 | net.ipv6.conf.all.accept_source_route = 0 55 | net.ipv4.conf.default.accept_source_route = 0 56 | net.ipv6.conf.default.accept_source_route = 0 57 | # Block SYN attacks 58 | net.ipv4.tcp_syncookies = 1 59 | net.ipv4.tcp_max_syn_backlog = 2048 60 | net.ipv4.tcp_synack_retries = 2 61 | net.ipv4.tcp_syn_retries = 5 62 | # Log Martians 63 | net.ipv4.conf.all.log_martians = 1 64 | net.ipv4.conf.default.log_martians=1 65 | ``` 66 | Load these changes: 67 | 68 | sysctl -p /etc/sysctl.conf 69 | 70 | *More info about these settings: 71 | [IP Spoofing](http://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.kernel.rpf.html) 72 | [ICMP broadcast requests](https://www.cloudflare.com/learning/ddos/smurf-ddos-attack/) 73 | [ICMP redirects](https://askubuntu.com/questions/118273/what-are-icmp-redirects-and-should-they-be-blocked) 74 | [Source packet routing](https://www.ccexpert.us/basic-security-services/disable-ip-source-routing.html) 75 | [SYN attacks](https://www.symantec.com/connect/articles/hardening-tcpip-stack-syn-attacks)* 76 | 77 |
78 | Setup OpenVPN 79 | 80 | ### **Install OpenVPN:** 81 | apt install openvpn 82 | 83 | ### **Move your config files to /etc/openvpn/:** 84 | Download the OpenVPN config files from your VPN provider. 85 | If your server configuration is saved as in /etc/openvpn/ the connection is automatically initialized during boot. 86 | 87 | cp /etc/openvpn/.conf 88 | mkdir /etc/openvpn/server 89 | 90 | If those files exist: 91 | 92 | mv /etc/openvpn/server/ 93 | mv /etc/openvpn/server/ 94 | mv /etc/openvpn/server/ 95 | 96 | ### **Store the VPN credentials in a file:** 97 | Insert in /etc/openvpn/: 98 | 99 | auth-user-pass /etc/openvpn/server/passwd.conf 100 | 101 | Create the file: 102 | ```xml 103 | echo " " > /etc/openvpn/server/passwd.conf 104 | ``` 105 | 106 | Only allow root to access the file: 107 | 108 | chown root:root /etc/openvpn/server/passwd.conf 109 | chmod 600 /etc/openvpn/server/passwd.conf 110 | 111 | ### **Depending on the files you got from your VPN provider you may have to configure certificates or keys:** 112 | Insert in /etc/openvpn/: 113 | ``` 114 | ca /etc/openvpn/server/.crt 115 | cert /etc/openvpn/server/.crt 116 | key /etc/openvpn/server/.key 117 | ``` 118 | 119 | ### **Configure iptables:** 120 | ``` 121 | iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 122 | iptables -A FORWARD -i eth0 -o eth0 -j REJECT 123 | iptables -A FORWARD -s 192.168.178.0/24 -o tun0 -j ACCEPT 124 | iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE 125 | 126 | ##If your VPN service supports IPv6 127 | ip6tables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 128 | ip6tables -A FORWARD -i eth0 -o eth0 -j REJECT 129 | ip6tables -A FORWARD -s fe80::/10 -o tun0 -j ACCEPT 130 | ip6tables -t nat -A POSTROUTING -o tun0 -j MASQUERADE 131 | ``` 132 | 133 | ### **Test the configuration:** 134 | 135 | openvpn --config /etc/openvpn/.conf --daemon 136 | 137 |
138 | 139 |
140 | Setup Wireguard 141 | 142 | ### **Install Wireguard:** 143 | 144 | apt install raspberrypi-kernel-headers wireguard 145 | 146 | ### **Move and rename your config file to /etc/wireguard/wg0.conf:** 147 | 148 | mv /etc/openvpn/wg0.conf 149 | 150 | ### **Only allow root to access the file:** 151 | 152 | chown root:root /etc/wireguard/wg0.conf 153 | chmod 600 /etc/wireguard/wg0.conf 154 | 155 | ### **Edit DNS server** 156 | *Although devices on your network will use Pi-Hole your server itself will use the DNS server specified in the Wireguard config file. Thus for your server to use Pi-Hole you have to set it to "127.0.0.1":* 157 | ``` 158 | #/etc/wireguard/wg0.conf 159 | DNS = 127.0.0.1 160 | ``` 161 | 162 | ### **Enable Wireguard to start on boot:** 163 | 164 | systemctl enable wg-quick@wg0 165 | 166 | ### **Configure iptables:** 167 | ``` 168 | iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 169 | iptables -A FORWARD -i eth0 -o eth0 -j REJECT 170 | iptables -A FORWARD -o wg0 -j ACCEPT 171 | iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE 172 | 173 | ##If your VPN service supports IPv6 174 | ip6tables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 175 | ip6tables -A FORWARD -i eth0 -o eth0 -j REJECT 176 | ip6tables -A FORWARD -o wg0 -j ACCEPT 177 | ip6tables -t nat -A POSTROUTING -o wg0 -j MASQUERADE 178 | ``` 179 | 180 | ### **Test the configuration:** 181 | 182 | wg-quick up wg0 183 | 184 |
185 | 186 | ### **Save this configuration:** 187 | Install 'iptables-persistent' 188 | 189 | apt install iptables-persistent 190 | 191 | Save the current iptables configuration (In case you didn't already do it during the installation) 192 | 193 | iptables-save > /etc/iptables/rules.v4 194 | iptables-save > /etc/iptables/rules.v6 ## If your VPN service supports IPv6 195 | -------------------------------------------------------------------------------- /legacy/main.md: -------------------------------------------------------------------------------- 1 | ## Guide 2 | Even if you don't wan't to use all services I would recommend setting up those you do want to in the following order. 3 | 4 | - ### [DNSCrypt-Proxy](DNSCrypt.md) 5 | Must be set up before configuring Pi-Hole to use localhost:5300 as DNS. 6 | 7 | - ### [VPN Gateway](VPNGateway.md) 8 | Must be set up before configuring the Pi-Hole DHCP to advertise your server as network gateway. 9 | 10 | - ### [Pi-Hole](Pi-Hole.md) 11 | 12 | - ### [PiVPN](PiVPN.md) 13 | 14 | - ### [Advanced](Advanced.md) 15 | - Leak testing 16 | - Automated security updates 17 | - Simple Firewall 18 | - Per devices rules and timed rules -------------------------------------------------------------------------------- /set-route.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | container=$1 3 | new_gateway=$2 4 | 5 | pid="$(docker inspect -f '{{.State.Pid}}' "$container")" 6 | mkdir -p /var/run/netns 7 | ln -s /proc/"$pid"/ns/net /var/run/netns/"$pid" 8 | 9 | # Replace old gateway 10 | ip netns exec "$pid" ip route del default 11 | ip netns exec "$pid" ip route add default via "$new_gateway" 12 | 13 | # Optionally set up an alternative gateway for certain IP ranges 14 | if (($# > 3)); then 15 | alternative_gateway=$3 16 | for ((i=4;i<=$#;i++)); do 17 | ip netns exec "$pid" ip route add "${!i}" via "$alternative_gateway" 18 | done 19 | fi -------------------------------------------------------------------------------- /unbound/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | wireguard-gw: 5 | image: linuxserver/wireguard 6 | container_name: wireguard-gw 7 | volumes: 8 | - '/etc/private-lan/volumes/wireguard-gw/:/config' 9 | networks: 10 | net: 11 | ipv4_address: 172.16.238.2 12 | restart: unless-stopped 13 | privileged: true 14 | cap_add: 15 | - NET_ADMIN 16 | - SYS_MODULE 17 | 18 | wireguard-dns: 19 | image: linuxserver/wireguard 20 | container_name: wireguard-dns 21 | volumes: 22 | - '/etc/private-lan/volumes/wireguard-dns/:/config' 23 | networks: 24 | net: 25 | ipv4_address: 172.16.238.8 26 | restart: unless-stopped 27 | privileged: true 28 | cap_add: 29 | - NET_ADMIN 30 | - SYS_MODULE 31 | 32 | dnsmasq: 33 | build: images/dnsmasq 34 | container_name: dnsmasq 35 | networks: 36 | net: 37 | ipv4_address: 172.16.238.3 38 | expose: 39 | - "67/udp" 40 | - "68/tcp" 41 | volumes: 42 | - '/etc/private-lan/volumes/dnsmasq/:/etc/dnsmasq.d/' 43 | restart: unless-stopped 44 | cap_add: 45 | - NET_ADMIN 46 | depends_on: 47 | - dhcp-helper 48 | 49 | pihole: 50 | image: pihole/pihole:latest 51 | container_name: pihole 52 | networks: 53 | net: 54 | ipv4_address: 172.16.238.4 55 | ports: 56 | - "192.168.178.2:53:53/tcp" 57 | - "192.168.178.2:53:53/udp" 58 | - "192.168.178.2:80:80/tcp" 59 | - "192.168.178.2:443:443/tcp" 60 | environment: 61 | DNS1: '172.16.238.6' 62 | DNS2: 'no' 63 | DNSMASQ_LISTENING: 'all' 64 | volumes: 65 | - '/etc/private-lan/volumes/pihole/pihole/:/etc/pihole/' 66 | - '/etc/private-lan/volumes/pihole/gravity/:/etc/pihole/gravity/' 67 | cap_add: 68 | - NET_ADMIN 69 | - SYS_NICE 70 | restart: unless-stopped 71 | depends_on: 72 | - unbound 73 | 74 | pihole-vpn: 75 | image: pihole/pihole:latest 76 | container_name: pihole-vpn 77 | networks: 78 | net: 79 | ipv4_address: 172.16.238.5 80 | ports: 81 | - "192.168.178.3:53:53/tcp" 82 | - "192.168.178.3:53:53/udp" 83 | - "192.168.178.3:80:80/tcp" 84 | - "192.168.178.3:443:443/tcp" 85 | environment: 86 | DNS1: '172.16.238.7' 87 | DNS2: 'no' 88 | DNSMASQ_LISTENING: 'all' 89 | volumes: 90 | - '/etc/private-lan/volumes/pihole/pihole-vpn/:/etc/pihole/' 91 | - '/etc/private-lan/volumes/pihole/gravity/:/etc/pihole/gravity/' 92 | cap_add: 93 | - NET_ADMIN 94 | - SYS_NICE 95 | restart: unless-stopped 96 | depends_on: 97 | - wireguard-gw 98 | - unbound-vpn 99 | 100 | unbound: 101 | build: images/unbound 102 | container_name: unbound 103 | networks: 104 | net: 105 | ipv4_address: 172.16.238.6 106 | expose: 107 | - "53/udp" 108 | - "53/tcp" 109 | volumes: 110 | - '/etc/private-lan/volumes/unbound/unbound.conf:/etc/unbound/unbound.conf' 111 | restart: unless-stopped 112 | depends_on: 113 | - wireguard-dns 114 | 115 | unbound-vpn: 116 | build: images/unbound 117 | container_name: unbound-vpn 118 | networks: 119 | net: 120 | ipv4_address: 172.16.238.7 121 | expose: 122 | - "53/udp" 123 | - "53/tcp" 124 | volumes: 125 | - '/etc/private-lan/volumes/unbound/unbound.conf:/etc/unbound/unbound.conf' 126 | restart: unless-stopped 127 | depends_on: 128 | - wireguard-gw 129 | 130 | dhcp-helper: 131 | build: images/dhcp-helper 132 | container_name: dhcp-helper 133 | restart: unless-stopped 134 | network_mode: "host" 135 | command: -s 172.16.238.3 136 | cap_add: 137 | - NET_ADMIN 138 | 139 | networks: 140 | net: 141 | driver: bridge 142 | driver_opts: 143 | com.docker.network.enable_ipv6: "true" 144 | ipam: 145 | driver: default 146 | config: 147 | - subnet: 172.16.238.0/24 148 | gateway: 172.16.238.1 149 | - subnet: 2001:3984:3989::/64 150 | gateway: 2001:3984:3989::1 151 | -------------------------------------------------------------------------------- /unbound/gateway-firewall.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Set firewall rules before docker startup 3 | Before=docker.service 4 | 5 | [Service] 6 | ExecStart=/etc/init.d/gateway-firewall.sh 7 | 8 | [Install] 9 | WantedBy=default.target -------------------------------------------------------------------------------- /unbound/gateway-firewall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get default interface with lowest metric 4 | lan_if="$(ip route | awk 'FNR == 1 {print $(5)}')" 5 | lan_subnet="$(ip -o -f inet addr show "$lan_if" | awk '/scope global/ {print $4}' | perl -ne 's/(?<=\d.)\d{1,3}(?=\/)/0/g; print;')" 6 | 7 | # Don't allow forwarding from lan_if to lan_if (bypassing the VPN gateway) 8 | iptables -I FORWARD -i "$lan_if" -o "$lan_if" -j REJECT 9 | 10 | # Only allow VPN containers to directly access the internet 11 | iptables -I FORWARD -s 172.16.238.0/24 ! -d "$lan_subnet" -o "$lan_if" -j REJECT 12 | iptables -I FORWARD -s 172.16.238.2 -o "$lan_if" -j ACCEPT 13 | iptables -I FORWARD -s 172.16.238.8 -o "$lan_if" -j ACCEPT -------------------------------------------------------------------------------- /unbound/gateway.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get default interface with lowest metric 4 | lan_if="$(ip route | awk 'FNR == 1 {print $(5)}')" 5 | # Overwrite interface 6 | # lan_if="eth0" 7 | lan_subnet="$(ip -o -f inet addr show "$lan_if" | awk '/scope global/ {print $4}' | perl -ne 's/(?<=\d.)\d{1,3}(?=\/)/0/g; print;')" 8 | 9 | # Move rules from gateway-firewall.sh to the top again 10 | iptables -D FORWARD -i "$lan_if" -o "$lan_if" -j REJECT 11 | iptables -D FORWARD -s 172.16.238.0/24 ! -d "$lan_subnet" -o "$lan_if" -j REJECT 12 | iptables -D FORWARD -s 172.16.238.2 -o "$lan_if" -j ACCEPT 13 | iptables -D FORWARD -s 172.16.238.8 -o "$lan_if" -j ACCEPT 14 | iptables -I FORWARD -i "$lan_if" -o "$lan_if" -j REJECT 15 | iptables -I FORWARD -s 172.16.238.0/24 ! -d "$lan_subnet" -o "$lan_if" -j REJECT 16 | iptables -I FORWARD -s 172.16.238.2 -o "$lan_if" -j ACCEPT 17 | iptables -I FORWARD -s 172.16.238.8 -o "$lan_if" -j ACCEPT 18 | 19 | # Get environment variables 20 | docker_if="br-$(docker network ls | grep private-lan_net | cut -d' ' -f1)" 21 | docker_if_ip="$(ip -4 addr show "$docker_if" | grep -oP '(?<=inet\s)\d+(\.\d+){3}')" 22 | docker_if_subnet="$(ip -o -f inet addr show "$docker_if" | awk '/scope global/ {print $4}' | perl -ne 's/(?<=\d.)\d{1,3}(?=\/)/0/g; print;')" 23 | lan_subnet="$(ip -o -f inet addr show "$lan_if" | awk '/scope global/ {print $4}' | perl -ne 's/(?<=\d.)\d{1,3}(?=\/)/0/g; print;')" 24 | wireguard_gateway_ip="$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' wireguard-gw)" 25 | wireguard_dns_ip="$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' wireguard-dns)" 26 | #unbound_ip="$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' unbound)" 27 | #default_gateway="$(ip route show default dev "$lan_if" | awk '/default/ { print $3 }')" 28 | 29 | # Default route in a new routing table via the VPN Gateway 30 | ip route add default via "$wireguard_gateway_ip" table 200 31 | # Use new table for all packets from lan_if 32 | ip rule add from all iif "$lan_if" lookup 200 33 | # Use main routing table first but only match if at least the first bit of an IP range in it is matching the destination IP. It won't match 0.0.0.0/0 ("default") 34 | ip rule add from all lookup main suppress_prefixlength 0 35 | 36 | # Uncomment if you want the host to use the VPN tunnel too 37 | # Route all traffic trough the Wireguard tunnel except for the the "wireguard_gateway" container and the non VPN unbound traffic 38 | # ip route add default via $default_gateway table 201 39 | # ip rule add from $wireguard_gateway_ip lookup 201 40 | # ip rule add from $unbound_ip lookup 201 41 | # ip route replace default via $wireguard_gateway_ip 42 | 43 | # Don't allow forwarding from lan_if to lan_if (bypassing the VPN gateway) 44 | if ! eval "iptables -C FORWARD -i "$lan_if" -o "$lan_if" -j REJECT &> /dev/null"; then 45 | iptables -I FORWARD -i "$lan_if" -o "$lan_if" -j REJECT 46 | fi 47 | # Allow forwarding from lan_if trough the docker interface to the Wireguard gateway 48 | if ! eval "iptables -C FORWARD -i "$lan_if" -o $docker_if -d $wireguard_gateway_ip -j ACCEPT &> /dev/null"; then 49 | iptables -I FORWARD -i "$lan_if" -o "$docker_if" -d "$wireguard_gateway_ip" -j ACCEPT 50 | fi 51 | # Replace the source IP of packets going out trough the docker interface to the Wireguard container 52 | if ! eval "iptables -t nat -C POSTROUTING ! -s $docker_if_subnet -d $wireguard_gateway_ip -o $docker_if -j MASQUERADE &> /dev/null"; then 53 | iptables -t nat -I POSTROUTING ! -s "$docker_if_subnet" -d "$wireguard_gateway_ip" -o "$docker_if" -j MASQUERADE 54 | fi 55 | 56 | # Wait until the pihole and pihole-vpn container finished start up 57 | until eval "/usr/bin/docker inspect -f {{.State.Running}} pihole" && eval "/usr/bin/docker inspect -f {{.State.Running}} pihole-vpn"; do 58 | sleep 0.1; 59 | done; 60 | 61 | # Set the default route of the containers to the "wireguard-gw" container and add an exception for packets addressed to the LAN or Wireguard clients 62 | bash /etc/private-lan/set-route.sh pihole-vpn "$wireguard_gateway_ip" "$docker_if_ip" "$lan_subnet" 10.6.0.0/24 63 | bash /etc/private-lan/set-route.sh unbound-vpn "$wireguard_gateway_ip" "$docker_if_ip" "$lan_subnet" 10.6.0.0/24 64 | # Reconfigure the routing table each time one of the containers are restarted 65 | docker events --filter "container=pihole-vpn" | awk '/container (start|restart)/ { system("/etc/private-lan/set-route.sh pihole-vpn '"$wireguard_gateway_ip"' '"$docker_if_ip"' '"$lan_subnet"' 10.6.0.0/24") }' & 66 | docker events --filter "container=unbound-vpn" | awk '/container (start|restart)/ { system("/etc/private-lan/set-route.sh unbound-vpn '"$wireguard_gateway_ip"' '"$docker_if_ip"' '"$lan_subnet"' 10.6.0.0/24") }' & 67 | 68 | # Set the default route of the containers to the "wireguard-dns" container and add an exception for packets addressed to the LAN or Wireguard clients 69 | bash /etc/private-lan/set-route.sh pihole "$wireguard_dns_ip" "$docker_if_ip" "$lan_subnet" 10.6.0.0/24 70 | bash /etc/private-lan/set-route.sh unbound "$wireguard_dns_ip" "$docker_if_ip" "$lan_subnet" 10.6.0.0/24 71 | # Reconfigure the routing table each time one of the containers are restarted 72 | docker events --filter "container=pihole" | awk '/container (start|restart)/ { system("/etc/private-lan/set-route.sh pihole '"$wireguard_dns_ip"' '"$docker_if_ip"' '"$lan_subnet"' 10.6.0.0/24") }' & 73 | docker events --filter "container=unbound" | awk '/container (start|restart)/ { system("/etc/private-lan/set-route.sh unbound '"$wireguard_dns_ip"' '"$docker_if_ip"' '"$lan_subnet"' 10.6.0.0/24") }' 74 | -------------------------------------------------------------------------------- /unbound/guide/DHCP.md: -------------------------------------------------------------------------------- 1 | #### DHCP config 2 | 3 | Create a .conf file like ```/etc/private-lan/volumes/dnsmasq/dhcp.conf```. 4 | To configure your DHCP server refer to the [official documentaion](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html). 5 | 6 | Just for orientation, here is how my config looks like: 7 | 8 | ```xml 9 | dhcp-authoritative 10 | 11 | ## New devices default ## 12 | dhcp-range=192.168.178.200,192.168.178.254,24h 13 | # Gateway 14 | dhcp-option-force=3,192.168.178.2 15 | # DNS1 and DNS2 16 | dhcp-option-force=6,192.168.178.3,192.168.178.3 17 | 18 | ## Known devices (static IP address) default ## 19 | # Devices in the IP range .20 - .199 are assigned to tag '0' 20 | dhcp-range=set:0,192.168.178.20,192.168.178.199,24h 21 | dhcp-option-force=tag:0,3,192.168.178.1 22 | dhcp-option-force=tag:0,6,192.168.178.2,192.168.178.2 23 | 24 | ## Settings for devices which were assigned the 'VPN' tag ## 25 | dhcp-option-force=tag:VPN,3,192.168.178.2 26 | dhcp-option-force=tag:VPN,6,192.168.178.3,192.168.178.3 27 | 28 | dhcp-leasefile=/etc/dnsmasq.d/dhcp.leases 29 | #quiet-dhcp 30 | 31 | domain=lan 32 | dhcp-rapid-commit 33 | ``` 34 | 35 | Example for the static DHCP leases: 36 | 37 | ```xml 38 | # /etc/private-lan/volumes/dnsmasq.d/static-leases.conf 39 | 40 | dhcp-host=81:7d:22:a2:3e:7d,192.168.178.20,PC-VPN,set:VPN 41 | dhcp-host=81:7d:22:a2:3e:7e,192.168.178.21,PC 42 | ``` 43 | 44 | #### Restart dnsmasq 45 | 46 | $ docker restart dnsmasq 47 | 48 | #### Disable other DHCP servers 49 | 50 | Most likely you have to disable the DHCP server of your router. How to do this depends on the router but while some may not allow you to configure a custom DNS server, there is almost always an option to turn off it's DHCP server. 51 | -------------------------------------------------------------------------------- /unbound/guide/diagram.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LAN 3 | +---------------------------------------------------------------------------------------------------------------------+ 4 | | Docker Host | 5 | | +-----------+ +-------------------------------------------------------------------------------------------+ | 6 | | | | | | | 7 | | | Router | | +-----------+ | | 8 | | | WAN | | | | | | 9 | | | | | Gateway | Docker | | | 10 | | | | <----------------------------+ | Interface | | | 11 | | | | | | | Docker | | 12 | | | | | +---------------------------------------------------------------------+ | | 13 | | | | | | | | | | | 14 | | +-----------+ | | | | Gateway +-------------------------+ | | | 15 | | | | | | <-------+ | | <------+ | | | 16 | | ^ | | +-----------+ | Wireguard-Gateway | <----+ | | | | 17 | | | Gateway | | | | | | | | | 18 | | | | >----------------------------> +-------------------------+ | | | | | 19 | | + | | | | | | | | 20 | | | | | +-------------------------+ | | | | | 21 | | +-----------+ | | | | | | | | | | 22 | | | | | | | | Wireguard-DNS | <--+ | | | | | 23 | | | | | | | | | <+ | | | | | | 24 | | | | | | | +-------------------------+ | | | | | | | 25 | | | | | | | | | | | | | | 26 | | | | Gateway | Static Route | | +-------------------------+ | | | | | | | 27 | | | | +-----------------------+ | | | | | | | | | | 28 | | | | | | +-> | Unbound | ++ | | | | | | 29 | | | | | | | | | | | | | | | 30 | | | | | | DNS | +-------------------------+ | | | | | | 31 | | | | | | | | | | | | | 32 | | | | | | | +-------------------------+ | | | | | | 33 | | | Clients | | | +-+ | | | | | GW | | | 34 | | | | DNS | DNAT | | Pi-Hole | +--+ | | | | | 35 | | | | +-------------------> +-----------------------------> | | | | | | | 36 | | | | | | +-------------------------+ | | | | | 37 | | | | | | | | | | | 38 | | | | | | +-------------------------+ | | | | | 39 | | | | | | | | | | | | | 40 | | | | | | | Unbound-VPN | +----+ | | | | 41 | | | | | | +> | | | | | | 42 | | | | | | | +-------------------------+ | | | | 43 | | | | | | DNS | | | | | 44 | | | | | | + +-------------------------+ | | | | 45 | | | | DNS | DNAT | | | | | | | 46 | | | | +-------------------> +-----------------------------> | Pi-Hole-VPN | +------+ | | | 47 | | | | | | | | | | | 48 | | | | | | +-------------------------+ | | | 49 | | | | | | | | | 50 | | | | | | +-------------------------+ | | | 51 | | | | | | | | | | | 52 | | | | | | +> | dnsmasq | | | | 53 | | | | | | | | | | | | 54 | | | | | | | +-------------------------+ | | | 55 | | | | | | | | | | 56 | | | | | | DHCP | +-------------------------+ | | | 57 | | | | | | + | | | | | 58 | | | | DHCP | | | DHCP-Helper | | | | 59 | | | | +---------------------------------------------------> | | | | | 60 | | | | | | +-------------------------+ | | | 61 | | | | | | | | | 62 | | +-----------+ | +---------------------------------------------------------------------+ | | 63 | | +-------------------------------------------------------------------------------------------+ | 64 | +---------------------------------------------------------------------------------------------------------------------+ 65 | ``` 66 | -------------------------------------------------------------------------------- /unbound/guide/main.md: -------------------------------------------------------------------------------- 1 | # Download files: 2 | 3 | $ git clone https://github.com/Trigus42/Private-LAN /etc/private-lan 4 | 5 | #### Create volume directories: 6 | 7 | $ mkdir -p /etc/private-lan/volumes/{unbound,dnsmasq,wireguard-gw,wireguard-dns,pihole,pihole-vpn} 8 | 9 | #### Move compose file to /etc/private-lan: 10 | 11 | $ mv /etc/private-lan/unbound/docker-compose.yml /etc/private-lan/ 12 | 13 | #### Edit docker-compose file: 14 | 15 | Edit the IPs in the port section of the pihole and pihole-vpn container in /etc/private-lan/docker-compose.yml to match your network environment. 16 | 17 | #### Place config files in volume directories: 18 | 19 | ``` 20 | $ echo "GRAVITYDB=/etc/pihole/gravity/gravity.db" | tee /etc/private-lan/volumes/pihole/pihole-FTL.conf /etc/private-lan/volumes/pihole-vpn/pihole-FTL.conf 21 | $ cp /etc/private-lan/unbound/unbound.conf /etc/private-lan/volumes/unbound/ 22 | ``` 23 | 24 | # Network configuration 25 | 26 | Add this to /etc/network/interfaces to create a new virtual interface and set a static IP: 27 | 28 | ``` 29 | auto eth0 30 | allow-hotplug eth0 31 | iface eth0 inet static 32 | address 192.168.178.2 33 | netmask 255.255.255.0 34 | gateway 192.168.178.1 35 | dns-nameservers 8.8.8.8 1.1.1.1 36 | dns-search domain-name 37 | 38 | auto eth0.1 39 | allow-hotplug eth0.1 40 | iface eth0.1 inet static 41 | address 192.168.178.3 42 | netmask 255.255.255.0 43 | vlan-raw-device eth0 44 | ``` 45 | 46 | #### Disable DHCP: 47 | 48 | $ systemctl disable dhcpcd 49 | 50 | #### Apply network changes: 51 | 52 | $ systemctl restart networking.service 53 | 54 | # Setup Docker 55 | 56 | #### Install Docker Engine: 57 | 58 | $ curl -fsSL https://get.docker.com | bash 59 | 60 | #### Install Docker Compose: 61 | 62 | $ apt install python3-pip -y && pip3 install docker-compose 63 | 64 | #### Enable Docker to start on boot: 65 | 66 | $ systemctl enable docker 67 | 68 | 69 | # Install Wireguard 70 | #### Install the Wireguard kernel module if your are on Debain Buster or lower : 71 | 72 | ``` 73 | $ echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list 74 | $ wget -O - https://ftp-master.debian.org/keys/archive-key-$(lsb_release -sr).asc | sudo apt-key add - 75 | $ printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable 76 | $ apt update 77 | ``` 78 | On Rapberry PI OS run: 79 | 80 | $ apt install raspberrypi-kernel-headers wireguard -y 81 | 82 | On any standard Debian installation run: 83 | 84 | $ apt install linux-headers wireguard -y 85 | 86 | #### If you are on Bullseye or higher run: 87 | 88 | $ apt install wireguard -y 89 | 90 | #### Wireguard config 91 | 92 | Download your config file(s) and insert the following lines in the Wireguard config file below `[Interface]`: 93 | 94 | ``` 95 | # Don't allow forwarding from eth0 to eth0 (bypassing the VPN gateway) 96 | PreUp = iptables -I FORWARD -i eth0 -o eth0 -j REJECT 97 | # Replace the source IP of packets going out trough the Wireguard interface AND add a route to your LAN subnet 98 | PostUp = iptables -t nat -A POSTROUTING -o %i -j MASQUERADE && ip route add via 172.16.238.1 99 | PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE && ip route delete via 172.16.238.1 100 | ``` 101 | 102 | Copy it to ```/etc/private-lan/volumes/wireguard-gw``` and ```/etc/private-lan/volumes/wireguard-dns``` as ```wg0.conf```. 103 | 104 |
105 | Example 106 | 107 | ``` 108 | [Interface] 109 | PrivateKey = ... 110 | Address = 100.64.67.64/32 111 | DNS = 10.255.255.3 112 | 113 | PreUp = iptables -I FORWARD -i eth0 -o eth0 -j REJECT 114 | PostUp = iptables -t nat -A POSTROUTING -o %i -j MASQUERADE && ip route add 192.168.178.0/24 via 172.16.238.1 115 | PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE && ip route delete 192.168.178.0/24 via 172.16.238.1 116 | 117 | [Peer] 118 | PublicKey = ... 119 | AllowedIPs = 0.0.0.0/0 120 | Endpoint = lon-229-wg.whiskergalaxy.com:443 121 | PresharedKey = ... 122 | ``` 123 |
124 | 125 | Assign permissions and ownership (No one but root should be able to see Private Key and PSK): 126 | 127 | $ chown -R root:root /etc/private-lan/volumes/wireguard-gw 128 | $ chmod 600 -R /etc/private-lan/volumes/wireguard-gw 129 | 130 | # Setup routing and NAT 131 | 132 | ``` 133 | $ cp /etc/private-lan/unbound/gateway*.sh /etc/init.d/ 134 | $ cp /etc/private-lan/unbound/gateway*.service /etc/systemd/system/ 135 | $ cp /etc/private-lan/gateway*.service /etc/systemd/system/ 136 | ``` 137 | 138 | #### Make the scripts executable 139 | ``` 140 | $ chmod +x /etc/init.d/gateway*.sh 141 | $ chmod +x /etc/private-lan/set-route.sh 142 | ``` 143 | 144 | #### Enable as a new service 145 | ``` 146 | $ systemctl daemon-reload 147 | $ systemctl enable gateway.service 148 | $ systemctl enable gateway-firewall.service 149 | ``` 150 | 151 | #### Edit kernel parameters to enable IP forwarding and enhance security: 152 | Uncomment/paste in /etc/sysctl.conf: 153 | ```yaml 154 | #IP Forwarding 155 | net.ipv4.ip_forward = 1 156 | #IP Spoofing protection 157 | net.ipv4.conf.all.rp_filter = 1 158 | net.ipv4.conf.default.rp_filter = 1 159 | #Ignore ICMP broadcast requests 160 | net.ipv4.icmp_echo_ignore_broadcasts = 1 161 | #Ignore ICMP redirects 162 | net.ipv4.conf.all.accept_redirects = 0 163 | net.ipv6.conf.all.accept_redirects = 0 164 | #Ignore send redirects 165 | net.ipv4.conf.all.send_redirects = 0 166 | net.ipv4.conf.default.send_redirects = 0 167 | #Disable source packet routing 168 | net.ipv4.conf.all.accept_source_route = 0 169 | net.ipv6.conf.all.accept_source_route = 0 170 | net.ipv4.conf.default.accept_source_route = 0 171 | net.ipv6.conf.default.accept_source_route = 0 172 | # Block SYN attacks 173 | net.ipv4.tcp_syncookies = 1 174 | net.ipv4.tcp_max_syn_backlog = 2048 175 | net.ipv4.tcp_synack_retries = 2 176 | net.ipv4.tcp_syn_retries = 5 177 | # Log Martians 178 | net.ipv4.conf.all.log_martians = 1 179 | net.ipv4.conf.default.log_martians=1 180 | ``` 181 | Load these changes: 182 | 183 | $ sysctl -p /etc/sysctl.conf 184 | 185 | *More info about these settings: 186 | [IP Spoofing](http://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.kernel.rpf.html) 187 | [ICMP broadcast requests](https://www.cloudflare.com/learning/ddos/smurf-ddos-attack/) 188 | [ICMP redirects](https://askubuntu.com/questions/118273/what-are-icmp-redirects-and-should-they-be-blocked) 189 | [Source packet routing](https://www.ccexpert.us/basic-security-services/disable-ip-source-routing.html) 190 | [SYN attacks](https://www.symantec.com/connect/articles/hardening-tcpip-stack-syn-attacks)* 191 | 192 | # Start everything up (or reboot) 193 | 194 | $ systemctl start gateway-firewall.service 195 | $ docker-compose -f /etc/private-lan/docker-compose.yml up -d 196 | $ systemctl start gateway.service 197 | 198 | #### Change gravity.db volume permissions 199 | 200 | $ chown 999:spi -R /etc/private-lan/volumes/pihole/gravity 201 | $ chmod 774 -R /etc/private-lan/volumes/pihole/gravity 202 | 203 | #### Set the Pi-Hole web interface password 204 | 205 | $ docker exec -it pihole pihole -a -p 206 | 207 | #### Client setup 208 | 209 | You can now manually configure your server as network gateway and DNS server in individual devices. 210 | However, it's much more convenient to set up a DHCP server. 211 | 212 | Using the IPs from the example network environment in /etc/private-lan/docker-compose.yml, you would configure the devices as follows: 213 | 214 | VPN: 215 | Gateway: `192.168.178.2` (or `192.168.178.3`) 216 | DNS: `192.168.178.3` 217 | 218 | Direct: 219 | Gateway: `192.168.178.1` 220 | DNS: `192.168.178.2` 221 | 222 | 223 | # Optional 224 | 225 | - ### [DHCP server](./DHCP.md) 226 | - ### [PiVPN](/guide/PiVPN.md) 227 | - ### [Updating](/guide/update.md) 228 | -------------------------------------------------------------------------------- /unbound/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | seperator() { 4 | screen_size=$(stty size) 5 | printf -v rows '%d' "${screen_size%% *}" 6 | for ((i=1;i<=rows;i++)); do echo -n "-"; done 7 | echo "" 8 | } 9 | 10 | msg_rows() { 11 | screen_size=$(stty size) 12 | printf -v rows '%d' "${screen_size%% *}" 13 | echo -n "$(( rows / 2 ))" 14 | } 15 | 16 | msg_columns() { 17 | screen_size=$(stty size) 18 | printf -v columns '%d' "${screen_size##* }" 19 | echo -n "$(( columns / 2 ))" 20 | } 21 | 22 | # User must be root 23 | printf "\\n" 24 | if [[ ! "${EUID}" -eq 0 ]]; then 25 | printf "Script called with non-root privileges" 26 | exit 1 27 | fi 28 | 29 | if whiptail --defaultno --title "Update" --yesno "Is recommended to update your system first.\nDepending on how old of an image you are using, this can take a while.\n\nDo you want to update?" $(msg_rows) $(msg_columns); then 30 | printf "\nUpdating...\n" 31 | seperator 32 | apt-get update 33 | apt-get upgrade -y 34 | seperator 35 | fi 36 | 37 | if whiptail --title "Install" --yesno "This script will now install\n- Docker\n- Python3\n- Docker Compose\n- Wireguard\n\nDo you want to proceed?" $(msg_rows) $(msg_columns); then 38 | printf "\nInstalling Docker...\n" 39 | seperator 40 | # curl -fsSL https://get.docker.com | bash 41 | seperator 42 | 43 | printf "\nInstalling Python3 and Docker Compose...\n" 44 | seperator 45 | apt install -y python3-pip -y 46 | pip3 install docker-compose -y 47 | seperator 48 | 49 | printf "\nInstalling Wireguard...\n" 50 | # Check if the Wireguard module is loaded 51 | if ! lsmod | grep "wireguard" &> /dev/null; then 52 | 53 | # If it is installed but not loaded, load it on boot-up 54 | if $(modprobe wireguard); then 55 | "wireguard" >> /etc/modules 56 | update-initramfs -u 57 | 58 | elif whiptail --title "Wireguard kernel module" --yesno "The Wireguard kernel module is not installed.\nDo you want to try installing it?" $(msg_rows) $(msg_columns); then 59 | # Add "unstable" sources 60 | seperator 61 | echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list 62 | wget -q -O - https://ftp-master.debian.org/keys/archive-key-$(lsb_release -sr).asc &> /dev/null | sudo apt-key add - 63 | printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable 64 | apt update 65 | 66 | # Kernel headers package is named differently on the RPi 67 | if [ $(python -c "import platform; print 'raspberrypi' in platform.uname()") == "True" ]; then 68 | apt install raspberrypi-kernel-headers wireguard -y 69 | else 70 | apt install linux-headers-$(uname -r) wireguard -y 71 | fi 72 | 73 | seperator 74 | else 75 | exit 1 76 | fi 77 | else 78 | exit 1 79 | fi 80 | 81 | printf "\nPreparing configs...\n" 82 | mkdir -p /etc/private-lan/volumes/{dnscrypt-proxy,wireguard-gateway,etc-pihole,etc-dnsmasq.d} 83 | chown -R root /etc/private-lan/volumes/wireguard-gateway 84 | chmod 600 -R /etc/private-lan/volumes/wireguard-gateway 85 | printf "Downloading docker/files...\n" 86 | git clone --quiet https://github.com/Trigus42/Private-LAN /tmp/private-lan 87 | mv /tmp/private-lan/docker/files/etc/* /etc/private-lan/ 88 | printf "Creating dnscrypt-proxy base config...\n" 89 | wget -q https://raw.githubusercontent.com/DNSCrypt/dnscrypt-proxy/release/dnscrypt-proxy/example-dnscrypt-proxy.toml -O /etc/private-lan/volumes/dnscrypt-proxy/dnscrypt-proxy.toml 90 | sed -i "s/listen_addresses = \['127\.0\.0\.1:53']/listen_addresses = ['127.0.0.1:5300', '[::1]:5300']/gm" /etc/private-lan/volumes/dnscrypt-proxy/dnscrypt-proxy.toml 91 | -------------------------------------------------------------------------------- /unbound/unbound.conf: -------------------------------------------------------------------------------- 1 | # For further information read: https://nlnetlabs.nl/documentation/unbound/unbound.conf/ 2 | 3 | server: 4 | # Listen on all interfaces 5 | interface: 0.0.0.0 6 | interface: ::0 7 | 8 | # The port number, default 53, on which the server responds to queries. 9 | port: 53 10 | 11 | # If given, after binding the port the user privileges are dropped. 12 | # Default is "unbound". If you give username: "" no user change is performed. 13 | username: "unbound" 14 | 15 | # The netblock is given as an IP4 or IP6 address with /size appended for a 16 | # classless network block. The action can be deny, refuse, allow or allow_snoop. 17 | # Here 0.0.0.0/0 is used cause we run it in a container and access to it should 18 | # controlled by the host. 19 | access-control: 0.0.0.0/0 allow 20 | 21 | # If "" is given, logging goes to stderr, or nowhere once daemonized. 22 | logfile: "" 23 | 24 | # The verbosity number, level 0 means no verbosity, only errors. 25 | # Level 1 gives operational information. 26 | # Level 2 gives detailed operational information. 27 | # Level 3 gives query level information, output per query. 28 | # Level 4 gives algorithm level information. 29 | # Level 5 logs client identification for cache misses. 30 | # Default is level 1. The verbosity can also be increased from the commandline. 31 | verbosity: 2 32 | 33 | # Read the root hints from this file. Default is nothing, using 34 | # builtin hints for the IN class. The file has the format of zone 35 | # files, with root nameserver names and addresses only. The 36 | # default may become outdated, when servers change, therefore it 37 | # is good practice to use a root-hints file. 38 | root-hints: /etc/unbound/root.hints 39 | 40 | # File with trust anchor for one zone, which is tracked with RFC5011 probes. 41 | # The probes are several times per month, thus the machine must be online frequently. 42 | # The initial file can be one with contents as described in trust-anchor-file. 43 | # The file is written to when the anchor is updated, so the unbound user must 44 | # have write permission. 45 | auto-trust-anchor-file: /usr/share/dnssec-root/trusted-key.key 46 | 47 | # Harden against algorithm downgrade when multiple algorithms are 48 | # advertised in the DS record. 49 | harden-algo-downgrade: yes 50 | 51 | # RFC 8020. returns nxdomain to queries for a name below another name that 52 | # is already known to be nxdomain. 53 | harden-below-nxdomain: yes 54 | 55 | # Require DNSSEC data for trust-anchored zones, if such data is absent, the 56 | # zone becomes bogus. If turned off you run the risk of a downgrade attack 57 | # that disables security for a zone. 58 | harden-dnssec-stripped: yes 59 | 60 | # Only trust glue if it is within the servers authority. 61 | harden-glue: yes 62 | 63 | # Ignore very large queries. 64 | harden-large-queries: yes 65 | 66 | # Perform additional queries for infrastructure data to harden the referral 67 | # path. Validates the replies if trust anchors are configured and the zones 68 | # are signed. This enforces DNSSEC validation on nameserver NS sets and the 69 | # nameserver addresses that are encountered on the referral path to the 70 | # answer. Experimental option. 71 | harden-referral-path: no 72 | 73 | # Ignore very small EDNS buffer sizes from queries. 74 | harden-short-bufsize: yes 75 | 76 | # Refuse id.server and hostname.bind queries 77 | hide-identity: yes 78 | 79 | # Refuse version.server and version.bind queries 80 | hide-version: yes 81 | 82 | # Report this identity rather than the hostname of the server. 83 | identity: "DNS" 84 | 85 | # These private network addresses are not allowed to be returned for public 86 | # internet names. Any occurrence of such addresses are removed from DNS 87 | # answers. Additionally, the DNSSEC validator may mark the answers bogus. 88 | # This protects against DNS Rebinding 89 | private-address: 10.0.0.0/8 90 | private-address: 172.16.0.0/12 91 | private-address: 192.168.178.0/16 92 | private-address: 169.254.0.0/16 93 | private-address: fd00::/8 94 | private-address: fe80::/10 95 | private-address: ::ffff:0:0/96 96 | 97 | # Use 0x20-encoded random bits in the query to foil spoof attempts. This 98 | # perturbs the lowercase and uppercase of query names sent to authority 99 | # servers and checks if the reply still has the correct casing. 100 | # This feature is an experimental implementation of draft dns-0x20. 101 | # Experimental option. 102 | use-caps-for-id: yes 103 | 104 | # Help protect users that rely on this validator for authentication from 105 | # potentially bad data in the additional section. Instruct the validator to 106 | # remove data from the additional section of secure messages that are not 107 | # signed properly. Messages that are insecure, bogus, indeterminate or 108 | # unchecked are not affected. 109 | val-clean-additional: yes --------------------------------------------------------------------------------