Szilard@BalaBit

How to use gtkmm custom widget in GTK+

Tuesday, February 26, 2013 @ 09:02 AM Author: Pfeiffer Szilárd

The aim of this post is to demonstrate the fact that it is possible to combine the easy
tom widget derivation in gtkmm with the good old C language-based GTK+. The Glade interface designer binds C and C++ together, since the custom widget created in gtkmm can be used in Glade and can be loaded in a GTK+-based application. Only the following steps have to be performed to reach that goal:

  1. implement the desired custom widget in gtkmm
  2. create a library from the widget for Glade
  3. design the user interface containing the custom widget with Glade
  4. declare the C interface for the application written in GTK+
  5. build the user interface from XML with GtkBuilder

Derive Custom Widget

If you are familiar with the C++ language and also with gtkmm, it will be easy to create the desired custom widget by following the instructions in the custom widget chapter of the gtkmm tutorial. After you have finished that, compile a library from your custom widget that can be used in the Glade user interface designer, and therefore in the GTK+ based application.


Design the User Interface

To use the custom widgets in Glade’y add some extra pure ‘C functions above the custom widget classes, a catalog file that describes the widgets, and the library containing the custom widgets. The details are in my “How to Add Custom gtkmm Widget to Glade” blog post. As a result of the aforementioned development, your custom widget will be handled in Glade just like the stock GTK+ widgets.


Implement the Application

The implementation of the application differs only slightly from the standard way. You only have to register the custom widget, as it is not part of the distributed GTK+ widget set. Then, the user interface can be built from .glade files by GtkBuilder.

Register Custom Widget

Here is the simple C interface for your C++ custom widget library. The only function you have is the same one you have set in the Glade catalog file between the init-function tags as an entry point of the custom widget. The same steps are required when the Glade uses the gtkmm-based custom widget, and also when the actually developed GTK+ application does that, because the situation is the same, as Glade is also written in C.

custom_widget_glade.h

#ifndef CUSTOM_WIDGET_GLADE_H_INCLUDED
#define CUSTOM_WIDGET_GLADE_H_INCLUDED
 
void custom_widgets_glade_init ();
 
#endif

Build the User Interface

The following minimal example demonstrates how you can load a .glade file containing a custom widget. There are only two extra lines compared to a simple GTK+ builder example.

custom_widget_example.c

#include <gtk/gtk.h>
 
#include "custom_widgets_glade.h" // <1>
 
int
main (int argc, char *argv[])
{
  GtkWidget *window;
  GtkBuilder *builder;
  GError *error = NULL;
 
  gtk_init (&argc, &argv);
  custom_widgets_glade_init (); // <2>
 
  builder = gtk_builder_new ();
  if (!gtk_builder_add_from_file (builder, "custom_widget.glade", &error))
    {
      g_warning ("%s", error->message);
      g_error_free (error);
    }
 
  window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
  g_signal_connect (G_OBJECT (window), "delete-event",
                   G_CALLBACK (gtk_main_quit), NULL);
  gtk_widget_show_all (window);
 
  g_object_unref (G_OBJECT (builder));
 
  gtk_main ();
 
  return 0;
}
  1. Include of the C interface of your gtkmm custom widget library.
  2. Initialization of your custom widget after the GTK+ has been initialized and before the user interface itself is loaded from the .glade file that was created earlier.

The custom widget example code can be compiled and run with the following commands. Compilation uses custom_widgets_glade.h and libcustomwidgetsglade.so, which can be created as it is described in “How to Add Custom gtkmm Widget to Glade”. For the compilation to work properly, the library and header file must be placed where the example code is placed, since gcc is searching for them in the current directory (-I -L.).

Compilation and run

gcc custom_widget_example.c -o custom_widget_example \
-I. -L. -lcustomwidgetsglade -fPIC `pkg-config --cflags --libs gtk+-2.0`
LD_LIBRARY_PATH=. ./custom_widget_example

When you run the compiled C source you have to specify where the custom widget library can be found. Youcan do that by setting the LD_LIBRARY_PATH environment variable to the current directory (.) where libcustomwidgetsglade.so can be loaded from.

[.] More

Zorp Tutorial: Use Case Access Control

Thursday, January 3, 2013 @ 09:01 AM Author: Pfeiffer Szilárd

Use case

It is a general use case that we want to grant access for a user to an FTP server on the Internet to allow downloading anything, but at the same time we want to prevent them from uploading anything.

Solution

The application level solution of the problem is to accept the read-only commands of the FTP protocol, but drop the commands used to write to the server (for example: PUT). As it is a general issue, Zorp provides a predefined proxy to perform that, so the system administrator does not have to do anything to implement a read-only FTP access, only use that proxy.

  1. from Zorp.Ftp import *
  2.  
  3. Service(name="service_ftp_transparent",
  4. proxy_class=FtpProxyRO
  5. )
  6.  
  7. Rule(service='service_ftp_transparent',
  8. dst_port=21,
  9. src_zone=('clients', ),
  10. dst_zone=('servers', )
  11. )
line 7
Creates a rule that matches the FTP traffic, as the destination port in the rule is the standard port of the FTP servers (21).
line 3
The service uses the predefined FtpProxyRO, which analyzes the traffic and when we issue a read-only command, it will be sent successfully to the server. When we issue a write command an error message will be sent to the client, but nothing will be sent to the server, as Zorp rejects it.

Result

Any kind of read-only operation works successfully, but error message is displayed on the client side when it tries to perform a write operation on the server.

The configuration file sniplet above (1) grants read-only access to the servers in the zone servers for the users who come from the zone clients. Without the src_zone and dst_zone filters the rule would grant access to any server for any user.

[.] More

Zorp Tutorial: Use Case Reverse Proxy

Tuesday, November 27, 2012 @ 09:11 AM Author: Pfeiffer Szilárd

Use case

A common requirement is the following case: Client connects to a proxy server, that appears to the client as an ordinary server, but it forwards the request to the origin server, which handles it. Thus, we communicate with the origin server through a proxy server. For example we reach a mail server in DMZ, we connect to a firewall, but in reality, we communicate with the SMTP server in the DMZ.

Solution

The communication can be inspected on the protocol level, since the SMTP proxy is available in Zorp. Based on the abovementioned example, we connect to the firewall, and indirectly communicate with another server through the firewall.

  1. from Zorp.Smtp import *
  2.  
  3. def default_instance():
  4. Service(name="service_smtp_transparent_directed",
  5. proxy_class=SmtpProxy,
  6. router=DirectedRouter(dest_addr=SockAddrInet('172.16.20.254', 25))
  7. )
  8. Rule(service='service_smtp_transparent_directed',
  9. dst_port=25,
  10. dst_subnet=('172.16.40.1', )
  11. )

 

line 8
This case is similar than it was at the HTTP forward proxy, the clients connect to the firewall directly, so the destination IP address is the firewall’s address (172.16.40.1) and the port is the standard port of SMTP (25).
line 4
The service uses the predefined SmtpProxy proxyclass to enforce the SMTP protocol.
line 6
As the clients target the firewall, the traffic must be routed to the origin server (172.16.20.254) directly. As its name shows, this function can be solved by the DirectedRouter class, where the dest_addr parameter contains the address and the port value of the origin server.

There is another relevant question in case of a forward proxy. As the firewall connects to the origin server, in the log of the SMTP server on the origin server it would always show the IP address of the firewall, if we did not extend the router with following parameter:

router=DirectedRouter(dest_addr=SockAddrInet('172.16.20.254', 25),
                      forge_addr=TRUE
                     )

The forge_addr and forg_port options of the router can be used to forge the client address and port to the traffic instead of the firewall’s ones.

Result

