diff --git a/collectors/statsd.plugin/statsd.c b/collectors/statsd.plugin/statsd.c
index 7468f2746f..e8e6301a8b 100644
--- a/collectors/statsd.plugin/statsd.c
+++ b/collectors/statsd.plugin/statsd.c
@@ -1014,7 +1014,8 @@ void *statsd_collector_thread(void *ptr) {
             , statsd_rcv_callback
             , statsd_snd_callback
             , statsd_timer_callback
-            , NULL
+            , NULL                     // No access control pattern
+            , 0                        // No dns lookups for access control pattern
             , (void *)d
             , 0                        // tcp request timeout, 0 = disabled
             , statsd.tcp_idle_timeout  // tcp idle timeout, 0 = disabled
diff --git a/daemon/main.c b/daemon/main.c
index 0e56654db2..1bb8546a90 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -96,22 +96,69 @@ void web_server_threading_selection(void) {
     }
 }
 
-void web_server_config_options(void) {
-    web_client_timeout = (int) config_get_number(CONFIG_SECTION_WEB, "disconnect idle clients after seconds", web_client_timeout);
-    web_client_first_request_timeout = (int) config_get_number(CONFIG_SECTION_WEB, "timeout for first request", web_client_first_request_timeout);
-    web_client_streaming_rate_t = config_get_number(CONFIG_SECTION_WEB, "accept a streaming request every seconds", web_client_streaming_rate_t);
+int make_dns_decision(const char *section_name, const char *config_name, const char *default_value, SIMPLE_PATTERN *p)
+{
+    char *value = config_get(section_name,config_name,default_value);
+    if(!strcmp("yes",value))
+        return 1;
+    if(!strcmp("no",value))
+        return 0;
+    if(strcmp("heuristic",value))
+        error("Invalid configuration option '%s' for '%s'/'%s'. Valid options are 'yes', 'no' and 'heuristic'. Proceeding with 'heuristic'",
+              value, section_name, config_name);
+    return simple_pattern_is_potential_name(p);
+}
 
-    respect_web_browser_do_not_track_policy = config_get_boolean(CONFIG_SECTION_WEB, "respect do not track policy", respect_web_browser_do_not_track_policy);
+void web_server_config_options(void)
+{
+    web_client_timeout =
+        (int)config_get_number(CONFIG_SECTION_WEB, "disconnect idle clients after seconds", web_client_timeout);
+    web_client_first_request_timeout =
+        (int)config_get_number(CONFIG_SECTION_WEB, "timeout for first request", web_client_first_request_timeout);
+    web_client_streaming_rate_t =
+        config_get_number(CONFIG_SECTION_WEB, "accept a streaming request every seconds", web_client_streaming_rate_t);
+
+    respect_web_browser_do_not_track_policy =
+        config_get_boolean(CONFIG_SECTION_WEB, "respect do not track policy", respect_web_browser_do_not_track_policy);
     web_x_frame_options = config_get(CONFIG_SECTION_WEB, "x-frame-options response header", "");
-    if(!*web_x_frame_options) web_x_frame_options = NULL;
+    if(!*web_x_frame_options)
+        web_x_frame_options = NULL;
 
-    web_allow_connections_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow connections from", "localhost *"), NULL, SIMPLE_PATTERN_EXACT);
-    web_allow_dashboard_from   = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow dashboard from", "localhost *"), NULL, SIMPLE_PATTERN_EXACT);
-    web_allow_badges_from      = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow badges from", "*"), NULL, SIMPLE_PATTERN_EXACT);
-    web_allow_registry_from    = simple_pattern_create(config_get(CONFIG_SECTION_REGISTRY, "allow from", "*"), NULL, SIMPLE_PATTERN_EXACT);
-    web_allow_streaming_from   = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow streaming from", "*"), NULL, SIMPLE_PATTERN_EXACT);
-    web_allow_netdataconf_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow netdata.conf from", "localhost fd* 10.* 192.168.* 172.16.* 172.17.* 172.18.* 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.* 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.* 172.31.*"), NULL, SIMPLE_PATTERN_EXACT);
-    web_allow_mgmt_from        = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow management from", "localhost"), NULL, SIMPLE_PATTERN_EXACT);
+    web_allow_connections_from =
+        simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow connections from", "localhost *"),
+                              NULL, SIMPLE_PATTERN_EXACT);
+    web_allow_connections_dns  =
+        make_dns_decision(CONFIG_SECTION_WEB, "allow connections by dns", "heuristic", web_allow_connections_from);
+    web_allow_dashboard_from   =
+        simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow dashboard from", "localhost *"),
+                              NULL, SIMPLE_PATTERN_EXACT);
+    web_allow_dashboard_dns    =
+        make_dns_decision(CONFIG_SECTION_WEB, "allow dashboard by dns", "heuristic", web_allow_dashboard_from);
+    web_allow_badges_from      =
+        simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow badges from", "*"), NULL, SIMPLE_PATTERN_EXACT);
+    web_allow_badges_dns       =
+        make_dns_decision(CONFIG_SECTION_WEB, "allow badges by dns", "heuristic", web_allow_badges_from);
+    web_allow_registry_from    =
+        simple_pattern_create(config_get(CONFIG_SECTION_REGISTRY, "allow from", "*"), NULL, SIMPLE_PATTERN_EXACT);
+    web_allow_registry_dns     = make_dns_decision(CONFIG_SECTION_REGISTRY, "allow by dns", "heuristic",
+                                                   web_allow_registry_from);
+    web_allow_streaming_from   = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow streaming from", "*"),
+                                                       NULL, SIMPLE_PATTERN_EXACT);
+    web_allow_streaming_dns    = make_dns_decision(CONFIG_SECTION_WEB, "allow streaming by dns", "heuristic",
+                                                   web_allow_streaming_from);
+    // Note the default is not heuristic, the wildcards could match DNS but the intent is ip-addresses.
+    web_allow_netdataconf_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow netdata.conf from",
+                                                       "localhost fd* 10.* 192.168.* 172.16.* 172.17.* 172.18.*"
+                                                       " 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.*"
+                                                       " 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.*"
+                                                       " 172.31.*"), NULL, SIMPLE_PATTERN_EXACT);
+    web_allow_netdataconf_dns  =
+        make_dns_decision(CONFIG_SECTION_WEB, "allow netdata.conf by dns", "no", web_allow_mgmt_from);
+    web_allow_mgmt_from        =
+        simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow management from", "localhost"),
+                              NULL, SIMPLE_PATTERN_EXACT);
+    web_allow_mgmt_dns         =
+        make_dns_decision(CONFIG_SECTION_WEB, "allow management by dns","heuristic",web_allow_mgmt_from);
 
 
 #ifdef NETDATA_WITH_ZLIB
