Uploading large files to proftpd through paramiko times out - python

I've set up a SFTP server using proftpd on my local machine. It works fine, except that it times out when uploading files larger than approximately 30000 characters.
Uploading from the command line through proftpd works without any problems, and using paramiko to upload to a different SFTP server also works. This leads me to think there is a bug specifically in the interaction between paramiko and proftpd.
I've made a small script to illustrate the problem:
import paramiko
transport = paramiko.Transport(('localhost', 2220)) # my proftpd SFTP port
transport.connect(username='x', password='x')
client = paramiko.SFTPClient.from_transport(transport)
with open('testimage.jpg') as f: # 35241 characters
content = f.read()
with client.open('testimage.jpg', 'w') as f:
f.write(content)
My SFTP-specific proftpd configuration:
<IfModule mod_sftp.c>
<VirtualHost 0.0.0.0>
Include /etc/proftpd/conf.d
SFTPEngine on
SFTPLog /var/log/proftpd/sftp.log
Port 2220
SFTPHostKey /etc/ssh/ssh_host_rsa_key
SFTPHostKey /etc/ssh/ssh_host_dsa_key
SFTPAuthMethods password
SFTPCompression delayed
MaxLoginAttempts 3
</VirtualHost>
</IfModule>
After 10 minutes, the program exits and spits out this error:
Traceback (most recent call last):
File "ftptest.py", line 9, in <module>
f.write(content)
File "/Library/Python/2.7/site-packages/paramiko/file.py", line 330, in write
self._write_all(data)
File "/Library/Python/2.7/site-packages/paramiko/file.py", line 447, in _write_all
count = self._write(data)
File "/Library/Python/2.7/site-packages/paramiko/sftp_file.py", line 176, in _write
self._reqs.append(self.sftp._async_request(type(None), CMD_WRITE, self.handle, long(self._realpos), data[:chunk]))
File "/Library/Python/2.7/site-packages/paramiko/sftp_client.py", line 668, in _async_request
self._send_packet(t, msg)
File "/Library/Python/2.7/site-packages/paramiko/sftp.py", line 170, in _send_packet
self._write_all(out)
File "/Library/Python/2.7/site-packages/paramiko/sftp.py", line 135, in _write_all
raise EOFError()
EOFError
Using paramiko 1.15 and proftpd 1.3.5

The default window size of 4 GB was too big for paramiko, causing data transfer to stall.
The issue was resolved by adding this to the proftpd SFTP configuration:
SFTPClientMatch ".*" channelWindowSize 3999MB

Related

VI_ERROR_TMO (-1073807339) on Anritsu OSA

