Paramiko is a popular Python library used for SSH connectivity. It allows for secure connections to remote servers, making it useful to system administrators, developers, and data engineers.
Let’s dive into setting up a virtual environment (venv) on both Windows and Linux, followed by real-world examples of using Paramiko.
1. Setting Up a Virtual Environment
Using a virtual environment isolates dependencies, ensuring that different projects don’t interfere with each other. Here’s how to set up a venv on Windows and Linux.
Windows
Open a command prompt.
Navigate to your project directory:
cd C:\path\to\your\project
Create the virtual environment:
python -m venv venv
Activate the environment:
venv\Scripts\activate
Linux
Open a terminal.
Navigate to your project directory:
cd /path/to/your/project
Create the virtual environment:
python3 -m venv venv
Activate the environment:
source venv/bin/activate
After activating the environment, install Paramiko with:
pip install paramiko
2. Basic SSH Connection and Command Execution
The most common use of Paramiko is establishing an SSH connection to execute commands remotely.
Example 1: Connecting to a Remote Server and Running Commands
File: remote_command.py
In this example, we’ll connect to a remote server and execute a simple command.
import paramiko
# Server details
hostname = 'your-server-ip'
username = 'your-username'
password = 'your-password'
# Establishing the SSH connection
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname, username=username, password=password)
# Executing a command
stdin, stdout, stderr = client.exec_command('ls -l /home/your-username')
# Print the command output
print("Output:")
print(stdout.read().decode())
print("Errors:")
print(stderr.read().decode())
finally:
client.close()
In this script, replace hostname
, username
, and password
with your server details. After running this script, you should see a list of files in the specified directory on the remote server.
NOTE: The paramiko.AutoAddPolicy
is a policy in Paramiko that automatically accepts the server’s SSH key when the client connects to a server for the first time. Normally, SSH clients check the server’s SSH key to ensure they are connecting to the correct server and to prevent “man-in-the-middle” attacks. However, for this check to work, the client must have a record of the server’s key from previous connections.
Here’s what AutoAddPolicy
does:
- Automatically Accepts Unknown Host Keys: If the server’s key is not known to the client (i.e., it is not in the known hosts),
AutoAddPolicy
tells Paramiko to accept the key without prompting, adding it to the session’s list of known hosts for this session. - Simplifies Development and Testing: Using
AutoAddPolicy
can be helpful in development or when you are working in a trusted network, where security concerns are minimal.
If you don’t use paramiko.AutoAddPolicy()
, Paramiko will use its default host key policy, which is RejectPolicy
. This default policy will reject connections to any server whose SSH key is not already known to the client. Here’s what will happen in detail:
- Connection Refusal for Unknown Hosts: When you try to connect to a server for the first time, Paramiko will check its list of known hosts (typically stored in a file or maintained in memory for that session). If the server’s SSH key isn’t already present in this list, the connection will be rejected with an error.
- Manual Key Management: Without
AutoAddPolicy
, you’ll need to manually manage the server’s SSH key to allow a connection. You can add the server’s SSH key to Paramiko’s host key database programmatically using code, or you can store it in a known hosts file, which Paramiko will check. - Increased Security: By avoiding
AutoAddPolicy
, you force Paramiko to only connect to trusted servers, which can help prevent “man-in-the-middle” attacks. It ensures you don’t connect to a server you haven’t verified. - Alternative: Manual Key Verification: If you want to connect to a new server without
AutoAddPolicy
, you can explicitly load the server’s key manually into Paramiko before connecting. Here’s how you might do that:
import paramiko
client = paramiko.SSHClient()
# Load the host keys from a known hosts file or add them programmatically
client.load_host_keys('/path/to/known_hosts') # Load from a file
# Attempt to connect
client.connect(hostname='your-server-ip', username='your-username', password='your-password')
3. Transferring Files with SFTP
Paramiko includes SFTP support, which is handy for transferring files between your local machine and a remote server.
Example 2: Uploading and Downloading Files
File: file_transfer.py
The following script connects to the server and uploads or downloads files using SFTP.
import paramiko
hostname = 'your-server-ip'
username = 'your-username'
password = 'your-password'
local_file_path = 'C:/path/to/local/file.txt'
remote_file_path = '/home/your-username/remote_file.txt'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname, username=username, password=password)
sftp = client.open_sftp()
# Uploading a file
sftp.put(local_file_path, remote_file_path)
print(f"File uploaded to {remote_file_path}")
# Downloading a file
sftp.get(remote_file_path, 'C:/path/to/local/downloaded_file.txt')
print("File downloaded successfully.")
finally:
sftp.close()
client.close()
Change local_file_path
and remote_file_path
to the appropriate paths for your environment. This script uploads a local file to the server and then downloads it back to the local machine.
4. Using SSH Keys for Secure Access
For added security, SSH keys can be used instead of a password.
Example 3: SSH Key Authentication
File: ssh_key_auth.py
To use SSH keys, ensure your public key (id_rsa.pub
) is added to the server’s ~/.ssh/authorized_keys
file.
import paramiko
hostname = 'your-server-ip'
username = 'your-username'
private_key_path = 'C:/path/to/your/private_key.pem'
key = paramiko.RSAKey.from_private_key_file(private_key_path)
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname, username=username, pkey=key)
# Run a command
stdin, stdout, stderr = client.exec_command('df -h')
print(stdout.read().decode())
finally:
client.close()
Replace hostname
, username
, and private_key_path
with your server details. This script connects to the server using an SSH key and runs a command to check disk space.
5. Automating Server Scripts
Paramiko is perfect for automating server management tasks. Here’s a practical example that checks for memory usage and restarts a service if usage is too high.
Example 4: Monitoring Memory and Restarting a Service
File: monitor_memory.py
import paramiko
hostname = 'your-server-ip'
username = 'your-username'
password = 'your-password'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname, username=username, password=password)
# Check memory usage
stdin, stdout, stderr = client.exec_command("free -m | grep Mem | awk '{print $3/$2 * 100.0}'")
memory_usage = float(stdout.read().decode().strip())
print(f"Memory usage: {memory_usage}%")
if memory_usage > 80.0:
# Restart the service
client.exec_command('sudo systemctl restart your-service')
print("Service restarted due to high memory usage.")
finally:
client.close()
In this example, your-service
could be any service running on the remote server, like apache2
or nginx
. Replace hostname
, username
, and password
as needed. The script checks memory usage and restarts the service if it exceeds 80%.
6. Advanced File Management
Sometimes you need to manipulate files directly on the server, like moving or deleting them after processing.
Example 5: Deleting Files After Processing
File: file_cleanup.py
import paramiko
hostname = 'your-server-ip'
username = 'your-username'
password = 'your-password'
directory = '/home/your-username/processed_files/'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname, username=username, password=password)
# Delete files in the directory
client.exec_command(f'rm -f {directory}*')
print(f"All files in {directory} have been deleted.")
finally:
client.close()
This script deletes all files in a specified directory on the remote server.
Thank you for reading this article. We hope you found it helpful and informative. If you have any questions, or if you would like to suggest new Python code examples or topics for future tutorials/articles, please feel free to join and comment. Your feedback and suggestions are always welcome!
You can find the same tutorial on Medium.com.