m (→Debugging: Regular user is not allowed to run unbound-control commands, thus the change from '$' to '#'. 'active' is a switch not a command. nmcli expect either connection name or switch at this position.) |
|||
(6 intermediate revisions by 3 users not shown) | |||
Line 3: | Line 3: | ||
Applications that don't understand DNSSEC are transparently protected by the local validating resolver which reports name resolution failure whenever validation of a DNS record fails. On the other hand, applications that know about DNSSEC can distinguish validated DNS records from DNS records in unsigned zones. Such applications can use DNSSEC validated data for example to initiate TLS sessions. A TLS library can do that for the application. | Applications that don't understand DNSSEC are transparently protected by the local validating resolver which reports name resolution failure whenever validation of a DNS record fails. On the other hand, applications that know about DNSSEC can distinguish validated DNS records from DNS records in unsigned zones. Such applications can use DNSSEC validated data for example to initiate TLS sessions. A TLS library can do that for the application. | ||
== | == Client side DNSSEC deployment == | ||
DNSSEC brings data integrity and authenticity to plain DNS. This is very important, since one can publish different cryptographic (or any trusted) data in DNS database. This enables new types of applications and functionality like: | |||
* Verify a remote server SSH fingerprint using SSHFP record in DNS (RFC 4255) | |||
* Verify a TLS certificate offered by the remote server using DANE and TLSA record in DNS (RFC 6698) | |||
* Get IPsec keys for a particular remote host automatically using IPSECKEY record in DNS (RFC 4025) | |||
* Get X.509 or OpenPGP certificates using CERT record in DNS (RFC 4398) | |||
* Verify that a specific Certification Authority is authorized to issue a certificate for a particular domain, using the CAA record in DNS (RFC 6844) | |||
Validating resolver can validate the signed DNS response and set '''AD flag''' saying that it did the validation. One may not trust the network-provided DNS resolver and/or the channel (network) between the host and resolver. | |||
There are currently two meaningful approaches for implementing DNSSEC aware applications: | |||
# Use some intelligent name resolution library, which is able to do the validation (e.g. [https://getdnsapi.net/ getdns library]) | |||
# Use locally running validating resolver (e.g. Unbound) and trust the '''AD flag''' in DNS response | |||
This section explains the solution based on local validating resolver. This approach is beneficial also for applications that are not DNSSEC aware, since these will always get only responses that were validated. This improves the overall security of the system and of all applications that are doing domain name resolution for any purpose. | |||
{{admon/tip|1=Blog post discussing development of DNSSEC aware applications|2=You can find more information in the [http://developerblog.redhat.com/2015/04/14/writing-an-application-that-supports-dnssec-in-rhel-and-fedora/ Writing an application that supports DNSSEC in RHEL and Fedora] blog post.}} | |||
=== How it works === | |||
{{admon/note|Basic assumption|Note that we are assuming that you are using '''NetworkManager''' for your network configuration. For using or testing dnssec-trigger, we recommend using a fully updated Fedora 22 or later.}} | |||
The solution we are using in Fedora consists of three components: | |||
* [https://wiki.gnome.org/Projects/NetworkManager NetworkManager] | |||
* [http://www.nlnetlabs.nl/projects/dnssec-trigger/ dnssec-trigger daemon] | |||
* [https://unbound.nlnetlabs.nl/ Unbound validating resolver] | |||
The overall solution is designed so that it is able to dynamically react to any network configuration changes. The user should not need to configure Unbound manually in most cases and everything should work out of the box. Note that some use-cases relying on various hacks and previous incorrect behavior of some components may not work. Example of such situation may be when one is using only NetworkManager and is connected to VPN that should be used only for resources from that network. In such case all DNS queries were forwarded to the VPN. This behavior was incorrect and will not work anymore. VPN should list all the domains it is providing. This way there is no information leaking to VPN when doing domain name resolution. | |||
The purpose of each component is outlined in the following sections. | |||
==== NetworkManager ==== | |||
In the client side DNSSEC deployment '''we use NetworkManager as the single source of the network configuration'''. We also rely on NetworkManager, to be notified on every network configuration change. This is really important, since the locally running validating resolver needs to be always configured properly to be able to successfully resolve domain names. | |||
For communication with NetworkManager we use the Python bindings for libnm-glib. We are consuming the following information: | |||
* current list of active connections | |||
* <strike>check the Connectivity state (if there is Captive Portal, etc.)</strike> not yet done | |||
* for each connection we inspect | |||
** if the connection is marked as default by NetworkManager for IPv4 or IPv6 connectivity | |||
** connection provided DNS resolvers | |||
** connection provided (search) domains | |||
** if the connection is VPN | |||
==== dnssec-trigger ==== | |||
dnssec-trigger daemon and script are '''responsible for dynamic reconfiguration of Unbound server based on the current network configuration'''. The dnssec-trigger consists of multiple components, responsible for performing various tests, reconfiguring Unbound server and also user interaction. Most of the behavior is configurable and also the default configuration and behavior differs based on the Fedora Product you are using (e.g. Workstation has different default configuration than Server). | |||
===== dnssec-trigger script ===== | |||
There are actually two scripts. One is simple Bash script installed in <code>/etc/NetworkManager/dispatcher.d/</code> which is triggered on every network configuration change by NetworkManager dispatcher. The second is the Python script located in <code>/usr/libexec/dnssec-trigger-script</code>. This script fetches the current configuration from NetworkManager using libnm-glib API and based on the configuration does: | |||
* tells dnssec-trigger daemon which DNS resolvers it should try to use for global name resolution (These are the resolvers from default connections) | |||
* adds/removes explicit forward zones directly in Unbound for connection provided domains (regular connection or VPN connection provided) - this effectively configures split DNS | |||
* may configure forward zones for private address range reverse zones pointing to the connection provided DNS resolvers | |||
* may add connection provided search domains into <code>/etc/resolv.conf</code> | |||
* backups/restores <code>/etc/resolv.conf</code> on dnssec-trigger service start/stop | |||
===== dnssec-trigger daemon ===== | |||
The daemon is responsible for configuring Unbound server properly so it is able to do DNSSEC validation. | |||
'''TBD''' | |||
===== dnssec-trigger panel ===== | |||
The panel is a simple GTK2 panel for user interaction. The user interaction is needed in some situations like when Captive Portal is detected or when the connection-provided resolvers don't support DNSSEC and all fall-back possibilities failed. The panel runs in background and connects to running dnssec-trigger daemon using SSL socket. You can interact with the panel intentionally by clicking on a ''blue anchor icon'' in the status bar of your desktop environment. When dnssec-trigger daemon needs some user input, it notifies all connected panels which can create a pop-up dialog and gather user input. | |||
{{admon/important|This is important|dnssec-trigger panel is not installed by default any more.}} | |||
==== Unbound ==== | |||
Unbound is a validating resolver. It runs on <code>127.0.0.1</code> port <code>53</code>. It is possible to configure it statically using its configuration file or dynamically using <code>unbound-control</code> utility. You need to run it as ''root'' or be in ''unbound'' group. This is also the interface dnssec-trigger daemon and script uses for dynamic Unbound reconfiguration. | |||
{{admon/note|User-defined configuration|User-defined forward zones are preserved and not overridden by dnssec-trigger.}} | |||
==== Handling of VPN connections ==== | |||
With VPNs there are two situations: | |||
# The VPN is configured to be used only for resources from the network | |||
# The VPN is configured to be used for all resources | |||
===== VPN just for resources from the network ===== | |||
TBD | |||
===== VPN used for all resources ===== | |||
In this situation the VPN is chosen by NetworkManager as a default connection. This means it is handled in the same fashion as regular default connection. | |||
=== Installation === | |||
<pre> | |||
dnf install dnssec-trigger | |||
</pre> | |||
This will get you all necessary packages (most importantly Unbound server) as dependencies. | |||
'''Note:''' if you need the dnssec-trigger panel on your desktop environment you need to install the panel by hand: | |||
<pre> | <pre> | ||
dnf install dnssec-trigger-panel | |||
</pre> | </pre> | ||
{{admon/note|Product specific configuration|dnssec-trigger uses different configuration for different Fedora Products. At the moment Fedora Workstation uses different configuration. In all other products and non-product environments the configuration is the same.}} | |||
=== | === Getting started === | ||
Since | Since Fedora 22, dnssec-triggerd service is enabled by default and thus you can simply reboot. If that is inconvenient, start dnssec-triggerd service manually. | ||
<pre> | <pre> | ||
Line 23: | Line 117: | ||
</pre> | </pre> | ||
Make sure <code>dnssec-trigger-panel</code> gets started in your session. It's an important piece of the ecosystem as it notifies you when | Make sure <code>dnssec-trigger-panel</code> gets started in your session if you don't use GNOME. It's an important piece of the ecosystem as it notifies you when Captive Portal is detected and allows you to perform hotspot signon or disable DNSSEC temporarily. Having user interface at hand is a critical feature when moving between networks. On a headless system with a SSH session, the same actions can be performed using <code>dnssec-trigger-control</code>. | ||
=== | === Getting rid of it === | ||
The best way to disable the split DNS and DNSSEC functions temporarily is to choose <em>Hotspot signon</em> in the context menu of dnssec-trigger applet to which dnssec-trigger daemon currently responds by doing its best to reset <code>/etc/resolv.conf</code> to a state without dnssec-trigger. Stopping the daemon results in similar behavior. You can perform the same action from the command line as well. | The best way to disable the split DNS and DNSSEC functions temporarily is to choose <em>Hotspot signon</em> in the context menu of dnssec-trigger applet to which dnssec-trigger daemon currently responds by doing its best to reset <code>/etc/resolv.conf</code> to a state without dnssec-trigger. Stopping the daemon results in similar behavior. You can perform the same action from the command line as well. | ||
Line 39: | Line 133: | ||
</pre> | </pre> | ||
To abandon the features permanently, the best way is to | To abandon the features permanently, the best way is to remove dnssec-trigger package. DNF will remove Unbound as well if there is nothing else requiring it on the system. | ||
<pre> | <pre> | ||
dnf remove unbound | |||
</pre> | </pre> | ||
=== | == Configuring unbound manually for split DNS and DNSSEC == | ||
== Manual configuration via Unbound == | == Manual configuration via Unbound == | ||
Line 76: | Line 168: | ||
<pre> | <pre> | ||
# unbound-control forward | |||
# unbound-control list_forwards | |||
</pre> | </pre> | ||
Line 83: | Line 175: | ||
<pre> | <pre> | ||
$ nmcli connection show active | $ nmcli connection show --active | ||
$ nmcli connection show active <id/uuid> | $ nmcli connection show --active <id/uuid> | ||
</pre> | </pre> | ||
== How it works elsewhere == | |||
Please see page [[Networking/NameResolution/DNSSEC/OtherOSes]] for summary about other operating systems. | |||
== Documentation TODO == | == Documentation TODO == |
Latest revision as of 08:42, 27 October 2016
DNS name resolution queries can be secured by DNSSEC to avoid various spoofing attacks. When a local validating DNS resolver is in use, all software can potentially benefit from local DNSSEC validation if the system is configured properly. The root zone provides a global trust anchor that in turn allows for validation of DNS records in signed zones. Other trust anchors can be configured to explicitly protect known DNS subtrees.
Applications that don't understand DNSSEC are transparently protected by the local validating resolver which reports name resolution failure whenever validation of a DNS record fails. On the other hand, applications that know about DNSSEC can distinguish validated DNS records from DNS records in unsigned zones. Such applications can use DNSSEC validated data for example to initiate TLS sessions. A TLS library can do that for the application.
Client side DNSSEC deployment
DNSSEC brings data integrity and authenticity to plain DNS. This is very important, since one can publish different cryptographic (or any trusted) data in DNS database. This enables new types of applications and functionality like:
- Verify a remote server SSH fingerprint using SSHFP record in DNS (RFC 4255)
- Verify a TLS certificate offered by the remote server using DANE and TLSA record in DNS (RFC 6698)
- Get IPsec keys for a particular remote host automatically using IPSECKEY record in DNS (RFC 4025)
- Get X.509 or OpenPGP certificates using CERT record in DNS (RFC 4398)
- Verify that a specific Certification Authority is authorized to issue a certificate for a particular domain, using the CAA record in DNS (RFC 6844)
Validating resolver can validate the signed DNS response and set AD flag saying that it did the validation. One may not trust the network-provided DNS resolver and/or the channel (network) between the host and resolver.
There are currently two meaningful approaches for implementing DNSSEC aware applications:
- Use some intelligent name resolution library, which is able to do the validation (e.g. getdns library)
- Use locally running validating resolver (e.g. Unbound) and trust the AD flag in DNS response
This section explains the solution based on local validating resolver. This approach is beneficial also for applications that are not DNSSEC aware, since these will always get only responses that were validated. This improves the overall security of the system and of all applications that are doing domain name resolution for any purpose.
How it works
The solution we are using in Fedora consists of three components:
The overall solution is designed so that it is able to dynamically react to any network configuration changes. The user should not need to configure Unbound manually in most cases and everything should work out of the box. Note that some use-cases relying on various hacks and previous incorrect behavior of some components may not work. Example of such situation may be when one is using only NetworkManager and is connected to VPN that should be used only for resources from that network. In such case all DNS queries were forwarded to the VPN. This behavior was incorrect and will not work anymore. VPN should list all the domains it is providing. This way there is no information leaking to VPN when doing domain name resolution.
The purpose of each component is outlined in the following sections.
NetworkManager
In the client side DNSSEC deployment we use NetworkManager as the single source of the network configuration. We also rely on NetworkManager, to be notified on every network configuration change. This is really important, since the locally running validating resolver needs to be always configured properly to be able to successfully resolve domain names.
For communication with NetworkManager we use the Python bindings for libnm-glib. We are consuming the following information:
- current list of active connections
check the Connectivity state (if there is Captive Portal, etc.)not yet done- for each connection we inspect
- if the connection is marked as default by NetworkManager for IPv4 or IPv6 connectivity
- connection provided DNS resolvers
- connection provided (search) domains
- if the connection is VPN
dnssec-trigger
dnssec-trigger daemon and script are responsible for dynamic reconfiguration of Unbound server based on the current network configuration. The dnssec-trigger consists of multiple components, responsible for performing various tests, reconfiguring Unbound server and also user interaction. Most of the behavior is configurable and also the default configuration and behavior differs based on the Fedora Product you are using (e.g. Workstation has different default configuration than Server).
dnssec-trigger script
There are actually two scripts. One is simple Bash script installed in /etc/NetworkManager/dispatcher.d/
which is triggered on every network configuration change by NetworkManager dispatcher. The second is the Python script located in /usr/libexec/dnssec-trigger-script
. This script fetches the current configuration from NetworkManager using libnm-glib API and based on the configuration does:
- tells dnssec-trigger daemon which DNS resolvers it should try to use for global name resolution (These are the resolvers from default connections)
- adds/removes explicit forward zones directly in Unbound for connection provided domains (regular connection or VPN connection provided) - this effectively configures split DNS
- may configure forward zones for private address range reverse zones pointing to the connection provided DNS resolvers
- may add connection provided search domains into
/etc/resolv.conf
- backups/restores
/etc/resolv.conf
on dnssec-trigger service start/stop
dnssec-trigger daemon
The daemon is responsible for configuring Unbound server properly so it is able to do DNSSEC validation.
TBD
dnssec-trigger panel
The panel is a simple GTK2 panel for user interaction. The user interaction is needed in some situations like when Captive Portal is detected or when the connection-provided resolvers don't support DNSSEC and all fall-back possibilities failed. The panel runs in background and connects to running dnssec-trigger daemon using SSL socket. You can interact with the panel intentionally by clicking on a blue anchor icon in the status bar of your desktop environment. When dnssec-trigger daemon needs some user input, it notifies all connected panels which can create a pop-up dialog and gather user input.
Unbound
Unbound is a validating resolver. It runs on 127.0.0.1
port 53
. It is possible to configure it statically using its configuration file or dynamically using unbound-control
utility. You need to run it as root or be in unbound group. This is also the interface dnssec-trigger daemon and script uses for dynamic Unbound reconfiguration.
Handling of VPN connections
With VPNs there are two situations:
- The VPN is configured to be used only for resources from the network
- The VPN is configured to be used for all resources
VPN just for resources from the network
TBD
VPN used for all resources
In this situation the VPN is chosen by NetworkManager as a default connection. This means it is handled in the same fashion as regular default connection.
Installation
dnf install dnssec-trigger
This will get you all necessary packages (most importantly Unbound server) as dependencies.
Note: if you need the dnssec-trigger panel on your desktop environment you need to install the panel by hand:
dnf install dnssec-trigger-panel
Getting started
Since Fedora 22, dnssec-triggerd service is enabled by default and thus you can simply reboot. If that is inconvenient, start dnssec-triggerd service manually.
systemctl start dnssec-triggerd
Make sure dnssec-trigger-panel
gets started in your session if you don't use GNOME. It's an important piece of the ecosystem as it notifies you when Captive Portal is detected and allows you to perform hotspot signon or disable DNSSEC temporarily. Having user interface at hand is a critical feature when moving between networks. On a headless system with a SSH session, the same actions can be performed using dnssec-trigger-control
.
Getting rid of it
The best way to disable the split DNS and DNSSEC functions temporarily is to choose Hotspot signon in the context menu of dnssec-trigger applet to which dnssec-trigger daemon currently responds by doing its best to reset /etc/resolv.conf
to a state without dnssec-trigger. Stopping the daemon results in similar behavior. You can perform the same action from the command line as well.
dnssec-trigger-control hotspot_signon
To get back the above functions, you can use the same context menu, just choose Reprobe. Command line variant is also available.
dnssec-trigger-control reprobe
To abandon the features permanently, the best way is to remove dnssec-trigger package. DNF will remove Unbound as well if there is nothing else requiring it on the system.
dnf remove unbound
Configuring unbound manually for split DNS and DNSSEC
Manual configuration via Unbound
TBD
Local zones
TBD
Global zone
TBD
Using dnssec-trigger-control (for testing only)
dnssec-trigger
configures /etc/resolv.conf
to use a local unbound instance on 127.0.0.1
and Unbound to use a secure global zone with nameservers submitted through dnssec-trigger-control
or, if those aren't suitable, using public nameservers run by Fedora or the upstream project.
It also performs captive portal (hotspot) detection and temporarily changes /etc/resolv.conf
to include the nameservers of the local network directly. That unfortunately breaks the local zones used with any network interfaces including those that have nothing to do with the captive portal connection.
NetworkManager integration
TBD
Debugging
Show global configuration and connection zones configuration in unbound:
# unbound-control forward # unbound-control list_forwards
To check NetworkManager's view of the configuration, use:
$ nmcli connection show --active $ nmcli connection show --active <id/uuid>
How it works elsewhere
Please see page Networking/NameResolution/DNSSEC/OtherOSes for summary about other operating systems.
Documentation TODO
- Adding search domains.
- Common changes that people may wish to make such as the add_wifi_provided_zones
- When caches are flushed and what triggers that.
- How issues such as VPN provided name servers are handled.
- How to restart the services correctly.