2009-07-27 12 views
17

Trong khi cố gắng tìm ra phương pháp tốt nhất để ping (ICMP) một cái gì đó từ trăn, tôi tình cờ gặp những câu hỏi này:trăn không có đặc quyền ICMP

Các câu trả lời thường đun sôi xuống để "sử dụng mô-đun bên thứ ba này với quyền root" hoặc "sử dụng lệnh ping của hệ thống và phân tích đầu ra". Trong số các phương thức gốc, icmplibM. Cowles and J. Diemer's ping.py đề cập rõ ràng nhu cầu về các đặc quyền gốc, cũng như scapymanual.

Vì vậy, từ mặt trước đó, việc gửi ping ICMP nguyên bản mà không có đặc quyền đặc biệt có vẻ là không thể. Lệnh ping hệ thống không quản lý bằng cách nào đó, nhưng trang người dùng của nó không làm sáng tỏ cách thực hiện. Các man page for icmp, mặt khác, dường như để nói nó có thể:

 
Non-privileged ICMP 
    ICMP sockets can be opened with the SOCK_DGRAM socket type without 
    requiring root privileges. The synopsis is the following: 

    socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP) 

    Datagram oriented ICMP sockets offer a subset of the functionality avail- 
    able to raw ICMP sockets. Only IMCP request messages of the following 
    types can be sent: ICMP_ECHO, ICMP_TSTAMP or ICMP_MASKREQ.

Vì vậy, nó sẽ có vẻ rằng, ít nhất là theo icmp, nó cho phép. Vậy tại sao tất cả các công cụ python lại không thể thực hiện được điều này? Là các công cụ python quá chung chung và mong đợi bất kỳ công việc trên ổ cắm đặc quyền để được đặc quyền? Nó sẽ có thể viết một chức năng ping trong C có thể ping mà không có quyền root, và mở rộng python với điều này? Có ai đã làm điều này không? Tôi vừa hiểu nhầm vấn đề chưa?

+0

Bạn đang sử dụng hệ điều hành nào? [Hạt nhân Linux gần đây] (https://lkml.org/lkml/2011/5/10/389) và Mac OS X được biết là có ổ cắm ICMP không có đặc quyền. Trang người dùng bạn tìm thấy là từ OS X và nó sẽ hoạt động. Tôi đã thành công với chương trình [ping program] không có đặc quyền (Python) (https://github.com/lilydjwg/winterpy/blob/master/pylib/icmplib.py) hoạt động trên Linux (với thay đổi cài đặt hạt nhân) nhưng có thể cần một số điều chỉnh trên OS X. – lilydjwg

+0

Đối với Linuix, xem tại đây http://stackoverflow.com/questions/8290046/icmp-sockets-linux/20105379#20105379, bạn cần một sysctl đặc biệt để có thể sử dụng 'socket (AF_INET, SOCK_DGRAM, IPPROTO_ICMP) ' – nos

Trả lời

11

Chương trình ping được cài đặt root setuid. Điều này cho phép bất kỳ người dùng nào sử dụng chương trình và vẫn có thể mở một ổ cắm thô.

Sau khi mở ổ cắm thô, thông thường nó sẽ làm giảm các máy chủ riêng.

Bạn thường cần một ổ cắm thô để thực hiện chính xác ICMP và ổ cắm thô thường bị hạn chế. Vì vậy, nó không thực sự là lỗi của python cả.

Về bit về ICMP ở trên, dường như nhiều triển khai thực sự không thực sự hỗ trợ các kết hợp cờ đó tốt. Vì vậy, có khả năng hầu hết các implmentations chỉ sử dụng cách mà chúng "biết" hoạt động trên hầu hết/tất cả các kiến ​​trúc.

+0

Ah, đó là một bí ẩn ít hơn - kể từ khoảng thời gian ngắn trên ping vẫn yêu cầu sudo, tôi không nghĩ rằng nó đã có setuid gốc, nhưng bạn rõ ràng đúng về điều đó. – Markus

+0

Ping không nhất thiết phải sử dụng đầu dò ICMP, cũng không phải ổ cắm thô và cũng không cần quyền root. –

11

Sau đây là cách/sbin/ping "bằng cách nào đó quản lý" (trên hầu hết các hệ thống Unix-y):

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

Thấy không? Nó thuộc sở hữu của root và có bit quan trọng s trong quyền - setuserid. Vì vậy, bất kể người dùng nào đang chạy nó, hãy ping chạy dưới dạng gốc.

Nếu bạn đang sử dụng hạt nhân BSD với "ổ cắm ICMP không có đặc quyền" mới, bạn sẽ thấy thú vị khi sử dụng chức năng đó để ping từ Python (nhưng điều đó sẽ không giúp bất kỳ người dùng nào hạt nhân ít nâng cao, tất nhiên).

+0

Ổ cắm ICMP không có đặc quyền thú vị là mới? Có lẽ tôi sẽ cố gắng để có được rằng làm việc từ python khi tôi có một thời gian, chủ yếu là ra khỏi tò mò. – Markus

+0

Không phải tất cả những gì mới ** như là một đặc tả ** (Tôi tin rằng nó đi tất cả các cách trở lại tốt đẹp cũ BSD 4.3! -), nhưng thực hiện _working_ spec đó sẽ là khá mới (và rất tốt tin tức thực sự, IMHO). –

0

Tôi không chắc liệu có thể đăng nội dung nào đó trong câu hỏi có vẻ như nó đã được trả lời cách đây không lâu.

Tôi đã tìm kiếm cách triển khai tương tự và tìm cách làm ICMP qua Python với các đặc quyền không phải root.

python-ping sử dụng cùng một 'cần-root' cách để làm một ping, nhưng tình cờ đọc một báo cáo lỗi mà người dùng đề nghị thay đổi SOCK_RAW để SOCK_DGRAM khi gọi sock:

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

Các dev giải thích điều này sẽ là một tình huống "WONT-FIX" vì nó là một ping UDP.

Vì tôi thực sự không quan tâm nếu ICMP thực hiện qua UDP, tôi đã tiếp tục và nhận mã và thực hiện đề xuất đã thay đổi.

Tôi hiện có thể thực hiện lệnh ping mà không cần gọi tiến trình con hoặc cần root!

Một lần nữa, không chắc chắn nếu đăng bài ở đây sau một thời gian dài như vậy là OK, nhưng nghĩ rằng đây là một điều tốt hơn!

+0

Đó là một cách tiếp cận thú vị. Nên làm việc tốt, nhưng nghiêm túc nói, nó không phải là một ping nữa. Điều đó có nghĩa là tường lửa và các bức tường lửa có xử lý ping đặc biệt có thể sẽ hoạt động khác nhau. – DonGar

+3

Cách tiếp cận đó không có tác dụng gì cả. Bạn không thể tạo ổ cắm kiểu UDP với giao thức ICMP. Tôi nhận được EPROTONOSUPPORT (Giao thức không được hỗ trợ). - Lý do rất đơn giản: sự kết hợp giao thức như vậy không tồn tại. (Thử nghiệm đáp ứng có thể không được hỗ trợ với UDP/TCP, nhưng cần thêm những thay đổi tinh tế như thế này.) –

-2

Tôi cũng đang tìm cách triển khai ping mà không cần sử dụng tiến trình con hoặc cần root để ping. Giải pháp của tôi cần phải là nền tảng chéo, cụ thể là Windows và Linux.

Thay đổi socket trên Windows thành SOCK_DGRAM dẫn đến ngoại lệ "giao thức không được hỗ trợ 100043". Vì vậy, có vẻ như Windows kiểm tra chính xác để xem nếu icmp đang được gửi ra trên TCP chứ không phải là UDP. Tuy nhiên, các cửa sổ không quan tâm nếu nó đang chạy như là "root" vì đó là một khái niệm 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) 
1

