* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "dnsdist.hh"
-#include "dnsdist-healthchecks.hh"
-#include "dnsdist-prometheus.hh"
-#include "sstuff.hh"
-#include "ext/json11/json11.hpp"
-#include "ext/incbin/incbin.h"
-#include "dolog.hh"
-#include <thread>
-#include "threadname.hh"
+#include <boost/format.hpp>
#include <sstream>
-#include <yahttp/yahttp.hpp>
-#include "namespaces.hh"
#include <sys/time.h>
#include <sys/resource.h>
+#include <thread>
+
#include "ext/incbin/incbin.h"
-#include "htmlfiles.h"
+#include "ext/json11/json11.hpp"
+#include <yahttp/yahttp.hpp>
+
#include "base64.hh"
+#include "dnsdist.hh"
+#include "dnsdist-healthchecks.hh"
+#include "dnsdist-prometheus.hh"
+#include "dnsdist-web.hh"
+#include "dolog.hh"
#include "gettime.hh"
-#include <boost/format.hpp>
+#include "htmlfiles.h"
+#include "threadname.hh"
+#include "sstuff.hh"
bool g_apiReadWrite{false};
WebserverConfig g_webserverConfig;
{ "dyn-blocked", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because of a dynamic block")},
{ "dyn-block-nmg-size", MetricDefinition(PrometheusMetricType::gauge, "Number of dynamic blocks entries") },
{ "security-status", MetricDefinition(PrometheusMetricType::gauge, "Security status of this software. 0=unknown, 1=OK, 2=upgrade recommended, 3=upgrade mandatory") },
+ { "doh-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of DoH queries dropped because the internal pipe used to distribute queries was full") },
+ { "doh-response-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of DoH responses dropped because the internal pipe used to distribute responses was full") },
{ "udp-in-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp InErrors") },
{ "udp-noport-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp NoPorts") },
{ "udp-recvbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp RcvbufErrors") },
return false;
}
+static bool isClientAllowedByACL(const ComboAddress& remote)
+{
+ std::lock_guard<std::mutex> lock(g_webserverConfig.lock);
+ return g_webserverConfig.acl.match(remote);
+}
+
static void handleCORS(const YaHTTP::Request& req, YaHTTP::Response& resp)
{
const auto origin = req.headers.find("Origin");
struct timespec now;
gettime(&now);
for(const auto& e: *nmg) {
- if(now < e->second.until ) {
+ if(now < e.second.until ) {
Json::object thing{
- {"reason", e->second.reason},
- {"seconds", (double)(e->second.until.tv_sec - now.tv_sec)},
- {"blocks", (double)e->second.blocks},
- {"action", DNSAction::typeToString(e->second.action != DNSAction::Action::None ? e->second.action : g_dynBlockAction) },
- {"warning", e->second.warning }
+ {"reason", e.second.reason},
+ {"seconds", (double)(e.second.until.tv_sec - now.tv_sec)},
+ {"blocks", (double)e.second.blocks},
+ {"action", DNSAction::typeToString(e.second.action != DNSAction::Action::None ? e.second.action : g_dynBlockAction) },
+ {"warning", e.second.warning }
};
- obj.insert({e->first.toString(), thing});
+ obj.insert({e.first.toString(), thing});
}
}
}
// Latency histogram buckets
- output << "# HELP dnsdist_latency Histogram of responses by latency\n";
+ output << "# HELP dnsdist_latency Histogram of responses by latency (in milliseconds)\n";
output << "# TYPE dnsdist_latency histogram\n";
uint64_t latency_amounts = g_stats.latency0_1;
output << "dnsdist_latency_bucket{le=\"1\"} " << latency_amounts << "\n";
for (const auto& state : *states) {
string serverName;
- if (state->name.empty())
+ if (state->getName().empty())
serverName = state->remote.toStringWithPort();
else
serverName = state->getName();
Json::object server{
{"id", num++},
- {"name", a->name},
+ {"name", a->getName()},
{"address", a->remote.toStringWithPort()},
{"state", status},
{"qps", (double)a->queryLoad},
g_webserverConfig.password = password;
}
+void setWebserverACL(const std::string& acl)
+{
+ NetmaskGroup newACL;
+ newACL.toMasks(acl);
+
+ {
+ std::lock_guard<std::mutex> lock(g_webserverConfig.lock);
+ g_webserverConfig.acl = std::move(newACL);
+ }
+}
+
void setWebserverCustomHeaders(const boost::optional<std::map<std::string, std::string> > customHeaders)
{
std::lock_guard<std::mutex> lock(g_webserverConfig.lock);
{
setThreadName("dnsdist/webserv");
warnlog("Webserver launched on %s", local.toStringWithPort());
+
for(;;) {
try {
ComboAddress remote(local);
int fd = SAccept(sock, remote);
- vinfolog("Got connection from %s", remote.toStringWithPort());
+ if (!isClientAllowedByACL(remote)) {
+ vinfolog("Connection to webserver from client %s is not allowed, closing", remote.toStringWithPort());
+ close(fd);
+ continue;
+ }
+ vinfolog("Got a connection to the webserver from %s", remote.toStringWithPort());
std::thread t(connectionThread, fd, remote);
t.detach();
}
- catch(std::exception& e) {
+ catch (const std::exception& e) {
errlog("Had an error accepting new webserver connection: %s", e.what());
}
}