Customers can abusing server resources and bypass limits

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

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

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

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 :heart::heart::heart:

Yeah this:

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_%’;

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

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:
[root@server:/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
[root@wcloud:/var/lib/mysql]#

tested on another server
selecting all DB owned by id “2”
root@server [/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
root@server [/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

any progress? @whattheserver

Has this been fixed? My bandwidth usage is not showing and limits have no effect.

Hi

I plan to move my servers to cyberpanel and this is a very important feature for me. If i can´t limit web storage for a user or website it is not usable for web hosting.

Is there any workaround to get this fixed? Or any news about when it will be fixed?

These problems are not solved yet. Please solve it

@whattheserver
@CyberPanel
@usmannasir