├── .env.example ├── .github ├── FUNDING.yml └── workflows │ └── stale.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── docker-compose.yml └── unbound └── unbound.conf /.env.example: -------------------------------------------------------------------------------- 1 | # Docker Compose Environment Configuration 2 | 3 | # General settings 4 | # Set your timezone 5 | TIMEZONE=America/Los_Angeles 6 | 7 | # User and group identifiers 8 | # User ID 9 | PUID=1000 10 | # Group ID 11 | PGID=1000 12 | 13 | # Network settings 14 | # Subnet for the private network - NOT USED IN COMPOSE FILE, CAN BE REMOVED 15 | # SUBNET=10.2.0.0/24 16 | 17 | # Static IP for Unbound 18 | UNBOUND_IPV4_ADDRESS=10.2.0.200 19 | # Static IP for Pi-hole 20 | PIHOLE_IPV4_ADDRESS=10.2.0.100 21 | # Port for Wireguard server 22 | WIREGUARD_SERVER_PORT=51820 23 | # DNS for Wireguard peers, set to Pi-hole 24 | WIREGUARD_PEER_DNS=10.2.0.100 25 | 26 | # Wireguard settings 27 | # Number of peers (clients) to generate 28 | WIREGUARD_PEERS=1 29 | 30 | # Wireguard-UI settings 31 | # Session secret, change to something secure 32 | WGUI_SESSION_SECRET= 33 | # Username for Wireguard-UI 34 | WGUI_USERNAME=admin 35 | # Password for Wireguard-UI, change to something secure 36 | WGUI_PASSWORD=admin 37 | # Enable management of Wireguard start 38 | WGUI_MANAGE_START=true 39 | # Enable management of Wireguard restart 40 | WGUI_MANAGE_RESTART=true 41 | 42 | # Pi-hole settings 43 | # Web password for Pi-hole, set to a secure password 44 | WEBPASSWORD= 45 | 46 | # IP address for the Unbound server used by Pi-hole 47 | PIHOLE_DNS=10.2.0.200 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: IAmStoxe 2 | custom: "https://www.buymeacoffee.com/stoxe" -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. 2 | # 3 | # You can adjust the behavior by modifying this file. 4 | # For more information, see: 5 | # https://github.com/actions/stale 6 | name: Mark stale issues and pull requests 7 | 8 | on: workflow_dispatch 9 | 10 | jobs: 11 | stale: 12 | 13 | runs-on: ubuntu-latest 14 | permissions: 15 | issues: write 16 | pull-requests: write 17 | 18 | steps: 19 | - uses: actions/stale@v5 20 | with: 21 | repo-token: ${{ secrets.GITHUB_TOKEN }} 22 | stale-issue-message: 'Stale issue message' 23 | stale-pr-message: 'Stale pull request message' 24 | stale-issue-label: 'no-issue-activity' 25 | stale-pr-label: 'no-pr-activity' 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | wireguard/ 2 | unbound/* 3 | etc-pihole/ 4 | etc-dnsmasq.d/ 5 | !unbound/unbound.conf 6 | config/ 7 | db/ 8 | .env* 9 | !.env.example -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## Dependencies 2 | 3 | - [wireguard-ui license (MIT)](https://github.com/ngoduykhanh/wireguard-ui/blob/master/LICENSE) 4 | - [Pi-hole license (EUPL)](https://github.com/pi-hole/pi-hole/blob/master/LICENSE) 5 | - [Unbound-docker license (MIT)](https://github.com/MatthewVance/unbound-docker/blob/master/LICENSE) 6 | 7 | ## Disclaimer 8 | 9 | This software is provided "as is" and without any express or implied warranties, including, without limitation, the implied warranties of merchantability and fitness for a particular purpose. 10 | 11 | ## License 12 | 13 | Apache License 14 | Version 2.0, January 2004 15 | http://www.apache.org/licenses/ 16 | 17 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 18 | 19 | 1. Definitions. 20 | 21 | "License" shall mean the terms and conditions for use, reproduction, 22 | and distribution as defined by Sections 1 through 9 of this document. 23 | 24 | "Licensor" shall mean the copyright owner or entity authorized by 25 | the copyright owner that is granting the License. 26 | 27 | "Legal Entity" shall mean the union of the acting entity and all 28 | other entities that control, are controlled by, or are under common 29 | control with that entity. For the purposes of this definition, 30 | "control" means (i) the power, direct or indirect, to cause the 31 | direction or management of such entity, whether by contract or 32 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 33 | outstanding shares, or (iii) beneficial ownership of such entity. 34 | 35 | "You" (or "Your") shall mean an individual or Legal Entity 36 | exercising permissions granted by this License. 37 | 38 | "Source" form shall mean the preferred form for making modifications, 39 | including but not limited to software source code, documentation 40 | source, and configuration files. 41 | 42 | "Object" form shall mean any form resulting from mechanical 43 | transformation or translation of a Source form, including but 44 | not limited to compiled object code, generated documentation, 45 | and conversions to other media types. 46 | 47 | "Work" shall mean the work of authorship, whether in Source or 48 | Object form, made available under the License, as indicated by a 49 | copyright notice that is included in or attached to the work 50 | (an example is provided in the Appendix below). 51 | 52 | "Derivative Works" shall mean any work, whether in Source or Object 53 | form, that is based on (or derived from) the Work and for which the 54 | editorial revisions, annotations, elaborations, or other modifications 55 | represent, as a whole, an original work of authorship. For the purposes 56 | of this License, Derivative Works shall not include works that remain 57 | separable from, or merely link (or bind by name) to the interfaces of, 58 | the Work and Derivative Works thereof. 59 | 60 | "Contribution" shall mean any work of authorship, including 61 | the original version of the Work and any modifications or additions 62 | to that Work or Derivative Works thereof, that is intentionally 63 | submitted to Licensor for inclusion in the Work by the copyright owner 64 | or by an individual or Legal Entity authorized to submit on behalf of 65 | the copyright owner. For the purposes of this definition, "submitted" 66 | means any form of electronic, verbal, or written communication sent 67 | to the Licensor or its representatives, including but not limited to 68 | communication on electronic mailing lists, source code control systems, 69 | and issue tracking systems that are managed by, or on behalf of, the 70 | Licensor for the purpose of discussing and improving the Work, but 71 | excluding communication that is conspicuously marked or otherwise 72 | designated in writing by the copyright owner as "Not a Contribution." 73 | 74 | "Contributor" shall mean Licensor and any individual or Legal Entity 75 | on behalf of whom a Contribution has been received by Licensor and 76 | subsequently incorporated within the Work. 77 | 78 | 2. Grant of Copyright License. Subject to the terms and conditions of 79 | this License, each Contributor hereby grants to You a perpetual, 80 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 81 | copyright license to reproduce, prepare Derivative Works of, 82 | publicly display, publicly perform, sublicense, and distribute the 83 | Work and such Derivative Works in Source or Object form. 84 | 85 | 3. Grant of Patent License. Subject to the terms and conditions of 86 | this License, each Contributor hereby grants to You a perpetual, 87 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 88 | (except as stated in this section) patent license to make, have made, 89 | use, offer to sell, sell, import, and otherwise transfer the Work, 90 | where such license applies only to those patent claims licensable 91 | by such Contributor that are necessarily infringed by their 92 | Contribution(s) alone or by combination of their Contribution(s) 93 | with the Work to which such Contribution(s) was submitted. If You 94 | institute patent litigation against any entity (including a 95 | cross-claim or counterclaim in a lawsuit) alleging that the Work 96 | or a Contribution incorporated within the Work constitutes direct 97 | or contributory patent infringement, then any patent licenses 98 | granted to You under this License for that Work shall terminate 99 | as of the date such litigation is filed. 100 | 101 | 4. Redistribution. You may reproduce and distribute copies of the 102 | Work or Derivative Works thereof in any medium, with or without 103 | modifications, and in Source or Object form, provided that You 104 | meet the following conditions: 105 | 106 | (a) You must give any other recipients of the Work or 107 | Derivative Works a copy of this License; and 108 | 109 | (b) You must cause any modified files to carry prominent notices 110 | stating that You changed the files; and 111 | 112 | (c) You must retain, in the Source form of any Derivative Works 113 | that You distribute, all copyright, patent, trademark, and 114 | attribution notices from the Source form of the Work, 115 | excluding those notices that do not pertain to any part of 116 | the Derivative Works; and 117 | 118 | (d) If the Work includes a "NOTICE" text file as part of its 119 | distribution, then any Derivative Works that You distribute must 120 | include a readable copy of the attribution notices contained 121 | within such NOTICE file, excluding those notices that do not 122 | pertain to any part of the Derivative Works, in at least one 123 | of the following places: within a NOTICE text file distributed 124 | as part of the Derivative Works; within the Source form or 125 | documentation, if provided along with the Derivative Works; or, 126 | within a display generated by the Derivative Works, if and 127 | wherever such third-party notices normally appear. The contents 128 | of the NOTICE file are for informational purposes only and 129 | do not modify the License. You may add Your own attribution 130 | notices within Derivative Works that You distribute, alongside 131 | or as an addendum to the NOTICE text from the Work, provided 132 | that such additional attribution notices cannot be construed 133 | as modifying the License. 134 | 135 | You may add Your own copyright statement to Your modifications and 136 | may provide additional or different license terms and conditions 137 | for use, reproduction, or distribution of Your modifications, or 138 | for any such Derivative Works as a whole, provided Your use, 139 | reproduction, and distribution of the Work otherwise complies with 140 | the conditions stated in this License. 141 | 142 | 5. Submission of Contributions. Unless You explicitly state otherwise, 143 | any Contribution intentionally submitted for inclusion in the Work 144 | by You to the Licensor shall be under the terms and conditions of 145 | this License, without any additional terms or conditions. 146 | Notwithstanding the above, nothing herein shall supersede or modify 147 | the terms of any separate license agreement you may have executed 148 | with Licensor regarding such Contributions. 149 | 150 | 6. Trademarks. This License does not grant permission to use the trade 151 | names, trademarks, service marks, or product names of the Licensor, 152 | except as required for reasonable and customary use in describing the 153 | origin of the Work and reproducing the content of the NOTICE file. 154 | 155 | 7. Disclaimer of Warranty. Unless required by applicable law or 156 | agreed to in writing, Licensor provides the Work (and each 157 | Contributor provides its Contributions) on an "AS IS" BASIS, 158 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 159 | implied, including, without limitation, any warranties or conditions 160 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 161 | PARTICULAR PURPOSE. You are solely responsible for determining the 162 | appropriateness of using or redistributing the Work and assume any 163 | risks associated with Your exercise of permissions under this License. 164 | 165 | 8. Limitation of Liability. In no event and under no legal theory, 166 | whether in tort (including negligence), contract, or otherwise, 167 | unless required by applicable law (such as deliberate and grossly 168 | negligent acts) or agreed to in writing, shall any Contributor be 169 | liable to You for damages, including any direct, indirect, special, 170 | incidental, or consequential damages of any character arising as a 171 | result of this License or out of the use or inability to use the 172 | Work (including but not limited to damages for loss of goodwill, 173 | work stoppage, computer failure or malfunction, or any and all 174 | other commercial damages or losses), even if such Contributor 175 | has been advised of the possibility of such damages. 176 | 177 | 9. Accepting Warranty or Additional Liability. While redistributing 178 | the Work or Derivative Works thereof, You may choose to offer, 179 | and charge a fee for, acceptance of support, warranty, indemnity, 180 | or other liability obligations and/or rights consistent with this 181 | License. However, in accepting such obligations, You may act only 182 | on Your own behalf and on Your sole responsibility, not on behalf 183 | of any other Contributor, and only if You agree to indemnify, 184 | defend, and hold each Contributor harmless for any liability 185 | incurred by, or claims asserted against, such Contributor by reason 186 | of your accepting any such warranty or additional liability. 187 | 188 | END OF TERMS AND CONDITIONS 189 | 190 | APPENDIX: How to apply the Apache License to your work. 191 | 192 | To apply the Apache License to your work, attach the following 193 | boilerplate notice, with the fields enclosed by brackets "[]" 194 | replaced with your own identifying information. (Don't include 195 | the brackets!) The text should be enclosed in the appropriate 196 | comment syntax for the file format. We also recommend that a 197 | file or class name and description of purpose be included on the 198 | same "printed page" as the copyright notice for easier 199 | identification within third-party archives. 200 | 201 | Copyright [yyyy] [name of copyright owner] 202 | 203 | Licensed under the Apache License, Version 2.0 (the "License"); 204 | you may not use this file except in compliance with the License. 205 | You may obtain a copy of the License at 206 | 207 | http://www.apache.org/licenses/LICENSE-2.0 208 | 209 | Unless required by applicable law or agreed to in writing, software 210 | distributed under the License is distributed on an "AS IS" BASIS, 211 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 212 | See the License for the specific language governing permissions and 213 | limitations under the License. 214 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## What is this? 3 | 4 | WireHole is a docker-compose project that combines WireGuard, PiHole, and Unbound to create a full or split-tunnel VPN that is easy to deploy and manage. This setup allows for a VPN with ad-blocking via PiHole and enhanced DNS privacy and caching through Unbound. 5 | 6 | ## Author 7 | 8 | 👤 **Devin Stokes** 9 | 10 | - Twitter: [@DevinStokes](https://twitter.com/DevinStokes) 11 | - GitHub: [@IAmStoxe](https://github.com/IAmStoxe) 12 | 13 | ## 🤝 Contributing 14 | 15 | Contributions, issues, and feature requests are welcome! Feel free to check the [issues page](https://github.com/IAmStoxe/wirehole/issues). 16 | 17 | ## Show your support 18 | 19 | Give a ⭐ if this project helped you! 20 | 21 | [![Buy Me A Coffee](https://cdn.buymeacoffee.com/buttons/v2/default-orange.png)](https://www.buymeacoffee.com/stoxe) 22 | 23 | --- 24 | 25 | ### Supported Architectures 26 | 27 | The image supports multiple architectures such as `x86-64`, `arm64`, and `armhf`. The `linuxserver/wireguard` image automatically selects the correct image for your architecture. 28 | 29 | **The architectures supported by this image are:** 30 | 31 | | Architecture | Tag | 32 | | ------------ | -------------- | 33 | | x86-64 | amd64-latest | 34 | | arm64 | arm64v8-latest | 35 | | armhf | arm32v7-latest | 36 | 37 | --- 38 | 39 | ### Quickstart 40 | 41 | To begin using WireHole, clone the repository and start the containers: 42 | 43 | ```bash 44 | #!/bin/bash 45 | 46 | # Clone the WireHole repository from GitHub 47 | git clone https://github.com/IAmStoxe/wirehole.git 48 | 49 | # Change directory to the cloned repository 50 | cd wirehole 51 | 52 | # Update the .env file with your configuration 53 | cp .env.example .env 54 | nano .env # Or use any text editor of your choice to edit the .env file 55 | 56 | # Replace the public IP placeholder in the docker-compose.yml 57 | sed -i "s/REPLACE_ME_WITH_YOUR_PUBLIC_IP/$(curl -s ifconfig.me)/g" docker-compose.yml 58 | 59 | # Start the Docker containers 60 | docker compose up 61 | ``` 62 | 63 | Remember to set secure passwords for `WGUI_SESSION_SECRET`, `WGUI_PASSWORD`, and `WEBPASSWORD` in your `.env` file. 64 | 65 | --- 66 | 67 | ## Environment Configuration Details 68 | 69 | The `.env` file contains a series of environment variables that are essential for configuring the WireHole services within the Docker containers. Here is a detailed explanation of each variable: 70 | 71 | ### General Settings 72 | 73 | - `TIMEZONE`: Sets the timezone for all services. It is important for logging and time-based operations. Example: `America/Los_Angeles`. 74 | 75 | ### User / Group Identifiers 76 | 77 | - `PUID` and `PGID`: These ensure that the services have the correct permissions to access and modify files on the host system. They should match the user ID and group ID of the host user. 78 | 79 | ### Network Settings 80 | 81 | - `UNBOUND_IPV4_ADDRESS`: The static IP address assigned to Unbound, ensuring it is reachable by Pi-hole. 82 | - `PIHOLE_IPV4_ADDRESS`: The static IP address assigned to Pi-hole, allowing it to serve DNS requests for the network. 83 | - `WIREGUARD_SERVER_PORT`: The port on which the WireGuard server will listen for connections. 84 | - `WIREGUARD_PEER_DNS`: The DNS server that WireGuard clients will use, which is typically set to the Pi-hole's address. 85 | 86 | ### WireGuard Settings 87 | 88 | - `WIREGUARD_PEERS`: Specifies the number of peer/client configurations to generate for WireGuard. 89 | 90 | ### WireGuard-UI Settings 91 | 92 | - `WGUI_SESSION_SECRET`: A secret key used to encrypt session data for WireGuard-UI. This should be set to a secure, random value. 93 | - `WGUI_USERNAME` and `WGUI_PASSWORD`: Credentials for accessing the WireGuard-UI interface. 94 | - `WGUI_MANAGE_START`: When set to `true`, WireGuard-UI will manage the starting of the WireGuard service. 95 | - `WGUI_MANAGE_RESTART`: When set to `true`, WireGuard-UI will manage the restarting of the WireGuard service. 96 | 97 | ### Pi-hole Settings 98 | 99 | - `WEBPASSWORD`: The password for accessing the Pi-hole web interface. It should be set to a secure value to prevent unauthorized access. 100 | - `PIHOLE_DNS`: The IP address of the Unbound server used by Pi-hole to resolve DNS queries. 101 | 102 | Remember to replace any default or placeholder values with secure, unique values before deploying your services. 103 | 104 | --- 105 | 106 | ### Recommended Configuration / Split Tunnel 107 | 108 | For a split-tunnel VPN, configure your WireGuard client `AllowedIps` to `10.2.0.0/24`, which will route only the web panel and DNS traffic through the VPN. 109 | 110 | --- 111 | 112 | ### Accessing the Web Panel (WireGuard-UI) 113 | 114 | Manage your WireGuard VPN through the WireGuard-UI at: 115 | 116 | `http://{YOUR_SERVER_IP}:5000` 117 | 118 | Log in with the `WGUI_USERNAME` and `WGUI_PASSWORD` you have set in your `.env` file. 119 | 120 | ### Features of WireGuard-UI 121 | 122 | - Client Management: Add, remove, and manage clients. 123 | - Authentication: Secure login with a username and password. 124 | - Configurations: Update global server settings and manage client configurations. 125 | 126 | --- 127 | 128 | ### Access PiHole 129 | 130 | Connect to WireGuard and access the Pi-hole admin panel at `http://10.2.0.100/admin`. The login password is the one set as `WEBPASSWORD` in your `.env` file. 131 | 132 | --- 133 | 134 | ### Dynamic DNS (DDNS) 135 | 136 | Configure DDNS by setting `WG_HOST` in your `.env` file to your DDNS URL. 137 | 138 | ```yaml 139 | wireguard: 140 | environment: 141 | - WG_HOST=my.ddns.net 142 | ``` 143 | 144 | --- 145 | 146 | ### Configuring / Parameters 147 | 148 | Explain all the environment variables from your `.env` file here. (Refer to the previous section where we provided a table of explanations for each variable.) 149 | 150 | --- 151 | 152 | ### Additional Settings and Considerations 153 | 154 | Discuss any additional settings such as Docker secrets, umask settings, user/group identifiers, adding clients, modifying DNS providers, and networking considerations. Make sure to update any instructions to match the current setup. 155 | 156 | --- 157 | 158 | ### Support and Updates 159 | 160 | Provide information on how to access the shell while the container is running, view logs, update containers, and handle frequently asked questions. Ensure all the commands and steps are updated to reflect the current versions and practices. 161 | 162 | --- 163 | 164 | ###### Acknowledgements 165 | 166 | Credit to LinuxServer.io for their maintenance of the Wireguard image and other contributions to the project. 167 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | networks: 3 | private_network: 4 | ipam: 5 | driver: default 6 | config: 7 | - subnet: 10.2.0.0/24 8 | services: 9 | unbound: 10 | image: mvance/unbound:latest 11 | container_name: unbound 12 | restart: unless-stopped 13 | hostname: unbound 14 | volumes: 15 | - ./unbound:/opt/unbound/etc/unbound/ 16 | networks: 17 | private_network: 18 | ipv4_address: 10.2.0.200 19 | cap_add: 20 | - NET_ADMIN 21 | env_file: .env 22 | wireguard: 23 | depends_on: 24 | - unbound 25 | - pihole 26 | image: linuxserver/wireguard 27 | container_name: wireguard 28 | ports: 29 | - 5000:5000 30 | - 51820:51820/udp 31 | cap_add: 32 | - NET_ADMIN 33 | - SYS_MODULE 34 | sysctls: 35 | - net.ipv4.conf.all.src_valid_mark=1 36 | - net.ipv4.ip_forward=1 37 | volumes: 38 | - ./config:/config 39 | env_file: .env 40 | 41 | wireguard-ui: 42 | image: ngoduykhanh/wireguard-ui:latest 43 | container_name: wireguard-ui 44 | depends_on: 45 | - wireguard 46 | cap_add: 47 | - NET_ADMIN 48 | network_mode: service:wireguard 49 | logging: 50 | driver: json-file 51 | options: 52 | max-size: 50m 53 | volumes: 54 | - ./db:/app/db 55 | - ./config:/config 56 | env_file: .env 57 | 58 | pihole: 59 | depends_on: 60 | - unbound 61 | container_name: pihole 62 | image: pihole/pihole:latest 63 | restart: unless-stopped 64 | hostname: pihole 65 | dns: 66 | - 127.0.0.1 67 | - ${PIHOLE_DNS} 68 | volumes: 69 | - ./etc-pihole/:/etc/pihole/ 70 | - ./etc-dnsmasq.d/:/etc/dnsmasq.d/ 71 | cap_add: 72 | - NET_ADMIN 73 | networks: 74 | private_network: 75 | ipv4_address: 10.2.0.100 76 | env_file: ./.env 77 | -------------------------------------------------------------------------------- /unbound/unbound.conf: -------------------------------------------------------------------------------- 1 | server: 2 | ########################################################################### 3 | # BASIC SETTINGS 4 | ########################################################################### 5 | # Time to live maximum for RRsets and messages in the cache. If the maximum 6 | # kicks in, responses to clients still get decrementing TTLs based on the 7 | # original (larger) values. When the internal TTL expires, the cache item 8 | # has expired. Can be set lower to force the resolver to query for data 9 | # often, and not trust (very large) TTL values. 10 | cache-max-ttl: 86400 11 | 12 | # Time to live minimum for RRsets and messages in the cache. If the minimum 13 | # kicks in, the data is cached for longer than the domain owner intended, 14 | # and thus less queries are made to look up the data. Zero makes sure the 15 | # data in the cache is as the domain owner intended, higher values, 16 | # especially more than an hour or so, can lead to trouble as the data in 17 | # the cache does not match up with the actual data any more. 18 | cache-min-ttl: 60 19 | 20 | # Set the working directory for the program. 21 | directory: "/opt/unbound/etc/unbound" 22 | 23 | # RFC 6891. Number of bytes size to advertise as the EDNS reassembly buffer 24 | # size. This is the value put into datagrams over UDP towards peers. 25 | # 4096 is RFC recommended. 1472 has a reasonable chance to fit within a 26 | # single Ethernet frame, thus lessing the chance of fragmentation 27 | # reassembly problems (usually seen as timeouts). Setting to 512 bypasses 28 | # even the most stringent path MTU problems, but is not recommended since 29 | # the amount of TCP fallback generated is excessive. 30 | edns-buffer-size: 1472 31 | 32 | # Listen to for queries from clients and answer from this network interface 33 | # and port. 34 | interface: 0.0.0.0@53 35 | 36 | # Rotates RRSet order in response (the pseudo-random number is taken from 37 | # the query ID, for speed and thread safety). 38 | rrset-roundrobin: yes 39 | 40 | # Drop user privileges after binding the port. 41 | username: "_unbound" 42 | 43 | ########################################################################### 44 | # LOGGING 45 | ########################################################################### 46 | 47 | # Do not print log lines to inform about local zone actions 48 | log-local-actions: no 49 | 50 | # Do not print one line per query to the log 51 | log-queries: no 52 | 53 | # Do not print one line per reply to the log 54 | log-replies: no 55 | 56 | # Do not print log lines that say why queries return SERVFAIL to clients 57 | log-servfail: no 58 | 59 | # Further limit logging 60 | logfile: /dev/null 61 | 62 | # Only log errors 63 | verbosity: 0 64 | 65 | ########################################################################### 66 | # PRIVACY SETTINGS 67 | ########################################################################### 68 | 69 | # RFC 8198. Use the DNSSEC NSEC chain to synthesize NXDO-MAIN and other 70 | # denials, using information from previous NXDO-MAINs answers. In other 71 | # words, use cached NSEC records to generate negative answers within a 72 | # range and positive answers from wildcards. This increases performance, 73 | # decreases latency and resource utilization on both authoritative and 74 | # recursive servers, and increases privacy. Also, it may help increase 75 | # resilience to certain DoS attacks in some circumstances. 76 | aggressive-nsec: yes 77 | 78 | # Extra delay for timeouted UDP ports before they are closed, in msec. 79 | # This prevents very delayed answer packets from the upstream (recursive) 80 | # servers from bouncing against closed ports and setting off all sort of 81 | # close-port counters, with eg. 1500 msec. When timeouts happen you need 82 | # extra sockets, it checks the ID and remote IP of packets, and unwanted 83 | # packets are added to the unwanted packet counter. 84 | delay-close: 10000 85 | 86 | # Prevent the unbound server from forking into the background as a daemon 87 | do-daemonize: no 88 | 89 | # Add localhost to the do-not-query-address list. 90 | do-not-query-localhost: no 91 | 92 | # Number of bytes size of the aggressive negative cache. 93 | neg-cache-size: 4M 94 | 95 | # Send minimum amount of information to upstream servers to enhance 96 | # privacy (best privacy). 97 | qname-minimisation: yes 98 | 99 | ########################################################################### 100 | # SECURITY SETTINGS 101 | ########################################################################### 102 | # Only give access to recursion clients from LAN IPs 103 | access-control: 127.0.0.1/32 allow 104 | access-control: 192.168.0.0/16 allow 105 | access-control: 172.16.0.0/12 allow 106 | access-control: 10.0.0.0/8 allow 107 | # access-control: fc00::/7 allow 108 | # access-control: ::1/128 allow 109 | 110 | # File with trust anchor for one zone, which is tracked with RFC5011 111 | # probes. 112 | auto-trust-anchor-file: "var/root.key" 113 | 114 | # Enable chroot (i.e, change apparent root directory for the current 115 | # running process and its children) 116 | chroot: "/opt/unbound/etc/unbound" 117 | 118 | # Deny queries of type ANY with an empty response. 119 | #deny-any: yes 120 | 121 | # Harden against algorithm downgrade when multiple algorithms are 122 | # advertised in the DS record. 123 | harden-algo-downgrade: yes 124 | 125 | # RFC 8020. returns nxdomain to queries for a name below another name that 126 | # is already known to be nxdomain. 127 | harden-below-nxdomain: yes 128 | 129 | # Require DNSSEC data for trust-anchored zones, if such data is absent, the 130 | # zone becomes bogus. If turned off you run the risk of a downgrade attack 131 | # that disables security for a zone. 132 | harden-dnssec-stripped: yes 133 | 134 | # Only trust glue if it is within the servers authority. 135 | harden-glue: yes 136 | 137 | # Ignore very large queries. 138 | harden-large-queries: yes 139 | 140 | # Perform additional queries for infrastructure data to harden the referral 141 | # path. Validates the replies if trust anchors are configured and the zones 142 | # are signed. This enforces DNSSEC validation on nameserver NS sets and the 143 | # nameserver addresses that are encountered on the referral path to the 144 | # answer. Experimental option. 145 | harden-referral-path: no 146 | 147 | # Ignore very small EDNS buffer sizes from queries. 148 | harden-short-bufsize: yes 149 | 150 | # Refuse id.server and hostname.bind queries 151 | hide-identity: yes 152 | 153 | # Refuse version.server and version.bind queries 154 | hide-version: yes 155 | 156 | # Report this identity rather than the hostname of the server. 157 | identity: "DNS" 158 | 159 | # These private network addresses are not allowed to be returned for public 160 | # internet names. Any occurrence of such addresses are removed from DNS 161 | # answers. Additionally, the DNSSEC validator may mark the answers bogus. 162 | # This protects against DNS Rebinding 163 | private-address: 10.0.0.0/8 164 | private-address: 172.16.0.0/12 165 | private-address: 192.168.0.0/16 166 | private-address: 169.254.0.0/16 167 | private-address: fd00::/8 168 | private-address: fe80::/10 169 | private-address: ::ffff:0:0/96 170 | 171 | # Enable ratelimiting of queries (per second) sent to nameserver for 172 | # performing recursion. More queries are turned away with an error 173 | # (servfail). This stops recursive floods (e.g., random query names), but 174 | # not spoofed reflection floods. Cached responses are not rate limited by 175 | # this setting. Experimental option. 176 | #ratelimit: 1000 177 | 178 | # Use this certificate bundle for authenticating connections made to 179 | # outside peers (e.g., auth-zone urls, DNS over TLS connections). 180 | tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt 181 | 182 | # Set the total number of unwanted replies to eep track of in every thread. 183 | # When it reaches the threshold, a defensive action of clearing the rrset 184 | # and message caches is taken, hopefully flushing away any poison. 185 | # Unbound suggests a value of 10 million. 186 | unwanted-reply-threshold: 10000000 187 | 188 | # Use 0x20-encoded random bits in the query to foil spoof attempts. This 189 | # perturbs the lowercase and uppercase of query names sent to authority 190 | # servers and checks if the reply still has the correct casing. 191 | # This feature is an experimental implementation of draft dns-0x20. 192 | # Experimental option. 193 | #use-caps-for-id: yes 194 | 195 | # Help protect users that rely on this validator for authentication from 196 | # potentially bad data in the additional section. Instruct the validator to 197 | # remove data from the additional section of secure messages that are not 198 | # signed properly. Messages that are insecure, bogus, indeterminate or 199 | # unchecked are not affected. 200 | val-clean-additional: yes 201 | 202 | ########################################################################### 203 | # PERFORMANCE SETTINGS 204 | ########################################################################### 205 | # https://nlnetlabs.nl/documentation/unbound/howto-optimise/ 206 | # https://nlnetlabs.nl/news/2019/Feb/05/unbound-1.9.0-released/ 207 | 208 | # Number of slabs in the infrastructure cache. Slabs reduce lock contention 209 | # by threads. Must be set to a power of 2. 210 | # infra-cache-slabs: 4 211 | 212 | # Number of incoming TCP buffers to allocate per thread. Default 213 | # is 10. If set to 0, or if do-tcp is "no", no TCP queries from 214 | # clients are accepted. For larger installations increasing this 215 | # value is a good idea. 216 | # incoming-num-tcp: 10 217 | 218 | # Number of slabs in the key cache. Slabs reduce lock contention by 219 | # threads. Must be set to a power of 2. Setting (close) to the number 220 | # of cpus is a reasonable guess. 221 | # key-cache-slabs: 4 222 | 223 | # Number of bytes size of the message cache. 224 | # Unbound recommendation is to Use roughly twice as much rrset cache memory 225 | # as you use msg cache memory. 226 | msg-cache-size: 260991658 227 | 228 | # Number of slabs in the message cache. Slabs reduce lock contention by 229 | # threads. Must be set to a power of 2. Setting (close) to the number of 230 | # cpus is a reasonable guess. 231 | #msg-cache-slabs: 4 232 | 233 | # The number of queries that every thread will service simultaneously. If 234 | # more queries arrive that need servicing, and no queries can be jostled 235 | # out (see jostle-timeout), then the queries are dropped. 236 | # This is best set at half the number of the outgoing-range. 237 | # This Unbound instance was compiled with libevent so it can efficiently 238 | # use more than 1024 file descriptors. 239 | num-queries-per-thread: 4096 240 | 241 | # The number of threads to create to serve clients. 242 | # This is set dynamically at run time to effectively use available CPUs 243 | # resources 244 | #num-threads: 3 245 | 246 | # Number of ports to open. This number of file descriptors can be opened 247 | # per thread. 248 | # This Unbound instance was compiled with libevent so it can efficiently 249 | # use more than 1024 file descriptors. 250 | outgoing-range: 8192 251 | 252 | # Number of bytes size of the RRset cache. 253 | # Use roughly twice as much rrset cache memory as msg cache memory 254 | rrset-cache-size: 260991658 255 | 256 | # Number of slabs in the RRset cache. Slabs reduce lock contention by 257 | # threads. Must be set to a power of 2. 258 | #rrset-cache-slabs: 4 259 | 260 | # Do no insert authority/additional sections into response messages when 261 | # those sections are not required. This reduces response size 262 | # significantly, and may avoid TCP fallback for some responses. This may 263 | # cause a slight speedup. 264 | minimal-responses: yes 265 | 266 | # # Fetch the DNSKEYs earlier in the validation process, when a DS record 267 | # is encountered. This lowers the latency of requests at the expense of 268 | # little more CPU usage. 269 | prefetch: yes 270 | 271 | # Fetch the DNSKEYs earlier in the validation process, when a DS record is 272 | # encountered. This lowers the latency of requests at the expense of little 273 | # more CPU usage. 274 | prefetch-key: yes 275 | 276 | # Have unbound attempt to serve old responses from cache with a TTL of 0 in 277 | # the response without waiting for the actual resolution to finish. The 278 | # actual resolution answer ends up in the cache later on. 279 | serve-expired: yes 280 | 281 | # Open dedicated listening sockets for incoming queries for each thread and 282 | # try to set the SO_REUSEPORT socket option on each socket. May distribute 283 | # incoming queries to threads more evenly. 284 | so-reuseport: yes 285 | 286 | # Ensure kernel buffer is large enough to not lose messages in traffic spikes 287 | so-rcvbuf: 1m 288 | 289 | ########################################################################### 290 | # LOCAL ZONE 291 | ########################################################################### 292 | 293 | # # Include file for local-data and local-data-ptr 294 | # include: /opt/unbound/etc/unbound/a-records.conf 295 | # include: /opt/unbound/etc/unbound/srv-records.conf 296 | 297 | # ########################################################################### 298 | # # FORWARD ZONE 299 | # ########################################################################### 300 | 301 | # include: /opt/unbound/etc/unbound/forward-records.conf 302 | 303 | # OPTIONAL: 304 | # Forward Secure DNS to upstream provider Cloudflare DNS 305 | 306 | # forward-zone: 307 | # name: "." 308 | # forward-addr: 1.1.1.1@853#cloudflare-dns.com 309 | # forward-addr: 1.0.0.1@853#cloudflare-dns.com 310 | # forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com 311 | # forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com 312 | # forward-tls-upstream: yes 313 | 314 | remote-control: 315 | control-enable: no 316 | 317 | --------------------------------------------------------------------------------