cPanel Default Page

Had a user today that added a new domain to his reseller account. 

Apparently he had this domain with us before, and transferred it over to GoDaddy for hosting, then was bringing it back. 

 

I've seen this happen a few times when the IP address they were pointing to was incorrect, or the httpd.conf was pointing to the home folder or IP incorrectly. 

I tried the basics like rebuilding the httpdconf and still getting issues. 

Had a look at the Zone file for the domain, and saw that on our side, the authoratative nameserver were set to his previous host. 
Rebuilt the Zone file, and it appears that the site started working. 

Probably something I should have thought of earlier, but at least I got to the bottom of it. 

MySQL Optimizations

cPanel/WHM come with a pretty decent all-around configuration, but when you're running a more powerful box, you can beef up your settings to get a little better performance. 

 

Today, I'll cover a few Tweaks that can be done to Apache and MySQL to get that little extra bang out of your server that's not just a little VPS running 4-5 sites. 

 

For Easy Apache, I went with the following, to keep up with new features, but not be 'bleeding edge'

In the first stage we run the Easy Apache and selected the following:

Apache Version 2.4
PHP Version 5.5
 In step 5 “Exhaustive Options List” selected – Deflate – Expires – MPM Prefork and – MPM Worker

 

Next item to review is the Apache Global Configuration limits
WHM » Service Configuration » Apache Configuration » “Global Configuration”
These are pretty generic numbers based on how many GB's of ram on the server, these can still be tweaked a little further based on your usage, 

 
 
Apache Directive 	 	2GB             6GB             12GB 	 	

StartServers 	 	 	4 	 	8 	 	16 	
MinSpareServers 	 	4 	 	8 	 	16 	
MaxSpareServers 	 	8 	 	16 	 	32 	
ServerLimit 	 	 	64 	 	128 	 	256 	
MaxRequestWorkers 	 	50 	 	120 	 	250 	
MaxConnectionsPerChild 	 	1000 	 	2500 	 	5000 
Keep-Alive			On		On		On
Keep-Alive Timeout	 	5	 	5	 	 5
Max Keep-Alive Requests		50	 	120	 	120
Timeout				30		60		60


From here, I wanted to add in some basic Caching to Apache by default, so even is users don't specify Cache lifetimes, this will override.
WHM » Service Configuration » Apache Configuration » Include Editor » “Pre VirtualHost Include”

# Cache Control Settings for one hour cache
<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=86400, public"
</FilesMatch>

<FilesMatch ".(xml|txt)$">
Header set Cache-Control "max-age=86400, public, must-revalidate"
</FilesMatch>

<FilesMatch ".(html|htm)$">
Header set Cache-Control "max-age=3600, must-revalidate"
</FilesMatch>

# Mod Deflate performs data compression
<IfModule mod_deflate.c>
<FilesMatch ".(js|css|html|php|xml|jpg|png|gif)$">
SetOutputFilter DEFLATE
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch bMSIE no-gzip
</FilesMatch>
</IfModule>

With this, basic media files, such as images and flash vids are forcibly browser cached for a day, and html files for an hour.
This helps to account for the inaction of clients, and ensure that basic caches are in place. Making page loads a little faster, and server loads a little slower for repeat visitors.



In /etc/my.cnf I made the following additions to optimize the connections and buffering.

[mysqld]
local-infile=0
max_connections = 600
max_user_connections=1000
key_buffer_size = 512M
myisam_sort_buffer_size = 64M
read_buffer_size = 1M
table_open_cache = 5000
thread_cache_size = 384
wait_timeout = 20
connect_timeout = 10
tmp_table_size = 256M
max_heap_table_size = 128M
max_allowed_packet = 64M
net_buffer_length = 16384
max_connect_errors = 10
concurrent_insert = 2
read_rnd_buffer_size = 786432
bulk_insert_buffer_size = 8M
query_cache_limit = 5M
query_cache_size = 128M
query_cache_type = 1
query_prealloc_size = 262144
query_alloc_block_size = 65535
transaction_alloc_block_size = 8192
transaction_prealloc_size = 4096
max_write_lock_count = 8
slow_query_log
log-error
external-locking=FALSE
open_files_limit=50000

[mysqld_safe]

[mysqldump]
quick
max_allowed_packet = 16M

[isamchk]
key_buffer = 384M
sort_buffer = 384M
read_buffer = 256M
write_buffer = 256M

[myisamchk]
key_buffer = 384M
sort_buffer = 384M
read_buffer = 256M
write_buffer = 256M

#### Per connection configuration ####
sort_buffer_size = 1M
join_buffer_size = 1M
thread_stack = 192K

Then ran a Repair & optimize on the databases and restarted MySQL:

mysqlcheck --check --auto-repair --all-databases
mysqlcheck --optimize --all-databases
/etc/init.d/mysql restart


 

 

Preventing Outgoing Spam

We all know that Spam is fucking annoying, That being the case, when a user is compromized, either in a web script, or a hacked/cracked/socially engineered password, the spammers most likely avenue is to Spoof a random email address from the same domain or spoof something completely different. 

Here is how I had learned to combat this, by preventing my servers from sending outgoing spoofed mail, I know that I'm ensure that my domains are not part of the problem. 

 

By taking advantage of the EXIM Configuration Editor, we can effectively stop outgoing spoofing. 

I. Blocking all un-authenticated spoofed outbound emails

1. Login to WHM >> EXIM CONFIGURATION MANAGER >> ADVANCED EDITOR

2. Add the following entry in the top using Add additional configuration setting:
domainlist remote_domains = lsearch;/etc/remotedomains

 
3. Add the following code under acl_not_smtp >> custom_begin_outgoing_notsmtp_checkall:

deny
condition = ${if ! match_domain{${domain:${address:$h_From:}}}{ +local_domains : +remote_domains}}
message = Sorry, you don't have \
permission to send email from this server with a header that \
states the email is from ${lc:${domain:${address:$h_from:}}}.
accept

 
Here, the ACL will check for the presence of domain name part of the from address in either of the files – /etc/localdomains or /etc/remotedomains. If there is a mismatch, server will reject the email.

II. Blocking all authenticated spoofed outbound emails

1. WHM >> EXIM CONFIGURATION MANAGER >> ADVANCED EXIM EDITOR

2. Search for acl_smtp_data >> custom_begin_outgoing_smtp_checkall and add the following lines under it:

deny
authenticated = *
condition = ${if or {{ !eqi{$authenticated_id} {$sender_address} } \
{ !eqi{$authenticated_id} {${address:$header_From:}} } \
} \
}
message = Your FROM address ( $sender_address , $header_From )
must match your authenticated email user ( $authenticated_id ).
Treating this as a spoofed email.

 
Here, for all authenticated users, the rule will check whether the authenticated userid matches with the from address. If it matches, it will allow the email. Else, it will display the message “Your FROM must match your authenticated email user. Treating this as spoofed email”

PS: If the acl_smtp_data is mentioned as something else(like acl_smtp_data = check_message), locate check_message and add the above lines just under it.

IMPORTANT points to keep in mind

a. POP before SMTP won’t work with this setting. You will have to ask your customers to use the option – “My Server Requires Authentication” in the SMTP settings of their email client.
b. Username in the format user+domain.com will not work. They have to use user@domain.com instead.

These solutions have been tested on my personal cPanel server, and in a limited set of production servers. We have found it to be working in 100% of cases. However, using the above solution should be at your own risk. If you do not understand the ACLs posted above, always ask for expert opinion.

Modifying DNS

Had a customer today that migrated from a Shared hosting to a VPS. 

 

For some reason, all of his DNS zones were reporting the older nameservers as the SOA and the NS for the domain, so this was causing DNS issues. 

 

Found an easy way to update them all instead of manually "Edit DNS Zone" on a bunch of domains. 

 

From command line:

replace "<oldSOA>" "<newSOA>" -- /var/named/*.db
replace "<oldSecondaryNS>" "<newSecondaryNS>" -- /var/named/*.db

Made this process a lot less painful. 

rDNS bulk

We have a client that regularly requests large changes to rDNS records. 

 

Today I got a request for over 60 records to be added 30 each for 2 different IP blocks. 

The way we have been told to do these is from WHM, we can enter the PTR records for that DNS range 5 at a time. 

I find this process to be slow and annoying. 

 

The request comes in a list format, like 
192.168.0.2 domain.example.com
192.168.0.3 domain2.example.com

Pasting the list into kWrite, a few Find/replaces later, specifically
Find '192.168.0.' Replace with ''
Find ' dom' Replace with '      14400   IN      PTR     '
Find '.com' Replace with '.com.'

The resulting list of records can just be manually added directly into the named zone db file

vi /var/named/0.168.192.in.addr.arpa
and Just paste at the end, or replace existing records if it's an update instead of addition of new records. 

 

From this point, to verify, I double checked the record in WHM Edit DNS to ensure that everything loaded properly, advanced the SN on the record and saved it just to ensure that the updated records are properly being served.  
30+ minute process down to about 2-3 minutes. 

 

Time well saved.