Traffic Shaping in pfSense: Part Two

Traffic shaping in pfSense

Configuring interfaces in the pfSense traffic shaper wizard.

Wrapping a GUI around the underlying traffic shaping components in pfSense proved to be difficult. Lacking functionality in the underlying system in some areas also limits its capabilities. The traffic shaper was rewritten for pfSense 2.0 and accommodates multiple interfaces.

Traffic to the LAN IP is queued in the same manner as traffic traversing the firewall. If your web interface uses HTTPS, and your traffic shaper queue for HTTPS is filled, it will delay your traffic to the management interface the same as if your HTTPS request were going out to the Internet. If you use pings to the LAN IP from a monitoring system, you may see significant delay for the same reason.


In addition, the shaper is not capable of truly differentiating between protocols. Traffic using TCP port 80 is considered as HTTP, whether it’s really HTTP or it’s P2P application using port 80; traffic using port 443 is considered as HTTPS, and so on. This can be a significant problem in some cases.

Traffic Shaping in pfSense: A Brief Look at PF Rules

Traffic shaping functionality, as with everything else in pfSense, is provided by PF. If you’re willing to write your own rules, this gives you considerable flexibility in configuring traffic shaping. For example, consider the hypothetical from the first article in which there is a backlog of ACK packets on an asymmetric Internet connection. We want to alter the rule set so ACK packets have a higher priority than other packets, so we set up two separate data queues. The result might look something like this:

ext_if="kue0"

altq on $ext_if priq bandwidth 100Kb queue { q_pri, q_def }
    queue q_pri priority 7
    queue q_def priority 1 priq(default)

pass out on $ext_if proto tcp from $ext_if to any flags S/SA \
    keep state queue (q_def, q_pri)

pass in on $ext_if proto tcp from any to $ext_if flags S/SA \
    keep state queue (q_def, q_pri)

Here, a priority-based queue is set up on the external interface ($ext_if) with two subordinate queues. On subqueue has a high priority value of 7 (q_pri), while the other has a low priority value of 1 (q_def). Once a connection is assigned to the main queue, ALTQ inspects each packet’s type of service (ToS) field. ACK packets have the ToS Delay bit set to low, indicating that the sender wanted the speediest delivery possible. When ALTQ sees a low-delay packet and queues of differing priority are available, it will assign the packet to the higher-priority queue.

For those of us who don’t want to be bothered manually rewriting the rules, there’s the traffic shaper wizard. You can access the traffic shaper wizard from the pfSense web interface by navigating to Firewall -> Traffic Shaper and clicking on the Wizard tab. It is generally a good idea to configure traffic for the first time using the wizard. If you need custom rules, you can always step through the wizard, approximate what you need, then make the custom rules afterward. Each screen will setup unique queues, and rules that will control what traffic is assigned into those queues. Should you want to configure everything manually, simply specify your WAN speed at the first screen, then click Next through all the remaining screens without configuring anything.

In the next article, we’ll step though the pfSense traffic shaper wizard.


External Links:

Traffic Shaping Guide at doc.pfsense.org

HAProxy Load Balancing: Part Two

HAProxy

Listener configuration in HAProxy under pfSense 2.1.5.

In the previous article, we introduced HAProxy as a load balancing solution for TCP and HTTP-based applications. In this article, we will continue our look at HAProxy configuration.

The next setting in the “Settings” tab is “Global Advanced pass thru“, which is for text that you would like to pass through to the global settings area. The next section is “Configuration synchronization“. The first check box allows you to synchronize the HAProxy configuration to back up CARP members via XML-RPC, a remote procedure call which uses XML to encode its calls and uses HTTP as a transport mechanism. The next two fields are for the username and password that will be used during configuration synchronization. The username is general “admin” or an admin-level privileged account on the target system, and the password is generally the remote web configurator password. The next three fields are for sync hosts 1, 2, and 3. HAProxy will synchronize settings to the host’s IP address, if it is specified here. Finally, there are two buttons at the bottom. “Save” will just save the configuration, whereas “Save and Check Config” will parse the automatically generated config file and check for errors.


HAProxy: Configuring Listener Settings

The next tab is “Listener“. By pressing the “plus” button on the right side, you can specify a server to which HAProxy will listen. “Name” is the IP address of the interface to listen to. You can also specify an option “Description“. “Status” indicates whether the server pool is active or disabled. In the next field, “External address“, if you want the rule to apply to an IP address other than the IP address of the interface chosen here, you can select it here. You need to define virtual IP addresses for it first. If you are trying to redirect connections on the LAN, select the “any” option. You can also specify the port to listen to at “External port“, a backend server pool, the default server port, and the protocol at “Type” (HTTP, HTTPS, TCP, or a check for health). You can specifyy an ACL at “Access Control lists“.

