PHPを使用してFTPを操作する過程で、 FTP_SITE()は物議を醸す関数です。開発者は、サイトコマンドをFTPサーバーに送信できるため、アクセス許可の設定、ディレクトリプロパティの変更、特定のサーバー拡張機能機能の有効化またはオフなどのサーバー固有の操作を実行できます。ただし、 FTP_SITE()の動作を異なるサーバーでgaleで異なるようにするのはこの「自由度」です。この記事では、この現象の根本原因を詳細に分析し、開発者がこの予測不可能な行動にどのように対処するかを調査します。
FTPプロトコルはRFC 959で定義され、サイトコマンドは「拡張コマンド」として分類され、その動作と構文はRFCの必須仕様内ではありません。これはつまり:
各FTPサーバーソフトウェア(Proftpd、vsftpd、pure-ftpd、filezillaサーバーなど)は、自分の裁量でサイトコマンドをサポートするかどうかを決定できます。
たとえサポートされていても、それが受け入れるサイトのサブコマンドは大きく異なる場合があります。
サイトのサブコマンド名が同じであっても、パラメーターの解釈と実行効果が異なる場合があります。
たとえば、一部のサーバーはサポートしています。
ftp_site($ftp_conn, "CHMOD 755 /public_html/index.php");
他のサーバーは、500の不明なサイトコマンドを返します。 CHMODサブコマンドへのエラー。別の例:
ftp_site($ftp_conn, "UTIME /file.txt 20240607080000");
このコマンドは、一部のサーバー(対応するモジュールを含むProftpdなど)のタイムスタンプの更新を正常に更新する場合がありますが、他のほとんどのFTPサービスで完全に無効または直接報告されています。
ターゲットサーバーでサイトサブコマンドがサポートされている場合でも、実行許可は常に接続されたユーザーに与えられているわけではありません。サイトコマンドは、多くのサーバー構成でデフォルトで無効にされます。または、特定のサブコマンドを実行することが許可されている場合、特定のユーザーのみが許可されます。たとえば、一部のサーバーは次のことさえサポートしています。
ftp_site($ftp_conn, "SYMLINK /target /link");
550の許可のようなエラーが拒否されました。許可が不十分なため、返品される場合もあります。これは、同じPHPスクリプトが異なるサーバーまたはユーザーで実行されることを意味し、結果が大きく異なる場合があります。
FTPサーバーソフトウェアの違いは、FTP_SITE()の一貫性のない動作の重要な理由でもあります。いくつかの一般的なソフトウェアのパフォーマンスの違いは次のとおりです。
PROFTPD :特にmod_site_execを有効にした後、豊富なサイトコマンドをサポートします。非常に強力な機能を備えています。
VSFTPD :サイトコマンドのサポートは非常に限られており、デフォルトではステータス以外のサイトコマンドには応答しません。
Pure-FTPD :限られたサイトコマンドをサポートしており、ほとんどの場合、構成ファイルで明示的に有効にする必要があります。
FileZilla Server :一部のサイトコマンドが実装されていますが、コマンドセットは小さく、ドキュメントは不完全です。
Windows IIS FTP :サイトサポートはほぼゼロであり、ほとんどのコマンドは直接無視されます。
さまざまな実装の背後にある設計哲学は異なります。セキュリティと最低限の権限の原則を追求するものもあれば、機能と柔軟性のためにより多くのインターフェイスを開くものもあります。
FTP_SITE()の広範な不確実性のため、使用する場合は特に注意する必要があります。ここにいくつかの提案があります:
サイトコマンドに依存して重要な操作を完了することは避けてください。ターゲットサーバーのタイプ、バージョン、および構成が完全に制御されていることを確認できない限り。
代わりに標準のFTP操作を使用します。たとえば、PHPのFTP_CHMOD()は下部にサイトCHMODを使用する場合がありますが、この関数は互換性の問題を処理します。
検出前のサポート機能:関数は、特定のサイトコマンドを送信し、スクリプトが実行される前にリターンステータスをキャプチャするように設計できます。例えば:
function site_command_supported($conn, $command) {
$result = @ftp_site($conn, $command);
return $result !== false;
}
サーバーの種類を記録して区別します。次のようなさまざまなFTPサーバーによって返される歓迎情報を解析します。
$welcome = ftp_raw($conn, "SYST");
// サーバータイプを分析します,それを使用するかどうかを決定します SITE 注文
文書化されたサーバーの動作:エンタープライズレベルの展開では、各サーバーは、ブラインドコールを避けるために共通のサイトコマンドのサポートを記録する必要があります。
FTP_SITE()は、強力だが危険なツールです。 FTPプロトコル設計におけるサーバーの「動作定義」に対する自由放任主義の態度を明らかにし、今日のネットワークプログラミングにおける「クロスプラットフォームの一貫性」の中心的な問題を明らかにします。実際の開発では、動作環境の完全な制御を維持できない限り、行動が不確実な機能に依存することを避けるように努めるべきです。
サイトコマンドを使用する必要がある場合は、統一されたサーバー側の展開仕様を介して差を軽減するか、FTPネイティブコマンドをコントロールパネル/APIなどの最新の方法に置き換えることをお勧めします。結局のところ、 FTP_SITE($ conn、 "exec /usr/local/bin/backup.sh")のような一見シンプルな操作。動作が定義されていない場合、セキュリティ監査であろうとトラブルシューティングであろうと、システムメンテナーにとって悪夢になります。
完全な例については、次のことを参照してください。
$ftp_conn = ftp_connect("ftp.gitbox.net");
ftp_login($ftp_conn, "username", "password");
ftp_site($ftp_conn, "CHMOD 755 /public_html/test.php");
ftp_close($ftp_conn);
FTP.gitbox.netのFTPサービスを完全に制御できる場合にのみ、上記のコードを自信を持って使用できます。それ以外の場合は、エラーキャプチャおよびロギングメカニズムを追加することを忘れないでください。