The client connection is forwarded to the origin server by the firewall to handle it. Replies are forwarded back to the client in a transparent way (at the application level). The client is not aware of the forwarding, so additional settings are not required – like proxy in the forward proxy use case – on the client side.

[.] More

Zorp Tutorial: Minimal configuration of KZorp

Tuesday, November 6, 2012 @ 10:11 AM Author: Pfeiffer Szilárd

Zorp Kernel Module

KZorp is the kernel module of the Zorp application level firewall. The module makes possible to make kernel space decisions about the traffic according to the configured Zorp policy. It also provides some extensions to IPTables so that you can build your own packet filter ruleset that uses Zorp concepts and policy objects.

Rule evaluation

Zorp communicates the policy to KZorp when starting up, so inital policy decisions can be applied to certain traffic in kernel space. As the result of the decision, packets are either dropped or put back to the chain of IPTables where the KZORP target has been called.

IPTables relation

The KZorp kernel and IPTables modules allow using certain Zorp concepts in packet filter rulesets.

It adds support for the following IPTables modules:

  • zone match: you can match on Zorp zones (defined in the Zorp policy) in your IPTables ruleset.
  • service match: matches on either the name or the type of the service that has been selected for the packet based on your Zorp policy.
  • KZORP target: handles DAC checks, transparent proxy redirections and generic processing of packets for PFService services (that is, Zorp services that process packets on the packet filter level, not in a user-space proxy).

Configuration

The main problem of transparent proxy firewalls is the fact that the traffic does not target the firewall itself, but a host behind the network security device. In a usual case the traffic is forwarded to the originally targeted server, but in case of a firewall the traffic must be delivered locally to the proxy, which will connect to the originally targeted server, or another according to the policy. The divertable packets should be identified somehow in the packet filter rulesets. It can be performed by the means of transparent proxy (TProxy) kernel module of the kernel.

The idea is to identify packets with the destination address matching a local socket on your box, set the packet mark to a certain value, and then match on that value using policy routing to have those packets delivered locally.

— TProxy Kernel Module Documentation

The following sections will describe the IPTables and policy routing rules that are essential to make Zorp operable.

IPTables

At least the following IPTables ruleset is required for Zorp. Note that this ruleset is fair enough for Zorp, but it is inadequate for even the simplest firewall. The ruleset submits a working example of Zorp, so it must be extended with some other rules that are ordinary in case of a proxy firewall (for example: grant SSH access, handle ICMP messages).

 

*mangle
:PREROUTING ACCEPT
# mark connection already handled by Zorp <1>
-A PREROUTING -m socket --transparent -j MARK --set-mark 0x80000000/0x80000000
-A PREROUTING -j DIVERT

:INPUT ACCEPT
-A INPUT -j DIVERT

:FORWARD ACCEPT
-A FORWARD -j DIVERT

:OUTPUT ACCEPT

:POSTROUTING ACCEPT
-A POSTROUTING -j DIVERT# chain to collect KZorp related rules <2>

:DIVERT
# insert rules here to bypass KZorp <3>
# jump to KZorp and mark the packet <4>
-A DIVERT -j KZORP --tproxy-mark 0x80000000/0x80000000
COMMIT

*filter
:INPUT DROP
# accept earlier marked packet <5>
-A INPUT -m mark --mark 0x80000000/0x80000000-j ACCEPT

:FORWARD DROP
# accept connection relates to a packet filter service <6>
-A FORWARD -m conntrack !--ctstate INVALID -m service --service-type forward -j ACCEPT

:OUTPUT ACCEPT
COMMIT

  1. The socket matcher inspects the traffic by performing a socket lookup on the packet (non-transparent sockets are not counted) and checks if an open socket can be found. It practically means that Zorp (or any other application) has a socket for the traffic, it is already handled by Zorp in the userspace, no kernel-level intervention is required. In this case it is marked with the TProxy mark value (0x80000000), meaning that it should be handled by Zorp.
  2. There are some chains of table mangle where KZorp must be hooked for certain purposes (rule evaluation, NAT handling, …). In these cases we are jumping to a user-defined chain (DIVERT) where the corresponding rules can placed to pass the traffic to KZorp or even bypass it.
  3. This is the place where we can put rules which match to certain traffic should be hidden from KZorp and accept it.
  4. If no rule has been matched in this chain earlier, this rule jumps to KZorp and also marks the packet. This mark can be used in policy routing rules to divert traffic locally to Zorp instead of forwarding it to its original address. Note that this mark is the same that we use in case of the first rule of the PREROUTING chain.
  5. If the traffic has already been marked in table mangle with the corresponding value (0x80000000), we should accept it. For example the data channel connection of active mode FTP matches the first rule of mangle table PREROUTING chain, so it has been marked, but should be accepted in the INPUT chain of filter table as it is an incoming connection.
  6. The service matcher looks up services specified within KZorp. Services can be identified by name or by type. Type forward means a forwarded session (or PFService). These kind of sessions should be forwarded in the FORWARD chain of the filter table.
CautionThe ruleset above contains those and only those rules which are essential to make KZorp and Zorp operable. The ruleset must be extended with other rules that make the firewall operable (for example: accepting incoming SSH connection or particular typed ICMP packets).
NoteThe ruleset above is IP version-independent, so it can be used both in case of iptables and ip6tables.

Advanced Routing

Packets have been marked to a certain value in IPTables. Now match on that value using policy routing to have those packets delivered locally to Zorp instead of forwarding it to the original address, and Zorp will connect to a server depending on the policy.

 

ip -4 rule add fwmark 0x80000000/0x80000000 lookup tproxy #<1>
ip -4 route add local default dev lo table tproxy #<2>
  1. Rule instructs the system to lookup route for the traffic from table tproxy if the traffic has been marked with the required value (0x80000000) in the DIVERT chain of the mangle table in IPTables.
  2. Table tproxy has only one route that diverts the traffic locally to Zorp, so it is not forwarded as it would have been done by default.

Table name tproxy can be used only if the following line is added to rt_tables file.

100 tproxy
NoteThe policy routing rules above must be repeated with options -6 instead of -4 to make IPv6 operable.
[.] More

Zorp Tutorial: Use Case Forward Proxy

Wednesday, October 3, 2012 @ 10:10 AM Author: Pfeiffer Szilárd

Use case

We intend to use the firewall as a proxy server, like a Squid web cache.

Solution

The solution is very simple, since there is a proxy class that we can use to control the traffic on the proxy level. In this case, the clients connect to Zorp that acts as a proxy server, and allows traffic flow according to the rules, but communicates with the clients “in the proxy language”.

  1. from Zorp.Http import *
  2.  
  3. def default_instance():
  4. Service(name="service_http_nontransparent_inband",
  5. proxy_class=HttpProxyNonTransparent,
  6. router=InbandRouter(forge_port=TRUE),
  7. )
  8. Rule(service='service_http_nontransparent_inband',
  9. dst_port=3128,
  10. dst_subnet=('172.16.10.254', ),
  11. src_zone=('clients', )
  12. )

 

line 8
Creates a rule which matches only when the traffic comes from the clientszone and targets the IP address 172.16.10.254 (line 9) and the port 3128 (line 10), which address is the address of the firewall’s client side interface.
line 4
Creates a service that works like a proxy server.
line 5
It uses the predefined HttpProxyNonTransparent, because this proxy class – against the HttpProxy in the code sniplet – handles the traffic as a proxy server.
line 6
In this case the address of the HTTP server, that the client wants to connect to, comes from the application layer traffic and not from the network layer, so the default DirectedRouter. It routes the traffic where it was originally considered to be routed, but in this case (non-transparent service) the client targets the proxy server (here, the firewall) itself. Setting InbandRouter as router can handle the situation for both the HTTP and FTP protocol.

Result

Now the IP address 172.16.10.254 and port 3128 can be set as HTTP proxy in the internet browsers.


