2019-03-31 12:49:47 +02:00
|
|
|
.. Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2021-06-03 08:37:05 +02:00
|
|
|
..
|
2020-06-01 14:46:24 +00:00
|
|
|
.. SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
..
|
2019-03-31 12:49:47 +02:00
|
|
|
.. This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
.. License, v. 2.0. If a copy of the MPL was not distributed with this
|
2020-09-14 21:04:19 +00:00
|
|
|
.. file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2021-06-03 08:37:05 +02:00
|
|
|
..
|
2019-03-31 12:49:47 +02:00
|
|
|
.. See the COPYRIGHT file distributed with this work for additional
|
|
|
|
.. information regarding copyright ownership.
|
|
|
|
|
2022-03-22 00:38:26 +00:00
|
|
|
.. _security:
|
2019-03-31 12:49:47 +02:00
|
|
|
|
2022-03-22 00:38:26 +00:00
|
|
|
Security Configurations
|
|
|
|
=======================
|
2019-03-31 12:49:47 +02:00
|
|
|
|
2022-03-22 00:38:26 +00:00
|
|
|
.. _file_permissions:
|
|
|
|
|
|
|
|
.. _access_Control_Lists:
|
2019-03-31 12:49:47 +02:00
|
|
|
|
|
|
|
Access Control Lists
|
|
|
|
--------------------
|
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
Access Control Lists (ACLs) are address match lists that can be set up
|
2022-07-01 12:29:18 +02:00
|
|
|
and nicknamed for future use in :any:`allow-notify`, :any:`allow-query`,
|
|
|
|
:any:`allow-query-on`, :any:`allow-recursion`, :any:`blackhole`,
|
|
|
|
:any:`allow-transfer`, :any:`match-clients`, etc.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
ACLs give users finer control over who can access the
|
2020-07-02 16:54:57 +00:00
|
|
|
name server, without cluttering up configuration files with huge lists of
|
2019-03-31 12:49:47 +02:00
|
|
|
IP addresses.
|
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
It is a *good idea* to use ACLs, and to control access.
|
|
|
|
Limiting access to the server by outside parties can help prevent
|
|
|
|
spoofing and denial of service (DoS) attacks against the server.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
|
|
|
ACLs match clients on the basis of up to three characteristics: 1) The
|
|
|
|
client's IP address; 2) the TSIG or SIG(0) key that was used to sign the
|
2020-07-02 16:54:57 +00:00
|
|
|
request, if any; and 3) an address prefix encoded in an EDNS
|
|
|
|
Client-Subnet option, if any.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
|
|
|
Here is an example of ACLs based on client addresses:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
// Set up an ACL named "bogusnets" that blocks
|
2019-03-31 12:49:47 +02:00
|
|
|
// RFC1918 space and some reserved space, which is
|
|
|
|
// commonly used in spoofing attacks.
|
|
|
|
acl bogusnets {
|
|
|
|
0.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3;
|
|
|
|
10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Set up an ACL called our-nets. Replace this with the
|
|
|
|
// real IP numbers.
|
|
|
|
acl our-nets { x.x.x.x/24; x.x.x.x/21; };
|
|
|
|
options {
|
|
|
|
...
|
|
|
|
...
|
|
|
|
allow-query { our-nets; };
|
|
|
|
allow-recursion { our-nets; };
|
|
|
|
...
|
|
|
|
blackhole { bogusnets; };
|
|
|
|
...
|
|
|
|
};
|
|
|
|
|
|
|
|
zone "example.com" {
|
2020-07-02 16:54:57 +00:00
|
|
|
type primary;
|
2019-03-31 12:49:47 +02:00
|
|
|
file "m/example.com";
|
|
|
|
allow-query { any; };
|
|
|
|
};
|
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
This allows authoritative queries for ``example.com`` from any address,
|
|
|
|
but recursive queries only from the networks specified in ``our-nets``,
|
|
|
|
and no queries at all from the networks specified in ``bogusnets``.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
|
|
|
In addition to network addresses and prefixes, which are matched against
|
|
|
|
the source address of the DNS request, ACLs may include ``key``
|
|
|
|
elements, which specify the name of a TSIG or SIG(0) key.
|
|
|
|
|
|
|
|
When BIND 9 is built with GeoIP support, ACLs can also be used for
|
|
|
|
geographic access restrictions. This is done by specifying an ACL
|
2020-06-01 14:46:24 +00:00
|
|
|
element of the form: ``geoip db database field value``.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
The ``field`` parameter indicates which field to search for a match. Available fields
|
|
|
|
are ``country``, ``region``, ``city``, ``continent``, ``postal`` (postal code),
|
|
|
|
``metro`` (metro code), ``area`` (area code), ``tz`` (timezone), ``isp``,
|
|
|
|
``asnum``, and ``domain``.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
|
|
|
``value`` is the value to search for within the database. A string may be quoted
|
2020-06-01 14:46:24 +00:00
|
|
|
if it contains spaces or other special characters. An ``asnum`` search for
|
2019-03-31 12:49:47 +02:00
|
|
|
autonomous system number can be specified using the string "ASNNNN" or the
|
2020-06-01 14:46:24 +00:00
|
|
|
integer NNNN. If a ``country`` search is specified with a string that is two characters
|
2020-07-02 16:54:57 +00:00
|
|
|
long, it must be a standard ISO-3166-1 two-letter country code; otherwise,
|
2020-06-01 14:46:24 +00:00
|
|
|
it is interpreted as the full name of the country. Similarly, if
|
|
|
|
``region`` is the search term and the string is two characters long, it is treated as a
|
|
|
|
standard two-letter state or province abbreviation; otherwise, it is treated as the
|
2019-03-31 12:49:47 +02:00
|
|
|
full name of the state or province.
|
|
|
|
|
2022-07-01 12:29:18 +02:00
|
|
|
The :any:`database` field indicates which GeoIP database to search for a match. In
|
2019-03-31 12:49:47 +02:00
|
|
|
most cases this is unnecessary, because most search fields can only be found in
|
2020-06-01 14:46:24 +00:00
|
|
|
a single database. However, searches for ``continent`` or ``country`` can be
|
|
|
|
answered from either the ``city`` or ``country`` databases, so for these search
|
2022-07-01 12:29:18 +02:00
|
|
|
types, specifying a :any:`database` forces the query to be answered from that
|
|
|
|
database and no other. If a :any:`database` is not specified, these queries
|
2020-06-01 14:46:24 +00:00
|
|
|
are first answered from the ``city`` database if it is installed, and then from the ``country``
|
|
|
|
database if it is installed. Valid database names are ``country``,
|
|
|
|
``city``, ``asnum``, ``isp``, and ``domain``.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
|
|
|
Some example GeoIP ACLs:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
geoip country US;
|
|
|
|
geoip country JP;
|
|
|
|
geoip db country country Canada;
|
|
|
|
geoip region WA;
|
|
|
|
geoip city "San Francisco";
|
|
|
|
geoip region Oklahoma;
|
|
|
|
geoip postal 95062;
|
|
|
|
geoip tz "America/Los_Angeles";
|
|
|
|
geoip org "Internet Systems Consortium";
|
|
|
|
|
2020-07-02 16:54:57 +00:00
|
|
|
ACLs use a "first-match" logic rather than "best-match"; if an address
|
2019-03-31 12:49:47 +02:00
|
|
|
prefix matches an ACL element, then that ACL is considered to have
|
|
|
|
matched even if a later element would have matched more specifically.
|
|
|
|
For example, the ACL ``{ 10/8; !10.0.0.1; }`` would actually match a
|
2020-06-01 14:46:24 +00:00
|
|
|
query from 10.0.0.1, because the first element indicates that the query
|
2019-03-31 12:49:47 +02:00
|
|
|
should be accepted, and the second element is ignored.
|
|
|
|
|
|
|
|
When using "nested" ACLs (that is, ACLs included or referenced within
|
2020-06-01 14:46:24 +00:00
|
|
|
other ACLs), a negative match of a nested ACL tells the containing ACL to
|
2019-03-31 12:49:47 +02:00
|
|
|
continue looking for matches. This enables complex ACLs to be
|
|
|
|
constructed, in which multiple client characteristics can be checked at
|
2020-07-02 16:54:57 +00:00
|
|
|
the same time. For example, to construct an ACL which allows a query
|
2019-03-31 12:49:47 +02:00
|
|
|
only when it originates from a particular network *and* only when it is
|
|
|
|
signed with a particular key, use:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
allow-query { !{ !10/8; any; }; key example; };
|
|
|
|
|
|
|
|
Within the nested ACL, any address that is *not* in the 10/8 network
|
2020-12-16 10:24:01 +01:00
|
|
|
prefix is rejected, which terminates the processing of the ACL.
|
2020-06-01 14:46:24 +00:00
|
|
|
Any address that *is* in the 10/8 network prefix is accepted, but
|
2019-03-31 12:49:47 +02:00
|
|
|
this causes a negative match of the nested ACL, so the containing ACL
|
2020-06-01 14:46:24 +00:00
|
|
|
continues processing. The query is accepted if it is signed by
|
|
|
|
the key ``example``, and rejected otherwise. The ACL, then, only
|
2019-03-31 12:49:47 +02:00
|
|
|
matches when *both* conditions are true.
|
|
|
|
|
|
|
|
.. _chroot_and_setuid:
|
|
|
|
|
|
|
|
``Chroot`` and ``Setuid``
|
|
|
|
-------------------------
|
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
On Unix servers, it is possible to run BIND in a *chrooted* environment
|
2022-03-02 16:54:31 +01:00
|
|
|
(using the ``chroot()`` function) by specifying the :option:`-t <named -t>` option for
|
2022-03-03 22:17:04 +01:00
|
|
|
:iscman:`named`. This can help improve system security by placing BIND in a
|
2020-06-01 14:46:24 +00:00
|
|
|
"sandbox," which limits the damage done if a server is compromised.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
Another useful feature in the Unix version of BIND is the ability to run
|
2022-03-02 16:54:31 +01:00
|
|
|
the daemon as an unprivileged user (:option:`-u <named -u>` user). We suggest running
|
2019-03-31 12:49:47 +02:00
|
|
|
as an unprivileged user when using the ``chroot`` feature.
|
|
|
|
|
|
|
|
Here is an example command line to load BIND in a ``chroot`` sandbox,
|
2022-03-03 22:17:04 +01:00
|
|
|
``/var/named``, and to run :iscman:`named` ``setuid`` to user 202:
|
2019-03-31 12:49:47 +02:00
|
|
|
|
|
|
|
``/usr/local/sbin/named -u 202 -t /var/named``
|
|
|
|
|
|
|
|
.. _chroot:
|
|
|
|
|
|
|
|
The ``chroot`` Environment
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2020-06-01 14:46:24 +00:00
|
|
|
For a ``chroot`` environment to work properly in a particular
|
|
|
|
directory (for example, ``/var/named``), the
|
|
|
|
environment must include everything BIND needs to run. From BIND's
|
|
|
|
point of view, ``/var/named`` is the root of the filesystem;
|
2022-07-01 12:29:18 +02:00
|
|
|
the values of options like :any:`directory` and :any:`pid-file`
|
2020-06-01 14:46:24 +00:00
|
|
|
must be adjusted to account for this.
|
|
|
|
|
2023-06-07 16:00:00 +02:00
|
|
|
Unlike with earlier versions of BIND,
|
2022-03-03 22:17:04 +01:00
|
|
|
:iscman:`named` does *not* typically need to be compiled statically, nor do shared libraries need to be installed under the new
|
2020-06-01 14:46:24 +00:00
|
|
|
root. However, depending on the operating system, it may be necessary to set
|
|
|
|
up locations such as ``/dev/zero``, ``/dev/random``, ``/dev/log``, and
|
2019-03-31 12:49:47 +02:00
|
|
|
``/etc/localtime``.
|
|
|
|
|
|
|
|
.. _setuid:
|
|
|
|
|
|
|
|
Using the ``setuid`` Function
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2022-03-03 22:17:04 +01:00
|
|
|
Prior to running the :iscman:`named` daemon, use the ``touch`` utility (to
|
2019-03-31 12:49:47 +02:00
|
|
|
change file access and modification times) or the ``chown`` utility (to
|
2020-06-01 14:46:24 +00:00
|
|
|
set the user id and/or group id) on files where BIND should
|
2019-03-31 12:49:47 +02:00
|
|
|
write.
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
2022-03-03 22:17:04 +01:00
|
|
|
If the :iscman:`named` daemon is running as an unprivileged user, it
|
2020-06-01 14:46:24 +00:00
|
|
|
cannot bind to new restricted ports if the server is
|
2019-03-31 12:49:47 +02:00
|
|
|
reloaded.
|
|
|
|
|
|
|
|
.. _dynamic_update_security:
|
|
|
|
|
|
|
|
Dynamic Update Security
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
Access to the dynamic update facility should be strictly limited. In
|
|
|
|
earlier versions of BIND, the only way to do this was based on the IP
|
|
|
|
address of the host requesting the update, by listing an IP address or
|
2022-07-01 12:29:18 +02:00
|
|
|
network prefix in the :any:`allow-update` zone option. This method is
|
2020-07-02 16:54:57 +00:00
|
|
|
insecure, since the source address of the update UDP packet is easily
|
2019-03-31 12:49:47 +02:00
|
|
|
forged. Also note that if the IP addresses allowed by the
|
2022-07-01 12:29:18 +02:00
|
|
|
:any:`allow-update` option include the address of a secondary server which
|
2020-06-01 14:46:24 +00:00
|
|
|
performs forwarding of dynamic updates, the primary can be trivially
|
|
|
|
attacked by sending the update to the secondary, which forwards it to
|
|
|
|
the primary with its own source IP address - causing the primary to approve
|
2019-03-31 12:49:47 +02:00
|
|
|
it without question.
|
|
|
|
|
|
|
|
For these reasons, we strongly recommend that updates be
|
|
|
|
cryptographically authenticated by means of transaction signatures
|
2022-07-01 12:29:18 +02:00
|
|
|
(TSIG). That is, the :any:`allow-update` option should list only TSIG key
|
2020-07-02 16:54:57 +00:00
|
|
|
names, not IP addresses or network prefixes. Alternatively, the
|
2022-07-01 12:29:18 +02:00
|
|
|
:any:`update-policy` option can be used.
|
2019-03-31 12:49:47 +02:00
|
|
|
|
2020-07-02 16:54:57 +00:00
|
|
|
Some sites choose to keep all dynamically updated DNS data in a
|
2019-03-31 12:49:47 +02:00
|
|
|
subdomain and delegate that subdomain to a separate zone. This way, the
|
2020-07-02 16:54:57 +00:00
|
|
|
top-level zone containing critical data, such as the IP addresses of
|
|
|
|
public web and mail servers, need not allow dynamic updates at all.
|
2022-03-22 00:38:26 +00:00
|
|
|
|
|
|
|
.. _sec_file_transfer:
|
|
|
|
|
|
|
|
.. _dns_over_tls:
|