• Hi Gregory,
    first of all thanks for this great plugin and your work!

    I came upon sth annoying related to sth. that has beed discussed various times here.

    Different IPs in the ACL and like half of them have ip_long_begin + ip_long_end set to zero. For those, the ACL rule is not working at all:
    https://www.ads-software.com/support/topic/acl-database-errors/

    And

    ACL Access list does not recognize some IPs:
    https://www.ads-software.com/support/topic/access-list-does-not-recognize-some-ips/

    And I myself have multiple Entries in the ACL.

    All of this seems to be related to a 32-Bit Server Problem…

    I have multiple Cerber Installations and they are working great.
    But I have an obviously 32-Bit Server Hosting environment, where my Cerbers are not working as expected due to failing IP recognizations:

    You rely on ip2long to check an IP and determine duplicatons and so on.
    But ip2long “fails” for “large” IPs in a 32-Bit Environment due to an integer Overflow and returns a signed int-value:
    https://www.php.net/manual/de/function.ip2long.php

    I succeeded by replacing the ip2long func to an “unsinged int” version that i added to the main wp-cerber.php:

    function ip2long64( $ip )
    {
    	return sprintf("%u", ip2long($ip));
    }
    

    and then I replaced all occurrences of the ip2long with ip2long64. (Especially in cerber-load.php, dashboard.php and cerber-lab.php)

    This way now cerber_acl_fixer also works again. The “Repair Database”/”Repair Cerber’s Tables” Function is not able to working properly with ip2long and the ip_long_begin and _ip_long_end keep staying at zero…. But with ip2long64 also these Entries get repaired and everything works again as expected.

    In the CIDR2range Function where long2ip appears it seems to work as expected.
    you might try to take sth from here:
    https://www.php.net/manual/de/function.long2ip.php

    But then again the Ranges seem not to be saveable to the database within dashboard.php // cerber_acl_add
    because in the “$wpdb->insert( CERBER_ACL_TABLE …” the Range again has the integer format in the format-array (%d). And therefore it becomes 2147483647 that resolves to 127.255.255.255…
    …so just pass the values e.g. by string and it works….

    $result = $wpdb->insert( CERBER_ACL_TABLE, array(
    		'ip'            => $ip,
    		'ip_long_begin' => $begin,
    		'ip_long_end'   => $end,
    		'tag'           => $tag,
    		'comments'      => $comment,
    		'acl_slice'     => $acl_slice,
    		'v6range'       => $v6range,
    		'ver6'          => $ver6,
    	), array( '%s', /* >> */ '%s', '%s' /* << INSTEAD OF %d, %d */, '%s', '%s', '%d', '%s', '%d' ) );
    

    …that’s how it worked for me. ; )
    I hope you could include sth like this in the next version because my 32-Bit Server won’t change. And i don’t want to change my firewall : ))
    Greetigns!

    • This topic was modified 3 years, 8 months ago by ingonieur.
    • This topic was modified 3 years, 8 months ago by ingonieur.
