プロフィール

髭山髭人(ひげひと)

自分の書いた記事が、一人でも誰かの役に立てば...
活動信条の一つとして「貴方のメモは、誰かのヒント」というのがあります。

このサイトについて

本家HP packetroom.net から切り離した いわゆる技術メモ用のブログで、無料レンタルサーバーにて運用しています。広告表示はその義務なのでご容赦。
XREA さんには長年お世話になっています

【Samba】Windows10のエクスプローラからサーバ内ディレクトリを操作して云々

概要 / 下準備

やりたかった事

ほぼタイトル通りです。
普段使いをしているPC(Windows10)と同じネットワーク上にサーバーマシン(RaspberryPiですが..)があり、
これを、Windows上のUIを使うノリで、サーバ内のファイルを読み書き出来たらなーと思いました。

調べたところ、Samba というものをサーバー上に入れれば実現可能との事
導入やら一部の設定覚書をまとめました

留意事項

  • ディレクトリ / フォルダ の表記ブレ
  • OSは Raspbian ですが、他のlinux系でも十分通用すると思います
  • 導入 2018/10/05 時点 Version 4.5.12-Debian

導入 / 一部確認系のコマンドとか

インストール
sudo apt-get install samba

ヘルプコマンド
samba -? または samba -V

起動系 2種
sudo systemctl start smbd
sudo systemctl start nmbd

sudo systemctl restart smbd
sudo systemctl restart nmbd

確認
sudo service smbd status

Samba通信の許可

大抵の場合、サーバにはファイアーウォール系のソフトが導入されていると思います
自分は firewalld というものを使っています。
( 環境によっては iptables だったりするかもしれません )
自分のケースだと、sambaインストール後に下記コマンドを実行するだけで除外設定できました。
ここでは本筋とは関係ないので、テンプレ的なコマンドだけ書いておきます
sudo firewall-cmd --permanent --zone=public --add-service=samba

このコマンドに関して少しだけ触れると、
firewalldに対し、publicという名前のプリセット(一概には言えないが、大抵の場合はコレが使われている)に、
samba は許可してね、という恒久的(permanent)な変更の指示を与える、みたいな認識でOKだと思います

(※便宜上、プリセットと書いてますが、正しくはテーブルと呼ばれる概念です)

第一目標:windowsからログイン的な作業無しで、誰でも読み書き可能な共有ディレクトリを試しに作成してみる

概要など

基礎的な..と言って良いかどうかわかりませんが、
少な目の手順で、パブリックなディレクトリをサーバ上で作成し、
windows10側から好きなように読み書きできる様な設定をして共有してみたいと思います。

解説や考察を挟むので、煩わしく見えるかも..orz

公開用のディレクトリを(ヌルいパーミッションで)作成

sudo mkdir -m 775 /public_share/

スーパーユーザー権限にて、mkdirコマンドを用いて、最上層に /public_share/ ディレクトリを作成
この時 -m オプションで、パーミッション、即ちディレクトリの操作権限を 775 にする
775 はシステム的にかなりぬるいレベルの権限であり、読み書きに関しては誰でも可能とされる

smb.conf に 公開用セクションを追記する

/etc/samba/smb.conf を編集して、ファイルの末尾に [ ] で括ったセクションを新しく書き足します
ここで設定したセクション名が、そのままwindowsネットワーク上で表示されるフォルダ名に相当するようです

# 元からあるメイン設定
[global]

security = user
map to guest = Bad User
...
(中略)
...

# ↓public_share という名前のセクションを設けてみる
[public_share]

path = /share_folder/
public = yes
read only = no
writeable = yes

[public_share] セクション内にて path =を用いて、先程作った公開用ディレクトリを指定します

public = yes は、全ユーザーに公開

更に、read only を明示的に no そして writeable を明示的に yes とします。
どちらも「書き込めるようにする」という雰囲気が漂ってきますね。 公式ドキュメントによると、対となる?(互いに反対の意味を持つ)設定らしいのですが...
自分はこのあたり、あまり深く掘り下げていません(ザル認識)

samba.org - #WRITEABLE
samba.org - #READONLY

他にもセクション用のオプションが沢山あるみたいですが、複雑すぎるのでとりあえずサラっとした感じで...

