ソケットを理解する

提供:Dev Guides
ソケットを理解するから転送)
移動先:案内検索

序章

ソケットは、サーバー上で実行されているプログラム間、または別々のサーバー上で実行されているプログラム間のプロセス間通信を可能にする方法です。 サーバー間の通信は、ネットワークソケットに依存します。このソケットは、インターネットプロトコル(IP)を使用して、データの送受信をカプセル化および処理します。

クライアントとサーバーの両方のネットワークソケットは、ソケットアドレスによって参照されます。 アドレスは、伝送制御プロトコル(TCP)やユーザーデータグラムプロトコル(UDP)などのトランスポートプロトコル、IPアドレス、およびポート番号の一意の組み合わせです。

このチュートリアルでは、プロセス間通信に使用される次のさまざまなタイプのソケットについて学習します。

  • ストリームソケット。基盤となるトランスポートプロトコルとしてTCPを使用します。
  • データグラムソケット。基盤となるトランスポートプロトコルとしてUDPを使用します。
  • Unixドメインソケット。ネットワークインターフェイスやIPパケットの代わりに、ローカルファイルを使用してデータを送受信します。

このチュートリアルの各セクションでは、Linuxシステムでそれぞれのソケットタイプを列挙する方法も学習します。 さまざまなコマンドラインツールを使用して、各タイプのソケットを調べます。

前提条件

このチュートリアルの例は、Ubuntu20.04サーバーで検証されています。 ディストリビューションに必要な各ツールの同等のバージョンがインストールされている限り、ローカルコンピューターまたはリモートサーバーで最新のLinuxディストリビューションを使用してこのチュートリアルに従うことができます。

Ubuntu 20.04の使用を開始するには、 Ubuntu20.04の初期サーバーセットアップガイドに従って構成された1台のサーバーが必要です。

このページに埋め込まれているインタラクティブ端末を使用して、このチュートリアルで使用するサンプルのsocatおよびncコマンドを試すこともできます。 次のインタラクティブターミナルを起動します!ボタンをクリックして開始します。

インタラクティブターミナルを起動します!

また、システムのソケットを調べるために、他のいくつかのパッケージが必要になります。 apt updateコマンドを使用して、システムのパッケージキャッシュが最新であることを確認します。

sudo apt update 

次に、次のコマンドを使用して必要なパッケージをインストールします。

sudo apt install iproute2 netcat-openbsd socat

iproute2パッケージには、ssユーティリティが含まれています。これは、ソケットの検査に使用します。 netcat-openbsdパッケージを使用してnetcatをインストールします。 netcatは、コマンドラインで呼び出されるとncと省略されることに注意してください。 最後に、socatパッケージを使用してサンプルソケットを作成します。

ストリームソケットとは何ですか?

ストリームソケットはコネクション型です。つまり、ネットワークソケットとの間で送受信されるパケットは、アプリケーションで処理するためにホストオペレーティングシステムによって配信されます。 ネットワークベースのストリームソケットは通常、伝送制御プロトコル(TCP)を使用して、ネットワークインターフェイスを介してデータをカプセル化して送信します。

TCPは、ステートフル接続に依存する信頼性の高いネットワークプロトコルになるように設計されています。 TCPベースのストリームソケットを使用してプログラムによって送信されたデータは、リモートシステムによって正常に受信されます(ルーティング、ファイアウォール、またはその他の接続の問題がないことを前提としています)。 TCPパケットは、物理ネットワークインターフェイスに任意の順序で到着できます。 パケットが順不同で到着した場合、ネットワークアダプタとホストオペレーティングシステムは、アプリケーションで処理するためにパケットが正しい順序で再構築されることを保証します。

TCPベースのストリームソケットの一般的な使用法は、ポート80でHTTPリクエストを処理する、またはポート443でHTTPSを処理するApacheやNginxなどのWebサーバーです。 HTTPの場合、ソケットアドレスは203.0.113.1:80のようになり、HTTPSの場合は203.0.113.1:443のようになります。

