跳转到主要内容

使用SMB 2/3协议与服务器交互

项目描述

smbs协议

Python的SMBv2和v3客户端。

Test workflow codecov PyPI version License

SMB是一种网络文件共享协议,在过去的几年中经过了多次迭代。这个库基于MS-SMB2文档实现了SMBv2和SMBv3协议。

特性

  • 将SMB 2.0.2协议协商到SMB 3.1.1(Windows 10/Server 2016)
  • 使用NTLM和Kerberos进行身份验证
  • 消息签名
  • 消息加密(SMB 3.x.x+)
  • 连接到Tree/Share
  • 打开文件、管道和目录
  • 在打开文件时设置创建上下文
  • 读取和写入文件和管道
  • 发送IOCTL命令
  • 在一个数据包中发送多条消息(复合)
  • 对独立和DFS服务器共享的实验性支持

这肯定不是功能完整的,因为SMB是一个相当复杂的协议,请参阅待办事项中的库中应有的功能。

要求

要在Linux上使用Kerberos身份验证,还需要其他依赖项,要安装这些依赖项,请运行

# for Debian/Ubuntu/etc:
sudo apt-get install gcc python-dev libkrb5-dev
pip install smbprotocol[kerberos]

# for RHEL/CentOS/etc:
sudo yum install gcc python-devel krb5-devel krb5-workstation python-devel
pip install smbprotocol[kerberos]

Windows上的Kerberos身份验证应使用库直接工作,但在Linux上,必须安装库,并且需要特定的GSSAPI扩展才能工作。此扩展应安装在大多数MIT或Heimdal Kerberos安装中,但这并不保证。要验证Linux上是否有Kerberos,您可以在Python控制台中运行以下检查

try:
    from gssapi.raw import inquire_sec_context_by_oid
    print("python-gssapi extension is available")
except ImportError as exc:
    print(f"python-gssapi extension is not available: {exc}")

如果没有可用,则需要设置系统gssapi实现的新版本,并针对该新版本编译python-gssapi。如果没有此扩展,则仅使用NTLM身份验证。

安装

要安装smbprotocol,只需运行

pip install smbprotocol

# To install with Kerberos support
pip install smbprotocol[kerberos]

这将下载此包中使用的所需包,并使您的Python环境准备就绪。

附加信息

SMB协议的第一步之一是协商使用的方言和其他可用功能。目前smbprotocol支持以下方言;

  • 2.0.0:随Server 2008/Windows Vista添加
  • 2.1.0:随Server 2008 R2/Windows 7添加
  • 3.0.0:随Server 2012/Windows 8添加
  • 3.0.2:随Server 2012 R2/Windows 8.1添加
  • 3.1.1:随Server 2016/Windows10添加

每个方言都会向协议中添加更多功能,其中一些是微小的,但有些是重大的。一个重大变化是在方言3.x中添加了消息加密。消息加密默认设置为True,需要覆盖以创建旧方言的会话对象。

默认情况下,协商过程将使用服务器支持的最新方言,但如果需要,则可以覆盖它。这是通过以下代码实现的

import uuid

from smbprotocol.connection import Connection, Dialects

connection = Connection(uuid.uuid4(), "server", 445)
connection.connect(Dialects.SMB_3_0_2)

虽然您可能不想降级到早期版本,但这确实允许您设置所需的最低方言版本。

示例

您可以在此库中使用两种不同的API。

  • smbprotocol:低级接口可以完成您想要的一切,但相当冗长
  • smbclient:高级接口实现了内置的osos.path文件系统功能,但用于SMB支持

examples文件夹包含高级和低级接口的示例,但对于日常用户来说,建议使用smbclient,因为它要简单得多。

smbclient接口

高级接口smbclient旨在使人们更容易使用此库进行简单和常用案例。它旨在复制内置的osos.path文件系统功能,如os.open()os.stat()os.path.exists()。它还旨在处理对DFS目标的连接,而smbprotocol则不行。

smbclient建立的连接将保留在池中,并在对同一服务器的后续请求中重复使用,直到Python进程终止。这使得身份验证简单,并且只需在第一次调用服务器时进行。任何DFS引用也缓存在该Python进程中。这优化了对同一DFS命名空间的任何后续请求。

smbclient 中的函数有一个全局配置对象,可以用来为任何未来的连接设置任何连接默认值。它还可以用来指定任何基于域的DFS设置,以进行更高级的配置。建议使用 ClientConfig() 来设置任何全局凭据,如下所示:

import smbclient

smbclient.ClientConfig(username='user', password='password')

