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


Thursday, December 18, 2014

AWS OpsWorks FAQ and common commands

To create a deploy via CLI

Before using the command, you will need to first setup AWS cli on your computer, use the official AWS guide here

$ aws opsworks --region us-east-1 create-deployment --stack-id 9xxxx3-xxxx-455f-bc5c-8xxxx7a --app-id 090xxx88-2d32-xxxx-a460-faaxxxd7 --command "{ \"Name\": \"deploy\" }"

Note: AWS OpsWorks supports only one endpoint, opsworks.us-east-1.amazonaws.com (HTTPS), so you must connect to that endpoint. You can then use the API to direct AWS OpsWorks to create stacks in any AWS Region. Source

The following message will be returned if command issued accepted.
----------------------------------------------------------
|                    CreateDeployment                    |
+---------------+----------------------------------------+
|  DeploymentId |  912b37aa-f423-4dda-9966-021680bbc1a8  |

+---------------+----------------------------------------+

===================================================================================
To Create and Schedule a time-based instance via CLI

Below sample command will create a time-based instance, stack-id, layers-ids, instance type are mondoroty

aws opsworks --region us-east-1 create-instance --stack-id 58af7c69-xxxx-xxxx-8e6a-7660d7a18e55 --layer-ids 6e876603-ac96-4714-89a0-2453e1dc06f0 --os Custom --ami-id ami-6d1b343f --instance-type t2.medium --subnet-id subnet-1ae9f56e --auto-scaling-type timer --ssh-key-name sysadmin

Next, You will need to assign scheduler to wake or shut instance off, here's the sample command. The command will schedule instance 064c0869-xxxx-xxxx-9728-53d271c4a484 to power on between 00800 to 1900GMT+8 from Monday to Friday. Saturday and Sunday is included in the command to override any schedule on previously set to ON

I personally find that the command is not so user friendly as you will need to include each and every hour slot into the command.


aws opsworks  set-time-based-auto-scaling --region us-east-1 --instance-id "064c0869-xxxx-xxxx-9728-53d271c4a484" --auto-scaling-schedule "{\"Monday\": {\"0\": \"on\", \"1\": \"on\", \"2\": \"on\", \"3\": \"on\", \"4\": \"on\", \"5\": \"on\", \"6\": \"on\", \"7\": \"on\", \"8\": \"on\", \"9\": \"on\", \"10\": \"on\", \"11\": \"off\", \"12\": \"off\", \"13\": \"off\", \"14\": \"off\", \"15\": \"off\", \"16\": \"off\", \"17\": \"off\", \"18\": \"off\", \"19\": \"off\", \"20\": \"off\", \"21\": \"off\", \"22\": \"off\", \"23\": \"off\"}, \"Tuesday\": {\"0\": \"on\", \"1\": \"on\", \"2\": \"on\", \"3\": \"on\", \"4\": \"on\", \"5\": \"on\", \"6\": \"on\", \"7\": \"on\", \"8\": \"on\", \"9\": \"on\", \"10\": \"on\", \"11\": \"off\", \"12\": \"off\", \"13\": \"off\", \"14\": \"off\", \"15\": \"off\", \"16\": \"off\", \"17\": \"off\", \"18\": \"off\", \"19\": \"off\", \"20\": \"off\", \"21\": \"off\", \"22\": \"off\", \"23\": \"off\"}, \"Wednesday\": {\"0\": \"on\", \"1\": \"on\", \"2\": \"on\", \"3\": \"on\", \"4\": \"on\", \"5\": \"on\", \"6\": \"on\", \"7\": \"on\", \"8\": \"on\", \"9\": \"on\", \"10\": \"on\", \"11\": \"off\", \"12\": \"off\", \"13\": \"off\", \"14\": \"off\", \"15\": \"off\", \"16\": \"off\", \"17\": \"off\", \"18\": \"off\", \"19\": \"off\", \"20\": \"off\", \"21\": \"off\", \"22\": \"off\", \"23\": \"off\"}, \"Thursday\": {\"0\": \"on\", \"1\": \"on\", \"2\": \"on\", \"3\": \"on\", \"4\": \"on\", \"5\": \"on\", \"6\": \"on\", \"7\": \"on\", \"8\": \"on\", \"9\": \"on\", \"10\": \"on\", \"11\": \"off\", \"12\": \"off\", \"13\": \"off\", \"14\": \"off\", \"15\": \"off\", \"16\": \"off\", \"17\": \"off\", \"18\": \"off\", \"19\": \"off\", \"20\": \"off\", \"21\": \"off\", \"22\": \"off\", \"23\": \"off\"}, \"Friday\": {\"0\": \"on\", \"1\": \"on\", \"2\": \"on\", \"3\": \"on\", \"4\": \"on\", \"5\": \"on\", \"6\": \"on\", \"7\": \"on\", \"8\": \"on\", \"9\": \"on\", \"10\": \"on\", \"11\": \"off\", \"12\": \"off\", \"13\": \"off\", \"14\": \"off\", \"15\": \"off\", \"16\": \"off\", \"17\": \"off\", \"18\": \"off\", \"19\": \"off\", \"20\": \"off\", \"21\": \"off\", \"22\": \"off\", \"23\": \"off\"}, \"Saturday\": {\"0\": \"off\", \"1\": \"off\", \"2\": \"off\", \"3\": \"off\", \"4\": \"off\", \"5\": \"off\", \"6\": \"off\", \"7\": \"off\", \"8\": \"off\", \"9\": \"off\", \"10\": \"off\", \"11\": \"off\", \"12\": \"off\", \"13\": \"off\", \"14\": \"off\", \"15\": \"off\", \"16\": \"off\", \"17\": \"off\", \"18\": \"off\", \"19\": \"off\", \"20\": \"off\", \"21\": \"off\", \"22\": \"off\", \"23\": \"off\"}, \"Sunday\": {\"0\": \"off\", \"1\": \"off\", \"2\": \"off\", \"3\": \"off\", \"4\": \"off\", \"5\": \"off\", \"6\": \"off\", \"7\": \"off\", \"8\": \"off\", \"9\": \"off\", \"10\": \"off\", \"11\": \"off\", \"12\": \"off\", \"13\": \"off\", \"14\": \"off\", \"15\": \"off\", \"16\": \"off\", \"17\": \"off\", \"18\": \"off\", \"19\": \"off\", \"20\": \"off\", \"21\": \"off\", \"22\": \"off\", \"23\": \"off\"}}"


