Tuesday, June 30, 2015

Laravel - Gotcha


Laravel composer update error:-
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/framework v5.0.9 requires ext-mcrypt * -> the requested PHP extension mcrypt is missing from your system.

Solution:-
On Ubuntu 14.04, the error message still shown even after installing the php5-mcrypt. The problem is that the package doesn't create a link for the php5 CLI (used by composer/artisan), so the correct thing to do is to run the following commands:
  1. cd /etc/php5/cli/conf.d
  2. sudo ln -s ../../mods-available/mcrypt.ini 20-mcrypt.ini
  3. reload apache

Wednesday, June 10, 2015

Magento Gotcha

Customer login doesn't work

The answer is that your theme does not supply a variable called form_key.
Just as stated above I have to add:
<input type="hidden" name="form_key" value="<?php echo Mage::getSingleton('core/session')->getFormKey(); ?>" />
you add it right after <ul class="form-list">
to each one of my login.phtml files for the theme.
You may also have problems with update quantity of cart items
Take a look at http://iamvikram.com/magento-form-keys-in-version-1-8/ for more information
Here is the importance of form_keys:
Since the beginning of time, Magento's backend contained a form key that protected against XSS attacks [1]. With Magento 1.8 the form key has entered the frontend for pretty much the same reason: to protect against form submission from another website, using your browser. a malicious attacker can add stuff to your cart while you're in a different browser tab or even complete an order for you. This relies on predictable URLs, because the site will not have access to the actual HTML content in the browser tab where you have your Magento order waiting. Everything sent to the Magento store will however submit your cookies and thus use your session.
By adding a unique key to each form or to each link that generates an action on the server, the URL or form content becomes no longer predictable. The form key is stored in the session data and validated upon submission to the server. If they don't match, you get a form key error and the action is not completed.
Source: http://magento.stackexchange.com/questions/31933/customer-login-doesnt-work-in-1-9

======================================================================
"Your web server is configured incorrectly. As a result, configuration files with sensitive information are accessible from the outside. Please contact your hosting provider." message on dashboard

The message prompt you that your www.domain.com/app/etc/local.xml, which store DB string, is exposed to public. 
Mostly likely that AllowOverride option is not set to All on Apache/Nginx conf file, hence .htaccess rule on web root couldn't take effect.

=====================================================================

Magento place order button not responding

It could be your info.phtml in your theme file not compatible with Magento version installed.

Solution: replace theme checkout info.html file with default info.html
i.e. cp ./app/design/frontend/base/default/template/checkout/onepage/review/info.phtml ./app/design/frontend/THEME/default/template/checkout/onepage/review/info.phtml 

=====================================================================

Magento plugin file turned into directory

You received plugin file from software developer, and applied to via connect manager. You see installation success message.
After log out and re-login, new sub-section you expected to see in Configuration module is not there. Upon check web code, you found out that some new add file are added as folder instead of file. i.e. *.php

Solution: double check your plugin file, make sure it's .tgz file and not tgz.gz file. If it's tgz.gz file, try decompress it by running gunzip -d filename.tgz.gz.
Manual delete files added and re-install the plugin again.
















Tuesday, April 14, 2015

Fail2ban - STOP apache abnormal POST request


Received an site down alert this morning and discovered that one of a site was being password brunt forced with log entries below:-

104.245.97.218 - - [14/Apr/2015:10:10:26 +0800] "POST /xmlrpc.php HTTP/1.0" 200 394 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
104.245.97.218 - - [14/Apr/2015:10:10:27 +0800] "POST /xmlrpc.php HTTP/1.0" 200 394 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
104.245.97.218 - - [14/Apr/2015:10:10:28 +0800] "POST /xmlrpc.php HTTP/1.0" 200 394 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
104.245.97.218 - - [14/Apr/2015:10:10:28 +0800] "POST /xmlrpc.php HTTP/1.0" 200 394 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
104.245.97.218 - - [14/Apr/2015:10:10:29 +0800] "POST /xmlrpc.php HTTP/1.0" 200 394 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
104.245.97.218 - - [14/Apr/2015:10:10:30 +0800] "POST /xmlrpc.php HTTP/1.0" 200 394 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
104.245.97.218 - - [14/Apr/2015:10:10:30 +0800] "POST /xmlrpc.php HTTP/1.0" 200 394 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
104.245.97.218 - - [14/Apr/2015:10:10:31 +0800] "POST /xmlrpc.php HTTP/1.0" 200 394 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"

