Mikrotik with NetFlow on FreeBSD

A short how to adding NetFlow to Mikrotik using ntop and FreeBSD. FreeBSD is the best operating system you can go for your server. While Mikrotik is a budget router it is capable of many. I’m covering Ntop not Ntopng. While Ntopng is fancier, requires a probe to collect NetFlow which is not free. Without the probe you can still collect traffic on the server where Ntopng is installed but not from another device. You can buy a NetFlow capable Mikrotik router for less than $50. Of course, if you have the big bucks you can go with a Cisco and Ntopng.

This article assumes you know already how to install FreeBSD and do basic configurations on Mikrotik.

Let’s install Ntop, this can be done using precompiled packages or from source.

Package, using pkg
pkg install ntop
pkg will update automatically it’s repository, however you can can also invoke it manually with pkg update. 
Ready carefully the details, only proceed if you agree with all what the package manager is telling

Source, using ports
Ports however won’t update automatically the ports tree, you have to do it yourself, be sure to do this before installing anything from ports
portsnap fetch
portsnap update

cd /usr/ports/net/ntop
make config-recursive
make install clean

Using config-recursive instead of config will configure all dependencies as well, so you can step away while the source code is compiling, it could take awhile.
Installing software from ports and packages on the same server requires lots of attention, so be careful. Explaining is out of the scope of this article.

After you installed ntop enable it:
sysrc ntop_enable="YES" or carefully add it manually to /etc/rc.conf.
Additional flags can be set, like sysrc ntop_flags="-d --use-syslog=daemon -u nobody -4"

  • -d: run as a demon
  • –use-syslog=daemon: ave the messages into the system log
  • -u nobody: run as user nobody
  • -4: IPv4 only

Now start the service:
# service ntop start
Starting ntop.
Sun Feb 11 16:25:58 2018 Initializing gdbm databases
# service ntop status
ntop is running as pid 4277.

You should see the service running and listening on 3000/tcp:
# sockstat -l|grep ntop
nobody ntop 512 2 tcp4 *:3000 *:*
nobody ntop 512 8 dgram (not connected)

Now go to http://address_of_your_server:3000, voila, there is your Ntop.
Let’s add the NetFlow support.
Go to Plugins-NetFlow-Active

  • Set NetFlow Device – Whatever name you want for your device
  • Local Collector UDP Port – default is 2055
  • Virtual NetFlow Interface Network Address – address_of_your_server


Check if your server is listening
# sockstat -l|grep ntop
nobody ntop 512 2 tcp4 *:3000 *:*
nobody ntop 512 8 dgram (not connected)
nobody ntop 512 15 udp4 *:2055 *:*

Good. Now we can proceed configuring Mikrotik
[user@MikroTik] > ip traffic-flow set active-flow-timeout=1m enabled=yes
[user@MikroTik] > ip traffic-flow target add dst-address=address_of_your_server port=2055 v9-template-timeout=1m

Check if it is there
[user@MikroTik] > ip traffic-flow target print
Flags: X - disabled
0        address_of_your_server   2055       9

Go back to your browser, then Plugins-NetFlow-Statistics, you should see some data.

Of course you can use a Linux distro instead, but why would you use Linux when you can use FreeBSD?
Why do this? To see what really happens on your network and find some amazing details about it.


Raspberry Pi and FreeBSD

I’m writing down a few steps for the future me how I installed RaspBSD on a Raspberry Pi 3

  • Download http://www.raspbsd.org/
  • Insert memory card then:
    diskutil list
    sudo diskutil unmountDisk /dev/disk2
    sudo dd bs=1 if=insertFreeBSDImage.img of=/dev/disk2
  • While writing the image press ctrl+t to get progress (this works on OS-X & FreeBSD but not on Linux)
    • Boot Pi from the MicroSD card
    • set date

ntpdate 0.pool.ntp.org
Enable ntpd, NTP is important since the board has no batteries, time will be very off
sysrc ntpd_enable="YES"

  • If you are installing FreeBSD12 on it today (2018.02.11) then you’ll have to use 11’s pkg repository
    env ABI=FreeBSD:11:aarch64 pkg bootstrap
    Add “ABI = “FreeBSD:11:aarch64”; to /usr/local/etc/pkg/repo.vrt

