From: Alexander Gozman Date: Sun, 26 Feb 2017 11:09:42 +0000 (+1300) Subject: Native FTP relay: NAT and TPROXY interception fixes X-Git-Tag: SQUID_3_5_25~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a3def4126bf424886fac7062c113b572fa12647f;p=thirdparty%2Fsquid.git Native FTP relay: NAT and TPROXY interception fixes --- diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 919c956a1f..9678d63154 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1454,9 +1454,33 @@ Ftp::Server::createDataConnection(Ip::Address cltAddr) Comm::ConnectionPointer conn = new Comm::Connection(); conn->flags |= COMM_DOBIND; - // Use local IP address of the control connection as the source address - // of the active data connection, or some clients will refuse to accept. - conn->setAddrs(clientConnection->local, cltAddr); + if (clientConnection->flags & COMM_INTERCEPTION) { + // In the case of NAT interception conn->local value is not set + // because the TCP stack will automatically pick correct source + // address for the data connection. We must only ensure that IP + // version matches client's address. + conn->local.setAnyAddr(); + + if (cltAddr.isIPv4()) + conn->local.setIPv4(); + + conn->remote = cltAddr; + } else { + // In the case of explicit-proxy the local IP of the control connection + // is the Squid IP the client is knowingly talking to. + // + // In the case of TPROXY the IP address of the control connection is + // server IP the client is connecting to, it can be spoofed by Squid. + // + // In both cases some clients may refuse to accept data connections if + // these control connectin local-IP's are not used. + conn->setAddrs(clientConnection->local, cltAddr); + + // Using non-local addresses in TPROXY mode requires appropriate socket option. + if (clientConnection->flags & COMM_TRANSPARENT) + conn->flags |= COMM_TRANSPARENT; + } + // RFC 959 requires active FTP connections to originate from port 20 // but that would preclude us from supporting concurrent transfers! (XXX?) conn->local.port(0);