
Benefits:
  Front servers which can't do: PASV, EPRT/EPSV, FTPS
  Can use to do your logging: TransferLog, ExtendedLog, mod_log_zmq, etc.
  Can use to do your monitoring: mod_snmp, etc
  Single SSL cert (on the proxy) for several different backend servers

  Have mod_netsieve here, for sieving the inbound commands and outbound files
  (have netsieve rules for common cases like scanning for SSNs/credit card
  numbers in outbound data)


What would a proxy module for proftpd look like?

  client <-------> mod_proxy <--------> FTP server

So we'd be proxying FTP connections to other FTP servers, including data
transfers.  Would we support both forward and reverse proxy configurations?

  * Set DefaultServer on in the <VirtualHost> section using mod_proxy (or
    don't set it all).  That way, on a proxy server, only connections to
    vhosts configured for proxying are handled; others are rejected.

Forward Proxy
  Need some kind of mechanism that clients can use to specify their end
  targets.

Reverse Proxy
  Terminates any SSL session (backend connection to use SSL or not?)
  What credentials to use for authenticating to backend server for a reverse
  proxy connection?  Modifying of directory listing results as necessary

  How to map clients to origin servers?  By user name, by client IP, or...?
  Re-use proxy USER/PASS with origin server, or override with shared/common
  origin server USER/PASS?  Round-robin, consistent hashing, load balance?
  *Do it based on USER: that's the one feature that mod_proxy can do (i.e.
   it's protocol-aware); the other implementations are TCP-specific, and
   can be done by nginx, haproxy, etc.

  If map/lookup is done based on client IP, then it can be done at connect
  time, and thus mod_proxy can relay the connection to the remote host, and
  let all authentication be handled by the remote/target host.

  Scenarios:

    Complex:
      backend server selection based on USER; this means mod_proxy needs to
      handle login, _then_ select backend and create control connection to
      selected backend.

      *NB: Actually, the selection of the backend user *can* happen based
       on just the USER command, no PASS; this assumes that the auth will
       either succeed using the given USER, or it won't (and the connection
       will be closed).  This distinction means that the proxy does not
       necessarily have to handle authentication itself.

    Balancing (or: selection of backend server)
      ProxyReverseConnect
        roundrobin [options]
        hashing (?) [options]
        userbased [options]

      ProxyReverseServers ftp://localhost:20741 ftp://localhost:20743 

      ProxyReverseServers file://path/to/servers.txt
                          sql://SQLNamedQuery/...
                          ldap://...?

 HAproxy PROXY protocol
   http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
    http://ben.timby.com/?page_id=210

   Implemented in mod_proxy_protocol.

Any caching of proxied results, files, directory transfers, etc?

Use of DNAT/SNAT, so the remote/target server sees real IP of connecting
client, rather than that of the proxy?  Or how else to inform the
backend/origin of the connecting client info?  Keep in mind this possibility:

  client -> proxy -> proxy -> proxy -> proxy -> server

FTP to SFTP proxying:

  http://superuser.com/questions/422348/ftp-to-sftp-scp-proxy

for securing outbound connections (in a forward proxy mode), as well as SFTP
to FTP proxying (e.g. for SFTP for external clients, FTP for internal/legacy
servers) for reverse proxying.

  * Use URIs for specifying protocol proxying; means needing a URI parser
    good enough to extract scheme, host, port, and perhaps authority.

Health checks
  TCP

Data Transfers:
  MODE Z on frontend, backend?

Load balancing

Failover

Timeouts
  ProxyConnectTimeout

Reverse connectivity feature?  (Requires that the backend server know to
connect to proxy for "listening" connection, so custom work.)

HTTP CONNECT

  Client sends CONNECT to proxy, then proceeds to do an _FTP_ control channel
  through the established TCP connection.

  * Can this be used to proxy/hide the origin of an SSH connection as well?
    I think so...

client --> (sftp) --> proxy --> (ftp) --> origin
client --> (ftp) --> proxy --> (sftp) --> origin

Other Proxy Implementations

  http://www.mcknight.de/jftpgw/features.html
  http://aggemam.dk/ftpproxy
    Forward FTP proxy, written in Java
  http://www.glub.com/
    Secure FTP Wrapper; see their "Login" article
  http://frox.sourceforge.net/
  http://www.ftpproxy.org/
  http://freecode.com/projects/suseproxy-suite
    http://www.linuxjournal.com/magazine/configuring-and-using-ftp-proxy
  httpd.apache.org/docs/2.2/mod/mod_proxy.html
    http://forums.devshed.com/ftp-help-113/apache-ftp-reverse-proxy-78960.html
    http://www.apachelounge.com/viewtopic.php?t=3677

  http://www.faqs.org/rfcs/rfc1919.html ("Classical Vs Transparent IP Proxies")

  http://www.faqs.org/rfcs/rfc1579.html ("Firewall-Friendly FTP")

  https://calomel.org/ftp_proxy.html
    ftp-proxy started off as pftpx?
    https://calomel.org/

  http://www.codeproject.com/KB/IP/ProxyFtp.aspx

  http://www.chilkatsoft.com/refdoc/xChilkatFtp2Ref.html
    See ProxyMethod for various FTP proxy approaches

  http://linux.die.net/man/1/lftp
    ftp:proxy
    ftp:proxy-auth-type

  http://www.apsis.ch/pound/index_html

  http://haproxy.1wt.eu/

  http://www.loadbalancer.org/

  http://www.tomkleinpeter.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/

  http://cr.yp.to/ftpparse.html
    Use for parsing FTP lists into SFTP dirlist
    What about MLSD, though?  Need to find parser for that, if avail
      http://software.clapper.org/grizzled-python/epydoc/grizzled.net.ftp.parse.FTPMlstDataParser-class.html 

Links/Articles:

  http://ben.timby.com/?page_id=210
  http://www.taiter.com/techlog/2012/09/ftp-load-balanced-through-haproxy.html
    FTP load balancing through HAproxy

  http://blog.cryptographyengineering.com/2012/03/how-do-interception-proxies-fail.html

  ftpcluster:
    http://www.awk-scripting.de/cluster/
      Uses different cluster server addresses in PORT/PASV, and FXP among
      cluster nodes.  Interesting idea.

Goals

  Contrast with Squid, Apache mod_proxy, others

Testing

  Net::FTP in Perl; use Firewall, FirewallType constructor args.  See
  Net::Config perldocs (quite interesting, actually).

  Net::SOCKS
  IO::Socket::SOCKS
  IO::Socket::SecureSocks
  URI::Socks
  Net::Proxy::Type

Need handle cases like:

  client --> proxy <--> SOCKS/HTTP proxy <--> server

i.e. where the proxy needs to be able to tunnel its connections through
SOCKS/HTTP proxies.
