WSL2 samba構築(ポートフォワーディング)

# 目標
1. wsl2でsamba構築
1. ポートフォワーディングで外部からもアクセスできるようにする

# 割愛
- wslインストール

# 構成図
<img width="500" alt="kousei.png (285.9 kB)" src="https://img.esa.io/uploads/production/attachments/8212/2024/06/07/147595/6717abed-df04-4bfa-8404-d8412e77f962.png">

- wsl上でsambaを動かす都合上、外部からアクセスするためには、上図のようなポートフォワーディングが必要になります。


# samba設定
### インストール

```
sudo apt update
sudo apt install samba
```

### sambaの設定ファイル
/etc/samba/smb.conf のの末尾に追記
```
[share]
path = /home/あなたのユーザー名/samba
read only = no
guest ok = yes
writable = yes
valid users = あなたのユーザー名
```

- share: 共有フォルダの名前。クライアントからこの名前でアクセスされる
- path = /home/あなたのユーザー名/samba: 共有するディレクトリのパス。WSL上のディレクトリ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810146/53c6649e-7a9a-85db-3d65-db73e38e0eaa.png)



> こんな感じになる


### パスワード設定
以下を実行すると、パスワードが設定できる
```
sudo smbpasswd -a あなたのユーザー名
```

### shell scriptsを作成・実行
- samba起動用シェルスクリプトを作成

```~/start
#!/bin/bash

set -eax

sudo mkdir -p /run/samba/ncalrpc
sudo systemctl restart smbd
sudo systemctl status smbd --no-pager
sudo systemctl restart nmbd
sudo systemctl status nmbd --no-pager

```

- ~/startの権限を実行可能に変更
```
sudo chmod +x ~/start
```

- 実行
```
./start
```
※ポリシー違反のエラーが出た場合にはこちらを参考にしてみてください。
**[【Qiita】PowerShellでこのシステムではスクリプトの実行が無効になっているため、ファイル hoge.ps1 を読み込むことができません。となったときの対応方法](https://qiita.com/ponsuke0531/items/4629626a3e84bcd9398f)**

- <span style="color: red ; ">**終了したい場合** </span>は以下
```
sudo systemctl stop smbd
sudo systemctl stop nmbd
```


### ポート確認
```
sudo netstat -tulnp | grep smbd
```

```結果
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      680/smbd
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      680/smbd
tcp6       0      0 :::445                  :::*                    LISTEN      680/smbd
tcp6       0      0 :::139                  :::*                    LISTEN      680/smbd
```
139と445番地でlistenしていることがわかる
（tcpとtcp6はそれぞれIPv4とIPv6のことです）


# ポートフォワーディング
139と445を使用していることが分かったのでwslのポートをwindowsのポートへフォワーディングします。

以下のshellscriptsを作成
```.\server_conf.ps1
# 現在のユーザーが管理者権限を持っていない場合に、スクリプトを管理者権限で再実行するための処理です。
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) { Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs; exit }

# WSL 2 インスタンスの IP アドレスを取得します。
# bash.exe を使って、ip r コマンドを実行し、結果からIPアドレスを抽出します。
# IP アドレスが取得できない場合、スクリプトは終了します。
$ip = bash.exe -c "ip r |tail -n1|cut -d ' ' -f9"
if( ! $ip ){
  echo "The Script Exited, the ip address of WSL 2 cannot be found";
  exit;
}

# 通信を許可するポート番号のリストを指定します。
# このスクリプトでは、139,445の3つのポートを指定しています。
$ports=@(139,445);
$ports_a = $ports -join ",";

# 以前に作成されたファイアウォールの例外ルールを削除します。
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";

# New-NetFireWallRule コマンドを使用して、指定したポート番号に対するインバウンドおよびアウトバウンドのファイアウォール例外ルールを作成します。
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";

# netsh interface portproxy コマンドを使用して、ポートプロキシの設定を行います。
# 指定したポート番号に対して、IP アドレスを介しての接続を許可します。
for( $i = 0; $i -lt $ports.length; $i++ ){
  $port = $ports[$i];
  iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=* connectport=$port connectaddress=$ip";
}

# 作成されたポートプロキシの設定を表示します。
iex "netsh interface portproxy show v4tov4";

```


<span style="color: red ; ">**管理者権限** </span>powershellで以下を実行

```
.\server_conf.ps1
```



### ポートフォワーディングの確認
以下を実行
```
netsh interface portproxy show all
```
```実行結果
Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               139         172.20.xxx.xxx   139
*               445         172.20.xxx.xxx   445
```
- 0.0.0.0 (すべてのインターフェース) のポート 139 が、WSL の IP アドレス 172.20.xxx.xxx のポート 139 に転送される。
- 0.0.0.0 (すべてのインターフェース) のポート 445 が、WSL の IP アドレス 172.20.xxx.xxx のポート 445 に転送される。
ことが確認できる

# ファイアウォール設定
以下を実行します
```
netsh advfirewall firewall add rule name="Allow Samba Port 139" protocol=TCP dir=in localport=139 action=allow
netsh advfirewall firewall add rule name="Allow Samba Port 445" protocol=TCP dir=in localport=445 action=allow
```
これにより、139と445番地上での受信が可能になります

# 接続
### mac
<img width="500" alt="image.png (10.2 MB)" src="https://img.esa.io/uploads/production/attachments/8212/2024/06/07/147595/08ded105-28e9-4b7a-94c5-35fb4647832f.png">

<img width="500" alt="image.png (166.7 kB)" src="https://img.esa.io/uploads/production/attachments/8212/2024/06/07/147595/6ee0fbb2-7b77-4ddc-8b89-ba5d60c543fd.png">

> shareの部分は [sambaの設定ファイル](#sambaの設定ファイル)の[]で囲まれた文字列を使います （今回はshare）

<img width="500" alt="image.png (198.2 kB)" src="https://img.esa.io/uploads/production/attachments/8212/2024/06/07/147595/4bfd5402-6dcd-4703-92b2-ab37209bb5fc.png">

> できました

### win
winマーク＋R で\\192.168.xxx.xxx\shareに接続
<img width="500" alt="image.png (135.0 kB)" src="https://img.esa.io/uploads/production/attachments/8212/2024/06/07/147595/d04c03b1-b0db-4f26-bb61-441046bb1007.png">

> shareの部分は [sambaの設定ファイル](#sambaの設定ファイル)の[]で囲まれた文字列を使います （今回はshare）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810146/fde06273-05e2-4559-360b-9ee81ff5d473.png)


> できました


# 参考
- [【Samba】Linux⇔Windowsマシン間相互のファイル共有](https://qiita.com/OPySPGcLYpJE0Tc/items/4ec603883091f8fc7555)
- [wsl2 samba 開発環境構築](https://qiita.com/nuage/items/33d13e188c927cd29f56)
- [wsl2 で立てたサーバーにローカルネットワーク内の他の端末からアクセスする](https://qiita.com/tomoken_nikki/items/82234030e712c44c2e40)
- [PowerShellでこのシステムではスクリプトの実行が無効になっているため、ファイル hoge.ps1 を読み込むことができません。となったときの対応方法](https://qiita.com/ponsuke0531/items/4629626a3e84bcd9398f)