raihanafroz / zkteco

ZKTeco Laravel Library
147 stars 56 forks source link

I uploaded to live server and getting error socket_sendto(): Unable to write to socket [1]: Operation not permitted #35

Open ukhanPronto opened 5 months ago

ukhanPronto commented 5 months ago

The application was working fine on localhost as soon as I uploaded it to live server it made an issue

socket_sendto(): Unable to write to socket [1]: Operation not permitted

hasnain8540 commented 5 months ago

i'm also facing same issue

9822824952 commented 5 months ago

Send me code


From: ukhanPronto @.> Sent: Tuesday, February 6, 2024 3:41 AM To: raihanafroz/zkteco @.> Cc: Subscribed @.***> Subject: [raihanafroz/zkteco] I uploaded to live server and getting error socket_sendto(): Unable to write to socket [1]: Operation not permitted (Issue #35)

The application was working fine on localhost as soon as I uploaded it to live server it made an issue

socket_sendto(): Unable to write to socket [1]: Operation not permitted

β€” Reply to this email directly, view it on GitHubhttps://github.com/raihanafroz/zkteco/issues/35, or unsubscribehttps://github.com/notifications/unsubscribe-auth/A3QBNQLGSIYKQMLQYJLX23TYSFKH7AVCNFSM6AAAAABC25JMPSVHI2DSMVQWIX3LMV43ASLTON2WKOZSGEYTSNJUHAYTSNQ. You are receiving this because you are subscribed to this thread.Message ID: @.***>

ukhanPronto commented 5 months ago

Below is the code please let me know if you need anything else

 use Rats\Zkteco\Lib\ZKTeco;

 public function test() {
    $zk = new ZKTeco('192.168.18.100');
    $zk->connect();  

    $usersData = $zk->getUser();

    $attendancesData = $zk->getAttendance();

    foreach($attendancesData as $attendance):
            if(date('Y-m-d', strtotime($attendance['timestamp'])) >= date('Y-m-d')) {
                     print_r($attendance);
            }
        }
    endforeach;`
  }
9822824952 commented 5 months ago

required static IP


From: ukhanPronto @.> Sent: Wednesday, February 14, 2024 10:23 PM To: raihanafroz/zkteco @.> Cc: 9822824952 @.>; Comment @.> Subject: Re: [raihanafroz/zkteco] I uploaded to live server and getting error socket_sendto(): Unable to write to socket [1]: Operation not permitted (Issue #35)

Below is the code please let me know if you need anything else

` use Rats\Zkteco\Lib\ZKTeco;

public function test() { $zk = new ZKTeco('192.168.18.100'); $zk->connect();

$usersData = $zk->getUser();

$attendancesData = $zk->getAttendance();

foreach($attendancesData as $attendance):
        if(date('Y-m-d', strtotime($attendance['timestamp'])) >= date('Y-m-d')) {
                 print_r($attendance);
        }
    }
endforeach;`

}

β€” Reply to this email directly, view it on GitHubhttps://github.com/raihanafroz/zkteco/issues/35#issuecomment-1944226504, or unsubscribehttps://github.com/notifications/unsubscribe-auth/A3QBNQM2K7QHMXDL3EPENSDYTTT2JAVCNFSM6AAAAABC25JMPSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBUGIZDMNJQGQ. You are receiving this because you commented.Message ID: @.***>

ukhanPronto commented 5 months ago

I have assigned static IP to the device. if not please guide me

9822824952 commented 5 months ago

Send me device images IP Gateway DNS Cloud setting and port


From: ukhanPronto @.> Sent: Thursday, February 15, 2024 9:48 PM To: raihanafroz/zkteco @.> Cc: 9822824952 @.>; Comment @.> Subject: Re: [raihanafroz/zkteco] I uploaded to live server and getting error socket_sendto(): Unable to write to socket [1]: Operation not permitted (Issue #35)

I have assigned static IP to the device. if not please guide me

β€” Reply to this email directly, view it on GitHubhttps://github.com/raihanafroz/zkteco/issues/35#issuecomment-1946462323, or unsubscribehttps://github.com/notifications/unsubscribe-auth/A3QBNQMUIRYBBTHWFOUB4GLYTYYOVAVCNFSM6AAAAABC25JMPSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBWGQ3DEMZSGM. You are receiving this because you commented.Message ID: @.***>

Ehtasham-CEF commented 5 months ago

@9822824952 This lib works only when you are connected with same internal network. If we access it external using static IP with port forwarding to internal device ip/port, It does not work i.e device does not connect.

have you tested yourself from accessing outside the same network? if yes then please share how?

erdum commented 4 months ago

You can only access this device within your Local Area Network (LAN). If you want to access the device from anywhere on the internet, you have to forward your device from the settings in your home router and even with that I assume you will only able to access it from your Wide Area Network only because your ISP will not allow forwarding. And ISP's uses complex internal network of multiple routers and switches.

To verify that, first forward your device to WAN by going to your home router forwarding settings enter your zkteco device IP and put 4730 in service port and 4730 also in the internal port. And copy the WAN IP showing in your home router settings page.

Now try access the device from your WAN IP first, if it works you have successfully forwarded your device to your WAN.

Now get your public IP by visiting any what's my IP website. Compare your WAN IP with your Public IP if it's same then congrats you're a lucky person and your router is directly connected to the internet which will never going to happen.

With WAN forwarding working, you can access the device from within your office building or within your street, area, etc. But not outside the network.

And your zkteco device IP will change if router restarts or your device is reconnected to the network, for that you have to assign static IP to your device from your home router settings.

Now what after WAN success? You can contact your ISP and tell them about your situation, they will give you a custom connection that will allow forwarding and has less overhead connectivity.

Ehtasham-CEF commented 4 months ago

@erdum I already have tried your scenario. I have a static IP with an open port (not 4370) from my ISP. And the forwarding rule is also set which is like static-IP:port(xxxx) will be forward to internal-IP:port(4370). But i get same: error socket_sendto(): Unable to write to socket [1]: Operation not permitted

erdum commented 4 months ago

Try to check your firewall permissions.

And also provide more detail about your environment, where your code is running? If it is running on a remote server, then what type of hosting?

Ehtasham-CEF commented 4 months ago

@erdum I am currently using HOSTINGER hosting, but I also tested it on another server, which was hosted by GoDaddy.

Also where exactly to check for firewall permissions?

One more thing I want to mention here is that when I try to connect within ZKTECO's software i.e. ZKTime5.0 using my static IP and external port while being within the same network, the device gets connected.

The library only connects when you are within the same network, using the internal network IP assigned to the device, and the port, if it's set to the default, i.e., 4370.

erdum commented 4 months ago

@Ehtasham-CEF First your device is not visible to your server because you are using a remote server. Static IP doesn't mean you can forward your LAN devices to the internet, it just makes sure your public facing IP will not change.

And if you are using Hostinger i.e., shared hosting there is no way directly you can access firewall with command line. Try to find firewall setting in your cPanel interface or similar, whichever you have.

Ehtasham-CEF commented 4 months ago

@erdum Ok then what's the concept and use case of port forwarding? And do you have any idea how to achieve if someone wanna access device data over remote server?

Ehtasham-CEF commented 4 months ago

@erdum Also, when I attempt to connect within ZKTeco's software, specifically ZKTime5.0, using my static IP and external port, whether I am within or outside the same network, the device successfully connects. I'm testing this by changing my internet connection.

erdum commented 4 months ago

@Ehtasham-CEF

Also, when I attempt to connect within ZKTeco's software, specifically ZKTime5.0, using my static IP and external port, whether I am within or outside the same network, the device successfully connects. I'm testing this by changing my internet connection.

If you're saying this, then I am assuming that your forwarding is working. To better confirm it, connect your pc to a network other than the network to which your device is connected.

Then use telnet to connect to your static IP telnet static_ip 4370 4370 is the port, you can change it according to your case.

If you're on Windows upon successful connection, your screen will clear, and you will see a blank screen on your cmd. And if you're on Linux, you will see connected to _staticip on your screen.

If you're able to connect to your device from static_ip from outside your network, then the only thing which is stopping the remote server from accessing your device is server permission or disabled PHP socket module which can be given from CLI in case of virtual private server running Linux.

I don't think we can modify permissions on the shared hosting with php_ini directives or with .htaccess file.

erdum commented 4 months ago

@Ehtasham-CEF Also dump the phpinfo(); of your server

Ehtasham-CEF commented 4 months ago

@erdum The Telnet connection to the IP and port is successful. Sockets are also enabled but still could you please tell me what details I should look for in the php_info?

erdum commented 4 months ago

@Ehtasham-CEF

Look for "sockets" and "streams" in your phpinfo dump.

Ehtasham-CEF commented 4 months ago

@erdum here it is: image

erdum commented 4 months ago

@Ehtasham-CEF

Place this test script on your server, change the IP with your static IP and port according to your case, then try to run it and see if you're able to connect or not.

Your phpinfo dump seems fine.

<?php

$server_ip = '127.0.0.1'; $server_port = 4370;

// Create a TCP/IP socket $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

if ($socket === false) { echo "Failed to create socket: " . socket_strerror(socket_last_error()) . "\n"; exit(1); }

echo "Socket created successfully.\n";

// Connect to the server $result = socket_connect($socket, $server_ip, $server_port);

if ($result === false) { echo "Failed to connect to server: " . socket_strerror(socket_last_error($socket)) . "\n"; socket_close($socket); exit(1); }

echo "Connected to server.\n";

socket_close($socket);

echo "Socket closed.\n";

Ehtasham-CEF commented 4 months ago

@erdum image

erdum commented 4 months ago

@Ehtasham-CEF Your application is also placed in the same place where you placed your test script?

Ehtasham-CEF commented 4 months ago

@erdum Yes it is.

erdum commented 4 months ago

@Ehtasham-CEF Very strange, if your code is able to make connection with your server, then your application should too.

I think we're missing something, you need to debug your connect() method to see what parameters it is using when calling PHP native socket functions.

erdum commented 4 months ago

@Ehtasham-CEF I think I have found the problem, your server is not allowing UDP connections while allowing TCP connection. To verify this assumption just run the test script, this time it will try to make a UDP connection as this library is doing.

<?php

$server_ip = '192.168.18.201';
$server_port = 4370;

// Create a TCP/IP socket
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

if ($socket === false) {
    echo "Failed to create socket: " . socket_strerror(socket_last_error()) . "\n";
    exit(1);
}

echo "Socket created successfully.\n";

// Connect to the server
$result = socket_connect($socket, $server_ip, $server_port);

if ($result === false) {
    echo "Failed to connect to server: " . socket_strerror(socket_last_error($socket)) . "\n";
    socket_close($socket);
    exit(1);
}

echo "Connected to server.\n";

socket_close($socket);

echo "Socket closed.\n";
Ehtasham-CEF commented 4 months ago

@erdum it also connects with UDP. image

Ehtasham-CEF commented 4 months ago

@erdum But now, no matter what IP or port I provide to this script, even incorrect ones, it still shows as connected. πŸ˜•

Ehtasham-CEF commented 4 months ago

@Ehtasham-CEF

Try this, it will try to send actual data from your remote server to your device.

$server_ip = '192.168.18.201';
$server_port = 4370;

// Create a UDP socket
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

if ($socket === false) {
    echo "Failed to create socket: " . socket_strerror(socket_last_error()) . "\n";
    exit(1);
}

echo "Socket created successfully.\n";

// Connect to the server
$result = socket_connect($socket, $server_ip, $server_port);

if ($result === false) {
    echo "Failed to connect to server: " . socket_strerror(socket_last_error($socket)) . "\n";
    socket_close($socket);
    exit(1);
}

echo "Connected to server.\n";

$msg = 'test';
$len = strlen($msg);
$t = socket_sendto($socket, $msg, $len, 0, $server_ip, $server_port);

var_dump($t);

socket_close($socket);

echo "Socket closed.\n";

@erdum ok trying this one now

erdum commented 4 months ago

@erdum But now, no matter what IP or port I provide to this script, even incorrect ones, it still shows as connected. πŸ˜•

Sorry, script was incorrect for testing UDP. I have removed them.

Still, we have to verify that the server can establish a UDP connection over your static IP

Ehtasham-CEF commented 4 months ago

@erdum ok with your latest script, it shows: image

erdum commented 4 months ago

@erdum ok with your latest script, it shows: image

That script was not correct but still it verified that server is unable to send data.

Ehtasham-CEF commented 4 months ago

@erdum ok then what now? Should we attempt to modify the default library files to resolve this issue?

Ehtasham-CEF commented 4 months ago

@erdum ok with your latest script, it shows: image

That script was not correct but still it verified that server is unable to send data.

@erdum What could be the reason? and any solutions for this?

erdum commented 4 months ago

@Ehtasham-CEF First, I want to verify that UDP connection is the cause. Then I can modify the code for that.

I am creating a script to verify it, will share with you once it is ready.

erdum commented 4 months ago

@Ehtasham-CEF Try this code, it tries to send connect command to the device over UDP. If it's stuck then failed to send the command, otherwise it will immediately print success. Don't forget to change remote_address.

<?php

const USHRT_MAX = 65535;

function createChkSum($p)
  {
    $l = count($p);
    $chksum = 0;
    $i = $l;
    $j = 1;
    while ($i > 1) {
      $u = unpack('S', pack('C2', $p['c' . $j], $p['c' . ($j + 1)]));

      $chksum += $u[1];

      if ($chksum > USHRT_MAX) {
        $chksum -= USHRT_MAX;
      }
      $i -= 2;
      $j += 2;
    }

    if ($i) {
      $chksum = $chksum + $p['c' . strval(count($p))];
    }

    while ($chksum > USHRT_MAX) {
      $chksum -= USHRT_MAX;
    }

    if ($chksum > 0) {
      $chksum = -($chksum);
    } else {
      $chksum = abs($chksum);
    }

    $chksum -= 1;
    while ($chksum < 0) {
      $chksum += USHRT_MAX;
    }

    return pack('S', $chksum);
  }

  /**
   * This function puts a the parts that make up a packet together and
   * packs them into a byte string
   *
   * @inheritdoc
   */

  function createHeader($command, $chksum, $session_id, $reply_id, $command_string)
  {
    $buf = pack('SSSS', $command, $chksum, $session_id, $reply_id) . $command_string;

    $buf = unpack('C' . (8 + strlen($command_string)) . 'c', $buf);

    $u = unpack('S', createChkSum($buf));

    if (is_array($u)) {
      $u = reset($u);
    }
    $chksum = $u;

    $reply_id += 1;

    if ($reply_id >= USHRT_MAX) {
      $reply_id -= USHRT_MAX;
    }

    $buf = pack('SSSS', $command, $chksum, $session_id, $reply_id);

    return $buf . $command_string;

  }

$remote_address = '192.168.18.202';
$remote_port = 4370;

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if ($socket === false) {
    echo "Failed to create socket: " . socket_strerror(socket_last_error()) . "\n";
    exit(1);
}

$command = 1000;
$command_string = '';
$chksum = 0;
$session_id = 0;
$reply_id = -1 + USHRT_MAX;
$_data_recv;

$buf = createHeader($command, $chksum, $session_id, $reply_id, $command_string);

socket_sendto($socket, $buf, strlen($buf), 0, $remote_address, $remote_port);

@socket_recvfrom($socket, $_data_recv, 1024, 0, $remote_address, $remote_port);
if (strlen($_data_recv) > 0) {
    exit('success');
}
Ehtasham-CEF commented 4 months ago

@erdum its stuck and continuously loading

erdum commented 4 months ago

@erdum its stuck and continuously loading

That's mean UDP traffic isn't allowed. You have to modify the library code to utilize TCP/IP instead of UDP.

Ehtasham-CEF commented 4 months ago

@erdum its stuck and continuously loading

That's mean UDP traffic isn't allowed. You have to modify the library code to utilize TCP/IP instead of UDP.

@erdum where exactly? can you help?

erdum commented 4 months ago

@Ehtasham-CEF You have to modify parameters in socket_create call. And you have to replace socket_sendto with socket_write I guess.

Ehtasham-CEF commented 4 months ago

@erdum are you talking about these changes in your script file or the library's?

Ehtasham-CEF commented 4 months ago

I've never worked with these sockets stuff beforeπŸ˜”

ph4t0o0o0om commented 4 months ago

Does anyone make this thing work? I uploaded it in hosting but I got this same error . Pls help

erdum commented 4 months ago

@ph4t0o0o0om Read the discussion above.

ph4t0o0o0om commented 4 months ago

@erdum I already read the discussion above. In your side have you modified the libary to make this work in hosting?

erdum commented 4 months ago

@ph4t0o0o0om I started playing with it but not getting free time to properly make it run. But I have deeply explained to, so with little knowledge you can do this easily. And I am here for any help.

Masarkah commented 2 months ago

any one found solution

erdum commented 2 months ago

any one found solution

@Masarkah The problem is occurring only on shared hosting and for that you have to modify the code as I have mentioned above.

04gabrielmartinez commented 1 month ago

This same error was happening to me and I was able to solve it in a very easy way. It happens that shared servers usually have outgoing UDP connections blocked by default. I just had to talk to my support to enable UDP connections through port 4730. and ready