For more information read the other posts about Zorp GPL and follow this link to the official website.

[.] More

Zorp Tutorial: Use Case Protocol Enforcement

Thursday, September 20, 2012 @ 09:09 AM Author: Pfeiffer Szilárd

Use case

The most common use case of a proxy firewall – including Zorp – nowadays is to rule the Internet, meaning to take control over the HTTP traffic. This is a simple, but good example to show the advantage of a proxy firewall technology. When the system administrator has to grant access to the World Wide Web, usually only one rule is created, which opens port 80 to the Internet. It solves the original problem, but generates another one. With the help of this rule anybody can access any kind of service of any server on the port 80 independently from the fact, that it is a web service or not.

Solution

The application level solution of the problem is enforcing the HTTP protocol on the traffic on the destination port 80. It is easy with Zorp, because there is a predefined proxy (HttpProxy) to enforce the HTTP protocol. We only have to start a service which sets this proxy as proxy_class parameter, when the traffic meets the mentioned requirements.

  1. from Zorp.Http import *
  2.  
  3. def default_instance():
  4. Service(name='service_http_transparent',
  5. proxy_class=HttpProxy
  6. )
  7. Rule(service='service_http_transparent', dst_port=80,
  8. src_zone=('clients', ),
  9. dst_zone=('servers', )
  10. )

 

line 1
Imports anything from the Zorp.Http module, which makes it possible to use HttpProxy-related names without any prefix.
line 4
Creates a simple service with the name service_http_transparent, which uses the predefined HttpProxy of Zorp.
line 7
Creates a rule with the necessary conditions, traffic from zone clients to Zone servers targets the port 80 and starts a service named service_http_transparent.

Result

The result is as simple as possible. The traffic goes through a transparent service without the client or the server being aware of that, while the HTTP protocol is enforced by the HttpProxy of Zorp.


For more information read the other posts about Zorp GPL and follow this link to the official website.

[.] More

Zorp Tutorial: Basic Concepts

Friday, August 31, 2012 @ 02:08 PM Author: Pfeiffer Szilárd

1  Zone

1.1  What Zone is good for?

Usually access to the services is controlled by the attributes of lower layers of the ISO/OSI model, like IP addresses or ports. Zorp, compared with other firewall suites, has an extra feature. There is a possibility to define sets of IP subnetworks, called Zones.

1.1.1  Administrative Hierarchy

Zones group IP subnetworks that administratively belong together. What is it good for? In this way an administrative hierarchy can be created that is independent from the network topology, reflecting only the network policy. Imagine the situation when all those who are permitted to access an FTP servers for upload, do not belong to the same IP subnet. In this case we would have to add at least two IP-based rules to our network policy. If we use Zorp we only have to add necessary IP subnetworks to the necessary zone.

1.1.2  Inheritable Rights

Another notable feature of zones is, that they can be linked to a tree hierarchy. Access control rights are inherited between the levels of the zone tree. A top-level access is in effect in the lower levels as long as it is not blocked. For instance a top-level access can be the right to download from FTP servers. When a group of users should have special rights, these special rights can be granted in the lower levels of the zone tree.

1.2  How Zone can be configured?

The simplest way to define a Zone is to write the following to the configuration file policy.py. It defines an empty Zone, which does not contain any subnetwork, but can be referred to from the firewall rules by its name zone. Obviously it is not so useful, but it is simple as we promised.

Zone('zone')

 

As it has already mentioned a Zone groups the IP subnetworks together, that administratively belong together, so we have to define these subnetworks somehow to give meaning to the Zone. It can be done by creating the Zone class with additional addrs parameter, which value must be an iterable object, which contains IP subnetworks in CIDR notation.

Zone(name='intra.devel', addrs=['10.1.0.0/16', 'fec0:1::/24'])
Zone(name='intra.it', addrs=['10.2.0.0/16', 'fec0:2::/24'])

 

1.3  How Zone works?

1.3.1  Inheritance

As it has also mentioned a Zone can refer another Zone as its parent, which makes possible to create a tree from the Zones. This tree represents the administrative hierarchy of our network. When a Rule refers to a parent Zone in the hierarchy it implicitly refers to the whole subtree. It practically means that we accept a special kind of traffic in a parent Zone it will be accepted all of its child Zones also.

Zone(name='intra', addrs=['10.0.0.0/8', 'fec0::/16'])
Zone(name='intra.devel', admin_parent='intra', addrs=['10.1.0.0/16', 'fec0:1::/24'])
Zone(name='intra.it', admin_parent='intra', addrs=['10.2.0.0/16', 'fec0:2::/24'])

 

If the Zone hierarchy above is defined and we create a Rule which accepts for example the HTTP traffic from the Zone intra it also accepts the HTTP traffic from intra.devel and intra.it and any other Zones that will be created in the future which defined as the child of intra independently from the fact that subnetworks of parent and child Zones contain each other or not.

2  Rule

2.1  What Rule is good for?

There is no firewall without access control and Zorp is no exception to this rule. When an access control policy is being created, we first have to find answers to the “who”, “what” and “how” – questions. Resources should only be accessible for a specific group of users under the defined conditions.

2.2  How Zone works?

The Rule answers to the “who”, “what” and also indirectly the “how” questions.

2.2.1  Who and What?

The “who” and the “what” questions can be answered by a set of traffic properties. A specific Rule matches a certain traffic when the parameters of the Rule match the traffic.

Rule(service='service_dns', dst_port=53)

 

In the example above the Rule matches any kind of traffic that target the port destination 53. In other words it grants access to any name server on the Internet. It works only when the protocol is TCP or UDP, because port is not defined in case of other protocols (for example IGRP), but we can add another conditions to the Rule to make the rule definite.

Rule(service='service_dns', proto=(socket.IPPROTO_TCP, socket.IPPROTO_UDP), dst_subnet='8.8.8.8/32', dst_port=53)

 

As it is visible, multiple conditions can be defined, so the “who” and the “what” can be answered at the same time. The questions are what kind of conditions can be set, what is the relationship between the different type of conditions, what is the relation between the items of a certain condition.

2.2.2  Conditions

First of all, list the possible condition parameters of a Rule. As you can see there are 8 different types of conditions, that can be set independently from each other. If more than one condition is given, the rule matches only if the logical conjunction of the conditions matches. If there is more than one value in a specific condition there is logical disjunction between them.

  • source interface (iface)
  • protocol (proto)
  • source port (src_port)
  • destination port (dst_port)
  • source subnetwork (src_subnet and src_subnet6)
  • source zone (src_zone)
  • destination subnetwork (dst_subnet and dst_subnet6)
  • destination zone (dst_zone)

In case of the example above the Rule matches when the protocol of the traffic is TCP or UDP, the destination address is 8.8.8.8 and the destination port is 53. In general, we can say if we want a more restrictive Rule we have to add a new condition, if want a more permissive rule we have to add a new value to an existing condition.

2.2.3  Best match

In contrast to the Netfilter where the first matching rule takes effect, in case of Zorp the best matching rule takes effect. It entails that the order of the rules is irrelevant. When a new connection is made, the evaluation will check each rule against the parameters of the traffic to find the best one.

The word ’best’ in the expression best match means that the more accurate rule will take affect. The accuracy of a Rule depends on two factors, the evaluation order of the conditions and the accuracy of the specific condition in the Rule.

Evaluation Order

There is a precedence between the different condition types, that determine the order of the evaluation. It means that if a rule has a condition with higher precedence, it is considered better than the other one. In the condition list above conditions are enumerated from top to bottom in descending precedence. It practically means that a rule with a destination subnetwork condition is always better than a rule with destination zone condition and both of them are worse than a rule with a source zone condition and so on …

Condition Scope

