Instalação do Módulo Paramiko
O módulo Paramiko fornece funcionalidade para conexão a servidores Linux, permitindo autenticação via usuário/senha ou por meio de chaves pública e privada. Após a autenticação, é possível executar comandos remotamente via código Python, com encapsulamento de operações comuns.
Como é um módulo de terceiros, deve ser instalado via pip:
pip3 install paramiko --index-url https://pypi.tuna.tsinghua.edu.cn/simple/
Conexão Básica com Usuário e Senha
Exemplo de uso com credenciais em texto plano, que pode ser inseguro se o código for exposto:
import paramiko
# Inicializar cliente SSH
cliente_ssh = paramiko.SSHClient()
# Permitir hosts não registrados no known_hosts
cliente_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Estabelecer conexão com o servidor
cliente_ssh.connect(hostname='192.168.1.10', port=22, username='admin', password='minha_senha')
# Executar comando remoto
entrada, saida, erro = cliente_ssh.exec_command('uptime')
# Obter resultado do comando
resultado = saida.read().decode('utf-8')
print(resultado)
# Encerrar conexão
cliente_ssh.close()
Esta abordagem utiliza uma estrutura similar a pipes, comparable ao módulo subprocess do Python.
Autenticação com Chaves Pública e Privada
Para evitar armazenar senhas no código, pode-se utilizar autenticação por chaves assimétricas, que é mais segura tanto para conexões SSH quanto para transferência de arquivos. O processo envolve gerar um par de chaves localmente e copiar a chave pública para o servidor.
Gerando Chaves em Ambiente Windows
No Windows, após instalar o Git, pode-se usar o Git Bash para gerar chaves com o comando:
ssh-keygen -t rsa
É rceomendado definir uma passphrase para proteger a chave privada. Em seguida, copiar a chave pública para o servidor:
ssh-copy-id -i /caminho/para/chave.pub usuario@ip_do_servidor
Após inserir a senha uma vez, conexões futuras usarão a chave privada automaticamente.
Conexão via Paramiko com Chaves
Para usar chaves no Paramiko, carregue a chave privada e conecte-se sem senha:
import paramiko
# Carregar chave privada de arquivo (supondo que não tenha passphrase)
chave_privada = paramiko.RSAKey.from_private_key_file(r'/home/usuario/.ssh/id_rsa')
# Configurar cliente SSH
conexao_ssh = paramiko.SSHClient()
conexao_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Conectar usando chave privada
conexao_ssh.connect(hostname='servidor.exemplo.com', port=22, username='admin', pkey=chave_privada)
# Executar comando
_, saida, _ = conexao_ssh.exec_command('df -h')
resultado_saida = saida.read().decode('utf-8')
print(resultado_saida)
conexao_ssh.close()
Transferência de Arquivos via SFTP
Paramiko também suporta SFTP para upload e download de arquivos:
import paramiko
transporte = paramiko.Transport(('ip_do_servidor', 22))
transporte.connect(username='admin', password='minha_senha')
# Iniciar cliente SFTP
sftp = paramiko.SFTPClient.from_transport(transporte)
# Upload de arquivo local para servidor
sftp.put('/caminho/local/arquivo.txt', '/caminho/remoto/arquivo.txt')
# Download de arquivo remoto para local
sftp.get('/caminho/remoto/dados.log', '/caminho/local/dados.log')
sftp.close()
transporte.close()
Encapsualmento de Funcionalidades em Classe
Para reutilização, pode-se criar uma classe que gerencia conexões SSH e operações SFTP, suportando context manager:
import paramiko
class GerenciadorSSH:
def __init__(self, servidor, porta, usuario, chave_path=None, senha=None):
self.servidor = servidor
self.porta = porta
self.usuario = usuario
self.chave_path = chave_path
self.senha = senha
self.transporte = None
def abrir_conexao(self):
self.transporte = paramiko.Transport((self.servidor, self.porta))
if self.chave_path:
chave = paramiko.RSAKey.from_private_key_file(self.chave_path)
self.transporte.connect(username=self.usuario, pkey=chave)
else:
self.transporte.connect(username=self.usuario, password=self.senha)
def executar_comando(self, comando):
cliente = paramiko.SSHClient()
cliente._transport = self.transporte
_, saida, _ = cliente.exec_command(comando)
return saida.read().decode('utf-8')
def enviar_arquivo(self, origem, destino):
sftp = paramiko.SFTPClient.from_transport(self.transporte)
sftp.put(origem, destino)
sftp.close()
def receber_arquivo(self, origem, destino):
sftp = paramiko.SFTPClient.from_transport(self.transporte)
sftp.get(origem, destino)
sftp.close()
def fechar_conexao(self):
if self.transporte:
self.transporte.close()
def __enter__(self):
self.abrir_conexao()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.fechar_conexao()
# Exemplo de uso com context manager
with GerenciadorSSH('ip_do_servidor', 22, 'admin', chave_path='/home/usuario/.ssh/id_rsa') as gerenciador:
print(gerenciador.executar_comando('ls -la'))
gerenciador.enviar_arquivo('/local/dados.csv', '/remoto/dados.csv')