0

I try to use socket_create ICMP to ping Ip read data or not,In Windows10 works,but CentOS7 not working, The error message is "socket_create(): Unable to create socket [1]: Operation not permitted", And I also check phpinfo() enable sockets in CentOS7, Is this problem about root permissions? How can I fix it...

I try to use chmod -R 4777 /var/www/html/MyWeb but still not working

/* ICMP ping packet with a pre-calculated checksum */
    $package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
    $icmp = getprotobyname("icmp");

    $socket = socket_create(AF_INET, SOCK_RAW, $icmp);
    socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout,  'usec'  =>  0));
    if (@socket_set_option($socket, SOL_SOCKET, SO_BINDTODEVICE, $iface) === false) return false;
    socket_connect($socket,  $host,  100);

    $ts = microtime(true);
    socket_send($socket,  $package,  strLen($package),  0);


    if (@socket_read($socket, 255)) {
        $result = $host;
    } else {
        $result = false;
    }
    socket_close($socket);

The error message is:

socket_create(): Unable to create socket [1]: Operation not permitted
Siong Thye Goh
  • 3,518
  • 10
  • 23
  • 31
YunHong
  • 11
  • 1
  • 2

1 Answers1

2

The reason it doesn't work on your Linux system is that SOCK_RAW requires root access on Linux. The technical reason can be found in the Linux man pages https://linux.die.net/man/7/raw

Only processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets.

I wouldn't recommend running your web server with root privileges.

If you are just looking to ping another server then you could use shell_exec() instead.

https://www.php.net/shell_exec

For example:

$ip = '8.8.8.8';
echo shell_exec("ping $ip -c 1");

This returns:

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=10.7 ms --- 8.8.8.8 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 10.775/10.775/10.775/0.000 ms

Using -c 1 limits the ping to one attempt otherwise the ping command will happily keep rechecking for you.

You'll need to do a little parsing on the returned string to pull out whichever information you're actually after.

If you don't own the server that is running the script (e.g shared hosting) then it's possible that the exec() and shell_exec() commands might be disabled for security reasons.

IMPORTANT: Don't pass raw parameters from the browser directly into shell_exec() or you're gonna have a bad time.

As an alternative, if you're just checking if a website is available then you could probably use cURL. This post topic has a suggested way of doing that.

curl and ping - how to check whether a website is either up or down?


Update in response to comment:

It's generally a very bad idea to run the web server as root, if an attacker compromises the web server application they can gain access to the entire server. That being said if it's on a private network that can't be accessed from the Internet then it might be alright.

There is some discussion of options for Ubuntu in this topic:

Apache as root on ubuntu

I don't have much experience with CentOS but I assume that the principle could work the same. However, I don't know whether SELinux would block the attempts.

I think we're getting a bit beyond the original scope of this question, I would suggest that you ask a new question over at the Server Fault sister site.

ArchCodeMonkey
  • 2,264
  • 1
  • 10
  • 9
  • What if I wanna running my web server with root privileges how can I do(In CentOS7)? I do ICMP ping that's because I wanna send ping message request to my controller(it has IP) and then get response from it. – YunHong Aug 13 '19 at 06:20
  • @YunHong I've added some more information in response to your comment. – ArchCodeMonkey Aug 13 '19 at 08:05
  • How about use nmap to scan all ip ? is it better than those methods? – YunHong Aug 14 '19 at 02:45
  • @YunHong Calling Nmap from PHP would be similar to calling ping, it would require `shell_exec()`. Also, a lot of Nmap functionality can require root privileges and is a bit excessive just to check if a server is live. If my answer isn't meeting your needs then would you mind providing more detail about what you are trying to achieve. What does this other server do and why do you need to ping it? – ArchCodeMonkey Aug 15 '19 at 04:47
  • I finally use exec("sudo nmap -sP ips") to find all the ips of certain network segment, Why I wanna scan ips? That's because I am trying to build an IOT, and mutilple controllers has own ip, so that's the reason. And i trying to use exec("ping ips"), it is too slow. English is not very well sor. – YunHong Aug 15 '19 at 10:00
  • @YunHong I'm glad we managed to solve your problem between us, good luck with your project. :) – ArchCodeMonkey Aug 23 '19 at 01:12
  • great for a simple php ping (checking if database is available as running nginx on laptop) – Datadimension Jan 07 '22 at 13:58