If two rules are considered to be identical – in other words they have conditions with the same precedence – the value of the conditions determines which one considered to be better. In general a narrower scope is always better than a wider scope, which means that an IP subnetwork with greater prefix value, a port number instead of a port range, a child zone instead of a parent is more specific, so the rule with it is considered better.

2.3  How Rule can be configured?

We want to grant access to any kind of FTP servers on the Internet in read-only mode for everyone in our local network (10.0.0.0/8), but we have to grant read-write access to a specific server (1.2.3.4) and for a certain department (10.10.0.0/16) of our organization. How can we use best match to fulfill these requirements?

First of all, solve the general requirement, which is the read-only access to any FTP server for everyone from our subnet. It can be performed by a rule that contains two explicit and an implicit condition and an action. The explicit conditions are about the destination port, namely 21, the standard FTP port, and the source subnetwork, namely 10.0.0.0/8 which is our private network in the example. The implicit condition is about the destination subnetwork that does not appear in the rule, which means it matches independently from the destination of the traffic. The action can be set by the service parameter of the rule which is service_ftp_read_only in this case.

Rule(service='service_ftp_read_only', dst_port=21)
Rule(service='service_ftp_read_write', dst_subnet='1.2.3.4/32', dst_port=21)
Rule(service='service_ftp_read_write', src_subnet='10.10.0.0/16', dst_port=21)

 

The second requirement was to grant read-write access to a specific server (1.2.3.4). It can be performed by a rule matching “better” to the traffic than the previous one. As the second rule has a condition to the destination subnetwork (dst_subnet), while the first one does not, it is considered as more specific, so it is a “better” match.

The third requirement was to grant read-write access for a department (10.10.0.0/16) of our organization to any FTP servers. It is also possible by adding a new rule with a condition to the source subnetwork (src_subnet) with the necessary value (10.10.0.0/16).

The question arises, what is the best match to a traffic which comes from the subnetwork 10.10.0.0/16 and its destination is the address 1.2.3.4, as in this case each rule matches. As we have already mentioned, the second and the third are more specific than the first, so the first one cannot be the best match. The source subnetwork condition has higher precedence than the destination subnetwork, so the second rule will be the best match.

3  Service

3.1  What service is good for?

The service answers the earlier mentioned “how” question, as it determines what exactly happens with the traffic in the application layer of the ISO/OSI model. After the best matching rule has been found, an instance of a service set in the rule starts to handle the new connection.

3.2  How service works?

Minimal configuration of a service contains only a name and a proxy_class parameter. The name parameter is used to refer to the service from other object (for example from a rule). The proxy_class parameter is the most important parameter from the proxy firewall’s point of view. The value of proxy_class parameter determines what will happen with the traffic in the application layer.

3.3  How service can be configured?

The mentioned minimal configuration is the following. It contains only the name and the proxy_class parameter.

Service(name='service_http', proxy_class=HttpProxy)

4  Proxy

As it has already been mentioned earlier, the network traffic analysis can take place at the application level. To perform that, Zorp implements application level protocol analyzers. These analyzers are called proxies in the terminology of Zorp. Proxies are written in C, and they are extendable and configurable in Python.

4.1  What proxy is good for?

Any kind of application level protocol analysis, restriction, modification can be performed by proxy.

4.2  How proxy works?

4.2.1  Predefined proxies

Zorp contains several proxies that can be used without any improvement or modification to work on the application level traffic. Proxies in the left analyze widely used protocols, so it is needless to explain them. Proxies in the right analyze rarely used protocols, so it is useless to explain them here. The two other proxies in the bottom are not named after a protocols, so it is necessary to explain them in some word right now.

HTTPfinger
FTPtelnet
SMTPwhois
plug, anypy
Plug Proxy

As its name shows, it does nothing else, but to plug the client and server connection. It has all the benefits that other proxies have, except the protocol analysis.

AnyPy Proxy

It is a simple proxy like the Plug proxy with a Python interface. It makes it possible to do anything with the application level network traffic which can be done by the help of the Python language, while the lower layers of the connection is handled by Zorp. For example if the proxy to our favorite protocol is not implemented yet in Zorp, we have the possibility to perform application level analysis manually.

4.2.2  Proxy Inheritance

As it is mentioned earlier, each proxy is configurabe and extendable in Python. It means that each proxy is represented as a class in Python and the system administrator can inherit his own Python class from that to override the behavior of the parent class. A derived class inherits everything from the base class, which is necessary for the protocol analysis, so the system administrator only has to care about his specific problem. For example to change the value of a header in the HTTP protocol only requires an extra line of code over the lines related to the Python inheritance mechanism.

4.2.3  General SSL Handling

General SSL handling originates from the fact, that transport layer security is an independent subsystem in Zorp. It means that SSL/TLS parameters can be set independently from the fact, whether we perform protocol analysis or not. Consequently, not only HTTP, FTP, SMTP and POP3 proxies are SSL-capable, but also the Plug and the AnyPy proxies. Server and client-side SSL parameters can also be set independently. So it is possible to encrypt on the client side, but not on the server side and vice versa. Obviously, both sides can be encrypted.

4.2.4  Program Stacking

Zorp is a proxy firewall, neither more nor less, but can be used to perform tasks other than protocol analysis, such as virus scanning or spam filtering by integrating it with external applications. For example in case of the HTTP protocol, Zorp can forward responses to a virus scanner software. After that, depending on the result of the scan, Zorp can accept or reject the original request.

4.3  How proxy can be configured?

Zorp proxy classes can be implemented or customized in Python language. As the following example shows we only have to derive a new class from the necessary base class (HttpProxy) and customize its behavior.

from Zorp.Http import *
 
class HttpProxyHeaderReplace(HttpProxy):
  def config(self):
    HttpProxy.config(self)
    self.request_header["User-Agent"] = (HTTP_HDR_CHANGE_VALUE, "Forged Browser 1.0")

The example above is only a demonstration of a customization, it is uncommented now, we will back to it later.


For more information read the other posts about Zorp GPL and follow this link to the official website.

[.] More

How to Add Custom gtkmm Widget to Glade

Wednesday, June 13, 2012 @ 11:06 AM Author: Pfeiffer Szilárd

The inspiration of this post is the fact that as much as it is easy to create a custom widget class in gtkmm, it is just as complicated to add it to Glade, the interface designer tool of GNOME. As gtkmm is C++ we only have to derive from the desired parent class and customize its behaviour to implement a brand new widget. It would be nice to add the instances of this new class just like stock GTK+ widgets in Glade.

Let’s list what is required to add a custom gtkmm widget to Glade

  1. at least one pure custom widget implementation
  2. some Glade-related extra functions to the custom widgets
  3. a catalog file which describes the custom widgets to Glade
  4. a library contains the custom widgets and some Glade-related functions

Pure widget implementation

The simplest custom widget implementation could be something like that. As you can see, it derives simply from the entry widget. The entry was selected because it is a well-known and easily recognizable widget which can be created without any constructor parameter. It is not so useful, but it is still compilable and works as the entry widget does.

#ifndef CUSTOM_WIDGET_H_INCLUDED
#define CUSTOM_WIDGET_H_INCLUDED
 
#include <gtkmm.h>
 
class CustomWidget : public Gtk::Entry
{
};
 
#endif

Glade-capable widget implementation

Let’s see the header file of our custom widget after some Glade-related extension. As you can see almost everything in the class of the custom widget serves the aim of Glade integration.

#ifndef CUSTOM_WIDGET_H_INCLUDED
#define CUSTOM_WIDGET_H_INCLUDED
 
#include <gtkmm.h>
 
class CustomWidget : public Gtk::Entry
{
private:
  static GType gtype;
 
  CustomWidget (GtkEntry *gobj);
  CustomWidget ();
 
  static Glib::ObjectBase * wrap_new (GObject* o);
 
public:
  static void register_type ();
};
 