cat /usr/local/etc/pkg.conf
ABI = "FreeBSD:11:aarch64";
all-depends: query %dn-%dv,
annotations: info -A,
build-depends: info -qd,
cinfo: info -Cx,
comment: query -i "%c",
csearch: search -Cx,
desc: query -i "%e",
download: fetch,
iinfo: info -ix,
isearch: search -ix,
prime-list: "query -e '%a = 0' '%n'",
prime-origins: "query -e '%a = 0' '%o'",
leaf: "query -e '%#r == 0' '%n-%v'",
list: info -ql,
noauto = "query -e '%a == 0' '%n-%v'",
options: query -i "%n - %Ok: %Ov",
origin: info -qo,
provided-depends: info -qb,
raw: info -R,
required-depends: info -qr,
roptions: rquery -i "%n - %Ok: %Ov",
shared-depends: info -qB,
show: info -f -k,
size: info -sq,

  • Then you should extend the HDD with uncommenting this line in /etc/rc.conf


If that doesn’t work take a look at my previous post.


A reminder.

If you are installing RaspBSD following the instruction from here then the default disk size is going to be 2GB no matter the size of the Micro SD card you’re using. This can be changed with:
gpart show
Pay attention and check what can be extended, in my case it was /dev/mmcsd0s2
gpart resize -i 1 mmcsd0s2 (where 1 is the the index,  mmcsd0 is the disk, s2 is the second slice)
growfs /dev/mmcsd0s2
In case after grows fails with Operation not permitted you need to start the growfs service
service growfs onestart

Then you don’t have to but won’t hurt a reboot



National FreeBSD Day – 19th of June

Today is National FreeBSD Day! Why today? Because 23 years ago on this day, 19th of June was when the official name for this amazing operating system has been agreed upon: FreeBSD. A little email can be found here.

For more info log on to the foundations page.


FreeNAS 10

A pretty nice update for FreeNAS, FeeNAS was already the best storage OS you can get, now with this update got even better.


Incorrect argument handling in sendmsg(2)

To all the FreeBSD users out there, don’t forget to update your systems.

The sendmsg(2) system call allows to send data to a socket.  The data
may be accompanied by optional ancillary data.

For details please visit: https://www.freebsd.org/security/advisories/FreeBSD-SA-16:19.sendmsg.asc


check free memory in FreeBSD

In case you’re coming from Linux world to FreeBSD first of all: Welcome!

You might miss some commands, like free.
Here is a very short tutorial for that.

fetch https://raw.githubusercontent.com/ocochard/myscripts/master/FreeBSD/freebsd-memory.sh

sh freebsd-memory.sh

Then of course you can make it executable and move it to a proper place, whatever is in your path: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin

All the credit for the script goes to Ralf S. Engelschall
In case someone would remove the file from githubusercontent.com here is the script:


# Display memory usage information on FreeBSD
# This function is a shell re-writting of the perl script:
## freebsd-memory — List Total System Memory Usage
## Copyright (c) 2003-2004 Ralf S. Engelschall <rse@engelschall.com>
## http://www.cyberciti.biz/files/scripts/freebsd-memory.pl.txt

# round the physical memory size to the next power of two which is
# reasonable for memory cards. We do this by first determining the
# guessed memory card size under the assumption that usual computer
# hardware has an average of a maximally eight memory cards installed
# and those are usually of equal size.

# Strict script
set -e
set -u