詰まったポイント / 書き込み許可

試行錯誤中、ググったサイトを参考にして、
[global] セクションで security = share を設定したら、以下のようなエラーが出て怒られました。

Ignoring invalid value 'share' for parameter 'security'

どうやらこの security = share オプション、
自分が扱っているバージョンでは廃止された項目のようです。

古い設定項目「security = share」と、ほぼ同等とされる?設定にして、これをそのまま導入しました

[global]

# この3項目を用意(弄る)
security = user
map to guest = Bad User
guest ok = yes

...以下略...

詰まったポイント / そもそもネットワーク画面にサーバーをどうやって出すん?

Samba弄り始めがてら、最初に色々なサイトを見よう見まねで参考にして触って見ましたが、
なんと、自分はまず最初に、安定して「エクスプローラー(ネットワーク)上に表示させる」段階で詰まっていました。
設定ファイルを何度も書き換えたり、
windowsエクスプローラ上のネットワークをF5更新したりと、とにかく頭を悩ませていました..

ネットワークの画面一覧には何も出てこないが、
エクスプローラのアドレスバーに、\\192.168.11.10 と入力してネットワークインターフェースにアクセスすると、
とりあえず繋がりはするようなのです。
( 未設定時の話なので、「このフォルダーは空です」 の状態となっていた )

エクスプローラのアドレスバーに、\\raspberrypi と入力しても、とりあえず繋がりはする( こちらも空の状態で )
でたらめなIPや、ホスト名を入力した場合は明確に繋がらない(弾かれる)ので、
何らかの設定は生きているのかな?といった印象

↓解決ポイント

Windows 10 の SMB 1.0/CIFS クライアント を有効にする 事で解決。
これをしないと、そもそもsambaを試行錯誤して弄っても ネットワーク上に出てこなくなる。
完全に混乱のもとだから、機能が有効(ON)であるかどうか確認しておいて損はないと思います

ちなみに SMB 1.0/CIFS サーバ のほうはオフのままでも表示されました

※これらの機能がどういったものなのか、自分はよく分かっていません

Windowsネットワーク上に表示されているか / 読み書き可能かを試す

設定を書き換えたら、都度サービスを再起動してネットワークを確認

sudo vim /etc/samba/smb.conf 編集
sudo systemctl restart smbd 再起動
sudo systemctl restart nmbd 再起動

ちなみに試行錯誤中は、ただひたすら

  • vimで編集
  • サービスrestart
  • windowsのネットワーク画面を更新して(ちょっと待ってから)確認

...の繰り返しでした

実際にwindows側の操作で、ファイルの書き込み操作をしてみる

設定が適切であれば、まずはwindows上のネットワークから、対象となるホスト名のサーバーが開けます。
そこから更に、作成・公開した /public_share/ ディレクトリにアクセスが可能なハズ。
あとはそのままフォルダを開き、右クリックから新規テキスト等、好きなファイルを作成できれば書き込み処理も成功です。

権限設定により、作成できない場合もある

もし操作を拒否された場合は、上の手順で一通り行った「誰でも読み書き可能」な低レベル権限の操作要求では、
書き込み操作が許されないパーミッションのディレクトリである可能性があります。

先程の手順通りなら 775 のパーミッションでディレクトリが作成されているので、
低権限な状態でもファイルの書き込み処理が出来るはずなのですが。

権限により結果が異なる / 同条件で設定された、2つの公開用ディレクトリ

ある2つのディレクトリに対し、それぞれ以下の同じ設定を与えて検証してみました。
[global] セクションの詳細は省きますが、
ユーザー情報不要(ログイン無し)で、誰でもアクセス出来て、書き換え系も受け付けるよ、という意図の設定です

/etc/samba/smb.conf

    # ※ 以下2セクションの設定内容は同じ

    # 1. お馴染み home ディレクトリ
    [home]
    path = /home/
    public = yes
    read only = no
    writeable = yes

    # 2. 権限 775 で作成したディレクトリ
    [share_folder]
    path = /share_folder/
    public = yes
    read only = no
    writeable = yes

前者はお馴染み(?)の /home/ ディレクトリですが、
後者は mkdir コマンドで作成したディレクトリとなります。
この時、後者は先程の手順を踏襲し、パーミッション権限を 775 とユルく作ってみました。