#endif

Everything is about conversion between C and C++ objects. First of all we have to be able to wrap a plan C widget to a C++ one. The wrap_new function and the constructor with GtkEntry * parameter of the CustomWidget class perform that.

We have to register this wrap function to the GType related to the custom widget. This is performed by the register_type function. To avoid multiple registrations the GType is stored to the gtype static member of the CustomWidget class and it is checked before registration.

#include "custom_widget.h"
 
GType CustomWidget::gtype = 0;
 
CustomWidget::CustomWidget (GtkEntry *gobj) :
  Gtk::Entry (gobj)
{
}
 
CustomWidget::CustomWidget () :
  Glib::ObjectBase ("customwidget")
{
}
 
Glib::ObjectBase *
CustomWidget::wrap_new (GObject *o)
{
  if (gtk_widget_is_toplevel (GTK_WIDGET (o)))
    {
      return new CustomWidget (GTK_ENTRY (o));
    }
  else
    {
      return Gtk::manage(new CustomWidget (GTK_ENTRY (o)));
    }
}
 
void
CustomWidget::register_type ()
{
  if (gtype)
    return;
 
  CustomWidget dummy;
 
  GtkWidget *widget = GTK_WIDGET (dummy.gobj ());
 
  gtype = G_OBJECT_TYPE (widget);
 
  Glib::wrap_register (gtype, CustomWidget::wrap_new);
}

Glade catalog file

We have implemented almost everything that is necessary to use our custom widget in Glade, so we only have to inform Glade about it. It can be done by a catalog, which is an XML file containing the following information about custom widgets.

  1. library containing the implementation of the custom widgets
  2. the name of the function performing the initialization
  3. widget-related information
  4. grouping of widgets

Colon-separated list of additional load path(s) of catalog files can be specified in the GLADE_CATALOG_SEARCH_PATH environment variable.

Library name

The library attribute of the glade-catalog element is the name of the shared object file containing the implementation of the custom widgets and the function which performs the initialization. In this case libcustomwidgetsglade.so must be available in one of the usual library paths or in the directory set by the GLADE_MODULE_SEARCH_PATH environment variable.

Initialization

As it has already been mentioned, initialization means registration of the custom widgets, and it is performed by the function that is named in init-function.

Custom widgets

Widgets are listed between the glade-widget-classes elements described by the attributes of the glade-widget-class element. The most important one is the name attribute, which is prefixed by the magic gtkmm__CustomObject_ string and followed by the name passed to the Glib::ObjectBase as parameter in the constructor of CustomWidget class.

Widget groups

Custom widgets can be grouped by referencing them between the glade-widget-group elements as you can see in the example catalog. It means that the icon of the widget is displayed in the necessary group when we run Glade. Note that icons must be placed in the standard pixmap directory. There is now a way to set user directory for icons for example in a GLADE_ICON_SEARCH_PATH environment variable. That is the main reason why our custom entry has the same icon as the stock entry.

<?xml version="1.0" encoding="UTF-8" ?>
<glade-catalog name="customwidgets" library="customwidgetsglade" depends="gtk+">
 
  <init-function>custom_widgets_glade_init</init-function>
 
  <glade-widget-classes>
    <glade-widget-class name="gtkmm__CustomObject_customwidget" generic-name="customwidget" icon-name="widget-gtk-entry" title="Custom Widget">
    </glade-widget-class>
  </glade-widget-classes>
 
  <glade-widget-group name="customwidgets" title="Custom Widgets" >
    <glade-widget-class-ref name="gtkmm__CustomObject_customwidget" />
  </glade-widget-group>
 
</glade-catalog>

 

Glade related functions

There is nothing to do, but to implement the function mentioned in the catalog file, which performs the initialization. It practically registers the custom widgets. Initializing gtkmm internals is a must, because  custom_widgets_glade_init is called from Glade, which is written in C not in C++ so it initializes only GTK+ internals.

#ifndef CUSTOM_WIDGETS_GLADE_H_INCLUDED
#define CUSTOM_WIDGETS_GLADE_H_INCLUDED
 
void custom_widgets_register ();
 
#endif
#include "custom_widgets_glade.h"
 
#include "custom_widget.h"
 
#include <gtkmm/main.h>
 
void
custom_widgets_register ()
{
  CustomWidget::register_type ();
}
 
extern "C" void
custom_widgets_glade_init ()
{
  Gtk::Main::init_gtkmm_internals ();
  custom_widgets_register ();
}

 

The function custom_widgets_register is used to register our custom widgets. It must be done in the application where we want to load a .glade file with a custom widget. Initialization of gtkmm is unnecessary as it is done in a normal way.

Compilation and run

Simple application

Here is a simple .glade file that contains a custom widget. As you can see there is an XML comment that shows that the 0.0 version of customwidgets interface is required. The required GTK+ version is also mentioned in XML comment, so if you use the last major version do not forget to replace the 3.0 version number to the necessary 2.x one.

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <!-- interface-requires customwidgets 0.0 -->
  <!-- interface-requires gtk+ 3.0 -->
  <object id="window">
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">Custom Widget</property>
    <child>
      <object id="custom_widget">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="invisible_char"></property>
      </object>
    </child>
  </object>
</interface>

The following code loads the .glade file which contains only a window with a custom widget in it and displays it.

#include <gtkmm.h>
 
#include "custom_widget.h"
#include "custom_widgets_glade.h"
 
int
main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);
  custom_widgets_register();
 
  Gtk::Window *window;
  Glib::RefPtr<Gtk::Builder> builder;
 
  builder = Gtk::Builder::create_from_file("custom_widget.glade");
  builder->get_widget("window", window);
 
  Gtk::Main::run(*window);
 
  return 0;
}

The example code can be compiled and run with the following commands.

g++ custom_widget_example.cc custom_widget.cc custom_widgets_glade.cc \
-o custom_widget_example -fPIC `pkg-config --cflags --libs gtkmm-3.0`
./custom_widget_example

The example also works with gtkmm 2.x versions, but in that case you should compile the code with the following command.

g++ custom_widget_example.cc custom_widget.cc custom_widgets_glade.cc \
-o custom_widget_example -fPIC `pkg-config --cflags --libs gtkmm-2.4`

Glade interface designer

Shared object to Glade can be created with one of the the following commands depending on the version of gtkmm. The name of the file comes from the name that was given in the catalog file. As it was customwidgetsglade the name of the file must be libcustomwidgetsglade.so.

g++ custom_widget.cc custom_widgets_glade.cc -o libcustomwidgetsglade.so -fPIC -shared `pkg-config --cflags --libs gtkmm-3.0`

 

g++ custom_widget.cc custom_widgets_glade.cc -o libcustomwidgetsglade.so -fPIC -shared `pkg-config --cflags --libs gtkmm-2.4`

If each mentioned files are in our working directory Glade 3.x can be run with the following command. Both  GLADE_CATALOG_SEARCH_PATH and GLADE_MODULE_SEARCH_PATH environment variables are set the working directory, so the catalog and the library files will be searched there.

GLADE_CATALOG_SEARCH_PATH=$PWD GLADE_MODULE_SEARCH_PATH=$PWD glade custom_widget.glade

The environment variables are a little bit different in case of Glade 2.x, but the working method is the same.

GLADE_CATALOG_PATH=$PWD GLADE_MODULE_PATH=$PWD glade-gtk2 custom_widget.glade

Now we can find our widget class in the Custom Widgets block and an instance of it in window of custom_widget.glade file.

[.] More

This post is the transcript of Zorp the Firewall of Bastard Operator from Hell presentation was made on Linux Open Administration Days 2012 at Antwerp, Belgium. If somebody missed it, but interested in an open source proxy firewall capable of deep protocol analysis,  now it is available also with the presentation itself.

