proxy_ftp : your opinion ? EPSV / PASV and firewalls

proxy_ftp : your opinion ? EPSV / PASV and firewalls

am 14.03.2003 12:58:29 von Peter Van Biesen

Hello,

Our firewall between the proxy and the internet is configured very
restrictive, so only known ports are allowed in either direction. This
poses a problem with the EPSV/PASV implementation of the ftp proxy;
servers that are able to run in EPSV or PASV mode make the proxy produce
a "bad gateway" error ( Firewall / NAT ? ). I've temporarly enabled the
bypass code but I was thinking of writing a more permanent patch.

Therefor, please your opinion: there are two ways to implement this :

1) add a directive to specify if EPSV and/or PASV should be used
2) alter the code to continue with PORT where it now throws a bad
gateway error

The second option is the easiest for the administrator, but generates
more processing overhead ( arbitrary ports will always be blocked, but
the proxy will continue trying for every request ). The first options
produces less overhead, but requires intervention by the administrator (
adaptation of docs, ... ).

Thanx !

Peter.

Re: proxy_ftp : your opinion ? EPSV / PASV and firewalls

am 16.03.2003 18:50:42 von Graham Leggett

Peter Van Biesen wrote:

> Our firewall between the proxy and the internet is configured very
> restrictive, so only known ports are allowed in either direction. This
> poses a problem with the EPSV/PASV implementation of the ftp proxy;
> servers that are able to run in EPSV or PASV mode make the proxy produce
> a "bad gateway" error ( Firewall / NAT ? ). I've temporarly enabled the
> bypass code but I was thinking of writing a more permanent patch.
>
> Therefor, please your opinion: there are two ways to implement this :
>
> 1) add a directive to specify if EPSV and/or PASV should be used

EPSV and PASV are always used.

The logic is try EPSV, if that fails, try PASV, if that fails, try PORT.

> 2) alter the code to continue with PORT where it now throws a bad
> gateway error

To be honest I think you are probably looking at the broken firewall
implementation. Try set up the firewall so that it does PASV properly.

Regards,
Graham
--
-----------------------------------------
minfrin@sharp.fm "There's a moon
over Bourbon Street
tonight..."

Re: proxy_ftp : your opinion ? EPSV / PASV and firewalls

am 17.03.2003 09:50:06 von Peter Van Biesen

Graham Leggett wrote:

> Peter Van Biesen wrote:
> The logic is try EPSV, if that fails, try PASV, if that fails, try PORT.
>
>> 2) alter the code to continue with PORT where it now throws a bad
>> gateway error
>
>
> To be honest I think you are probably looking at the broken firewall
> implementation. Try set up the firewall so that it does PASV properly.

Out firewall allows PASV, connecting manually to a remote server in
passive mode works fine, but with the current implementation of
proxy_ftp this wouldn't help either. If the remote server is able to use
EPSV, PASV is never tried, even when the firewall blocks the
dataconnection, it just gives a 'bad gateway' error, or am I reading the
source wrong ? I've pasted some relevant code from the source at the bottom.

> Regards,
> Graham

I'll make a patch which jumps to PASV when the dataconnection fails (
time permitting ;-) ) ...

Peter.

/*
* IV: Make Data Connection? -------------------------
*
* Try EPSV, if that fails... try PASV, if that fails... try PORT.
*/

/* set up data connection - EPSV */
{
rc = proxy_ftp_command("EPSV" CRLF,
r, origin, bb, &ftpmessage);

ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy: FTP: EPSV contacting remote host on port %d",
data_port);

/* opening a socket is possible ... */
if ((rv = apr_socket_create(&data_sock, connect_addr->family,
SOCK_STREAM, r->pool)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
"proxy: FTP: error creating EPSV socket");
return HTTP_INTERNAL_SERVER_ERROR;
}

/* but now, connection gets blocked by the firewall */
rv = apr_connect(data_sock, epsv_addr);
if (rv != APR_SUCCESS) {
/* should jump to PASV, but just gives a 'bad gateway' instead ... */
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
"proxy: FTP: EPSV attempt to connect to %pI failed - Firewall/NAT?",
epsv_addr);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_psprintf(r->pool,
"EPSV attempt to connect to %pI failed - firewall/NAT?", epsv_addr));
}
else {
connect = 1;
}
}
else {
/* and try the regular way */
apr_socket_close(data_sock);
}
}
}