Googling the solution and found fail2ban is the most suitable tool to be used in this case.

This is the brief introduction on fail2ban home page:-
"Fail2ban scans log files (e.g. /var/log/apache/error_log) and bans IPs that show the malicious signs -- too many password failures, seeking for exploits, etc. Generally Fail2Ban is then used to update firewall rules to reject the IP addresses for a specified amount of time, although any arbitrary other action (e.g. sending an email) could also be configured. Out of the box Fail2Ban comes with filters for various services (apache, courier, ssh, etc). 
Fail2Ban is able to reduce the rate of incorrect authentications attempts however it cannot eliminate the risk that weak authentication presents. Configure services to use only two factor or public/private authentication mechanisms if you really want to protect services."

Configuration to ban POST request at abnormal rate

Add this to jail.conf  file (usually in /etc/fail2ban/)

[apache-post]
 enabled = true
 filter = apache-post
 action = iptables[name=httpd, port=80, protocol=tcp]
 sendmail-whois[name=post_block, dest=email@example.com]
 logpath = /var/log/httpd/access_log
 findtime = 10
 bantime = 86400
 maxretry = 4

The above configure will block IP with 4 or more HTTP POST attempts in 10 sec for 183600(1 day)


Now create apache-post.conf in filter.d directory with following lines

 # Fail2Ban configuration file
 #
 #
 # $Revision: 1 $
 #
 [Definition]
 # Option: failregex
 # Notes.: Regexp to catch known spambots and software alike. Please verify
 # that it is your intent to block IPs which were driven by
 # abovementioned bots.
 # Values: TEXT
 #
 failregex = ^<HOST> -.*"POST.*
 # Option: ignoreregex
 # Notes.: regex to ignore. If this regex matches, the line is ignored.
 # Values: TEXT
 #

 ignoreregex =


Gotcha/Note

  • *"POST.* -> make sure it is '"'
  • To test the configuration, use curl with POST - curl --data "param1=value1&param2=value2" http://sitename.com/wp-admin. Repeat the command 5 times in 10 sec.
  • In Access Log, we have:-
162.243.18.229 - - [14/Apr/2015:13:47:38 +0800] "POST /wp-admin HTTP/1.1" 301 240 "-" "curl/7.37.1"162.243.18.229 - - [14/Apr/2015:13:47:52 +0800] "POST /wp-admin HTTP/1.1" 301 240 "-" "curl/7.37.1"
162.243.18.229 - - [14/Apr/2015:13:47:53 +0800] "POST /wp-admin HTTP/1.1" 301 240 "-" "curl/7.37.1"
162.243.18.229 - - [14/Apr/2015:13:47:55 +0800] "POST /wp-admin HTTP/1.1" 301 240 "-" "curl/7.37.1"
162.243.18.229 - - [14/Apr/2015:13:47:56 +0800] "POST /wp-admin HTTP/1.1" 301 240 "-" "curl/7.37.1"
  • The IP is now blocked in IPTABLES
Chain fail2ban-httpd (1 references)
num  target     prot opt source               destination1    REJECT     all  --  162.243.18.229       0.0.0.0/0            reject-with icmp-port-unreachable2    RETURN     all  --  0.0.0.0/0            0.0.0.0/0

  • Change http.conf LogFormat if your sites behind proxy or loadbalancer, in order to get true client IP

A default logging configuration in your httpd.conf looks like this:
1LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
2CustomLog log/acces_log combined
There are several changes you are going to want to make to the default format in order to log the X-Forwarded-For client ip address or the real client ip address if the X-Forwarded-For header does not exist. Those changes are below:
1LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
2LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy
3SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
4CustomLog "logs/access_log" combined env=!forwarded
5CustomLog "logs/access_log" proxy env=forwarded
You may also want to consider SecSign real two-factor authentication (2FA)plugin for Wordpress