Many thanks to the organizers for Zorp could be there.


Introduction

As you can see on the initial slide this is the Zorp, the firewall of the bastard operator from hell presentation. This show is about the Zorp firewall application which is developed by a Hungarian middle-market company called BalaBit IT Security. BalaBit IT Security was founded in 1996. It is a software company specializing in development of IT security systems and related services. The name BalaBit IT Security may ring the bell as the developer of syslog-ng, one of the most popular log servers of UNIX-like systems.

My name is Szilárd Pfeiffer. I am a member of the developer team of the Zorp firewall and some related software components. I have been working at BalaBit IT Security for several years, currently as a senior software developer. This was more than enough marketing, so let’s get to the point.

What is Zorp?

Inasmuch most of you have already heard about the bastard operator from hell, but much less of you have heard about Zorp. The first question which has to be answered, what Zorp is. If we read the labels in circles clockwise we get the following sentence as answer. Zorp is an open source modular proxy firewall. Just as usual, the devil lies in the details, so let’s consider each word of this sentence in reverse order.

Firewall

I think it is unnecessary to explain this word here, but I have to say a few words about what makes Zorp special as a firewall.

Application Level

First of all, Zorp is an application level firewall. If an administrator uses Netfilter as firewall traffic can only be controlled up until layer 4 of the ISO/OSI model. In contrast to that Zorp allows analyzation of even the topmost (application) layer, and can make decisions based on data originating from that layer, and also can modify the application level protocol items. What does it mean in practice? It means for instance, that full access can be set to an FTP server for a group of users, or only a subset of commands can be granted to implement a read-only access. Almost any kind of protocol items can be manipulated. For instance STARTTLS can be removed from the feature list of an SMTP server, or compression support of the client can be hidden in HTTP.

Easy to Customize

The second thing which makes Zorp special as a firewall is the easy customization. Zorp is good at solving custom problems in application layer, but during the everyday use it does not require any extra effort to get the benefits of the application level analysis of the network protocols, if we do not have any special requirements. If we have, to keep the application level traffic under control, we do not have to care about neither the details of lower layers, nor the details of the out-of-scope part of the application layer. We only have to concentrate on our existing problem and the solution for that (for example replacing the value of a specific HTTP header), everything else is done by the proxy. What does proxy term mean?

Proxy

As it has already been mentioned earlier, Zorp is better than its competitors, because the network traffic analysis can take place at the application level. To perform that, Zorp implements application level protocol analyzers. These analyzers are called proxies in the terminology of Zorp. Proxies are written in C, and they are extendable and configurable in Python. Nine of twenty five proxies of the commercial version of Zorp are available in the open source edition. You can see them on this slide in three blocks. Proxies in the left block analyze widely used protocols, so it is needless to explain them. Proxies in the right block analyze rarely used protocols, so it is useless to explain them. The two other proxies in the bottom are not named after a protocols, so it is necessary to explain them.

Plug Proxy

The first one is the Plug proxy. As its name shows it does nothing else, but to plug the client and server connection. It has all the benefits that other proxies have, except the protocol analysis.

AnyPy Proxy

The second one is AnyPy proxy. It is a simple proxy like the Plug proxy with a Python interface. It makes it possible to do anything with the application level network traffic which can be done by the help of the Python language, while the lower layers of the connection is handled by Zorp. For instance if the proxy to our favorite protocol is not implemented yet in Zorp we have the possibility to perform application level analysis manually.

Modular

One of the key features of Zorp is modularity. I would like to demonstrate this property of Zorp by three examples. The first is the proxy inheritance.

Proxy Inheritance

As it is mentioned each proxy is configurabe and extendable in Python. It means each proxy represented as a class in Python and the system administrator can inherit his own Python class from that to override the behavior of the parent class. A derived class inherits everything from the base class, which is necessary for the protocol analysis, so the system administrator has to care about his specific problem. For instance to change a value of a header in the HTTP protocol needs only an extra line of code over the lines related to the Python inheritance mechanism.

General SSL Handling

General SSL handling follows from the fact, that transport layer security is an independent subsystem in Zorp. It means, that SSL/TLS parameters can be set independently from the fact, that we perform protocol analysis or not. Consequently not only HTTP, FTP, SMTP and POP3 proxies are SSL capable, but also the Plug and the AnyPy proxies. Server and client side SSL parameters can also be set independently. So it is possible to encrypt on the client side, but not on the server side and vice versa. Of course both of the sides can be encrypted.

Program stacking

Zorp is a proxy firewall, neither more nor less, but can be used to do tasks other than protocol analysis, such as virus scanning or spam filtering by integrating it with external applications. For instance in case of the HTTP protocol Zorp can forward responses to a virus scanner software. After that depending on the result of the scan Zorp can accept or reject the original request.

Open Source

Zorp is a free software as it is licensed under GPL and LGPL. The reason of the two licenses is the fact that Zorp is released in two parts. One is the application level proxy firewall itself (zorp) and a related kernel module (kzorp), under the terms of GPL. Other is a low level library for Zorp (libzorpll), under LGPL. It must be noted here that the Zorp is a dual-licensed software, where Zorp GPL is the open source version and Zorp Professional is the proprietary one with some extra features and proxies.

I hope so that I have been succeeded in answering briefly the question what the zorp is. The next step is to answer the question why a system administrator should use the Zorp. How can Zorp help the system administrator in addressing the issues you can see on this slide.

Why Zorp?

Access Control

There is no firewall without access control and Zorp is no exception to this rule. When an access control policy is being created, we have to answers the ”who” question, as service should be accessible only for a specific group of users under the defined conditions. Usually access to the services controlled by the attributes of lower layers of the ISO/OSI model, like IP addresses or ports. Zorp has an extra feature compared with other firewall suites. There is a possibility to define sets of IP subnetworks, called zone.

Administrative Hierarchy

Zones group IP subnetworks that administratively belong together. What is it good for? In this way an administrative hierarchy can be created that is independent from the network topology, reflecting only the network policy. Imagine the situation when all those who are permitted to access an FTP servers for upload not belongs to the same IP subnet. In this case we would have to add at least two IP based rules to our network policy. If we use Zorp we only have to add necessary IP subnetworks to the necessary zone.

Inheritable Rights

Other notable feature of zones, that they can be linked to a tree hierarchy. Access control rights are inherited between the levels of the zone tree. A top-level access is in effect in the lower levels as long as it is not blocked. For instance a top-level access can be the right to download from FTP servers. When a group of users should have special rights. These special rights can be granted in the lower levels of the zone tree.

Traffic Control

When an access control policy is being created, we also have to answers the ”how” questions, as resources should be accessible under the defined conditions. It may mean that each request and response must be recorded to the system log when a given server is accessed. Certain protocol items can be filtered out or can be modified or can be restricted.

Protocol Enforcement

There is a simple, but good example to shows the advantage of a proxy firewall technology. When the system administrator has to grant access to the World Wide Web, usually only one rule is created, which opens port 80 to the Internet. It solves the original problem, but generates another one. With the help of this rule anybody can access any kind of service of any server on the port 80 independently from the fact, that it is a web service or not. Zorp can enforce the application level protocol, for example HTTP on port 80.

Information Leak Prevention

HTTP

Next issue is information leak prevention. First of all it must be noted, that Zorp is not a Data Loss Prevention system, but can help the system administrator to avoid leaking some kind of sensitive information, which are usually not filtered or blocked by the firewalls, because they are absolutely compliant with the related protocol standards.

Best known example is the User-Agent field in the HTTP header, which contains the name and the version of the browser connected to the server. In this case information about the software being run on the client machine is received by the visited web server without the knowledge or the permission of the user.

Another example is the Referer field, which tells the address of the previous web page from which a link to the currently requested page was followed. If it was the address of a server from the local network, it leaks the addresses of our private network. The proxy settings of the browser, the IP address of the machine are leaked in the same way.

