python实现FTP服务器服务的方法


Posted in Python onApril 11, 2017

FTP服务的主动模式和被动模式

在开始之前,先聊一下FTP的主动模式和被动模式,两者的区别 , 用两张图来表示可能会更加清晰一些:

主动模式:

python实现FTP服务器服务的方法

主动模式工作过程:

1. 客户端以随机非特权端口N,就是大于1024的端口,对server端21端口发起连接

2. 客户端开始监听 N+1端口;

3. 服务端会主动以20端口连接到客户端的N+1端口。

主动模式的优点:

服务端配置简单,利于服务器安全管理,服务器只需要开放21端口

主动模式的缺点:

如果客户端开启了防火墙,或客户端处于内网(NAT网关之后), 那么服务器对客户端端口发起的连接可能会失败

被动模式:

python实现FTP服务器服务的方法

被动模式工作过程:

1. 客户端以随机非特权端口连接服务端的21端口

2. 服务端开启一个非特权端口为被动端口,并返回给客户端

3. 客户端以非特权端口+1的端口主动连接服务端的被动端口

被动模式缺点:

服务器配置管理稍显复杂,不利于安全,服务器需要开放随机高位端口以便客户端可以连接,因此大多数FTP服务软件都可以手动配置被动端口的范围

被动模式的优点:对客户端网络环境没有要求

了解了FTP之后,开始使用python来实现FTP服务

准备工作

本次使用python版本:python 3.4.3

安装模块 pyftpdlib

pip3 install pyftpdlib

创建代码文件 FtpServer.py

代码

实现简单的本地验证

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()

开启服务

$python FtpServer.py

测试一下:

python实现FTP服务器服务的方法

输入个错误密码试试:

python实现FTP服务器服务的方法

验证不通过,无法登录 。

但这似乎是主动模式的FTP ,如何实现被动模式呢?

通过以下代码添加被动端口:

handler.passive_ports = range(2000,2333)

完整代码:

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

FTP用户管理:

通过上面的实践,FTP服务器已经可以正常工作了,但是如果需要很多个FTP用户呢,怎么办呢? 每个用户都写一遍吗?

其实我们可以定义一个用户文件user.py

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

然后遍历该文件,将不以#开头的行加入到user_list列表中

完整代码:

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('#') 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('user', '12345', '/home/', perm='elradfmw')
user_list = get_user('/home/huangxm/test_py/FtpServer/user.conf')
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('/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()

到这里,FTP 服务已经完成了。

规范一下代码

首先创建conf目录,存放settings.py和user.py

目录结构(cache里面的不用管):

python实现FTP服务器服务的方法

setting.py

ip = '0.0.0.0'

port = '2121'

#上传速度 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 = 'off'
#匿名用户目录
anonymous_path = '/home/huangxm'

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

#欢迎信息
welcome_msg = 'Welcome to my ftp'

user.py

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

FtpServer.py

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('#') 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('user', '12345', '/home/', perm='elradfmw')
  user_list = get_user('conf/user.py')
  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 == 'on':
    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 == 'on':
    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('开始服务')
  server.serve_forever()

if __name__ == "__main__":
  ftp_server()

最后,说一下权限问题

读权限 :

e 改变文件目录
l 列出文件
r 从服务器接收文件

写权限 :

a 文件上传
d 删除文件
f 文件重命名
m 创建文件
w 写权限
M 文件传输模式(通过FTP设置文件权限 )

M 示例:

python实现FTP服务器服务的方法

到服务器上查看一下权限:

python实现FTP服务器服务的方法

可以看到权限已经被修改了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之赋值,简单也不简单
Sep 24 Python
Swift中的协议(protocol)学习教程
Jul 08 Python
Python简单读取json文件功能示例
Nov 30 Python
Python编程pygame模块实现移动的小车示例代码
Jan 03 Python
Python操作Excel插入删除行的方法
Dec 10 Python
Python多线程原理与用法实例剖析
Jan 22 Python
python 实现多线程下载m3u8格式视频并使用fmmpeg合并
Nov 15 Python
Python实现bilibili时间长度查询的示例代码
Jan 14 Python
win10下python3.8的PIL库安装过程
Jun 08 Python
pytorch使用horovod多gpu训练的实现
Sep 09 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
Feb 02 Python
python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
Apr 14 Python
python读写json文件的简单实现
Apr 11 #Python
Python实现Mysql数据库连接池实例详解
Apr 11 #Python
详解Python中类的定义与使用
Apr 11 #Python
python获取指定时间差的时间实例详解
Apr 11 #Python
一个基于flask的web应用诞生 组织结构调整(7)
Apr 11 #Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
Apr 11 #Python
一个基于flask的web应用诞生 用户注册功能开发(5)
Apr 11 #Python
You might like
PHP+javascript模拟Matrix画面
2006/10/09 PHP
PHP采集静态页面并把页面css,img,js保存的方法
2014/12/23 PHP
ThinkPHP实现递归无级分类――代码少
2015/07/29 PHP
PHP实现搜索相似图片
2015/09/22 PHP
PHP实现的简单sha1加密功能示例
2017/08/27 PHP
PHP实现的迪科斯彻(Dijkstra)最短路径算法实例
2017/09/16 PHP
PHP判断当前使用的是什么浏览器(推荐)
2019/10/27 PHP
prototype 学习笔记整理
2009/07/17 Javascript
javascript 检测浏览器类型和版本的代码
2009/09/15 Javascript
不使用ajax实现无刷新提交表单
2014/12/21 Javascript
简单总结JavaScript中的String字符串类型
2016/05/26 Javascript
深入理解javascript作用域第二篇之词法作用域和动态作用域
2016/07/24 Javascript
Google 地图控件集详解及实例代码
2016/08/06 Javascript
使用JavaScript获取Request中参数的值方法
2016/09/27 Javascript
详解Vue组件之间的数据通信实例
2017/06/17 Javascript
JavaScript编程设计模式之观察者模式(Observer Pattern)实例详解
2017/10/25 Javascript
使用next.js开发网址缩短服务的方法
2020/06/17 Javascript
Python中内置的日志模块logging用法详解
2016/07/12 Python
Linux下为不同版本python安装第三方库
2016/08/31 Python
python中实现k-means聚类算法详解
2017/11/11 Python
批量将ppt转换为pdf的Python代码 只要27行!
2018/02/26 Python
Python序列循环移位的3种方法推荐
2018/04/09 Python
对tensorflow 中tile函数的使用详解
2020/02/07 Python
基于python tkinter的点名小程序功能的实例代码
2020/08/22 Python
Django数据统计功能count()的使用
2020/11/30 Python
html5 canvas 画图教程案例分析
2012/11/23 HTML / CSS
Blank NYC官网:夹克、牛仔裤等
2020/12/16 全球购物
简单说下OSPF的操作过程
2014/08/13 面试题
支部鉴定材料
2014/06/02 职场文书
廉政文化进校园广播稿
2014/10/20 职场文书
2014年教师学期工作总结
2014/11/08 职场文书
班主任经验交流材料
2014/12/16 职场文书
仓管员岗位职责范本
2015/04/01 职场文书
工地食品安全责任书
2015/05/09 职场文书
行政处罚事先告知书
2015/07/01 职场文书
2016大学生国家助学贷款承诺书
2016/03/25 职场文书