How to enable SSL/HTTPS in Java Micro-Service/Spring-Boot application

  1. Generate SSL certificate –

keytool -genkey -alias <alias> -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650

  1. Add the below lines in your application.properties file –

server.port: 8443

server.ssl.key-store: classpath : keystore.p12

server.ssl.key-store-password: <keystore password>

server.ssl.keyStoreType: PKCS12

server.ssl.keyAlias: <alias>

3. Restart your java application. Now you’ll be able to access your application over HTTPS on https://localhost:8443 instead of http://localhost:8080.

Advertisements

Windows VMware Issue: VMware Workstation and Hyper-V are not compatible. Remove the Hyper-V role from the system before running VMware Workstation.

Recently I have gotten into this issue after updating my windows. Before updating my windows machine, I was able to boot up my virtual machine. After that it got failed saying “VMware Workstation and Hyper-V are not compatible. Remove the Hyper-V role from the system before running VMware Workstation.”. Below is the required steps to solve this issue –

1.) Go to “Programs and Features” icon on your windows machine.

2.) Click on “Turn Windows features on or off”.

3.) When the new window opens, uncheck the checkbox labelled as “Hyper-V”.

4.) Now it will ask you to reboot your system.

5.) After the PC restarts, try to launch VMWare again. I worked for me. Hope it helps you as well. 🙂 

Stuck in verifying while installing pkg file on MAC

  1. Go to finder. Click on Go and then Go to Folder and type /System/Library/CoreServices/Installer.app. Then invoke the installer.app
  2. Now you just need to go to the location where .pkg file exists and that was stuck in verifying.
  3. Select the file to open and now you will be able to run the installer easily.

It saved my day. Hope it helps for you as well. 🙂

Kill process/port on MAC machine in case of java.net.BindException: Address already in use

  • First try netstat –
    netstat -vanp tcp | grep <PORT Number(8061)>

    Result

    tcp46      0      0  *.8061                 *.*                    LISTEN      131072 131072  71666      0

  • The Find the PID for the locking port –
    lsof -i :<PORT Number(8061)>
    

    Result

    COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME

    java    71666 tangupta   90u  IPv6 0x9f73e601cf2fbd79      0t0  TCP *:8061 (LISTEN)

  • Kill:
    kill -9 <PID(71666)>

Result – Process running on the above port would be killed. Now you can resume your           work on the above port which was blocked.

Steps to mitigate Uncaught PHP PDOException “Host is blocked because of many connection errors” | Useless* ZmEu(w00tw00t.at.blackhats.romanian.anti-sec) Bot Attack

Problem Statement :

I am working on PHP(5.6) Symfony application which connects to mysql(5.6.32) using doctrine tool. Recently we have moved our server from RackSpace to AWS. So here we have been facing the bot attacks named w00tw00t.at.blackhats.romanian.anti-sec(ZmEu) continuously.

Analysis by Request: – Looking for similar requests which is long and tedious process

  • GET /phpMyAdmin
  • GET /MyAdmin
  • GET /w00tw00t.at.blackhats.romanian.anti-sec etc.
  • GET /muieblack
  • GET /scripts/setup.php

and finally it’s throwing 500 internal server error and having the following exception on the server.
Uncaught PHP Exception PDOException: “SQLSTATE[HY000] [1129] Host ‘10.27.134.240’ is blocked because of many connection errors; unblock with ‘mysqladmin flush-hosts‘” at /usr/local/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.phpline 40

Note :

  • We had never faced this kind of issue on RackSpace.
  • Just checked all the folders like phpMyAdmin with standard php files which were not there on the server.
  • Tried to brute-force the same kind of attack but still was not able to troubleshoot how it’s trying to make the DB connection and causing the above issue.

Temporary Solution :

  • We flushed the host every-timeusing the query “mysqladmin flush-hosts” which I was not supposed to do.
  • We have signal sciences enabled for the server in blocking mode. Every time it checks for the new IP and blocks the same for few hours and again it got released. But it doesn’t seem working perfectly with me because of IP spoofing.

Real Finding :

First of all, I would like to say neither it had to do with application nor bot attack. *That’s why I have made marked the half part of Subject as useless Bot Attack It was the main issue with our MySql configuration and Load balancer which is configured on AWS. How ?

