Dh Key Too Small (Python FTP) on Whonix

ghz 15hours ago ⋅ 9 views

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.

  1. Open the file with a text editor:

    sudo nano /etc/ssl/openssl.cnf
    
  2. Locate the section starting with [system_default_sect] or [default_policy]. Add or modify the CipherString line to:

    CipherString = DEFAULT:@SECLEVEL=1
    
  3. 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.