RSS iMasters 5 Denunciar post Postado Setembro 27, 2010 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 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
RafaelSonyLock 18 Denunciar post Postado Novembro 8, 2010 Tópico Reformulado e adicionado ao Índice de Tópicos ! Compartilhar este post Link para o post Compartilhar em outros sites