So here comes the detailed explanation to mitigate the above issue and this is how we went through from top to down manner –

  1. Got the Exception from the application after enabling the debug log – Uncaught PHP Exception PDOException: “SQLSTATE[HY000] [1129] Host ‘10.27.134.240’ is blocked because of many connection errors; unblock with ‘mysqladmin flush-hosts'”.
  2. This above exception comes when one parameter named max_connect_errors exceeds the certain value (1000 in our case) defined in my.cnf/my.ini file. This parameter determines how many successive interrupted connection requests are permitted. After max_connect_errors failed requests without a successful connection, mysqld assumes that something is wrong (for example, that someone is trying to break in), and blocks the host from further connections until you issue a FLUSH HOSTS statement or execute a mysqladmin flush-hosts command.
  3. Now we decided to check few other connection parameters like  Aborted_connects and Connections using mysql command”show status like ‘onn%’;“. The value of both the parameters was very high and difference was very less. So it was confirmed that there was something going wrong on the basis of that it is aborting the mysql connection and to be surprised when we tried checking these parameters in the real time, their values were increasing sequentially with in 5 sec.
  4. Unsuccessful connection attempts can occur for the following reasons:
  • A client attempts to access a database but has no privileges for it.
  • A client uses an incorrect password.
  • A connection packet does not contain the right information.
  • It takes more than connect_timeout seconds to obtain a connect packet.
  • Socket_timeout=60s and Connect_timeout=60s in our case.

5. Above 4th point was important for us and then we got some clue. But again the surprise was that there were no error logs of this kind in error log. 

6. So now we took the tcpdump using the following command -“sudo tcpdump -i eth0 port 3306 -s 65535 -x -n -q -tttt > tcpdump.out

7. Here we got the same error as expected that host “IP Address” is blocked because of many connection error. But the other part was that we got two IPs through the dump.

8. Anyhow looking at this, our mind diverted towards AWS mysql configuration. There we saw that ELB was configured in front of App server and DB server as well. After scanning all it’s configuration setting, we got a catch here:-) There was a health check to monitor the health of DB in every 5 sec on port 3306 which was trying to access DB server successfully.  

9. Now the question comes how it was able to access the DB server. We tried the following query discussed in the next point to check the user permission  on the defined hosts.

10. MySQL stores the user information in its own database. The name of the database is mysql. Inside that database the user information is in a table, a dataset, named user. If you want to see what users are set up in the MySQL user table, run the following command:

SELECT User, Host FROM mysql.user;
+------------------+-----------+
| User             | Host      |
+------------------+-----------+
| root             | localhost |
| root             | DBDomainName  |
| root             | 127.0.0.1 |
| debian-sys-maint | localhost |
|                  | %         |
|                  | localhost |
|                  | DBDomainName|
+------------------+-----------+

   11. Hence, we deleted the last 3 rows and 3rd row from the last says that someone from outside the world has the capability to access your DB and yes, connection was made through our ELB IP in every 5 sec because of this only. But as it is never closed and in turn it  gives timeout which counts as unsuccessful attempt.

Background about ELB (Elastic Load balancing) :

Elastic Load Balancing automatically distributes incoming application traffic across multiple Amazon EC2 instances. It enables you to achieve fault tolerance in your applications, seamlessly providing the required amount of load balancing capacity needed to route application traffic. So basically whenever any request comes on our application or database server, it goes through ELB and in turn ELB transfers the request on respected hosts.

Conclusion:

  1. The db issue was caused by the health check from the ELB tier in front of the MySQL using a blank db user. 
  2.  Need to disable the DB user and host to avoid any unnecessary health check.

 Resolution:

1.       Had to remove the ELB tier in front of the MySQL and created a security group to manage the access .

2.       Updated the MySQL user table and cleaned up the access by deleting the above defined rows.

Hope this analysis works for you in case you are trapped into the same situation. Rocks 🙂

Logging in PHP using MonoLog and Standard Error Handling Functions to log the data

Problem Statement : While working on Symfony PHP application which connects with database using 3rd party Doctrine tool, we have high chances to enable debug and application log for any kind of troubleshooting.