Re: proxy_ftp : your opinion ? EPSV / PASV and firewalls

am 25.03.2003 14:50:11 von Peter Van Biesen

This is a multi-part message in MIME format.
--------------000007070005010904030601
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

I've made the patch and tested it with our firewall configuration. When
EPSV failes because of the firewall, the proxy continues with PASV and
so on ... Errors are now warnings. The problem download now produces a
warning on EPSV but continues with PASV, which succeeds ...

[Tue Mar 25 14:47:31 2003] [warn] (239)Connection refused: proxy: FTP:
EPSV attempt to connect to 129.33.28.113:6073 failed - Firewall/NAT?
Trying PASV ...

patch in attachment.

Regards,

Peter.


Peter Van Biesen wrote:

> Graham Leggett wrote:
>
>> Peter Van Biesen wrote:
>> The logic is try EPSV, if that fails, try PASV, if that fails, try PORT.
>>
>>> 2) alter the code to continue with PORT where it now throws a bad
>>> gateway error
>>
>>
>>
>> To be honest I think you are probably looking at the broken firewall
>> implementation. Try set up the firewall so that it does PASV properly.
>
>
> Out firewall allows PASV, connecting manually to a remote server in
> passive mode works fine, but with the current implementation of
> proxy_ftp this wouldn't help either. If the remote server is able to
> use EPSV, PASV is never tried, even when the firewall blocks the
> dataconnection, it just gives a 'bad gateway' error, or am I reading
> the source wrong ? I've pasted some relevant code from the source at
> the bottom.
>
>> Regards,
>> Graham
>
>
> I'll make a patch which jumps to PASV when the dataconnection fails (
> time permitting ;-) ) ...
>
> Peter.
>

--------------000007070005010904030601
Content-Type: text/plain;
name="proxy_ftp.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="proxy_ftp.patch"

*** proxy_ftp.c.orig Mon Mar 17 12:05:14 2003
--- proxy_ftp.c Tue Mar 25 14:37:49 2003
***************
*** 1291,1300 ****
apr_sockaddr_info_get(&epsv_addr, data_ip, connect_addr->family, data_port, 0, p);
rv = apr_connect(data_sock, epsv_addr);
if (rv != APR_SUCCESS) {
! ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
! "proxy: FTP: EPSV attempt to connect to %pI failed - Firewall/NAT?", epsv_addr);
! return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_psprintf(r->pool,
! "EPSV attempt to connect to %pI failed - firewall/NAT?", epsv_addr));
}
else {
connect = 1;
--- 1291,1300 ----
apr_sockaddr_info_get(&epsv_addr, data_ip, connect_addr->family, data_port, 0, p);
rv = apr_connect(data_sock, epsv_addr);
if (rv != APR_SUCCESS) {
! ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
! "proxy: FTP: EPSV attempt to connect to %pI failed - Firewall/NAT? Trying PASV ...", epsv_addr);
! /* port blocked, clean up and try PASV */
! apr_socket_close(data_sock);
}
else {
connect = 1;
***************
*** 1376,1385 ****
apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0), connect_addr->family, pasvport, 0, p);
rv = apr_connect(data_sock, pasv_addr);
if (rv != APR_SUCCESS) {
! ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
! "proxy: FTP: PASV attempt to connect to %pI failed - Firewall/NAT?", pasv_addr);
! return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_psprintf(r->pool,
! "PASV attempt to connect to %pI failed - firewall/NAT?", pasv_addr));
}
else {
connect = 1;
--- 1376,1385 ----
apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0), connect_addr->family, pasvport, 0, p);
rv = apr_connect(data_sock, pasv_addr);
if (rv != APR_SUCCESS) {
! ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
! "proxy: FTP: PASV attempt to connect to %pI failed - Firewall/NAT? Trying PORT ...", pasv_addr);
! /* clean up and continue with PORT */
! apr_socket_close(data_sock);
}
else {
connect = 1;

--------------000007070005010904030601--