実際に操作すると、2つともwindowsエクスプローラ(ネットワーク)経由にて、
フォルダ内にはログイン不要でアクセスできましたが、
いざファイルを作ろうとすると、それぞれ以下のような結果になりました。

  • /home/ ディレクトリは「アクセス許可が必要です」と、操作を拒否された
  • /share_folder/ ディレクトリは、問題なくファイルを作成できる

各ディレクトリのパーミッションを確認

ls -la コマンドでディレクトリを確認すると

# ls -la /home/
drwxr-xr-x 3 root root 4096 10月 6 09:06 .
drwxr-xr-x 24 root root 4096 10月 6 16:36 ..
drwxr-xr-x 2 watashi_desu watashi_desu 4096 10月 6 09:05 watashi_desu

# ls -la /share_folder/
drwxrwxrwx 2 root root 4096 10月 6 18:18 .
drwxr-xr-x 24 root root 4096 10月 6 16:36 ..
-rwxr--r-- 1 nobody nogroup 0 10月 6 18:18 hoge.txt

このようになりました。
hoge.txt は、エクスプローラ上で試しに作成したテキストファイルです

よく見てみると、書き込みの権限 w が、/home/ ディレクトリには一部付いていないことが分かります
読み解くと、所有グループ および その他 に対して書き込みが許されていない状態です
どうやらこれが、/home/ ディレクトリ上でファイルを作成できなかった原因とも言えそうです。

smb.conf をある程度弄っても、
「ちゃんとパーミッションまで考慮してくださいね~」
「ディレクトリ操作の権限は乗り越えられませんよ~」
という事なのでしょうね。
公開範囲や用途に合わせて、この辺の権限や設定を調節すると、より細かい場面に対応した設定が作れそうです。

ユーザー設定の出番かも

例として挙げた /home/ ディレクトリの権限を、迂闊にユルくする訳にも行きませんので、
もう少し権限周りを意識して、再び samba の設定を弄ってみたいと思います

この手の権限はどうやら、「あなたならOK」「あなた"達"ならOK」「あなた"以外"ならOK」等、
いろいろ組み合わせて細かく調節することも可能なようです。

[global] セクションの guest account 項目に注目

先程表示させたパーミッションログをもう一度載せます

# ls -la /share_folder/
drwxrwxrwx 2 root root 4096 10月 6 18:18 .
drwxr-xr-x 24 root root 4096 10月 6 16:36 ..
-rwxr--r-- 1 nobody nogroup 0 10月 6 18:18 hoge.txt

hoge.txt の情報に注目すると、所有者のユーザー名が nobody として記載されています

実はこれ、[global]セクションで設定されているデフォルトのゲストユーザー名がそのまま反映されているものです

表記上では(中略)として端折りましたが、[global]セクションを確認してみると、
初期設定で nobody というユーザー名が書かれているかと思います

nobody と見てピンと来る方も居ると思いますが、unix上で良く用いられる非特権ユーザーがこのアカウントに相当します
伝統的に良く用いられる、通常のユーザーより更に低い権限のユーザーアカウント名..みたいな認識で良いと思います。

/etc/samba/smb.conf

[global]
...中略...

guest account = nobody

...以下略...

通常、と言って良いのか分かりませんが、windowsネットワークから共有フォルダにアクセスする場合、
ユーザー名とパスワードを用いたログオンを求められるケースがあります。

前の手順で掲載していた設定方法だと、敢えてこの煩雑なログイン手順を意識させないようにしていました。
ログイン処理が行われない場合はゲスト扱いとなり、guest account で指定されたユーザーに成り代わります

先程までの設定だと、ログインがされない場合、自動的にゲストアカウントにマッピングされるので、
ログインしていないように見えて、実の所 nobody アカウントの権限を持ってアクセスしていた、という事となります。
それゆえ、作成した hoge.txt のオーナーが nobody となっていた訳ですね。

つまり、普段サーバーで作業している watashi_desu というユーザーアカウントが存在していた場合、
Sambaの設定ファイルで もし guest account = watashi_desu と書いていたら、
先程のケースで windows上からテキストファイルを作成する時、
hoge.txt ファイルのオーナーは watashi_desu となっていたでしょう。