Command to show instance detail
aws opsworks --region us-east-1 describe-time-based-auto-scaling --instance-id 398913d7-ea3e-xxxx-xxxx-44ffc8befa46

Output:-
-------------------------------------------------------------------------------------
|                           DescribeTimeBasedAutoScaling                            |
+-----------------------------------------------------------------------------------+
||                       TimeBasedAutoScalingConfigurations                        ||
|+---------------------------------------------------------------------------------+|
||                                   InstanceId                                    ||
|+---------------------------------------------------------------------------------+|
||  398913d7-ea3e-4c91-9b16-44ffc8befa46                                           ||
|+---------------------------------------------------------------------------------+|
|||                              AutoScalingSchedule                              |||
||+-------------------------------------------------------------------------------+||
||||                                   Friday                                    ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  0  |  1   | 10   |  2   |  3   |  4   |  5   |  6   |  7   |   8   |   9   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  on |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on   |  on   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||                                   Monday                                    ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  0  |  1   | 10   |  2   |  3   |  4   |  5   |  6   |  7   |   8   |   9   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  on |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on   |  on   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||                                  Saturday                                   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  0  |  1   | 10   |  2   |  3   |  4   |  5   |  6   |  7   |   8   |   9   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  off|  off |  off |  off |  off |  off |  off |  off |  off |  off  |  off  ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||                                   Sunday                                    ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  0  |  1   | 10   |  2   |  3   |  4   |  5   |  6   |  7   |   8   |   9   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  off|  off |  off |  off |  off |  off |  off |  off |  off |  off  |  off  ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||                                  Thursday                                   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  0  |  1   | 10   |  2   |  3   |  4   |  5   |  6   |  7   |   8   |   9   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  on |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on   |  on   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||                                   Tuesday                                   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  0  |  1   | 10   |  2   |  3   |  4   |  5   |  6   |  7   |   8   |   9   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  on |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on   |  on   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||                                  Wednesday                                  ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  0  |  1   | 10   |  2   |  3   |  4   |  5   |  6   |  7   |   8   |   9   ||||
|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||
||||  on |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on  |  on   |  on   ||||

|||+-----+------+------+------+------+------+------+------+------+-------+-------+|||

http://docs.aws.amazon.com/cli/latest/reference/opsworks/set-time-based-auto-scaling.html

Thursday, July 31, 2014

Win-Win with Dropbox Registration via referral link


Hi folks,

Dropbox is currently only offering 2Gb free storage space when you first register.

Do you know you and I  can get additional 500Mb when when you use this Registration Link to get an account and download/install its app on computer? 

You could further boost your storage space to additional 3Gb by signing up camera uploads too. Make it total of 5.5Gb which is more than enough to store most of you documents.

Happy dropboxing!
Joe

Thursday, February 6, 2014

Puppet FAQ

Puppet FAQ

So you have setup your Puppet master and got few servers joined the show. Everything runs smooth and another happy man.

Wait, on the last node, when you almost done with the project, there is one node keep throwing this error
[root@ clinet]# puppet agent --test
err: Could not request certificate: Connection timed out - connect(2)
Exiting; failed to retrieve certificate and waitforcert is disabled

You very certain that you have open all the ports, other nodes talk to master, only this node. Restarting master and client 654 times but no luck.

After spending 2 hours Googling, no luck still.

Out of sudden, you realised that you have not defined puppet master server on node's puppet.conf file
[main]
    # The Puppet log directory.
    # The default value is '$vardir/log'.
    logdir = /var/log/puppet

    # Where Puppet PID files are kept.
    # The default value is '$vardir/run'.
    rundir = /var/run/puppet

    # Where SSL certificates are kept.
    # The default value is '$confdir/ssl'.
    ssldir = $vardir/ssl
    server  = puppetmaster.local 

Hope this post could save someone 120mins, repeating the same I went through.