Under “Advanced settings“, you can specify several other paramters. “Connection timout” allows you to specify the amount of time in milliseconds HAProxy will wait for a connection to complete, while “Server timeout” indicates the amount of time to wait for data from the server. “Retries” indicates the number of retry attempts. “Balance” indicates what method is used to load balance. If “Round robin” is selected, each server is used in turns, according to their weights. The algorithm is dynamic, which means that server weights may be adjusted on the fly for slow starts. If “Source” is selected, the source IP address will be hashed and divided by the total weight of the running servers to designate which server will receive the request. As a result, the same client IP address will always reach the same server as long as no server goes up or down. If the hash result changes due to the number of running servers changing, many clients will be directed to a different server.

In the next article, we we conclude our look at HAProxy configuration.


External Links:

The official HAProxy site

HAProxy on Wikipedia

Port Blocking in Linux

port blockingIn the previous article, I covered the network security benefit of disabling unused services. In this article, I will cover the concept of port blocking, and how it can be done under Linux.

TCP/IP networks assign a port to each service: e.g. HTTP, Simple Mail Transfer Protocol (SMTP), Telnet, FTP, and Post Office Protocol version 3 (POP3). This port is given a number, called a port number, used to link incoming data to the correct service. For example, if a client browser is requesting to view a server’s web page, the request will be directed to port 80 on the server. If the client starts an FTP session, the request will be directed to port 21. The web service receive the request and sends the web page to the client. Each service is assigned a port number, and each port number has a TCP and UDP port. For example, port 137 is used for the NetBIOS name service and has a TCP and a UDP port, with NetBIOS over TCP usually using UDP port 137 (TCP port 137 can be used, but rarely is).

There are two types of ports used for TCP/IP networks: well-known ports and registered ports. The well-known ports are the network services that have been assigned a specific port number (as defined by /etc/services). For example, SSH is assigned port 22, and HTTP is assigned port 80. Servers listen on the network for the requests of well-known ports. Registered ports are temporary ports, usually used by clients, and that will vary each time a service is used. You can also call registered ports ephemeral ports, because they only last for a brief time.

Port Blocking: Determining Which Ports to Block

When determining which ports to block on your server, you must first determine which services you need. In most cases, you can block all ports that are not exclusively required by those services. This is a bit tricky, because in implementing port blocking, you can easily block yourself from services you need, especially services that use ephemeral ports, as explained earlier.


For example, if your server is an exclusive FTP server, you can block all TCP ports except ports 20 and 21, respectively. If your server is an exclusive HTTP server, you can block all ports except TCP port 80. In the case of the FTP server, you can block all UDP ports except port 20, since FTP requires UDP port 20 to be open. If you use the system as an HTTP server, in setting up port blocking you can block all UDP ports, since HTTP uses TCP services exclusively.

However, if you want to use your server as an HTTP client, or as an e-mail client or an e-mail client to a remote mail server, you will restrict the system by doing this. Clients require registered UDP ports for DNS, as well as registered TCP ports for establishing connections with web servers.




If you, for example, try to download an operating system update, and you have only opened UDP port 20, DNS requests will be blocked because DNS queries use port 53. Even if you open port 53, a different registered port may be assigned each time for the answer. In this situation, the best policy may be to open all TCP/UDP registered ports, or set up port blocking to block all of them, and download operating system updates from another computer.

Port Blocking in Red Hat and Other Linux Distros

To utilize port blocking for TCP/UDP services in Linux, you must disable the service that uses the specific port. You may use the GUI interfaces of firewall services offered by most of the Linux distros. In Red Hat Enterprise Linux (RHEL) 5, this is achieved by navigating to System -> Administration -> Security Level and Firewall, which opens up the firewall configuration utility. To allow a service to run, just check and enable the service and to block, uncheck the service. If you want to add any non-standard port or a custom port to be allowed by the firewall, then click on Other ports and add the protocol type (TCP or UDP) and add the port number.

If you don’t use RHEL, don’t despair. Regardless of which version of Linux you use, iptables is the Linux kernel firewall, and rules can be added or deleted at the command line. For example, to set the default chain policy to block, type this:

iptables -P INPUT DROP

Once you do this, you can complete your port blocking setup by selectively enable ports. For example, to allow all incoming SSH connections on eth0, type:

iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT

You may, however, opt to use a frontend to iptables to implement port blocking. Shorewall is one such frontend, and its creators call it “iptables made easy”. If you use Ubuntu, the default firewall configuration tool is ufw (Uncomplicated Firewall), and it simplifies the process of using iptables. To enable ufw, type:

