O que há de errado com o auditctl?
Você faria assim ...
1) Defina sua regra de auditoria para auditar sendmsg e enviar para as chamadas do sistema. Essas chamadas do sistema são usadas durante a resolução de nomes.
auditctl -a exit,always -F arch=b64 -S sendmsg -S sendto -k send
2) Agora procure seus registros de auditoria. Você pode fazer o grep com base no IP do DNS remoto aqui
ausearch -k send -i|grep -A2 "serv:53"
No exemplo abaixo, você pode ver que o aplicativo responsável pela chamada do sistema é chamado de dig
ausearch -k send -i|grep -A2 "serv:53"
type=SOCKADDR msg=audit(10/31/2016 15:24:56.264:176998) : saddr=inet host:172.16.0.23 serv:53
type=SYSCALL msg=audit(10/31/2016 15:24:56.264:176998) : arch=x86_64 syscall=sendmsg success=yes exit=29 a0=14 a1=7fa1919f9ac0 a2=0 a3=7fa1919f9780 items=0 ppid=31729 pid=32047 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts5 ses=52 comm=dig exe=/usr/bin/dig subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=send
comm=dig exe=/usr/bin/dig
E a maneira de diferenciar a qual solicitação de DNS remoto é enviada está aqui. Então você teria apenas que grep para um host DNS específico.
saddr=inet host:172.16.0.23 serv:53
Ou ainda melhor - veja quais hosts DNS são usados (eu tenho apenas um neste exemplo)
ausearch -k send -i|grep "serv:53"|awk '{print $6}'|sort|uniq -c
3 host:172.16.0.23
Depois, reduza quais aplicativos estão usando esses hosts específicos.
Editar 1: Na verdade eu apenas fiz um simples ping para um host. Parece que o sendmsg nem sempre é usado. Aqui está o que eu vejo
socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.16.0.23")}, 16) = 0
gettimeofday({1477929832, 712018}, NULL) = 0
poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}])
sendto(4, "6auditctl -a exit,always -F arch=b64 -S connect -k connect
ausearch -k connect -i|grep saddr|grep "serv:53"|awk '{print $6}'|sort|uniq -c
auditctl -a exit,always -F arch=b64 -S sendmsg -S sendto -k send
ausearch -k send -i|grep -A2 "serv:53"
ausearch -k send -i|grep -A2 "serv:53"
type=SOCKADDR msg=audit(10/31/2016 15:24:56.264:176998) : saddr=inet host:172.16.0.23 serv:53
type=SYSCALL msg=audit(10/31/2016 15:24:56.264:176998) : arch=x86_64 syscall=sendmsg success=yes exit=29 a0=14 a1=7fa1919f9ac0 a2=0 a3=7fa1919f9780 items=0 ppid=31729 pid=32047 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts5 ses=52 comm=dig exe=/usr/bin/dig subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=send
comm=dig exe=/usr/bin/dig
saddr=inet host:172.16.0.23 serv:53
ausearch -k send -i|grep "serv:53"|awk '{print $6}'|sort|uniq -c
3 host:172.16.0.23
socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.16.0.23")}, 16) = 0
gettimeofday({1477929832, 712018}, NULL) = 0
poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}])
sendto(4, "6auditctl -a exit,always -F arch=b64 -S connect -k connect
ausearch -k connect -i|grep saddr|grep "serv:53"|awk '{print $6}'|sort|uniq -c
%pre%%pre%%pre%%pre%%pre%%pre%\tvkontakteru%pre%%pre%%pre%", 30, MSG_NOSIGNAL, NULL, 0) = 30
poll([{fd=4, events=POLLIN}], 1, 5000) = 1 ([{fd=4, revents=POLLIN}])
ioctl(4, FIONREAD, [62]) = 0
recvfrom(4, "610%pre%%pre%%pre%%pre%%pre%%pre%\tvkontakteru%pre%%pre%%pre%0\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.16.0.23")}, [16]) = 62
close(4) = 0
\tvkontakteru%pre%%pre%%pre%", 30, MSG_NOSIGNAL, NULL, 0) = 30
poll([{fd=4, events=POLLIN}], 1, 5000) = 1 ([{fd=4, revents=POLLIN}])
ioctl(4, FIONREAD, [62]) = 0
recvfrom(4, "610%pre%%pre%%pre%%pre%%pre%%pre%\tvkontakteru%pre%%pre%%pre%0\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.16.0.23")}, [16]) = 62
close(4) = 0
Meu exemplo anterior foi baseado no aplicativo dig, que leva um caminho ligeiramente diferente em termos de chamadas do sistema.
Então, parece que na maioria dos casos seria essa regra
%pre%
Seguido por ausearch
%pre%