Skip to content

Commit c82bd8c

Browse files
jackivanovdguido
authored andcommitted
DNS-over-HTTPS (trailofbits#875)
1 parent 4bd59be commit c82bd8c

25 files changed

+722
-19
lines changed

algo

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ read -p "
4343
Do you want to install a DNS resolver on this VPN server, to block ads while surfing?
4444
[y/N]: " -r dns_enabled
4545
dns_enabled=${dns_enabled:-n}
46-
if [[ "$dns_enabled" =~ ^(y|Y)$ ]]; then ROLES+=" dns"; fi
46+
if [[ "$dns_enabled" =~ ^(y|Y)$ ]]; then ROLES+=" dns"; EXTRA_VARS+=" local_dns=true"; fi
4747

4848
read -p "
4949
Do you want each user to have their own account for SSH tunneling?

config.cfg

+11-4
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,20 @@ adblock_lists:
2929
- "https://www.malwaredomainlist.com/hostslist/hosts.txt"
3030
- "https://hosts-file.net/ad_servers.txt"
3131

32+
# Enalbe DNS encryption. Use dns_encrypted_provider to specify the provider. If false dns_servers should be specified
33+
dns_encryption: true
34+
35+
# Possible values: google, cloudflare
36+
dns_encryption_provider: cloudflare
37+
38+
# DNS servers which will be used if dns_encryption disabled
3239
dns_servers:
3340
ipv4:
34-
- 8.8.8.8
35-
- 8.8.4.4
41+
- 1.1.1.1
42+
- 1.0.0.1
3643
ipv6:
37-
- 2001:4860:4860::8888
38-
- 2001:4860:4860::8844
44+
- 2606:4700:4700::1111
45+
- 2606:4700:4700::1001
3946

4047
# IP address for the local dns resolver
4148
local_service_ip: 172.16.0.1

deploy.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
tags: always
6464

6565
roles:
66-
- { role: dns_adblocking, tags: ['dns', 'adblock' ] }
66+
- { role: dns_adblocking, tags: [ 'dns', 'adblock' ] }
6767
- { role: ssh_tunneling, tags: [ 'ssh_tunneling' ] }
6868
- { role: vpn, tags: [ 'vpn' ] }
6969

docs/client-linux.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ In this example we'll assume the IP of our Algo VPN server is `1.2.3.4` and the
6464
* Certificate: `cacert.pem` found at `/path/to/algo/configs/1.2.3.4/cacert.pem`
6565
* Client:
6666
* Authentication: *Certificate/Private key*
67-
* Certificate: `user-name.crt` found at `/path/to/algo/configs/1.2.3.4/pki/certs/user-name.crt`
67+
* Certificate: `user-name.crt` found at `/path/to/algo/configs/1.2.3.4/pki/certs/user-name.crt`
6868
* Private key: `user-name.key` found at `/path/to/algo/configs/1.2.3.4/pki/private/user-name.key`
6969
* Options:
7070
* Check *Request an inner IP address*, connection will fail without this option

docs/setup-roles.md

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* **DNS-based Adblocking**
2121
* Install the [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) local resolver with a blacklist for advertising domains
2222
* Constrains dnsmasq with AppArmor and cgroups CPU and memory limitations
23+
* **DNS encryption**
24+
* Install [dnscrypt-proxy](https://github.com/jedisct1/dnscrypt-proxy)
25+
* Constrains dingo with AppArmor and cgroups CPU and memory limitations
2326
* **SSH Tunneling**
2427
* Adds a restricted `algo` group with no shell access and limited SSH forwarding options
2528
* Creates one limited, local account per user and an SSH public key for each

roles/common/tasks/ubuntu.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22
- name: Cloud only tasks
33
block:
44
- name: Install software updates
5-
apt: update_cache=yes upgrade=dist
5+
apt:
6+
update_cache: true
7+
install_recommends: true
8+
upgrade: dist
9+
10+
- name: Upgrade the ca certificates
11+
apt:
12+
name: ca-certificates
13+
state: latest
614

715
- name: Check if reboot is required
816
shell: >

roles/dns_adblocking/meta/main.yml

+3
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22

33
dependencies:
44
- { role: common, tags: common }
5+
- role: dns_encryption
6+
tags: dns_encryption
7+
when: dns_encryption == true

roles/dns_adblocking/tasks/freebsd.yml

+8
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,11 @@
22

33
- name: FreeBSD / HardenedBSD | Enable dnsmasq
44
lineinfile: dest=/etc/rc.conf regexp=^dnsmasq_enable= line='dnsmasq_enable="YES"'
5+
6+
- name: The dnsmasq additional directories created
7+
file:
8+
dest: "{{ item }}"
9+
state: directory
10+
mode: '0755'
11+
with_items:
12+
- "{{ config_prefix|default('/') }}etc/dnsmasq.d"

roles/dns_adblocking/tasks/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
- name: The DNS tag is defined
55
set_fact:
6-
local_dns: Y
6+
local_dns: true
77

88
- name: Dnsmasq installed
99
package: name=dnsmasq

roles/dns_adblocking/tasks/ubuntu.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
owner: root
88
group: root
99
mode: 0600
10-
when: apparmor_enabled is defined and apparmor_enabled == true
10+
when: apparmor_enabled|default(false)|bool == true
1111
notify:
1212
- restart dnsmasq
1313

1414
- name: Ubuntu | Enforce the dnsmasq AppArmor policy
1515
shell: aa-enforce usr.sbin.dnsmasq
16-
when: apparmor_enabled is defined and apparmor_enabled == true
16+
when: apparmor_enabled|default(false)|bool == true
1717
tags: ['apparmor']
1818

1919
- name: Ubuntu | Ensure that the dnsmasq service directory exist

roles/dns_adblocking/templates/dnsmasq.conf.j2

+5-1
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,13 @@ no-resolv
8888
# You can control how dnsmasq talks to a server: this forces
8989
# queries to 10.1.2.3 to be routed via eth1
9090
# server=10.1.2.3@eth1
91+
{% if dns_encryption|default(false)|bool == true %}
92+
server={{ local_service_ip }}#5353
93+
{% else %}
9194
{% for host in dns_servers.ipv4 %}
9295
server={{ host }}
9396
{% endfor %}
97+
{% endif %}
9498

9599
# and this sets the source (ie local) address used to talk to
96100
# 10.1.2.3 to 192.168.1.1 port 55 (there must be a interface with that
@@ -660,7 +664,7 @@ bind-interfaces
660664

661665
# Include another lot of configuration options.
662666
#conf-file=/etc/dnsmasq.more.conf
663-
conf-dir=/etc/dnsmasq.d
667+
conf-dir={{ config_prefix|default('/') }}etc/dnsmasq.d/,*.conf
664668

665669
# Include all the files in a directory except those ending in .bak
666670
#conf-dir=/etc/dnsmasq.d,.bak
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
listen_port: "{% if local_dns|d(false)|bool == true %}5353{% else %}53{% endif %}"
3+
# the version used if the latest unavailable (in case of Github API rate limited)
4+
dnscrypt_proxy_version: 2.0.10
5+
apparmor_enabled: true
6+
dns_encryption: true
7+
dns_encryption_provider: "*"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <tunables/global>
2+
3+
/usr/sbin/dnscrypt-proxy {
4+
#include <abstractions/base>
5+
#include <abstractions/nameservice>
6+
#include <abstractions/openssl>
7+
8+
capability chown,
9+
capability dac_override,
10+
capability net_bind_service,
11+
capability setgid,
12+
capability setuid,
13+
capability sys_resource,
14+
15+
/etc/dnscrypt-proxy.toml r,
16+
/etc/ld.so.cache r,
17+
/usr/sbin/dnscrypt-proxy mr,
18+
/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv r,
19+
/usr/local/lib/{@{multiarch}/,}libldns.so* mr,
20+
/usr/local/lib/{@{multiarch}/,}libsodium.so* mr,
21+
/run/dnscrypt-proxy.pid rw,
22+
/run/systemd/notify rw,
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/sh
2+
3+
# PROVIDE: dnscrypt-proxy
4+
# REQUIRE: LOGIN
5+
# BEFORE: securelevel
6+
# KEYWORD: shutdown
7+
8+
# Add the following lines to /etc/rc.conf to enable `dnscrypt-proxy':
9+
#
10+
# dnscrypt_proxy_enable="YES"
11+
# dnscrypt_proxy_flags="<set as needed>"
12+
#
13+
# See rsync(1) for rsyncd_flags
14+
#
15+
16+
. /etc/rc.subr
17+
18+
name="dnscrypt-proxy"
19+
rcvar=dnscrypt_proxy_enable
20+
load_rc_config "$name"
21+
pidfile="/var/run/$name.pid"
22+
start_cmd=dnscrypt_proxy_start
23+
stop_postcmd=dnscrypt_proxy_stop
24+
25+
: ${dnscrypt_proxy_enable="NO"}
26+
: ${dnscrypt_proxy_flags="-config /usr/local/etc/dnscrypt-proxy/dnscrypt-proxy.toml"}
27+
28+
dnscrypt_proxy_start() {
29+
echo "Starting dnscrypt-proxy..."
30+
touch ${pidfile}
31+
/usr/sbin/daemon -cS -T dnscrypt-proxy -p ${pidfile} /usr/dnscrypt-proxy/freebsd-amd64/dnscrypt-proxy ${dnscrypt_proxy_flags}
32+
}
33+
34+
dnscrypt_proxy_stop() {
35+
[ -f ${pidfile} ] && rm ${pidfile}
36+
}
37+
38+
run_rc_command "$1"
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
- name: daemon reload
3+
systemd:
4+
daemon_reload: true
5+
6+
- name: restart dnscrypt-proxy
7+
service:
8+
name: dnscrypt-proxy
9+
state: restarted

roles/dns_encryption/meta/main.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
dependencies:
3+
- role: common
4+
tags: common
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
- name: FreeBSD | Ensure that the required directories exist
3+
file:
4+
path: "{{ item }}"
5+
state: directory
6+
with_items:
7+
- "{{ config_prefix|default('/') }}etc/dnscrypt-proxy/"
8+
- /usr/dnscrypt-proxy/
9+
10+
- name: Required tools installed
11+
package:
12+
name: gtar
13+
14+
- name: FreeBSD | Retrive the latest versions
15+
uri:
16+
url: https://api.github.com/repos/jedisct1/dnscrypt-proxy/releases/latest
17+
register: dnscrypt_proxy_latest
18+
ignore_errors: true
19+
20+
- name: FreeBSD | Set default dnscrypt-proxy assets
21+
set_fact:
22+
dnscrypt_proxy_latest:
23+
json:
24+
assets:
25+
- name: "dnscrypt-proxy-freebsd_amd64-{{ dnscrypt_proxy_version }}.tar.gz"
26+
browser_download_url: "https://github.com/jedisct1/dnscrypt-proxy/releases/download/{{ dnscrypt_proxy_version }}/dnscrypt-proxy-freebsd_amd64-{{ dnscrypt_proxy_version }}.tar.gz"
27+
when: dnscrypt_proxy_latest.failed
28+
29+
- name: FreeBSD | Download the latest archive
30+
get_url:
31+
url: "{{ item['browser_download_url'] }}"
32+
dest: "/tmp/dnscrypt-proxy-freebsd_amd64-{{ dnscrypt_proxy_version }}.tar.gz"
33+
mode: '0755'
34+
force: true
35+
with_items: "{{ dnscrypt_proxy_latest['json']['assets'] }}"
36+
no_log: true
37+
when: '"freebsd_amd64" in item.name'
38+
notify: restart dnscrypt-proxy
39+
40+
- name: FreeBSD | Extract the latest archive
41+
unarchive:
42+
remote_src: true
43+
src: /tmp/dnscrypt-proxy-freebsd_amd64-{{ dnscrypt_proxy_version }}.tar.gz
44+
dest: /usr/dnscrypt-proxy
45+
46+
- name: FreeBSD | Configure rc script
47+
copy:
48+
src: rc.dnscrypt-proxy.sh
49+
dest: /usr/local/etc/rc.d/dnscrypt-proxy
50+
mode: "0755"
51+
notify: restart dnscrypt-proxy

roles/dns_encryption/tasks/main.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
- name: Include tasks for Ubuntu
3+
include_tasks: ubuntu.yml
4+
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
5+
6+
- name: Include tasks for FreeBSD
7+
include_tasks: freebsd.yml
8+
when: ansible_distribution == 'FreeBSD'
9+
10+
- name: dnscrypt-proxy configured
11+
template:
12+
src: dnscrypt-proxy.toml.j2
13+
dest: "{{ config_prefix|default('/') }}etc/dnscrypt-proxy/dnscrypt-proxy.toml"
14+
notify:
15+
- restart dnscrypt-proxy
16+
17+
- name: dnscrypt-proxy enabled and started
18+
service:
19+
name: dnscrypt-proxy
20+
state: started
21+
enabled: true
22+
23+
- meta: flush_handlers

roles/dns_encryption/tasks/ubuntu.yml

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
- name: Add the repository
3+
apt_repository:
4+
state: present
5+
codename: artful
6+
repo: ppa:shevchuk/dnscrypt-proxy
7+
8+
- name: Install dnscrypt-proxy
9+
apt:
10+
name: dnscrypt-proxy
11+
state: latest
12+
update_cache: true
13+
14+
- block:
15+
- name: Ubuntu | Unbound profile for apparmor configured
16+
copy:
17+
src: apparmor.profile.dnscrypt-proxy
18+
dest: /etc/apparmor.d/usr.sbin.dnscrypt-proxy
19+
owner: root
20+
group: root
21+
mode: 0600
22+
notify: restart dnscrypt-proxy
23+
24+
- name: Ubuntu | Enforce the dnscrypt-proxy AppArmor policy
25+
command: aa-enforce usr.sbin.dnscrypt-proxy
26+
changed_when: false
27+
tags: apparmor
28+
when: apparmor_enabled|default(false)|bool == true
29+
30+
- name: Ubuntu | Ensure that the dnscrypt-proxy service directory exist
31+
file:
32+
path: /etc/systemd/system/dnscrypt-proxy.service.d/
33+
state: directory
34+
mode: 0755
35+
owner: root
36+
group: root
37+
38+
- name: Ubuntu | Setup the cgroup limitations for dnscrypt-proxy
39+
copy:
40+
dest: /etc/systemd/system/dnscrypt-proxy.service.d/100-CustomLimitations.conf
41+
content: |
42+
[Service]
43+
MemoryLimit=16777216
44+
CPUAccounting=true
45+
CPUQuota=5%
46+
notify:
47+
- daemon-reload
48+
- restart dnscrypt-proxy

0 commit comments

Comments
 (0)