Kategorien
Webdeveloper Tools

Bitcoins senden testen im TestNet

Um die Zahlung mit Bitcoins zu testen ohne zahlungspflichtige Transaktionen auszulösen, muss man sich einen Wallet besorgen, bei dem man auch Test-Bitcoins (TestNet Bitcoins) senden kan:

https://copay.io/

Dort kann man sich ein Wallet einrichten in der Testwährung und erhält dann eine Bitcoin-Adresse aus dem TestNet, die alle mit „m“, z.B. mqfc7CVvhSD2eGVwkHS8s8Wc1FyZz8Z8xD

Auf dieses Konto kann man sich dann Bitcoins aufladen lassen auf der Webseite:

http://tpfaucet.appspot.com/

Danach kann man testen Zhalungen zu empfangen und zu senden und das Ergebnis auf der TestNet Blockchain verfolgen:

http://tbtc.blockr.io/

Kategorien
PHP

PHP PDO Connection Timeout für Datenbank setzen und bestimmen

Normalerweise soll man das Datenbank Connection Timeout in PHP auslesen können mittels:

$pdo = new PDO('mysql:host=localhost;port=80;dbname=xxx', 'xxx', 'xxxx');
$pdo->getAttribute(PDO::ATTR_TIMEOUT);

Allerdings gibt das bei meiner alten PDO Version die Fehlermeldung:

SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute

Also habe ich ein Testscript geschrieben, mit dem man das Timeout provozieren kann (das Messen der Zeit ist nicht enthalten, wäre nett, wenn jemand das posten könnte):

$pdo = new PDO('mysql:host=localhost;port=80;dbname=xxx', 'xxx', 'xxxx');

Damit wird das Timeout ausgelöst.

Um das Timeout zu verlängern, kann man den Parameter PDO::ATTR_TIMEOUT setzen:

$pdo = new PDO('mysql:host=localhost;port=80;dbname=xxx', 'xxx', 'xxxx', array(
   PDO::ATTR_TIMEOUT => 5
));
Kategorien
Server Administration

Bash Script um Konsolen Befehle auf mehreren Servern auszuführen

Wenn man einen Cluster von Severn administrieren muss, hilft es sehr, wenn man Befehler „in einem Rutsch“ auf allen Mitgliedern des Clusters ausführen kann mit Hilfe eines einzigen Konsolen Befehls.

Wenn man z.B. den Befehl: apt-get update ausführen will auf 3 Servern, kann man folgendes Script benutzen (Dateiname ist „each“ und auf dem Master abzulegen):

#!/bin/bash
echo -e "\nServer1:"
ssh serverName1$*
echo -e "\nnServer2:"
ssh serverName2$*
echo -e "\nnServer3:"
ssh serverName3$*

Der Aufruf erfolgt folgender Maßen auf der Konsole:

each "apt-get update"

Das Skript verbindet sich dann per SSH auf die Server und führt auf jedem den Befehl apt-get update aus und zeigt das Ergebnis der Operation auf der Konsole an. Vorrausetzung ist, dass die Server ohne Passwort Zugriff aufeinander haben, was in einem Cluster der Fall sein sollte. Der Befehl sollte vom Master des Clusters aus ausgeführt werden.

Kategorien
MySQL

MySQL eigener Variablen in Query verwenden

Es ist sehr einfach möglich in MYSQL Variablen zu verwenden für MySQL Statements. Diese müssen definiert werden mit der SET Funktion und dem @-Prefix:

SET @a= 'a';

Und kann dann benutzt werden für die Dauer der DB-Session:

UPDATE my_table SET x = @a WHERE y = @a;

 

Kategorien
MySQL

History für MySQL Tabelle anlegen

Wenn man loggen will, wer wann und welche Änderungen an einer Tabelle „tabelle1“ gemacht hat, sollte man sich eine Tabelle namens „tabelle1_history“ und automatisch per MySQL Trigger auf Update und Delete Ereignisse reagieren:

Hinweis: __XYZ__ Platzhalter sind zu ersetzen

