mirror of https://gitlab.com/curben/blog
post(nixos): update stubby to 22.05 syntax
https://nixos.org/manual/nixos/stable/release-notes.html#sec-release-22.05
This commit is contained in:
parent
6ae6c9dacc
commit
0cb811a549
|
@ -2,7 +2,7 @@
|
||||||
title: "Setup Caddy as a reverse proxy on NixOS (Part 2: Hardening)"
|
title: "Setup Caddy as a reverse proxy on NixOS (Part 2: Hardening)"
|
||||||
excerpt: "Part 2: Securing NixOS"
|
excerpt: "Part 2: Securing NixOS"
|
||||||
date: 2020-03-04
|
date: 2020-03-04
|
||||||
updated: 2020-11-09
|
updated: 2022-07-06
|
||||||
tags:
|
tags:
|
||||||
- server
|
- server
|
||||||
- linux
|
- linux
|
||||||
|
@ -11,7 +11,7 @@ tags:
|
||||||
series: true
|
series: true
|
||||||
---
|
---
|
||||||
|
|
||||||
> 9 Nov 2020: Updated to NixOS 20.09 syntax.
|
> 6 Jul 2022: Updated to NixOS 22.05 syntax.
|
||||||
|
|
||||||
In this post, I show you how I securely configure the NixOS, the server OS behind this website.
|
In this post, I show you how I securely configure the NixOS, the server OS behind this website.
|
||||||
|
|
||||||
|
@ -96,23 +96,27 @@ Combining with the previous user configs, I ended up with:
|
||||||
hashedPassword = "*";
|
hashedPassword = "*";
|
||||||
};
|
};
|
||||||
nixos = {
|
nixos = {
|
||||||
|
group = "nixos";
|
||||||
hashedPassword = "xxxx";
|
hashedPassword = "xxxx";
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
};
|
};
|
||||||
caddyProxy = {
|
caddyProxy = {
|
||||||
|
group = "caddyProxy";
|
||||||
home = "/var/lib/caddyProxy";
|
home = "/var/lib/caddyProxy";
|
||||||
createHome = true;
|
createHome = true;
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = "caddyProxy";
|
group = "caddyProxy";
|
||||||
};
|
};
|
||||||
caddyTor = {
|
caddyTor = {
|
||||||
|
group = "caddyTor";
|
||||||
home = "/var/lib/caddyTor";
|
home = "/var/lib/caddyTor";
|
||||||
createHome = true;
|
createHome = true;
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = "caddyTor";
|
group = "caddyTor";
|
||||||
};
|
};
|
||||||
tor = {
|
tor = {
|
||||||
|
group = "tor";
|
||||||
home = "/var/lib/tor";
|
home = "/var/lib/tor";
|
||||||
createHome = true;
|
createHome = true;
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
|
@ -122,15 +126,10 @@ Combining with the previous user configs, I ended up with:
|
||||||
};
|
};
|
||||||
|
|
||||||
groups = {
|
groups = {
|
||||||
caddyProxy = {
|
nixos = {};
|
||||||
members = [ "caddyProxy" ];
|
caddyProxy = {};
|
||||||
};
|
caddyTor = {};
|
||||||
caddyTor = {
|
tor = {};
|
||||||
members = [ "caddyTor" ];
|
|
||||||
};
|
|
||||||
tor = {
|
|
||||||
gid = config.ids.gids.tor;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
@ -166,42 +165,74 @@ Once the secret is generated, TOTP can be enabled using the following config. I
|
||||||
|
|
||||||
Since DNS is not encrypted in transit, it risks being tampered. To resolve that, I use DNS-over-TLS which as the name implies, uses TLS to encrypt the DNS traffic. I use `stubby` which creates a DNS resolver that listens on localhost and forward DNS query to the upstream server(s) using DoT. `stubby` enables DNSSEC by default to verify authenticity of the DNS response for supported domains. (This domain mdleom.com has DNSSEC enabled through a DS record)
|
Since DNS is not encrypted in transit, it risks being tampered. To resolve that, I use DNS-over-TLS which as the name implies, uses TLS to encrypt the DNS traffic. I use `stubby` which creates a DNS resolver that listens on localhost and forward DNS query to the upstream server(s) using DoT. `stubby` enables DNSSEC by default to verify authenticity of the DNS response for supported domains. (This domain mdleom.com has DNSSEC enabled through a DS record)
|
||||||
|
|
||||||
I use Cloudflare DNS simply because I'm already using its CDN, using other alternatives wouldn't have the privacy benefit since it already knows that a visitor is browsing this website. I add [Quad9](https://quad9.net/) as a backup. Refer to [stubby.yml](https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example) for a full list of supported servers.
|
I use Cloudflare DNS (simply because I'm already using its CDN) and [Quad9](https://quad9.net/) as backup. Refer to [stubby.yml](https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example) for a full list of supported servers. For Cloudflare DNS, I opt for the malware-blocking flavour, refer to the following IPs if you prefer the default flavour.
|
||||||
|
|
||||||
|
```
|
||||||
|
Source: https://developers.cloudflare.com/1.1.1.1/setup/
|
||||||
|
# No malware blocking
|
||||||
|
1.1.1.1
|
||||||
|
1.0.0.1
|
||||||
|
2606:4700:4700::1111
|
||||||
|
2606:4700:4700::1001
|
||||||
|
|
||||||
|
# Malware blocking
|
||||||
|
1.1.1.2
|
||||||
|
1.0.0.2
|
||||||
|
2606:4700:4700::1112
|
||||||
|
2606:4700:4700::1002
|
||||||
|
```
|
||||||
|
|
||||||
``` nix
|
``` nix
|
||||||
## DNS-over-TLS
|
## DNS-over-TLS
|
||||||
services.stubby = {
|
services.stubby = {
|
||||||
enable = true;
|
enable = true;
|
||||||
listenAddresses = [ "0::1" "127.0.0.1" ];
|
settings = {
|
||||||
roundRobinUpstreams = false;
|
# ::1 cause error, use 0::1 instead
|
||||||
upstreamServers =
|
listen_addresses = [ "127.0.0.1" "0::1" ];
|
||||||
''
|
# https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example
|
||||||
## Cloudflare DNS
|
resolution_type = "GETDNS_RESOLUTION_STUB";
|
||||||
- address_data: 2606:4700:4700::1112
|
dns_transport_list = [ "GETDNS_TRANSPORT_TLS" ];
|
||||||
tls_auth_name: "cloudflare-dns.com"
|
tls_authentication = "GETDNS_AUTHENTICATION_REQUIRED";
|
||||||
- address_data: 2606:4700:4700::1002
|
tls_query_padding_blocksize = 128;
|
||||||
tls_auth_name: "cloudflare-dns.com"
|
idle_timeout = 10000;
|
||||||
- address_data: 1.1.1.2
|
round_robin_upstreams = 1;
|
||||||
tls_auth_name: "cloudflare-dns.com"
|
tls_min_version = "GETDNS_TLS1_3";
|
||||||
- address_data: 1.0.0.2
|
dnssec = "GETDNS_EXTENSION_TRUE";
|
||||||
tls_auth_name: "cloudflare-dns.com"
|
upstream_recursive_servers = [
|
||||||
## Quad9
|
{
|
||||||
- address_data: 2620:fe::fe
|
address_data = "1.1.1.2";
|
||||||
tls_auth_name: "dns.quad9.net"
|
tls_auth_name = "cloudflare-dns.com";
|
||||||
- address_data: 2620:fe::9
|
}
|
||||||
tls_auth_name: "dns.quad9.net"
|
{
|
||||||
- address_data: 9.9.9.9
|
address_data = "1.0.0.2";
|
||||||
tls_auth_name: "dns.quad9.net"
|
tls_auth_name = "cloudflare-dns.com";
|
||||||
- address_data: 149.112.112.112
|
}
|
||||||
tls_auth_name: "dns.quad9.net"
|
{
|
||||||
'';
|
address_data = "2606:4700:4700::1112";
|
||||||
extraConfig =
|
tls_auth_name = "cloudflare-dns.com";
|
||||||
''
|
}
|
||||||
# Set TLS 1.3 as minimum acceptable version
|
{
|
||||||
tls_min_version: GETDNS_TLS1_3
|
address_data = "2606:4700:4700::1002";
|
||||||
# Require DNSSEC validation
|
tls_auth_name = "cloudflare-dns.com";
|
||||||
dnssec: GETDNS_EXTENSION_TRUE
|
}
|
||||||
'';
|
{
|
||||||
|
address_data = "9.9.9.9";
|
||||||
|
tls_auth_name = "dns.quad9.net";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "149.112.112.112";
|
||||||
|
tls_auth_name = "dns.quad9.net";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "2620:fe::fe";
|
||||||
|
tls_auth_name = "dns.quad9.net";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "2620:fe::9";
|
||||||
|
tls_auth_name = "dns.quad9.net";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -477,21 +508,52 @@ Since [unattended upgrade](#Unattended-upgrade) is executed on 00:00, I delay ga
|
||||||
## DNS-over-TLS
|
## DNS-over-TLS
|
||||||
services.stubby = {
|
services.stubby = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# ::1 cause error, use 0::1 instead
|
settings = {
|
||||||
listenAddresses = [ "0::1" "127.0.0.1" ];
|
listen_addresses = [ "127.0.0.1" "0::1" ];
|
||||||
roundRobinUpstreams = false;
|
# https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example
|
||||||
upstreamServers =
|
resolution_type = "GETDNS_RESOLUTION_STUB";
|
||||||
''
|
dns_transport_list = [ "GETDNS_TRANSPORT_TLS" ];
|
||||||
## Cloudflare DNS
|
tls_authentication = "GETDNS_AUTHENTICATION_REQUIRED";
|
||||||
- address_data: 2606:4700:4700::1111
|
tls_query_padding_blocksize = 128;
|
||||||
tls_auth_name: "cloudflare-dns.com"
|
idle_timeout = 10000;
|
||||||
- address_data: 2606:4700:4700::1001
|
round_robin_upstreams = 1;
|
||||||
tls_auth_name: "cloudflare-dns.com"
|
tls_min_version = "GETDNS_TLS1_3";
|
||||||
- address_data: 1.1.1.1
|
dnssec = "GETDNS_EXTENSION_TRUE";
|
||||||
tls_auth_name: "cloudflare-dns.com"
|
upstream_recursive_servers = [
|
||||||
- address_data: 1.0.0.1
|
{
|
||||||
tls_auth_name: "cloudflare-dns.com"
|
address_data = "1.1.1.2";
|
||||||
'';
|
tls_auth_name = "cloudflare-dns.com";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "1.0.0.2";
|
||||||
|
tls_auth_name = "cloudflare-dns.com";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "2606:4700:4700::1112";
|
||||||
|
tls_auth_name = "cloudflare-dns.com";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "2606:4700:4700::1002";
|
||||||
|
tls_auth_name = "cloudflare-dns.com";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "9.9.9.9";
|
||||||
|
tls_auth_name = "dns.quad9.net";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "149.112.112.112";
|
||||||
|
tls_auth_name = "dns.quad9.net";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "2620:fe::fe";
|
||||||
|
tls_auth_name = "dns.quad9.net";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
address_data = "2620:fe::9";
|
||||||
|
tls_auth_name = "dns.quad9.net";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.nameservers = [ "::1" "127.0.0.1" ];
|
networking.nameservers = [ "::1" "127.0.0.1" ];
|
||||||
|
@ -566,7 +628,11 @@ Since [unattended upgrade](#Unattended-upgrade) is executed on 00:00, I delay ga
|
||||||
|
|
||||||
### The rest will be explained in the next articles
|
### The rest will be explained in the next articles
|
||||||
## Caddy web server
|
## Caddy web server
|
||||||
require = [ /etc/caddy/caddyProxy.nix /etc/caddy/caddyTor.nix /etc/caddy/caddyI2p.nix ];
|
require = [
|
||||||
|
/etc/caddy/caddyProxy.nix
|
||||||
|
/etc/caddy/caddyTor.nix
|
||||||
|
/etc/caddy/caddyI2p.nix
|
||||||
|
];
|
||||||
services.caddyProxy = {
|
services.caddyProxy = {
|
||||||
enable = false;
|
enable = false;
|
||||||
config = "/etc/caddy/caddyProxy.conf";
|
config = "/etc/caddy/caddyProxy.conf";
|
||||||
|
|
Loading…
Reference in New Issue