Symfony is bundled  with an outside library called MonoLog which allows us to dump logs that can be stored in a variety of different places.

Different Environments, different Configuration Files :

  • for the dev environment: app/config/config_dev.yml
  • for the prod environment: app/config/config_prod.yml
  • for the test environment: app/config/config_test.yml

Working config_dev.yml file :

# app/config/config.yml
imports:
       # All the logging parameters which you want to see in the logs are defined in the below file.
       -{ resource : config.xml}
monolog:
    handlers:
        # Below is the key "main". you can name it anything.
        main:
            # fingers_crossed stores all log messages and passes it to next defined handler.
            type: fingers_crossed
            # if *one* log is error or higher, pass *all* to nested
            path: "%kernel.logs_dir%/%kernel.environment%.log"
            action_level: error
            handler: nested

        # now passed *all* logs, but only if one log is error or higher
        nested:
            type: stream
            path: "%kernel.logs_dir%/%kernel.environment%.log"
            level : debug

Working config.xml file :

#Doctrine Configuration
doctrine:
   orm:
       auto_generate_proxy_classes: '%kernel.debug%'
       auto_mapping:true
#Twig Configuration 
twig:
    debug: '%kernel.debug%'
    form:
        resources: 
           - 'BundleName:Form:twigfilename.twig'       

Note- Based on the above configuration, we will get the various types of events like request, security, doctrine etc in log file. So we can make a filter of it as well using the below parameters which we can put in the app_dev.yml file –

channels: “!events”

Executing an Application in different Environments :

app.php      -> *prod* environment
app_dev.php  -> *dev* environment

Working app_dev.php file :

$kernel = new AppKernel('prod/dev', true/false);

First argument says the environment and seconds tell whether you want to enable it or not and then it will create the respected log file either prod.log or dev.log based on the environment you set.

Note* – Please do not give any Tab in the yml file, it will give you the error as it’s not able to parse the elements. 

Logging a Custom Message in the application:

To log a message, fetch the logger service from the container in your controller:

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
public function mainAction(Request $request)
{
    $logger = $this->get('logger');
    $logger->info('Info logger');
    $logger->error('Error Logger');
    $logger->critical('Critical Log');  
    $logger->info('Request Log :: '.$request);
}

It’ll dump these messages or data in the above defined log file.

Working with Standard Error Handling Functions :

Apart from MonoLog, php provides the standard way to log the data either using configuration or at code level. But it has very limited usage in terms of logging the data. You can differentiate the logs in terms of info, debug, error etc using these function but MonoLog gives you the full flexibility to do the same.

Changes required in php.ini :

log_errors = On/Off
error_log = /path/filename

Changes required in app_dev.php :

If you want to override above changes of php.ini file, you can add the following function  in app_dev.php file –

define(‘WEB_DIRECTORY’,DIR);

init_set(‘error_log’,DIR . ‘/../app/logs/error.log’);

Error Handling Functions :

Out of all the above predefined functions. error_log() is the one which is used most of the time in the following way to log the custom data, request, headers, response etc.

error_log(‘Info Log :: Inside ‘ .basename(FILE));
error_log(‘Request Header Log:: ‘.print_r($_REQUEST,true));
error_log(‘SERVER Header Log:: ‘.print_r($_SERVER,true));
$kernel->loadClassCache();
$request = Request::createFromGlobals();
error_log(‘App Request Log:: ‘.$request);
$response = $kernel->handle($request);

$response->send();
error_log(‘App Response Log:: ‘.$response);

$curlInfo = curl_getinfo($ch);

error_log (‘ Box CURLINFO url log :: ‘ . print_r( $curlInfo,true) . ‘ ‘);
//error_log (‘ CURLINFO request_header log :: ‘ . print_r( $curlInfo[‘request_header’],true) . ‘ ‘);

//error_log (print_r($ch) );
curl_close($ch);

if ($response === false) {
error_log (‘ CurlError log :: ‘ . print_r( $curlError,true) . ‘ ‘ );
throw new Exception($curlError);
}

I have used the mixture of both MonoLog and standard function to log the data based on my requirement. I hope this will help you to work with PHP application easily 🙂