Trigger auf Update Aktionen

CREATE DEFINER=`__USER__`@`%` TRIGGER `__DB__`.`__TRIGGER_NAME_DEL__` BEFORE DELETE ON `__DB__`.`__TABLE__` FOR EACH ROW BEGIN
    insert into
        __DB__.__TABLE_HISTORY__
        (
        dataset_id,
        my_data1
        my_data2
        created_on
        created_by
        )

    VALUES (
        OLD.id,
        OLD.my_data1
        OLD.my_data2
        OLD.created_on,
        OLD.created_by
  );

Trigger auf Delete Aktionen

CREATE DEFINER=`__USER__`@`%` TRIGGER `__DB__`.`__TRIGGER_NAME_UPDATE__` BEFORE UPDATE ON `__DB__`.`__TABLE__` FOR EACH ROW BEGIN
        insert into
        __DB__.__TABLE_HISTORY__
        (
        dataset_id,
        my_data1
        my_data2
        created_on
        created_by
        )

    VALUES (
        OLD.id,
        OLD.my_data1
        OLD.my_data2
        OLD.created_on,
        OLD.created_by
  );
Kategorien
Apache Webserver

Apache Virtual Hosts einrichten unter MAC und Windows

Wenn man eine Seite lokal mit einem Werbserver wie Apache entwicklen will und die URL-Struktur Einfluss auf die Funktonsweise der Webseite hat, empfielt es sich Virtual Hosts einzurichten. Damit kann die Seite im Browser unter der späteren URL wie sebastianviereck.de erreichbar gemacht werden, obwohl Sie für andere noch nicht Online ist oder man die Domain noch nicht besitzt.

Normalerweise ruft man lokale Webseiten mit der URL wie:

http://localhost/sebastianviereck/

auf.

Wenn man stattdessen lieber die URL

http://sebastianviereck.local/

aurufen will, muss man einfach folgendes machen:

1. Die Datei

bei Windows xampp\apache\conf\extra\ httpd-vhosts.conf

bei MAC  /Applications/XAMPP/xamppfiles/apache2/conf/httpd.conf

ändern:

<Directory /xampp/htdocs    >   
    Order Allow,Deny   
    Allow from all 
</Directory>

NameVirtualHost *:80

<VirtualHost *:80>   
    DocumentRoot "/xampp/htdocs"
    ServerName localhost 
</VirtualHost> 

<VirtualHost *:80>   
    DocumentRoot "/xampp/htdocs/sebastianviereck"
    ServerName sebastianviereck.local
</VirtualHost>

2. Die Datei

bei Windows: C:\Windows\System32\drivers\etc\hosts

bei MAC /private/etc/hosts

ändern:

127.0.0.1  sebastianviereck.local
127.0.0.1   localhost   #damit localhost noch funktioniert, am Ende einfügen

3. Apache neu starten.

4. Im Browser erscheint dann bei der Eingabe von sebastianviereck.local die eigene lokale Webseite.

Kategorien
Diverses

Google Mail – unsichere Verbindung

Das google Mail nicht sicher ist und „unbefugte Dritte“ versuchen könnten Informationen zu stehlen, hat jeder schon vermutet, jetzt wird es auch von Google selber endlich zugegeben im Chrome:

google_mail_unsichere_verbindung

Kategorien
PHP PHP 7

PHP How to debug Segmentation Faults

Um Segementation Faults, die gerne in PHP7 zur Zeit auftreten zu bestimmen und zu analysieren, kann man folgender Weise vorgehen

1. Angabe des Speicherortes für die Coredumps

echo '/tmp/coredump_%e_%p' > /proc/sys/kernel/core_pattern

2. aktivieren der Coredumps in PHP-FPM

in der Datei: php-fpm.conf:

rlimit_core = unlimited     ; vorher: 0

3. PHP FPM restarten

service php-fpm restart

4. Analysieren der Coredumps mit gdb

Kategorien
PHP

SSH Verbindung mit PHP

