Friday 25 November 2011

Asterisk


Asterisk

 (VoIP)


1. Overview

Telephone communication has not changed radically since the telephone was invented in the late 1800s. New technologies like digital circuits, DTMF (or, "touch tone"), and caller ID have improved on this invention, of course, but its basic functionality still remains the same. Over the years, service providers made a number of innovative changes in order to improve the kinds and types of services offered to subscribers, including toll-free numbers, call-return, and call-forwarding, etc. By and large, users did not know how these services worked, but they did know two things: the same old telephone is used, and the service provider charges for every incremental service addition introduced.

In the 1990s, a number of individuals in research environments, both in educational and in corporate institutions, began to take a serious interest in carrying voice and video over IP networks, especially over corporate Intranets and the Internet. This technology is commonly referred to today as Voice over Internet Phone (VoIP). It is the process of breaking up audio or video into small chunks, transmitting those chunks over an IP network, and reassembling those chunks at the far end so that two people can communicate using both audio and video.

The idea of VoIP is certainly not new, as there are research papers and patents dating back several decades; and demonstrations of the concept have been given at various times over the years. VoIP took center stage with the "information super highway" (or, the Internet) concept that was popularized by former US Vice President Al Gore in the 1990s. It was envisioned that the Internet would make it possible to interconnect every home and every business with a packet-switched data network. Before Al Gore's effort to grow the Internet, the Internet was generally limited to use in academic environments only, but the possibility of mass deployment of the Internet sparked renewed interest in VoIP.

2. Introduction

Asterisk© is a Linux-based IPBX application developed by Mark Spencer of Digium™, the company behind Asterisk. Asterisk@Home© evolved from the core of Asterisk. It is made up of several major components. These were developed under the GNU General Public License (GPL), supported relatively by the users themselves. It consists of applications, a provisioning system, an installer, and an operating system that, together, constitute a complete package ready-for-use as an out-of-the-box PBX.

For the purposes of this tutorial, the major components of Asterisk@Home© include:

1.   Asterisk, the core PBX
2.   Flash Operator Panel, a screen-based operator’s console
3.   Asterisk Management Portal (AMP), a web-based provisioning tool for Asterisk
4.   A report system - that part of the AMP which provides CDR reporting tools
5.   A maintenance system, also a part of the AMP, which provides low-level interfaces to some components, and real-time system information
6.   CentOS, a version of Linux related to Enterprise Linux (but without the branding and the support)

2.1. The Components

Two main components need to be set up:

  • An Asterisk-powered IP PBX
  • The phones (or softphones)
  • Network

2.1.1. The IP PBX

A dedicated PC is needed in order to run an IP PBX. The PC described below is sufficient enough to power an IPBX in a small office environment:

  • 600 Mhz Pentium III PC or better
  • 256 MB RAM – minimum
  • 10 GB hard disk space - minimum
  • 10/100 NIC
  • CD-ROM Drive
  • 10/100 4 or 8 ports Ethernet switch

2.1.2. Phones

You can use soft phones as well as hard phones from Planet, and Cisco, etc.

To get started, it is easiest to get a softphone, and run it on another computer. For details, see the section on how to install a softphone.

2.1.3. Network

A static IP address is needed to run Asterisk on a network (e.g. 192.168.0.12).

3. Installation and Configurations


  • Burn the downloaded ISO image onto a blank CD.
  • Ensure that your PC will boot from the CD. If necessary, change the BIOS settings to reflect this. Warning: This will erase all the data on the hard drives of the PC. If you have two drives, both may be erased as well - beware.
  • Boot your Asterisk PC with the CD in the CD drive, and press the “Enter” key. 


  • Press the “Enter” key to start the installation. It will take approximately 30 minutes for the installation to be complete ready for the configuration stage.
  • During this stage, you will see screens similar to the following.  Linux and the required files are being installed. Wait for the process to end.


  • After Linux is loaded, the CD will eject. Take the CD out, and wait for the system to reboot. You will then be presented with lines and lines of code. This process will take a while because it is building Asterisk.

Change Default Settings
Once Asterisk@Home has been installed, some default system changes need to be made to Asterisk.

Log in to your new Asterisk@Home box (user: root, password: password)


To get help, At the command-line, type:

            help-aah

A help list will be displayed:

Change the Linux Password

Note: Change your root password immediately by typing:
passwd

 
Change some of the other default passwords as well; set your date, and the IP address of your box to a static address.

Change the IP Address 

Change the Asterisk IP address from DHCP to static. At the command prompt, type:
netconfig



Select [Yes] to set up networking, and hit the “Enter” key.


Use the “Tab” key to switch between various fields. Enter the IP address that is to be allocated to the Asterisk box, the Netmask (sub-net mask), Default Gateway and Primary nameserver, as per the example given above. 
Select “OK”, and reboot the system.

 

Set Time Zone

Set the correct time zone. The following examples depend on whether you are setting up AAH 1.x or AAH 2.x.

For AAH 1.x type the following at the command-line:

redhat-config-date

You will get the screen on the left; choose an appropriate time zone. Check the system clock. Use UTC if you want to.

Choose “OK” to complete the process.


For AAH 1.5 and 2.x, type the following at the command-line:

config

You will get the prompt as per the screen on the right.

Press D.

You will then be presented with the time zone screen.

Choose your time zone to complete the process.

Log off Linux and reboot. Asterisk will now start with the new IP address.

4. Connect to AMP from a Web Browser

Connect to http://ipaddress/ (e.g. http:192.168.1.7) to configure Asterisk@Home. You will be presented with an Asterisk Management Portal (AMP) as illustrated below:

4.1 Logging into an Asterisk Management Portal (AMP)

To log in to an Asterisk Management Portal (AMP) use the user: maint, and the password: password, unless you have changed the password during the initial set up.

Once you have logged into an AMP, you will be presented with the following screen:


Select the Setup tab and you will be presented with the following screen.

