pyftpdlib代码实战

本文介绍了如何使用pyftpdlib库创建一个FTP服务器,并着重讲解了如何添加日志管理、启用MD5加密用户密码、实现多线程/多进程支持、带宽限制以及SSL认证。此外,还探讨了自定义事件回调处理,增强了服务器的安全性和可控性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新建一个基本的ftp服务器

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

def main():
    authorizer = DummyAuthorizer()
    authorizer.add_user('user', '12345', '.', perm='elradfmwM')

    authorizer.add_anonymous(os.getcwd())              #此处添加一个匿名用户

    handler = FTPHandler                               #初始化处理客户端命令的类
    handler.authorizer = authorizer

    handler.banner = "pyftpdlib based ftpd ready."     #客户端连接时返回的字符串

    #handler.masquerade_address = '151.25.42.11'       #如果你在NAT之后,就用这个指定被动连接的参数
    #handler.passive_ports = range(60000, 65535)

    address = ('0.0.0.0', 2121)                        #设置服务器的监听地址和端口
    server = FTPServer(address, handler)


    server.max_cons = 256                              #给链接设置限制
    server.max_cons_per_ip = 5

    server.serve_forever()                             # 启动服务器

if __name__ == '__main__':
    main()

添加一个日志管理功能

level可以等于logging.INFO或者 logging.DEBUG,后者记录的更加详细
启用logging后,屏幕上不显示了,全都重定向到了自己设置的.log文件中

import logging

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

authorizer = DummyAuthorizer()
authorizer.add_user('user', '12345', '.', perm='elradfmwM')
handler = FTPHandler
handler.authorizer = authorizer

logging.basicConfig(filename='/var/log/pyftpd.log', level=logging.INFO)

server = FTPServer(('', 2121), handler)
server.serve_forever()

md5加密用户名密码,一定程度上防止攻击

import os
import sys
from hashlib import md5

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

#继承类以后添加加密功能
class DummyMD5Authorizer(DummyAuthorizer):

    def validate_authentication(self, username, password, handler):
        if sys.version_info >= (3, 0):
            password = md5(password.encode('latin1'))
        hash = md5(password).hexdigest()
        try:
            if self.user_table[username]['pwd'] != hash:
                raise KeyError
        except KeyError:
            raise AuthenticationFailed


def main():
    # get a hash digest from a clear-text password
    hash = md5('12345').hexdigest()
    authorizer = DummyMD5Authorizer()
    authorizer.add_user('user', hash, os.getcwd(), perm='elradfmw')
    authorizer.add_anonymous(os.getcwd())
    handler = FTPHandler
    handler.authorizer = authorizer
    server = FTPServer(('', 2121), handler)
    server.serve_forever()

if __name__ == "__main__":
    main()

多线程和多进程

from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import ThreadedFTPServer  # <-
from pyftpdlib.authorizers import DummyAuthorizer


def main():
    authorizer = DummyAuthorizer()
    authorizer.add_user('user', '12345', '.')
    handler = FTPHandler
    handler.authorizer = authorizer
    server = ThreadedFTPServer(('', 2121), handler)
    server.serve_forever()

if __name__ == "__main__":
    main()
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import MultiprocessFTPServer  # <-
from pyftpdlib.authorizers import DummyAuthorizer


def main():
    authorizer = DummyAuthorizer()
    authorizer.add_user('user', '12345', '.')
    handler = FTPHandler
    handler.authorizer = authorizer
    server = MultiprocessFTPServer(('', 2121), handler)
    server.serve_forever()

if __name__ == "__main__":
    main()

带宽限制

import os

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


def main():
    authorizer = DummyAuthorizer()
    authorizer.add_user('user', '12345', os.getcwd(), perm='elradfmw')
    authorizer.add_anonymous(os.getcwd())

    dtp_handler = ThrottledDTPHandler
    dtp_handler.read_limit = 30720  # 30 Kb/sec (30 * 1024)
    dtp_handler.write_limit = 30720  # 30 Kb/sec (30 * 1024)

    ftp_handler = FTPHandler
    ftp_handler.authorizer = authorizer
    # have the ftp handler use the alternative dtp handler class
    ftp_handler.dtp_handler = dtp_handler

    server = FTPServer(('', 2121), ftp_handler)
    server.serve_forever()

if __name__ == '__main__':
    main()

添加ssl认证

"""
An RFC-4217 asynchronous FTPS server supporting both SSL and TLS.
Requires PyOpenSSL module (http://pypi.python.org/pypi/pyOpenSSL).
"""

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


