Sunday, September 21, 2014

Change DATA directory of PostgreSQL in CentOS

You need to stop the PostgreSQL first to change the DATA directory.

service postgresql stop

Now edit the start-up script

vi /etc/rc.d/init.d/postgresql

Change the PGDATA and PGLOG variable to wherever you want

Create the directory and set the permissions

mkdir -p /home/data/path
chown postgres:postgres /home/data/path

Initialize the database engine

su - postgres -c "initdb -D /path/to/pgdata"

Now start the PostgreSQL

service postgresql start

If you see FAILED and Permission denied message, check SELinux mode.
stop the SELinux OR change the mode enforcing to permissive.

Saturday, August 9, 2014

Install phpMyAdmin in CentOS

The easiest way to install phpMyAdmin is using EPEL Repositories.

Add EPEL repositories to your yum source by downloading a configuration file from the repository.

wget http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

Install the package running the following command

rpm -ivh epel-release*

Then run the following command

yum install phpmyadmin

You may be asked to confirm once or twice, and then the packages will be installed.

Note: You need to have apache and MySQL installed in your system to access phpMyAdmin.

Now configure phpMyAdmin and allow IPs from where you want to access phpMyAdmin.

check the the following file to Allow/Deny Ips

/etc/httpd/conf.d/phpMyAdmin.conf

Now Access http://YOUR_IP/phpmyadmin

Monday, June 30, 2014

Install pptpd VPN server in centOS

To install PPTP in your centOS, first download the repo

rpm -i http://poptop.sourceforge.net/yum/stable/rhel6/pptp-release-current.noarch.rpm

Now install PPTPD

yum -y install pptpd

Now edit /etc/pptpd.conf and add the following lines:

localip 192.168.10.1
remoteip 192.168.10.100-200

Where localip is IP address of the server and remoteip are IPs that will be assigned to clients that connect to it.

Now, you should setup authentication for PPTP by adding users and passwords.
Simply add them to /etc/ppp/chap-secrets :

user1 pptpd "password" *

Add DNS servers to /etc/ppp/pptpd-options

ms-dns 8.8.8.8
ms-dns 8.8.4.4

service pptpd restart

Verify that it is running and accepting connections:

netstat -alpn | grep :1723

Now enable forwarding. Simply edit /etc/sysctl.conf and add the following line if it doesn’t exist there already:

net.ipv4.ip_forward = 1

To make changes active, run

sysctl -p

Now create a NAT rule for iptables

iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE

If you would also like your PPTP clients to talk to each other, add the following iptables rules:

iptables --table nat --append POSTROUTING --out-interface ppp0 -j MASQUERADE
iptables -I INPUT -s 192.168.10.0/24 -i ppp0 -j ACCEPT
iptables --append FORWARD --in-interface venet0 -j ACCEPT

Now save iptables

iptables-save

Thursday, January 30, 2014

TOTP two factor authentication using PHP

I needed to implemented TOTP two-factor authentication in a project.
After searching a found a php class somewhere and used it in my project.

Time based one time password works based on current timestamp.
If you face problem time problem in your maching, you can fetch timestamp from ntp server.
For fetching timestamp from ntp server, see my previous post.

I am writing the class here so you can use it.


