メモの日々


2024年10月01日(火) [長年日記]

[windows][net][howto] WSLにポートフォワードで外部からアクセス可能にする

WSLに外部からSSHでアクセスできるようにする方法をメモ。なお、試した環境はWindows 11ではなくWindows 10。

WSL上でsshdを使えるようにする方法は割愛。WSLをホストしているWindowsからはWSLへSSH接続できるものとする。

ポートフォワーディング設定

Windowsホスト上でnetsh interface portproxyコマンドを使ってWSLへのポートフォワーディングを設定する。なお、この設定には管理者権限が必要。

> netsh interface portproxy add v4tov4 `
    listenport=22222 listenaddress=0.0.0.0 `
    connectport=22 connectaddress=192.0.2.100

設定の確認はshow allサブコマンドでできる。

> netsh interface portproxy show all

ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
0.0.0.0         22222       192.0.2.100     22

これにより、Windowsホストのポート22222へのアクセスはWSL(のアドレスを仮に192.0.2.100とした)のポート22へ転送されるようになる。

ファイアウォール設定

上記に加え、Windowsのファイアウォール設定を変更しないとアクセスできなかった。ファイアウォールの設定はnetsh advfirewallコマンドを使って行える。こちらも要管理者権限。

> netsh advfirewall firewall add rule `
    name="WSL-SSH" `
    protocol=TCP `
    localport=22222 `
    dir=in `
    action=allow

設定の確認は次の通り。

> netsh advfirewall firewall show rule name=WSL-SSH

規則名:                               WSL-SSH
----------------------------------------------------------------------
有効:                                 はい
方向:                                 入力
プロファイル:                         ドメイン,プライベート,パブリック
グループ:
ローカル IP:                          任意
リモート IP:                          任意
プロトコル:                           TCP
ローカル ポート:                      22222
リモート ポート:                      任意
エッジ トラバーサル:                  いいえ
操作:                                 許可
OK

以上の設定で外部からWSLのSSHへのアクセスができるようになった。

設定の削除方法

ファイアウォール設定とポートフォワード設定を削除して元に戻すには次のようにする。

> netsh advfirewall firewall delete rule name=WSL-SSH

1 規則を削除しました。
OK
> netsh interface portproxy delete v4tov4 listenport=22222 listenaddress=0.0.0.0

NetNat系コマンドとの違い

以前にHyper-V上のVMへ外部からアクセスする方法をメモしていて、このときはnetshではなくAdd-NetNatStaticMappingコマンドなどを使っていた。

WSLについても同じようにしてできるのかもしれないが、netshを使うと仮想スイッチの設定を気にしなくていいのでこちらの方がWSL向きな気がする。

違いは理解できていない。


2024年10月08日(火) [長年日記]

[python] SQLModelのdatetimeに対する動作

どうしてそうなるのかは理解できていないが、事実をメモ。

SQLModel0.0.22を使っている。

datetime型のフィールドを持つモデルを定義して、そのmodel_validate_json()によりJSONからのでシリアライズを行ったときに次のようになる。

  • table=True無しで定義したモデルはdatetime型のフィールドにdatetime型の値が格納される
  • table=True有りで定義したモデルはdatetime型のフィールドにstr型の値が格納されてしまう

検証コードと実行結果を示す。

from datetime import datetime

from sqlmodel import Field, SQLModel


class A(SQLModel):
    id: int = Field(primary_key=True)
    dt: datetime


class B(SQLModel, table=True):
    id: int = Field(primary_key=True)
    dt: datetime


json = '{ "id": 1, "dt": "2024-01-02T03:45:06+09:00" }'
a = A.model_validate_json(json)
b = B.model_validate_json(json)
print(type(a.dt))
print(type(b.dt))
<class 'datetime.datetime'>
<class 'str'>