27

Python から何かを ping (ICMP) するための最良の方法を見つけようとしているときに、次の質問に出くわしました。

答えは通常、「このサードパーティモジュールをルート権限で使用する」または「システムのpingコマンドを使用して出力を解析する」に要約されます。ネイティブ メソッドのうち、icmplibM. Cowles と J. Diemer の ping.pyは、 scapy マニュアルと同様に、root 権限の必要性を明示的に述べています。

そのため、特別な権限なしで ICMP ping をネイティブに送信することは不可能に思えます。システムの ping コマンドは何とか管理できますが、そのマニュアル ページにはその方法が説明されていません。一方、 icmpのマニュアルページには、可能であると書かれているようです:

非特権 ICMP
     ICMP ソケットは、SOCK_DGRAM ソケット タイプを使用せずに開くことができます。
     root 権限が必要です。あらすじは次のとおりです。

     ソケット(AF_INET、SOCK_DGRAM、IPPROTO_ICMP)

     データグラム指向の ICMP ソケットは、利用可能な機能のサブセットを提供します。
     ICMP ソケットを raw することができます。以下の IMCP 要求メッセージのみ
     次のタイプを送信できます: ICMP_ECHO、ICMP_TSTAMP、または ICMP_MASKREQ。

したがって、少なくとも icmp によれば、許可されているように見えます。では、すべての python ツールがこれを実行できないのはなぜでしょうか? Python ツールは一般的すぎて、特権ソケットでの作業が特権を持つことを期待していますか? root権限なしでpingできるping関数をCで書いて、これでpythonを拡張することは可能でしょうか? 誰かがこれをしましたか?問題を誤解しただけですか?

4

9 に答える 9

14

ping プログラムは setuid root にインストールされます。これにより、すべてのユーザーがプログラムを使用でき、生のソケットを開くことができます。

raw ソケットを開いた後、通常はルート権限を削除します。

通常、ICMP を正しく実行するには raw ソケットが必要であり、raw ソケットは通常制限されています。したがって、実際には python のせいではありません。

上記の ICMP に関するちょっとしたことですが、どうやら多くの実装では、これらのフラグの組み合わせをうまくサポートしていないようです。したがって、ほとんどの実装は、ほとんど/すべてのアーキテクチャで機能することを「知っている」方法を使用する可能性があります。

于 2009-07-27T17:17:25.417 に答える
12

/sbin/ping が「何とか管理」する方法は次のとおりです (ほとんどの Unix-y システムで):

$ ls -l /sbin/ping
-r-sr-xr-x  1 root  wheel  68448 Jan 26 10:00 /sbin/ping

見る?これはsetuseridによって所有されており、パーミッションにroot重要な部分があります。sしたがって、どのユーザーが実行していても、pingは root として実行されます。

新しい「非特権 ICMP ソケット」を備えた BSD カーネルを使用している場合、その機能を使用して Python から ping を実行するために何が必要かを確認するのは興味深いでしょう (ただし、高度でないカーネルを使用しているユーザーには役に立ちません。もちろん)。

于 2009-07-27T17:18:06.460 に答える
5

少し前に既に回答済みのような質問に何かを投稿してよいかどうかわかりません。

私は同じ実装を探していて、root 以外の権限で Python 経由で ICMP を実行する方法を見つけました。

python-ping同じ 'need-root' の方法を使用して ping を実行しますが、ユーザーが呼び出し時に次のように変更SOCK_RAWすることを提案したというバグ レポートに遭遇しました。SOCK_DGRAMsock

http://hg.io/delroth/python-ping/issue/1/icmp-without-root-privilege

開発者は、これはむしろ UDP ping であるため、「WONT-FIX」の状況になると説明しています。

ICMP が UDP 経由で送信されるかどうかは気にしないので、先に進んでコードを取得し、提案された変更を行いました。

サブプロセスを呼び出したり、root を必要とせずに ping を実行できるようになりました。

繰り返しますが、こんなに長い間ここに投稿しても大丈夫かどうかはわかりませんが、これは良いことだと思いました!

于 2010-08-05T12:40:24.647 に答える
5

最新の Linux の ping は libcap を使用し、libcap に作業を依頼します。

linux@jacax:~/WORK$ ldd /bin/ping  
    linux-gate.so.1 =>  (0xb77b6000)  
    libcap.so.2 => /lib/i386-linux-gnu/libcap.so.2 (0xb7796000)  
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75e7000)  
    /lib/ld-linux.so.2 (0xb77b7000)   

「myping」プログラムがあるとしましょう:

linux@jacax:~/WORK$ getcap ./myping    
linux@jacax:~/WORK$   (-> nothing! )  
linux@jacax:~/WORK$ setcap cap_net_raw=ep ./myping  
unable to set CAP_SETFCAP effective capability: Operation not permitted  
linux@jacax:~/WORK$ sudo setcap cap_net_raw=ep ./myping  

今行う:

linux@jacax:~/WORK$ getcap ./myping  
./ping = cap_net_raw+ep

これで、「myping」はルートなしで機能します。mypingつまり、実際にバイナリ プログラムである限り。スクリプトの場合、代わりにこの機能をスクリプト インタープリターで設定する必要があります。

于 2014-11-21T10:30:35.080 に答える
1

実際、Windows 7およびVistaでは、次のことを行うために「管理者として実行」する必要があります。

my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)

お気づきのように、データグラムソケットを介して実行するとエラーが発生します。

于 2011-04-06T19:51:46.907 に答える
-1

また、サブプロセスを使用せず、ping に root を必要としない ping の実装も探していました。私のソリューションはクロスプラットフォーム、つまり Windows と Linux である必要がありました。

Windows のソケットを SOCK_DGRAM に変更すると、「protocol not supported 100043」例外が発生します。したがって、Windows は、icmp が UDP ではなく TCP で送信されているかどうかを正しくチェックしているようです。ただし、Windows は Linux の概念であるため、「ルート」として実行されているかどうかは気にしません。

if os.name == 'nt':
    #no root on windows
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
else:
    #changed to UDP socket...gets around ROOT priv issue
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, icmp)
于 2011-03-19T13:18:43.443 に答える
-9

私はWindows 7でpythonを実行しています。Eclipse pydevプラグインでコードを編集および「コンパイル」しているため、私の解決策は次のとおりです。管理者としてeclipse.exeを実行する:これで問題が解決しました。

この解決策は、管理者として cmd を実行するのと似ています。

于 2011-06-08T15:18:33.210 に答える