sudo ufw enable

The default parameter allows us to set the default policy. Let’s assume we want set the default policy to block all incoming traffic. We would type:

sudo ufw default deny in

Here, “deny” is the policy (the choices are allow, deny, or reject), and “in” indicates the direction in which traffic is blocked (choices are in or out). Since “in” is the direction the rule applies to by default, we could have just typed:

sudo ufw default deny

If we wanted to allow incoming traffic on port 80, we would type:

sudo ufw allow in to any port 80

There’s much more to ufw than what I present here, so I advise reading the documentation (especially the man page) for more information on port blocking. However, one important parameter for ufw that should be mentioned is –dry-run. When this command is invoked, ufw won’t modify anything, but will just show the changes.


External Links:

iptables at Wikipedia

Shorewall homepage

ufw manpage

Firewall at help.ubuntu.com

25 Most Frequently Used Linux IPTables Rules Examples

Firewall Rules in pfSense: Part One

Firewall Rules: Part One

Firewall: Rules page in the pfSense web GUI.

In the previous article about NAT port forwarding, we used “Add associated filter rule” in order to generate the firewall rule for the Apache web server. We could, however, have chosen “None” for the “Filter Rule Association” and created the rule ourselves. This next article describes how to create firewall rules.


Adding Firewall Rules

In order to do this, first browse to Firewall -> Rules. There will be two pre-configured firewall rules by default: “Block private networks” (for blocking 10.x.x.x, 172.16.x.x, and 192.168.x.x addresses) and “Block bogon networks” (for blocking bogus addresses). There will be at least three tabs: “Floating“, “WAN” and “LAN“. Select “WAN” if it isn’t already selected. Press the “Plus” button to add a new firewall rule. Under “Action”, there are three options: “Pass“, “Block”, and “Reject“. The web GUI has the following explanation of the difference between “Block” and “Reject“:

Hint: the difference between block and reject is that with reject, a packet (TCP RST or ICMP port unreachable for UDP) is returned to the sender, whereas with block the packet is dropped silently. In either case, the original packet is discarded.

In this case, you can leave the default unchanged as “Pass“. Next is the option to “Disable this rule“; we don’t want to do this so leave this box unchecked. At “Interface”, you will again have a choice of “LAN“, “WAN” and whatever other interfaces were configured; choose “WAN“.

Firewall Rules: Part One

Adding a firewall rule in pfSense.

At “Protocol“, there are a number of options in addition to the four listed under NAT port forwarding. “ICMP” stands for Internet Control Message Protocol and is used to send error messages indicating, for example, that a requested service is not available or that a host or router could not be reached. ICMP can also be used to relay query messages. “AH” stands for Authentication Header, which is part of the IPsec suite and provides connectionless integrity and data origin authentication for IP datagrams and provides protection against replay attacks. “IGMP” stands for Internet Group Management Protocol and is a connectionless protocol used by hosts and adjacent routers on IP networks to establish multicast group memberships; it is used for one-to-many networking applications such as online streaming video and gaming, among other uses. “OSPF” stands for Open Shortest Path First, a link-state routing protocol for IP networks that uses a link state routing algorithm and falls into the group of interior routing protocols. “CARP” stands for Common Address Redundancy Protocol, a protocol which allows multiple hosts on the same local network to share a set of IP addresses. Its primary purpose is to provide failover redundancy. Finally, “pfsync” is a computer protocol used to synchronize firewall states between machines running Packet Filter (PF) for High Availability. If is used along with CARP to make sure a backup firewall has the same information as the main firewall. In this case, we should leave the default protocol “TCP” unchanged.


At “Source“, specify “any”, as the “Type” and at “Source Port Range“, also specify any. The “Type” options are the same as the options under “Source” and “Destination” for NAT port forwarding; therefore I will not go into detail on them here. In “Destination“, select “Single host or alias” as the type, and specify 192.168.1.125 (our Apache server) for the “Address”. At “Destination Port Range“, specify “HTTP“. You can leave “Log packets that are handled by this rule” unchecked unless you have reason to log the packets. Specify a “Description” if you wish and press the “Save” button to save the changes.

Firewall Rules: The Source Port Range is Usually Unknown

It should be noted that when a firewall rule is created, the “Source Port Range” is almost always set to “any“. This is because the client decides which port to open on the client computer, which may or may not be the same as the port requested on the server. The source port is an an ever-changing port which the end user probably never knows about. So most of the time, we will not know the Source Port Range of the traffic being allowed in.

