How to log all DNS calls from PHP
It becomes larger and larger problem to control remote calls from applications like Joomla or Wordpress. This guide will show you how to log all remote calls which use DNS resolver into Bind9 log files without damaging performance of your server generally. This guide is intended for system administrators and we had done this on Ubuntu 12.04.
Prerequirities
1. php-fpm with chroot -> when running PHP in chroot you protect the server from unauthorized escape of the php user into your system files. if you do not run php in chroot, this guide will explain how to catch all DNS calls from all sites on your server at once and thus you should only apply the guide temporary
2. Bind9 is what we used to catch all of the DNS calls. Other DNS systems will work as well as far as they provide query logging
3. files and structures are shown here: https://www.rupostel.com/svn3/bind9-php-log/
4. they can be download from https://www.rupostel.com/svn3/bind9-php-log/all.tar.gz
Constants:
PHPCHROOT: in our case we use /ssd/www/customer_home (if chroot is not used, your ROOT directory is used - i.e. / )
CHROOTBIND: /var/lib/named
#: refers to the command line shell
Guide
1. create a new directory in CHROOTBIND/etc/bind-log, this will be a new configuraiton place for new instance of named/bind9. You can copy the original config, or just leave it empty for now and upload our named.conf which you can point to your own original directory
CHROOTBIND/etc/bind-log
2. create a symlink to your general config:
CHROOTBIND/etc/bind-log
to
/etc/bind-log
4. create a new loopback IP and interface:
# ifconfig lo:0 127.0.0.2 netmask 255.0.0.0 up
(this could have been done many different ways, but this one is the simplest single line code)
5. create a new files as shown here:
https://www.rupostel.com/svn3/bind9-php-log/
/etc/init.d/bind9-log
(loader file)
/etc/bind-log/named.conf
(this file needs a slight adjustment, see below)
/etc/bind-log/named.conf.log
(logging configuration as advised at http://stackoverflow.com/questions/11153958/how-to-enable-named-bind-dns-full-logging)
/etc/bind-log/named.conf.options
(the most important file here, since we make the second instance of bind to run on 127.0.0.2)
now in our case the /etc/bind-log is a symlink of CHROOTBIND/etc/bind-log
to be able to execute the bind9-log adjust permissions:
# chmod +x /etc/init.d/bind9-log
6. create a new directory in your /var/log/named/log/ and make sure your bind user has access to it - in our case it was:
# mkdir /var/log/named/log/
# chrown bind:bind /var/log/named/log/
7. in your PHPCHROOT path adjust your:
PHPCHROOT/etc/hosts (change here is probably not needed, but it resolves localhost name into 127.0.0.2)
PHPCHROOT/etc/networks (we didn't do any change here actually)
PHPCHROOT/etc/resolv.conf (the most important change, is to use your new 127.0.0.2 resoler)
8. IMPORTANT: adjust your new /etc/bind-log/named.conf so it loads your original config except the options and log. Adjust also any paths if they different from our example.
8. try to run tests:
8.1:
# /etc/init.d/bind9-log start
see your /var/log/syslog
if you get any sort of IP conflicts and if the bind was capable of starting on 127.0.0.2:53 and 127.0.0.2:953
our modified init script removes rndc so it does not conflicts with other instance of bind running on the same server and adjusts the paths and configuration file per this guide
8.2: you can test if the logging works:
#su chrooteduser
#ping google.com (if ping is available in PHPCHROOT/bind)
see you your /var/log/named/log/queries.log
8.3. test from within PHP:
create: PHPCHROOT/WEBROOT/test.php
and visit via your domain.com/test.php
you should see a log entry in
/var/log/named/log/queries.log
8.4. the simmplest test is with:
#nslookup example.com 127.0.0.2
NOTES:
1. we must had modified the init script since the rndc was not capable of running in two instances. We also removed all control options from our new named.conf so the new bind does not initialize the control ports
2. we tested with file_get_contents at PHP to download the remote content - depending on your php config, this may be already disabled. this guide should catch also curl and other remote calls done from within the chroot
3. general but not complete guide on how to create PHP chroot:
we created a structure of directories required for chroot at our:
/backup-hdd/Jail
upon creation of chroot this directory is first rsynced with mnt_chroot.sh. Please note that the mounts in our example are ready/write and it's also possible to mount some shares as read-only.
for further chroot details see /backup-hdd/Jail/readme.txt
Author: Stan Scholtz, RuposTel.com