• Stars
    star
    142
  • Rank 258,495 (Top 6 %)
  • Language
    C
  • License
    GNU Lesser Genera...
  • Created over 6 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A DNS over HTTPS resolver for glibc
                     _   _
 _ __  ___ ___      | |_| |___
| '_ \/ __/ __|_____| __| / __|
| | | \__ \__ \_____| |_| \__ \
|_| |_|___/___/      \__|_|___/

Build Status

Motivation

Unlike most web browser traffic, which is encrypted thanks to HTTPS, the resolving of domain names to internet addresses still happens through DNS, an old, unencrypted protocol. This benefits analytics companies, advertisers, internet providers and attackers, but not the end-user, who seeks online privacy and security.

Overview

nss-tls is an alternative, encrypted name resolving library for Linux distributions with glibc, which uses DNS-over-HTTPS (DoH).

The glibc name resolver can be configured through nsswitch.conf(5) to use nss-tls instead of the DNS resolver, or fall back to DNS when nss-tls fails.

This way, all applications that use the standard resolver API (getaddrinfo(), gethostbyname(), etc'), are transparently migrated from DNS to encrypted means of name resolving, with zero application-side changes and minimal resource consumption footprint. However, nss-tls does not deal with applications that use their own, built-in DNS resolver.

Architecture

nss-tls consists of three parts:

  • nss-tlsd runs in the background, receives name resolving requests over a Unix socket and replies with resolved addresses.
  • libnss_tls.so is a tiny client library, which delegates the resolving work to nss-tlsd through the Unix socket and passes the results back to the application, without dependencies other than libc. This way, applications that resolve through nss-tls are not affected by the complexity and resource consumption of runtime libraries (e.g. libstdc++) and dependency libraries used by nss-tlsd, or the constraints they impose on applications that load them (like signal or thread safety issues).
  • tlslookup is equivalent to nslookup(1), but uses libnss_tls.so instead of DNS.

Security and Privacy

An unprivileged user can start a private, unprivileged instance of nss-tlsd and libnss-tls.so will automatically use that one, instead of the system-wide instance of nss-tlsd. Each user's nss-tlsd instance holds its own cache of lookup results, to speed up resolving. Because the cache is not shared with other users, it remains "hot" even if other users resolve many names.

Users who don't have such a private instance will continue to use the system-wide instance. which does not perform caching by default, to prevent a user from extracting the browsing history of another user, using timing-based methods. In addition, nss-tlsd drops its privileges to greatly reduce its attack surface.

Also, nss-tlsd is capable of using multiple DoH servers, with a deterministic algorithm that chooses which server to use to resolve a domain. This way, no DoH server can track the user's entire browsing history.

To avoid bloat, duplicate effort and potential remotely-exploitable vulnerabilities, nss-tlsd uses the libc API for building DNS queries and parsing responses, instead of implementing its own parser.

Dependencies

nss-tls depends on:

If systemd is present, the installation of nss-tls includes unit files for nss-tlsd, and nss-tlsd may co-exist with systemd-resolved.

However, nss-tls does not depend on systemd. When systemd is not present, other means of running a nss-tlsd instance for each user (e.g. xinitrc) and root (e.g. an init script) should be used.

nss-tls uses Meson as its build system.

On Debian and derivatives, these dependencies can be obtained using:

apt install libglib2.0-dev libsoup2.4-dev ninja-build python3-pip
pip3 install meson

Usage

Assuming your system runs systemd:

meson --prefix=/usr --buildtype=release -Dstrip=true build
ninja -C build install
systemctl daemon-reload
systemctl enable nss-tlsd
systemctl start nss-tlsd
systemctl --user --global enable nss-tlsd
systemctl --user start nss-tlsd
ldconfig

Then, add "tls" to the "hosts" entry in /etc/nsswitch.conf, before "resolve", "dns" or anything else that contains "dns".

This will enable a system nss-tlsd instance for all non-interactive processes (which runs as an unprivileged user) and a private instance of nss-tlsd for each user. Name resolving will happen through nss-tls and DNS will be attempted only if nss-tls fails.

Choosing a DoH Server

By default, nss-tls uses the DNS servers specified in /etc/resolv.conf, assuming they support DoH.

To use a different DoH server, change the "resolvers" key of nss-tls.conf:

[global]
resolvers=https://9.9.9.9/dns-query

nss-tlsd looks for nss-tls.conf in user's home directory (only when running as an unprivileged user; usually under .config) and the system configuration file directory (usually /etc). If both files exist, nss-tlsd prefers the user's one.

nss-tlsd monitors the chosen configuration file and /etc/resolv.conf for changes and deletion, so changes are applied without having to restart nss-tlsd.

If /etc/resolv.conf is a symlink and specifies a stub DNS resolver, because of systemd-resolved, nss-tlsd tries to guess where the real resolv.conf is (usually /run/systemd/resolve/resolv.conf).

If the "resolvers" key is missing or empty, nss-tlsd falls back to using the DNS servers specified in /etc/resolv.conf.

To change the server selection in the default configuration file created at build time, use the "resolvers" build option:

meson configure -Dresolvers=cloudflare-dns.com/dns-query

Using Multiple DoH Servers

It is also possible to use multiple DoH servers:

[global]
resolvers=https://dns9.quad9.net/dns-query,https://cloudflare-dns.com/dns-query

When nss-tls is configured like this, it pseudo-randomly chooses one of the servers, for each name lookup. The choice of the server is consistent: if the same domain is resolved twice (e.g. for its IPv4 and IPv6 addresses, respectively), nss-tlsd will use the same DoH server for both queries. If nss-tlsd is restarted, it will keep using the same DoH server to resolve that domain. This contributes to privacy, since every DoH server sees only a portion of the user's browsing history.

Choosing the HTTP Method

A standard DoH server should support both GET and POST requests. By default, nss-tlsd sends POST requests, beause they are faster to craft and tend to be smaller.

However, one might wish to use GET requests if this makes a specific DoH server respond faster (for example, if the server does not cache responses to POST requests). This can be done by adding "+get" after the server URL:

[global]
resolvers=https://dns.google/dns-query+get

DoH Without Fallback to DNS

If the DoH servers used by nss-tls are specified using their domain names, nss-tls needs a way to resolve the address of each DoH server and it cannot resolve it through itself.

To build nss-tls without dependency on other resolving methods (like DNS), specify the DoH servers using their addresses, e.g.:

[global]
resolvers=https://9.9.9.9/dns-query,https://1.1.1.1/dns-query

Alternatively, the DoH server addresses can be hardcoded using /etc/hosts, e.g:

echo "8.8.8.8 dns.google" >> /etc/hosts

Then, the DoH server can be specified by its domain name:

[global]
resolvers=https://dns.google/dns-query

To disable DNS and use nss-tls exclusively, remove all DNS resolvers from the "hosts" entry in /etc/nsswitch.conf (but keep "tls").

Performance

On paper, DNS over HTTPS is much slower than DNS, due to the overhead of TCP and TLS.

Therefore, each nss-tls instance keeps established HTTPS connections open and reuses them. Also, if running with the -c option, each user's nss-tls instance maintains an internal cache of lookup results. In this cache, IPv4 and IPv6 addresses are stored in separate hash tables, to make the cache faster to iterate over.

Therefore, in reality, DNS over HTTPS using nss-tls may be much faster than DNS.

One may wish to use a system-wide cache that also covers DNS, instead of the internal cache of nss-tls; nscd(8) can do that. To enable system-wide cache on Debian and derivatives:

apt install unscd

Then, set "enable-cache" for "hosts" to "yes" in /etc/nscd.conf. Then:

systemctl enable unscd
systemctl start unscd

Legal Information

nss-tls is free and unencumbered software released under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version license.

nss-tls is not affiliated with Quad9, Cloudflare or Google.

The ASCII art logo at the top was made using FIGlet.

More Repositories

1

szl

A lightweight, embeddable scripting language
C
147
star
2

loksh

A Linux port of OpenBSD's ksh
C
116
star
3

tootik

A federated nanoblogging service with a Gemini frontend.
Go
98
star
4

rlsd

A lightweight, retro Linux-libre distro
Shell
72
star
5

shus

A tiny HTTP server for static sites
C
71
star
6

tty8

A suckless terminal multiplexer
C
41
star
7

papaw

A simple, decompressing executable packer
C
39
star
8

rlsd2

A minimalistic GNU/Linux-libre distro
Shell
37
star
9

LoginKit

A standalone logind shim - GitHub mirror
C
32
star
10

luufs

Lazy man's, user-mode union file system
C
30
star
11

pylzfse

Python bindings for LZFSE
C
29
star
12

libwaive

A library that allows processes to waive their rights
C
27
star
13

lazy-utils

A collection of tiny, permissively-licensed Linux system tools; deprecated in favor of sdaemons
C
25
star
14

dohli

Set up your own ad-blocking DoH server
Go
21
star
15

sdaemons

Suckless daemons
C
19
star
16

codile

A web-based IDE
TypeScript
19
star
17

nosystem

A libsystemd stub library, a research project for Devuan
C
18
star
18

packlim

A small, hackable and secure package manager
C
16
star
19

overheadfs

A FUSE proxy file system
C
16
star
20

b6b

A lightweight, embeddable scripting language
C
15
star
21

toolchains

Toolchains for ultra-portable static binaries
Shell
14
star
22

devsus

Libre Devuan for the Asus C201
Shell
14
star
23

fbim

A tiny framebuffer image viewer
C
13
star
24

lok

A Linux port of OpenBSD's awk
C
11
star
25

guppy-protocol

Unencrypted, UDP-based alternative to the Gemini protocol
Python
10
star
26

elfence

An overlay that verifies signed ELF binaries
C
9
star
27

roar-ng

Generic build system for GNU/Linux distributions; orphaned
Shell
8
star
28

nss-block

A transparent, domain-based ad blocker
C
7
star
29

dillo

Dillo 0.8.6, patched and working
C
6
star
30

packdude

A simple package manager that does the right thing and that's it; orphaned in favor of packlad
C
6
star
31

roar-ng-ii

A generic and extensible build system for GNU/Linux distributions; orphaned
Shell
5
star
32

locwm

A Linux port of OpenBSD's cwm
C
5
star
33

lolibc

An OpenBSD libc compatibility layer as a Meson subproject
C
4
star
34

boydemdb

Key-value database as a Meson subproject
C
4
star
35

krisa

A small library that generates crash dumps
C
4
star
36

literocks

A stripped-down fork of ROX-Filer; orphaned
C
4
star
37

nopdev

A device manager that does less
C
4
star
38

lobsder

An OpenBSD compatibility layer for Linux; orphaned
C
4
star
39

ogg122

A tiny Ogg Vorbis player
C
4
star
40

logfence

An overlay that prevents log tampering
C
4
star
41

packlad

A small, efficient and secure package manager; orphaned in favor of packlim
C
3
star
42

termolos

A console color scheme generator
C
3
star
43

darls

Dima's Already Riced Live System
3
star
44

ted

Ted 2.17, patched and working
C
3
star
45

subito

A minimalistic and versatile GNU/Linux distribution based on roar-ng; orphaned
Shell
3
star
46

frost

A simple suspend tool for GNU/Linux; orphaned
C
3
star
47

libretee

A fast, asynchronous implementation of tee(1); orphaned
C
3
star
48

frugalify

Converts a Puppy Linux "full installation" into a "frugal installation"
C
3
star
49

containers

Containers for C/Go development and CI
Slim
2
star
50

logoutd

An experimental, standalone fork of logind
C
2
star
51

2d-grey-rounded

Flat and minimalistic GTK+ theme
CSS
2
star
52

xplayargs

A xargs-like audio player
C
2
star
53

wpa_supplicant

Working copy of wpa_supplicant
C
2
star
54

packsiz

A tiny, hackable and secure package manager
Meson
2
star
55

emelfm

A lighter emelFM 0.9.2
C
2
star
56

xchat

X-Chat 1.8.9, patched and working
C
2
star
57

tinyunmute

A tinyalsa-based volume initialization tool
C
2
star
58

glib

GLib 1.2.10, patched and working
C
2
star
59

xz-embedded

A copy of upstream xz-embedded that allows shallow clones
C
1
star
60

cdaemon

Node.js addon that wraps the daemon() C function
C++
1
star
61

woof-CE-c201

Puppy Linux + Devsus = ?
Shell
1
star
62

code-oss-arm64

Dockerfile
1
star
63

go-papaw

Go module for papaw
C
1
star
64

honeybear

Dropbear 0.66, hacked to act as a poor man's honeypot
C
1
star
65

gdk-pixbuf

gdk-pixbuf 0.22.0, patched and working
C
1
star
66

beaver

Beaver 0.2.7, patched and working
C
1
star
67

packlim-recipes

Build system for packlim packages
Shell
1
star
68

ncsplash

A simple ncurses-based splash screen which reads strings from a FIFO and prints them to the screen, one at a time; orphaned
C
1
star
69

packlim-sd

A Linux-libre distro based on packlim and packlim-recipes
Shell
1
star
70

locwm-5.6

A Linux port of OpenBSD's cwm
C
1
star
71

part-hotplug-handler

A lightweight, udev-based, partition hotplugging notifier; orphaned
C
1
star
72

rox

ROX-Filer 1.2.2, patched and working
C
1
star
73

sazache

A tiny, scalable HTTP server for static sites
Makefile
1
star
74

gtk

GTK+ 1.2.10, patched and working
C
1
star