TCPベースのストリームソケットの作成

次の例では、socatSOcket CATの略)コマンドを使用して、ポート8080(代替HTTPポート)でHTTP要求をリッスンするWebサーバーをエミュレートします。 次に、ssおよびncコマンドを使用してソケットを調べます。

まず、次のsocatコマンドを実行して、IPv4およびIPv6インターフェイスを使用して、ポート8080で接続をリッスンする2つのTCPベースのソケットを作成します。

socat TCP4-LISTEN:8080,fork /dev/null&
socat TCP6-LISTEN:8080,ipv6only=1,fork /dev/null&
  • TCP4-LISTEN:8080およびTCP6-LISTEN:8080引数は、使用するプロトコルタイプとポート番号です。 socatに、すべてのIPv4およびIPv6インターフェイスのポート8080にTCPソケットを作成し、各ソケットで着信接続をリッスンするように指示します。 socatは、システムで使用可能な任意のポートでリッスンできるため、0から65535までの任意のポートがソケットオプションの有効なパラメーターです。
  • forkオプションは、socatが接続を処理した後も実行を継続するようにするために使用されます。実行しない場合、自動的に終了します。
  • リモートソケットアドレスの代わりに/dev/nullパスが使用されます。 この場合、socatに、着信入力を/dev/nullファイルに出力するように指示します。これにより、入力はサイレントに破棄されます。
  • ipv6only=1フラグは、IPv6ソケットに使用され、ソケットがIPv4にマップされたIPv6アドレスにパケットを送信するように構成されていないことをオペレーティングシステムに通知します。 このフラグがないと、socatはIPv4アドレスとIPv6アドレスの両方にバインドされます。
  • &文字は、コマンドをバックグラウンドで実行するようにシェルに指示します。 このフラグは、ソケットを調べるために他のコマンドを呼び出している間、socatが実行され続けることを保証します。

次のような出力が表示されます。これは、シェルセッションのバックグラウンドで実行されている2つのsocatプロセスIDを示しています。 プロセスIDは、ここで強調表示されているものとは異なります。

Output[1] 434223
[2] 434224

バックグラウンドでTCPポート8080をリッスンする2つのsocatプロセスがあるので、ssおよびncユーティリティを使用してソケットを調べることができます。

TCPベースのストリームソケットの調査

ssコマンドを使用して最新のLinuxシステムでTCPソケットを調べるには、次のフラグを指定してTCPソケットを実行し、出力を制限します。

  • -4フラグと-6フラグは、ssにそれぞれIPv4またはIPv6ソケットのみを検査するように指示します。 このオプションを省略すると、両方のソケットセットが表示されます。
  • tフラグは、出力をTCPソケットに制限します。 デフォルトでは、ssツールは、Linuxシステムで使用されているすべてのタイプのソケットを表示します。
  • lフラグは、出力をリスニングソケットに制限します。 このフラグがないと、SSH、Webサーバーに接続されている可能性のあるクライアント、またはシステムが他のサーバーに接続している可能性のある接続など、すべてのTCP接続が表示されます。
  • nフラグは、サービス名の代わりにポート番号が表示されるようにします。

最初にss -4 -tlnコマンドを実行して、システム上の接続をリッスンしているIPv4TCPベースのソケットを調べます。

ss -4 -tln

次のような出力が表示されます。

OutputState      Recv-Q     Send-Q         Local Address:Port           Peer Address:Port     Process     
. . .
LISTEN     0          1                    0.0.0.0:8080                  0.0.0.0:*
. . .

システムで実行されているサービスによっては、出力に他のポートを持つ他の回線が存在する場合があります。 出力の強調表示された0.0.0.0:8080部分は、IPv4TCPソケットがポート8080で使用可能なすべてのIPv4インターフェイスをリッスンしていることを示します。 特定のIPv4アドレスのみをリッスンしているサービスは、強調表示されたフィールドにそのIPのみを表示します(例:203.0.113.1:8080)。