class TOTP {

const keyRegeneration = 30; // Interval between key regeneration
const otpLength = 6; // Length of the Token generated

private static $lut = array( // Lookup needed for Base32 encoding
"A" => 0, "B" => 1,
"C" => 2, "D" => 3,
"E" => 4, "F" => 5,
"G" => 6, "H" => 7,
"I" => 8, "J" => 9,
"K" => 10, "L" => 11,
"M" => 12, "N" => 13,
"O" => 14, "P" => 15,
"Q" => 16, "R" => 17,
"S" => 18, "T" => 19,
"U" => 20, "V" => 21,
"W" => 22, "X" => 23,
"Y" => 24, "Z" => 25,
"2" => 26, "3" => 27,
"4" => 28, "5" => 29,
"6" => 30, "7" => 31
);

/**
* Generates a 16 digit secret key in base32 format
* @return string
**/
public static function generate_secret_key($length = 16) {
$b32 = "234567QWERTYUIOPASDFGHJKLZXCVBNM";
$s = "";

for ($i = 0; $i < $length; $i++)
$s .= $b32[rand(0,31)];

return $s;
}

/**
* Returns the current Unix Timestamp devided by the keyRegeneration
* period.
* @return integer
**/
public static function get_timestamp() {
return floor( (microtime(true) + 10) /self::keyRegeneration);
}

/**
* Decodes a base32 string into a binary string.
**/
public static function base32_decode($b32) {

$b32 = strtoupper($b32);

if (!preg_match('/^[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]+$/', $b32, $match))
throw new Exception('Invalid characters in the base32 string.');

$l = strlen($b32);
$n = 0;
$j = 0;
$binary = "";

for ($i = 0; $i < $l; $i++) {

$n = $n << 5; // Move buffer left by 5 to make room
$n = $n + self::$lut[$b32[$i]]; // Add value into buffer
$j = $j + 5; // Keep track of number of bits in buffer

if ($j >= 8) {
$j = $j - 8;
$binary .= chr(($n & (0xFF << $j)) >> $j);
}
}

return $binary;
}

/**
* Takes the secret key and the timestamp and returns the one time
* password.
*
* @param binary $key - Secret key in binary form.
* @param integer $counter - Timestamp as returned by get_timestamp.
* @return string
**/
public static function oath_hotp($key, $counter)
{
   if (strlen($key) < 8)
throw new Exception('Secret key is too short. Must be at least 16 base 32 characters');

   $bin_counter = pack('N*', 0) . pack('N*', $counter); // Counter must be 64-bit int
   $hash = hash_hmac ('sha1', $bin_counter, $key, true);

   return str_pad(self::oath_truncate($hash), self::otpLength, '0', STR_PAD_LEFT);
}

/**
* Verifys a user inputted key against the current timestamp. Checks $window
* keys either side of the timestamp.
*
* @param string $b32seed
* @param string $key - User specified key
* @param integer $window
* @param boolean $useTimeStamp
* @return boolean
**/
public static function verify_key($b32seed, $key, $window = 4, $useTimeStamp = true) {

$timeStamp = self::get_timestamp();

if ($useTimeStamp !== true) $timeStamp = (int)$useTimeStamp;

$binarySeed = self::base32_decode($b32seed);

for ($ts = $timeStamp - $window; $ts <= $timeStamp + $window; $ts++)
if (self::oath_hotp($binarySeed, $ts) == $key)
return true;

return false;

}

/**
* Extracts the OTP from the SHA1 hash.
* @param binary $hash
* @return integer
**/
public static function oath_truncate($hash)
{
   $offset = ord($hash[19]) & 0xf;

   return (
       ((ord($hash[$offset+0]) & 0x7f) << 24 ) |
       ((ord($hash[$offset+1]) & 0xff) << 16 ) |
       ((ord($hash[$offset+2]) & 0xff) << 8 ) |
       (ord($hash[$offset+3]) & 0xff)
   ) % pow(10, self::otpLength);
}



}

$InitalizationKey = "M5UIUKQBTRCU7IQG"; // Set the inital key

$TimeStamp  = TOTP::get_timestamp();
$secretkey  = TOTP::base32_decode($InitalizationKey); // Decode it into binary
$otp        = TOTP::oath_hotp($secretkey, $TimeStamp); // Get current token

echo("Init key: $InitalizationKey\n");
echo("Timestamp: $TimeStamp\n");
echo("One time password: $otp\n");

// Use this to verify a key as it allows for some time drift.

$result = TOTP::verify_key($InitalizationKey, "123456");

var_dump($result);

Wednesday, January 22, 2014

Retrive timestamp from an NTP server using PHP

In my PHP application, I needed to retrive time from NTP server using PHP.
NTP server uses port 123 and I needed to communicate to pool.ntp.org with UDP port 123.
I used the following function to retrive time.

function getNtpTime($host = "pool.ntp.org") {

    $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
    socket_connect($sock, $host, 123);

    $msg = "\010" . str_repeat("\0", 47);
    socket_send($sock, $msg, strlen($msg), 0);
    
    socket_recv($sock, $recv, 48, MSG_WAITALL);
    socket_close($sock);
    
    $data = unpack('N12', $recv);
    $timestamp = sprintf('%u', $data[9]);
    $timestamp -= 2208988800;

    return $timestamp;
}