LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Evaluation of the SuSE FTP Proxy as a followup to the recent postings

To: "lvs-users@xxxxxxxxxxxxxxxxxxxxxx" <lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Evaluation of the SuSE FTP Proxy as a followup to the recent postings
Cc: Joseph Mack <mack@xxxxxxxxxxx>, Lars Marowsky-Bree <lmb@xxxxxxx>
From: Roberto Nibali <ratz@xxxxxx>
Date: Tue, 08 May 2001 12:35:09 +0200
Hi guys,

There has been some talks about ftp, security and LVS recently and different
opinions appeared. I wasn't aware of the fact the people still heavily use 
the ftp protocol through a firewall, rather then putting a completely secluded
box in a corner. Back here at terreActive we have been fighting with the ftp
problem since 4 years already and we have not yet the ultimate solution. As
such we also evaluated the SuSE FTP proxy available from 

http://www.suse.de/en/support/proxy_suite/

What follows is an evaluation mostly done by one of our coworkers Martin 
Trampler and me (ratz). We're not yet finished with testing everything and
all possible setups (NAT, non-NAT, client behind a firewall, etc.) but the
result looks rather good in terms of improving security. A better paper will
probably follow, but we're too busy right now and ftp is anyway not allowed
in our company policy unless the customer has a special SLA.

Best regards,
Roberto Nibali, ratz