Um eine SSH Verbindung mit PHP zu erstellen, gibt es mehrere Möglichkeiten:

Die saubere Lösung: Verbinden mit PHP-SSH2

Dazu muss die das Package php-ssh2 installiert werden, siehe php.net.

    $connection = ssh2_connect($host, $port);
    if(ssh2_auth_password($connection, $user, $password)){
        $stream = ssh2_exec($connection, $command);
        stream_set_blocking($stream, false);
        $stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
        $result = stream_get_contents($stream_out);
    }

Quick and dirty: Verbinden mit exec()

Einfach über die Console des Betriebsystems (sshpass sollte installiert werden, damit das Passwort mitangegeben werden kann).

$command = 'sshpass -p "'
    . $password
    . '" ssh -p '.$port.' '
    . $user. '@'. $host. ' "'
    . $sshCommand.'" ';
$result = exec($command);

Fingerprint umgehen bei wechselnden Ports

$command = 'sshpass -p "'
    . $password
    . '" ssh -p '.$port.' -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '    
    . $user. '@'. $host. ' "'
    . $sshCommand.'" ';
$result = exec($command);

In dem Beispiel wird mittels der Parameter

-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no

die Fingerprint-Validierung umgangen, was man im Livebetrieb nicht machen sollten, bzw. man sollte sich den Fingerprint vorher auf der Console der Servers besorgen und dann benötigt man diese Parameter nicht.

 

Kategorien
PHP Server Administration

Nagios Plugins mit PHP schreiben

Nagios Plugins zum Monitoring von Servern und Funktionalitäten kann man in jeder verfügbaren Sprache schreiben. Die einzige Regel, an die man sich halten muss ist, dass der Return Code des Scriptes und der Response Text (enthält auch die Performance Daten) nach einem bestimmten Schema aufgebaut werden muss.

Als Hilfe kann man die Klasse NagiosPlugin benutzen, um Plugins zu schreiben:

abstract class NagiosPlugin {

    /**
     * @var boolean
     */
    protected $verbose = false;

    /**
     * setVerboseModeFromArgv
     * @see https://nagios-plugins.org/doc/guidelines.html#AEN41
     *
     * @param $argv
     * @return void
     */
    public function setVerboseModeFromArgv($argv) {
        if(in_array('-v', $argv)){
            $this->verbose = true;
        }
    }

    /**
     * addVerboseMessage
     *
     * @param $message
     * @return void
     */
    protected function displayVerboseMessage($message){
        if($this->verbose){
            echo $message.PHP_EOL;
        }
    }

    /**
     * endWithStatusOk
     * @see https://nagios-plugins.org/doc/guidelines.html#AEN200
     *
     * @param string $message
     * @param string $performanceData has format "nameOfData=value"
     * @return void
     */
    protected function endWithStatusOk($message, $performanceData){
        print "OK - $message".$this->addPerformaceData($performanceData);
        exit(0);
    }

    /**
     * endWithStatusWarning
     *
     * @param string $message
     * @param string $performanceData
     * @return void
     */
    protected function endWithStatusWarning($message, $performanceData){
        print "WARNING - $message".$this->addPerformaceData($performanceData);
        exit(1);
    }

    /**
     * endWithStatusCritical
     *
     * @param string $message
     * @param string $performanceData
     * @return void
     */
    protected function endWithStatusCritical($message, $performanceData){
        print "CRITICAL - $message".$this->addPerformaceData($performanceData);
        exit(2);
    }

    /**
     * endWithStatusUnknown
     *
     * @param string $message
     * @param string $performanceData
     * @return void
     */
    protected function endWithStatusUnknown($message, $performanceData){
        print "UNKNOWN - $message".$this->addPerformaceData($performanceData);
        exit(3);
    }

    /**
     * addPerformaceData
     *
     * @param string $performanceData
     * @return string
     */
    private function addPerformaceData($performanceData){
        $result = '';
        if(!empty($performanceData)){
            $result = ' | '.$performanceData;
        }
        return $result;
    }
}