Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --bind to specify serving address with relaxed default (0.0.0.0) #475

Merged
merged 4 commits into from
Jun 3, 2024

Conversation

omochi
Copy link
Contributor

@omochi omochi commented May 29, 2024

現状

dev server は --host で指定したアドレスで待ち受けします。

課題

指定しない場合

仮に --host がデフォルトの 127.0.0.1 の場合、
同一ホスト上から http://127.0.0.1:8080 へのアクセスでなければ接続できません。

ホストのLAN IPが 192.168.1.2 だったとして、 http://192.168.1.2:8080 では接続できません。
また、同一LAN の他のマシンやスマートフォンからも接続できません。
ウェブアプリ開発ではスマホを対象にしたりするのでこれは不便です。

指定する場合

--host で 192.168.1.2 を指定すれば、それで接続できますが、
この場合は同一ホストであっても 127.0.0.1 から接続できません。

状況に応じて使い分ける必要があり、面倒です。

また、Docker内部で起動する場合、
コンテナのネットワークアドレスが必要ですが、
これを把握するのは多少面倒です。

提案

こういった状況のために、ソケットインターフェースには待ち受けアドレスとして 0.0.0.0 が指定できます。
これはそのホストのあらゆるアドレスからの接続を受け入れる特別な設定です。
これで起動すれば、接続元に応じたホストのアドレスを指定するだけで良いので簡単です。

知る限りでは、 npx serve コマンドや nc コマンド、 vitejs の devサーバ なども、
デフォルトではこのモードで待ち受けおり、一般的です。

そこで、新たに --bind オプションを導入し、待ち受けアドレスを指定できるようにしつつ、
そのデフォルト値として 0.0.0.0 を指定します。

--host オプションのデフォルト値は 127.0.0.1 を使うのをやめて、
--bind オプションの値を使うようにします。

ただし、 0.0.0.0 は接続先アドレスとして不正です。
例えばSafariではこれはエラーとなり接続できません。

そこで、 --bind オプションが 0.0.0.0 の場合は、
--host オプションの値は 127.0.0.1 にします。
この書き換えは、Chromeのアドレスバーに 0.0.0.0 を指定した時と同じ挙動です。

--host の用途

--host を指定する機能はこれまで通り必要です。
立ち上がったサーバに接続するためのURLを構築するために使われているからです。

セキュリティ

待ち受けアドレスを限定するのはセキュリティを高める効果があります。
意図しない外部からの接続を遮断できるからです。
例えば postgresql などは初期状態でそのように設定されています。
この変更はそれを低下させます。

しかし、 dev server はデーモンとして常駐させるような使い方よりも、
明示的に CLI から起動し、フロントエンドジョブとしてユーザが運用するものなので、
影響は小さいです。

@@ -304,7 +304,7 @@ public actor Server {
}
// Enable SO_REUSEADDR for the accepted Channels
.childChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
.bind(host: configuration.host, port: configuration.port)
.bind(host: "0.0.0.0", port: configuration.port)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you just change the default value of --host option to keep the address still configurable? It's important to be able to make it restrictive by the option.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--host0.0.0.0 を指定することはできません。
この設定は接続用のURLを作るために使われるので、
http://0.0.0.0:8080 でブラウザを開こうとしてしまいます。

0.0.0.0 は待ち受け用のワイルドカードであって、
接続先のアドレスとして使うことはできません。

Chromeはそのような実装に配慮して 127.0.0.1 に読み替えて接続してくれますが、
別のサイトとみなされるので別の問題が生じます。
Safariは無効なアドレスとみなして接続エラーになります。


オプションとして設定可能にする場合、
外部から接続するためのアドレス (--host) とは別のパラメータとして
新たに用意する必要があると思います。
例えば --listen などでしょうか。

Copy link
Contributor Author

@omochi omochi May 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

会話した
https://discord.com/channels/291054398077927425/383442648012423179/1245364906434363513

以下の方針とする

  • WebDriver を使って Docker内部 などから NAT 超えをする状況もサポートしたい (Swift 6 が mac でぶっ壊れていたりするためニーズがある)
  • --listen を導入、デフォルトは 0.0.0.0
  • --host 指定なし、 --listen 指定ありの場合、--host デフォルト値を --listen から導出したい。127では接続できないことがわかっているため。

@omochi omochi changed the title dev server の待ち受けアドレスを 0.0.0.0 にする dev server の待ち受けアドレスを --listen で指定可能にする。デフォルトは 0.0.0.0 にする。 Jun 2, 2024
self.port = port
self.host = host
self.customIndexPath = customIndexPath
self.resourcesPaths = resourcesPaths
self.entrypoint = entrypoint
self.terminal = terminal
}

public static func host(listen: String, host: String?) -> String {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hostとlistenからhostを決定するロジックをここに定義します。
devコマンドとtestコマンドから共通で利用しています。

@omochi
Copy link
Contributor Author

omochi commented Jun 2, 2024

@kateinoigakukun --listen オプションを実装しました。

kateinoigakukun
kateinoigakukun previously approved these changes Jun 2, 2024
@kateinoigakukun
Copy link
Member

ArgumentParser/ParsableArguments.swift:271: Fatal error: Validation failed for `CartonFrontendTestCommand`:

- Multiple (2) `Option` or `Flag` arguments are named "-l".

@omochi
Copy link
Contributor Author

omochi commented Jun 2, 2024

@kateinoigakukun ショートオプションの -ltest コマンドの list と被っていたので削除しました。
dev コマンドと test コマンドで使い方が違うのは混乱を招くので、どちらも削除しました。

しかし、 --host オプションよりも --listen オプションの方が基本的なものになるので、
--host-h で指定できるのに --listen にはショートオプションがないのは不自然です。

-l は使えないので、代わりに bind-b を設定するのはどうでしょうか?
bind はソケットをアドレスに割り当てるAPIの名前で、 NIO もそれを踏襲しています。

@kateinoigakukun
Copy link
Member

--bind / -b sounds reasonable to me 👍

@omochi
Copy link
Contributor Author

omochi commented Jun 3, 2024

ロングオプションも合わせて bind に変更するということですね。後で対応します。

@omochi omochi changed the title dev server の待ち受けアドレスを --listen で指定可能にする。デフォルトは 0.0.0.0 にする。 dev server の待ち受けアドレスを --bind / -b で指定可能にする。デフォルトは 0.0.0.0 にする。 Jun 3, 2024
@kateinoigakukun kateinoigakukun changed the title dev server の待ち受けアドレスを --bind / -b で指定可能にする。デフォルトは 0.0.0.0 にする。 Add --bind to specify serving address with relaxed default Jun 3, 2024
@kateinoigakukun kateinoigakukun changed the title Add --bind to specify serving address with relaxed default Add --bind to specify serving address with relaxed default (0.0.0.0) Jun 3, 2024
@kateinoigakukun kateinoigakukun merged commit b8048c4 into swiftwasm:main Jun 3, 2024
4 checks passed
@kateinoigakukun
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants