Bulk import DHCPD data into pfSense

Similar to my previous post, if you are trying to bulk import your current DHCPD data into pfSense, the built-in pfSense shell comes in handy.

Here we’ll start to use the current ISC-DHCPD configuration file, /etc/dhcp/dhcpd.conf, which will have entries like this:

host pi31 { hardware ethernet AA:BB:CC:DD:EE:FF; fixed-address pi31; }
host pi32 { hardware ethernet DD:EE:FF:AA:BB:CC; fixed-address pi32; }
host MobilePhone { hardware ethernet CC:DD:AA:BB:EE:FF; fixed-address mobilephone; }

Then run the following script – modify it to your needs – which will print out the commands for the pfSense shell. Since my DHCPD configuration is relying upon existing DNS entries and I am having hostnames as “fixed-address” entries, I need to resolve these entries with a dig command. If your file is always using IP addresses, just parse them out:

echo "global \$config;"
echo "parse_config(true);"

index=0
grep '^host' /etc/dhcp/dhcpd.conf | while read line
do
  hostname=$(echo $line | cut -d ' ' -f 2)
  mac=$(echo $line | cut -d '{' -f 2 | cut -d ' ' -f 4 | cut -d';' -f 1)
  ip=$(dig +short $hostname.mydomain.com)

if test -n "$ip"
then
  echo "\$config['dhcpd']['lan']['staticmap']['$index']['mac']=\"$mac\";"
  echo "\$config['dhcpd']['lan']['staticmap']['$index']['cid']=\"$hostname\";"
  echo "\$config['dhcpd']['lan']['staticmap']['$index']['ipaddr']=\"$ip\";"
  echo "\$config['dhcpd']['lan']['staticmap']['$index']['hostname']=\"$hostname\";"
  echo "\$config['dhcpd']['lan']['staticmap']['$index']['descr']=\"Automatically migrated\";"
else
  # echo "NO IP KNOWN FOR $hostname"
  echo -n ""
fi

let index=$index+1
done
echo "write_config();"
echo "exec"

This will generate the following output, ready to paste into the pfSense shell:

global $config;
parse_config(true);
$config['dhcpd']['lan']['staticmap']['0']['mac']="AA:BB:CC:DD:EE:FF";
$config['dhcpd']['lan']['staticmap']['0']['cid']="pi31";
$config['dhcpd']['lan']['staticmap']['0']['ipaddr']="192.168.1.1";
$config['dhcpd']['lan']['staticmap']['0']['hostname']="pi31";
$config['dhcpd']['lan']['staticmap']['0']['descr']="Automatically migrated";
$config['dhcpd']['lan']['staticmap']['1']['mac']="DD:EE:FF:AA:BB:CC";
$config['dhcpd']['lan']['staticmap']['1']['cid']="pi32";
$config['dhcpd']['lan']['staticmap']['1']['ipaddr']="192.168.1.2";
$config['dhcpd']['lan']['staticmap']['1']['hostname']="pi32";
$config['dhcpd']['lan']['staticmap']['1']['descr']="Automatically migrated";
$config['dhcpd']['lan']['staticmap']['2']['mac']="CC:DD:AA:BB:EE:FF";
$config['dhcpd']['lan']['staticmap']['2']['cid']="MobilePhone";
$config['dhcpd']['lan']['staticmap']['2']['ipaddr']="192.168.1.3";
$config['dhcpd']['lan']['staticmap']['2']['hostname']="MobilePhone";
$config['dhcpd']['lan']['staticmap']['2']['descr']="Automatically migrated";
write_config();
exec

Please keep in mind the index starts at 0, valid for an empty list of host names in your pfSense DHCPD configuration. For each already existing entry you have to add 1 to the starting index of 0.

Bulk import DNS data into pfSense

If you are trying to bulk import your current DNS data into pfSense, the built-in pfSense shell comes in handy.

First, get your current data into a file with 2 columns like this:

name.domain.com.  192.168.1.1
name2.domain2.com. 192.168.2.1
name3.domain2.de. 192.168.2.2

Then run the following script – modify it to your needs – which will print out the commands for the pfSense shell:

echo "global \$config;"
echo "parse_config(true);"

index=0
cat alldns.txt | while read name ip
do
  hostname=$(echo $name | cut -d '.' -f 1)
  domain=$(echo $name | cut -d '.' -f 2- | sed -e 's/\.$//')

  echo "\$config['unbound']['hosts']['$index']['host']=\"$hostname\";"
  echo "\$config['unbound']['hosts']['$index']['domain']=\"$domain\";"
  echo "\$config['unbound']['hosts']['$index']['ip']=\"$ip\";"
  echo "\$config['unbound']['hosts']['$index']['descr']=\"Automatically migrated\";"

  let index=$index+1
done
echo "write_config();"
echo "exec"

This will generate the following output, ready to paste into the pfSense shell:

global $config;
parse_config(true);
$config['unbound']['hosts']['0']['host']="name";
$config['unbound']['hosts']['0']['domain']="domain.com";
$config['unbound']['hosts']['0']['ip']="192.168.1.1";
$config['unbound']['hosts']['0']['descr']="Automatically migrated";
$config['unbound']['hosts']['1']['host']="name2";
$config['unbound']['hosts']['1']['domain']="domain2.com";
$config['unbound']['hosts']['1']['ip']="192.168.2.1";
$config['unbound']['hosts']['1']['descr']="Automatically migrated";
$config['unbound']['hosts']['2']['host']="name3";
$config['unbound']['hosts']['2']['domain']="domain2.de";
$config['unbound']['hosts']['2']['ip']="192.168.2.2";
$config['unbound']['hosts']['2']['descr']="Automatically migrated";
write_config();
exec

Please keep in mind the index starts at 0, valid for an empty list of host names in your pfSense Unbound/DNS configuration. For each already existing entry you have to add 1 to the starting index of 0.

Sixxs Heartbeat Tunnel without Aiccu but Python (pfSense compatible)

For systems that do not provide Sixxs’ aiccu package to setup a GIF tunnel automatically, you can easily start the tunnel (not setup the routing 🙂 ) by executing the following script once per minute via cron:

#!/usr/local/bin/python2.7

import time,hashlib,subprocess,socket,os

localv6="2001:3880:fe20:121::2"
password="abcdef1234567890abcdef123456"
remotev4="98.76.54.123"
remotev6="2001:3880:fe20:121::1"

hbBase="HEARTBEAT TUNNEL " + localv6 + " sender " + str(int(time.time()))
hbToSend=hbBase + " " + hashlib.md5(hbBase + " " + password).hexdigest()
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.sendto(hbToSend, (remotev4, 3740))
sock.close()
with open(os.devnull, "w") as fnull:
  subprocess.call(["/sbin/ping6", "-s", "8", "-c", "1", remotev6], stdout=fnull, stderr=fnull)

This solution was first posted here:

UBNT – Sixxs Tunnel