Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

RSS iMasters

Criando um servidor FTP com Python

Recommended Posts

Semana passada, escrevi um artigo sobre como criar um Daemon HTTP via Python. Hoje, vamos ver como criar um servidor de FTP.

 

Onde podemos usar e por que fazer um servidor de FTP?

Nos dias de hoje, no mundo Linux, temos alguns servidores de FTP muito bons (vsftpd, proftpd e outros), mas quando vamos para o ambiente Microsoft Windows não conheço muitos servidores leves. Por esse motivo, acho muito interessante termos alguma solução para esse ambiente usando Python.

 

Vou explicar como fazer o daemon, depois vai da criatividade de cada um de como aplicar no dia a dia.

 

Tenho um cluster de servidores onde rodo sistemas de cliente - a parte de FTP rodava com vsFTPd, hoje está rodando com um daemon em Python, o mesmo que vamos fazer aqui no artigo, só que trabalho com uma base de usuário no MongoDB (usuário, senha e pasta).

 

Por que eu migrei de vsFTPd para um daemon em Python?

1. A base de dados onde estão as informações dos meus clientes é MongoDB, onde estou centralizando todas as informações.

2. Consigo fazer meu daemon interagir com outros aplicativos Python que rodam no meu servidor

 

Para escrever este artigo, vamos usar a biblioteca pyftpdlib, que é mantida pelo Giampaolo Rodola. É uma biblioteca muito robusta e fácil de utilizar, onde podemos escrever poderosos servidores FTP.

Instalando o pyftpflib

 

Imagem Postada

cd /usr/src/

svn checkout http://pyftpdlib.googlecode.com/svn/trunk/ pyftpdlib-read-only

cd pyftpdlib-read-only

python setup.py build

python setup.py install

Agora que já está tudo instalado, vamos começar a escrever o código de nosso servidor:

from pyftpdlib import ftpserver

 

authorizer = ftpserver.DummyAuthorizer()

authorizer.add_user("avelino.us", "mudar123", "/home/avelino.us", perm="elradfmw")

authorizer.add_anonymous("/home/nobody")

handler = ftpserver.FTPHandler

handler.authorizer = authorizer

address = ("127.0.0.1", 21)

ftpd = ftpserver.FTPServer(address, handler)

ftpd.serve_forever()

O pyftpdlib tem uma biblioteca chamada ftpserver que usamos para declarar o servidor. Vamos passar dois parâmetros: o primeiro é o endereço de onde ele vai abrir a conexão/porta; o segundo é o servidor Handler.

 

A última linha é "ftpd.serve_forever()", que mantém o servidor rodando.

 

Explicando como funciona a parte de user

Temos como adicionar usuários normais ou anônimos.

authorizer.add_user("avelino.us", "mudar123", "/home/avelino.us", perm="elradfmw")

A linha na parte superior adiciona um usuário normal, com nome "avelino.us", senha "mudar123", com acesso à pasta "/home/avelino.us".

 

authorizer.add_anonymous("/home/nobody")

No usuário anônimo, basta colocar na pasta a qual ele vai ter acesso "/home/nobody".

 

A parte de log funciona exatamente igual ao de qualquer FTP, vou colocar abaixo um log dessa aplicação rodando local:

Serving FTP on 127.0.0.1:21

[]127.0.0.1:56026 Connected.

127.0.0.1:56026 ==> 220 pyftpdlib 0.6.0 ready.

127.0.0.1:56026 <== USER avelino.us

127.0.0.1:56026 ==> 331 Username ok, send password.

127.0.0.1:56026 <== PASS ******

127.0.0.1:56026 ==> 530 Authentication failed.

[]@127.0.0.1:56026 Authentication failed.

[]@127.0.0.1:56026 Disconnected.

[]127.0.0.1:56562 Connected.

127.0.0.1:56562 ==> 220 pyftpdlib 0.6.0 ready.

127.0.0.1:56562 <== USER avelino.us

127.0.0.1:56562 ==> 331 Username ok, send password.

127.0.0.1:56562 <== PASS ******

127.0.0.1:56562 ==> 530 Authentication failed.

[]@127.0.0.1:56562 Authentication failed.

[]@127.0.0.1:56562 Disconnected.

[]127.0.0.1:56567 Connected.

127.0.0.1:56567 ==> 220 pyftpdlib 0.6.0 ready.

127.0.0.1:56567 <== USER avelino.us

127.0.0.1:56567 ==> 331 Username ok, send password.

127.0.0.1:56567 <== PASS ******

127.0.0.1:56567 ==> 230 Login successful.

[avelino.us]@127.0.0.1:56567 User avelino.us logged in.