-- 
mailto: `echo NrOatSz@xxxxxxxxx | sed 's/[NOSPAM]//g'`
   Title: SuSE FTP Proxy evaluation (as transparent proxy)
   
   Tests : mt & ratz, countless hours during night.
   Author: mt; xx/May/2001, ratz; shortened and edited for LVS 
           mailinglist
   
                                    General
                                       
   Motivated by
    1. the general problems related to allowing FTP-traffic through a not
       stateful packetfilter
    2. the special problems we encountered with the Firewall-1 software
       on one of our packetfilter which in the end forced us to deinstall FW1
    3. the broken Linux FTP-masquerading module
       
   I started in March/01 with a search for a FTP Proxy-software, which
   could be used as a drop-in on pab1/2-machines to increase the security
   of the machines (clients and servers) behind the packetfilters. Since
   it was a requirement that this Software should be able to
   transparently proxy external clients (i.e. the clients don't realize
   that there is a proxy inbetween), there was only one package which
   deserved a closer look: The FTP-Proxy from the SuSE Proxy Suite (which
   actually consists of nothing but this FTP-Proxy). This Proxy since
   about 4 months also includes support for transparent proxying mode.
   
                               Mode of operation
                                       
   The Proxy consists of a single binary (ftp-proxy, stripped about 50k).
   All configuration-options can be set in a single configuration-file
   which by default is named ftp-proxy.conf and searched for in whatever
   directory was given with the configure-option --sysconfdir=. If this
   option was not given it is searched for in
   /usr/local/proxy-suite/etc/, which shows SuSEs braindead BSD-heritage.
   Best way is, to give the config-file at runtime with the -f
   cmdline-option.
   
   It is very useful to compile debugging-support into the binary during
   evaluation and to run it with the cmdline-option -v 4 for maximum
   debugging. Debugging output is then appended to /tmp/ftp-proxy.debug.
   It can be run from (x)inetd or in standalone-mode as daemon. I only
   evaluated the daemon.
   
   It reads the config-file (which must exist) and binds to some local
   port (e.g. 3129, which is IANA-unassigned and squid+1). The
   Packetfilter has to be configured to redirect all packets which come
   in on port 21 to this port (more later). As soon as it gets a request
   it handles it by first replying to the client only. After the initial
   USER <username> command it connects to the server (or, more exactly,
   to port 21 of the host whose IP was the destination of the redirected
   package).
   
   The configfile may contain user-specific sections which direct special
   users to special servers. This feature may be very useful but was not
   evaluated either. It then continues as an agent between client and
   server; checking either side's communication for correct syntax, as a
   good application-proxy should.
   
   As soon as the client prepares a data connection (either by sending a
   PASV or a PORT command, it acknowledges it and, in case of a requested
   passive connection, establishes a listener which binds to the server's
   IP (!!). This came rather as a surprise to me. It actually works and
   means, that the data connection is transparent as well for the client.
   The range of port on which it listens is configureable as well as the
   range of ports it uses for outgoing connection (to either the server
   or to the client in the active-ftp case).
   
   As soon as the client actually wants to retrieve data, the connection
   to the server is established and the data is shuffeled around. Since
   the connection to the server is completely seperate from the client
   connection, its mode doesn't have to be the one the client requests
   (also by default it is). The data-connection to the server may also be
   configured to always be active or passive. Here it is clearly
   desireable to always use passive mode to avoid opening another
   listener on the packetfilter.
   
                                  Evaluation
                                       
   After initially having some minor problems to compile the proxy (it
   has to be configured --with-regex) and to get it running (by default
   it thinks it is started by inetd, i.e. standalone-mode is not the
   default) it ran without problems and also wrote informative messages
   into the debugging file. Almost everything can be configured in the
   configuration file (also not everything is documented unambigously)
   but in general the quality of the documentation, the logging and the
   debugging messages seems quite high.
   
   The proxy is, as already mentioned, completely transparent for the
   client and of course intransparent for the server (i.e. the server
   sees the connections coming from the client).
   
   First more extensive stress-testing and code-review performed on
   04/Apr/01 showed the following irregularities:
     * Using active ftp, the data-connection on the server-side often
       failed. This problem could be circumvented by forcing the Proxy to
       always use passive mode on the server side (which should be used
       anyways, see below)
     * The control-connection on the server side often could not be
       established.
     * When running with debugging-output enabled, we found strange
       characters in the debugging as well as in the logging-output.
       
   The failed connections result from portnumbers being reused where they
   should be increased. I think, this problem would also be found on the
   client-side of the connection if the stress-test would issue more than
   1 data-retrieving command. It may help to undefine the
   Destination[Min|Max]Port configuration directive to get a port
   assigned by the system.
   
   The - attack-behaviour vanished after disabling debugging
   output but may nevertheless being an issue. We found a questionable
   use of a static char* in a formatting routine.
   
                    Integration into a firewall suite
                                       
Packetfilter-ruleset

   First the Packetfilterport on which the proxy listens must be closed.
   It is well possible to bind the proxy to e.g. localhost, but the
   ipchains ... -j REDIRECT (see below) only allows the specification of
   a port, not of port+IP. If the proxy is bound to an IP it doesn't get
   the packets. It has to be universally bound and therefore its port
   must be closed.
   
   In the following I use:
   PASV_PORTS: Configuration-directives "Passive[Min|Max]DataPort"; Ports
   on which Listeners for passive connections (to Clients) may be
   installed
   SC_PORTS: Configuration-directives "Destination[Min|Max]Port"; Ports
   which are used for connecting to the server (control-conn., data-conn.
   if server in passive mode) or on which the proxy listens for the
   server's data (if server in active mode, not documented). For
   client-connections it is necessary that:
     * In the input-chain (for the IF on which client packets arrive)
       there must be a redirect for packets from the client to the
       server, port 21 to the port on which the proxy listens.
     * In the input-Chain (for the IF on which client packets arrive)
       connections from the client to the server on port (UNPRIV->21) and
       (UNPRIV->PASV_PORTS) are accepted (as well as the reply-packets in
       the output-chain). The redirect-rule already acts as accepting
       rule for the incoming packets for port 21.
       Furthermore in the output-chain connections from the proxy (but
       with IP-adress of the server!), port 20, to the client (UNPRIV)
       must be allowed (as well as the corresponging reply-packets in the
       input-chain).
       
   For server-connections it is necessary that:
     * In the output-chain of the server-side IF connections from the
       proxy (SC_PORTS) to port 21 of the server are allowed (and the
       reply packets in the input-chain)
     * In the output-chain of the server-side IF connections from the
       proxy (SC_PORTS) to the server (UNPRIV) are allowed (and the reply
       packets in the input-chain)
       
   The latter pair of rules covers the case that all data connections
   from the proxy to the server are passive.
   Note, that no rules for the forward-chain are necessary at all.
   
   Have a look at this nice ASCII-Art, which shows the
   control-connection.

                        +--------------------------+
                        |      |     Proxy      |  |
                        |      |3129____________|  |
  +--------+   tcp/21   |-----   ^         |  -----|  tcp/21   +--------+
  | Client |----------->|eth0|   |         +->|eth1|---------->| Server |
  +--------+ to server  |--------+redirect    -----|           +--------+
                        |Packetfilter              |
                        +--------------------------+

   The obvious problem is, to formulate a fw-ftp-proxy script which
   accepts 2 NEs (external client, internal server) as input and does not
   generate redundant rules. Because the server-side connection is
   completely independent from the client, its rules must only be added
   once for each server while the client-side rules (including the
   redirect) are dependent of both server and client. Probably the best
   way would be to add a script which only handles the client-side and to
   add each ftp-server seperately with a "tcp@fw"-rule. Since tcp@fw does
   not allow specification of source-ports, this rule would then be wider
   as necessary.
   
   In the client-side script, the portrange used in the proxy-configfile
   would then have to be hardwired. It would be necessary to verify, that
   for every server used as target in a client-side script there is at
   least (or even better exactly one) tcp@fw as described above.
   
Security considerations

   General Aspects
   We had a swift look at the code and it looks rather clean and well
   documented to me. Unfortunately some features are incorrectly
   documented or not documented at all while some features are already
   documented but not yet implemented.
   
   As already mentioned, the port on which the proxy listens has to be
   closed. The servers should only be driven in passive mode, which
   should be possible for any server. The PASV_PORTS should be restricted
   to a dozen or so (depending on the load).
   
   For the maintainers of the servers, the major drawback is the proxy's
   intransparency.
   
                          Features not yet evaluated
                                       
     * User-specific configurations
     * Use with LDAP and the TCP-Wrapper library (configure-options
       --with-ldap and --with-libwrap
     * Limiting the set of allowed commands
     * Proc-Filesystem Interface (module)
     * chroot of forked processes
       
                                  Conclusion
                                       
General Aspects

   Given the current situation, where we shoot huge holes in the firewall
   to fully enable (passive) ftp connections to servers located inside,
   the use of this proxy would greatly increase the security of these
   systems.
   
   Prior to deployment I think the code should be reviewed more closely
   (remember that the proxy opens listeners on the PF!) and some more
   efforts should be undertaken to find a configuration which is as tight
   as possible by providing the required functionality (cf. the section
   above).
   
Extensions

   It should, in general, be possible to have a second proxy running for
   inside clients. There we still have the problem, that we have to open
   the whole UNPRIV-Range for connections coming from sourceport 20.
   Basically I think, that this problem should be handled differently:
   Providing the functionality is the business of the server (hence the
   name) . The FTP-Protocol provides passive mode exactly for this case
   (firewalled client). So we should in general not allow clients behind
   our Firewalls/Packetfilters to make active FTP connections.
   
   We found out that it should not be too difficult to enable
   "bidirectional transparency".
<Prev in Thread] Current Thread [Next in Thread>