とはいえ、ログイン処理を飛ばしてアクセスするゲストは所詮ゲスト。
狙ってそうしているのなら兎も角、あまり高い権限をゲスト持たせるのもなんだかな~と思わないことは無いので、
次の手順では、windowsのネットワークからサーバーに入る時に、きちんとログイン処理を設けてみようと思います

ログイン処理が挟まれるように、設定を変えてみる

[global] セクション内

[global]セクションの一部項目が関係しているようです

[global]
map to guest = Bad User
security = user
guest account = nobody

samba.org - smb.conf.5.html

公式ドキュメント見ながらいろいろ考察してました。

map to guest = Bad User だと、ログイン失敗(ログイン無し)の処理を
そのままゲストアカウントとして流していくスタイルなので、
この箇所を、ログイン無し状態を拒否する(=ログイン必須にする)パラメータの map to guest = Never にするか、
コメントアウトして項目自体を外すか(そうするとデフォルトの拒否設定 Never 扱いになる)で良さそうです。

もうひとつの guest account 自体は、ログインに失敗した(ログインしない)場合に
流していくゲストアカウントを指定する機能です。
map to guest = Never にした場合、ログイン失敗した(ログインしない)場合は、明確に要求を拒否するので、
guest account が設定されていても、ゲストアカウントに流れないようになります。
( つまりディレクトリの中身にアクセスできない )

自分の結論としては、map to guest を無効化 or 設定値を Never にすると良いのかなーと。

ログイン画面は出るが、Samba側で有効なユーザーを登録させないと入れない

さて、実際に設定を変えて、このようにしました
windowsのネットワーク上からサーバーにアクセスしようとすると、ログインフォームがでてきます

[global]
map to guest = Never
security = user
guest account = nobody

map to guest = Never が効いているので、
ログインに成功しないと、アクセスなどの操作要求がすべて拒否されるようになりました。
ログイン自体を無視する事も出来ない(無視=失敗扱い)ので、
guest account の項目が設定してあっても、nobody ユーザーとして入る事は出来ません。

ここでログインできるユーザー is 何?

ここで認証に用いられるユーザー情報は、Sambaが認識できる(登録された)ものに限ります。
linux側のアカウントを用いても、それでは(それだけでは)受け付けられません

認証可能なアカウント情報をSamba側に設定する

samba側が利用するユーザーを追加(設定)

ログインフォームを出したのに、認証できるユーザー自体が存在していないってのも変な話ですね。
という訳で、ここではSambaが認識できるユーザーを与える系の手順を書いていきます。

Samba用のアカウントを用意するのも良いですが、
ここではとりあえず、あなたが作業で用いている、"既存"の linux アカウント を利用することにしましょう

samba側が利用するユーザーを追加

pdbedit というコマンドがあるのですが、これを用いて、
Sambaで認証するためのユーザーを、Samba側に登録します

とりあえず既存のユーザー 一覧を確認してみましょう。
linuxのユーザー情報が保存されたファイルを覗き見するのが、手っ取り早い方法のようです

cat /etc/passwd 指定されたファイルを眺める

あなたが作業用に独自のユーザーアカウントを設けて使っているのなら、
恐らくそのユーザー名がファイルの後方行に書かれているかと思います

今回作業で用いているユーザー名を watashi_desu アカウントとしているので、
このアカウント名を用いて、Samba側でも認証させられるアカウントを pdbedit コマンドで登録してやります

ちなみに、pdbedit を用いて Samba に登録できるユーザーは、既にシステムに存在するユーザー というのが大前提です。
linux側で存在しないユーザー名を pdbedit で追加しようとしたら弾かれてしまいました。

古くだと smbpasswd というものが、pdbedit に相当する機能だったらしいです。
pdbedit は Samba3.0あたりから新しく追加されたそうで。
一応 smbpasswd で作成しても構わないが、pdbedit のほうが汎用性が高い、とも書いてありました。

※出典忘れましたごめん野菜。

pdbeditコマンドでSambaにアカウントを追加

sudo pdbedit -a watashi_desu -a 登録するユーザー名を与える。