127.0.0.1:56567 <== SYST

127.0.0.1:56567 ==> 215 UNIX Type: L8

127.0.0.1:56567 <== FEAT

127.0.0.1:56567 ==> 211 End FEAT.

127.0.0.1:56567 <== OPTS MLST type;perm;size;modify;unix.mode;unix.uid;unix.gid;

127.0.0.1:56567 ==> 200 MLST OPTS type;perm;size;modify;unix.mode;unix.uid;unix.gid;

127.0.0.1:56567 <== PWD

127.0.0.1:56567 ==> 257 "/" is the current directory.

127.0.0.1:56567 <== TYPE I

127.0.0.1:56567 ==> 200 Type set to: Binary.

127.0.0.1:56567 <== PASV

127.0.0.1:56567 ==> 227 Entering passive mode (127,0,0,1,220,248).

127.0.0.1:56567 <== MLSD

[avelino.us]@127.0.0.1:56567 OK MLSD "/". Transfer starting.

127.0.0.1:56567 ==> 150 File status okay. About to open data connection.

127.0.0.1:56567 ==> 226 Transfer complete.

127.0.0.1:56567 <== MKD test

[avelino.us]@127.0.0.1:56567 OK MKD "/test".

127.0.0.1:56567 ==> 257 "/test" directory created.

127.0.0.1:56567 <== CWD test

[avelino.us]@127.0.0.1:56567 OK CWD "/test".

127.0.0.1:56567 ==> 250 "/test" is the current directory.

127.0.0.1:56567 <== PWD

127.0.0.1:56567 ==> 257 "/test" is the current directory.

127.0.0.1:56567 <== PASV

127.0.0.1:56567 ==> 227 Entering passive mode (127,0,0,1,220,253).

127.0.0.1:56567 <== MLSD

[avelino.us]@127.0.0.1:56567 OK MLSD "/test". Transfer starting.

127.0.0.1:56567 ==> 150 File status okay. About to open data connection.

127.0.0.1:56567 ==> 226 Transfer complete.

[]127.0.0.1:56575 Connected.

127.0.0.1:56575 ==> 220 pyftpdlib 0.6.0 ready.

127.0.0.1:56575 <== USER avelino.us

127.0.0.1:56575 ==> 331 Username ok, send password.

127.0.0.1:56575 <== PASS ******

127.0.0.1:56575 ==> 230 Login successful.

[avelino.us]@127.0.0.1:56575 User avelino.us logged in.

127.0.0.1:56575 <== OPTS MLST type;perm;size;modify;unix.mode;unix.uid;unix.gid;

127.0.0.1:56575 ==> 200 MLST OPTS type;perm;size;modify;unix.mode;unix.uid;unix.gid;

127.0.0.1:56575 <== CWD /test

[avelino.us]@127.0.0.1:56575 OK CWD "/test".

127.0.0.1:56575 ==> 250 "/test" is the current directory.

127.0.0.1:56575 <== PWD

127.0.0.1:56575 ==> 257 "/test" is the current directory.

127.0.0.1:56575 <== TYPE A

127.0.0.1:56575 ==> 200 Type set to: ASCII.

127.0.0.1:56575 <== PASV

127.0.0.1:56575 ==> 227 Entering passive mode (127,0,0,1,221,0).

127.0.0.1:56575 <== STOR test.py

[avelino.us]@127.0.0.1:56575 OK STOR "/test/test.py". Upload starting.

127.0.0.1:56575 ==> 150 File status okay. About to open data connection.

127.0.0.1:56575 ==> 226 Transfer complete.

[avelino.us]@127.0.0.1:56575 /home/avelino.us/test/test.py received in 0.001 seconds.

127.0.0.1:56575 <== TYPE I

127.0.0.1:56575 ==> 200 Type set to: Binary.

127.0.0.1:56575 <== PASV

127.0.0.1:56575 ==> 227 Entering passive mode (127,0,0,1,221,2).

127.0.0.1:56575 <== MLSD

[avelino.us]@127.0.0.1:56575 OK MLSD "/test". Transfer starting.

127.0.0.1:56575 ==> 150 File status okay. About to open data connection.

127.0.0.1:56575 ==> 226 Transfer complete.

Se você ler o log, vai reparar que tentei logar duas vez com a senha errada, depois fiz a autenticação com a correta, criei uma pasta e mandei um arquivo test.py para o FTP.

 

Agora vai da criatividade do programador para colocar mais funcionalidade para o serviço. Boa sorte!

 

Fonte: http://imasters.com.br/artigo/18298/programacao/criando_um_servidor_ftp_com_python/

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.