mem_rounded () {
chip_guess=`echo “$mem_size / 8 – 1” | bc`
while [ $chip_guess != 0 ]
chip_guess=`echo “$chip_guess / 2” | bc`
chip_size=`echo “$chip_size * 2” | bc`
mem_round=`echo “( $mem_size / $chip_size + 1 ) * $chip_size” | bc`
echo $mem_round
exit 0

free_memory () {
# determine the individual known information
# NOTICE: forget hw.usermem, it is just (hw.physmem – vm.stats.vm.v_wire_count).
# NOTICE: forget vm.stats.misc.zero_page_count, it is just the subset of
# vm.stats.vm.v_free_count which is already pre-zeroed.
mem_phys=`sysctl -n hw.physmem`
set +e
mem_hw=`mem_rounded $mem_phys`
set -e
sysctl_pagesize=`sysctl -n hw.pagesize`
mem_all=`echo “\`sysctl -n vm.stats.vm.v_page_count\` \
* $sysctl_pagesize” | bc`
mem_wire=`echo “\`sysctl -n vm.stats.vm.v_wire_count\` \
* $sysctl_pagesize” | bc`
mem_active=`echo “\`sysctl -n vm.stats.vm.v_active_count\` \
* $sysctl_pagesize” | bc`
mem_inactive=`echo “\`sysctl -n vm.stats.vm.v_inactive_count\` \
* $sysctl_pagesize” | bc`
mem_cache=`echo “\`sysctl -n vm.stats.vm.v_cache_count\` \
* $sysctl_pagesize” | bc`
mem_free=`echo “\`sysctl -n vm.stats.vm.v_free_count\` \
* $sysctl_pagesize” | bc`

# determine the individual unknown information
mem_gap_vm=`echo “$mem_all – ( $mem_wire + $mem_active + \
$mem_inactive + $mem_cache + $mem_free )” | bc`
mem_gap_sys=`echo “$mem_phys – $mem_all” | bc`
mem_gap_hw=`echo “$mem_hw – $mem_phys” | bc`

# determine logical summary information
mem_avail=`echo “$mem_inactive + $mem_cache + $mem_free” | bc`
mem_used=`echo “$mem_total – $mem_avail” | bc`

# print system results
printf “mem_wire: %12d (%7dMB) [%3d%%] %s\n” $mem_wire \
`echo “$mem_wire / ( 1024 * 1024 )” | bc` `echo “$mem_wire \
* 100 / $mem_all” | bc` “Wired: disabled for paging out”
printf “mem_active: + %12d (%7dMB) [%3d%%] %s\n” $mem_active \
`echo “$mem_active / ( 1024 * 1024 )” | bc` `echo “$mem_active \
* 100 / $mem_all” | bc` “Active: recently referenced”
printf “mem_inactive:+ %12d (%7dMB) [%3d%%] %s\n” $mem_inactive \
`echo “$mem_inactive / ( 1024 * 1024 )” | bc` `echo “$mem_inactive \
* 100 / $mem_all” | bc` “Inactive: recently not referenced”
printf “mem_cache: + %12d (%7dMB) [%3d%%] %s\n” $mem_cache \
`echo “$mem_cache / ( 1024 * 1024 )” | bc` `echo “$mem_cache \
* 100 / $mem_all” | bc` “Cached: almost avail. for allocation”
printf “mem_free: + %12d (%7dMB) [%3d%%] %s\n” $mem_free \
`echo “$mem_free / ( 1024 * 1024 )” | bc` `echo “$mem_free \
* 100 / $mem_all” | bc` “Free: fully available for allocation”
printf “mem_gap_vm: + %12d (%7dMB) [%3d%%] %s\n” $mem_gap_vm \
`echo “$mem_gap_vm / ( 1024 * 1024 )” | bc` `echo “$mem_gap_vm \
* 100 / $mem_all” | bc` “Memory gap: UNKNOWN”
printf “______________ ____________ ___________ ______\n”
printf “mem_all: = %12d (%7dMB) [100%%] %s\n” $mem_all \
`echo “$mem_all / ( 1024 * 1024 )” | bc` “Total real memory managed”
printf “mem_gap_sys: + %12d (%7dMB) %s\n” $mem_gap_sys \
`echo “$mem_gap_sys / ( 1024 * 1024 )” | bc` “Memory gap: Kernel?!”
printf “______________ ____________ ___________\n”
printf “mem_phys: = %12d (%7dMB) %s\n” $mem_phys \
`echo “$mem_phys / ( 1024 * 1024 )” | bc` “Total real memory available”
printf “mem_gap_hw: + %12d (%7dMB) %s\n” $mem_gap_hw \
`echo “$mem_gap_hw / ( 1024 * 1024 )” | bc` “Memory gap: Segment Mappings?!”
printf “______________ ____________ ___________\n”
printf “mem_hw: = %12d (%7dMB) %s\n” $mem_hw \
`echo “$mem_hw / ( 1024 * 1024 )” | bc` “Total real memory installed”
# print logical results
printf “\n”
printf “mem_used: %12d (%7dMB) [%3d%%] %s\n” $mem_used \
`echo “$mem_used / ( 1024 * 1024 )” | bc` `echo “$mem_used \
* 100 / $mem_total” | bc` “Logically used memory”
printf “mem_avail: + %12d (%7dMB) [%3d%%] %s\n” $mem_avail \
`echo “$mem_avail / ( 1024 * 1024 )” | bc` `echo “$mem_avail \
* 100 / $mem_total” | bc` “Logically available memory”
printf “______________ ____________ __________ _______\n”
printf “mem_total: = %12d (%7dMB) [100%%] %s\n” $mem_total \
`echo “$mem_total / ( 1024 * 1024 )” | bc` “Logically total memory”
exit 0

## Main function ##