%description backend-sqlite
This package contains the SQLite backend for %{name}
+%package backend-tinydns
+Summary: TinyDNS backend for %{name}
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: tinycdb-devel
+%global backends %{backends} tinydns
+
+%description backend-tinydns
+This package contains the TinyDNS backend for %{name}
+
%prep
%setup -q -n %{name}-${TARBALLVERSION}
%doc modules/gsqlite3backend/dnssec-3.x_to_3.4.0_schema.sqlite3.sql
%doc modules/gsqlite3backend/nodnssec-3.x_to_3.4.0_schema.sqlite3.sql
%{_libdir}/%{name}/libgsqlite3backend.so
+
+%files backend-tinydns
+%{_libdir}/%{name}/libtinydnsbackend.so
EOF
;;
SLES\ 12*)
AC_MSG_NOTICE([Built-in modules: $modules])
AC_MSG_NOTICE([Dynamic modules: $dynmodules])
AC_MSG_NOTICE([])
-AS_IF([test "x$openssl_ecdsa" == "xyes"],
+AS_IF([test "x$openssl_ecdsa" = "xyes"],
[AC_MSG_NOTICE([OpenSSL ecdsa: yes])],
[AC_MSG_NOTICE([OpenSSL ecdsa: no])]
)
[AC_MSG_NOTICE([LuaJit: $LUAJITPC])],
[AC_MSG_NOTICE([Lua/LuaJit: no])])
])
-AS_IF([test "x$enable_experimental_gss_tsig" == "xyes"],
+AS_IF([test "x$enable_experimental_gss_tsig" = "xyes"],
[AC_MSG_NOTICE([GSS-TSIG: yes])]
)
AS_IF([test "x$systemd" != "xn"],
You can also download releases on the [website](https://downloads.powerdns.com/releases/).
These releases are PGP-signed with key-id [FBAE 0323 821C 7706 A5CA 151B DCF5
-13FA 7EED 19F3](https://pgp.mit.edu/pks/lookup?op=get&search=0xDCF513FA7EED19F3)
-or [1628 90D0 689D D12D D33E 4696 1C5E
-E990 D2E7 1575](https://pgp.mit.edu/pks/lookup?op=get&search=0x1C5EE990D2E71575).
+13FA 7EED 19F3](https://pgp.mit.edu/pks/lookup?op=get&search=0xDCF513FA7EED19F3),
+[1628 90D0 689D D12D D33E 4696 1C5E
+E990 D2E7 1575](https://pgp.mit.edu/pks/lookup?op=get&search=0x1C5EE990D2E71575)
+or [B76C D467 1C09 68BA A87D E61C 5E50 715B F2FF E1A7](https://pgp.mit.edu/pks/lookup?op=get&search=0x5E50715BF2FFE1A7).
## OS specific gotcha's
### AIX
* Default: yes
If a PID file should be written. Available since 4.0.
+
+## `xfr-max-received-mbytes`
+* Integer
+* Default: 100
+
+Specifies the maximum number of received megabytes allowed on an incoming AXFR/IXFR update, to prevent
+resource exhaustion. A value of 0 means no restriction.
## Bug fixes
- [#4162](https://github.com/PowerDNS/pdns/pull/4162) Don't validate zones from the local auth store, go one level down while validating when there is a CNAME
+ - [#4187](https://github.com/PowerDNS/pdns/pull/4187):
+ * Don't go bogus on islands of security
+ * Check all possible chains for Insecures
+ * Don't go Bogus on a CNAME at the apex
## Improvements
* tsigalgo = the name of the TSIG algorithm (like 'hmac-md5') used
* tsigsecret = base64 encoded TSIG secret
* refresh = an integer describing the interval between checks for updates. By default, the RPZ zone's default is used
+* maxReceivedMBytes = the maximum size in megabytes of an AXFR/IXFR update, to prevent resource exhaustion.
+The default value of 0 means no restriction.
If no settings are included, the RPZ is taken literally with no overrides applied.
## `root-nx-trust`
* Boolean
-* Default: no
-* Available since: 3.7.0
+* Default: no (<= 4.0.0), yes
If set, an NXDOMAIN from the root-servers will serve as a blanket NXDOMAIN for the entire TLD
the query belonged to. The effect of this is far fewer queries to the root-servers.
-@ 86400 IN SOA pdns-public-ns1.powerdns.com. pieter\.lexis.powerdns.com. 2016071102 10800 3600 604800 10800
+@ 86400 IN SOA pdns-public-ns1.powerdns.com. pieter\.lexis.powerdns.com. 2016072001 10800 3600 604800 10800
@ 3600 IN NS pdns-public-ns1.powerdns.com.
@ 3600 IN NS pdns-public-ns2.powerdns.com.
; Auth
auth-3.4.8.security-status 60 IN TXT "1 OK"
auth-3.4.9.security-status 60 IN TXT "1 OK"
-auth-4.0.0-alpha1.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-alpha2.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-alpha3.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-beta1.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-rc1.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-rc2.security-status 60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-alpha2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-alpha3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-beta1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-rc2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
auth-4.0.0.security-status 60 IN TXT "1 OK"
; Auth Debian
auth-3.4.6-1_bpo8_1.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-03/"
auth-3.4.7-1_bpo8_1.debian.security-status 60 IN TXT "1 OK"
-auth-4.0.0_alpha1-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha1-2.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-2.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-3.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-4.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_beta1-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha1-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha1-2.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-2.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-3.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-4.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_beta1-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
; Auth Ubuntu
auth-3.4.1-3.ubuntu.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/md/security/powerdns-advisory-2015-02/"
auth-3.4.6-1.ubuntu.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-03/"
auth-3.4.7-1.ubuntu.security-status 60 IN TXT "1 OK"
-auth-4.0.0_alpha1-1.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-1.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-3build1.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha1-1.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-1.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-3build1.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
; Auth Raspbian
auth-3.4.1-3.raspbian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/md/security/powerdns-advisory-2015-02/"
recursor-3.7.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
recursor-3.7.3.security-status 60 IN TXT "1 OK"
-recursor-4.0.0-alpha1.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0-alpha2.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0-alpha3.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0-beta1.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0-rc1.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0-alpha2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0-alpha3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0-beta1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
recursor-4.0.0.security-status 60 IN TXT "1 OK"
; Recursor Debian
recursor-3.7.3-1_bpo8_1.debian.security-status 60 IN TXT "1 OK"
recursor-3.7.3-1_bpo7_1.debian.security-status 60 IN TXT "1 OK"
-recursor-4.0.0_alpha1-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha1-3.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha2-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha2-2.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-2.debian.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha1-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha1-3.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha2-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha2-2.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-2.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
; Recursor Raspbian
recursor-3.6.2-2.raspbian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
recursor-3.7.2-1.ubuntu.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
recursor-3.7.3-1.ubuntu.security-status 60 IN TXT "1 OK"
-auth-4.0.0_alpha1-1.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-2.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha1-1.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-2.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
; Recursor Fedora, EL
recursor-3.6.2-1.fc19.fedora.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
;; Builder Generated packages (auth)
; Debian
-auth-4.0.0_alpha1-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_beta1-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha1-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_beta1-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
; Ubuntu
-auth-4.0.0_alpha2-1pdns.wily.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_beta1-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha2-1pdns.wily.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_beta1-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
; Raspbian
-auth-4.0.0_alpha2-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha2-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
;; Builder Generated packages (recursor)
; Debian
-recursor-4.0.0_alpha1-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha2-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha1-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha2-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
; Ubuntu
-recursor-4.0.0_alpha2-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha2-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
-recursor-4.0.0_alpha2-1pdns.wily.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1pdns.wily.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.wily.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha2-1pdns.wily.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1pdns.wily.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.wily.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
-recursor-4.0.0_alpha3-1pdns.xenial.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.xenial.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha3-1pdns.xenial.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.xenial.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
; Raspbian
-recursor-4.0.0_alpha2-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha2-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
AS_IF([test "x$enable_remotebackend_zeromq" != "xno"],
[
- AS_IF([test "x$have_remotebackend" == "xyes"],
+ AS_IF([test "x$have_remotebackend" = "xyes"],
[
PKG_CHECK_MODULES([LIBZMQ], [libzmq],
[
return 1;
}
- lua_pushstring(lua, lb->dnspacket->getRemote().c_str());
+ lua_pushstring(lua, lb->dnspacket->getRemote().toString().c_str());
lua_pushinteger(lua, lb->dnspacket->getRemotePort());
- lua_pushstring(lua, lb->dnspacket->getLocal().c_str());
+ lua_pushstring(lua, lb->dnspacket->getLocal().toString().c_str());
lua_pushstring(lua, lb->dnspacket->getRealRemote().toString().c_str());
return 4;
string remoteIP="0.0.0.0";
Netmask realRemote("0.0.0.0/0");
if (pkt_p) {
- localIP=pkt_p->getLocal();
+ localIP=pkt_p->getLocal().toString();
realRemote = pkt_p->getRealRemote();
- remoteIP = pkt_p->getRemote();
+ remoteIP = pkt_p->getRemote().toString();
}
// abi-version = 1
// type qname qclass qtype id remote-ip-address
string realRemote="0.0.0.0/0";
if (pkt_p) {
- localIP=pkt_p->getLocal();
+ localIP=pkt_p->getLocal().toString();
realRemote = pkt_p->getRealRemote().toString();
- remoteIP = pkt_p->getRemote();
+ remoteIP = pkt_p->getRemote().toString();
}
Json query = Json::object{
* Number of entries in a given section (RecordsCountRule)
* Number of entries of a specific type in a given section (RecordsTypeCountRule)
* Presence of trailing data (TrailingDataRule)
+ * Number of labels in the qname (QNameLabelsCountRule)
+ * Wire length of the qname (QNameWireLengthRule)
Special rules are:
* an OpcodeRule
* an OrRule
* a QClassRule
+ * a QNameLabelsCountRule
+ * a QNameWireLengthRule
* a QTypeRule
* a RegexRule
* a RE2Rule
* `OrRule()`: matches if at least one of the sub-rules matches
* `OpcodeRule()`: matches queries with the specified opcode
* `QClassRule(qclass)`: matches queries with the specified qclass (numeric)
+ * `QNameLabelsCountRule(min, max)`: matches if the qname has less than `min` or more than `max` labels
+ * `QNameWireLengthRule(min, max)`: matches if the qname's length on the wire is less than `min` or more than `max` bytes
* `QTypeRule(qtype)`: matches queries with the specified qtype
* `RegexRule(regex)`: matches the query name against the supplied regex
* `RecordsCountRule(section, minCount, maxCount)`: matches if there is at least `minCount` and at most `maxCount` records in the `section` section
* `toStringWithPort()`: alias for `tostringWithPort()`
* DNSName related:
* `newDNSName(name)`: make a DNSName based on this .-terminated name
+ * member `countLabels()`: return the number of labels
* member `isPartOf(dnsname)`: is this dnsname part of that dnsname
* member `tostring()`: return as a human friendly . terminated string
* member `toString()`: alias for `tostring()`
+ * member `wirelength()`: return the length on the wire
* DNSQuestion related:
* member `dh`: DNSHeader
* member `len`: the question length
::arg().setSwitch("outgoing-axfr-expand-alias", "Expand ALIAS records during outgoing AXFR")="no";
::arg().setSwitch("8bit-dns", "Allow 8bit dns queries")="no";
+
+ ::arg().set("xfr-max-received-mbytes", "Maximum number of megabytes received from an incoming XFR")="100";
}
static time_t s_start=time(0);
if(logDNSQueries) {
string remote;
if(P->hasEDNSSubnet())
- remote = P->getRemote() + "<-" + P->getRealRemote().toString();
+ remote = P->getRemote().toString() + "<-" + P->getRealRemote().toString();
else
- remote = P->getRemote();
+ remote = P->getRemote().toString();
L << Logger::Notice<<"Remote "<< remote <<" wants '" << P->qdomain<<"|"<<P->qtype.getName() <<
"', do = " <<P->d_dnssecOk <<", bufsize = "<< P->getMaxReplyLen()<<": ";
}
"PoolAction(", "printDNSCryptProviderFingerprint(",
"RegexRule(", "RemoteLogAction(", "RemoteLogResponseAction(", "rmResponseRule(",
"rmRule(", "rmServer(", "roundrobin",
- "QTypeRule(",
+ "QNameLabelsCountRule(", "QNameWireLengthRule(", "QTypeRule(",
"setACL(", "setDNSSECPool(", "setECSOverride(",
"setECSSourcePrefixV4(", "setECSSourcePrefixV6(", "setKey(", "setLocal(",
"setMaxTCPClientThreads(", "setMaxTCPQueuedConnections(", "setMaxUDPOutstanding(", "setRules(",
}
ComboAddress sourceAddr;
unsigned int sourceItf = 0;
- if(auto address = boost::get<string>(&pvars)) {
+ if(auto addressStr = boost::get<string>(&pvars)) {
+ ComboAddress address(*addressStr, 53);
std::shared_ptr<DownstreamState> ret;
+ if(IsAnyAddress(address)) {
+ g_outputBuffer="Error creating new server: invalid address for a downstream server.";
+ errlog("Error creating new server: %s is not a valid address for a downstream server", *addressStr);
+ return ret;
+ }
try {
- ret=std::make_shared<DownstreamState>(ComboAddress(*address, 53));
+ ret=std::make_shared<DownstreamState>(address);
}
catch(std::exception& e) {
g_outputBuffer="Error creating new server: "+string(e.what());
- errlog("Error creating new server with address %s: %s", *address, e.what());
+ errlog("Error creating new server with address %s: %s", addressStr, e.what());
return ret;
}
}
std::shared_ptr<DownstreamState> ret;
+ ComboAddress address(boost::get<string>(vars["address"]), 53);
+ if(IsAnyAddress(address)) {
+ g_outputBuffer="Error creating new server: invalid address for a downstream server.";
+ errlog("Error creating new server: %s is not a valid address for a downstream server", boost::get<string>(vars["address"]));
+ return ret;
+ }
try {
- ret=std::make_shared<DownstreamState>(ComboAddress(boost::get<string>(vars["address"]), 53), sourceAddr, sourceItf);
+ ret=std::make_shared<DownstreamState>(address, sourceAddr, sourceItf);
}
catch(std::exception& e) {
g_outputBuffer="Error creating new server: "+string(e.what());
return std::shared_ptr<DNSRule>(new TrailingDataRule());
});
+ g_lua.writeFunction("QNameLabelsCountRule", [](unsigned int minLabelsCount, unsigned int maxLabelsCount) {
+ return std::shared_ptr<DNSRule>(new QNameLabelsCountRule(minLabelsCount, maxLabelsCount));
+ });
+
+ g_lua.writeFunction("QNameWireLengthRule", [](size_t min, size_t max) {
+ return std::shared_ptr<DNSRule>(new QNameWireLengthRule(min, max));
+ });
+
g_lua.writeFunction("addAction", [](luadnsrule_t var, std::shared_ptr<DNSAction> ea)
{
setLuaSideEffect();
g_lua.registerFunction("toStringWithPort", &ComboAddress::toStringWithPort);
g_lua.registerFunction<uint16_t(ComboAddress::*)()>("getPort", [](const ComboAddress& ca) { return ntohs(ca.sin4.sin_port); } );
g_lua.registerFunction("isPartOf", &DNSName::isPartOf);
+ g_lua.registerFunction("countLabels", &DNSName::countLabels);
+ g_lua.registerFunction("wirelength", &DNSName::wirelength);
g_lua.registerFunction<string(DNSName::*)()>("tostring", [](const DNSName&dn ) { return dn.toString(); });
g_lua.registerFunction<string(DNSName::*)()>("toString", [](const DNSName&dn ) { return dn.toString(); });
g_lua.writeFunction("newDNSName", [](const std::string& name) { return DNSName(name); });
vinfolog("Got query from %s, relayed to %s", remote.toStringWithPort(), ss->getName());
}
catch(std::exception& e){
- errlog("Got an error in UDP question thread while parsing a query from %s, id %d: %s", remote.toStringWithPort(), queryId, e.what());
+ vinfolog("Got an error in UDP question thread while parsing a query from %s, id %d: %s", remote.toStringWithPort(), queryId, e.what());
}
}
return 0;
return d_rawpacket;
}
-string DNSPacket::getRemote() const
+ComboAddress DNSPacket::getRemote() const
{
- return d_remote.toString();
+ return d_remote;
}
uint16_t DNSPacket::getRemotePort() const
// address & socket manipulation
void setRemote(const ComboAddress*);
- string getRemote() const;
+ ComboAddress getRemote() const;
Netmask getRealRemote() const;
- string getLocal() const
+ ComboAddress getLocal() const
{
ComboAddress ca;
socklen_t len=sizeof(ca);
getsockname(d_socket, (sockaddr*)&ca, &len);
- return ca.toString();
+ return ca;
}
uint16_t getRemotePort() const;
// dh->rd=1; // useful to replay traffic to auths to a recursor
uint16_t dlen = pr.d_len;
- addECSOption((char*)pr.d_payload, 1500, &dlen, pr.getSource(), stamp);
+ if (stamp >= 0) addECSOption((char*)pr.d_payload, 1500, &dlen, pr.getSource(), stamp);
pr.d_len=dlen;
s_socket->sendTo((const char*)pr.d_payload, dlen, remote);
sent=true;
}
};
+class QNameLabelsCountRule : public DNSRule
+{
+public:
+ QNameLabelsCountRule(unsigned int minLabelsCount, unsigned int maxLabelsCount): d_min(minLabelsCount), d_max(maxLabelsCount)
+ {
+ }
+ bool matches(const DNSQuestion* dq) const override
+ {
+ unsigned int count = dq->qname->countLabels();
+ return count < d_min || count > d_max;
+ }
+ string toString() const override
+ {
+ return "labels count < " + std::to_string(d_min) + " || labels count > " + std::to_string(d_max);
+ }
+private:
+ unsigned int d_min;
+ unsigned int d_max;
+};
+
+class QNameWireLengthRule : public DNSRule
+{
+public:
+ QNameWireLengthRule(size_t min, size_t max): d_min(min), d_max(max)
+ {
+ }
+ bool matches(const DNSQuestion* dq) const override
+ {
+ size_t const wirelength = dq->qname->wirelength();
+ return wirelength < d_min || wirelength > d_max;
+ }
+ string toString() const override
+ {
+ return "wire length < " + std::to_string(d_min) + " || wire length > " + std::to_string(d_max);
+ }
+private:
+ size_t d_min;
+ size_t d_max;
+};
+
class DropAction : public DNSAction
{
public:
int SConnect(int sockfd, const ComboAddress& remote)
{
int ret = connect(sockfd, (struct sockaddr*)&remote, remote.getSocklen());
- if(ret < 0)
- RuntimeError(boost::format("connecting socket to %s: %s") % remote.toStringWithPort() % strerror(errno));
+ if(ret < 0) {
+ int savederrno = errno;
+ RuntimeError(boost::format("connecting socket to %s: %s") % remote.toStringWithPort() % strerror(savederrno));
+ }
return ret;
}
int SBind(int sockfd, const ComboAddress& local)
{
int ret = bind(sockfd, (struct sockaddr*)&local, local.getSocklen());
- if(ret < 0)
- RuntimeError(boost::format("binding socket to %s: %s") % local.toStringWithPort() % strerror(errno));
+ if(ret < 0) {
+ int savederrno = errno;
+ RuntimeError(boost::format("binding socket to %s: %s") % local.toStringWithPort() % strerror(savederrno));
+ }
return ret;
}
// Returns pairs of "remove & add" vectors. If you get an empty remove, it means you got an AXFR!
vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& oursr,
- const TSIGTriplet& tt, const ComboAddress* laddr)
+ const TSIGTriplet& tt, const ComboAddress* laddr, size_t maxReceivedBytes)
{
vector<pair<vector<DNSRecord>, vector<DNSRecord> > > ret;
vector<uint8_t> packet;
// CURRENT MASTER SOA
shared_ptr<SOARecordContent> masterSOA;
vector<DNSRecord> records;
+ size_t receivedBytes = 0;
for(;;) {
if(s.read((char*)&len, 2)!=2)
break;
// cout<<"Got chunk of "<<len<<" bytes"<<endl;
if(!len)
break;
+
+ if (maxReceivedBytes > 0 && (maxReceivedBytes - receivedBytes) < (size_t) len)
+ throw std::runtime_error("Reached the maximum number of received bytes in an IXFR delta for zone '"+zone.toString()+"' from master '"+master.toStringWithPort());
+
char reply[len];
readn2(s.getHandle(), reply, len);
+ receivedBytes += len;
MOADNSParser mdp(string(reply, len));
if(mdp.d_header.rcode)
throw std::runtime_error("Got an error trying to IXFR zone '"+zone.toString()+"' from master '"+master.toStringWithPort()+"': "+RCode::to_s(mdp.d_header.rcode));
vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAddress& master, const DNSName& zone,
const DNSRecord& sr, const TSIGTriplet& tt=TSIGTriplet(),
- const ComboAddress* laddr=0);
+ const ComboAddress* laddr=0, size_t maxReceivedBytes=0);
return *this;
}
+
+Logger& Logger::operator<<(const ComboAddress &ca)
+{
+ *this<<ca.toString();
+ return *this;
+}
+
#include "namespaces.hh"
#include "dnsname.hh"
+#include "iputils.hh"
//! The Logger class can be used to log messages in various ways.
class Logger
Logger& operator<<(unsigned long); //!< log an unsigned int
Logger& operator<<(unsigned long long); //!< log an unsigned 64 bit int
Logger& operator<<(const DNSName&);
-
+ Logger& operator<<(const ComboAddress&); //!< log an address
Logger& operator<<(Urgency); //!< set the urgency, << style
Logger& operator<<(std::ostream & (&)(std::ostream &)); //!< this is to recognise the endl, and to commit the log
static int ldp_getRemote(lua_State *L) {
DNSPacket *p=ldp_checkDNSPacket(L);
- lua_pushstring(L, p->getRemote().c_str());
+ lua_pushstring(L, p->getRemote().toString().c_str());
return 1;
}
static int ldp_getRemoteRaw(lua_State *L) {
DNSPacket *p=ldp_checkDNSPacket(L);
- const ComboAddress& ca=p->d_remote;
+ const ComboAddress& ca=p->getRemote();
if(ca.sin4.sin_family == AF_INET) {
lua_pushlstring(L, (const char*)&ca.sin4.sin_addr.s_addr, 4);
}
ifstream ifs(fname);
if(!ifs) {
- theL()<<Logger::Error<<"Unable to read configuration file from '"<<fname<<"': "<<strerror(errno)<<endl;
- return;
+ throw std::runtime_error("Unable to read configuration file from '"+fname+"': "+strerror(errno));
}
d_lw->executeCode(ifs);
try {
Resolver resolver;
uint32_t theirserial;
- resolver.getSoaSerial(p->getRemote(),p->qdomain, &theirserial);
- resolver.resolve(p->getRemote(), p->qdomain, QType::NS, &nsset);
+ resolver.getSoaSerial(p->getRemote().toString(),p->qdomain, &theirserial);
+ resolver.resolve(p->getRemote().toString(), p->qdomain, QType::NS, &nsset);
}
catch(ResolverException &re) {
L<<Logger::Error<<"Error resolving SOA or NS for "<<p->qdomain<<" at: "<< p->getRemote() <<": "<<re.reason<<endl;
return RCode::Refused;
}
- if(!B.superMasterBackend(p->getRemote(), p->qdomain, nsset, &nameserver, &account, &db)) {
+ if(!B.superMasterBackend(p->getRemote().toString(), p->qdomain, nsset, &nameserver, &account, &db)) {
L<<Logger::Error<<"Unable to find backend willing to host "<<p->qdomain<<" for potential supermaster "<<p->getRemote()<<". Remote nameservers: "<<endl;
for(const auto& rr: nsset) {
if(rr.qtype.getCode()==QType::NS)
return RCode::Refused;
}
try {
- db->createSlaveDomain(p->getRemote(), p->qdomain, nameserver, account);
+ db->createSlaveDomain(p->getRemote().toString(), p->qdomain, nameserver, account);
if (tsigkeyname.empty() == false) {
vector<string> meta;
meta.push_back(tsigkeyname.toStringNoDot());
}
}
- if(::arg().contains("trusted-notification-proxy", p->getRemote())) {
+ if(::arg().contains("trusted-notification-proxy", p->getRemote().toString())) {
L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from trusted-notification-proxy "<< p->getRemote()<<endl;
if(di.masters.empty()) {
L<<Logger::Error<<"However, "<<p->qdomain<<" does not have any masters defined"<<endl;
L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" but we are master, rejecting"<<endl;
return RCode::Refused;
}
- else if(!db->isMaster(p->qdomain, p->getRemote())) {
+ else if(!db->isMaster(p->qdomain, p->getRemote().toString())) {
L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" which is not a master"<<endl;
return RCode::Refused;
}
bool needCommit = false;
for(auto i=ret.cbegin(); i!=ret.cend(); ++i) {
- if(!DNSSECOK && (i->d_type == QType::RRSIG || i->d_type==QType::NSEC || i->d_type==QType::NSEC3))
+ if( ! DNSSECOK &&
+ ( i->d_type == QType::NSEC3 ||
+ (
+ ( i->d_type == QType::RRSIG || i->d_type==QType::NSEC ) &&
+ (
+ ( dc->d_mdp.d_qtype != i->d_type && dc->d_mdp.d_qtype != QType::ANY ) ||
+ i->d_place != DNSResourceRecord::ANSWER
+ )
+ )
+ )
+ ) {
continue;
+ }
+
pw.startRecord(i->d_name, i->d_type, i->d_ttl, i->d_class, i->d_place);
if(i->d_type != QType::OPT) // their TTL ain't real
minTTL = min(minTTL, i->d_ttl);
::arg().setSwitch("write-pid","Write a PID file")="yes";
::arg().set("loglevel","Amount of logging. Higher is more. Do not set below 3")="4";
::arg().set("disable-syslog","Disable logging to syslog, useful when running inside a supervisor that logs stdout")="no";
- ::arg().set("log-common-errors","If we should log rather common errors")="yes";
+ ::arg().set("log-common-errors","If we should log rather common errors")="no";
::arg().set("chroot","switch to chroot jail")="";
::arg().set("setgid","If set, change group id to this gid for more security")="";
::arg().set("setuid","If set, change user id to this uid for more security")="";
::arg().setSwitch( "disable-packetcache", "Disable packetcache" )= "no";
::arg().set("edns-subnet-whitelist", "List of netmasks and domains that we should enable EDNS subnet for")="";
::arg().setSwitch( "pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads")="";
- ::arg().setSwitch( "root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist")="no";
+ ::arg().setSwitch( "root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist")="yes";
::arg().setSwitch( "any-to-tcp","Answer ANY queries with tc=1, shunting to TCP" )="no";
::arg().setSwitch( "lowercase-outgoing","Force outgoing questions to lowercase")="no";
::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate")="1680";
TSIGTriplet tt;
int refresh=0;
std::string polName;
+ size_t maxReceivedXFRMBytes = 0;
if(options) {
auto& have = *options;
if(have.count("policyName")) {
if(have.count("refresh")) {
refresh = boost::get<int>(constGet(have,"refresh"));
}
+ if(have.count("maxReceivedMBytes")) {
+ maxReceivedXFRMBytes = static_cast<size_t>(boost::get<int>(constGet(have,"maxReceivedMBytes")));
+ }
}
ComboAddress master(master_, 53);
DNSName zone(zone_);
- auto sr=loadRPZFromServer(master, zone, lci.dfe, polName, defpol, 0, tt);
+ auto sr=loadRPZFromServer(master, zone, lci.dfe, polName, defpol, 0, tt, maxReceivedXFRMBytes * 1024 * 1024);
if(refresh)
sr->d_st.refresh=refresh;
- std::thread t(RPZIXFRTracker, master, zone, polName, tt, sr);
+ std::thread t(RPZIXFRTracker, master, zone, polName, tt, sr, maxReceivedXFRMBytes * 1024 * 1024);
t.detach();
}
catch(std::exception& e) {
MANPAGES=pdns_recursor.1 \
rec_control.1
-dist_man_MANS=$(MANPAGES)
+if HAVE_PANDOC
+ dist_man_MANS=$(MANPAGES)
+endif
+if HAVE_MANPAGES
+ dist_man_MANS=$(MANPAGES)
+endif
if HAVE_PANDOC
$(MANPAGES): %: %.md
$(AM_V_GEN)$(PANDOC) -s -t man $< -o $@
else
-if HAVE_MANPAGES
-#nothing
-else
$(MANPAGES):
echo "You need pandoc to generate the manpages"
exit 1
endif
-endif
if HAVE_SYSTEMD
pdns-recursor.service: pdns-recursor.service.in
}
-void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& polName, const TSIGTriplet& tt, shared_ptr<SOARecordContent> oursr)
+void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& polName, const TSIGTriplet& tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes)
{
int refresh = oursr->d_st.refresh;
for(;;) {
L<<Logger::Info<<"Getting IXFR deltas for "<<zone<<" from "<<master.toStringWithPort()<<", our serial: "<<getRR<SOARecordContent>(dr)->d_st.serial<<endl;
vector<pair<vector<DNSRecord>, vector<DNSRecord> > > deltas;
try {
- deltas = getIXFRDeltas(master, zone, dr, tt);
+ deltas = getIXFRDeltas(master, zone, dr, tt, nullptr, maxReceivedBytes);
} catch(std::runtime_error& e ){
L<<Logger::Warning<<e.what()<<endl;
continue;
AXFRRetriever::AXFRRetriever(const ComboAddress& remote,
const DNSName& domain,
const TSIGTriplet& tt,
- const ComboAddress* laddr)
- : d_tt(tt), d_tsigPos(0), d_nonSignedMessages(0)
+ const ComboAddress* laddr,
+ size_t maxReceivedBytes)
+ : d_tt(tt), d_receivedBytes(0), d_maxReceivedBytes(maxReceivedBytes), d_tsigPos(0), d_nonSignedMessages(0)
{
ComboAddress local;
if (laddr != NULL) {
int len=getLength();
if(len<0)
throw ResolverException("EOF trying to read axfr chunk from remote TCP client");
-
- timeoutReadn(len);
+
+ if (d_maxReceivedBytes > 0 && (d_maxReceivedBytes - d_receivedBytes) < (size_t) len)
+ throw ResolverException("Reached the maximum number of received bytes during AXFR");
+
+ timeoutReadn(len);
+
+ d_receivedBytes += (uint16_t) len;
+
MOADNSParser mdp(d_buf.get(), len);
int err;
AXFRRetriever(const ComboAddress& remote,
const DNSName& zone,
const TSIGTriplet& tt = TSIGTriplet(),
- const ComboAddress* laddr = NULL);
- ~AXFRRetriever();
+ const ComboAddress* laddr = NULL,
+ size_t maxReceivedBytes=0);
+ ~AXFRRetriever();
int getChunk(Resolver::res_t &res, vector<DNSRecord>* records=0);
private:
TSIGTriplet d_tt;
string d_prevMac; // RFC2845 4.4
string d_signData;
+ size_t d_receivedBytes;
+ size_t d_maxReceivedBytes;
uint32_t d_tsigPos;
uint d_nonSignedMessages; // RFC2845 4.4
TSIGRecordContent d_trc;
if (! ::arg().mustDo("dnsupdate"))
return RCode::Refused;
- string msgPrefix="UPDATE (" + itoa(p->d.id) + ") from " + p->getRemote() + " for " + p->qdomain.toLogString() + ": ";
+ string msgPrefix="UPDATE (" + itoa(p->d.id) + ") from " + p->getRemote().toString() + " for " + p->qdomain.toLogString() + ": ";
L<<Logger::Info<<msgPrefix<<"Processing started."<<endl;
// Check permissions - IP based
}
}
-shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& polName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt)
+shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& polName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt, size_t maxReceivedBytes)
{
L<<Logger::Warning<<"Loading RPZ zone '"<<zone<<"' from "<<master.toStringWithPort()<<endl;
if(!tt.name.empty())
L<<Logger::Warning<<"With TSIG key '"<<tt.name<<"' of algorithm '"<<tt.algo<<"'"<<endl;
ComboAddress local= master.sin4.sin_family == AF_INET ? ComboAddress("0.0.0.0") : ComboAddress("::"); // should be configurable
- AXFRRetriever axfr(master, zone, tt, &local);
+ AXFRRetriever axfr(master, zone, tt, &local, maxReceivedBytes);
unsigned int nrecords=0;
Resolver::res_t nop;
vector<DNSRecord> chunk;
#include "dnsrecords.hh"
int loadRPZFromFile(const std::string& fname, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place);
-std::shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt);
+std::shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt, size_t maxReceivedBytes);
void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, const std::string& policyName, bool addOrRemove, boost::optional<DNSFilterEngine::Policy> defpol, int place);
-void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& policyName, const TSIGTriplet &tt, shared_ptr<SOARecordContent> oursr);
+void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& policyName, const TSIGTriplet &tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes);
DNSRecord dr;
dr.d_content = std::make_shared<SOARecordContent>(DNSName("."), DNSName("."), st);
- auto deltas = getIXFRDeltas(remote, domain, dr, tt, laddr.sin4.sin_family ? &laddr : 0);
+ auto deltas = getIXFRDeltas(remote, domain, dr, tt, laddr.sin4.sin_family ? &laddr : 0, ((size_t) ::arg().asNum("xfr-max-received-mbytes")) * 1024 * 1024);
zs.numDeltas=deltas.size();
// cout<<"Got "<<deltas.size()<<" deltas from serial "<<di.serial<<", applying.."<<endl;
vector<DNSResourceRecord> doAxfr(const ComboAddress& raddr, const DNSName& domain, const TSIGTriplet& tt, const ComboAddress& laddr, scoped_ptr<AuthLua>& pdl, ZoneStatus& zs)
{
vector<DNSResourceRecord> rrs;
- AXFRRetriever retriever(raddr, domain, tt, (laddr.sin4.sin_family == 0) ? NULL : &laddr);
+ AXFRRetriever retriever(raddr, domain, tt, (laddr.sin4.sin_family == 0) ? NULL : &laddr, ((size_t) ::arg().asNum("xfr-max-received-mbytes")) * 1024 * 1024);
Resolver::res_t recs;
bool first=true;
bool firstNSEC3{true};
}
}
- if(doCNAMECacheCheck(qname,qtype,ret,depth,res)) // will reroute us if needed
+ if(qtype != QType::DS && doCNAMECacheCheck(qname,qtype,ret,depth,res)) // will reroute us if needed
return res;
if(doCacheCheck(qname,qtype,ret,depth,res)) // we done
if(logDNSQueries) {
string remote;
if(packet->hasEDNSSubnet())
- remote = packet->getRemote() + "<-" + packet->getRealRemote().toString();
+ remote = packet->getRemote().toString() + "<-" + packet->getRealRemote().toString();
else
- remote = packet->getRemote();
+ remote = packet->getRemote().toString();
L << Logger::Notice<<"TCP Remote "<< remote <<" wants '" << packet->qdomain<<"|"<<packet->qtype.getName() <<
"', do = " <<packet->d_dnssecOk <<", bufsize = "<< packet->getMaxReplyLen()<<": ";
}
vector<string> nsips=fns.lookup(j, B);
for(vector<string>::const_iterator k=nsips.begin();k!=nsips.end();++k) {
// cerr<<"got "<<*k<<" from AUTO-NS"<<endl;
- if(*k == q->getRemote())
+ if(*k == q->getRemote().toString())
{
// cerr<<"got AUTO-NS hit"<<endl;
L<<Logger::Warning<<"AXFR of domain '"<<q->qdomain<<"' allowed: client IP "<<q->getRemote()<<" is in NSset"<<endl;
extern CommunicatorClass Communicator;
- if(Communicator.justNotified(q->qdomain, q->getRemote())) { // we just notified this ip
+ if(Communicator.justNotified(q->qdomain, q->getRemote().toString())) { // we just notified this ip
L<<Logger::Warning<<"Approved AXFR of '"<<q->qdomain<<"' from recently notified slave "<<q->getRemote()<<endl;
return true;
}
return state;
}
+/*
+ * This inline possibly sets currentState based on the new state. It will only
+ * set it to Secure iff the newState is Secure and mayUpgradeToSecure == true.
+ * This should be set by the calling function when checking more than one record
+ * and this is not the first record, this way, we can never go *back* to Secure
+ * from an Insecure vState
+ */
+inline void processNewState(vState& currentState, const vState& newState, bool& hadNTA, const bool& mayUpgradeToSecure)
+{
+ if (mayUpgradeToSecure && newState == Secure)
+ currentState = Secure;
+
+ if (newState == Insecure || newState == NTA) // We can never go back to Secure
+ currentState = Insecure;
+
+ if (newState == NTA)
+ hadNTA = true;
+}
+
vState validateRecords(const vector<DNSRecord>& recs)
{
if(recs.empty())
SRRecordOracle sro;
vState state=Insecure;
+ bool hadNTA = false;
if(numsigs) {
+ bool first = true;
for(const auto& csp : cspmap) {
for(const auto& sig : csp.second.signatures) {
- state = getKeysFor(sro, sig->d_signer, keys); // XXX check validity here
- if(state == NTA) {
- increaseDNSSECStateCounter(state);
- return Insecure;
- }
+ vState newState = getKeysFor(sro, sig->d_signer, keys); // XXX check validity here
+
+ if (newState == Bogus) // No hope
+ return increaseDNSSECStateCounter(Bogus);
+
+ processNewState(state, newState, hadNTA, first);
+
+ first = false;
+
LOG("! state = "<<vStates[state]<<", now have "<<keys.size()<<" keys"<<endl);
for(const auto& k : keys) {
LOG("Key: "<<k.getZoneRepresentation()<< " {tag="<<k.getTag()<<"}"<<endl);
}
- // this sort of charges on and 'state' ends up as the last thing to have been checked
- // maybe not the right idea
}
}
- if(state == Bogus)
- return increaseDNSSECStateCounter(state);
validateWithKeySet(cspmap, validrrsets, keys);
}
else {
LOG("! no sigs, hoping for Insecure status of "<<recs.begin()->d_name<<endl);
- state = getKeysFor(sro, recs.begin()->d_name, keys); // um WHAT DOES THIS MEAN - try first qname??
-
- LOG("! state = "<<vStates[state]<<", now have "<<keys.size()<<" keys "<<endl);
-
+
+ bool first = true;
+ for(const auto& rec : recs) {
+ vState newState = getKeysFor(sro, rec.d_name, keys);
+
+ if (newState == Bogus) // We're done
+ return increaseDNSSECStateCounter(Bogus);
+
+ processNewState(state, newState, hadNTA, first);
+ first = false;
+
+ LOG("! state = "<<vStates[state]<<", now have "<<keys.size()<<" keys "<<endl);
+ }
return increaseDNSSECStateCounter(state);
}
-
+
LOG("Took "<<sro.d_queries<<" queries"<<endl);
if(validrrsets.size() == cspmap.size())// shortcut - everything was ok
return increaseDNSSECStateCounter(Secure);
- if(keys.empty())
+ if(state == Insecure || keys.empty()) {
+ if (hadNTA) {
+ increaseDNSSECStateCounter(NTA);
+ return Insecure;
+ }
return increaseDNSSECStateCounter(Insecure);
+ }
#if 0
cerr<<"! validated "<<validrrsets.size()<<" RRsets out of "<<cspmap.size()<<endl;
return increaseDNSSECStateCounter(Bogus);
}
}
-
return increaseDNSSECStateCounter(Insecure);
}
}
vector<string> labels = zone.getRawLabels();
- vState state;
-
- state = Indeterminate;
typedef std::multimap<uint16_t, DSRecordContent> dsmap_t;
dsmap_t dsmap;
keyset_t validkeys;
DNSName qname = lowestTA;
- state = Secure; // the lowest Trust Anchor is secure
+ vState state = Secure; // the lowest Trust Anchor is secure
while(zone.isPartOf(qname))
{
LOG("\t"<<r->getZoneRepresentation()<<endl);
auto nsec = std::dynamic_pointer_cast<NSECRecordContent>(r);
if(nsec) {
- if(v.first.first == qname && !nsec->d_set.count(QType::DS))
+ if(v.first.first == qname && !nsec->d_set.count(QType::DS)) {
+ LOG("Denies existence of DS!"<<endl);
return Insecure;
+ }
else if(v.first.first.canonCompare(qname) && qname.canonCompare(nsec->d_next) ) {
LOG("Did not find DS for this level, trying one lower"<<endl);
goto skipLevel;
(_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
self.assertEquals(receivedResponse, expectedResponse)
+class TestAdvancedLabelsCountRule(DNSDistTest):
+
+ _config_template = """
+ addAction(QNameLabelsCountRule(5,6), RCodeAction(dnsdist.REFUSED))
+ newServer{address="127.0.0.1:%s"}
+ """
+
+ def testAdvancedLabelsCountRule(self):
+ """
+ Advanced: QNameLabelsCountRule(5,6)
+ """
+ # 6 labels, we should be fine
+ name = 'ok.labelscount.advanced.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ response = dns.message.make_response(query)
+ rrset = dns.rrset.from_text(name,
+ 3600,
+ dns.rdataclass.IN,
+ dns.rdatatype.A,
+ '192.0.2.1')
+ response.answer.append(rrset)
+
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(response, receivedResponse)
+
+ (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(response, receivedResponse)
+
+ # more than 6 labels, the query should be refused
+ name = 'not.ok.labelscount.advanced.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ expectedResponse = dns.message.make_response(query)
+ expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+ (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, expectedResponse)
+
+ (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, expectedResponse)
+
+ # less than 5 labels, the query should be refused
+ name = 'labelscountadvanced.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ expectedResponse = dns.message.make_response(query)
+ expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+ (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, expectedResponse)
+
+ (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, expectedResponse)
+
+class TestAdvancedWireLengthRule(DNSDistTest):
+
+ _config_template = """
+ addAction(QNameWireLengthRule(54,56), RCodeAction(dnsdist.REFUSED))
+ newServer{address="127.0.0.1:%s"}
+ """
+
+ def testAdvancedWireLengthRule(self):
+ """
+ Advanced: QNameWireLengthRule(54,56)
+ """
+ name = 'longenough.qnamewirelength.advanced.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ response = dns.message.make_response(query)
+ rrset = dns.rrset.from_text(name,
+ 3600,
+ dns.rdataclass.IN,
+ dns.rdatatype.A,
+ '192.0.2.1')
+ response.answer.append(rrset)
+
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(response, receivedResponse)
+
+ (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(response, receivedResponse)
+
+ # too short, the query should be refused
+ name = 'short.qnamewirelength.advanced.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ expectedResponse = dns.message.make_response(query)
+ expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+ (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, expectedResponse)
+
+ (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, expectedResponse)
+
+ # too long, the query should be refused
+ name = 'toolongtobevalid.qnamewirelength.advanced.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ expectedResponse = dns.message.make_response(query)
+ expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+ (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, expectedResponse)
+
+ (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+ self.assertEquals(receivedResponse, expectedResponse)
insecure-formerr.example. 3600 IN NS ns1.insecure-formerr.example.
ns1.insecure-formerr.example. 3600 IN A {prefix}.2
+
+islandofsecurity.example. 3600 IN NS ns1.islandofsecurity.example.
+ns1.islandofsecurity.example. 3600 IN A {prefix}.9
""",
'secure.example': """
secure.example. 3600 IN SOA {soa}
cname.secure.example. 3600 IN CNAME host1.secure.example.
cname-to-insecure.secure.example. 3600 IN CNAME node1.insecure.example.
cname-to-bogus.secure.example. 3600 IN CNAME ted.bogus.example.
+cname-to-islandofsecurity.secure.example. 3600 IN CNAME node1.islandofsecurity.example.
host1.sub.secure.example. 3600 IN A 192.0.2.11
ns1.secure.optout.example. 3600 IN A {prefix}.15
node1.secure.optout.example. 3600 IN A 192.0.2.8
+ """,
+ 'islandofsecurity.example': """
+islandofsecurity.example. 3600 IN SOA {soa}
+islandofsecurity.example. 3600 IN NS ns1.islandofsecurity.example.
+ns1.islandofsecurity.example. 3600 IN A {prefix}.9
+
+node1.islandofsecurity.example. 3600 IN A 192.0.2.20
"""
}
Private-key-format: v1.2
Algorithm: 13 (ECDSAP256SHA256)
PrivateKey: xcNUxt1Knj14A00lKQFDboluiJyM2f7FxpgsQaQ3AQ4=
+ """,
+
+ 'islandofsecurity.example': """
+Private-key-format: v1.2
+Algorithm: 13 (ECDSAP256SHA256)
+PrivateKey: o9F5iix8V68tnMcuOaM2Lt8XXhIIY//SgHIHEePk6cM=
"""
}
# go into the _zones's zonecontent
_auth_zones = {
'8': ['ROOT'],
- '9': ['secure.example'],
+ '9': ['secure.example', 'islandofsecurity.example'],
'10': ['example'],
'11': ['example'],
'12': ['bogus.example'],
self.assertRcodeEqual(resPTR, dns.rcode.NOERROR)
self.assertRRsetInAnswer(resPTR, expectedPTR)
+
+ def testIslandOfSecurity(self):
+ query = dns.message.make_query('cname-to-islandofsecurity.secure.example.', 'A', want_dnssec=True)
+
+ expectedCNAME = dns.rrset.from_text('cname-to-islandofsecurity.secure.example.', 0, 'IN', 'CNAME', 'node1.islandofsecurity.example.')
+ expectedA = dns.rrset.from_text('node1.islandofsecurity.example.', 0, 'IN', 'A', '192.0.2.20')
+
+ res = self.sendUDPQuery(query)
+
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertRRsetInAnswer(res, expectedA)
+