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

Peter Van Biesen <[email protected]> Mon, 17 Mar 2003 09:50:06 +0100
Newsgroups gmane.comp.apache.mod-proxy
Message-ID <[email protected]>
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);
}
}
}