def main():
    authorizer = DummyAuthorizer()
    authorizer.add_user('user', '12345', '.', perm='elradfmw')
    authorizer.add_anonymous('.')
    handler = TLS_FTPHandler
    handler.certfile = 'keycert.pem'
    handler.authorizer = authorizer
    # requires SSL for both control and data channel
    #handler.tls_control_required = True
    #handler.tls_data_required = True
    server = FTPServer(('', 21), handler)
    server.serve_forever()

if __name__ == '__main__':
    main()

自定义事件回调处理

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


class MyHandler(FTPHandler):

    def on_connect(self):
        print "%s:%s connected" % (self.remote_ip, self.remote_port)

    def on_disconnect(self):
        # do something when client disconnects
        pass

    def on_login(self, username):
        # do something when user login
        pass

    def on_logout(self, username):
        # do something when user logs out
        pass

    def on_file_sent(self, file):
        # do something when a file has been sent
        pass

    def on_file_received(self, file):
        # do something when a file has been received
        pass

    def on_incomplete_file_sent(self, file):
        # do something when a file is partially sent
        pass

    def on_incomplete_file_received(self, file):
        # remove partially uploaded files
        import os
        os.remove(file)


def main():
    authorizer = DummyAuthorizer()
    authorizer.add_user('user', '12345', homedir='.', perm='elradfmw')
    authorizer.add_anonymous(homedir='.')

    handler = MyHandler
    handler.authorizer = authorizer
    server = FTPServer(('', 2121), handler)
    server.serve_forever()

if __name__ == "__main__":
    main()
### pyftpdlib 库使用指南 `pyftpdlib` 是一个纯 Python 实现的 FTP 服务器库,支持多种功能扩展和自定义配置。以下是关于如何使用 `pyftpdlib` 的详细介绍以及示例代码。 #### 安装 pyftpdlib 为了使用该库,需先完成安装过程。可以通过以下命令安装此库[^1]: ```bash pip install pyftpdlib ``` #### 基础 FTP 服务实现 下面是一个简单的例子,展示如何创建一个基础的匿名访问 FTP 服务器: ```python from pyftpdlib.authorizers import AnonymousAuthorizer from pyftpdlib.handlers import FTPHandler from pyftpdlib.servers import FTPServer # 创建匿名授权对象 authorizer = AnonymousAuthorizer() # 设置根目录路径供匿名用户访问 authorizer.add_anonymous("/path/to/ftp/directory") # 初始化处理器并绑定到授权者 handler = FTPHandler handler.authorizer = authorizer # 配置服务器地址和端口 server = FTPServer(("0.0.0.0", 21), handler) # 设定最大连接数 server.max_cons = 256 server.max_cons_per_ip = 5 # 启动服务器 try: server.serve_forever() except KeyboardInterrupt: server.close_all() ``` 上述代码展示了如何通过指定 `/path/to/ftp/directory` 来允许匿名用户的文件共享。 #### 用户认证与权限控制 如果希望提供带用户名密码验证的服务,则可以修改如下部分代码: ```python from pyftpdlib.authorizers import DummyAuthorizer def main(): # 创建虚拟用户授权器 authorizer = DummyAuthorizer() # 添加具有读写权限的新用户 authorizer.add_user("user", "password", "/home/user", perm="elradfmwMT") # 将授权器应用至处理程序 handler = FTPHandler handler.authorizer = authorizer # 绑定服务器监听IP及端口号 address = ("0.0.0.0", 21) server = FTPServer(address, handler) # 运行服务器直到手动停止 try: server.serve_forever() except Exception as e: print(f"Error occurred: {e}") server.close_all() if __name__ == "__main__": main() ``` 在此段代码中,“perm”参数指定了用户的权限范围。“elradfmwMT”的含义分别代表不同的操作许可,具体可查阅官方文档获取更多信息[^4]。 #### 自定义日志记录 有时可能需要跟踪客户端活动以便调试或审计目的。这可通过重载默认的日志方法达成: ```python import logging class LoggingFTPServer(FTPHandler): def on_connect(self): logging.info(f"{self.remote_address} connected.") def on_disconnect(self): logging.info(f"{self.remote_address} disconnected.") def on_login(self, username): logging.info(f"user {username} logged in from {self.remote_address}") def on_logout(self, username): logging.info(f"user {username} has been logged out") # 替换原有 Handler 类型为新定义类型 handler = LoggingFTPServer handler.authorizer = authorizer ``` 以上即为基于 `pyftpdlib` 构建 FTP 服务的基础教程及其一些常见应用场景下的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值