This is where you start configuring Asterisk@Home. Notice the selection options on the left hand side. Selecting each option will display a configuration screen for that particular function e.g. creating new extensions, creating new trunks, etc.

4.2. General Settings

Select General Settings, and set them up as illustrated below:


Hover your mouse over the corresponding field description. An amber underline will display the purpose of the fields.

In the Asterisk Dial command option, customize your preferences regarding Asterisk’s “behavior”, e.g. if you want the caller to hear music instead of the standard ringing sound, replace the “r” with an “m”. For further options, hover your mouse over the label, and you will be informed about other options. After setting up the General Settings, click on the “Submit Changes” button, and the red bar on the top of the screen for the changes to take place.

4.3. Extensions

The number of extensions to be set up depends upon you. You can have soft phones installed in four or five computers, or have a mixture of ATAs and SIP SoftPhones.

The following extension numbers should be avoided:

200 -                             Park notify
300-399 -                       Reserved for speed-dial
70-79 -                          Reserved for call-on-hold
80-89 -                          Reserved for meet-me and conference
800-899 -                       Reserved for meet-me and conference
8000-8999 -                   Reserved for meet-me and conference
80000-89999 -                Reserved for meet-me and conference

Select the type of trunk e.g. SIP, IAX2, ZAP or Custom, from the Create Extension main menu illustrated below:


The AAH v2.x’s screen, where you actually create an extension, is given below:



Click on the “Add Extension” button to add more extensions, e.g. 201, 202, 2000 and 2001.

Allocate the password in the numeric form. If you enabled Voicemail, allocate the same password as well. You may also nominate an e-mail address for Voicemail e-mail notification.

5. Setting the soft phone

Now that Asterisk is up, you need to setup up a soft phone. The following soft phones can be used with Asterisk:

2.     DIAX softphone
3.     eStara softphone
5.     FireFly softphone
6.     Iaxcomm softphone
9.     KIAX softphone

We will use the BOL SIPPhone. It is extremely simple to set up for use with Asterisk, and it also features a call-forwarding facility.

Obtain a copy of the BOL 2000 SIPPhone from http://www.bol2000.com/download/sipphone/

After downloading and set up, the following screen will be displayed when it runs:

5.1. Profile Tab

This is the only screen that is required to be filled in.

Account: <enter the extension number e.g. 201>
Password: <enter the password e.g. 201>


Domain/Realm: <leave it blank>
Proxy: Your Asterisk network address e.g. 192.168.1.7
Port: 5060

Check the Auto Login and Keep Password.
Click OK.

5.2. Audio and Video Tab

Click on the “Audio & Video” tab to ensure that the audio properties set is consistent with the audio card installed in your PC/Notebook.


  • Click on the Tuning Wizard to tune your audio input and output.
  • Check Auto Send Video, if you are using video. Check it anyway.
  • Check Auto Receive Video, if you are using video. Check it anyway.

Click OK.

5.3. Network Tab

Ensure that your Internet Connection Type is set to LAN.

Ignore the “Information of Network” field.

Click OK.

5.4. Call-forwarding

To forward an unanswered call to an extension, click on the “Call Forward” tab, and enter the telephone number you want to forward your incoming calls to. You have three options of call-forwarding – Always On, Busy, or No Answer. This facility is only available, however, if your PC is on, and the softphone is active.

Click OK.

You might want to set-up a couple of PCs with the softphone, after which you can start testing your new phone system by dialing each extension in turn.

If you use one of the softphones and dial 7777, Asterisk will simulate an incoming call.

Once done, test your softphone connection to Asterisk.

To check if Asterisk is running
Click on the “System Status” tab. You will be presented with the following screen:


5.5. Flash Operator Panel (FOP)

The Flash Operator Panel is a switchboard-type application for the Asterisk PBX. It runs on a web browser with the Flash plug-in. It is able to display information about your PBX activity in real-time. The layout is configurable (button sizes and colors, icons, etc). You can have more than 100 buttons active per screen.

It also supports contexts: you can have one server running, and many different client displays (for hosted PBX, different departments, etc).

It can integrate with CRM software, by popping up a web page (and passing the CLID) when a specified button is ringing.


The following information is displayed on the FOP:

  • Which extensions are busy, ringing, or available
  • Who is talking and to whom (CLID, context, priority)
  • SIP and IAX registration, and reach status
  • Queue status (the number of waiting users)
  • Message Waiting Indicator and count
  • Parked channels
  • Logged-in agents

Functions you can perform on FOP:

  • Hang-up a channel
  • Using drag-and-drop to transfer a call
  • Initiate calls by drag-and-drop
  • Barge in on a call using drag-and-drop
  • Set the caller ID when transferring or originating a call
  • Automatically pop-up a web page with customer details
  • Click-to-dial from a web page


Firewalls


Firewalls



1. Introduction

Firewalls make it possible to filter incoming and outgoing traffic that flows through your system. A firewall can use one or more sets of “rules” to inspect the network packets as they come in or go out of your network connections, and either allows the traffic through, or blocks it. The rules of a firewall can inspect one or more characteristics of the packets, including, but not limited to, the protocol type, the source or destination host address, and the source or destination port.

Firewalls can greatly enhance the security of a host or a network. They can be used to perform one or more of the following actions:

  • To protect and insulate the applications, services and machines of your internal network from unwanted traffic coming in from the public Internet.
  • To limit or disable access from hosts of the internal network to services of the public Internet.
  • To support Network Address Translation (NAT), which allows your internal network to use private IP addresses and share a single connection to the public Internet (either with a single IP address or by a shared pool of automatically assigned public addresses).

2. Concepts

There are two basic ways to create firewall rulesets: “inclusive” or “exclusive”. An exclusive firewall allows all traffic through, except for the traffic matching the ruleset. An inclusive firewall does the reverse. It only allows traffic matching the rules through, and blocks everything else.
Inclusive firewalls are generally safer than exclusive firewalls because they significantly reduce the risk of allowing unwanted traffic to pass through the firewall.
Security can be further tightened using a “stateful firewall”. This firewall keeps track of which connections are opened through the firewall, and will only allow traffic through which either matches an existing connection, or opens a new one. The disadvantage of a stateful firewall is that it can be vulnerable to Denial of Service (DoS) attacks if a lot of new connections are opened very quickly. It is generally possible to use a combination of stateful and non-stateful behavior to make an optimal firewall for a website.
Many firewall packages are available for UNIX-flavored systems. IPFW is the easiest and most efficient IP-based firewall system currently running on FreeBSD OS.

3. IPFIREWALL (IPFW)

The IPFIREWALL (IPFW) is a FreeBSD-sponsored firewall software application, authored and maintained by FreeBSD volunteer staff members. It uses the legacy stateless rules and a legacy rule coding technique to achieve what is referred to as Simple Stateful logic.
The IPFW sample rule set (found in /etc/rc.firewall) in the standard FreeBSD install is rather simple and it is not expected that it used directly without modifications. The example does not use stateful filtering, which is beneficial in most setups, so it will not be used as base for this section.
The IPFW stateless rule syntax is empowered with technically sophisticated selection capabilities, which far surpass the knowledge level of the customary firewall installer. IPFW is targeted at professional users and at advanced technical computer hobbyists who have advanced packet selection requirements. A high degree of detailed knowledge into how different protocols use and create their unique packet header information is a prerequisite. Providing that level of explanation is out of the scope of this tutorial.
IPFW is composed of seven components:
1.     The primary component is the kernel firewall filter rule processor and its integrated packet accounting facility
2.     The logging facility
3.     The 'divert' rule which triggers the NAT facility
4.     The advanced special purpose facilities
5.     The dummynet traffic shaper facilities
6.     The 'fwd rule' forward facility
7.     The bridge facility
8.     The ipstealth facility

3.1. Enabling IPFW

IPFW is included in the basic FreeBSD installation package as a separate run-time loadable module. The system dynamically loads the kernel module when the rc.conf statement firewall_enable="YES" is used. Do not compile IPFW into the FreeBSD kernel unless you want the NAT function enabled.
After rebooting your system with firewall_enable="YES" in rc.conf the following message, highlighted in white, is displayed on the screen as part of the boot process:
ipfw2 initialized, divert disabled, rule-based forwarding disabled, default to deny, logging disabled
The loadable module already has logging ability compiled in it. To enable logging and set the verbose logging limit, there is a knob you can set in /etc/sysctl.conf by adding these statements; logging will be enabled on future reboots:
net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose_limit=5

3.1.1. Kernel Options

It is not a mandatory requirement to enable IPFW by compiling the following options into the FreeBSD kernel unless you need the NAT function. It is presented in this tutorial as background information:
options    IPFIREWALL
This option enables IPFW as part of the kernel.
options    IPFIREWALL_VERBOSE
Enables logging of packets that pass through IPFW and have the 'log' keyword specified in the rule set.
options    IPFIREWALL_VERBOSE_LIMIT=5
Limits the number of packets logged through syslogd on a per-entry basis. Use this option in hostile environments in which you want to log firewall activity. This will close a possible Denial of Service (DoS) attack via syslog flooding.
options    IPFIREWALL_DEFAULT_TO_ACCEPT
This option will allow everything to pass through the firewall by default, which is a good idea when you are first setting up your firewall.
options    IPV6FIREWALL
options    IPV6FIREWALL_VERBOSE
options    IPV6FIREWALL_VERBOSE_LIMIT
options    IPV6FIREWALL_DEFAULT_TO_ACCEPT
These options are exactly the same as the IPv4 options, but they are for IPv6. If you do not use IPv6, you might want to use IPV6FIREWALL without any rules to block all IPv6.
options    IPDIVERT
This enables the use of the NAT functionality.

Note: If you do not include IPFIREWALL_DEFAULT_TO_ACCEPT or set your rules to allow incoming packets, you will block all packets going to, and from, your machine.

3.1.2. /etc/rc.conf Options

If you do not have IPFW compiled into your kernel, you will need to load it with the following statement in /etc/rc.conf:

firewall_enable="YES"

Set the script to run to activate your rules:

firewall_script="/etc/ipfw.rules"

Enable logging:
firewall_logging="YES"

The IPFW command is the normal vehicle for making manual single rule additions or deletions to the firewall’s active internal rules while it is running. The problem with using this method is, once your system is shutdown or halted, all the rules you added, changed, or deleted, are lost. Writing all your rules in a file, and using that file to load the rules at boot time, or to replace, en masse, the currently running firewall rules with changes you made to the file’s content, is the recommended method used here.

The IPFW command is very useful to display the running firewall rules to the console screen. The IPFW accounting facility dynamically creates a counter for each rule that counts each packet that matches the rule. During the process of testing a rule, listing the rule with its counter is one of the ways of determining if the rule is functioning.

To list all the rules in sequence:

# ipfw list

To list all the rules with a time stamp of when the last time the rule was matched:

# ipfw -t list

To list the accounting information, packet-count the matched rules along with the rules themselves. The first column is the rule number, followed by the number of outgoing matched packets, followed by the number of incoming matched packets, and then the rule itself:
                 
# ipfw -a list

List the dynamic rules in addition to the static rules:
# ipfw -d list

Show the expired dynamic rules:

# ipfw -d -e list

Zero the counters:
# ipfw zero

Zero the counters for just rule NUM:

# ipfw zero NUM

3.3. IPFW Rule Sets

A rule set is a group of IPFW rules coded to allow or deny packets based on the values contained in the packet. The bi-directional exchange of packets between hosts comprises a session conversation. The firewall rule set processes the packet twice: once on its arrival from the public Internet host, and again as it leaves for its return trip back to the public Internet host. Each TCP/IP service (i.e. Telnet, www, mail, etc.) is pre-defined by its protocol, and by its port number. This is the basic selection criteria used to create rules which will allow or deny services.

When a packet enters the firewall, it is compared against the first rule in the rule set. It then progresses one rule at a time, moving from top to bottom of the set in an ascending rule number sequence order. When the packet matches a rule selection’s parameters, the rules action field value is executed, and the search of the rule set terminates for that packet. This is referred to as “the first match wins” search method. If the packet does not match any of the rules, it gets caught by the mandatory IPFW default rule, number 65535, which denies all packets, and discards them, without any reply, back to the originating destination.

The instructions contained here are based on using rules that contain the stateful 'keep state', 'limit', 'in'/'out', and ‘via’ options. This is the basic framework for coding an inclusive type firewall rule set.

An inclusive firewall only allows those services to come through which match the rules. In this way, you can control which services can originate behind the firewall destined for the public Internet, and also control the services which can originate from the public Internet accessing your private network. Everything else is denied by the default design. Inclusive firewalls are much more secure than exclusive firewall rule sets, and are the only rule set type covered in this tutorial.

3.3.1. Rule Syntax

The rule syntax presented here has been simplified to include only that which is necessary to create a standard inclusive type firewall rule set.

Rules contain keywords; these keywords have to be coded in a specific order from left to right on the line. Keywords are identified in bold type. Some keywords have sub-options, which may be keywords themselves, and also include more sub-options.

# is used to mark the start of a comment and may appear at the end of a rule line, or on its own lines. Blank lines are ignored.

CMD RULE_NUMBER ACTION LOGGING SELECTION STATEFUL
CMD
Each new rule has to be prefixed with add to add the rule to the internal table.

RULE_NUMBER
Each rule has to have a rule number to go with it.

ACTION
A rule can be associated with one of the following actions, which will be executed when the packet matches the selection criterion of the rule.

allow | accept | pass | permit
All these words mean the same thing, which is to allow packets that match the rule to exit the firewall rule processing. The search terminates at this rule.
check-state
It checks the packet against the dynamic rules table. If a match is found, execute the action associated with the rule which generated this dynamic rule, otherwise move onto the next rule. The check-state rule does not have a selection criterion. If no check-state rule is present in the rule set, the dynamic rules table is checked at the first keep-state or limit rule.
deny | drop
Both words mean the same thing, which is to discard packets that match this rule. The search terminates.
LOGGING
log or logamount

When a packet matches a rule with the log keyword, a message will be logged to syslogd with a facility name of SECURITY. The logging only occurs if the number of packets logged so far for that particular rule does not exceed the logamount parameter. If no logamount is specified, the limit is taken from the sysctl variable net.inet.ip.fw.verbose_limit. In both cases, a value of zero removes the logging limit. Once the limit is reached, logging can be re-enabled by clearing the logging counter or the packet counter for that rule; see the IPFW reset log command.

SELECTION
The keywords described below are used to describe the attributes of the packet to be interrogated when determining whether the rules match the packet or not. The following general-purpose attributes are provided for matching, and must be used in this order:

udp | tcp | icmp

or any protocol names found in /etc/protocols are recognized and may be used. The value specified has a protocol to be matched against. This is a mandatory requirement.

from src to dst

The ‘from’ and ‘to’ keywords are used to match against IP addresses. Rules must specify both the source and the destination parameters. ‘any’ is a special keyword that matches any IP address. ‘me’ is a special keyword that matches any IP address configured on an interface in your FreeBSD system to represent the PC the firewall is running on (i.e. this box) as in 'from me to any' or 'from any to me' or 'from 0.0.0.0/0 to any' or 'from any to 0.0.0.0/0' or 'from 0.0.0.0 to any' or 'from any to 0.0.0.0' or 'from me to 0.0.0.0'. IP addresses are specified as a dotted IP address numeric form/mask-length, or as a single-dotted IP address numeric form. This is a mandatory requirement.

port number

For protocols which support port numbers (such as TCP and UDP). It is mandatory that you code the port number of the service you want to match it with. Service names (from /etc/services) may be used instead of numeric port values.

in | out

The keywords ‘in’ and ‘out’ match incoming or outgoing packets, respectively; it is mandatory that you code one or the other as part of your rule-matching criterion.

via IF

Matches packets going through an interface specified by an exact name. The ‘via’ keyword causes the interface to always be checked as part of the matching process.

setup

This is a mandatory keyword that identifies the session start request for TCP packets.

keep-state

This is a mandatory keyword. Upon a match, the firewall will create a dynamic rule, whose default behavior is to match bi-directional traffic between the source and the destination IP/port using the same protocol.

limit {src-addr | src-port | dst-addr | dst-port}

The firewall will only allow N connections with the same set of parameters as specified in the rule. One or more of the source and destination addresses and ports can be specified. Both 'limit' and 'keep-state' cannot be used on the same rule. Also, ‘limit’ provides the same stateful function as 'keep-state', plus its own functions.

STATEFULL Rule Option
Stateful filtering treats traffic as a bi-directional exchange of packets comprising a session conversation. It has the interrogation abilities to determine if the session conversation between the originating sender and the destination are following the valid procedure of a bi-directional packet exchange. Any packets that improperly fit the session conversation template are automatically rejected as impostors.

'check-state' is used to identify where, in the IPFW rules set, the packet is to be tested against the dynamic rules facility. Upon finding a match, the packet exits the firewall to continue on its way, and a new rule is dynamically created for the next anticipated packet being exchanged during this bi-directional session conversation. Upon not matching, the packet advances to the next rule in the rule set for testing.

The dynamic rules facility is vulnerable to resource depletion from a SYN-flood attack, which can open a huge number of dynamic rules. To counter this attack, FreeBSD Version 4.5 has added another new option known as ‘limit'. This option is used to limit the number of simultaneous session conversations by interrogating the rules source or destinations fields as directed by the limit option and using the packet's IP address found there, in a search of the open dynamic rules counting the number of times this rule and IP address combination occurred, if this count is greater that the value specified on the limit option, the packet is discarded.

Logging Firewall Messages
Logging provides the ability to review, after the fact, the rules you activated logging on. This provides information such as which packets had been dropped, which addresses they had come from, and where they were going. This process provides a significant edge in tracking down attackers.
Even with the logging facility enabled, IPFW does not generate any rule-logging on its own. The firewall administrator decides which rules in the rule set require logging, and adds the log verb to those rules. Normally only deny rules are logged, like the deny rule for incoming ICMP pings. It is customary to duplicate the IPFW default deny everything rule, with the log verb included as the last rule in the rule set. This way, the administrator gets to see all the packets that did not match any of the rules in the rule set.
Logging is a two-edged sword; if you are not careful, you can lose yourself in an over-abundance of log data, and fill up your disk with growing log files. A DoS attack that fills up disk drives is one of the oldest attacks around. These log messages are not only written to syslogd, but are also displayed on the root console screen, and soon become very annoying.
The IPFIREWALL_VERBOSE_LIMIT=5 kernel option limits the number of consecutive messages sent to the system logger syslogd concerning the packet-matching of a given rule. When this option is enabled in the kernel, the number of consecutive messages concerning a particular rule is capped at the number specified. There is nothing to be gained from 200 log messages saying the same thing. Five consecutive messages concerning a particular rule, for example, will be logged to syslogd, the remaining identical consecutive messages will be counted, and posted to syslogd with a phrase like this:
last message repeated 45 times
All logged packets’ messages are written by default to the /var/log/security file, which is defined in the /etc/syslog.conf file.

3.4. Building a Rule Script

Most experienced IPFW users create a file containing the rules, and code them in a manner compatible with running them as a script. The major benefit of doing this is that the firewall rules can be refreshed en masse without the need to reboot the system to activate the new rules. This method is very convenient in testing new rules, as the procedure can be executed as many times as is necessary. Being a script, you can use symbolic substitution to code frequently used values and substitute them in multiple rules.

Consider the following example. The script syntax used here is compatible with the 'sh', 'csh', 'tcsh' shells. Symbolic substitution fields are prefixed with a dollar sign $. Symbolic fields do not have the $ prefix. The value to populate the symbolic field must be enclosed in "double quotes".

Start your rules’ file like this:

############### start of example ipfw rules script #############
#
ipfw -q -f flush       # Delete all rules
# Set defaults
oif="tun0"             # out interface
odns="192.0.2.11"      # ISP's DNS server IP address
cmd="ipfw -q add "     # build rule prefix
ks="keep-state"        # just too lazy to key this each time
$cmd 00500 check-state
$cmd 00502 deny all from any to any frag
$cmd 00501 deny tcp from any to any established
$cmd 00600 allow tcp from any to any 80 out via $oif setup $ks
$cmd 00610 allow tcp from any to $odns 53 out via $oif setup $ks
$cmd 00611 allow udp from any to $odns 53 out via $oif $ks
################### End of example ipfw rules script ############

The rules are not important in this example; how the symbolic substitution field is populated and used is.

If the above example is in the /etc/ipfw.rules file, you can reload these rules by typing:

# sh /etc/ipfw.rules

The /etc/ipfw.rules file can be located and named according to your preference. This can also be accomplished by running the following commands:

# ipfw -q -f flush
# ipfw -q add check-state
# ipfw -q add deny all from any to any frag
# ipfw -q add deny tcp from any to any established
# ipfw -q add allow tcp from any to any 80 out via tun0 setup keep-state
# ipfw -q add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state
# ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state



Stateful Ruleset
The following non-NATed rule set is an example of how to code a very secure 'inclusive' type of firewall. An inclusive firewall only allows those services to pass through that match the rules, and blocks all other by default. All firewalls have a minimum of two interfaces, which have to have rules to allow the firewall to function.

All UNIX® flavored operating systems, FreeBSD included, are designed to use the interface lo0 and the IP address 127.0.0.1 for internal communication within an operating system. The firewall rules must contain rules to allow the free movement of these special, internally-used packets.

The interface which faces the public Internet is the one which you code your rules to authorize and control access out to the public Internet and access requests arriving from the public Internet. This can be your ppp tun0 interface, or your NIC that is connected to your DSL or cable modem.
In cases where one or more than one NIC is connected to a private LAN behind the firewall, the interfaces must have rules coded to allow the free movement of packets originating from those LAN interfaces.

The rules should first be organized into three major sections: all the free interfaces; the public interface outbound, and the public interface inbound.

The order of the rules in each of the public interface sections should be in order of the most-used rules being placed before less often-used rules, with the last rule in the section being a block log all packets on that interface and direction.

The ‘Outbound’ section in the following rule set only contains 'allow' rules, which contain selection values that uniquely identify the service that is authorized for public Internet access. All the rules have proto, port, in/out, via and keep state option coded. The 'proto tcp' rules have the 'setup' option included to identify the start session request as the trigger packet to be posted to the keep state stateful table.

The ‘Inbound’ section contains all the blocking of unwelcome packets for two different reasons. Firstly, the packets being blocked may be part of an otherwise valid packet, which may be allowed in by later authorized service rules. Secondly, this rule explicitly blocks selected packets that one receives on an infrequent basis, and does not want to see in the log. This keeps them from being caught by the last rule in the section, which blocks and logs all packets which have fallen through the rules. This last rule creates the legal evidence needed to prosecute the people who are attacking your system.

No response is returned for any unwelcome material; their packets just get dropped and vanish. This way, the attacker has no knowledge of whether his or her packets have reached your system. The less the attackers can learn about your system, the more secure it is. When you log packets with port numbers you do not recognize, look the numbers up in /etc/services/ or go to http://www.securitystats.com/tools/portsearch.php and look up a port number to find what its purpose is. Visit http://www.simovits.com/trojans/trojans.html for port numbers used by Trojans.

3.4.1. A Sample Inclusive Rule set

The following non-NATed rule set is a completely inclusive type rule set. Comment out any pass rules for services you do not want. If you see any unwelcome messages in your log, add a deny rule in the inbound section. Change the 'dc0' interface name in every rule to the interface name of the NIC that connects your system to the public Internet. For user ppp it would be 'tun0'.

