Translate

sábado, 7 de diciembre de 2019

FTP port porfwarding through SSH tunnel


Tested in:
OS: CentOS 6.10 and  CentOS 7.7.1908
SSH server: openssh-server-5.3p1-124.el6_10, openssh-server-7.4p1-21.el7
FTP server: pure-ftpd-1.0.30-1.el6, pure-ftpd-1.0.47-2.el7
FTP client: ftp-0.17-54.el6.x86, ftp-0.17-67.el7

FTP ports
FTP uses one control FTP port ( the standard is port number  21) . This port allows to a client authenticate to the server, change directory and execute other commands but it is not used for data transfers or output for the listing command.
FTP uses various ports for data transfers. In passive mode, the FTP server receives data connections through these ports. The range of the ports are configured in the Pure-FTP server by the parameter "PassivePortRange". Every time a data connection is made to the FTP server, it informs to the client in which port will be accepted the connection.
In order to port forward de FTP ports through a SSH tunnel, is necessary to tunnel not only the port 21 (control port), but also the data ports that the server will use.

For Local Port Forwarding

FTP server side (destination host):

#Edit pure-ftpd configuration file:
vi /etc/pure-ftpd/pure-ftpd.conf

#Restrain the number of passive ports:
# PassivePortRange          30000 50000
PassivePortRange          30000 30001


#After edition restart server


Client side (origin host):

#SSH Tunel:
ssh -L2121:localhost:21 -L30000:localhost:30000 -L30001:localhost:30001 username@addressofserver

#FTP Client connection:
ftp  localhost 2121

#FTP Client verbose connection (for example, show opened ports):
 ftp  -d localhost 2121


Note:
Opened ports are shown as: (127,0,0,1,117,48). It means:
127,0,0,1 is the IP address ( 127.0.0.1)
117,48 are the high and low bytes of the 16 bit opened port
Hence 117*256 + 48 = 30000



For Local Port Forwarding to another host besides de SSH server host address:

Server side:

#Edit pure-ftpd configuration file and modify ForcePassiveIP parameter:
vi /etc/pure-ftpd/pure-ftpd.conf

# Force client to open localhost IP address in PASV/EPSV/SPSV replies:
ForcePassiveIP                127.0.0.1

#After edition restart server

Client side:

#SSH Tunel:
ssh -L2121:anotherhost:21 -L30000:anotherhost:30000 -L30001:anotherhost:30001 username@addressofSSHserver

#FTP Client connection:
ftp  localhost 2121


For Remote Port Forwarding:

FTP server side (host where the tunnel originates):
#Edit pure-ftpd configuration file:
vi /etc/pure-ftpd/pure-ftpd.conf

#Restrain the number of passive ports:
# PassivePortRange          30000 50000
PassivePortRange          30000 30001

#After edition restart server
 #SSH Tunel:
ssh -R2121:localhost:21 -R30000:localhost:30000 -R30001:localhost:30001 mmendez@lab.anahuac.mx username@addressofSSHserver


Client side (host where the tunnel has its destiny):
#FTP Client connection:
ftp -p localhost 2121


#Example of session (client connects to localhost IPv6):

[mmendez@7 test]$ ssh -R2121:localhost:21 -R30000:localhost:30000 -R30001:localhost:30001 mmendez@servertest.com
Last login: Sat Dec  7 12:23:32 2019 from 172.19.34.52

[mmendez@servertest ~]$ ftp -d -p localhost 2121
Trying ::1...
Connected to localhost (::1).
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 1 allowed.
220-Local time is now 12:26. Server port: 21.
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (localhost:mmendez):
---> USER mmendez
331 User mmendez OK. Password required
Password:
---> PASS XXXX
230 OK. Current restricted directory is /
---> SYST
215 UNIX Type: L8
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd test
---> CWD test
250 OK. Current directory is /test
ftp> ls -l
ftp: setsockopt (ignored): Permission denied
---> EPSV 2
229 Extended Passive mode OK (|||30000|)
---> LIST -l
150 Accepted data connection
drwxrwxr-x    2 mmendez    mmendez            23 Dec  7 12:26 .
drwx------   41 mmendez    mmendez          4096 Dec  7 12:25 ..
-rw-rw-r--    1 mmendez    mmendez            18 Dec  7 12:26 file1.txt
226-Options: -a -l
226 3 matches total
ftp> lcd /tmp
Local directory now /tmp
ftp> get file1.txt
local: file1.txt remote: file1.txt
---> TYPE I
200 TYPE is now 8-bit binary
ftp: setsockopt (ignored): Permission denied
---> EPSV 2
229 Extended Passive mode OK (|||30000|)
---> RETR file1.txt
150 Accepted data connection
226-File successfully transferred
226 0.000 seconds (measured here), 187.13 Kbytes per second
18 bytes received in 2.5e-05 secs (720.00 Kbytes/sec)
ftp> !ls -al file1.txt
/bin/bash
-rw-rw-r--. 1 mmendez mmendez 18 Dec  7 12:27 file1.txt
ftp> bye
---> QUIT
221-Goodbye. You uploaded 0 and downloaded 1 kbytes.
221 Logout.
[mmendez@servertest ~]$ cat /tmp/file1.txt
test file
for FTP
[mmendez@servertest ~]$




For Remote Port Forwarding connecting from another host besides de SSH server host address:

FTP server side (host where the tunnel originates):
#Edit pure-ftpd configuration file:
vi /etc/pure-ftpd/pure-ftpd.conf

#Restrain the number of passive ports:
# PassivePortRange          30000 50000
PassivePortRange          30000 30001

# Force client to open localhost IP address in PASV/EPSV/SPSV replies:
ForcePassiveIP                anotherhostIPaddress
#Example:
#ForcePassiveIP               192.168.0.1

#After edition restart server :
#In Centos 6:
server pure-ftpd restart
#In Centos 7:
systemctl restart pure-ftpd

#SSH Tunel:
ssh -Ranotherhost:2121:localhost:21 -Ranotherhost:30000:localhost:30000 -Ranotherhost:30001:localhost:30001 username@addressofSSHserver




Client side (host where the tunnel has its destiny):
#FTP Client connection:
ftp -p anotherhost 2121



Some references:
- SSH, The Secure Shell: The Definitive Guide, 2nd Edition by Robert G. Byrnes, Richard E. Silverman, Daniel J. Barrett (Chapter 11.2 FTP and SSH )