ClientConfig 是一个单例,任何未来的该对象实例化只会更新设置的键。你可以在 ClientConfig 上设置以下键:

  • client_guid:用于在新的连接中识别客户端的客户端GUID
  • username:如果未设置显式凭据,则用于创建新SMB会话的默认用户名
  • password:用于身份验证的默认密码
  • domain_controller:域名控制器的主机名。这对于具有DFS服务器的环境很有用,因为它用于自动识别DFS域名信息
  • skip_dfs:是否跳过执行任何DFS解析,如果有错误或不想浪费任何往返请求引用,则很有用
  • auth_protocol:要使用的身份验证协议;negotiate(默认),kerberosntlm
  • require_secure_negotiate:控制客户端是否在连接到共享时验证协商信息(默认:True)。

除了在 ClientConfig 上设置默认凭据外,你还可以在每个 smbclient 函数上或注册新服务器时指定凭据和其他连接参数。这些函数接受以下 kwargs:

  • username:用于连接共享的用户名
  • password:用于连接共享的密码
  • port:覆盖默认端口(445)以连接到
  • encrypt:是否在连接上强制加密,需要远程服务器上的 SMBv3 或更高版本(默认:False
  • connection_timeout:覆盖以秒为单位的连接超时(默认:60

如果使用 Kerberos 身份验证并且 Kerberos 票据已通过 kinit 设置,则 smbclient 将自动使用这些凭据,而无需显式设置。如果没有检索到票据或您想使用不同的凭据,则可以在 ClientConfig 上设置默认凭据或指定服务器第一次请求时的 usernamepassword

例如,我只需要在创建目录的第一次请求上设置凭据,而不是在该目录中创建文件的后续操作中设置凭据。

import smbclient

# Optional - specify the default credentials to use on the global config object
smbclient.ClientConfig(username='user', password='pass')

# Optional - register the credentials with a server (overrides ClientConfig for that server)
smbclient.register_session("server", username="user", password="pass")

smbclient.mkdir(r"\\server\share\directory", username="user", password="pass")

with smbclient.open_file(r"\\server\share\directory\file.txt", mode="w") as fd:
    fd.write(u"file contents")

如果您想重置缓存,您可以选择启动一个新的Python进程或调用 smbclient.reset_connection_cache() 来关闭客户端缓存的全部连接。

日志记录

该库使用内置的Python日志功能。日志消息记录到 smbprotocol 命名记录器以及 smbprotocol.*,其中 *smbprotocol 目录中的每个Python脚本。

这些日志在调试问题时非常有用,因为它们提供了更详细的步骤快照,说明它正在做什么以及可能出错的地方。调试端还会打印出客户端发送的每个SMB数据包的易读字符串,因此它可以非常详细。

测试

对于此模块,您首先需要安装一些先决条件。这可以通过运行以下命令来完成:

# Install in current environment.
# Recommend to have virtual environment installed at .venv path.
pip install -r requirements-dev.txt
pip install -e .

# you can also run tox by installing tox
pip install tox

然后,要运行基本测试,请运行以下命令;

py.test -v --cov smbprotocol --cov-report term-missing

# or with tox for dedicated virtual environments and multiple Python versions.
tox

在提交代码进行审查之前,除了确保所有测试通过外,还应检查代码是否符合编码标准。

source ./build_helpers/lib.sh

lib::sanity::run

有一些额外的测试,只有在设置某些环境变量时才会运行。要运行这些测试,请设置以下变量:

  • SMB_USER:用于身份验证的用户名
  • SMB_PASSWORD:用于身份验证的密码
  • SMB_SERVER:要身份验证的IP或主机名
  • SMB_PORT:SMB服务器监听的端口,默认为445
  • SMB_SHARE:要连接的共享名称,必须存在一个具有该名称的共享,以及一个具有名称$SMB_SHARE-encrypted的共享,这将强制加密

从这里开始,设置这些环境变量后运行toxpy.test将激活集成测试。

这需要Windows 10或Server 2016,因为它们支持测试所需的Dialect 3.1.1。

如果您没有访问Windows主机,可以使用Docker设置Samba容器,并将其作为测试的一部分使用。为此,请运行以下bash命令;

source ./build_helpers/lib.sh

lib::setup::smb_server

此命令还将设置测试中使用的所需SMB_*环境变量。

等待队列

以下是我希望整合的功能列表,如果您想自己实现它们,欢迎提交PR;

  • 多通道支持,以提高大数据传输速度
  • 等等...

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分布

smbprotocol-1.14.0.tar.gz (182.8 kB 查看哈希值)

上传时间 源代码

构建分布

smbprotocol-1.14.0-py3-none-any.whl (125.2 kB 查看哈希值)

上传时间 Python 3

由以下支持

AWSAWS云计算和安全赞助商DatadogDatadog监控FastlyFastlyCDNGoogleGoogle下载分析MicrosoftMicrosoftPSF赞助商PingdomPingdom监控SentrySentry错误日志StatusPageStatusPage状态页面