Observe a pattern in the usage of these rules:
  • All statements that are a request to start a session to the public Internet use ‘keep-state’.
  • All the authorized services that originate from the public Internet have the ‘limit’ option to stop flooding.
  • All rules use ‘in’ or ‘out’ to clarify direction.
  • All rules use the ‘via’ interface name to specify the interface the packet is travelling over.
The following rules go into /etc/ipfw.rules.
################ Start of IPFW rules file ###############################
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"
pif="dc0"     # public interface name of NIC
              # facing the public Internet

#################################################################
# No restrictions on Inside LAN Interface for private network
# Not needed unless you have LAN.
# Change xl0 to your LAN NIC interface name
#################################################################
#$cmd 00005 allow all from any to any via xl0

#################################################################
# No restrictions on Loopback Interface
#################################################################
$cmd 00010 allow all from any to any via lo0

#################################################################
# Allow the packet through if it has previous been added to the
# the "dynamic" rules table by a allow keep-state statement.
#################################################################
$cmd 00015 check-state

#################################################################
# Interface facing Public Internet (Outbound Section)
# Interrogate session start requests originating from behind the
# firewall on the private network or from this gateway server
# destine for the public Internet.
#################################################################

# Allow out access to my ISP's Domain name server.
# x.x.x.x must be the IP address of your ISP.s DNS
# Dup these lines if your ISP has more than one DNS server
# Get the IP addresses from /etc/resolv.conf file
$cmd 00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state
$cmd 00111 allow udp from any to x.x.x.x 53 out via $pif keep-state

# Allow out access to my ISP's DHCP server for cable/DSL configurations.
# This rule is not needed for .user ppp. connection to the public Internet.
# so you can delete this whole group.
# Use the following rule and check log for IP address.
# Then put IP address in commented out rule & delete first rule
$cmd 00120 allow log udp from any to any 67 out via $pif keep-state
#$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state

# Allow out non-secure standard www function
$cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state

# Allow out secure www function https over TLS SSL
$cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state

# Allow out send & get email function
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state

# Allow out FBSD (make install & CVSUP) functions
# Basically give user root "GOD" privileges.
$cmd 00240 allow tcp from me to any out via $pif setup keep-state uid root

# Allow out ping
$cmd 00250 allow icmp from any to any out via $pif keep-state

# Allow out Time
$cmd 00260 allow tcp from any to any 37 out via $pif setup keep-state

# Allow out nntp news (i.e. news groups)
$cmd 00270 allow tcp from any to any 119 out via $pif setup keep-state

# Allow out secure FTP, Telnet, and SCP
# This function is using SSH (secure shell)
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state

# Allow out whois
$cmd 00290 allow tcp from any to any 43 out via $pif setup keep-state

# deny and log everything else that.s trying to get out.
# This rule enforces the block all by default logic.
$cmd 00299 deny log all from any to any out via $pif

#################################################################
# Interface facing Public Internet (Inbound Section)
# Interrogate packets originating from the public Internet
# destine for this gateway server or the private network.
#################################################################

# Deny all inbound traffic from non-routable reserved address spaces
$cmd 00300 deny all from 192.168.0.0/16 to any in via $pif  #RFC 1918 private IP
$cmd 00301 deny all from 172.16.0.0/12 to any in via $pif     #RFC 1918 private IP
$cmd 00302 deny all from 10.0.0.0/8 to any in via $pif          #RFC 1918 private IP
$cmd 00303 deny all from 127.0.0.0/8 to any in via $pif        #loopback
$cmd 00304 deny all from 0.0.0.0/8 to any in via $pif            #loopback
$cmd 00305 deny all from 169.254.0.0/16 to any in via $pif   #DHCP auto-config
$cmd 00306 deny all from 192.0.2.0/24 to any in via $pif       #reserved for docs
$cmd 00307 deny all from 204.152.64.0/23 to any in via $pif  #Sun cluster interconnect
$cmd 00308 deny all from 224.0.0.0/3 to any in via $pif         #Class D & E multicast

# Deny public pings
$cmd 00310 deny icmp from any to any in via $pif

# Deny ident
$cmd 00315 deny tcp from any to any 113 in via $pif

# Deny all Netbios service. 137=name, 138=datagram, 139=session
# Netbios is MS/Windows sharing services.
# Block MS/Windows hosts2 name server requests 81
$cmd 00320 deny tcp from any to any 137 in via $pif
$cmd 00321 deny tcp from any to any 138 in via $pif
$cmd 00322 deny tcp from any to any 139 in via $pif
$cmd 00323 deny tcp from any to any 81 in via $pif

# Deny any late arriving packets
$cmd 00330 deny all from any to any frag in via $pif

# Deny ACK packets that did not match the dynamic rule table
$cmd 00332 deny tcp from any to any established in via $pif

# Allow traffic in from ISP's DHCP server. This rule must contain
# the IP address of your ISP.s DHCP server as it.s the only
# authorized source to send this packet type.
# Only necessary for cable or DSL configurations.
# This rule is not needed for .user ppp. type connection to
# the public Internet. This is the same IP address you captured
# and used in the outbound section.
#$cmd 00360 allow udp from any to x.x.x.x 67 in via $pif keep-state

# Allow in standard www function because I have apache server
$cmd 00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2

# Allow in secure FTP, Telnet, and SCP from public Internet
$cmd 00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2

# Allow in non-secure Telnet session from public Internet
# labeled non-secure because ID & PW are passed over public
# Internet as clear text.
# Delete this sample group if you do not have telnet server enabled.
$cmd 00420 allow tcp from any to me 23 in via $pif setup limit src-addr 2

# Reject & Log all incoming connections from the outside
$cmd 00499 deny log all from any to any in via $pif

# Everything else is denied by default
# deny and log all packets that fell through to see what they are
$cmd 00999 deny log all from any to any
################ End of IPFW rules file ###############################

3.4.2. A Sample NAT and Stateful Rule set

