Archive for the 'Managed Services' Category

Smokeping on FreeBSD 7

Thursday, April 24th, 2008

This write-up assumes a working copy of FreeBSD 7.0.  It was built using 7.0-RELEASE.  It should work on FreeBSD 6.x-STABLE and future versions of FreeBSD 7.  The package versions listed were current as of this writing but may have been updated by the time someone uses this howto.

This is a basic setup of Smokeping.  There are many extra features that I do not touch on here such as multi-target graphs, alerting, slaves, agents and additional probe types.  Check the online documentation for further info.

Please let me know if you run into typos or other technical issues when implementing this.

1.) First let’s update the ports collection.

Setup the update:


# cd /usr/ports/ports-mgmt/portupgrade
# make install clean
# cd /usr/ports/net/cvsup
# make install clean
# cp /usr/share/examples/cvsup/ports-supfile /root/ports-supfile
# pico /root/ports-supfile

Make it look something like this:


#######################################################
*default host=cvsup1.us.FreeBSD.org
*default base=/var/db
*default prefix=/usr
*default release=cvs  tag=.
*default delete use-rel-suffix
#comment the below line if you don't want to update the /src directory
#src-all
#update /usr/ports
ports-all tag=.
#######################################################

Run the update:


# cvsup -L 2 /root/ports-supfile
# portsdb -Uu

Update installed ports:


# portversion -l "<"
# portupgrade -arR
# pkgdb -F

2.) Install the necessary packages.