ここで、同じssコマンドを再度実行しますが、-6フラグを使用します。

ss -6 -tln

次のような出力が表示されます。

OutputState    Recv-Q   Send-Q     Local Address:Port     Peer Address:Port  Process  
. . .
LISTEN   0        5                   [::]:8080               [::]:*
. . .

システムで実行されているサービスによっては、出力に他のポートを持つ他の回線が存在する場合があります。 出力の強調表示された[::]:8080部分は、IPv6TCPソケットがポート8080で使用可能なすべてのIPv6インターフェイスをリッスンしていることを示します(::文字で示されます。これはIPv6表記です。すべてゼロで構成されるアドレス)。 特定のIPv6アドレスのみをリッスンしているサービスでは、強調表示されたフィールドにそのIPのみが表示されます(例:[2604:a880:400:d1::3d3:6001]:8080)。

TCPベースのストリームソケットへの接続

これまで、IPv4インターフェイスとIPv6インターフェイスの両方でTCPソケットを作成および列挙する方法を学習しました。 接続をリッスンする2つのソケットがあるので、netcatユーティリティを使用してソケットへの接続を試すことができます。

netcatを使用してローカルおよびリモートソケットへのTCP接続をテストすることは、システム間の接続とファイアウォールの問題を切り分けるのに役立つ非常に便利なトラブルシューティング手法です。

netcatを使用してローカルループバックアドレスを介してIPv4ソケットに接続するには、次のコマンドを実行します。

nc -4 -vz 127.0.0.1 8080
  • -4フラグは、netcatにIPv4を使用するように指示します。
  • -vフラグは、詳細な出力を端末に出力するために使用されます。
  • -zオプションは、netcatがデータを送信せずにソケットにのみ接続することを保証します。
  • システムには独自の一意のIPアドレスがあるため、ローカルループバック127.0.0.1IPアドレスが使用されます。 システムのIPがわかっている場合は、それを使用してテストすることもできます。 たとえば、システムのパブリックまたはプライベートIPアドレスが203.0.113.1の場合、ループバックIPの代わりにそれを使用できます。

次のような出力が表示されます。

OutputConnection to 127.0.0.1 (127.0.0.1) 8080 port [tcp/http-alt] succeeded!

強調表示されている行は、netcatからの出力です。 これは、netcatがTCPソケットに接続して、ポート8080のループバック127.0.0.1IPv4アドレスをリッスンしていることを示しています。 2行目は無視してかまいません。これは、端末のバックグラウンドで実行されているsocatプロセスからのものです。

これで、同じ接続テストを繰り返すことができますが、IPv6を使用します。 次のnetcatコマンドを実行します。

nc -6 -vz ::1 8080

次のような出力を受け取るはずです。

OutputConnection to ::1 8080 port [tcp/http] succeeded!

強調表示されている行は、netcatからの出力です。 これは、netcatがTCPソケットに接続して、ポート8080のループバック::1IPv6アドレスをリッスンしていることを示しています。 ここでも、出力の2行目を無視できます。

ソケットをクリーンアップするには、作成したsocatプロセスごとにfg(フォアグラウンド)コマンドを実行する必要があります。 次に、CTRL+Cを使用して各socatを閉じます。 fgは、実行した順序とは逆の順序でプロセスを端末のフォアグラウンドに移動します。したがって、プロセスを実行すると、2番目のsocatインスタンスが最初に対話するインスタンスになります。

fgを実行して、2番目のIPv6socatインスタンスを端末のフォアグラウンドに移動します。 次に、CTRL+Cを実行して閉じます。

fg

次のような出力が表示されます。

Outputsocat TCP6-LISTEN:8080,ipv6only=1,fork /dev/null

CTRL+Cを押してプロセスを停止します。

次に、fgを再度実行して、最初のIPv4ソケットをクリーンアップします。 次のような出力が必要です。

Outputsocat TCP4-LISTEN:8080,fork /dev/null

CTRL+Cを押してプロセスを停止します。