Some additional configuration statements need to be enabled in order to activate IPFW’s NAT function. The kernel source needs the 'option divert' statement to be added to the other IPFIREWALL statements, and compiled into a custom kernel.

In addition to the normal IPFW options in /etc/rc.conf, the following are required:

natd_enable="YES"                   # Enable NATD function
natd_interface="rl0"                  # interface name of public Internet NIC
natd_flags="-dynamic -m"        # -m = preserve port numbers if possible
Utilizing stateful rules with the ‘divert natd’ rule (Network Address Translation) greatly complicates the rule set coding logic. The positioning of the ‘check-state’ and 'divert natd' rules in the rule set becomes very critical. This is no longer a simple fall-through logic flow. A new action type is used, called 'skipto'. To use the skipto command, it is mandatory that you number each rule so that you know exactly where the skipto rule number is you are really jumping to.

The following is an uncommented example of one coding method, selected here to explain the sequence of the packet flow through the rule sets.

The processing flow starts with the first rule from the top of the rule file, and its progress, one rule at a time, deeper into the file, until the end is reached, or the packet being tested to the selection criteria matches it, and the packet is released out of the firewall. It is important to take notice of the location of rule numbers 100, 101, 450, 500, and 510. These rules control the translation of the outbound and inbound packets, so their entries in the keep-state dynamic table always register the private LAN IP address. Allow and deny rules specify the direction in which the packet is going (outbound or inbound) and the interface. All the start outbound session requests skip to rule 500 for the network address translation.

Suppose a LAN user uses his or her web browser to get a web page. Web pages communicate over port 80. The packet enters the firewall. It does not match rule 100 because it is headed out, not in. It passes rule 101 because this is the first packet, so it has not been posted to the keep-state dynamic table yet. The packet finally comes to rule 125 and matches. It is outbound through the NIC facing the public Internet. The packet still retains its source IP address as a private LAN IP address. Upon matching with this rule, two actions take place. The keep-state option posts this rule into the keep-state dynamic rules table, and the specified action is executed. The action is part of the information posted to the dynamic table. In this case it is "skipto rule 500". Rule 500 NATs the packet IP address, and out it goes. This is very important. This packet makes its way to the destination and returns and enters the top of the rule set. This time it matches rule 100, and has its destination IP address mapped back to its corresponding LAN IP address. It is then processed by the check-state rule, found in the table as an existing session conversation, and released to the LAN. It goes to the LAN PC that sent it, and a new packet is sent, requesting another segment of the data from the remote server. This time it gets checked by the check-state rule, its outbound entry is found, and the associated action, 'skipto 500', is executed. The packet jumps to rule 500, gets NATed and is released on its way out.

On the inbound side, everything coming in that is part of an existing session conversation is being automatically handled by the ‘check-state’ rule and the properly placed ‘divert natd’ rules. All you have to address is deny all the bad packets and only allow in the authorized services. Let us say there is an Apache server running on the firewall box, and you want people on the public Internet to be able to access the local website. The new inbound start request packet matches rule 100, and its IP address is mapped to the LAN IP for the firewall box. The packet is then matched against the unwelcome elements you want to check for, and finally matches against rule 425. Upon matching, two things happen. The packet rule is posted to the keep-state dynamic table, but this time, any new session request originating from that source IP address is limited to two. This defends against Denial of Service (DoS) attacks running on the specified port number. The action is allowed, and the packet is released to the LAN. On returning, the check-state rule recognizes the packet as belonging to an existing session conversation, sends it to rule 500 for NATing, and it is released to an outbound interface.

Example Ruleset #1:
#!/bin/sh
cmd="ipfw -q add"
skip="skipto 500"
pif=rl0
ks="keep-state"
good_tcpo="22,25,37,43,53,80,443,110,119"

ipfw -q -f flush

$cmd 002 allow all from any to any via xl0  # exclude LAN traffic
$cmd 003 allow all from any to any via lo0  # exclude loopback traffic

$cmd 100 divert natd ip from any to any in via $pif
$cmd 101 check-state

# Authorized outbound packets
$cmd 120 $skip udp from any to xx.168.240.2 53 out via $pif $ks
$cmd 121 $skip udp from any to xx.168.240.5 53 out via $pif $ks
$cmd 125 $skip tcp from any to any $good_tcpo out via $pif setup $ks
$cmd 130 $skip icmp from any to any out via $pif $ks
$cmd 135 $skip udp from any to any 123 out via $pif $ks


# Deny all inbound traffic from non-routable reserved address spaces
$cmd 300 deny all from 192.168.0.0/16  to any in via $pif  #RFC 1918 private IP
$cmd 301 deny all from 172.16.0.0/12   to any in via $pif  #RFC 1918 private IP
$cmd 302 deny all from 10.0.0.0/8      to any in via $pif  #RFC 1918 private IP
$cmd 303 deny all from 127.0.0.0/8     to any in via $pif  #loopback
$cmd 304 deny all from 0.0.0.0/8       to any in via $pif  #loopback
$cmd 305 deny all from 169.254.0.0/16  to any in via $pif  #DHCP auto-config
$cmd 306 deny all from 192.0.2.0/24    to any in via $pif  #reserved for docs
$cmd 307 deny all from 204.152.64.0/23 to any in via $pif  #Sun cluster
$cmd 308 deny all from 224.0.0.0/3     to any in via $pif  #Class D & E multicast

# Authorized inbound packets
$cmd 400 allow udp from xx.70.207.54 to any 68 in $ks
$cmd 420 allow tcp from any to me 80 in via $pif setup limit src-addr 1


$cmd 450 deny log ip from any to any

# This is skipto location for outbound stateful rules
$cmd 500 divert natd ip from any to any out via $pif
$cmd 510 allow ip from any to any

######################## end of rules  ##################

The following is pretty much the same as above, but uses a self-documenting coding style full of description comments to help an inexperienced IPFW rule writer better understand what the rules are doing.