Viewing 6 replies - 1 through 6 (of 6 total)
  • Plugin Author gioni

    (@gioni)

    Hi! I’ll look into the issues soon. From my understanding, you have two. One with ip2long() and another with saving rows into the DB. Please confirm.

    Thread Starter ingonieur

    (@ingonieur)

    Hi Gregory,

    no, it all breaks down to the ip2long-Problem.
    Mine as well as the mentioned/linked ones from @gingerbooch and @ableads

    Everything comes from this, if IPs are not correctly converted.

    … Black-List-Entries are faulty created as begin-0-end-0-IP-Entries (negative values are cut off because unsigned)

    … following IP Additions to the Block-List are inserted multiple times because the check-whether-ip-is-already-in-block-list fails (due to the faulty conversion)

    … ACL detections do not work anymore/intrusions are not detected/blocked because the intrusion-IP-is-in-Block-List-Range-Check fails (due to the faulty conversion).

    … your repair-DB-Script/Fix-ACL does not correct the faulty IPs, because the new long-IP-Value still is converted faulty…

    I hope you can add the ip2log-Fix with the next Update, because I unfortunately do still have some 32-Bit Servers from a shared hoster…

    The above mentioned solution in my first post is a fix that works great. Try to test it in a 32 Bit Environment. If you don’t have one, I can give you a test-access.

    Many thanks in advance!
    many greets, ingo

    • This reply was modified 3 years, 8 months ago by ingonieur.

    Hi there,

    Thank you @ingonieur for linking to us too.

    I realize I gave up on this thread because the problem was remaining and I decided to block the IPs from htaccess directly instead of Cerber, to make it really work.

    Anyway, seeing this discussion today I took a look at the base first, and I’m glad to say that the db entries have finally been fixed. I don’t know how nor when it happened because the last time I used the repair option it did not fix it.

    Thank you,

    GB

    Thread Starter ingonieur

    (@ingonieur)

    Hey @gingerbooch,

    haha, yeah, good solution! And very stable, ideed. But cerber is such a great tool and of course more comfortable than a htaccess List. : )

    I also had such a “magic fix” on another Server because the ACL_Fixing-Function runs every time Cerber gets a Plugin-Update and on this Server my hoster switched from faulty 32 to properly functioning 64-Bit…

    But the Problem itself in the Cerber-Plugin kept and still is the same.

    thanks for your message!
    ingo

    • This reply was modified 3 years, 8 months ago by ingonieur.
    Plugin Author gioni

    (@gioni)

    What about $wpdb->insert? Why did you mention it? I don’t follow you here.

    Thread Starter ingonieur

    (@ingonieur)

    Hi Gregory.

    wpdb->insert does its job, but not with log-int-values that cannot be stored as integers on 32-bit-machines.
    You use PHP ip2long, that doesn’t work either.

    Within the wpdb->insert Excerpt I wanted to focus on the INTEGER Format-Mapping of the long IPs. On a 32-Bit Machine this also leads to an Integer-Interpretation/mapping where the long-Value (even if correct) possibly leads to an overflow and a resulting negative value, that cannot be stored in the UNSIGNED-Int CERBER_ACL_TABLE field.

    So take “%s” instead of “%d”:
    array( '%s', /* >> */ '%s', '%s' /* << INSTEAD OF %d, %d */,

    Did you get the rest? Please don’t get me wrong, i don’t want to appear harsh or arrogant or sth like that… I think it might be a misunderstanding here.
    I do not have a question. I found a Bug and have a Solution.
    Sorry, it’s a really serious bug – I was hoping that it would get it into the new update – I really think you should implement this fix as soon as possible…

    I’ll try to recap:
    For many IPs the whole Cerber Blocking Mechanism DOES NOT WORK with ip2long you are using in every Block-Check. The way Cerber currently converts and saves the IPs does not work as intended on 32-Bit-Machines.
    The Blocking Mechanism is one of the most important things of a Firewall, but Cerber currently does not work on 32 Bit Servers – it fails silently without error…

    PHP says:
    ip2long:
    https://www.php.net/manual/en/function.ip2long.php

    Note:
    Because PHP's int type is signed, and many IP addresses will result in negative integers on 32-bit architectures, you need to use the "%u" formatter of sprintf() or printf() to get the string representation of the unsigned IP address.

    And in the cerber_acl Table the long IP values (ip_long_begin, ip_long_end) are stored in UNSIGNED bigint(20). Therefore: while trying to store a negative value it becomes cutted to Zeros…

    That’s why functions (and several others) like “cerber_acl_add” in dashbaord.php (also in Version 8.8.3) keep failing:

    5208	if ( cerber_is_ipv4( $ip ) ) {
    5209		$begin = ip2long( $ip );
    5210		$end   = ip2long( $ip );
    5211	}

    but if you would take

    	if ( cerber_is_ipv4( $ip ) ) {
    		$begin = sprintf("%u", ip2long($ip));;
    		$end   = sprintf("%u", ip2long($ip));;
    	}

    or better – a helper-function like sth I mentiones in my first post, then it would work again, because with ip2long only “0”-Values are stored in the Database, because of the unsigned Storage (cerber_acl Table Structure) and negative Values cannot be checked correctly with a “greater-or-smaller-than-IP-range-check”… so the sprintf-U-way is one of the smartest solutions I think…

    I hope this makes it more clear now.
    If not, please tell me, then I will again try to explain what i mean.

    Many greetings and nevertheless thanks again for this great plugin! : ))

    ingo

    • This reply was modified 3 years, 8 months ago by ingonieur.
    • This reply was modified 3 years, 8 months ago by ingonieur.
Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘ACL Block List contains multiple IPs and some are not blocked’ is closed to new replies.