In the next article, I will go into some detail on rules governing firewall rules, and some of the advanced options for firewall rules under pfSense 2.0.

External Links:

Firewall Rule Basics at doc.pfsense.org

Port Forwarding with NAT in pfSense

Firewall Configuration: NAT port forwarding

Firewall -> NAT configuration page in the pfSense web GUI.

In computer networking, Network Address Translation (NAT) is the process of modifying IP address information in IPv4 headers while in transit across a traffic routing device. In most cases, it involves translating from the WAN IP address to the 192.168.x.x addresses of your local network. In this article, I will describe how to set up NAT port forwarding.

NAT and firewall rules are distinct and separate. NAT rules forward traffic, while firewall rules block or allow traffic. In the next article, I will cover firewall rules, but for now keep in mind that just because a NAT rule is forwarding traffic does not mean the firewall rules will allow it.

NAT Port Forwarding

NAT port forwarding rules can differ in complexity, but in this example, let’s assume we set up an Apache server at 192.1.168.125 on the local network, and we want to direct all HTTP traffic (port 80) to that address. First, browse to Firewall -> NAT. The options are “Port Forward“, “1:1” and “Outbound“. Select the “Port Forward” tab. Click the “plus” button in order to create a new NAT port forward rule. “Disable the rule” and “No RDR” can be left unchanged. For “Interface” you can choose WAN and LAN; we are concerned about incoming requests from the Internet, so you can keep it as WAN.


For “Protocol”, there are five choices: TCP, UDP, TCP/UDP, GRE, and ESP. TCP stands for Transmission Control Protocol, and is the transport level protocol of the Internet protocol suite. This is usually what we want to use. Next is UDP, or User Datagram Protocol, another transport level protocol which is also part of the Internet protocol suite. It is suitable for purposes where error checking and correction are either not necessary or are performed in the application. GRE stands for Generic Routing Encapsulation, a tunneling protocol that can encapsulate a wide variety of network layer protocols inside virtual point-to-point links. It can be used, among other things, in conjunction with PPTP to create VPNs. ESP stands for Encapsulating Security Payload, a member of the IPsec protocol suite which provides authenticity, integrity and confidentiality protection of packets. In this port forwarding scenario, you can leave the protocol unchanged (TCP).

Firewall Configuration: NAT

Adding a NAT port forwarding rule.

For “Source“, you can specify the allowed client source. Typically you can leave it as “any”, but there are several choices: “Single host or alias“, “Network“, “PPTP clients“, “PPPoE clients“, “L2TP clients“, “WAN subnet“, “WAN address“, “LAN subnet“, and “LAN address“. In this case, you can leave the default (any) unchanged.

For “Source port range“, we want to redirect HTTP traffic (port 80), so choose HTTP for the from and to drop-down boxes. “Destination” offers the same choices as “Source” and can be left unchanged. “Destination port range” should be changed to HTTP for the from and to drop-down boxes. For “Redirect target IP“, specify the web server the traffic to be forwarded to (in our case, 192.168.1.125). For “Redirect target Port“, choose HTTP. Next is “No XMLRPC Sync“; enable this option to prevent this rule from being applied to any redundant firewalls using CARP. This option can be left unchecked now. “NAT Reflection” can be enabled or disabled, usually it is disabled. “Filter Rule association” will automatically create a firewall rule and associate it to this NAT rule. Check this box to avoid having to create a separate firewall rule. Add a description if you wish, and press “Save” to save the changes. The port forwarding rule set up should now be in effect.

NAT Port Redirection

In this case, we passed traffic from port 80 on the source to port 80 on the destination, which is the classic port forwarding scenario. But there’s no reason you can’t redirect traffic to a different port. There are two reasons you might want to do this:

[1] Security: A good way to thwart hackers is to put services on non-standard ports. For example, everyone knows the standard port for FTP is 21, but an outsider is unlikely to find your FTP server if you place it on port 69, or better yet, an even higher port number (e.g. 51782). The same can be said of SSH. Users will have to know the port in order to access it.

[2] Single Public IP Address, more than one computer with the same services: Smaller networks with only a single public IP address may be stuck if the want to expose a lot of public services. For example, imagine that we want to have two separate FTP servers, but on two separate computers. With port redirection, we create two different NAT rules: the first rule will redirect port 51782 to port 21 on FTPServer1, and the second will redirect port 51783 to port 21 on FTPServer2. We can then remote into two separate FTP servers on two different computers using the same IP address.


External Links:

Port Forwarding Troubleshooting at doc.pfsense.org

© 2013 David Zientara. All rights reserved. Privacy Policy