transparency — network transparency and the related aspects


The Kernun firewall is able to transparently grab clients' connections and hand them over to its proxies, as well as to pretend to servers that connections come from clients' real IP addresses instead of the firewall's IP address. This ability is implemented in the transparency support that was added to the FreeBSD kernel.

Transparency for clients

Transparency for clients is realized using special sockets called transparent listening sockets. Unlike a regular listening socket, a transparent listening socket is able to accept transparent connections, i.e., it accepts a connection even if the client is not connecting explicitly to the firewall, but directly to some server's IP address.

A transparent listening connection can be configured either to accept connections that arrive to any interface, or it can be limited to a particular interface. The former case is configured in the Kernun configuration by specifying a special IP address, The latter one can be configured either by specifying the name of the interface, or by specifying its IP address (which is only used to determine the particular interface). See listen-on(5) for the proper syntax.

Transparent listening sockets can be identified in a running system by sockstat(1). They are distinguished from regular sockets by the special syntax in the LOCAL ADDRESS field of the sockstat(1): {iface|*}>>:port. If present, the iface value denotes the interface the transparent listening socket is limited to. Otherwise (denoted by *), the socket listens on all network interfaces.

In the TCP protocol, accepting connection by accept(2) returns a new socket that is used for communication with the client. Packets sent via this socket are automatically assigned the real destination (the server's) IP address as the source address, and all packets sent within this connection from the client to the server would come to this socket. These sockets are indicated by syntax >>addr:port in the LOCAL ADDRESS field of the sockstat(1). Here, the addr denotes the IP address of the server (i.e., the IP address the client thinks to be connected to).

In the typical scenario there would be one transparent listening socket for each interface the proxy listens on (FD 5 in the following example). This socket is shared by the proxy's parent process and by all of its child processes. In addition, there would be two sockets for each connection established via the proxy: one for the connection from the client to the proxy (FD 11), and another for the connection from the proxy to the server (FD 12). The situation is shown in the following example ( stands for the client IP address, stands for the firewall external address and stands for the server IP address):

kernun tcp-proxy 26802 5  tcp4  vr0>>:22       *:*
kernun tcp-proxy 26801 5  tcp4  vr0>>:22       *:*
kernun tcp-proxy 26800 5  tcp4  vr0>>:22       *:*
kernun tcp-proxy 26800 11 tcp4  >>
kernun tcp-proxy 26800 12 tcp4
kernun tcp-proxy 26799 5  tcp4  vr0>>:22       *:*
kernun tcp-proxy 26798 5  tcp4  vr0>>:22       *:*
kernun tcp-proxy 26797 5  tcp4  vr0>>:22       *:*

Matching transparency

Connections can be considered in ACLs according to their transparency. This is done using a keyword to the to configuration item. If the key transparent is present in this item, only transparent connections get matched. Similarly, with keyword non-transparent present, only non-transparent connections get matched.

Changing source address

This feature allows servers to see real clients' addresses upon receiving connections instead of the firewall's address (which is the standard behavior for proxies). It can be specified in an ACL section using either of the following syntax constructions:

source-address client;
source-address [];

This feature can be regarded as transparency for servers. source-address might be used either in transparent or non-transparent mode.

For example, if a client of wants to connect through proxy at (either transparently or non-transparently) to server, the server sees normally the connection as coming from firewall's external address, e.g. Taking advantage of source-address client, the server sees the connection as if it were coming from In that case, the sockstat(1) gives the following output:

kernun tcp-proxy 23008 11 tcp4  >>
kernun tcp-proxy 23008 12 tcp4

Unlike in the first example, the connection from the firewall to the server (FD=12) shows the LOCAL ADDRESS to be (i.e., the client's IP address).

Socket conflicts

For a given TCP/UDP port there can be more than one type of application listening side-by-side: transparent proxies, non-transparent proxies or system daemons (such as ssh daemon sshd). However, they must not be in mutual conflict.

Conflicts are detected by the /verify command of cml(8). Two applications that listen on the same port (or with their listen port ranges overlapping) are in conflict, if any of the following cases occurs:

  1. Both listen in the non-transparent mode on the same IP address

  2. Both listen in the non-transparent mode on the wildcard IP address

  3. Both listen transparently on the same interface (either if the interface name was given directly or if it was deduced from the IP address)

  4. Both listen transparently without interface restriction

Note that the conflicts check is only performed for the components configured within the cml configuration file. It is not performed for the components that are configured out of it.

Socket precedence

When a packet arrives, the most specific socket is chosen according to the following precedence order (from the most specific to the most generic):

  1. Non transparent, single IP address, single port

  2. Non transparent, wildcard address (, single port

  3. Transparent with interface restriction, single port

  4. Transparent without interface restriction, single port

  5. Non transparent, single IP address, port range

  6. Non transparent, wildcard address (, port range

  7. Transparent with interface restriction, port range

  8. Transparent without interface restriction, port range

It is therefore possible to provide several services for the same port, as long as they do not collide. For example, the SSH daemon might be available for an administrative connection to the firewall on all interfaces (SSH daemon only makes sense in the non-transparent mode), while tcp-proxy might be configured in the transparent mode for proxying the ssh traffic through the server for the internal interface. In that case, packets with the destination address equal to any of the firewall's IP addresses would end up in the SSH daemon, while packets with the destination in the external network would be processed by the tcp-proxy. See the examples section.

Bypassing transparency

When transparency is enabled (sysctl net.inet.ip.transparency=1), every packet is considered to be potentially local (i.e., destinated for some firewall's process) and is therefore delivered into the local IP stack. One of the consequences of this fact is that the packet is not eventually ip-forwarded (even if sysctl net.inet.ip.forwarding=1 and it would have been forwarded, if the standard FreeBSD kernel had been used).

Under certain circumstances it might be desirable to bypass transparency. Kernun firewall uses the packet filter (pf(4), packet-filter(5)) for this purpose. When the packet has the pf tag NOTRANSP set, the kernel handles it the same way the regular FreeBSD kernel would. The actual tag that is used for this purpose can be changed using sysctl net.inet.ip.no_transp_tag. NOTRANSP is the default value.

The following rule can be used to tag all the traffic from client of

pass in on vr0 from to any tag NOTRANSP

Note that all the traffic that is required not to undergo the transparency must be tagged NOTRANSP. Especially, for bidirectional communication, packets for both directions must be tagged so (see the latter example in this manual page).

See Also

Kernun: acl(5), ftp-proxy.cfg(5), listen-on(5), access-control(7), dns-proxy(8), ftp-proxy(8), kat(8), smtp-proxy(8), tcp-proxy(8)

FreeBSD: ioctl(2), pf(4), pf.conf(5), pfctl(8)


This man page is a part of Kernun Firewall.
Copyright © 2000–2023 Trusted Network Solutions, a. s.
All rights reserved.