PHPを使用したプログラミングネットワークの場合、 socket_set_optionは非常に重要な機能であり、開発者がさまざまな通信ニーズを満たすためにソケットのさまざまなオプションを設定できるようにします。ただし、実際の開発では、この関数を使用してソケットオプションを設定する場合、特にサーバー環境やローカル開発中に許可関連エラーが発生することがよくあります。この記事では、これらの一般的な許可エラーを分析し、対応するソリューションを提供します。
これは最も一般的な間違いの1つです。エラーコード[13]は、「許可を拒否する」を意味します。つまり、許可は拒否されます。これは通常、 SO_BROADCASTやSO_REUSEPORTなどのシステムで保護されたソケットオプションを設定しようとするときに発生します。
元のソケットにIP_Hdrinclなどのオプションを設定しようとする場合、スクリプトに十分な権限がない場合(たとえば、ルートとして実行されていない)、システムによって禁止されます。
セキュリティモジュール(SelinuxやApparmorなど)を有効にし、十分なシステム許可を持つ厳格な構成を備えたシステムでは、ポリシーの制限によりいくつかのソケットオプションが設定されない場合があります。
PHP-FPMまたはCLIを非プリビルドユーザーとして実行する:デフォルトでは、Webサーバー(Nginx、Apacheなど)またはCLI PHPプログラムは通常、非ルートユーザーとして実行されるため、高度な権限を必要とする特定のオプションを設定しようとすると失敗します。
制限付きポートまたはブロードキャストにバインドするアドレス: so_broadcastなどのポートを使用したり、1024未満のポートにバインディングしたりする場合、オペレーティングシステムは非ルートユーザーが使用を制限する場合があります。
Dockerまたは制限付きコンテナ環境で実行する:コンテナ化されたPHPプログラムは、権限が正しく構成されていない場合、そのようなエラーに遭遇する場合があります。
受け入れられる場合は、スクリプトを実行する権限を増やすことで解決できます。
sudo php your_script.php
または、特定のユーザーがルート特権を使用してPHPを実行できるようにWebサービスを構成しますが、このプラクティスはセキュリティリスクをもたらし、生産環境では推奨されません。
CLIスクリプトの場合、特定のユーザーがパスワードを入力せずにルートアクセスを使用して特定のPHPスクリプトを実行できるように/etc /sudoersを構成できます。
username ALL=(ALL) NOPASSWD: /usr/bin/php /path/to/your_script.php
元のパケットを送信する必要があるソケット操作の場合、PHP実行可能ファイルに必要なアクセス許可を与えることができます。
sudo setcap cap_net_raw+ep /usr/bin/php
このようにして、PHPスクリプト全体をルートとして実行する必要はありませんが、必要なソケット操作を実行できます。
SelinuxまたはApparmorが有効になっているシステムの場合、セキュリティポリシーがソケットの特定の操作をブロックするかどうかを確認します。次のコマンドに従って、selinuxログを確認できます。
sudo ausearch -m avc -ts recent
Apparmorの場合、 /var/log/syslogで関連する制限付きログを表示する必要があります。
たとえば、ルート許可の必要性を回避するために、サービスポートを1024以上に調整します。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 12345); // 非実力ポートを使用します
たとえば、ソケット設定が必要ない場合があります。たとえば、 SO_BROADCASTはUDPブロードキャストにのみ使用されます。これは、TCP接続では完全に無視できます。
socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1); // 本当に必要な場合にのみ設定します
許可関連エラーのトラブルシューティングの場合、詳細なエラーログ出力を有効にすることをお勧めします。
error_reporting(E_ALL);
ini_set('display_errors', 1);
システムログ( /var/log/syslog、/var/log/php-fpm.logなど)を組み合わせて、より多くのコンテキスト情報を取得します。
さらに、コードにデバッグ情報を追加することにより、問題の検索を支援できます。
if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
echo "Set option failed: " . socket_strerror(socket_last_error($socket)) . PHP_EOL;
}
通常、一般的な許可エラーは、ソケット構成にsocket_set_optionを使用する場合、システム許可、セキュリティポリシーの制限、または誤ったパラメーター設定によって引き起こされます。このタイプの問題は、実行許可の改善、システムセキュリティポリシーの構成、またはソケットの使用の最適化により、効果的に回避および解決できます。
生産環境では、ルートアクセスの使用にPHPスクリプトを実行しないようにしますが、代わりに、セキュリティと機能性のバランスを確保するために、より細かい粒状許可制御( SETCAPや特別なシステムユーザー許可設定など)を介して必要な機能を実装してください。実際のプロジェクトでブロードキャストまたはローポートのバインディングコミュニケーションを実装する場合は、 https://gitbox.net/docs/php-socket-broadcastのサンプルコードと実際の経験を参照できます。