先程も書きましたが、ここでのユーザー名はシステムに存在しないものだと弾かれます。
次いで、 new passwordretype new password で、対応するパスワードを指定してあげます。

linuxで既にパスワードを登録して使っているのに、Sambaに認識させるときに、何故新しく入力する必要があるのか?
..と思わない事も無いですが、Linux と Sambaではパスワードの暗号化方式が異なるようで、
Sambaはwindowsの暗号化方式に合わせているのだそう。

Renoji.com - Sambaへのユーザー登録

実際にwindowsのネットワーク画面から、ログインしてみる

設定が反映されていれば、ログイン画面に今しがた登録したユーザー名+パスで入れるかと思います

Windows側で入力(記憶)した、資格情報もといログイン情報を消す場合

  1. コントロールパネル
  2. ユーザーアカウント
  3. 資格情報の管理
  4. Windows資格情報

の流れで、管理画面にたどり着けるので、そこから当該する情報を削除すればいけるかなと。

また、この方法だとセッションが残り、PCログオフなどを一度挟まないと、
ネットワークログオン前の最初の状態に戻る事が出来なかったりするようです

この辺の反映はシビアなのかなーと思います。
\困ったときの再起動!/

ファイルの書き換えを明示的に許可

各種、公開ディレクトリ用のセクションで、以下のようにしましょう

readonly = no
writeable = yes

狙って書き込みを禁止させている場合は良いですが、
Sambaできちんと登録したユーザーでディレクトリ等を操作している時、
ここの「書き換えてもOKよ♪」的な設定が反映されていなければ、操作が拒否されてしまいます

実際自分も、Sambaに登録したアカウント情報でログイン後、
windowsのネットワークからファイルを書き込もうとしたら弾かれました。
上記2つの設定を明示してみたら、サービス再起動後は相当権限で操作が出来るようになりました。

余談:ネットワークインターフェースについて

[global] セクションの interfaces について

筆者はRaspberryPi 3 B+を用いている以上、ネットワークに繋ぐ主要インターフェースが2つあります
一つは有線LANの差込口があるので、これに相当する eth0
もう一つは、無線LANのほうで、大抵の場合は wlan0 といった具合に管理されているかと思います。
( こちらはラズパイユーザーさんなら手動設定とかした事あるんじゃないでしょうか )

ちなみに ifconfig コマンドで、このインターフェース一覧を調べられます。

interfaces を明示的に指定していない場合、或いは、
bind interfaces only = yes にしていない or コメントアウトで無効等にしている場合は
ブロードキャスト出来る全てのインターフェースが自動で設定されるようです

自分の場合、有線LAN相当の eth0 IPアドレスは 192.168.11.16 で、
無線LAN相当の wlan0192.168.11.10 となっています

設定を弄ると、どのように反映されるのか、
windowsのエクスプローラから、敢えてこのインターフェースに相当するIPアドレスにアクセスする方法で試してみました

interfaces = 127.0.0.0/8 eth0

これが恐らくデフォルトの設定になっていると思います( 違ったら適宜脳内変換お願いします )
自分はラズパイで、無線LAN(wlan0)での運用を行うつもりなので、
使わない eth0 を敢えて外し、代わりに wlan0 を追加しました

interfaces = 127.0.0.0/8 wlan0

設定を反映させて、windowsエクスプローラから、eth0 相当の 192.168.11.16 にアクセスすると、繋がってしまいました。
おかしいですよね。 設定で敢えて eth0 を外したのに、繋がるのは不自然です

ところが、interfaces = 127.0.0.0/8 wlan0 はそのままに、

bind interfaces only = yes

として、ここを有効にすると、
無事、ネットワーク上で eth0192.168.11.16 に繋がらなくなりました
逆に、wlan0 を設定に入れたので、相当する 192.168.11.10 には繋がるようになっています。狙い通り('ω')b

明示的に「これしか使わないでね!」というbind設定が、ちゃんと活きてるんだなぁ..と思いました(小並感)

interfaces = 127.0.0.0/8 wlan0
bind interfaces only = yes

エクスプローラのネットワーク上で表示される名前は、通常はホスト名なので、
それでアクセスするのが通例だとは思うのですが、
敢えてIP指定で繋ぐことで bind interfaces only の設定がキチンと効いているかの証左になるのかな、と。