I am trying to upload files to a server from within the Whonix operating system. I was able to do it successfully using Filezilla from within Whonix, so I'm not really sure why the Python code isn't working.
from ftplib import FTP, FTP_TLS
import os
ftp = FTP_TLS()
ftp.set_debuglevel(2)
ftp.connect('ftp.server.com', 21)
ftp.login('Username', 'Password')
item_name = 'myfile.mp4'
item_path = os.path.abspath(item_name)
fp = open(item_path, 'rb')
ftp.storbinary('STOR {}'.format(item_name), fp, 8192)
fp.close()
Does anybody know how I should change the Python code to be able to upload the file succesfully from within Whonix? For reference, the Python code works when I run it directly from within Windows. It only fails when I try it from within Whonix, and I don't know why.
This is the error I get, and I don't understand it:
*get* '220-This is a private system - No anonymous login\n'
*get* '220-IPv6 connections are also welcome on this server.\n'
*get* '220 You will be disconnected after 30 minutes of inactivity.\n'
*resp* '220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------\n220-You are user number 17 of 50 allowed.\n220-Local time is now 01:28. Server port: 21.\n220-This is a private system - No anonymous login\n220-IPv6 connections are also welcome on this server.\n220 You will be disconnected after 30 minutes of inactivity.'
*cmd* 'AUTH TLS'
*put* 'AUTH TLS\r\n'
*get* '234 AUTH TLS OK.\n'
*resp* '234 AUTH TLS OK.'
Traceback (most recent call last):
File "test.py", line 8, in <module>
ftp.login('Username', 'Password')
File "/usr/lib/python3.7/ftplib.py", line 749, in login
self.auth()
File "/usr/lib/python3.7/ftplib.py", line 761, in auth
server_hostname=self.host)
File "/usr/lib/python3.7/ssl.py", line 412, in wrap_socket
session=session
File "/usr/lib/python3.7/ssl.py", line 853, in _create
self.do_handshake()
File "/usr/lib/python3.7/ssl.py", line 1117, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1056)
Answer
The error ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small
occurs because the Diffie-Hellman (DH) key size used by the FTP server is smaller than the minimum allowed by the version of OpenSSL in your Python installation. Whonix might have stricter security settings compared to your Windows environment, which is why the issue appears only in Whonix.
Here’s how to resolve the issue:
1. Adjust OpenSSL Security Level
The issue is related to OpenSSL’s default security level. You can lower the security level to allow smaller DH key sizes:
Update OpenSSL Configuration
Edit the OpenSSL configuration file. On most Linux systems, this file is located at /etc/ssl/openssl.cnf
.
-
Open the file with a text editor:
sudo nano /etc/ssl/openssl.cnf
-
Locate the section starting with
[system_default_sect]
or[default_policy]
. Add or modify theCipherString
line to:CipherString = DEFAULT:@SECLEVEL=1
-
Save the file and exit.
Note:
Lowering the security level reduces protection against certain vulnerabilities. Use this change only if necessary and only for trusted servers.
2. Configure SSL Context in Python
Instead of modifying the system-wide OpenSSL configuration, you can change the SSL context in your Python script to allow weaker DH keys:
from ftplib import FTP_TLS
import ssl
import os
ftp = FTP_TLS()
ftp.set_debuglevel(2)
# Create a custom SSL context with a lower security level
context = ssl.create_default_context()
context.set_ciphers("DEFAULT:@SECLEVEL=1")
# Connect using the custom SSL context
ftp.connect('ftp.server.com', 21)
ftp.auth() # Switch to secure TLS
ftp.prot_p() # Protect the data channel
ftp.ssl_version = context # Apply the custom context
ftp.login('Username', 'Password')
item_name = 'myfile.mp4'
item_path = os.path.abspath(item_name)
with open(item_path, 'rb') as fp:
ftp.storbinary(f'STOR {item_name}', fp)
ftp.quit()
3. Verify the DH Key Size
If you have access to the FTP server or its administrator, you could ask them to increase the DH key size to at least 2048 bits. This is the best long-term solution for ensuring compatibility with modern SSL/TLS clients.
4. Alternative Workaround: Use a Different FTP Client
If the problem persists and you can't modify the OpenSSL configuration or the server, you could use Filezilla
or another FTP client for uploads within Whonix as a temporary solution.
Testing
After applying the changes, test the script again to confirm it works correctly. If you continue to face issues, ensure that the FTP server's TLS configuration is compatible with modern SSL/TLS clients.