手帳

  • 2025-02-19
  • IT系

ポートについて迷っていたらAIが、「netstat -tuln」とコマンドを打ち込んでん結果を見せろと言ったので色々と聞いてみた。

netstat -tulnとその結果

netstat -tuln
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN       
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:43025         0.0.0.0:*               LISTEN   
  • Proto: プロトコル(tcp, udp, tcp6, udp6)
  • Recv-Q: 受信キュー
  • Send-Q: 送信キュー
  • Local Address: ローカルのIPアドレスとポート番号
    • 0.0.0.0: 全てのネットワークインターフェースでリッスン
    • 127.0.0.1: ローカルホストのみでリッスン
    • :::: IPv6の全てのインターフェースでリッスン
  • Foreign Address: 接続相手のアドレスとポート
    • 0.0.0.0:*: どのアドレスからの接続も受け付ける
  • State: 接続の状態
    • LISTEN: 接続待ち受け状態

Local Addressってなに?

Local Address は「どのインターフェースで待ち受けるか」を指定しています。

例えば:

  • 127.0.0.1:37589 の場合
    • localhost(=loopbackインターフェース)のみがPort37589を待ち受けできる
  • 0.0.0.0:32791 の場合
    • 全てのインターフェースでPort32791 を待ち受けできる

つまり

Local Address          Foreign Address      State
127.0.0.1:37589       0.0.0.0:*           LISTEN

ならば

  • Local Address=>localhost(=loopbackインターフェース)の37589ポートで待ち受ける
  • Foreign Address=>接続してくる相手のアドレスは制限なし(ただしloopbackインターフェースからしかアクセスできないため、実質的には同じマシン内からのみ)
  • State: 待ち受け中

という意味になります。

Local Address で指定できる主なものは:

  • 0.0.0.0 : 全てのインターフェース
  • 127.0.0.1 : loopbackインターフェースのみ
  • 特定のIPアドレス : その特定のインターフェースのみ

です。

ネットワークインターフェース

ネットワークインターフェースには物理的なものと論理的(仮想的)なものがある

  1. 物理インターフェース:
    • eth0(イーサネットカード)
    • wlan0(無線LANカード) など、実際のハードウェアデバイス
  1. 論理インターフェース:
    • localhost = loopback(lo、127.0.0.1)
    • docker0(Dockerの仮想ネットワーク)
    • tun0/tap0(VPNの仮想インターフェース)
    • vethXXXXX(コンテナ用の仮想イーサネット) など、ソフトウェアで作られた仮想的なインターフェース

Local Addressが「0.0.0.0:32791」と書いてあったら

設定上の可能性(0.0.0.0) 待ち受け可能なインターフェース: eth0 lo (127.0.0.1) docker0 その他のネットワークインターフェース 実際のポート32791の状態 Docker Daemonが使っている場合 Port 32791 Docker Daemon 専有中 Other Process Other Process Other Process

Local Addressが「127.0.0.53:53」と書いてあったら

53ポートで待ち受けているのは127.0.0.53

Foreign Addressで、0.0.0.0:*と書いてあって、「どのアドレスからの接続も受け付ける」と決められていても、既に「127.0.0.53」がポートを(待ち受けのために)占有しているので他のネットワークインターフェースは接続できない。

VPS Server Port 53 (DNS) 127.0.0.53 systemd-resolved ポート占有中 eth0 接続できない その他のインターフェース 接続できない Local Address: 127.0.0.53:53 1. 127.0.0.53のインターフェースが  53番ポートを占有 2. Foreign Address: 0.0.0.0:*  は理論上どこからでも受付可能 3. しかし実際には127.0.0.53からの  アクセスのみ可能

じゃあ、dockerのymlファイルでPortsって書いてあるのは何?

ymlでPortsで指定すると、その内容をDocker Daemonが察して指定のポートで待ち受けてその内容をコンテナ内の指定された仮想ポートに転送する

ports:
  # 全インターフェースでの待ち受け(0.0.0.0)
  - "32791:80"  

  # Dockerインターフェースのみ(172.17.0.1)
  - "172.17.0.1:32791:80"

  # eth0の特定IPのみ
  - "x123-45-67-89:32791:80"
Internet VPS Server Network Interfaces eth0(x123-45-67-89:32791) lo (127.0.0.1:32791) Docker Daemon ポート監視 &転送 Container (nginx) 80 コンテナ側 外部からの アクセス ポートマッピング “32791:80” の仕組み: 1. 外部からのアクセス: • x123-45-67-89:32791 でアクセス → eth0インターフェース経由 2. 内部からのアクセス: • 127.0.0.1:32791 でアクセス → loインターフェース経由 3. Dockerデーモンの役割: • 32791ポートを監視し、入ってきたデータを全てコンテナ内の80ポートに転送

dockerでNginx Proxyを使って複数のサイトを作るとき、それぞれのサイトのymlではPortsは使わない!

それぞれのサイトのymlでPorts: 80:80みたいにしたら、Docker Daemonにそれぞれ別々に80ポートの監視を依頼して、コンフリクトする!

なのでNginx ProxyのymlファイルだけPorts: 80:80, 443:443を書いて、あとのymlファイルではexpose: 80のように書く。

docker psでDocker Daemonに監視を依頼しているコンテナがわかる

docker psコマンドで-> の矢印がある表示があるものが、Docker Daemonにホストのポート監視を依頼しているコンテナということ

$ docker ps
PORTS
80/tcp                                                                                      hogehoge1-nginx
80/tcp                                                                                      hogehoge2-nginx
0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp                 nginx-proxy

この例だと、nginx-proxyが、全てのネットワークインターフェースの80と443ポートを監視してdocker内の仮想ポート80に転送していることになる。