I'm working on interfacing an old Optical Spectrum Analyzer Anritsu MS9710B with a RS232 connection. A year ago, I managed to comunicate with him, send SCPI command using pyvisa and receive data. Today, I execute the exact same code with libraries up to date and I get an error Timeout when I query IDN or anything. The RS232-USB drivers are ok, I manage to open a communication but a query or read fail.
I changed the parameter to "RS232C" on the OSA parameters and my communication parameters are the same between OSA and program. Following advices from the forum, I tried the connection with NI-VISA where I get the same error. I tried to change timeout parameter, write_termination and read_termination but there isn't any change. The manual is very hard to understand termination value, but when it worked I didn't add anything.
I don't know anymore what to do.
Any advices and help would be warmly welcome to fix my problem !
import pyvisa
from pyvisa.constants import StopBits, Parity
rm = pyvisa.ResourceManager()
print(rm.list_resources())
my_instrument = rm.open_resource('ASRL5::INSTR')
my_instrument.baud_rate=9600
my_instrument.data_bits=8
my_instrument.parity=Parity.even
my_instrument.stop_bits=StopBits.one
my_instrument.write('*IDN?')
print(my_instrument.read())```
'''
('ASRL5::INSTR',)
Traceback (most recent call last):
File "PremiereComm.py", line 26, in <module>
print(my_instrument.read())
File "C:\Program Files\Python38\lib\site-packages\pyvisa\resources\messagebased.py", line 486, in read
message = self._read_raw().decode(enco)
File "C:\Program Files\Python38\lib\site-packages\pyvisa\resources\messagebased.py", line 442, in _read_raw
chunk, status = self.visalib.read(self.session, size)
File "C:\Program Files\Python38\lib\site-packages\pyvisa\ctwrapper\functions.py", line 2337, in read
ret = library.viRead(session, buffer, count, byref(return_count))
File "C:\Program Files\Python38\lib\site-packages\pyvisa\ctwrapper\highlevel.py", line 222, in _return_handler
return self.handle_return_value(session, ret_value) # type: ignore
File "C:\Program Files\Python38\lib\site-packages\pyvisa\highlevel.py", line 251, in handle_return_value
raise errors.VisaIOError(rv)
pyvisa.errors.VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.
>>> '''

EFOError when trying to connect Pyftpsync to remote server on port 22

I am trying to sync two folders via FTP, yes I know there are better or different ways but for now I need to implement it this way, I was trying the example code from pyftpsync since well, a sample code should work easily right? I am just trying to connect between some test folders I made, one is empty(local) and the remote has a single text file that I want to fetch. It tries to connect but after about 2 minutes I get this error.
Well, my FTP does work outside of python. I can connect over WinSCP just fine.
Some places mentioned that a proxy could possibly cause this, but it seems I am not behind a proxy currently, but maybe I did not set that properly and it believes there should be a proxy somehow?
Here is my code, just using commands on the prompt for pyftpsync produces the same errors for me. So it is possible some input parameter is off causing all of this.
import time
import os
import re
import shutil
import string
import sys
from ftpsync.targets import FsTarget
from ftpsync.ftp_target import FtpTarget
from ftpsync.synchronizers import DownloadSynchronizer
#synchronize a local folder with ftp
local = FsTarget( "C:\\testfolder\\" )
user = "login"
passwd = "password"
remote = FtpTarget("/my/folder/location/testfold/", "126.0.0.1",port=22, username=user,password=passwd,tls=False,timeout=None,extra_opts=None)
opts = {}
s=DownloadSynchronizer(local, remote, opts)
s.run()
This is the output I am getting, I have edited out the folder names and IP addresses.
INFO:keyring.backend:Loading KWallet
INFO:keyring.backend:Loading SecretService
INFO:keyring.backend:Loading Windows
INFO:keyring.backend:Loading chainer
INFO:keyring.backend:Loading macOS
INFO:pyftpsync:Download to C:\testfolder
from ftp://126.0.0.1/.../testfold
INFO:pyftpsync:Encoding local: utf-8, remote: utf-8
Traceback (most recent call last):
File "c:\..\.py", line 30, in <module>
s.run()
File "C:\\AppData\Local\Programs\Python\Python37-32\lib\site-
packages\ftpsync\synchronizers.py", line 1268, in run
res = super(DownloadSynchronizer, self).run()
File "C:\\AppData\Local\Programs\Python\Python37-
32\lib\site-packages\ftpsync\synchronizers.py", line 827, in run
res = super(BiDirSynchronizer, self).run()
File "C:\\AppData\Local\Programs\Python\Python37-
32\lib\site-packages\ftpsync\synchronizers.py", line 211, in run
self.remote.open()
File "C:\\AppData\Local\Programs\Python\Python37-
32\lib\site-packages\ftpsync\ftp_target.py", line 141, in open
self.ftp.connect(self.host, self.port)
File "C:\\AppData\Local\Programs\Python\Python37-
32\lib\ftplib.py", line 155, in connect
self.welcome = self.getresp()
File "C:\\Local\Programs\Python\Python37-
32\lib\ftplib.py", line 236, in getresp
resp = self.getmultiline()
File "C:\\AppData\Local\Programs\Python\Python37-
32\lib\ftplib.py", line 226, in getmultiline
nextline = self.getline()
File "C:\\AppData\Local\Programs\Python\Python37-
32\lib\ftplib.py", line 210, in getline
raise EOFError
EOFError
Anyways any possible troubleshooting ideas would help. Thank you.
Pyftpsync uses FTP protocol.
You are connecting to port 22, which is used for SSH/SFTP.
So if your server is actually SFTP server, not FTP server, you cannot use Pyftpsync with it.

Paramiko failing due due to file permissions

I have been trying to automate SFTP transfer from a Windows client via a python script to a CentOS machine running an Apache server. I have created a user account on the CentOS server that can only access SFTP, similar to the instructions listed here: https://www.digitalocean.com/community/tutorials/how-to-enable-sftp-without-shell-access-on-centos-7
I then used the following code in an attempt to transfer the file
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put(base_dir + '\\report', '/var/www/html/reports/' + host_name, confirm = False)
However this results in the following error:
Traceback (most recent call last):
File "noschedule_make_report.py", line 74, in <module>
main()
File "noschedule_make_report.py", line 62, in main
sftp.chdir('/var/www/html/reports')
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 626, in chdir
if not stat.S_ISDIR(self.stat(path).st_mode):
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 460, in stat
t, msg = self._request(CMD_STAT, path)
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 780, in _request
return self._read_response(num)
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 832, in _read_response
self._convert_status(msg)
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 861, in _convert_status
raise IOError(errno.ENOENT, text)
IOError: [Errno 2] No such file
This code worked when I didn't set the restrictions on the upload user account as described in the Digital Ocean post, and instead had much more liberal permissions and shell login. Is there a way for me to have both the locked out login for the upload user and to use the Paramiko funcitonality?
Please note that using a sftp.chdir('/var/www/html/reports') command before the put command produced the same error, occurring at the chdir line instead.
Also I understand that similar questions have been asked (IOError: [Errno 2] No such file - Paramiko put()), but I am specifically asking if I can relegate these two sets of functionality.
There is a concept I think you have perhaps overlooked when configuring the sftp part, This is ChrootDirectory.
A Chroot in Unix world is a way to execute a command or an environment inside a system directory, so this directory appears the root of the system you're into. This is primary used as security feature because there is no way to escape this chroot. For instance imagine you have a path /opt/server/ftp/users/ and a ftp daemon is chrooted in /opt/server/ftp/ a client will see the users directory when he will do a ls -al and it will be impossible to access files on the system like /etc/
So this problem has nothing to do with the Paramiko code per-se but with the sftp configuration you set and the comprehension of what is a Chroot environment.
ChrootDirectory in you setup define the sftp user will be dropped into this directory when connection it created AND that he'll be impossible to see the full path of the system when it is logged, so when you upload the files you don't have to chdir /var/www/html/reports because you can't see this directory. Considering you set ChrootDirectory /var/www/html/reports
Check first the ChrootDirectory value you set, if you put /var/sftp/ but you want to access the system path (not the chroot one) /var/www/html/reports/ this is wrong. Correct to /var/www/html/reports/ seems legit, then change your code to
sftp.put(base_dir + '\\report', '.' + host_name, confirm = False)
the character . as second parameter means the current directory

Getting an EOFError when getting large files with Paramiko

I'm trying to write a quick python script to grab some logs with sftp. My first inclination was to use Pysftp, since it seemed like it made it very simple. It worked great, until it got to a larger file. I got an error while getting any file over about 13 MB. I then decided to try writing what I needed directly in Paramiko, rather than relying on the extra layer of Pysftp. After figuring out how to do that, I ended up getting the exact same error. Here's the Paramiko code, as well as the trace from the error I get. Does anyone have any idea why this would have an issue pulling any largish files? Thanks.
# Create tranport and connect
transport = paramiko.Transport((host, 22))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
# List of the log files in c:
files = sftp.listdir('c:/logs')
# Now pull them, logging as you go
for f in files:
if f[0].lower() == 't' or f[:3].lower() == 'std':
logger.info('Pulling {0}'.format(f))
sftp.get('c:/logs/{0}'.format(f), output_dir +'/{0}'.format(f))
# Close the connection
sftp.close()
transport.close()
And here's the error:
No handlers could be found for logger "paramiko.transport"
Traceback (most recent call last):
File "pull_logs.py", line 420, in <module> main()
File "pull_logs.py", line 410, in main
pull_logs(username, host, password, location)
File "pull_logs.py", line 142, in pull_logs
sftp.get('c:/logs/{0}'.format(f), output_dir +'/{0}'.format(f))
File "/Users/me/my_site/site_packages/paramiko/sftp_client.py", line 676, in get
size = self.getfo(remotepath, fl, callback)
File "/Users/me/my_site/site_packages/paramiko/sftp_client.py", line 645, in getfo
data = fr.read(32768)
File "/Users/me/my_site/site_packages/paramiko/file.py", line 153, in read
new_data = self._read(read_size)
File "/Users/me/my_site/site_packages/paramiko/sftp_file.py", line 152, in _read
data = self._read_prefetch(size)
File "/Users/me/my_site/site_packages/paramiko/sftp_file.py", line 132, in _read_prefetch
self.sftp._read_response()
File "/Users/me/my_site/site_packages/paramiko/sftp_client.py", line 721, in _read_response
raise SSHException('Server connection dropped: %s' % (str(e),))
paramiko.SSHException: Server connection dropped:

socket error using boto with Jython

I'm in the process of porting a project originally done in CPython over to Jython in order to leverage some java libraries. Things seem to be working fine except that for some reason I'm getting errors when trying to connect to s3 with boto:
>>> from boto.s3.connection import S3Connection
>>> s3 = S3Connection(aws_access_id, aws_secret_key)
>>> s3.get_all_buckets()
File "<stdin>", line 1, in <module>
File "/usr/share/jython/Lib/site-packages/boto/s3/connection.py", line 384, in
body = response.read()
File "/usr/share/jython/Lib/site-packages/boto/connection.py", line 411, in rea
self._cached_response = httplib.HTTPResponse.read(self)
File "/usr/share/jython/Lib/httplib.py", line 546, in read
s = self.fp.read()
File "/usr/share/jython/Lib/httplib.py", line 1296, in read
return s + self._file.read()
File "/usr/share/jython/Lib/socket.py", line 1672, in read
data = self._sock.recv(recv_size)
File "/usr/share/jython/Lib/socket.py", line 180, in set_last_error
return method(obj, *args, **kwargs)
File "/usr/share/jython/Lib/socket.py", line 171, in map_exception
raise _map_exception(jlx)
socket.error: [Errno 104] Software caused connection abort
Running the exact same connection code in CPython works perfectly.
I've tried forcing boto to log debug messages, but they are the exact same between Jython and CPython until the Jython one fails. Has anyone run into this before or have any suggestions for debugging this further?
Running Jython 2.7b1, CPython 2.7.4 on ubuntu.

Categories

Resources