@ -8,8 +8,13 @@
* running a recursive DNS resolver on a machine in the network awaiting input from clients over TCP/53 & UDP/53
* running a recursive DNS resolver on a machine in the network awaiting input from clients over TCP/853 ( DoT )
In the below test setup we are trying to implement all of those use cases
without creating a bazillion machines .
In the below test setup we are trying to implement all of those use cases .
Another aspect that we cover is access to the local control UNIX socket . It
can optionally be enabled and users can optionally be in a group to gain
access . Users that are not in the group ( except for root ) should not have
access to that socket . Also , when there is no socket configured , users
shouldn't be able to access the control socket at all . Not even root .
* /
import ./make-test-python.nix ( { pkgs , lib , . . . }:
let
@ -96,7 +101,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
} ;
# machine that runs a local unbound that will be reconfigured during test execution
local_resolver = { lib , nodes , . . . }: {
local_resolver = { lib , nodes , config , . . . }: {
imports = [ common ] ;
networking . interfaces . eth1 . ipv4 . addresses = lib . mkForce [
{ address = " 1 9 2 . 1 6 8 . 0 . 3 " ; prefixLength = 24 ; }
@ -113,11 +118,22 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
enable = true ;
allowedAccess = [ " : : 1 " " 1 2 7 . 0 . 0 . 0 / 8 " ] ;
interfaces = [ " : : 1 " " 1 2 7 . 0 . 0 . 1 " ] ;
localControlSocketPath = " / r u n / u n b o u n d / u n b o u n d . c t l " ;
extraConfig = ''
include : " / e t c / u n b o u n d / e x t r a * . c o n f "
'' ;
} ;
users . users = {
# user that is permitted to access the unix socket
someuser . extraGroups = [
config . users . users . unbound . group
] ;
# user that is not permitted to access the unix socket
unauthorizeduser = { } ;
} ;
environment . etc = {
" u n b o u n d - e x t r a 1 . c o n f " . text = ''
forward-zone :
@ -132,12 +148,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
something . local . IN A 3 .4 .5 .6
'' }
'' ;
" u n b o u n d - e x t r a 3 . c o n f " . text = ''
remote-control :
control-enable : yes
control-interface : /run/unbound/unbound.ctl
'' ;
} ;
} ;
@ -218,6 +228,10 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
resolver . wait_for_unit ( " u n b o u n d . s e r v i c e " )
with subtest ( " r o o t i s u n a b l e t o u s e u n b o u n c - c o n t r o l w h e n t h e s o c k e t i s n o t c o n f i g u r e d " ) :
resolver . succeed ( " w h i c h u n b o u n d - c o n t r o l " ) # the binary must exist
resolver . fail ( " u n b o u n d - c o n t r o l l i s t _ f o r w a r d s " ) # the invocation must fail
# verify that the resolver is able to resolve on all the local protocols
with subtest ( " t e s t t h a t t h e r e s o l v e r r e s o l v e s o n a l l p r o t o c o l s a n d t r a n s p o r t s " ) :
test ( resolver , [ " : : 1 " , " 1 2 7 . 0 . 0 . 1 " ] , doh = True )
@ -241,18 +255,24 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
print ( local_resolver . succeed ( " j o u r n a l c t l - u u n b o u n d - n 1 0 0 0 " ) )
test ( local_resolver , [ " : : 1 " , " 1 2 7 . 0 . 0 . 1 " ] , args = [ " + t i m e o u t = 6 0 " ] )
with subtest ( " t e s t t h a t w e c a n u s e t h e u n b o u n d c o n t r o l s o c k e t " ) :
out = local_resolver . succeed (
" s u d o - u s o m e u s e r - - u n b o u n d - c o n t r o l l i s t _ f o r w a r d s "
) . strip ( )
# Thank you black! Can't really break this line into a readable version.
expected = " e x a m p l e . l o c a l . I N f o r w a r d ${ ( lib . head nodes . resolver . config . networking . interfaces . eth1 . ipv6 . addresses ) . address } ${ ( lib . head nodes . resolver . config . networking . interfaces . eth1 . ipv4 . addresses ) . address } "
assert out == expected , f " E x p e c t e d ` { e x p e c t e d } ` b u t g o t ` { o u t } ` i n s t e a d . "
local_resolver . fail ( " s u d o - u u n a u t h o r i z e d u s e r - - u n b o u n d - c o n t r o l l i s t _ f o r w a r d s " )
# link a new config file to /etc/unbound/extra.conf
local_resolver . succeed ( " l n - s f / e t c / u n b o u n d - e x t r a 2 . c o n f / e t c / u n b o u n d / e x t r a 2 . c o n f " )
# reload the server & ensure the new local zone works
with subtest ( " t e s t t h a t w e c a n q u e r y t h e n e w l o c a l z o n e " ) :
local_resolver . succeed ( " s y s t e m c t l r e l o a d u n b o u n d " )
local_resolver . succeed ( " u n b o u n d - c o n t r o l r e l o a d " )
r = [ ( " A " , " 3 . 4 . 5 . 6 " ) ]
test ( local_resolver , [ " : : 1 " , " 1 2 7 . 0 . 0 . 1 " ] , zone = " s o m e t h i n g . l o c a l . " , records = r )
with subtest ( " t e s t t h a t w e c a n e n a b l e u n b o u n d c o n t r o l s o c k e t s o n t h e f l y " ) :
local_resolver . succeed ( " l n - s f / e t c / u n b o u n d - e x t r a 3 . c o n f / e t c / u n b o u n d / e x t r a 3 . c o n f " )
local_resolver . succeed ( " s y s t e m c t l r e l o a d u n b o u n d " )
local_resolver . succeed ( " u n b o u n d - c o n t r o l l i s t _ f o r w a r d s " )
'' ;
} )