Trên thực tế, trên Windows 7 và Vista, bạn cần phải 'Run as Administrator' để làm:

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

và như bạn lưu ý, thực hiện nó trên một ổ cắm datagram gây ra một lỗi.

-8

Tôi đang chạy python dưới cửa sổ 7, Kể từ khi tôi đang chỉnh sửa và "biên soạn" mã dưới Eclipse Plugin PyDev, Giải pháp của tôi là: Chạy eclipse.exe như một quản trị viên: này đã giải quyết được vấn đề,

Giải pháp này tương tự như chạy cmd với tư cách quản trị viên.

+8

Vui lòng không đề nghị mọi người chạy các chương trình tùy ý với tư cách Quản trị viên. Đó là cách mà UAC có một bài rap tồi tệ ngay từ đầu. Câu trả lời của bạn cũng không giúp cho một chương trình được triển khai vào sản xuất. – AdmiralNemo

0

Trang người dùng bạn đang đọc nói về "BSD Kernel Interfaces Manual" và dường như đến từ "Mac OS X 10.9". Tôi không có một máy Mac OS X để cố gắng, nhưng trong Linux, như là người chủ hoặc là người dùng tôi nhận được một lỗi cho phép từ chối khi tôi cố gắng để mở như một ICMP:

$ strace -e trace=socket python 
Python 2.7.5+ (default, Sep 19 2013, 13:48:49) 
[GCC 4.8.1] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import socket 
>>> socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_ICMP) 
socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP) = -1 EACCES (Permission denied) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.7/socket.py", line 187, in __init__ 
    _sock = _realsocket(family, type, proto) 
socket.error: [Errno 13] Permission denied 

Dưới OpenBSD tôi nhận được một "Nghị định thư không được hỗ trợ" lỗi:

>>> import socket 
>>> socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_ICMP) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/socket.py", line 187, in __init__ 
    _sock = _realsocket(family, type, proto) 
socket.error: [Errno 43] Protocol not supported 

có thể ai đó có thể thử dưới hệ điều hành MacOS X hoặc BSDs khác, nhưng dù sao loại ổ cắm này không giống như di động, để nói rằng ít nhất!

+0

Bạn đang làm sai, các tin nhắn ICMP được lấy bởi ổ cắm DGRAM dưới dạng thông báo lỗi. Chỉ định ICMP làm giao thức socket trên DGRAM là sai. –

+0

Tôi làm những gì OP đã làm ... và yêu cầu. – Pierre

3

Ping Linux hiện đại sử dụng libcap và yêu cầu libcap thực hiện công việc.kiểm tra này (capget/bộ funcitons) và quản lý quyền:

[email protected]:~/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) 

phép nói rằng bạn có một "myping" chương trình:

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

Bây giờ làm:

[email protected]:~/WORK$ getcap ./myping 
./ping = cap_net_raw+ep 

Bây giờ, bạn " myping "sẽ hoạt động mà không cần root. Tức là, miễn là myping thực ra là một chương trình nhị phân. Nếu đó là một tập lệnh, khả năng này phải được đặt trên trình thông dịch kịch bản lệnh thay thế.

+0

điểm tuyệt vời, tôi gần như tuyệt vọng mà không ai đề cập đến khả năng. Tuy nhiên, nó phải được lưu ý rằng nếu "chương trình" của bạn là một kịch bản, khả năng phải được đặt trong trình thông dịch kịch bản chứ không phải là tập lệnh. – 0xC0000022L