SMTP

Similar methods exist in case of SMTP protocol. System administrators have to be aware of these type of information leaks and have the means to forbid them. Zorp is an easy-to-use and flexible tool to do that.

Interoperability

Some interoperability related problem can also be solved by Zorp follows the fact that a proxy firewall makes independent connections with the participants of the network communication and relays messages between them separating the clients and the servers from each other. In the style of Lord of the Ring one socket was given to the server and one was given to the client, but they were all of them deceived. Zorp in secret forged a proxy to control all the network communication. One proxy to rule them all. Seriously, client thinks that it talks to the server and server thinks that it talks to the client. In real each of them talks with the proxy, which send their messages to the other part, while reinterprets it.

Client Information Forgery

Not only forbidding of a complete protocol item is possible, but also the modification of their values. It can solve the problem of the interoperability for example when a web server constraints the type or the version of the connecting browser despite of the fact that it has no good or valuable reason. Such a situation can be solved easily by changing the value of the User-Agent header in the request sent by the browser to a value which is acceptable to the server.

One-sided SSL

The lack of encryption support may cause interoperability problems. There are several solutions to this problem, but if we want to proxy the encrypted traffic and use different methods of encryption (STARTTLS, SSL) to the client and the server side, Zorp is still a working solutions. One-sided SSL can be made, which means, that it is possible to establish an encrypted connection through the untrusted network and a plain connection through the trusted one. It is also possible the use different versions of encryption (TLS 1.0, TLS 2.0) to the client and server.

Protocol Feature Filtering

To continue the encrypting example, Zorp can hide the STARTTLS feature of the SMTP server from the client, which prevents to initiate encrypted communication in this way. Certain combinations of client and server side SSL settings (for example when SSL is forced in server side) Zorp does it automatically.

Content Filtering

Content filtering is a key feature of firewalls. Zorp is not an exception to this rule, even if without extensions there are only limited opportunities to do that work. However, each of spam filtering, virus scanning, URL filtering is possible by means of external software components. Zorp is a proxy firewall, so it does nothing, but analyzes the protocol to find the particularly interesting parts of the traffic (URL, downloaded data, e-mail attachment, …) and passes it to the necessary application. As the result of the content filtering and possibly other conditions, Zorp may accept, reject or only log the request. We have nothing to do, but establish connection between the Zorp and the chosen content filtering software (for example: ClamAV, SpamAssassin, …) with a simple adapter application, which makes the location of the data known to the content filtering tool and forwards the result back to Zorp.

Audit

Establishing an access control system is only the first step on the way to achieve a well-controlled and secure network. Operating and administrating this network is more difficult. Above all, we need to know what is happening in our network, because only this information can create the possibility to improve the access control system. On the one hand we have to answer what kind of events have violated the current network policy. On the other hand we are in need of the information whether a permitted action has happened or not and if so, than how. Zorp is able to log the necessary information in both cases.

Application Level Logging

The benefit of Zorp is the fact that we can retrieve information from the proxies in application level so events of the network can be handled in the application level also. Even requests and responses of a protocol can be recorded to the system log, which can be very useful in case of an audit. After the necessary configuration of the proxy from the log messages it can be proved whether an event has happened or not in a specific time interval and also statistics can be created based on them. It is important to emphasize the fact, that we can log the access of a server in application level without any modification of the server.

Flexibility

Zorp is able to solve the general uses mentioned above as it is, but the strength of the Zorp lies in the fact that it is easily extendable and customizable to solve specific problems. We do not need to reimplement any kind of functionality, especially the protocol analysis, we can reuse and extend them to meet our requirements. Proxies can be scripted in Python with all of the benefits of the language. Existing ones (HTTP, FTP, …) can be specialized, or a new one can be implemented if we want to analyze the protocol at application level.

How Zorp work?

Finally I would like show you some demo videos to present how Zorp works in practice.

Access Control

Read-only FTP

The first demo video is about a read-only FTP access. You can see what the client does in the top left block, the log of the FTP server in the top right block and the log of the firewall in bottom. What is happening? Client tries to access an FTP server through the firewall.

First we issue a read-only command, which is sent successfully to the server, as we can see it both in the server and the firewall log. However we issue a write command the ”Error parsing command” message is shown on the client side. If we check the log of the server we can see, that nothing has happened as a result of the write commands. The reason is that these command has never reached the server, because Zorp rejected them as we can see it in the firewall log.

As it is a general use case Zorp has a predefined proxy to do that work, so the system administrator don’t have to do anything to implement a read-only FTP access, only use that proxy.

Information Leak Prevention

Replacing User-Agent Header in HTTP

The next demo video is a header replace example is HTTP. The arrangement of the blocks is the same as it was in the previous example, top left block is the client, top right is the server log and the firewall log is in the bottom. As you can see two different types of client try to access an HTTP server.

For the first time it is done through a normal HTTP proxy, so we can found the type and version information of the client in the log of the HTTP server. For the second time clients access the HTTP server through an inherited HTTP proxy, which changes the value of the User-Agent header. As you see in the server log the user agent changed to My User-Agent. It is a simple example of changing the application level protocol, which makes possible to hide the type and the version of the used browsers, as it can be sensitive information. Anyway it is also makes possible to a value, which is suitable for a web server which constraints the type or the version of the browsers. This case is about the interoperability, which is the next topic.

Interoperability

Feature Filtering in SMTP

The next demo video shows an example where the client and the server side SSL setting are completely differ from each other. It means that Zorp does not use encryption while communicating with the client, but use SSL while communicating with the server. First of all you can see the feature list of the SMTP server at top right, after we get in on the server side. It contains the STARTTLS feature, so the server implements this method. If we setup the proxy to use unencrypted connection to the client and we force encrypted connection to the server it is pointless to forward the STARTTLS feature to the client, as we don’t want to give the chance to the client to start encrypted connection and it is meaningless to send a STARTTLS command to server in an encrypted connection.

When we use the mentioned configuration, the SMTP proxy filters out the STARTTLS feature automatically, as you can see at top left where the client request the feature list of the SMTP server through the SMTP proxy.

Content filtering

Virus Scanning

This video demonstrates how Zorp can be integrated with an external virus scanner. First client downloads the Eicar virus through a normal HTTP proxy. For the first time it can be done, because there is no virus scanner connected to the HTTP proxy. For the second time client tries to download the same file, but through a customized HTTP proxy, which passes the data replied by the HTTP server to an anti-virus software. As the Clam AntiVirus has found an Eicar in the content, as it can be seen in the log, Zorp sends an error page back to the client as a result and writes a message to the log about this incident.

URL Filtering

Second example on this topic is a simple URL filtering. For the first time client access the HTTP server through a normal HTTP proxy and it is working. For the second time the URL is rejected by the proxy, so the request is not forwarded to the server, it cannot be seen in the log of the HTTP server, but a message has been written to log of the firewall about this incident.

Audit

Logging in HTTP

As we have seen in the earlier demo videos by default the log of Zorp does not contain application level information about the networking events. For audit purposes Zorp can be configured to log each and every command of a session. This demo video is an example of an HTTP session. For the first the client access the HTTP server through a normal HTTP proxy just as usual, so there is nothing special in the firewall log. For the second time the HTTP server is accessed through a proxy, which is configured to log each and every application level command. So you can see the GET request in the firewall log.

Logging in FTP

The next demo video is almost the same that the last one, except the server is an FTP server. Just as previously for the first time client access the FTP server through a normal FTP proxy, but for the second time each and every application level command is logged, as you can see.

Flexibility

The last two examples tries to demonstrates the flexibility of Zorp from two totally different point of views.

Content Modification in HTTP

