Maison  >  Article  >  développement back-end  >  Comment implémenter le service de serveur FTP en Python (Collection)

Comment implémenter le service de serveur FTP en Python (Collection)

PHPz
PHPzoriginal
2017-04-12 14:28:502655parcourir

Cet article présente principalement la méthode d'implémentation du serveur FTP en python. L'éditeur pense que c'est plutôt bon. Maintenant, je vais le partager avec vous et le donner comme référence. Suivons l'éditeur pour y jeter un oeil

Mode actif et mode passif du service FTP

Avant de commencer, parlons du mode actif et du mode passif de FTP. La différence entre eux peut être plus clairement représentée par deux images :

Mode actif :

Processus de travail en mode actif :

1. Le client initie une connexion au port 21 du serveur en utilisant un port N aléatoire non privilégié, qui est un port supérieur à 1024

2. 1;

3. Le serveur se connectera activement au port N+1 du client via le port 20.

Avantages du mode actif :

La configuration du serveur est simple, ce qui est propice à la gestion de la sécurité du serveur. Le serveur n'a besoin que d'ouvrir le port 21

Inconvénients du mode actif :

Si le client a un pare-feu activé, ou si le client est sur l'intranet (derrière une passerelle NAT), la connexion initiée par le serveur au port client peut échouer

Mode passif :

Processus de travail en mode passif :

1. Le client se connecte au port 21 du serveur via un. port non privilégié aléatoire

2. Le serveur ouvre un port non privilégié en tant que port passif et le renvoie au client

3 Le client se connecte activement au port passif du serveur avec le port non privilégié. + 1 port

Inconvénients du mode passif :

La gestion de la configuration du serveur est légèrement compliquée, ce qui n'est pas propice à la sécurité. Le serveur doit ouvrir des ports aléatoires à haut débit pour que les clients puissent se connecter, donc. la plupart des logiciels de service FTP peuvent configurer manuellement la plage de ports passifs

Avantages passifs du mode : il n'y a aucune exigence pour l'environnement réseau client

Après avoir compris FTP, commencez à utiliser Python pour implémenter les services FTP

Travail de préparation

Cette version python utilisée : python 3.4.3

Installer le module pyftpdlib


Créer le fichier de code FtpServer.py
pip3 install pyftpdlib

Code

Implémenter une vérification locale simple


from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

#实例化虚拟用户,这是FTP验证首要条件
authorizer = DummyAuthorizer()

#添加用户权限和路径,括号内的参数是(用户名, 密码, 用户目录, 权限)
authorizer.add_user('user', '12345', '/home/', perm='elradfmw')

#添加匿名用户 只需要路径
authorizer.add_anonymous('/home/huangxm')

#初始化ftp句柄
handler = FTPHandler
handler.authorizer = authorizer

#监听ip 和 端口,因为linux里非root用户无法使用21端口,所以我使用了2121端口
server = FTPServer(('192.168.0.108', 2121), handler)

#开始服务
server.serve_forever()
Activer le service

$python FtpServer.py

Testez-le :

Entrez un mot de passe erroné et essayez :

Échec de la vérification et impossible de se connecter.

Mais cela semble être un mode FTP actif. Comment implémenter le mode passif ?

Ajoutez des ports passifs via le code suivant :

handler.passive_ports = range(2000, 2333)

Code complet :


Activez le service et vous pourrez voir les informations du port passif :
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

#实例化虚拟用户,这是FTP验证首要条件
authorizer = DummyAuthorizer()

#添加用户权限和路径,括号内的参数是(用户名, 密码, 用户目录, 权限)
authorizer.add_user('user', '12345', '/home/', perm='elradfmw')

#添加匿名用户 只需要路径
authorizer.add_anonymous('/home/huangxm')

#初始化ftp句柄
handler = FTPHandler
handler.authorizer = authorizer

#添加被动端口范围
handler.passive_ports = range(2000, 2333)

#监听ip 和 端口
server = FTPServer(('192.168.0.108', 2121), handler)

#开始服务
server.serve_forever()


$ python FtpServer.py 
[I 2017-01-11 15:18:37] >>> starting FTP server on 192.168.0.108:2121, pid=46296 <<<
[I 2017-01-11 15:18:37] concurrency model: async
[I 2017-01-11 15:18:37] masquerade (NAT) address: None
[I 2017-01-11 15:18:37] passive ports: 2000->2332
Gestion des utilisateurs FTP :

Grâce à la pratique ci-dessus, le serveur FTP peut déjà fonctionner normalement, mais que se passe-t-il si de nombreux utilisateurs FTP sont nécessaires ? Chaque utilisateur doit-il l'écrire une fois ?

En fait, on peut définir un fichier utilisateur user.py


puis parcourir le fichier et ajouter des lignes qui ne commencent pas par # au user_list Medium
#用户名   密码    权限     目录
# root   12345   elradfmwM  /home
huangxm   12345   elradfmwM  /home

Code complet :


À ce stade, le service FTP est terminé.
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer


def get_user(userfile):
  #定义一个用户列表
  user_list = []
  with open(userfile) as f:
    for line in f:
      print(len(line.split()))
      if not line.startswith(&#39;#&#39;) and line:
        if len(line.split()) == 4: 
          user_list.append(line.split())
        else:
          print("user.conf配置错误")
  return user_list

#实例化虚拟用户,这是FTP验证首要条件
authorizer = DummyAuthorizer()

#添加用户权限和路径,括号内的参数是(用户名, 密码, 用户目录, 权限)
#authorizer.add_user(&#39;user&#39;, &#39;12345&#39;, &#39;/home/&#39;, perm=&#39;elradfmw&#39;)
user_list = get_user(&#39;/home/huangxm/test_py/FtpServer/user.conf&#39;)
for user in user_list:
  name, passwd, permit, homedir = user
  try:
    authorizer.add_user(name, passwd, homedir, perm=permit)
  except Exception as e:
    print(e)

#添加匿名用户 只需要路径
authorizer.add_anonymous(&#39;/home/huangxm&#39;)

#初始化ftp句柄
handler = FTPHandler
handler.authorizer = authorizer

#添加被动端口范围
handler.passive_ports = range(2000, 2333)

#监听ip 和 端口
server = FTPServer((&#39;192.168.0.108&#39;, 2121), handler)

#开始服务
server.serve_forever()

Standardisez le code

Créez d'abord le répertoire conf pour stocker settings.py et user.py

Structure du répertoire (ne vous inquiétez pas du ceux dans le cache) :

setting.py


user.py
ip = &#39;0.0.0.0&#39;

port = &#39;2121&#39;

#上传速度 300kb/s
max_upload = 300 * 1024

#下载速度 300kb/s
max_download = 300 * 1024

#最大连接数
max_cons = 150

#最多IP数
max_per_ip = 10

#被动端口范围,注意被动端口数量要比最大IP数多,否则可能出现无法连接的情况
passive_ports = (2000, 2200)

#是否开启匿名访问 on|off
enable_anonymous = &#39;off&#39;
#匿名用户目录
anonymous_path = &#39;/home/huangxm&#39;

#是否开启日志 on|off
enable_logging = &#39;off&#39;
#日志文件
loging_name = &#39;pyftp.log&#39;

#欢迎信息
welcome_msg = &#39;Welcome to my ftp&#39;


FtpServer.py
#用户名   密码    权限     目录
#root   12345   elradfmwM  /home/
huangxm   12345   elradfmwM  /home/
test    12345   elradfmwM  /home/huangxm


Enfin, parlons du problème d'autorisation
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler, ThrottledDTPHandler
from pyftpdlib.servers import FTPServer
from conf import settings
import logging


def get_user(userfile):
  #定义一个用户列表
  user_list = []
  with open(userfile) as f:
    for line in f:
      if not line.startswith(&#39;#&#39;) and line:
        if len(line.split()) == 4: 
          user_list.append(line.split())
        else:
          print("user.conf配置错误")
  return user_list

def ftp_server():
  #实例化虚拟用户,这是FTP验证首要条件
  authorizer = DummyAuthorizer()
  
  #添加用户权限和路径,括号内的参数是(用户名, 密码, 用户目录, 权限)
  #authorizer.add_user(&#39;user&#39;, &#39;12345&#39;, &#39;/home/&#39;, perm=&#39;elradfmw&#39;)
  user_list = get_user(&#39;conf/user.py&#39;)
  for user in user_list:
    name, passwd, permit, homedir = user
    try:
      authorizer.add_user(name, passwd, homedir, perm=permit)
    except Exception as e:
      print(e)

  #添加匿名用户 只需要路径
  if settings.enable_anonymous == &#39;on&#39;:
    authorizer.add_anonymous(settings.anonymous_path)
  
  #下载上传速度设置
  dtp_handler = ThrottledDTPHandler
  dtp_handler.read_limit = settings.max_download
  dtp_handler.write_limit = settings.max_upload

  #初始化ftp句柄
  handler = FTPHandler
  handler.authorizer = authorizer

  #日志记录
  if settings.enable_logging == &#39;on&#39;:
    logging.basicConfig(filename=settings.loging_name, level=logging.INFO)

  #欢迎信息
  handler.banner = settings.welcome_msg
  

  #添加被动端口范围
  handler.passive_ports = range(settings.passive_ports[0], settings.passive_ports[1])

  #监听ip 和 端口
  server = FTPServer((settings.ip, settings.port), handler)
  
  #最大连接数
  server.max_cons = settings.max_cons
  server.max_cons_per_ip = settings.max_per_ip
  
  #开始服务
  print(&#39;开始服务&#39;)
  server.serve_forever()

if __name__ == "__main__":
  ftp_server()

Autorisation de lecture :

Autorisation d'écriture :
e 改变文件目录
l 列出文件
r 从服务器接收文件

M Exemple :

Allez sur le serveur et vérifiez les autorisations :

Vous pouvez voir que le les autorisations ont été modifiées.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn