むろっちのStacking

日々の中で学んだIT知識をメモして置く場所

pysmbの設定とSMBバージョン差異について

pythonでSMB共有をするときは「pysmb」ライブラリが有名かと思います。

使い方はこんな感じです

import platform
from smb.SMBConnection import SMBConnection

if __name__ == "__main__":
    user = ''
    pw = ''
    remote_host = ''
    ip = ''
    domain_name='' #workgroupの場合はなしorWORKGROUPでOK

    # 設定1
    conn = SMBConnection(
    user,
    pw,
    platform.uname().node,
    remote_host,
    domain=domain_name,
    use_ntlm_v2=True
    )
    conn.connect(ip, 139)

    # 設定2
    conn = SMBConnection(
    user,
    pw,
    platform.uname().node,
    remote_host,
    domain=domain_name,
    use_ntlm_v2=True,
    is_direct_tcp=True)
    conn.connect(ip, 445)

⇛これでTrueが返ってくれば接続OK

ただ使ってみると接続エラーがたくさん出てうまくいかないことがあります

 

なぜつながらないのか

SMBには様々なバージョンが存在し、オプション設定がどのような役割を果たすのか理解していないと共有サーバーの設定と不一致となり、ID、PASSが適切であっても接続できないケースがあります

 

SMBで使うポート

137/UDP 137/TCP 138/UDP 139/TCP 445/UDP 445/TCP

 

SMBの動き(ざっくり)

SMB1/CIFS Netbios名で宛先を解決し、データを送信(Port 137,138,139) SMB1のみ SMB Direct(Port 445)をサポート(CIFSは対象外) SMB2以降 SMB Direct(Port 445)を利用

アクセス時には上位のプロトコル(SMB3)から順に試行してクライアント、サーバー双方が利用できるVerを利用します。

 

最近のSMB事情

Windows2012R2/Window8.1以降はデフォルトでSMB1が無効になっています →Port139でのアクセスは不可

ただ、古い機器等所有している企業などはSMB1系しか対応していない機器もあるためSMB1の対応を設定することも多いようです

f:id:murochi:20210111140801p:plain:w500

ですので、 アクセス対象のサーバーがCIFSにしか対応していない場合
→SMB Directが使えない

SMB1機能を無効化している場合
→CIFS/SMB1の機能であるNetbios名ファイル共有が使えない

 

結論

pysmb等で繋ぐ場合は
古い機器の場合

  • is_direct_tcp=False または書かない(Default:False)
  • connectポート指定は139

新しい機器の場合

  • is_direct_tcp=True
  • connectポート指定は445

仕様を読む限り、is_direct_tcp=Trueのほうが新しいプロトコルを使って共有アクセスするので性能が出るはず。なので設定しておいたほうがいいかと思います

参考 http://www.atmarkit.co.jp/ait/articles/0010/07/news002.html http://www.atmarkit.co.jp/ait/articles/1501/19/news092.html http://www.atmarkit.co.jp/ait/articles/1507/02/news026.html