Example Ruleset #2:
#!/bin/sh
################ Start of IPFW rules file ###############################
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"
skip="skipto 800"
pif="rl0"     # public interface name of NIC
              # facing the public Internet

#################################################################
# No restrictions on Inside LAN Interface for private network
# Change xl0 to your LAN NIC interface name
#################################################################
$cmd 005 allow all from any to any via xl0

#################################################################
# No restrictions on Loopback Interface
#################################################################
$cmd 010 allow all from any to any via lo0

#################################################################
# check if packet is inbound and nat address if it is
#################################################################
$cmd 014 divert natd ip from any to any in via $pif

#################################################################
# Allow the packet through if it has previous been added to the
# the "dynamic" rules table by a allow keep-state statement.
#################################################################
$cmd 015 check-state

#################################################################
# Interface facing Public Internet (Outbound Section)
# Interrogate session start requests originating from behind the
# firewall on the private network or from this gateway server
# destine for the public Internet.
#################################################################

# Allow out access to my ISP's Domain name server.
# x.x.x.x must be the IP address of your ISP's DNS
# Dup these lines if your ISP has more than one DNS server
# Get the IP addresses from /etc/resolv.conf file
$cmd 020 $skip tcp from any to x.x.x.x 53 out via $pif setup keep-state


# Allow out access to my ISP's DHCP server for cable/DSL configurations.
$cmd 030 $skip udp from any to x.x.x.x 67 out via $pif keep-state

# Allow out non-secure standard www function
$cmd 040 $skip tcp from any to any 80 out via $pif setup keep-state

# Allow out secure www function https over TLS SSL
$cmd 050 $skip tcp from any to any 443 out via $pif setup keep-state

# Allow out send & get email function
$cmd 060 $skip tcp from any to any 25 out via $pif setup keep-state
$cmd 061 $skip tcp from any to any 110 out via $pif setup keep-state

# Allow out FreeBSD (make install & CVSUP) functions
# Basically give user root "GOD" privileges.
$cmd 070 $skip tcp from me to any out via $pif setup keep-state uid root

# Allow out ping
$cmd 080 $skip icmp from any to any out via $pif keep-state

# Allow out Time
$cmd 090 $skip tcp from any to any 37 out via $pif setup keep-state

# Allow out nntp news (i.e. news groups)
$cmd 100 $skip tcp from any to any 119 out via $pif setup keep-state

# Allow out secure FTP, Telnet, and SCP
# This function is using SSH (secure shell)
$cmd 110 $skip tcp from any to any 22 out via $pif setup keep-state

# Allow out whois
$cmd 120 $skip tcp from any to any 43 out via $pif setup keep-state

# Allow ntp time server
$cmd 130 $skip udp from any to any 123 out via $pif keep-state

#################################################################
# Interface facing Public Internet (Inbound Section)
# Interrogate packets originating from the public Internet
# destine for this gateway server or the private network.
#################################################################

# Deny all inbound traffic from non-routable reserved address spaces
$cmd 300 deny all from 192.168.0.0/16  to any in via $pif  #RFC 1918 private IP
$cmd 301 deny all from 172.16.0.0/12   to any in via $pif  #RFC 1918 private IP
$cmd 302 deny all from 10.0.0.0/8      to any in via $pif  #RFC 1918 private IP
$cmd 303 deny all from 127.0.0.0/8     to any in via $pif  #loopback
$cmd 304 deny all from 0.0.0.0/8       to any in via $pif  #loopback
$cmd 305 deny all from 169.254.0.0/16  to any in via $pif  #DHCP auto-config
$cmd 306 deny all from 192.0.2.0/24    to any in via $pif  #reserved for docs
$cmd 307 deny all from 204.152.64.0/23 to any in via $pif  #Sun cluster
$cmd 308 deny all from 224.0.0.0/3     to any in via $pif  #Class D & E multicast

# Deny ident
$cmd 315 deny tcp from any to any 113 in via $pif

# Deny all Netbios service. 137=name, 138=datagram, 139=session
# Netbios is MS/Windows sharing services.
# Block MS/Windows hosts2 name server requests 81
$cmd 320 deny tcp from any to any 137 in via $pif
$cmd 321 deny tcp from any to any 138 in via $pif
$cmd 322 deny tcp from any to any 139 in via $pif
$cmd 323 deny tcp from any to any 81  in via $pif

# Deny any late arriving packets
$cmd 330 deny all from any to any frag in via $pif

# Deny ACK packets that did not match the dynamic rule table
$cmd 332 deny tcp from any to any established in via $pif

# Allow traffic in from ISP's DHCP server. This rule must contain
# the IP address of your ISP's DHCP server as it's the only
# authorized source to send this packet type.
# Only necessary for cable or DSL configurations.
# This rule is not needed for 'user ppp' type connection to
# the public Internet. This is the same IP address you captured
# and used in the outbound section.
$cmd 360 allow udp from x.x.x.x to any 68 in via $pif keep-state

# Allow in standard www function because I have Apache server
$cmd 370 allow tcp from any to me 80 in via $pif setup limit src-addr 2

# Allow in secure FTP, Telnet, and SCP from public Internet
$cmd 380 allow tcp from any to me 22 in via $pif setup limit src-addr 2

# Allow in non-secure Telnet session from public Internet
# labeled non-secure because ID & PW are passed over public
# Internet as clear text.
# Delete this sample group if you do not have telnet server enabled.
$cmd 390 allow tcp from any to me 23 in via $pif setup limit src-addr 2

# Reject & Log all unauthorized incoming connections from the public Internet
$cmd 400 deny log all from any to any in via $pif

# Reject & Log all unauthorized out going connections to the public Internet
$cmd 450 deny log all from any to any out via $pif

# This is skipto location for outbound stateful rules
$cmd 800 divert natd ip from any to any out via $pif
$cmd 801 allow ip from any to any

# Everything else is denied by default
# deny and log all packets that fell through to see what they are
$cmd 999 deny log all from any to any
################ End of IPFW rules file ###############################