これで、システムのIPv4およびIPv6ソケットが作成、調査、および接続されました。 これらの手法とツールは、ローカル開発システムまたはリモート実稼働サーバーで機能するため、各ツールを試して、TCPソケットのテストとトラブルシューティングにどのように使用できるかを理解してください。

データグラムソケットとは何ですか?

データグラムソケットはコネクションレス型です。つまり、ソケットとの間で送受信されるパケットは、アプリケーションによって個別に処理されます。 ネットワークベースのデータグラムソケットは通常、ユーザーデータグラムプロトコル(UDP)を使用してデータをカプセル化および送信します。

UDPはパケットヘッダーのシーケンス情報をエンコードせず、プロトコルに組み込まれているエラー訂正はありません。 データグラムベースのネットワークソケットを使用するプログラムは、データ送信を成功させるために、独自のエラー処理およびデータ順序付けロジックを組み込む必要があります。

UDPソケットは、ドメインネームシステム(DNS)サーバーで一般的に使用されています。 デフォルトでは、DNSサーバーはポート53を使用してドメイン名のクエリを送受信します。 DNSサーバーのUDPソケットアドレスの例は、203.0.113.1:53のようになります。

:プロトコルは人間が読める形式のソケットアドレスには含まれていませんが、オペレーティングシステムは、アドレスの一部としてTCPプロトコルとUDPプロトコルを含めることでソケットアドレスを区別します。 したがって、203.0.113.1:53のような人間が読める形式のソケットアドレスはどちらのプロトコルも使用できます。 ssや古いnetstatユーティリティなどのツールを使用して、使用されているソケットの種類を判別します。


ネットワークタイムプロトコル(NTP)は、ポート123のUDPソケットを使用して、コンピューター間のクロックを同期します。 NTPプロトコルのUDPソケットの例は、203.0.113.1:123です。

データグラムソケットの作成

前のTCPソケットの例と同様に、このセクションでは、socatを再度使用して、UDPポート123で要求をリッスンするNTPサーバーをエミュレートします。 次に、ssおよびncコマンドを使用して作成したソケットを調べます。

まず、次のsocatコマンドを実行して、IPv4およびIPv6インターフェイスを使用して、ポート123で接続をリッスンする2つのUDPソケットを作成します。

sudo socat UDP4-LISTEN:123,fork /dev/null&
sudo socat UDP6-LISTEN:123,ipv6only=1,fork /dev/null&

次のような出力が表示されます。これは、シェルセッションのバックグラウンドで実行されている2つのsocatプロセスIDを示しています。 プロセスIDは、ここで強調表示されているものとは異なります。

Output[1] 465486
[2] 465487
  • ほとんどのシステムではポート0から1024が予約されているため、各コマンドの前にはsudoが付いています。 sudoは、管理者権限でコマンドを実行します。これにより、socatは予約された範囲内の任意のポートにバインドできます。
  • UDP4-LISTEN:123およびUDP6-LISTEN:123引数は、使用するプロトコルタイプとポートです。 それらは、IPv4とIPv6の両方のインターフェースのポート123にUDPベースのソケットを作成し、着信データをリッスンするようにsocatに指示します。 ここでも、0〜65535の全範囲のポートは、UDPソケットの有効なパラメータです。
  • forkipv6only=1、および/dev/null引数は、前のTCPの例で説明したのと同じ方法で使用されます。

UDPポート123でリッスンする2つのsocatプロセスがあるので、ssおよびncユーティリティを使用してソケットを調べることができます。

データグラムソケットの調査

