Creating a Module::Build Distribution

(Up-to-date source of this post.)

Creating a Module::Build Distribution

We show here how to create a Perl distribution using Module::Build build system with Module::Starter. The other Perl build system (we don't show here) is ExtUtils::MakeMaker. For sophisticated distribution creation see Dist::Zilla.

Create config file ~/.module-starter/config:

author: Foo Bar
email: foo@bar.org
builder: Module::Build
verbose: 1
# Allow adding new modules to existing distro.
plugins: Module::Starter::AddModule

... or use module-starter (see below) with command line arguments like:

--author="Foo Bar" \
--email=foo@bar.org \
--mb \
--verbose \

Run basic commands

  • install needed modules: cpanm Module::Build Module::Starter Module::Starter::AddModule
  • create (a working skeleton of) module distribution: module-starter --module=Animal
  • change to the created distro directory: cd Animal
  • create the Build script: perl Build.PL
  • build the distro (modules from lib copied to blib staging area and embedded documenation translated into Unix manpage in blib/libdoc): ./Build
  • make sure the tests pass: ./Build test (or run individual tests - see below)
  • test the distro: ./Build disttest
  • create the distro: ./Build dist

Add modules

  • add new modules: module-starter --module=Sheep,Cow,Horse --dist=Animal
  • add new modules (we are inside our distribution directory): module-starter --module=Sheep,Cow,Horse --dist=.

Run individual tests

  • rebuild distro and run test including modules from blib/lib: ./Build && perl -Iblib/lib -T t/Cow.t
  • rebuild distro and run test including modules from blib/lib: ./Build && perl -Mblib -T t/Cow.t

Measure out test coverage

  • run testcover target: ./Build testcover
  • turn the collected statistics into human-readable reports: cover

The following is a typical release cycle for github users:

  1. Work on changes until all tests pass
  2. Make sure the Changes file documents all major changes
  3. Make your changes atomic, all changes related to a particular fix or feature should go in a single commit, including the Changes entry.
  4. Bump the version
  5. Upload to PAUSE
  6. Tag with the version. By convention for version 1.01 the tag would be 'v1.01'
  7. Push to github

For more see:


Finding a Good CPAN Module

(Up-to-date source of this post.)

Anyone can contribute to CPAN. It is also pretty huge. This means you might want to separate the wheat from the chaff. To do that these hints might help:

  1. What's the code activity? The more the better.

  2. How many issues do we have? The open bugs show community involvement, the closed ones are about the maintainer's diligence.

  3. What aboout the quality and quantity of tests and their results.

  4. Are there any reverse dependencies (they use the same basic principle as Google PageRank)? The more the better.

  5. Follow the advice of experts in the Perl field, ex. Task::Kensho.

NOTE: don't check any of the hints above in isolation but all/more of them together.


  • https://www.usenix.org/system/files/login/articles/logindec1410_blank-edelman.pdf


tcpdump - standard Unix tool for analyzing network packets

(Up-to-date source of this post.)

  • despite its name it can do much more than capturing TCP headers
  • can sniff traffic on many network types (including 802.1Q VLAN)
  • de facto standard for command line packet analysis in Unix environment

Useful options:

-D -- list available interfaces

-i INTERFACE -- listen on INTERFACE (default: lowest numbered interface)

-w FILE -- write raw packets to FILE

-r FILE -- read packets from FILE

-nn -- turn off host and protocol name resolution (to avoid generating DNS packets)

-s0 -- set snaplength to 0, i.e. read the whole packet not just first 68 bytes (default if version >= 4.0)

-t -- turn off timestamp entries

-c COUNT -- capture COUNT packets and stop


tcpdump -nni eth1 -w packets.pcap
tcpdump -nnr packets.pcap

Output format will vary based upon what protocols are in use:

  • TCP

    timestamp L3_protocol sIP.sPort > dIP.dPort: TCP_flags,
    TCP_sequence_number, TCP_acknowledgement_number, TCP_windows_size,
  • UDP

    timestamp L3_protocol sIP.sPort > dIP.dPort: L4_protocol, data_length
  • use up to -vvv to provide more information on headers

  • use -x to get entire packets (including data not just headers) in hex format
  • use -A to get entire packets in hex and ASCII format
  • use -X to get entire packets in hex and ASCII format

Packet Filtering

  • utilizes the Berkeley Packet Filter (BPF) format
  • added to the end of the command (recommended to use single quotes)

    tcpdump -nnr packets.pcap 'tcp dst port 8080' -w packets_tcp8080.pcap
    tcpdump -nnr packets.pcap -F known_good_hosts.bpf


 primitive   |      primitive
     |       |         |
+---------+  | +----------------+
|         |  | |                |
udp port 53 && dst host
 |        |
 |        value


  • host
  • net - network in CIDR notation
  • port
  • src - communication source
  • dst - communication destination
  • ip - IP protocol
  • tcp - TCP protocol
  • upd - UPP protocol

Logical operators

  • && - true when both conditions are true
  • || - true when either condition is true
  • ! - true when a condition is NOT met


  • host - match traffic to/from
  • dst host 2001:db8:85a3::8a2e:370:7334 - match traffic to the IPv6 address
  • ether host 00:50:56:98:60:92 - match traffic to the specified MAC address
  • !port 22 - match any traffic not to/from port 22
  • icmp - match all ICMP traffic
  • !ip6 - match everything that is not IPv6


  • Applied Network Security Monitoring


Common Vagrant Tasks

(Up-to-date source of this post.)

Search and add a box (virtual machine image):

vagrant box add https://atlas.hashicorp.com/ubuntu/boxes/trusty64
  • added box is global to the vagrant install
  • this is the base box (used to start the VM from the clean state)
  • base boxes are stored in ~/.vagrant.d/boxes

Initialize vagrant environment:

mkdir ubuntu-trusty64
cd ubuntu-trusty64
vagrant init ubuntu/trusty64
  • Vagrantfile is created

Start vagrant environment:

vagrant up
  • vagrant "imports" (copies) the base box to provider specific location (ex. ~/.VirtualBox)

Check box(es) status:

vagrant status

Check box(es) SSH configuration:

vagrant ssh-config

Ssh to a box:

vagrant ssh

Clean up:

# save VM's state; fastest to start again; eats most diskspace (hard disk + saved state of RAM)
vagrant suspend

# graceful shutdown; slower to start again, still eats disk space (hard disk)
vagrant halt

# power down and remove all of the guest hard disks; even slower to
# start again (reimport of the base box and reprovisioning)
vagrant destroy

Show status of all vagrant environments on the host (independent of the directory you're in):

vagrant global-status [--prune]

To share a folder from the host on the guest, add following to Vagrantfile:

config.vm.synced_folder "../../eset-repos", "/shared/eset-repos",
  owner: "jreisinger", group: "jreisinger"


  • https://docs.vagrantup.com
  • https://sysadmincasts.com/episodes/4-vagrant
  • http://docs-v1.vagrantup.com/v1/docs/