CyberHosting

Customers can abusing server resources and bypass limits

https://prnt.sc/prg0zs

in cpanel after using more than allotted diskspace user locked from adding removing new files, but in cyberpanel there is no restrictions. users can add as much files, database, domain as he want. so there is no limit and no package restrictions.

is there any way to prevent it? otherwise this panel will become useless for shared hosting production system.

@whattheserver
@CyberPanel
@usmannasir
Tagged:
Tagged:

Comments

  • edited November 3
    I am experiencing the same issue, shared on forum but didnt receive any respond yet which I think very serious issue. Actually I havent receive any respond to any of my topics, Honestly starting to loose my believe on Cyberpanel..
  • a similar problem is because users have no limits on their mail capacity
    https://forums.cyberpanel.net/discussion/2095/mailbox-size-cyber-panel#latest
  • Tadeusz said:

    a similar problem is because users have no limits on their mail capacity
    https://forums.cyberpanel.net/discussion/2095/mailbox-size-cyber-panel#latest

    yes, bandwidth limit has no effect too.
  • i've started working on a script now, it will check user usage then set permission to read only if user exceed his usage limit. it will check usage once every 15min. current api doesnt have any feature to view diskusage. so im thinking about brute forcing directory to get actual size
  • currently i'm locking user account based on their usage

    du -msh /home/domain.com
    du -msh /vmail/domain.com

    then using chattr -R +i /home/domain.com/public_html/

    but still some issue exists, for example db size and addon/subdomains email occupied space are not included.

    im using whmcs api to grab package details and match disk usage then lock account. its not a good way at all, there should be a native way to lockin and lock out.

    @CyberPanel
    @usmannasir
  • This is being looked into and a solution will be implemented when ready.

    Disk space, Mail quota and Database usage will be counted towards the users quota. The suggestion is that you will be able to allow or disallow overselling of disk and bandwidth usage with automatic suspension if it is not allowed.

  • i prefer file lock instead of account suspending. it will create bad impression to your customer. however sound great !! cant wait to see this feature ♥♥♥
  • Yeah this:
    https://github.com/usmannasir/cyberpanel/blob/6dcff4e4379882969f0ee29d2562c831f11fce6d/websiteFunctions/website.py#L706

    diskUsageDetails = virtualHostUtilities.getDiskUsage("/home/" + self.domain, website.package.diskSpace)

    Should be more like a total from
    diskUsageDetailsTotal = diskUsageDetailsHome + diskUsageDetailsMail + diskUsageDetailsDB

    diskUsageDetailsHome = virtualHostUtilities.getDiskUsage("/home/" + self.domain)
    diskUsageDetailsMail = virtualHostUtilities.getDiskUsage("/home/vmail/" + self.domain)

    DB is going to be trickier.
    We need to grab the domains "id" from websiteFunctions_websites and use that to lookup all owned DB's in databases_databases and then loop through and addup the disk usage

    diskUsageDetailsDB =

    Database: cyberpanel »Table: websiteFunctions_websites "id" for domain


    Database: cyberpanel »Table: databases_databases

    website_id

    for dbName in databases_databases with website_id = ''; do
    du -sh /var/lib/mysql/ + dbName

    sum = sum + i

    or something like this per DB and summed?

    SELECT table_schema "database", sum(data_length + index_length)/1024/1024 "size in MB" FROM information_schema.TABLES WHERE table_schema='YOUR_DATABASE_NAME' GROUP BY table_schema;
  • actually addon and subdomain creates own folder inside vmail folder separately so to calculate mail usage we have grab all domain record then usage

    vmail/maindomain.com + vmail/subdomain.com = total mail usage

    /home/maindomain.com = total website file usage

    and regarding db we can use like operator and username ( WHERE user LIKE '%username_%';
  • edited November 8
    nice observation hadn't looked into childdomains(addons) or subdomains structure. So looks like we would have to loop through through and sum them up too.

    THanks for the suggestion. MySQL is not my strong suit sadly. Would you mind expanding on how we could implement that to calculate the mysql disk usage for all the DB's for one user?

    Example of how im seeing it
    https://imgur.com/a/4WwT7iC

    This table lists website owner id
    SELECT * FROM `cyberpanel`.`websiteFunctions_websites` WHERE `id` = 1

    this is the link from the databases map to website owner. With below i can get all the databases associated with the website_id aka domain aka the account holder.
    SELECT dbName FROM `databases_databases` WHERE 1

    Lost on how to splice this in with getting all the usage from the above selected DB's. Seems like we should be able to select all the tables from above DB and get one total. I suppose worst case we could do it x times and sum it up but that seems inefficient.
  • @whattheserver sorry brother, i have not checked cyberpanel db structure properly before i just assume that i could use username but its impossible since cyber panel use unique user. also if one user name match with another it will show wrong result. after your last comment i have analysed cyberpanel db stucture.

    Here is a demo flowchart, may be it can help you to get some idea.

    // get the website ids as per your plan from user domain and subdomain

    SELECT id FROM cyberpanel WHERE domain = 'maindomain.com' OR domain = 'sub/addondomain.com'

    //result 1,2 (array)

    //then instead of using array we can convert array to string and make one query (it will optimize the performance greatly)

    SELECT dbName FROM databases_databases WHERE FIND_IN_SET(website_id,'1,3');

    //result test1, test3


    so we got two database now get size of them

    there is two way to calculate
    1. calculate disk size
    2. calculate the sum of index and data length

    lets check their difference, i have tested a small database
    Result:
    Disk calculation: 2.6G occupied
    Query Calculation: 2.292G

    so the difference will be really big if we check 10GB or 50 GB database, we can neglect the difference in case of small db but in case of big db it will be bigger.

    from my own point of view disk calculation will be good choice as /var/lib/mysql/databasename folder is belongs to the customer himself so he is responsible for all data inside.

    when we develop a system our first priority is to give less pressure on the machine so we try to optimize it. so disk calculation is better if you want real time calculation and give less stress on the db server

    i agree with your point "I suppose worst case we could do it x times and sum it up but that seems inefficient." because if a user has 50 database it will run 50 query then sum up that will give lots of pressure. but what if provider use one server for db another for own site? many of us do this to distribute load and reduce expense. in that case we cant calculate db size from another server disk. but we can use db query to calculate them though have to edit settings and other files and will make it more complex but will open another possibility of new feature.

    for db query my suggestion:
    we can run cron every 15 or 30 min to grab all database uses from all user, below query is really fast and can show all database uses at a single query

    SELECT table_schema "database", sum( data_length + index_length) / 1024 / 1024
    "size in MB" FROM information_schema.TABLES GROUP BY table_schema ;

    after getting all db size in an array we can easily sum them say
    db1 5mb
    db2 5mb
    db3 5mb
    db4 5mb

    db1 and db2 belongs to one user so db1+db2= total db size then save this total value in a cache file (can be text file or another db table. i prefer text file) then we can calculate this db size anytime with the real time directory size of website and email.

    or we can grab data based on specific user within single query ( probably you are looking for it )

    SELECT table_schema "database", sum( data_length + index_length) / 1024 / 1024
    "size in MB" FROM information_schema.TABLES
    WHERE FIND_IN_SET(table_schema,'db1,db2') GROUP BY table_schema;

    result:
    database size in MB
    db1 0.40861511
    db2 2292.92187500

    or
    SELECT (sum( data_length + index_length) / 1024 / 1024) as total FROM information_schema.TABLES
    WHERE FIND_IN_SET(table_schema,'db1,db2') GROUP BY table_schema;


    we can calculate directory usage from /var/lib/mysql/db
    we can simply get all the db list belongs to user from database then calculate directory usage. it can be real time and less resource intensive




  • Nice thanks.

    Well, it's not complete but very close now.


    To get csv list of databases for website_id 1
    domainNameDBs=$(mysql -e 'SELECT dbName FROM `cyberpanel`.`databases_databases` WHERE `website_id` = 1' -s --skip-column-names| paste -s -d, -);

    Now that we have that list we can then specify that variable in the below query to get total disk used in MB for all databases as one value:
    mysql -e "SELECT table_schema 'database', sum(data_length + index_length)/1024/1024 'size in MB' FROM information_schema.TABLES WHERE FIND_IN_SET(table_schema,'$domainNameDBs');" -sN | cut -f2 ;

    Putting it together:
    Get total disk used for all databases owned by domain with id "1"
    domainNameDBs=$(mysql -e 'SELECT dbName FROM `cyberpanel`.`databases_databases` WHERE `website_id` = 1' -s --skip-column-names| paste -s -d, -); mysql -e "SELECT table_schema 'database', sum(data_length + index_length)/1024/1024 'size in MB' FROM information_schema.TABLES WHERE FIND_IN_SET(table_schema,'$domainNameDBs');" -sN | cut -f2 ;

    See it in action:
    [[email protected]:/var/lib/mysql]# domainNameDBs=$(mysql -e 'SELECT dbName FROM `cyberpanel`.`databases_databases` WHERE `website_id` = 1' -s --skip-column-names| paste -s -d, -); mysql -e "SELECT table_schema 'database', sum(data_length + index_length)/1024/1024 'size in MB' FROM information_schema.TABLES WHERE FIND_IN_SET(table_schema,'$domainNameDBs');" -sN | cut -f2 ;
    111.49689865
    [[email protected]:/var/lib/mysql]#


    tested on another server
    selecting all DB owned by id "2"
    [email protected] [/root]# domainNameDBs=$(mysql -e 'SELECT dbName FROM `cyberpanel`.`databases_databases` WHERE `website_id` = 2' -s --skip-column-names| paste -s -d, -); mysql -e "SELECT table_schema 'database', sum(data_length + index_length)/1024/1024 'size in MB' FROM information_schema.TABLES WHERE FIND_IN_SET(table_schema,'$domainNameDBs');" -sN | cut -f2 ;
    50.28125000
    [email protected] [/root]#


    Now the part I'm stuck on and it probably cause I'm getting tired is how to pass in the domain to select the id. for some reason it's failing when I'm trying the below.

    DOMAIN='example.com';DomainOwnerID=$(mysql -e 'SELECT `id` FROM `cyberpanel`.`websiteFunctions_websites` WHERE `domain` = `$DOMAIN`;')

    the query works via raw mysql
    SELECT `id` FROM `cyberpanel`.`websiteFunctions_websites` WHERE `domain` = 'example.com';

    MariaDB [(none)]> SELECT `id` FROM `cyberpanel`.`websiteFunctions_websites` WHERE `domain` = example.com';
    +----+
    | id |
    +----+
    | 3 |
    +----+
    1 row in set (0.00 sec)

    MariaDB [(none)]>

    Or:
    MariaDB [(none)]> SELECT id FROM `cyberpanel`.`websiteFunctions_websites` WHERE domain = 'example.com' OR domain = 'test.example.com';
    +----+
    | id |
    +----+
    | 4 |
    | 3 |
    +----+



    Once I figure that out we should be able to loop through all website_id/id and calculate one total per domain and write it to a file. The addon/child domains could then be summed up most likely from there unless there.
  • @whattheserver

    This works in my case

    DOMAIN=$'greenweb.com.bd';
    getIDS=$(mysql -uroot -ptest12345changeit -Dcyberpanel -N -B -e "SELECT id FROM websiteFunctions_websites WHERE domain = '$DOMAIN';")

    domainNameDBs=$(mysql -uroot -ptest12345changeit -Dcyberpanel -N -B -e "SELECT dbName FROM databases_databases WHERE website_id = '$getIDS';")

    mysql -uroot -ptest12345changeit -Dcyberpanel -N -B -e "SELECT table_schema 'database', sum(data_length + index_length)/1024/1024 'size in MB' FROM information_schema.TABLES WHERE FIND_IN_SET(table_schema,'$domainNameDBs');"

    result: greenweb.com.bd 2411.14062500
  • For multiple DB of single domain:

    DOMAIN=$'otp.li';
    getIDS=$(mysql -uroot -pchangeitpass -Dcyberpanel -N -B -e "SELECT id FROM websiteFunctions_websites WHERE domain = '$DOMAIN';")

    domainNameDBs=$(mysql -uroot -pchangeitpass -Dcyberpanel -N -B -e "SELECT dbName FROM databases_databases WHERE website_id = '$getIDS';")
    domainNameDBs=`echo $domainNameDBs | sed 's/ /,/g'`
    mysql -uroot -pchangeitpass -Dcyberpanel -N -B -e "SELECT table_schema 'database', sum(data_length + index_length)/1024/1024 'size in MB' FROM information_schema.TABLES WHERE FIND_IN_SET(table_schema,'$domainNameDBs');"


    it will grab id using domain>then get ids say 3 4 replace space by comma to format> then grab both db size



    For multiple domain no need to loop. it will be faster and much efficient:


    DOMAIN=$'otp.li,greenweb.com.bd';
    getIDS=$(mysql -uroot -pchangeitpass -Dcyberpanel -N -B -e "SELECT id FROM websiteFunctions_websites WHERE FIND_IN_SET(domain, '$DOMAIN');")
    getIDS=`echo $getIDS | sed 's/ /,/g'`
    domainNameDBs=$(mysql -uroot -pchangeitpass -Dcyberpanel -N -B -e "SELECT dbName FROM databases_databases WHERE FIND_IN_SET(website_id, '$getIDS');")
    domainNameDBs=`echo $domainNameDBs | sed 's/ /,/g'`
    mysql -uroot -pchangeitpass -Dcyberpanel -N -B -e "SELECT table_schema 'database', sum(data_length + index_length)/1024/1024 'size in MB' FROM information_schema.TABLES WHERE FIND_IN_SET(table_schema,'$domainNameDBs');"

    result: otp.li+greenweb.com.bd db size= 2411.14062500 MB


  • Another thing you can run first two queries using cyberpanel db user credentials but last query which calculate db space must be run by root user. because cyberpanel db user doesnt have sufficient privilege to calculate.



    DOMAIN=$'otp.li,greenweb.com.bd';
    getIDS=$(mysql -ucyberpanel -preplaceitbycyberpanelpass -Dcyberpanel -N -B -e "SELECT id FROM websiteFunctions_websites WHERE FIND_IN_SET(domain, '$DOMAIN');")
    getIDS=`echo $getIDS | sed 's/ /,/g'`
    domainNameDBs=$(mysql -ucyberpanel -preplaceitbycyberpanelpass -Dcyberpanel -N -B -e "SELECT dbName FROM databases_databases WHERE FIND_IN_SET(website_id, '$getIDS');")
    domainNameDBs=`echo $domainNameDBs | sed 's/ /,/g'`


    mysql -uroot -pgiverootpasshere -Dcyberpanel -N -B -e "SELECT table_schema 'database', sum(data_length + index_length)/1024/1024 'size in MB' FROM information_schema.TABLES WHERE FIND_IN_SET(table_schema,'$domainNameDBs');"


    Hope it will help you. @whattheserver
Sign In or Register to comment.
CyberPanel Discord

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!