diff --git a/libnetdata/simple_pattern/simple_pattern.c b/libnetdata/simple_pattern/simple_pattern.c
index 57b0aecc82..f5175a796c 100644
--- a/libnetdata/simple_pattern/simple_pattern.c
+++ b/libnetdata/simple_pattern/simple_pattern.c
@@ -260,3 +260,74 @@ void simple_pattern_free(SIMPLE_PATTERN *list) {
 
     free_pattern(((struct simple_pattern *)list));
 }
+
+/* Debugging patterns
+
+   This code should be dead - it is useful for debugging but should not be called by production code.
+   Feel free to comment it out, but please leave it in the file.
+*/
+extern void simple_pattern_dump(uint64_t debug_type, SIMPLE_PATTERN *p)
+{
+    struct simple_pattern *root = (struct simple_pattern *)p;
+    if(root==NULL) {
+        debug(debug_type,"dump_pattern(NULL)");
+        return;
+    }
+    debug(debug_type,"dump_pattern(%p) child=%p next=%p mode=%d match=%s", root, root->child, root->next, root->mode,
+          root->match);
+    if(root->child!=NULL)
+        simple_pattern_dump(debug_type, (SIMPLE_PATTERN*)root->child);
+    if(root->next!=NULL)
+        simple_pattern_dump(debug_type, (SIMPLE_PATTERN*)root->next);
+}
+
+/* Heuristic: decide if the pattern could match a DNS name.
+
+   Although this functionality is used directly by socket.c:connection_allowed() it must be in this file
+   because of the SIMPLE_PATTERN/simple_pattern structure hiding.
+   Based on RFC952 / RFC1123. We need to decide if the pattern may match a DNS name, or not. For the negative
+   cases we need to be sure that it can only match an ipv4 or ipv6 address:
+     * IPv6 addresses contain ':', which are illegal characters in DNS.
+     * IPv4 addresses cannot contain alpha- characters.
+     * DNS TLDs must be alphanumeric to distinguish from IPv4.
+   Some patterns (e.g. "*a*" ) could match multiple cases (i.e. DNS or IPv6).
+   Some patterns will be awkward (e.g. "192.168.*") as they look like they are intended to match IPv4-only
+   but could match DNS (i.e. "192.168.com" is a valid name).
+*/
+static void scan_is_potential_name(struct simple_pattern *p, int *alpha, int *colon, int *wildcards)
+{
+    while (p) {
+        if (p->match) {
+            if(p->mode == SIMPLE_PATTERN_EXACT && !strcmp("localhost", p->match)) {
+                p = p->child;
+                continue;
+            }
+            char const *scan = p->match;
+            while (*scan != 0) {
+                if ((*scan >= 'a' && *scan <= 'z') || (*scan >= 'A' && *scan <= 'Z'))
+                    *alpha = 1;
+                if (*scan == ':')
+                    *colon = 1;
+                scan++;
+            }
+            if (p->mode != SIMPLE_PATTERN_EXACT)
+                *wildcards = 1;
+            p = p->child;
+        }
+    }
+}
+
+extern int simple_pattern_is_potential_name(SIMPLE_PATTERN *p)
+{
+    int alpha=0, colon=0, wildcards=0;
+    struct simple_pattern *root = (struct simple_pattern*)p;
+    while (root != NULL) {
+        if (root->match != NULL) {
+            scan_is_potential_name(root, &alpha, &colon, &wildcards);
+        }
+        if (root->mode != SIMPLE_PATTERN_EXACT)
+            wildcards = 1;
+        root = root->next;
+    }
+    return (alpha || wildcards) && !colon;
+}
diff --git a/libnetdata/simple_pattern/simple_pattern.h b/libnetdata/simple_pattern/simple_pattern.h
index b96a018efe..cb5e7699dd 100644
--- a/libnetdata/simple_pattern/simple_pattern.h
+++ b/libnetdata/simple_pattern/simple_pattern.h
@@ -30,4 +30,7 @@ extern int simple_pattern_matches_extract(SIMPLE_PATTERN *list, const char *str,
 // list can be NULL, in which case, this does nothing.
 extern void simple_pattern_free(SIMPLE_PATTERN *list);
 
+extern void simple_pattern_dump(uint64_t debug_type, SIMPLE_PATTERN *p) ;
+extern int simple_pattern_is_potential_name(SIMPLE_PATTERN *p) ;
+
 #endif //NETDATA_SIMPLE_PATTERN_H
diff --git a/libnetdata/socket/socket.c b/libnetdata/socket/socket.c
index fa1414dc0c..2289bf4c46 100644
--- a/libnetdata/socket/socket.c
+++ b/libnetdata/socket/socket.c
@@ -1007,13 +1007,16 @@ int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) {
  *                        of *writable* bytes (i.e. be aware of the strdup used to compact the pollinfo).
  */
 extern int connection_allowed(int fd, char *client_ip, char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list,
-                              const char *patname) {
+                              const char *patname, int allow_dns)
+{
+    debug(D_LISTENER,"checking %s... (allow_dns=%d)", patname, allow_dns);
     if (!access_list)
         return 1;
     if (simple_pattern_matches(access_list, client_ip))
         return 1;
     // If the hostname is unresolved (and needed) then attempt the DNS lookups.
-    if (client_host[0]==0)
+    //if (client_host[0]==0 && simple_pattern_is_potential_name(access_list))
+    if (client_host[0]==0 && allow_dns)
     {
         struct sockaddr_storage sadr;
         socklen_t addrlen = sizeof(sadr);
@@ -1021,8 +1024,8 @@ extern int connection_allowed(int fd, char *client_ip, char *client_host, size_t
         if (err != 0 ||
             (err = getnameinfo((struct sockaddr *)&sadr, addrlen, client_host, (socklen_t)hostsize,
                               NULL, 0, NI_NAMEREQD)) != 0) {
-            error("Incoming connection on '%s' does not match a numeric pattern, "
-                  "and host could not be resolved (err=%s)", client_ip, gai_strerror(err));
+            error("Incoming %s on '%s' does not match a numeric pattern, and host could not be resolved (err=%s)",
+                  patname, client_ip, gai_strerror(err));
             if (hostsize >= 8)
                 strcpy(client_host,"UNKNOWN");
             return 0;
@@ -1074,9 +1077,8 @@ extern int connection_allowed(int fd, char *client_ip, char *client_host, size_t
 
 // --------------------------------------------------------------------------------------------------------------------
 // accept_socket() - accept a socket and store client IP and port
-
 int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize,
-                  char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list) {
+                  char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list, int allow_dns) {
     struct sockaddr_storage sadr;
     socklen_t addrlen = sizeof(sadr);
 
@@ -1088,7 +1090,7 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
             strncpyz(client_ip, "UNKNOWN", ipsize - 1);
             strncpyz(client_port, "UNKNOWN", portsize - 1);
         }
-        if(!strcmp(client_ip, "127.0.0.1") || !strcmp(client_ip, "::1")) {
+        if (!strcmp(client_ip, "127.0.0.1") || !strcmp(client_ip, "::1")) {
             strncpy(client_ip, "localhost", ipsize);
             client_ip[ipsize - 1] = '\0';
         }
@@ -1126,7 +1128,7 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
                 debug(D_LISTENER, "New UNKNOWN web client from %s port %s on socket %d.", client_ip, client_port, fd);
                 break;
         }
-        if(!connection_allowed(nfd, client_ip, client_host, hostsize, access_list, "connection")) {
+        if (!connection_allowed(nfd, client_ip, client_host, hostsize, access_list, "connection", allow_dns)) {
             errno = 0;
             error("Permission denied for client '%s', port '%s'", client_ip, client_port);
             close(nfd);
@@ -1135,7 +1137,7 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
         }
     }
 #ifdef HAVE_ACCEPT4
-    else if(errno == ENOSYS)
+    else if (errno == ENOSYS)
         error("netdata has been compiled with the assumption that the system has the accept4() call, but it is not here. Recompile netdata like this: ./configure --disable-accept4 ...");
 #endif
 
@@ -1444,7 +1446,7 @@ static void poll_events_process(POLLJOB *p, POLLINFO *pi, struct pollfd *pf, sho
 
                         debug(D_POLLFD, "POLLFD: LISTENER: calling accept4() slot %zu (fd %d)", i, fd);
                         nfd = accept_socket(fd, SOCK_NONBLOCK, client_ip, INET6_ADDRSTRLEN, client_port, NI_MAXSERV,
-                                            client_host, NI_MAXHOST, p->access_list);
+                                            client_host, NI_MAXHOST, p->access_list, p->allow_dns);
                         if (unlikely(nfd < 0)) {
                             // accept failed
 
@@ -1562,6 +1564,7 @@ void poll_events(LISTEN_SOCKETS *sockets
         , int   (*snd_callback)(POLLINFO * /*pi*/, short int * /*events*/)
         , void  (*tmr_callback)(void * /*timer_data*/)
         , SIMPLE_PATTERN *access_list
+        , int allow_dns
         , void *data
         , time_t tcp_request_timeout_seconds
         , time_t tcp_idle_timeout_seconds
@@ -1592,6 +1595,7 @@ void poll_events(LISTEN_SOCKETS *sockets
             .checks_every = (tcp_idle_timeout_seconds / 3) + 1,
 
             .access_list = access_list,
+            .allow_dns   = allow_dns,
 
             .timer_milliseconds = timer_milliseconds,
             .timer_data = timer_data,
diff --git a/libnetdata/socket/socket.h b/libnetdata/socket/socket.h
index 227f054345..eb09b3f9a7 100644
--- a/libnetdata/socket/socket.h
+++ b/libnetdata/socket/socket.h
@@ -73,9 +73,9 @@ extern int sock_enlarge_in(int fd);
 extern int sock_enlarge_out(int fd);
 
 extern int connection_allowed(int fd, char *client_ip, char *client_host, size_t hostsize,
-                              SIMPLE_PATTERN *access_list, const char *patname);
+                              SIMPLE_PATTERN *access_list, const char *patname, int allow_dns);
 extern int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize,
-                         char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list);
+                         char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list, int allow_dns);
 
 #ifndef HAVE_ACCEPT4
 extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
@@ -155,6 +155,7 @@ struct poll {
     struct pollinfo *first_free;
 
     SIMPLE_PATTERN *access_list;
+    int allow_dns;
 
     void *(*add_callback)(POLLINFO *pi, short int *events, void *data);
     void  (*del_callback)(POLLINFO *pi);
@@ -193,6 +194,7 @@ extern void poll_events(LISTEN_SOCKETS *sockets
         , int   (*snd_callback)(POLLINFO *pi, short int *events)
         , void  (*tmr_callback)(void *timer_data)
         , SIMPLE_PATTERN *access_list
+        , int allow_dns
         , void *data
         , time_t tcp_request_timeout_seconds
         , time_t tcp_idle_timeout_seconds
diff --git a/registry/README.md b/registry/README.md
index f852809bec..205937ba40 100644
--- a/registry/README.md
+++ b/registry/README.md
@@ -122,6 +122,23 @@ Netdata v1.9+ support limiting access to the registry from given IPs, like this:
 
 Keep in mind that connections to Netdata API ports are filtered by `[web].allow connections from`. So, IPs allowed by `[registry].allow from` should also be allowed by `[web].allow connection from`.
 
+The patterns can be matches over IP addresses or FQDN of the host.
+In order to check the FQDN of the connection without opening the Netdata agent to DNS-spoofing, a reverse-dns record
+must be setup for the connecting host. At connection time the reverse-dns of the peer IP address is resolved, and
+a forward DNS resolution is made to validate the IP address against the name-pattern.
+
+Please note that this process can be expensive on a machine that is serving many connections. The behaviour of
+the pattern matching can be controlled with the following setting:
+```
+[registry]
+    allow by dns = heuristic
+```
+
+The settings are:
+* `yes` allows the pattern to match DNS names.
+* `no` disables DNS matching for the patterns (they only match IP addresses).
+* `heuristic` will estimate if the patterns should match FQDNs by the presence or absence of `:`s or alpha-characters.
+
 ### Where is the registry database stored?
 
 `/var/lib/netdata/registry/*.db`
diff --git a/web/server/README.md b/web/server/README.md
index 9f47cb8d93..4866173545 100644
--- a/web/server/README.md
+++ b/web/server/README.md
@@ -149,7 +149,7 @@ Netdata supports access lists in `netdata.conf`:
 	allow management from = localhost
 ```
 
-`*` does string matches on the IPs of the clients.
+`*` does string matches on the IPs or FQDNs of the clients.
 
 -   `allow connections from` matches anyone that connects on the Netdata port(s).
      So, if someone is not allowed, it will be connected and disconnected immediately, without reading even
@@ -169,6 +169,26 @@ Netdata supports access lists in `netdata.conf`:
 
 -   `allow management from` checks the IPs to allow API management calls. Management via the API is currently supported for [health](../api/health/#health-management-api)
 
+In order to check the FQDN of the connection without opening the Netdata agent to DNS-spoofing, a reverse-dns record
+must be setup for the connecting host. At connection time the reverse-dns of the peer IP address is resolved, and
+a forward DNS resolution is made to validate the IP address against the name-pattern.
+
+Please note that this process can be expensive on a machine that is serving many connections. Each access list has an
+associated configuration option to turn off DNS-based patterns completely to avoid incurring this cost at run-time:
+
+```
+	allow connections by dns = heuristic
+	allow dashboard by dns = heuristic
+	allow badges by dns = heuristic
+	allow streaming by dns = heuristic
+	allow netdata.conf by dns = no
+	allow management by dns = heuristic
+```
+
+The three possible values for each of these options are `yes`, `no` and `heuristic`. The `heuristic` option disables
+the check when the pattern only contains IPv4/IPv6 addresses or `localhost`, and enables it when wildcards are
+present that may match DNS FQDNs.
+
 ### Other netdata.conf [web] section options
 
 |setting|default|info|
diff --git a/web/server/static/static-threaded.c b/web/server/static/static-threaded.c
index c432b9bf30..b9c91ef147 100644
--- a/web/server/static/static-threaded.c
+++ b/web/server/static/static-threaded.c
@@ -396,6 +396,7 @@ void *socket_listen_main_static_threaded_worker(void *ptr) {
                         , web_server_snd_callback
                         , web_server_tmr_callback
                         , web_allow_connections_from
+                        , web_allow_connections_dns
                         , NULL
                         , web_client_first_request_timeout
                         , web_client_timeout
diff --git a/web/server/web_server.c b/web/server/web_server.c
index b8b84bc36e..4da08d4319 100644
--- a/web/server/web_server.c
+++ b/web/server/web_server.c
@@ -74,46 +74,53 @@ void api_listen_sockets_setup(void) {
 // access lists
 
 SIMPLE_PATTERN *web_allow_connections_from = NULL;
+int web_allow_connections_dns;
 
 // WEB_CLIENT_ACL
 SIMPLE_PATTERN *web_allow_dashboard_from = NULL;
+int             web_allow_dashboard_dns;
 SIMPLE_PATTERN *web_allow_registry_from = NULL;
+int             web_allow_registry_dns;
 SIMPLE_PATTERN *web_allow_badges_from = NULL;
+int             web_allow_badges_dns;
 SIMPLE_PATTERN *web_allow_mgmt_from = NULL;
+int             web_allow_mgmt_dns;
 SIMPLE_PATTERN *web_allow_streaming_from = NULL;
+int             web_allow_streaming_dns;
 SIMPLE_PATTERN *web_allow_netdataconf_from = NULL;
+int             web_allow_netdataconf_dns;
 
 void web_client_update_acl_matches(struct web_client *w) {
     w->acl = WEB_CLIENT_ACL_NONE;
 
     if (!web_allow_dashboard_from ||
         connection_allowed(w->ifd, w->client_ip, w->client_host, sizeof(w->client_host),
-                           web_allow_dashboard_from, "dashboard"))
+                           web_allow_dashboard_from, "dashboard", web_allow_dashboard_dns))
         w->acl |= WEB_CLIENT_ACL_DASHBOARD;
 
     if (!web_allow_registry_from ||
         connection_allowed(w->ifd, w->client_ip, w->client_host, sizeof(w->client_host),
-                           web_allow_registry_from, "registry"))
+                           web_allow_registry_from, "registry", web_allow_registry_dns))
         w->acl |= WEB_CLIENT_ACL_REGISTRY;
 
     if (!web_allow_badges_from ||
         connection_allowed(w->ifd, w->client_ip, w->client_host, sizeof(w->client_host),
-                           web_allow_badges_from, "badges"))
+                           web_allow_badges_from, "badges", web_allow_badges_dns))
         w->acl |= WEB_CLIENT_ACL_BADGE;
 
     if (!web_allow_mgmt_from ||
         connection_allowed(w->ifd, w->client_ip, w->client_host, sizeof(w->client_host),
-                           web_allow_mgmt_from, "management"))
+                           web_allow_mgmt_from, "management", web_allow_mgmt_dns))
         w->acl |= WEB_CLIENT_ACL_MGMT;
 
     if (!web_allow_streaming_from ||
         connection_allowed(w->ifd, w->client_ip, w->client_host, sizeof(w->client_host),
-                           web_allow_streaming_from, "streaming"))
+                           web_allow_streaming_from, "streaming", web_allow_streaming_dns))
         w->acl |= WEB_CLIENT_ACL_STREAMING;
 
     if (!web_allow_netdataconf_from ||
        connection_allowed(w->ifd, w->client_ip, w->client_host, sizeof(w->client_host),
-                          web_allow_netdataconf_from, "netdata.conf"))
+                          web_allow_netdataconf_from, "netdata.conf", web_allow_netdataconf_dns))
         w->acl |= WEB_CLIENT_ACL_NETDATACONF;
 
     w->acl &= w->port_acl;
diff --git a/web/server/web_server.h b/web/server/web_server.h
index e7c2dd4482..7bfc81c9df 100644
--- a/web/server/web_server.h
+++ b/web/server/web_server.h
@@ -20,12 +20,19 @@ typedef enum web_server_mode {
 } WEB_SERVER_MODE;
 
 extern SIMPLE_PATTERN *web_allow_connections_from;
+extern int             web_allow_connections_dns;
 extern SIMPLE_PATTERN *web_allow_dashboard_from;
+extern int             web_allow_dashboard_dns;
 extern SIMPLE_PATTERN *web_allow_registry_from;
+extern int             web_allow_registry_dns;
 extern SIMPLE_PATTERN *web_allow_badges_from;
+extern int             web_allow_badges_dns;
 extern SIMPLE_PATTERN *web_allow_streaming_from;
+extern int             web_allow_streaming_dns;
 extern SIMPLE_PATTERN *web_allow_netdataconf_from;
+extern int             web_allow_netdataconf_dns;
 extern SIMPLE_PATTERN *web_allow_mgmt_from;
+extern int             web_allow_mgmt_dns;
 
 extern WEB_SERVER_MODE web_server_mode;