I'm trying to download a file from a ftp server of a client. I have my code that gets the file and it works fine on my laptop. When I run it from the console in my production server which is inside a virtual machine it doesn't work. It also doesnt work on a virtual machine inside of my desktop pc.
The timout happen on ftp.retrbinary
Code:
# python > 3.6
from ftplib import FTP
file_csv = 'test.txt'
ftp = FTP(host=hostname, timeout=20)
login = ftp.login(user=user_name, passwd=user_pass)
ftp.set_pasv(False)
ftp.cwd('/csv_files/')
localfile = open(file_csv, 'wb')
ftp.retrbinary('RETR ' + file_csv, localfile.write, 1024)
ftp.quit()
localfile.close()
I've set the timeout to 20 or the code will never stop unless i force it. The message i get after the time out is
~/.pyenv/versions/3.6.8/lib/python3.6/socket.py in accept(self)
203 For IP sockets, the address info is a pair (hostaddr, port).
204 """
--> 205 fd, addr = self._accept()
206 # If our type has the SOCK_NONBLOCK flag, we shouldn't pass it onto the
207 # new socket. We do not currently allow passing SOCK_NONBLOCK to
I haven't been able to solve this. Please if someone can help with this, tahnks.
Do not use FTP active mode, unless you have a very specific reason to do so. The active mode usually does not work due to ubiquitous firewalls and NATs.
Use the passive mode instead. To use the passive mode, remove this call:
ftp.set_pasv(False)
ftplib defaults to the passive mode.
For some background, refer to my article on FTP connection modes.
Thanks for the answer Martin, I need to use set_pasv or it wont work.
I Solved the problem, my virtualmachine was using the default NAT settings. After switching to another settings it worked.(to 'Use bridged networking' on vmware)
Related
I am trying to capture ftp packets using scapy. I need to capture the ftp file listing packet when I type the ftp command "ls".
I searched online and found that file listing should be done in passive mode, but that means server port will change; it will not be 21 which I use in scapy to recognize the ftp packets from other packets.
Is there a way I can list the files in active mode? Or another way to capture the listing package in scapy while the server port is a variable "not 21"?
Thank you in advance.
If you have a complete control over the FTP connection, you can use both passive and active mode to retrieve the directory listing.
Though with active mode, the server has to be able to connect to your machine, what is often not possible due to ubiquitous firewalls and NATs. Read my article on network setup needed for FTP active and passive connection modes.
In active mode, the server should use outgoing port 20 for the directory listing. Though if firewall/NAT is involved, the real port, that your client (and Scapy) will see, can be completely different anyway. So it may not help in the end.
With passive mode, you would have to inspect the main (control) connection and detect what port will be used for the listing/data connection and start inspecting that port too. Scapy may even have that functionality (or part of it) built-in, I'm not familiar with Scapy.
I am learning to retrieve files from an ftp server using ftplib from this link : https://docs.python.org/2/library/ftplib.html
When i run this code
from ftplib import FTP
ftp = FTP('ftp.debian.org')
ftp.login()
I get
TimeoutError: [WinError 10060] A connection attempt failed because the
connected party did not properly respond after a period of time, or
established connection failed because connected host has failed to
respond
From this answer https://stackoverflow.com/questions/4946960/when-using-ftplib-in-python#= i get to know that this is a server side issue which can be fixed by changing to ACTV mode.
So i changed my code to
from ftplib import FTP
ftp = FTP()
ftp.set_pasv(True)
ftp.connect('ftp.debian.org')
ftp.login()
Still same error. Can anyone tell me what other reasons could there be from my problem?
Edit - Using Python 3.6.1 on Thonny(IDE) in a 64 bit Win 10 environment
Nothing wrong with this code. It works for me. Maybe the server was just very slow at the time you tried it. You can set a timeout in the connect:
ftp.connect('ftp.debian.org',timeout=seconds)
I had the same problem. As the ftplib description Passive mode is on by default. So set it to False. It works for me.
ftp.set_pasv(False)
Or active passive in server(it's Debian 11 for me) as define the min & max port:
pasv_min_port=10000
pasv_max_port=11000
Of course, you need add the ports in firewall:
ufw allow 10000:11000/tcp
Setting passive mode to False works for me. Thanks!!
ftp.set_pasv(False)
Imagine you have a HTTP server on your local machine, this is a typical Python/Twisted application. This server is used to access your local data, server is used just as a GUI interface. So user can use his web browser or special application ( acts like a web browser ) to access his local data.
Now you want to be sure that only local user who physically sit near this machine get access to the HTTP server.
Also I will have FTP server and it must be protected the same way too.
At the moment I am running such code for my HTTP server:
class LocalSite(server.Site):
def buildProtocol(self, addr):
if addr.host != '127.0.0.1':
print 'WARNING connection from ' + str(addr)
return None
try:
res = server.Site.buildProtocol(self, addr)
except:
res = None
return res
So I am just check the IP address at the moment and I am not sure this is enough.
Is there any ways to emulate local IP from remote machine.?
Well, If a bad guy get access over my OS I have no way to protect - but this is not my deal. My firewall and antivirus should care about this, right?
Anyway, I would like to listen any extra ideas about increase security of such HTTP server.
May be we can use MAC address to verify connection.?
Check the processes on local machine and detect which is actually executes connection?
We can use HTTPS, but in my understanding this acts in opposite direction: this is for user to trust to the server, not server to trust to the user.
Using CAPTCHA is a kind of solution. But I do not like this at all (it strains users) and this will not work for FTP server.
I am also use random port number every time application starts.
The type of internet connection is not defined - this is a p2p application. Any user in the WEB can use my software and it must be protected against remote access.
I believe the way you handled it is good enough. About it being cross-platform, I believe it is as Windows(starting from windows 7) too maps localhost to 127.0.0.1 but for previous versions, you have to define localhost in the main hosts file.
I'm running Python 2.6.5 on ec2 and I've replaced the old ftplib with the newer one from Python2.7 that allows importing of FTP_TLS. Yet the following hangs up on me:
from ftplib import FTP_TLS
ftp = FTP_TLS('host', 'username', 'password')
ftp.retrlines('LIST') (Times out after 15-20 min)
I'm able to run these three lines successfully in a matter of seconds on my local machine, but it fails on ec2. Any idea as to why this is?
Thanks.
It certainly sounds like a problem related to whether or not you're in PASSIVE mode on your FTP connection, and whether both ends of the connection can support it.
The ftplib documentations suggests that it is on by default, which is a shame, because I was going to suggest that you turn it on. Instead, I'll suggest that you set_debuglevel to where you can see the lower levels of the protocol happening and see what mode you're in. That should give you information on how to proceed. Either you're in passive mode and the other end can't deal with it properly, or (hopefully) you'd not, but you should be.
FTP and FTPS (but not SFTP) can be configured so that the server makes a backwards connection to the client for the actual transfers or so that the client makes a second forward connection to the server for the transfers. The former, especially, is prone to complications whenever network address translation is involved. Without the TLS, some firewalls can actually rewrite the FTP session traffic to make it magically work, but with TLS that's impossible due to encryption.
The fact that are presumably authenticating and then timing out when you try to transfer data (LIST requires a 2nd connection in one direction or the other) is the classic symptom, usually, of a setup that either needs passive mode, OR, there's this:
Connect as usual to port 21 implicitly securing* the FTP control connection before authenticating. Securing the data connection requires the user to explicitly ask for it by calling the prot_p() method.
ftps.prot_p() # switch to secure data connection
ftps.retrlines('LIST') # list directory content securely
I don't work with FTPS often, since SFTP is so much less problematic, but if you're not doing that, the far end server might not be cooperating.
*note, I suspect this sentence is trying to say that FTP_TLS "implicitly secures the FTP control connection" in contrast with the explicit securing of the data connection.
If you're still having trouble could you try ruling out Amazon firewall problems. (I'm assuming you're not using a host based firewall.)
If your EC2 instance is in a VPC then in the AWS Management Console could you:
ensure you have an internet gateway
ensure that the subnet your EC2 instance is in has a default route (0.0.0.0/0) configured pointing at the internet gateway
in the Security Group for both inbound and outbound allow All Traffic from all sources (0.0.0.0/0)
in the Network ACLs for both inbound and outbound allow All Traffic from all sources (0.0.0.0/0)
If your EC2 instance is NOT in a VPC then in the AWS Management Console could you:
in the Security Group for inbound allow All Traffic from all sources (0.0.0.0/0)
Only do this in a test environment! (obviously)
This will open your EC2 instance up to all traffic from the internet. Hopefully you'll find that your FTPS is now working. Then you can gradually reapply the security rules until you find out the cause of the problem. If it's still not working then the AWS firewall is not the cause of the problem (or you have more than one problem).
I'd like to be able to transfer files between my mobile phone and computer. The phone is a smartphone that can run python 2.5.4 and the computer is running windows xp (with python 2.5.4 and 3.1.1).
I'd like to have a simple python program on the phone that can send files to the computer and get files from the computer. The phone end should only run when invoked, the computer end can be a server, although preferably something that does not use a lot of resources. The phone end should be able to figure out what's in the relevant directory on the computer.
At the moment I'm getting files from computer to phone by running windows web server on the computer (ugh) and a script with socket.set_ default _ access_point (so the program can pick my router's ssid or other transport) and urlretrieve (to get the files) on the phone. I'm sending files the other way by email using smtplib.
Suggestions would be appreciated, whether a general idea, existing programs or anything in between.
I would use paramiko. It's secure fast and really simple. How bout this?
So we start by importing the module, and specifying the log file:
import paramiko
paramiko.util.log_to_file('/tmp/paramiko.log')
We open an SSH transport:
host = "example.com"
port = 22
transport = paramiko.Transport((host, port))
Next we want to authenticate. We can do this with a password:
password = "example101"
username = "warrior"
transport.connect(username = username, password = password)
Another way is to use an SSH key:
import os
privatekeyfile = os.path.expanduser('~/.ssh/id_rsa')
mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile)
username = 'warrior'
transport.connect(username = username, pkey = mykey)
Now we can start the SFTP client:
sftp = paramiko.SFTPClient.from_transport(transport)
Now lets pull a file across from the remote to the local system:
filepath = '/home/zeth/lenna.jpg'
localpath = '/home/zeth/lenna.jpg'
sftp.get(filepath, localpath)
Now lets go the other way:
filepath = '/home/zeth/lenna.jpg'
localpath = '/home/zeth/lenna.jpg'
sftp.put(filepath, localpath)
Lastly, we need to close the SFTP connection and the transport:
sftp.close()
transport.close()
How's that?? I have to give credit to this for the example.
I ended up using python's ftplib on the phone and FileZilla, an ftp sever, on the computer. Advantages are high degree of simplicity, although there may be security issues.
In case anyone cares, here's the guts of the client side code to send and receive files. Actual implementation has a bit more infrastructure.
from ftplib import FTP
import os
ftp = FTP()
ftp.connect(server, port)
ftp.login(user, pwd)
files = ftp.nlst() # get a list of files on the server
# decide which file we want
fn = 'test.py' # filename on server and for local storage
d = 'c:/temp/' # local directory to store file
path = os.path.join(d,fn)
r = ftp.retrbinary('RETR %s' % fn, open(path, 'wb').write)
print(r) # should be: 226 Transfer OK
f = open(path, 'rb') # send file at path
r = ftp.storbinary('STOR %s' % fn, f) # call it fn on server
print(r) # should be: 226 Transfer OK
f.close()
ftp.quit()
There are a couple of examples out there, but you have to keep in mind that, IIRC, PyBluez will work only on Linux.
I've previously done OBEX-related things, mostly fetching things from
mobile phones, using the obexftp program 2 which is part of the
OpenOBEX project 3. Naturally, you can call the obexftp program from
Python and interpret the responses and exit codes using functions in
the os, popen2 and subprocess modules. I believe that obexftp also
supports "push" mode, but you could probably find something else
related to OpenOBEX if it does not.
Since Bluetooth communications are supported using sockets in GNU/
Linux distributions and in Python (provided that the Bluetooth support
is detected and configured), you could communicate with phones using
plain network programming, but this would probably require you to
implement the OBEX protocols yourself - not a straightforward task for
a number of reasons, including one I mention below. Thus, it's
probably easier to go with obexftp at least initially.
You also have lightblue, that is a cross-os bluetooth library.
There is also a complete script, PUTools: Python Utility Tools for PyS60 Python (examples has Windows screenshots), that has a:
Python interpreter that takes input and shows output on PC, connects over Bluetooth to phone, and executes on the phone. You also get simple shell functionality for the phone (cd, ls, rm, etc.). The tool also allows you to synchronize files both from PC to phone (very useful in application development) and from phone to PC (your images, logfiles from the program you are working on, etc.).