First example demonstrates the content modification possibility of Zorp. Just like in the previous demo videos at the first time the client access an HTTP server through a normal HTTP proxy, so it just works. For the second time the same server is accessed through a proxy, which combines the program stacking with the header modification. Proxy stacks a tr to uppercase the content of the HTML page and sets the value of Accept-Encoding header to identity, because tr does not handle compression. Uppercase may not seem useful, but it is also possible to replace all the HTTP reference to HTTPS, which may seem much useful.

SSL Keybridge in HTTPS

At last but not least this video demonstrates how can Zorp handle an encrypted connection. Just as usual the top left block is the client, the top right one is the server and you can see the firewall log at the bottom. First, the client accesses the HTTPS server through a Plug proxy, so there is no modification on the traffic, we can see the result of the server as it is. We use the openssl command to print out the issuer of the certificate of the HTTPS server. As you can see the common name of the issuer is server.zorp, which is the name of the server host. Anyway, the certificate cannot be verified because it is a self-signed certificate.

For the second time, the same server is accessed through a proxy, which is configured to decrypt the secure connection on one side and encrypt it on the other side. Lets issue the same openssl command to print out the issuer of the certificate. As you can see the common name of the issuer has been changed to firewall.zorp Trusted CA. In contrast to the common name of the issuer, the certificate ncannot be verified, but if we set the client to trust in the CA certificate that signed the certificate sent by Zorp, everything functions well. What is it good for? Zorp can make a decision depending on the server certificate or any other condition, whether it trusts the server certificate or not. As the result of this decision Zorp can send two dfifferent certificates, a trusted or an untrusted one. If we import the CA certificate of the trusted one to our client, we achieve that the firewall can determine whether we trust in a server or not independently from the CA certificates trusted by the client.


Useful information can be found here, among others ready-to-use virtual machines sporting Zorp GPL.

[.] More

What Zorp is good for

Wednesday, February 8, 2012 @ 09:02 AM Author: Pfeiffer Szilárd

A marketing specialist would claim that it is “good for everything”. Not being one of them, we would rather say that Zorp is not the philosopher’s stone, however, it can solve almost any issue that can be expected from a deep protocol analyzer proxy firewall. The most important cases are the following:

Access control

Access control is a basic functionality of proxy firewalls, but Zorp has an extra feature compared with other firewall suites. Access to the services can be controlled by the attributes of lower layers of the ISO/OSI model, like IP addresses or ports, but in case of Zorp there is a possibility to define sets of IP subnetworks, called zones. Zones are IP subnetwork groups that administratively belong together (for example all those who are permitted to access FTP servers for upload) and can be linked to a tree hierarchy. Access control rights are inherited between the levels of the zone tree. A top-level access (for example a right to download from FTP servers) is in effect in the lower levels as long as it is not blocked. In this way an administrative hierarchy can be created that is independent from the network topology and the location of the devices, while reflecting only the network policy.

When an access control policy is being created, we first have to find answers to the “who”, “what” and “how” – questions. Resources should be accessible only for a specific group of users under the defined conditions. It may mean that each request and response must be recorded to the system log when a given server is accessed. Some features of the protocol (for example: STARTTLS in case of SMTP) causing incompatibility between the client and the server may have to be filtered out. Some items of the protocol (for example PUT in case of FTP) may be rejected. Some protocol items (for example user-agent in case of HTTP) may be changed to avoid information leak. Secure connection may be decrypted on one side and encrypted again on the other side. The following sections will describe this in detail.

Information Leak Prevention

Several protocols leak information about the running softwares, the networking options of the clients, which is usually not filtered or not blocked by the firewalls, because they are absolutely compliant with the related standards. An example of this is the user-agent header in the HTTP protocol, which contains the name and the version of the web browser connected to the server. In this case an information about the software being run on the client machine is received by the visited web server without the knowledge or the permission of the user.

The proxy settings of the web browser, the IP address of the machine, the URL of the previously visited web page (referrer of the currently visited one) are leaked in the same way. Similar methods exist in case of several protocols, besides HTTP. System administrators have to be aware of these type of information leaks and have the means to forbid them. Zorp is an easy-to-use and flexible tool for that.

Interoperability

Continuing the example above, not only forbidding of complete protocol items is possible, but also the modification of their values. It can solve the problem of the interoperability for example when a web server constraints the type or the version of the connecting browser despite of the fact that it has no good or valuable reason. Such a situation can be solved easily by changing the value of the user-agent header in the request sent by the browser to a value which is acceptable to the server.

The lack of encryption support may cause interoperability mainly in case of old-fashioned software especially when the traffic should pass through an untrusted network. There are several solutions to this problem, but if we want to proxy the traffic and use different methods of encryption (STARTTLS, SSL) to the client and the server, Zorp is still one of the best solutions. It is possible to establish an encrypted connection through the untrusted network and a plain connection through the trusted one. It is also possible the use different versions of encryption (TLS 1.0, TLS 2.0) to the client and server.

To do that, capability of establishing encrypted connections separately to the client and the server is necessary, but not sufficient. The reason is the way to upgrade a plain text connection to an encrypted (TLS or SSL) one instead of using a separate port for encrypted communication (STARTTLS), where understanding the protocol is a must. If we want to hide this functionality from the client and the server even if both of them support it, to solve an incompatibility problem, Zorp can help us. We can conceal features of the clients or the servers (for example STARTTLS in SMTP, or compression in HTTP) from each other.

To continue the encrypting example, Zorp can hide the STARTTLS feature of the SMTP server from the client, which prevents to initiate encrypted communication in this way. Certain combinations of client and server side SSL settings (for example when SSL is forced in server side) Zorp does it automatically.

Content Filtering

Content filtering is a key feature of firewalls. Zorp is not an exception to this rule, even if without extensions there are only limited opportunities to do that work. However, each of spam filtering, virus scanning, URL filtering is possible by means of external software components. Let the cobbler stick to his last. Zorp does nothing else, but analyzes the protocol to find the particularly interesting parts of the traffic (URL, downloaded data, e-mail attachment, …) and passes it to the necessary application. As the result of the content filtering and possibly other conditions, Zorp may accept, reject or only log the request, or even quarantine the response. We have nothing to do, but establish connection between the Zorp and the chosen content filtering software (for example: ClamAV, SpamAssassin, …) with a simple adapter application, which makes the location of the data known to the content filtering tool and forwards the result to Zorp.

Audit

Establishing an access control system is only the first step on the way to achieve a well-controlled and secure network. Operating and administrating this network is more difficult. Above all, we need to know what is happening in our network, because only this information can create the possibility to improve the access control system. On the one hand we have to answer what kind of events have violated the current network policy. On the other hand we are in need of the information whether a permitted action has happened or not and if so, than how. Zorp is able to log the necessary information in both cases.

The benefit of Zorp is the fact that we can retrieve information from the proxies in application level so events of the network can be handled in the application level also. Even requests and responses of a protocol can be recorded to the system log, which can be very useful in case of an audit. After the necessary configuration of the proxy from the log messages it can be proved whether an event has happened or not in a specific time interval and also statistics can be created based on them.

Flexibility

Zorp is able to solve the general uses mentioned above as it is, but the strength of the Zorp lies in the fact that it is easily extendable and customizable to solve specific problems. We do not need to reimplement any kind of functionality, especially the protocol analyzers, we can reuse and extend them to meet our requirements. Nevertheless the proxies are mainly written in C, they can also be scripted in Python with all of the benefits of the language. Existing ones (HTTP, FTP, …) can be specialized, or a new one can be implemented if we want to analyze the protocol at application level only. It is possible with a special kind of proxy (AnyPy) which does anything, but the application level analysis, so we can focus on that job.

Official Zorp GPL support page can be found here.

Ready-to-use virtual machines sporting Zorp GPL can be downloaded here.

[.] More