Descriptions of packages and uses here: http://oss.oetiker.ch/smokeping/doc/smokeping_install.en.html

  •          Perl 5.8:
  • Installed by default with FreeBSD install

  •          RRDTool 1.2.26:

  • # cd /usr/ports/databases/rrdtool
    # make install clean

     

  •          Fping 2.4b2_to-ipv6:

  • # cd /usr/ports/net/fping
    # make install clean

     

  •          EchoPing 6.0.0:

  • # cd /usr/ports/net/echoping
    # make install clean

  •          Dig:
  • Installed by default with FreeBSD install

  •         Perl modules:
  • Socket6

    # cpan
    # install Socket6

    Net:DNS

    # install Net::DNS
    # quit

  •          Apache 2.2.8:

  • # cd /usr/ports/www/apache22
    # make install clean

  •          SpeedyCGI 2.22_4:

  • # cd /usr/ports/www/p5-CGI-SpeedyCGI/
    # make install clean

  •          Smokeping 2.2.7_2:

  • # cd /usr/ports/net-mgmt/smokeping
    # make install clean

    3.) Configure the packages.

  •          Configure Apache:

  • # pico /usr/local/etc/apache22/httpd.conf

    Add:

    (within the <IfModule alias_module> section)


    <Directory "/usr/local/smokeping/htdocs">

    Add:

    (within the <IfModule dir_module> section)

    Add smokeping.cgi after index.html on the DirectoryIndex line to allow smokeping.cgi to load as a default document.

    It should look like:

    DirectoryIndex index.html smokeping.cgi

    Allow the startup of Apache:

    Add the following to /etc/rc.conf

    apache22_enable="YES"           # enable Apache 2.2

    Start Apache:

    # /usr/local/etc/rc.d/apache22 start

  •          Configure Smokeping:
  • Edit the variables in the following files appropriately

    # pico /usr/local/etc/smokeping/config

    Variable example settings in the first section:


    owner    = Systems Administrator
    contact  = sysadmin@domain.com
    mailhost = localhost
    sendmail = /usr/sbin/sendmail
    imgcache = /usr/local/smokeping/htdocs/img
    imgurl   = /smokeping/img
    datadir  = /usr/local/var/smokeping
    piddir  = /usr/local/var/smokeping
    cgiurl   = http://server.domain.com/smokeping/smokeping.cgi
    smokemail = /usr/local/etc/smokeping/smokemail
    tmail = /usr/local/etc/smokeping/tmail

    *** Alerts ***

    The “*** Targets ***” section is where you define your Smokeping targets and build the navigation menu.  It is a little too in depth to cover here.  Play around with it to figure out how it works.

    In depth configuration info is here: http://oss.oetiker.ch/smokeping/doc/smokeping_config.en.html

    There are some configuration samples here: http://oss.oetiker.ch/smokeping/doc/smokeping_examples.en.html

    Verify the path to Speedy:

    # pico /usr/local/smokeping/htdocs/smokeping.cgi

    -first line pointing to full path of speedy

    Customizations to the Smokeping web page templates can be made in the following config files:


    /usr/local/etc/smokeping/smokemail
    /usr/local/etc/smokeping/basepage.html
    /usr/local/etc/smokeping/tmail

    Set file system permissions to make the img folder and files writeable:

    # find /usr/local/smokeping/htdocs/img -type d -exec chmod 777 {} \;
    # find /usr/local/smokeping/htdocs/img -type f -exec chmod 666 {} \;

    Allow the startup of Smokeping:

    Add the following to /etc/rc.conf

  • smokeping_enable=”YES”          # enable smokeping
  • Start Smokeping:


    # /usr/local/etc/rc.d/smokeping start

    Operational Notes:

  •          You should now be able to browse to http://www.yourdomain.com/smokeping/ to view your Smokeping statistics.
  •          You may want to consider securing the Smokeping page with .htaccess users, a firewall or other form of authentication.
  •          I updated the index.html page in the root of the default Apache site:
  •  index.html at /usr/local/www/apache22/data/

    <meta http-equiv=”refresh” content=”0;url=http://www.someotherdomain.com”/>

    This redirects traffic sent to the root of your server to a different domain since this traffic obviously doesn’t need to be hitting the Smokeping server.

  •          When you add new targets or change targets in the /usr/local/etc/smokeping/config file you will need to restart Smokeping:
  • #/usr/local/etc/rc.d/smokeping restart

     

    Installing MySQL4 and MySQL5 on a single FreeBSD 6.2 Server.

    Tuesday, March 11th, 2008

    This write-up makes the following assumptions:

    • Working copy of FreeBSD 6.2.
    • Build: 6.2-RELEASE.

    Which should work on 6.2-STABLE and 7.0 as well.

    Please let me know if you run into typos or other technical issues when implementing this.

    1. Download the latest binaries from mysql.com.
    2. At write-up time this was:

      mysql-5.0.45-freebsd6.0-i386.tar.gz
      mysql-standard-4.1.22-unknown-freebsd6.0-i386.tar.gz
    3. Install MySQL 4.
    4. Uncompress the binary source.

      # cd /usr/local
      # gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
      # ln -s full-path-to-mysql-VERSION-OS mysql4

      Create the daemon user and group.

      # pw groupadd mysql4
      # pw useradd -n mysql4 -c "" -g mysql4 -d /nonexistent -s /usr/sbin/nologin

      Set the file permissions.

      # cd /usr/local/mysql4
      # chown -R root:mysql4 .

      Run the setup database setup script.

      # scripts/mysql_install_db --user=mysql4

      Copy the startup script to the proper location.

      # cp /usr/local/mysql4/support-files/mysql.server /usr/local/etc/rc.d/mysql4.server.sh

      Change two variables in the start script.

      # pico /usr/local/etc/rc.d/mysql4.server.sh

      Change “basedir=” to “basedir=/usr/local/mysql4″
      Change “datadir=/usr/local/mysql/data” to “datadir=/usr/local/mysql4/data”
      Change “pid_file=” to “pid_file=/var/run/mysql4/mysql4.pid”

      Create configuration files.

      Copy one of the sample configuration files based on your server usage replacing xxxx in the line below.

      # cp /usr/local/mysql4/support-files/my-xxxx.cnf /usr/local/mysql4/data/my.cnf

      Change variables in the configuration file.

      # pico /usr/local/mysql4/data/my.cnf

      Add a variable at the top of the [mysqld] section - “user = mysql5″
      Change the “port = 3306″ variables to “port = 3304″
      Change the “socket = /tmp/mysql.sock” variables to “socket = /tmp/mysql4.sock”

      Create a run directory for the MySQL 4 process and set permissions on it.

      # mkdir /var/run/mysql4
      # chown -R mysql4:mysql4 /var/run/mysql4
    5. Install MySQL 5.
    6. Uncompress the binary source.

      # cd /usr/local
      # gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
      # ln -s full-path-to-mysql-VERSION-OS mysql5

      Create the daemon user and group.

      # pw groupadd mysql5
      # pw useradd -n mysql5 -c "" -g mysql5 -d /nonexistent -s /usr/sbin/nologin

      Set the file permissions.

      # cd /usr/local/mysql5
      # chown -R root:mysql5 .

      Run the setup database setup script.

      # scripts/mysql_install_db --user=mysql5

      Copy the startup script to the proper location.

      # cp /usr/local/mysql5/support-files/mysql.server /usr/local/etc/rc.d/mysql5.server.sh

      Change a few variables in the start script.

      # pico /usr/local/etc/rc.d/mysql5.server.sh

      Change “basedir=” to “basedir=/usr/local/mysql5″
      Change “datadir=” to “datadir=/usr/local/mysql5/data”
      Change “pid_file=” to “pid_file=/var/run/mysql5/mysql5.pid”
      Change “server_pid_file=” to “server_pid_file=/var/run/mysql5/mysql5.pid”
      Change “user=mysql” to “user=mysql5″

      Create configuration files.

      Copy one of the sample configuration files based on your server usage replacing xxxx in the line below.

      # cp /usr/local/mysql5/support-files/my-xxxx.cnf /usr/local/mysql5/my.cnf

      Change variables in the configuration file.

      # pico /usr/local/mysql5/my.cnf

      Add a variable at the top of the [mysqld] section - “user = mysql5″
      Change the “port = 3306″ variables to “port = 3305″
      Change the “socket = /tmp/mysql.sock” variables to “socket = /tmp/mysql5.sock”

      Create a run directory for the MySQL 5 process and set permissions on it.

      # mkdir /var/run/mysql5
      # chown -R mysql5:mysql5 /var/run/mysql5
    7. Start the daemons.
    8. # /usr/local/etc/rc.d/mysql4.server.sh start
      # /usr/local/etc/rc.d/mysql5.server.sh start
    9. Post installation configuration.
    10. MySQL4:

      Connect to MySQL

      # /usr/local/mysql4/bin/mysql -u root -P3304 -S/tmp/mysql4.sock

      Remove the anonymous account.

      mysql> DELET FROM mysql.user WHERE Host='localhost' AND User='';

      Set the root password

      mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('difficultpassword1');
      mysql> SET PASSWORD FOR 'root'@'server.domain.com' = PASSWORD('difficultpassword1');

      Create a backupoperator account for backup script access to all databases.

      mysql> GRANT ALL PRIVILEGES ON *.* TO 'backupoperator'@'localhost' IDENTIFIED BY 'difficultpassword2';

      Apply changes.

      mysql> FLUSH PRIVILEGES;

      Quit.

      mysql> QUIT;

      MySQL5:

      Connect to MySQL

      # /usr/local/mysql5/bin/mysql -u root -P3305 -S/tmp/mysql5.sock

      Remove the anonymous account.

      mysql> DROP USER '';

      Set the root password.

      mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('difficultpassword1');
      mysql> SET PASSWORD FOR 'root'@'server.domain.com' = PASSWORD('difficultpassword1');
      mysql> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('difficultpassword1');

      Create a backupoperator account for backup script access to all databases

      mysql> GRANT ALL PRIVILEGES ON *.* TO 'backupoperator'@'localhost' IDENTIFIED BY 'difficultpassword2';

      Quit

      mysql> QUIT;

    That’s it! Create your mysql users and databases and connect your applications.

    Notes:

    1. Command line connections to mysql now require additional connection info to specify port and socket:
      MySQL4 - # /usr/local/mysql4/bin/mysql -u username -ppassword -P3304 -S/tmp/mysql4.sock
      MySQL5 - # /usr/local/mysql5/bin/mysql -u username -ppassword -P3305 -S/tmp/mysql5.sock
    2. Remote connections to mysql will require specifying the correct port in the connection string instead of assuming port 3306.

    Who’s keeping score?

    Sunday, December 9th, 2007

    perfect grade mcse

    I recently attended a Microsoft Certified Systems Engineer Boot Camp, put on by TECHPROS Group, in an attempt to obtain my MCSE. Yet, the certification wasn’t the only goal, I intended to meet all the criteria for the certification - in one week.

    Back in August, I hopped on a plane from Portland, OR to Irvine, CA. To start the trip off, the plane had maintenance issues, so as we started to take off - literally as the front of the plane left the ground - the pilot immediately landed the plane. The plane barely stopped in time before its tires rolled off the end of the runway. For the next two hours we were stalled, waiting for the mechanical issues to be resolved.

    opus interactive creative

    MCSE credentials are the certifications for professionals who analyze the business requirements and design and implement the infrastructure for business solutions based on the Microsoft Windows Server System.

    Because of this travel hurdle, I arrived three hours late to the boot camp. Missing certification orientation and dinner might phase one’s moral, but here at opus:interactive, it takes more than a false start at the beginning of the race to thwart a victory - a lot more.

    The boot camp was held at a rented house in the hills outside Irvine, CA. It was a very nice house with plenty of space and rooms for all fifteen of the boot camp attendees (below). TECHPROS had great content setup for us in terms of lectures and labs (below). The first three days we worked through labs with VMware as well as lectures. I finished the first lab Sunday night before turning in around 1AM. The second day I finished the second lab by dinner time and was ready to start studying for the tests. I crammed for 14 hours straight and attempted my first test on Tuesday:

    • Exam 70-298: Designing Security for a Windows Server 2003 Network

    I passed with a perfect score 1000/1000! The rest of the day was spent going through more labs and some simulations TECHPRO had setup to prepare us for the simulations on 70-291. I studied until around 2AM and was ready to take more tests on Wednesday.

    I was the only student to attempt three tests in one day and the ones I chose were:

    • Exam 70-291: Implementing, Managing, and Maintaining a Windows Server 2003 Network Infrastructure (rumor has it, this is the most challenging of the MCSE core exams)
    • Exam 70-285: Designing a Microsoft Exchange Server 2003 Organization
    • Exam 70-270: Installing, Configuring, and Administering Microsoft Windows XP Professional

    I ended up passing all three that day with a 984/1000 on the XP test! Even with these three tests behind me, I didn’t stop. I continued cramming and working on other labs and lectures for the rest of the day into the wee hours of Thursday, turning in around 3AM.

    I wanted to continue the testing insanity and scheduled three more tests for Thursday as follows:

    • Exam 70-293: Planning and Maintaining a Windows Server 2003 Network Infrastructure
    • Exam 70-294: Planning, Implementing, and Maintaining a Windows Server 2003 Active Directory Infrastructure
    • Exam 70-284: Implementing and Managing Microsoft Exchange Server 2003

    I was again the only student to attempt three tests that passed them all in one day.

    opus interactive testing hardware

    An example of one of the testing lab setups provided by TECHPRO Group, where I completed the testing for my MCSE (+)

    The camp was winding down and there was only one more testing opportunity before the flight back to Portland on Friday afternoon. I schedule one final test on Friday morning which would achieve my MCSE +Messaging.

    I ended up taking a second test because I had two hours to kill before catching a ride to the airport. I took the following tests:

    • Exam 70-290: Managing and Maintaining a Windows Server 2003 Environment
    • Exam 70-350: Implementing Microsoft Internet Security and Acceleration (ISA) Server 2004

    Both of these test I completed and passed, which brought my total of successfully passed tests to nine in four days! (Phew, what a relief!) I was literally brain dead at this point.

    One week later I felt the itch again and decided I should take the last elective for the Security add-on to the MCSE. I quickly scheduled this test:

    • Exam 70-299: Implementing and Administering Security in a Microsoft Windows Server 2003 Network

    Another perfect score of 1000/1000! Completing that exam gave me my MCSE +Security.

    Why stop there! I thought and continued a study for the new Hosting Specialization Exam:

    • Exam 70-501: TS: Microsoft Windows Server 2003 Hosted Environments, Configuring, and Managing

    This test encapsulates what we offer here at opus:interactive and as such: I nailed it with a 987/1000 score! That achieved me the MCTS: Hosting Specialization certification as well.

    In recent months we’ve been internally studying the ITIL Foundations and was finally ready to take that exam. This particular exam was administered by EXIN the Examination Institute for Information Science and is the first step in us implementing ITIL for our organization. I studied all the material I could find and ran some practice exam engines. I was finally ready to take the test. I aced that test with a perfect score of 1000/1000! Obtaining my ITIL Foundations Certification.

    A lot of testing and a lot of proof of just how excellent our organization and team are. Some might even say: the best in the business.

    TECHPRO Bunks

    Little time was spent in these for I was busy studying!

    COM Object Issues on Windows 2003 (URLFetch)

    Thursday, August 30th, 2007

    opus interactive edition windows 2003 upgrade

    With the passage of time, there is always technological challenges that crop up for existing clients, which is why as a managed service provider we step in to eagerly correct issues so our clients need not (after all, this is what they are paying us for.) These challenges manifest themselves either through user growth, hardware limitations or in worse case scenarios: hardware failures. Recently our monitors noticed that a five year old Windows 2000 Server was about to start digging a little virtual six-foot-deep grave and this is where we stepped into the challenge.

    I quickly stabilized their old server allowing it to keep running while we worked on a migration to a new solution. While this was happening, Jeremy (our beef-jerky-loving sales representative) sold the client one of our new dedicated managed HP c-Class BladeSystem servers. The web server will be migrated to Windows 2003 and the SQL server migrated to SQL 2005 on Windows 2003 as well. Additionally, I replaced their old Cisco PIX 501 firewall.

    After the migration of content, I began setting things up, including the VPN tunnels to the third party development company and the integration with the billing system. Once this was completed, I began full regression Quality Assurance.

    After testing, it was quickly discovered that the integration with the billing engine was not working. The reason was the rather old code (Active Server Pages, ASP, version 3.0) which had been written by a third-party development company back in 1999. The code they produced relied on a component called URLFetch, which didn’t work inside of the new operating system environment.

    Here is the particular code call:

    Set trs = server.CreateObject(”URLFetch.URLFetch”)

    This component is a COM Wrapper for a few lines of Java code that allow you to, basically, screen scrape sites and return them for use in the code. Since the billing system is on an internal network behind firewalls and a VPN, it can’t be served up direct to the end-user, so it has to be done from the code on the web server. Since this was an old component it was pretty much assumed that it wouldn’t work on Windows Server 2003 and IIS 6.

    The research began about this component and the specific error that was being thrown by the code, which was:

    Microsoft VBScript runtime error ‘800a01ad’
    ActiveX component can’t create object

    I quickly found this Microsoft Knowledge base (KB) article and grabbed filemon from sysinternals to check it out.

    Using depends.exe (from Dependency Walker) I looked into finding the missing .dll that I figured was trying to be loaded behind the scenes. This was confirmed and the missing dependent file was DWMAPI.dll.

    From there a little more research uncovered another team having difficulty with the same situation. From this information the .dll was found and downloaded.

    However, this new .dll didn’t produce results and I had to start again, from ground-zero.

    It was at this point that I began to deduct that this old component would not work on the Windows 2003 and IIS6. We then contacted the client and gave them the harrowing news that the possibility that they may need to re-write their code existed. Even in the face of this possibility, we wanted to assure that all avenues had been explored and I continued researching. Next was to review the component itself and how it was written - to define what dependencies it required. This additional digging uncovered the following information:

    The most likely cause to this problem is that you don’t have the latest Microsoft Virtual Machine installed on that computer. This is especially a problem with Windows Server 2003, as it does not ship with the Microsoft Virtual Machine. Please note that this is Microsoft’s Virtual Machine, and not Sun’s Java Virtual Machine. Microsoft’s Virtual Machine can be downloaded from these locations:

    opus interactive wants you to be a pepper tooThis was the final ‘a-ha!’ moment. I then quickly downloaded the Microsoft Virtual Machine and voilà, it worked! (The new SUN Java SDK was already tried before this and it didn’t work.)

    The end result: The client’s code now works great, on the new environment, with no need to update the code-base and I got to celebrate the moment with a Dr. Pepper.

    Pf as a transparent bridging firewall on FreeBSD 6.2

    Tuesday, February 20th, 2007

    The Goal:

    We needed a way to protect a set of load balanced web servers that host public facing web sites for a client. The web servers each run a copy of the hosting control panel DirectAdmin on top of FreeBSD 6.2 Release.

    The Problem:

    DirectAdmin licensing requires a real public IP address on the server’s external interface to protect against using the license multiple times by hiding it on a private network. Many different flavors of control panel software have this requirement.

    This, of course, eliminates the ability to take the easy way out and NAT the servers behind a firewall.

    We would have simply purchased a firewall appliance for this installation (we implement GB-2000 firewall appliances by GTA Inc. however an additional requirement was to use existing 1U server hardware and not purchase an additional appliance.

    Solution:

    The end solution was to install FreeBSD 6.2 Release on the 1U server hardware and utilize packet filter (pf) as a transparent bridge to meet the IP addressing requirements.

    Hardware load balancing was used to load balance HTTP traffic to the web servers but will not be discussed here.

    Howto:

    1.) Install FreeBSD 6.2.

    We have a checklist list of tasks to perform to install and lock down our production servers. Follow your own best practices to get a basic install of FreeBSD 6.2 running and patched. Install the minimal amount of options and packages necessary.

    You will need, or at least you will most likely want, a third NIC installed in the server. In a transparent bridge the WAN and LAN interfaces become “transparent” and no longer take an IP address. So without the third NIC installed and connected to your network you will have no way to remotely manage the server. A benefit of this though is that without an IP address to attack your transparent bridging firewall itself would be free from attack.

    Pf is available in a default install by re-compiling the kernel with specific changes made, or by enabling pf via kernel loadable module.

    We re-compiled the kernel. The options below were added at the end of the kernel source and the new kernel compiled:

    # pf support
    device pf # Packet Filter firewall
    device pflog # PF logging facility
    device pfsync # PF state syncing

    # ALTQ support
    options ALTQ
    options ALTQ_CBQ
    options ALTQ_RED
    options ALTQ_RIO
    options ALTQ_HFSC
    options ALTQ_PRIQ

    2.) Configure your third NIC with an IP address and verify you can remotely access your server.

    In the /etc/rc.conf file we have the following definition for the management IF:

    ifconfig_fxp0=”inet 123.123.123.2 netmask 255.255.255.0″

    We will be building pf rules for this NIC as well to protect the firewall itself.

    3.) Create the bridge between the two desired interfaces.

    Use your favorite editor to edit /etc/rc.conf and enable the bridge

    Add:

    cloned_interfaces=”bridge0″
    ifconfig_bridge0=”addm bge0 addm nfe0 up”
    ifconfig_bge0=”up”
    ifconfig_nfe0=”up”

    In this case we are bridging the two interfaces bge0 and nfe0.

    Use your favorite editor to edit /etc/sysctl.conf

    Add:

    net.link.bridge.pfil_onlyip=1
    net.link.bridge.pfil_member=1
    net.link.bridge.pfil_bridge=0

    4.) Enable the use of pf on your server.

    Use your favorite editor to edit /etc/rc.conf and enable the use of pf

    Add:

    pf_enable=”YES” # enable PF (load module if required)
    pf_rules=”/etc/pf-bridge.conf” # rules definition file for pf
    pf_flags=”" # additional flags for pfctl startup
    pflog_enable=”YES” # start pflogd(8)
    pflog_logfile=”/var/log/pflog” # where pflogd should store the logfile
    pflog_flags=”" # additional flags for pflogd startup

    5.) Build the firewall ruleset.

    First make a copy of the default ruleset and designate it as a bridging ruleset.

    # cp /etc/pf.conf /etc/pf-bridge.conf

    Use your favorite editor to edit /etc/pf-bridge.conf. Place your ruleset within the pf-bridge.conf file and save the changes.

    Here is the sample ruleset we used: pf-bridge_generic.txt

    6.) Apply the rules and enable the firewall.

    Finally to actually enable a new ruleset we need to tell pf to read the config file. This would also automatically happen upon reboot.

    # pfctl –f /etc/pf-bridge.conf
    # pfctl –e

    That’s it! You will now need to go through and test the bridge and verify you can access what you intended to allow access to, and that what you wanted to block is now blocked. Hopefully you still have access to the management interface as well. The best test will be to perform some form of vulnerability testing against IPs behind your firewall and the firewall itself.

    Some notes on the ruleset specifically:

  • There is really nothing in the ruleset that designates the firewall as a transparent bridge other than the absence of NAT rules. The bridge built in the OS itself in the /etc/rc.conf file is where the bridging is applied.
  • The IP addresses in the variable and table definitions will obviously have to be updated to fit a different environment.
  • Many options exist for pf and there are full books dedicated to the art of pf rulesets and using pf in general. This ruleset for example could be expanded to make more use of AltQ for QoS and added protection against DoS attacks.
  • Hurdles:

    The first major hurdle we ran into had to do with Multiple MAC address tables on the switch (or lack thereof). We wanted to use a single switch to handle the connectivity for both the inside (LAN) and outside (WAN) of my transparent bridge. To do this we created two VLANs on the switch so that the WAN IF of the bridge connected to VLAN 1 and the LAN IF and the web servers connected to VLAN 2.

    The problem is that because of the bridging, the MAC addresses of the web server network adapters were now appearing in both VLANs on the switch thoroughly confusing it.

    It turns out that the switch we were using – an older HP Procurve – only had a single MAC address table.

    The interim solution was to use two switches, one for each side of the transparent bridge. A better solution will be to use a switch that has more than one MAC address table so that we can use only a single switch for this solution.

    The second hurdle is really only the fact that it can take time to perfect the pf ruleset. There are so many options and more than one way to do the same thing. Keep working till it works out correctly.

    Some additional commands for managing pf:

    # pfctl -s rules : list current parsed rules
    # pfctl -f filename : reload the ruleset with the specified file
    # pfctl -d : disable pf
    # pfctl -e : enable pf
    # pfctl -R /etc/pf.conf : enable rules from specified file
    # pfctl -s rules -v : hit stats for each rule

    View current log with TCPDump:

    Log specific tcp packets to a different log file with a large snaplen
    (useful with a log-all rule to dump complete sessions)

    # pflogd -s 1600 -f suspicious.log port 80 and host evilhost

    Display binary logs:
    # tcpdump -n -e -ttt -v -r /var/log/pflog

    Display the logs in real time (this does not interfere with the operationof pflogd):

    # tcpdump -nexttti pflog0