ssコマンドを使用して最新のLinuxシステムでUDPソケットを調べるには、次の-4、-6 , and uln`フラグを指定して実行し、出力を制限します。

uフラグは、出力をUDPソケットに制限します。 その他のフラグは、前のTCPの例で使用されたものと同じです。

最初にss -4 -ulnコマンドを実行して、システムで接続をリッスンしているIPv4UDPソケットを調べます。

ss -4 -uln

次のような出力が表示されます。

OutputState      Recv-Q     Send-Q         Local Address:Port           Peer Address:Port     Process     
. . .
UNCONN   0        0                 0.0.0.0:123            0.0.0.0:*
. . .

システムで実行されているサービスによっては、出力に他のポートを持つ他の回線が存在する場合があります。 出力の強調表示された0.0.0.0:123部分は、IPv4UDPソケットがポート123のすべてのIPv4インターフェイスで使用可能であることを示します。 特定のIPv4アドレスでのみ利用可能なサービスでは、強調表示されたフィールドにそのIPのみが表示されます(例:203.0.113.1:123)。

ここで、同じssコマンドを再度実行しますが、-6フラグを使用します。

ss -6 -uln

次のような出力が表示されます。

OutputState    Recv-Q   Send-Q     Local Address:Port     Peer Address:Port  Process  
. . .
UNCONN   0        0                   [::]:123              [::]:*
. . .

システムで実行されているサービスによっては、出力に他のポートを持つ他の回線が存在する場合があります。 出力の強調表示された[::]:123部分は、IPv6 TCPソケットがポート123のすべてのIPv6インターフェイスで使用可能であることを示します(::文字で示されます)。 特定のIPv6アドレスでのみ利用可能なサービスでは、強調表示されたフィールドにそのIPのみが表示されます(例:[2604:a880:400:d1::3d3:6001]:123)。

データグラムソケットのテスト

IPv4インターフェイスとIPv6インターフェイスの両方でUDPソケットを作成および列挙する方法に精通しているので、それらに接続して実験することができます。 TCPソケットと同様に、netcatユーティリティを使用してUDPソケットを試すことができます。

このチュートリアルの前のセクションで作成したポート123のサンプルUDPソケットに接続するには、次のnetcatコマンドを実行します。

nc -4 -u -vz 127.0.0.1 123
  • -4フラグは、netcatにIPv4を使用するように指示します。
  • -uオプションは、TCPの代わりにUDPを使用するようにnetcatに指示します。
  • -vフラグは、詳細な出力を端末に出力するために使用されます。
  • -zオプションは、netcatがデータを送信せずにソケットにのみ接続することを保証します。
  • システムには独自の一意のIPアドレスがあるため、ローカルループバック127.0.0.1IPアドレスが使用されます。 システムのIPがわかっている場合は、それを使用してテストすることもできます。 たとえば、システムのパブリックまたはプライベートIPアドレスが203.0.113.1の場合、ループバックIPの代わりにそれを使用できます。

次のような出力が表示されます。

OutputConnection to 127.0.0.1 123 port [udp/ntp] succeeded!

出力は、netcatがポート123のループバック127.0.0.1IPv4アドレスをリッスンしているUDPソケットからエラーを受信しなかったことを示しています。 このエラー応答の欠如は、127.0.0.1:123のソケットが使用可能であることを推測するために使用されます。 この動作は、ソケットが使用可能かどうかを確認するためにパケットを交換する必要があるTCPソケットとは異なります。

注:この例のソケットが使用できない場合、リモートシステムはコード3ICMPタイプ3メッセージ(宛先到達不能)を返します。これは、ポートが到達不能であることを示します。リモートホスト。

エラー応答の欠如に基づいてソケットが使用可能であると推測することは、ICMPトラフィックをブロックしているファイアウォールまたは接続の問題がないことを前提としています。 UDPソケットを介してアプリケーションデータを送信、受信、および検証しない限り、リモートUDPポートが開いてパケットを受け入れるという保証はありません。


これで、同じ接続テストを繰り返すことができますが、IPv6を使用します。 次のnetcatコマンドを実行します。

nc -6 -u -vz ::1 123

次のような出力を受け取るはずです。

OutputConnection to ::1 123 port [udp/ntp] succeeded!!

出力は、netcatがポート123のループバック::1IPv6アドレスをリッスンしているUDPソケットからエラーを受信しなかったことを示しています。 この場合も、このエラー応答の欠如は、::1:123のソケットが使用可能であることを推測するために使用されます。

ソケットをクリーンアップするには、作成したsocatプロセスごとにfg(フォアグラウンド)コマンドを実行する必要があります。 次に、CTRL+Cを使用して各socatを閉じます。

fgを実行して、2番目のIPv6socatインスタンスを端末のフォアグラウンドに移動します。 次に、CTRL+Cを実行して閉じます。

fg

次のような出力が表示されます。

Outputsudo socat UDP6-LISTEN:123,ipv6only=1,fork /dev/null

CTRL+Cを押してプロセスを停止します。

次に、fgを再度実行して、最初のIPv4ソケットをクリーンアップします。 次のような出力が得られます。

Outputsudo socat UDP4-LISTEN:123,fork /dev/null

CTRL+Cを押してプロセスを停止します。

これで、システムでIPv4およびIPv6 UDPソケットを作成、調査、およびテストしました。 各ツールを試して、UDPソケットのテストとトラブルシューティングにどのように使用できるかを理解してください。

Unixドメインソケットとは何ですか?

同じサーバー上で実行されるプログラムは、Unixドメインソケット(UDS)を使用して相互に通信することもできます。 Unixドメインソケットは、ストリームベースまたはデータグラムベースにすることができます。 ドメインソケットを使用する場合、データは、ホストファイルシステム上のファイルを介して、オペレーティングシステムのカーネル内のプログラム間で直接交換されます。 ドメインソケットを使用してデータを送受信するには、プログラムはネットワークベースのソケットとプロトコルを完全にバイパスして、共有ソケットファイルの読み取りと書き込みを行います。

Unixドメインソケットは、ネットワークインターフェイスに接続する必要のないデータベースシステムで広く使用されています。 たとえば、Ubuntu上のMySQLは、デフォルトで/var/run/mysqld/mysql.sockという名前のファイルをローカルクライアントとの通信に使用します。 クライアントは、MySQLサーバー自体と同様に、ソケットからの読み取りとソケットへの書き込みを行います。

PostgreSQLは、ローカルの非ネットワーク通信にソケットを使用する別のデータベースシステムです。 通常、デフォルトでは/run/postgresql/.s.PGSQL.5432をソケットファイルとして使用します。

Unixドメインソケットの作成

前のセクションでは、TCPがストリームソケットでどのように使用されるか、およびUDPがデータグラムソケットでどのように使用されるかについて説明しました。 このセクションでは、socatを使用して、TCPまたはUDPを使用してデータをカプセル化してネットワーク経由で送信することなく、ストリームベースとデータグラムベースの両方のUnixドメインソケットを作成します。 次に、ssおよびncコマンドを使用して作成したソケットを調べます。 最後に、netcatを使用したUnixドメインソケットのテストについて学習します。

開始するには、次のsocatコマンドを実行して、2つのソケットファイルを作成します。

socat unix-listen:/tmp/stream.sock,fork /dev/null&
socat unix-recvfrom:/tmp/datagram.sock,fork /dev/null&
  • 最初のコマンドは、unix-listenアドレスタイプを使用してソケットを作成するようにsocatに指示します。これにより、ストリームベースのUDSが作成されます。
  • 2番目のコマンドは、ソケットタイプとしてunix-recvfromを指定します。これにより、データグラムベースのUDSが作成されます。
  • どちらのコマンドも、:区切り文字の後にファイル名を指定します。 ファイル名は、ソケット自体のアドレスです。 最初のストリームの例では/tmp/stream.sockであり、2番目のデータグラムの例では/tmp/datagram.sockです。 ソケットの名前は任意ですが、トラブルシューティングの際にわかりやすい名前にするのに役立ちます。
  • fork、および/dev/null引数は、ストリームおよびデータグラムソケットの例のセクションで説明されているのと同じ方法で使用されます。

2つのUDSソケットを作成したので、ssおよびncユーティリティを使用してそれらを調べることができます。

Unixドメインソケットの調査

リスニングしているすべてのUnixドメインソケットを一覧表示するには、ss -xlnコマンドを実行します。 xフラグは、ドメインソケットのみが表示されるようにします。

ss -xln

次のような出力が表示されます。

OutputNetid State  Recv-Q Send-Q      Local Address:Port   Peer Address:Port  Process
. . .
u_str LISTEN 0      5        /tmp/stream.sock 436470            * 0             
u_dgr UNCONN 0      0      /tmp/datagram.sock 433843            * 0
 . . .

/tmp/stream/sock行の強調表示されたu_str部分に注目してください。 このフィールドは、ソケットタイプがストリームベースのUDSであることを示します。 2行目は、タイプがu_dgrであることを示しています。これは、ソケットタイプがデータグラムベースであることを意味します。

Unixドメインソケットはファイルであるため、通常のLinuxユーザーおよびグループのアクセス許可とアクセス制御を使用して、ソケットに接続できるユーザーを制限できます。 lsmvchownchmodなどのファイルシステムツールを使用して、UDSファイルを調べたり操作したりすることもできます。 SELinuxなどのツールを使用して、UDSファイルにさまざまなセキュリティコンテキストでラベルを付けることもできます。

ファイルがUDSソケットであるかどうかを確認するには、lsfile、またはstatユーティリティを使用します。 ただし、これらのツールはいずれも、UDSがストリームベースかデータグラムベースかを判断できないことに注意してください。 Unixドメインソケットに関する最も完全な情報については、ssツールを使用してください。

ファイルシステム上のソケットを調べるために、statユーティリティは最も関連性の高い情報を表示します。 以前に作成したソケットで実行します。

stat /tmp/stream.sock /tmp/datagram.sock

次のような出力が表示されます。

Output  File: /tmp/stream.sock
  Size: 0             Blocks: 1          IO Block: 131072 socket
Device: 48h/72d    Inode: 1742        Links: 1
Access: (0755/srwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-03-01 18:10:25.025755168 +0000
Modify: 2021-03-01 18:10:25.025755168 +0000
Change: 2021-03-01 18:22:42.678231700 +0000
 Birth: -
  File: /tmp/datagram.sock
  Size: 0             Blocks: 1          IO Block: 131072 socket
Device: 48h/72d    Inode: 1743        Links: 1
Access: (0755/srwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-03-01 18:10:25.025755168 +0000
Modify: 2021-03-01 18:10:25.025755168 +0000
Change: 2021-03-01 18:10:25.025755168 +0000
 Birth: -

各ファイルのタイプはsocket(出力の右端で強調表示)であり、アクセスモードにはファイルのアクセス許可の前にs文字があることに注意してください。

lsユーティリティは、ファイルがソケットであるかどうかも示します。 ls -lを実行して、ファイルを調べます。

ls -l /tmp/stream.sock /tmp/datagram.sock

次のような出力が表示されます。 ソケットの場合、ファイルモードでは、ファイルのアクセス許可フィールドの前にs文字が含まれていることに注意してください。

Outputsrwxr-xr-x 1 root root 0 Mar  1 18:10 /tmp/datagram.sock
srwxr-xr-x 1 root root 0 Mar  1 18:10 /tmp/stream.sock

Unixドメインソケットを作成し、ssおよびさまざまなファイルシステムベースのツールを使用してそれらを調べる方法を学習したので、次のステップは、netcatなどのツールを使用してソケットをテストすることです。

Unixドメインソケットのテスト

netcatユーティリティを使用して、Unixドメインソケット、およびこのチュートリアルの前半ですでに学習したTCPおよびUDPソケットに接続できます。 作成したサンプルソケットに接続するには、netcatコマンドを実行するときに追加の-Uフラグを指定する必要があります。 このフラグは、TCPまたはUDPベースのネットワークソケットではなく、UDSに接続するようにnetcatに指示します。

さらに、ソケットがデータグラムベースの場合は、-uフラグを使用して、このチュートリアルの「データグラムソケット」セクションで学習したデータグラムを使用するようにnetcatに指示します。

次のコマンドを使用してストリームベースのソケットに接続することにより、UDSソケットの調査を開始しましょう。

nc -U -z /tmp/stream.sock

-Uは、Unixドメインソケットに接続していることをnetcatに通知します。 -zオプションは、netcatがデータを送信せずにソケットにのみ接続することを保証します。 /tmp/stream.sockは、ファイルシステム上のソケットのアドレスです。

コマンドを実行しても、netcatからの出力はありません。 ただし、ソケットが使用できない場合、netcatは次のようなエラーメッセージを出力します。

Outputnc: unix connect failed: No such file or directory
nc: /tmp/stream.sock: No such file or directory

したがって、ストリームベースのUDSソケットをテストするときにnetcatからの出力がないということは、接続が成功したことを意味します。

今回はデータグラムベースのUDSについて、テストプロセスを繰り返します。

nc -uU -z /tmp/datagram.sock

追加の-uフラグが追加され、リモートソケットがデータグラムソケットであることをnetcatに通知します。 この場合も、テストが成功した場合、出力は送信されません。

アドレスにソケットがない場合は、次のようなエラーが発生します。

Outputnc: unix connect failed: No such file or directory
nc: /tmp/datagram.sock: No such file or directory

ソケットをクリーンアップするには、作成したsocatプロセスごとにfg(フォアグラウンド)コマンドを実行する必要があります。 次に、CTRL+Cを使用して各socatを閉じます。

fgを実行して、データグラムベースのsocatインスタンスを端末のフォアグラウンドに移動します。

fg

次のような出力が表示されます。

Outputsocat unix-recvfrom:/tmp/datagram.sock,fork /dev/null

CTRL+Cを実行して閉じます。 出力は受信されません。

次に、fgを再度実行して、最初のストリームベースのUDSソケットをクリーンアップします。

ここでも、次のような出力が必要です。

Outputsocat unix-listen:/tmp/stream.sock,fork /dev/null

CTRL+Cを実行してプロセスを終了します。 出力は受信されません。

これで、システム上でUnixデータグラムソケットソケットを作成、調査、およびテストしました。 netcatとsocatを試して、UDSを介してデータを送受信する方法、およびUnixドメインソケットをテストおよびトラブルシューティングする方法をよく理解してください。

結論

このチュートリアルでは、Linuxシステムでさまざまな種類のソケットがどのように使用されるかを調べました。 通常、ネットワーク通信にTCPを使用するストリームベースのソケットについて学習しました。 また、UDPを使用してネットワーク経由でデータを送信するデータグラムベースのソケットについても学びました。 最後に、Unixドメインソケットをローカルサーバーに基づいてストリームまたはデータグラムベースにする方法を検討しました。

各セクションでは、ssユーティリティを使用して、Linuxシステムのソケットに関する情報を収集しました。 ssツールが提供するさまざまなフラグが、システム上のソケットを調べるときに、出力を特定のタイプのソケットに制限するのにどのように役立つかを学びました。

最後に、netcatおよびsocatツールを使用して、このチュートリアルで説明した3つの異なるタイプのソケットのそれぞれを作成して接続しました。 netcatユーティリティは、ソケットへの接続に広く使用されていますが、ソケットを作成することもできます。 そのドキュメント(man nc)には、どちらのモードでも使用できる方法の例が多数含まれています。 socatユーティリティは、このチュートリアルでカバーされていないさまざまな種類のソケットに接続するために使用できる、より高度なツールです。 そのドキュメント(man socat)には、さまざまな使用方法の例も多数含まれています。

ソケットとは何か、およびソケットがどのように機能するかを理解することは、コアシステム管理スキルです。 このチュートリアルで実験したツールと手法は、ソケットについて理解を深め、サーバーとアプリケーションが相互に正しく通信していない場合にソケットのトラブルシューティングを行う方法を理解するのに役立ちます。