diff --git a/Knot.files b/Knot.files
index eb6887ba443de6dcc67a5ef27116cd9cd836aba3..f364dccaad656272b557db1cdb163ad30c457fdd 100644
--- a/Knot.files
+++ b/Knot.files
@@ -73,8 +73,6 @@ src/common/slab/alloc-common.h
 src/common/libtap/tap.c
 src/common/libtap/tap.h
 src/common/libtap/tap_unit.h
-src/common/caps.h
-src/common/caps.c
 src/common/lists.h
 src/common/lists.c
 src/common/base32.h
diff --git a/configure.ac b/configure.ac
index eccd82f4e09128fd02b9b7b2d720d7a9d055b0a3..027f6ecc4986a9ba89cc9c2340080d9513928beb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -113,12 +113,12 @@ AC_SEARCH_LIBS([rcu_set_pointer_sym], [urcu], [], [AC_MSG_ERROR([liburcu not fou
 AC_SEARCH_LIBS([dlopen], [dl])
 AC_SEARCH_LIBS([clock_gettime], [rt], [], [AC_MSG_ERROR([librt not found])])
 AC_SEARCH_LIBS([OpenSSL_add_all_digests], [crypto],[], [AC_MSG_ERROR([libcrypto not found])])
-AC_SEARCH_LIBS([cap_set_flag], [cap])
+AC_SEARCH_LIBS([capng_apply], [cap-ng])
 #AC_SEARCH_LIBS([ldns_rr_list_pop_rrset], [ldns], [], [AC_MSG_ERROR([libldns not found])])
 
 # Checks for header files.
 AC_HEADER_RESOLV
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in_systm.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h sys/capability.h syslog.h unistd.h urcu.h ev.h])
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in_systm.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h cap-ng.h syslog.h unistd.h urcu.h ev.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_HEADER_STDBOOL
diff --git a/src/Makefile.am b/src/Makefile.am
index b50c33afa6830988b0dd982d9bf6a19f2b427551..e73b2bfb4d020fc6dfed9b58f3b2e70ed7496dc8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -223,8 +223,6 @@ libknots_la_SOURCES =				\
 	common/libtap/tap.c			\
 	common/libtap/tap.h			\
 	common/libtap/tap_unit.h		\
-	common/caps.c				\
-	common/caps.h				\
 	common/lists.c				\
 	common/base32.c				\
 	common/lists.h				\
diff --git a/src/common/caps.c b/src/common/caps.c
deleted file mode 100644
index 22fb273be5663a7df0cb6b685d33fc9122df13b8..0000000000000000000000000000000000000000
--- a/src/common/caps.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "caps.h"
-
-int cap_drop_all() {
-#ifdef USE_CAPABILITIES
-	cap_t caps = cap_init();
-	if (caps == NULL) {
-		return -1;
-	}
-	int ret = cap_apply(caps);
-	cap_free(caps);
-	return ret;
-#else
-	return -1;
-#endif
-}
-
diff --git a/src/common/caps.h b/src/common/caps.h
deleted file mode 100644
index 657390a74206f0e07e804168b738480982b2151b..0000000000000000000000000000000000000000
--- a/src/common/caps.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-/*!
- * \file caps.h
- *
- * \author Marek Vavrusa <marek.vavrusa@nic.cz>
- *
- * \brief POSIX 1003.1e capabilities interface.
- *
- * \addtogroup common_lib
- * @{
- */
-
-#ifndef _KNOTD_CAPS_H_
-#define _KNOTD_CAPS_H_
-
-#include <unistd.h>
-#include <config.h>
-
-/* Include required types. */
-#ifdef HAVE_SYS_CAPABILITY_H
-#include <sys/capability.h>
-
-/* Check gettid(). */
-#ifndef HAVE_GETTID
-#include <sys/syscall.h>
-static pid_t gettid() {
-#ifdef SYS_gettid
-	return (pid_t)syscall(SYS_gettid);
-#define HAVE_GETTID 1
-#else
-	return (pid_t)0;
-#endif
-}
-#endif
-#else
-/* Stub types. */
-typedef void* cap_t;
-typedef int cap_value_t;
-typedef int cap_flag_value_t;
-#endif
-
-/* Summarize. */
-#ifdef HAVE_SYS_CAPABILITY_H
-#ifdef HAVE_GETTID
-#define USE_CAPABILITIES
-#endif
-#endif
-
-/*!
- * \brief Set Permitted & Effective flag.
- * \param caps Capabilities context.
- * \param cp Flag to be set.
- * \retval 0 if success.
- * \retval -1 on error.
- */
-static inline int cap_set_pe(cap_t caps, cap_value_t cp) {
-#ifdef USE_CAPABILITIES
-	return cap_set_flag(caps, CAP_EFFECTIVE, 1, &cp, CAP_SET) +
-	       cap_set_flag(caps, CAP_PERMITTED, 1, &cp, CAP_SET);
-#else
-	return -1;
-#endif
-}
-
-/*!
- * \brief Apply privileges.
- * \param caps Capabilities context.
- * \retval 0 if success.
- * \retval -1 on error.
- */
-static inline int cap_apply(cap_t caps) {
-#ifdef USE_CAPABILITIES
-	return capsetp(gettid(), caps);
-#else
-	return -1;
-#endif
-}
-
-/*!
- * \brief Drop all capabilities.
- * \retval 0 if success.
- * \retval -1 on error.
- */
-int cap_drop_all();
-
-#endif //_KNOTD_CAPS_H_
diff --git a/src/knot/main.c b/src/knot/main.c
index 27cbb27c3a244a4c71997033a1a5ef51dd0f81f9..a3a1db7986c96f877d13b1551a144969e748dfdd 100644
--- a/src/knot/main.c
+++ b/src/knot/main.c
@@ -19,10 +19,12 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <getopt.h>
-#include "common.h"
+#ifdef HAVE_CAP_NG_H
+#include <cap-ng.h>
+#endif /* HAVE_CAP_NG_H */
 
+#include "common.h"
 #include "common/evqueue.h"
-#include "common/caps.h"
 #include "knot/common.h"
 #include "knot/other/error.h"
 #include "knot/server/server.h"
@@ -183,48 +185,39 @@ int main(int argc, char **argv)
 		config_fn = abs_cfg;
 	}
 	
-	/* Linux capabilities. */
-#ifdef USE_CAPABILITIES
-	cap_t caps = cap_get_proc();
-	if (caps != NULL) {
-		/* Read current and clear. */
-		cap_flag_value_t set_caps = CAP_CLEAR;
-		cap_get_flag(caps, CAP_SETPCAP, CAP_EFFECTIVE, &set_caps);
-		cap_clear(caps);
-		
-		/* Retain ability to set capabilities. */
-		cap_set_pe(caps, CAP_SETPCAP);
-
-		/* Allow binding to privileged ports.
-		 * (Not inheritable)
-		 */
-		cap_set_pe(caps, CAP_NET_BIND_SERVICE);
-		
-		/* Allow setuid/setgid. */
-		cap_set_pe(caps, CAP_SETUID);
-		cap_set_pe(caps, CAP_SETGID);
-		
-		/* Allow priorities changing. */
-		cap_set_pe(caps, CAP_SYS_NICE);
-			
-		/* Apply */
-		int caps_res = 0;
-		if (set_caps == CAP_SET) {
-			caps_res = cap_apply(caps);
-		} else {
-			log_server_info("User uid=%d is not allowed to set "
-			                "capabilities, skipping.\n", getuid());
-		}
-		if (caps_res < 0) {
+	/* POSIX 1003.1e capabilities. */
+#ifdef HAVE_CAP_NG_H
+	
+	/* Drop all capabilities. */
+	capng_clear(CAPNG_SELECT_BOTH);
+	
+	/* Retain ability to set capabilities. */
+	capng_type_t tp = CAPNG_EFFECTIVE|CAPNG_PERMITTED;
+	capng_update(CAPNG_ADD, tp, CAP_SETPCAP);
+	
+	/* Allow binding to privileged ports.
+	 * (Not inheritable)
+	 */
+	capng_update(CAPNG_ADD, tp, CAP_NET_BIND_SERVICE);
+	
+	/* Allow setuid/setgid. */
+	capng_update(CAPNG_ADD, tp, CAP_SETUID);
+	capng_update(CAPNG_ADD, tp, CAP_SETGID);
+	
+	/* Allow priorities changing. */
+	capng_update(CAPNG_ADD, tp, CAP_SYS_NICE);
+	
+	/* Apply */
+	if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
+		if (capng_apply(CAPNG_SELECT_BOTH) < 0) {
 			log_server_error("Couldn't set process capabilities - "
 			                 "%s.\n", strerror(errno));
 		}
-		/* Free capabilities list. */
-		cap_free(caps);
 	} else {
-		log_server_error("Couldn't initialize Linux capabilities.\n");
+		log_server_info("User uid=%d is not allowed to set "
+		                "capabilities, skipping.\n", getuid());
 	}
-#endif
+#endif /* HAVE_CAP_NG_H */
 
 	// Open configuration
 	log_server_info("Parsing configuration '%s' ...\n", config_fn);
diff --git a/src/knot/server/dthreads.c b/src/knot/server/dthreads.c
index 3ddf4593601e0114bfeba979427550bcde86b485..83466d8fa855b7fd5aa2991b379453fc0b6ba0e9 100644
--- a/src/knot/server/dthreads.c
+++ b/src/knot/server/dthreads.c
@@ -21,12 +21,14 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
+#ifdef HAVE_CAP_NG_H
+#include <cap-ng.h>
+#endif /* HAVE_CAP_NG_H */
 
 #include "knot/common.h"
 #include "knot/server/dthreads.h"
 #include "knot/other/log.h"
 #include "knot/other/error.h"
-#include "common/caps.h"
 
 /*! \brief Lock thread state for R/W. */
 static inline void lock_thread_rw(dthread_t *thread)
@@ -126,7 +128,10 @@ static void *thread_ep(void *data)
 	dbg_dt("dthreads: [%p] entered ep\n", thread);
 	
 	// Drop capabilities
-	cap_drop_all();
+#ifdef HAVE_CAP_NG_H
+	capng_clear(CAPNG_SELECT_BOTH);
+	capng_apply(CAPNG_SELECT_BOTH);
+#endif /* HAVE_CAP_NG_H */
 
 	// Run loop
 	for (;;) {