Paypal hat für 2016 Sicherheitsupdates für Händler angekündigt. Damit die IPN Abfragen auch in Zukunft reibungslos funktionieren, ist es sehr wichtig, die eigenen Systeme zu aktualisieren. In meinem Fall betrifft dies die Abfrage mit PHP / CURL. Es geht um folgende zwei Paypal Upgrades :

Mit folgendem Befehl kannst du direkt in der Shell prüfen, ob dein System die Sicherheitsupgrades von PayPal bereits unterstützt:

php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); var_dump(curl_exec($ch));'
  • Wenn alles gut ist, wird PayPal_Connection_OK ausgegeben.
  • Bei einem Fehler kommt bool(false).

Einen ausführlicheren Output gibts so:

php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); var_dump(curl_exec($ch)); var_dump(curl_error($ch));'

Was, wenn der CURL Test fehl schlägt…

Folgendes musst du wissen:

  • Mindestvoraussetzung ist die CURL Library 7.34.0 oder neuer
  • PHP – bzw. php-curl – nutzt die auf dem System installierte CURL Library
  • OpenSSL muss TLS 1.2 unterstützen. Mindestvoraussetzung ist OpenSSL 1.0.1c – diese sollte aber wegen dem Heartbleed Bug nicht verwendet werden. Am besten auf die aktuellste Version upgraden.

Teste direkt mit CURL

 # curl --http1.1 --tlsv1.2 --head https://tlstest.paypal.com/

curl: (35) Unsupported SSL protocol version
# curl -v https://tlstest.paypal.com/

* Trying 104.86.166.31...
* Connected to tlstest.paypal.com (104.86.166.31) port 443 (#0)
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /usr/local/share/certs/ca-root-nss.crt
CApath: none
* TLSv1.0 (OUT), TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to tlstest.paypal.com:443
* Closing connection 0
curl: (35) Unknown SSL protocol error in connection to tlstest.paypal.com:443

Daran hab ich lange herumgedocktert. Ich hatte CURL aktualisiert, jedoch hab ich es per Paketmanager (pkg) installiert.

curl-7.47.1 = up-to-date with index

Beim vorkompilierten Paket wird anscheinend – wahrscheinlich wegen dem Heartbleed Bug – eine veraltete OpenSSL Version verwendet:

# curl --version

curl 7.47.1 (amd64-portbld-freebsd9.3) libcurl/7.47.1 OpenSSL/0.9.8y zlib/1.2.7
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz UnixSockets

Obwohl ich auf meinem System OpenSSL Version 1.0.2.g habe, betrifft dies curl nicht, da ich es mit pkg install curl installiert habe.

# openssl version

OpenSSL 1.0.2g 1 Mar 2016

Lösung:

CURL Manuell kompilieren & locken, damit es beim nächsten pkg upgrade nicht wieder überschrieben wird.

# pkg unlock curl
# cd /usr/ports/ftp/curl; make clean; make; make deinstall; make reinstall
# pkg lock curl
curl-7.47.1: lock this package? [y/N]: y
Locking curl-7.47.1

und siehe da:

# curl --version
curl 7.47.1 (amd64-portbld-freebsd9.2) libcurl/7.47.1 OpenSSL/1.0.2g zlib/1.2.7
# curl --http1.1 --tlsv1.2 --head https://tlstest.paypal.com/
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 20
Date: Wed, 16 Mar 2016 14:23:54 GMT
Connection: keep-alive

Damit das jetzt in PHP auch läuft, muss PHP ebenfalls manuell kompiliert werden (nur die php-curl extension zu upgraden nützt leider nichts)

# php -i | grep -is ssl
Registered Stream Socket Transports => tcp, udp, unix, udg, ssl, sslv3, sslv2, tls, tlsv1.0
SSL => Yes
SSL Version => OpenSSL/0.9.8y
SSL Support => enabled
core SSL => supported
extended SSL => not supported
openssl
OpenSSL support => enabled
OpenSSL Library Version => OpenSSL 0.9.8y 5 Feb 2013
OpenSSL Header Version => OpenSSL 0.9.8zh-freebsd 3 Dec 2015
Openssl default config => /etc/ssl/openssl.cnf
openssl.cafile => no value => no value
openssl.capath => no value => no value
OpenSSL support => enabled

WICHTIG! Damit OpenSSL vom Port und nicht Base verwendet wird, unbedingt Makefile noch anpassen:

cd /usr/ports/lang/php56
vi Makefile

Hier nun –with-openssl=/usr/local  hinzufügen:

CONFIGURE_ARGS+=--with-layout=GNU \
--localstatedir=/var \
--with-config-file-scan-dir=${PREFIX}/etc/php \
--disable-all \
--enable-libxml \
--enable-mysqlnd \
--with-libxml-dir=${LOCALBASE} \
--with-pcre-regex=${LOCALBASE} \
--with-zlib-dir=/usr \
--with-openssl=/usr/local \
--program-prefix=""

Dann neu kompilieren:

make clean; make; make deinstall; make reinstall

pkg lock php56

Jetzt klappts 🙂

Nun am Besten php-openssl auch neu builden:

cd /usr/ports/security/php56-openssl; make clean; make; make deinstall; make reinstall
pkg lock php56-openssl

Nun klappts auch mit PayPal

# php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); var_dump(curl_exec($ch));'
PayPal_Connection_OKbool(true)

Probleme / Fehlermeldungen

Das ganze hat mir doch schon recht Kopfzerbrechen bereitet. Ich habe php / curl / openssl gefühlt tausend mal neu kompiliert und es wurd einfach immer noch die alte OpenSSL Library in PHP angezeigt. Wirklich keine Ahnung, woher die noch kam? Es schien alles korrekt gelinkt zu sein?

# pkg info php56-curl-5.6.19
php56-curl-5.6.19
Name           : php56-curl
Version        : 5.6.19
Installed on   : Wed Mar 16 15:56:18 2016 CET
Origin         : ftp/php56-curl
Architecture   : freebsd:9:x86:64
Prefix         : /usr/local
Categories     : ftp
Licenses       : PHP301
Maintainer     : ale@FreeBSD.org
WWW            : http://www.php.net/
Comment        : The curl shared extension for php
Shared Libs required:
        libcurl.so.4

 

#  ldd /usr/local/lib/libcurl.so.4
/usr/local/lib/libcurl.so.4:
        libssl.so.8 => /usr/local/lib/libssl.so.8 (0x801263000)
        libcrypto.so.8 => /usr/local/lib/libcrypto.so.8 (0x8014d8000)
        libz.so.6 => /lib/libz.so.6 (0x80190b000)
        libc.so.7 => /lib/libc.so.7 (0x80081b000)
        libthr.so.3 => /lib/libthr.so.3 (0x801b1f000)
# pkg shlib libssl.so.8
libssl.so.8 is provided by the following packages:
openssl-1.0.2_11
libssl.so.8 is linked to by the following packages:
cyrus-imapd23-2.3.19_1
ruby-2.1.8,1
python27-2.7.11_1
nagios-plugins-2.1.1_5,1
curl-7.47.1

OpenSSL Versionen sind auch ok:

# /usr/bin/openssl version                                                      
OpenSSL 1.0.2g  1 Mar 2016
# /usr/local/bin/openssl version
OpenSSL 1.0.2g  1 Mar 2016

Ok.. bin etwas weiter. Die OpenSSL BASE Version habe ich einfach mal auf die neuere verlinkt

/usr/bin/openssl@ -> /usr/local/bin/openssl

Die alte Version ist

# /usr/local/bin/openssl_OLD version
OpenSSL 0.9.8y 5 Feb 2013

Und das ist die, die bei PHP kompiliert wird. Ich muss also schauen, dass PHP mit dem OpenSSL PORT kompiliert und nicht mit der BASE Version.

Ich habe zwar von anfang an folgendes in der /etc/make.conf Datei drin, das scheint aber nichts zu bringen:

WITH_OPENSSL_PORT=yes
OPENSSLBASE=/usr/local #Nimm OpenSSL vom Port und nicht vom Base System

Wenigstens das bringt schon mal einen kleinen Teilerfolg:

cd /usr/ports/security/php56-openssl; make clean; make; make deinstall; make reinstall
# php -i |grep SSL
SSL => Yes
SSL Version => OpenSSL/0.9.8y
SSL Support => enabled
core SSL => supported
extended SSL => not supported
OpenSSL support => enabled
OpenSSL Library Version => OpenSSL 0.9.8y 5 Feb 2013
OpenSSL Header Version => OpenSSL 1.0.2g 1 Mar 2016
OpenSSL support => enabled

Aber Curl hat immer noch die alte Version!!

Lösung: Makefile von PHP editieren. Dann klappts:

cd /usr/ports/lang/php56
vi Makefile

Hier nun –with-openssl=/usr/local  hinzufügen:

CONFIGURE_ARGS+=--with-layout=GNU \
--localstatedir=/var \
--with-config-file-scan-dir=${PREFIX}/etc/php \
--disable-all \
--enable-libxml \
--enable-mysqlnd \
--with-libxml-dir=${LOCALBASE} \
--with-pcre-regex=${LOCALBASE} \
--with-zlib-dir=/usr \
--with-openssl=/usr/local \
--program-prefix=""

Und nochmal frisch kompilieren:

make clean; make; make deinstall; make reinstall

UND ENDLICH GEHTS!!!!!  – mich hat dieses Problem jetzt echt einige Tage beschäftigt. Tsss…

Unbedingt dran denken php56 zu  locken – sonst wird beim nächsten pkg upgrade gleich wieder alles zunichte gemacht.

pkg lock php56
# php -i |grep SSL
SSL => Yes
SSL Version => OpenSSL/1.0.2g
SSL Support => enabled
core SSL => supported
extended SSL => supported
OpenSSL support => enabled
OpenSSL Library Version => OpenSSL 1.0.2g 1 Mar 2016
OpenSSL Header Version => OpenSSL 1.0.2g 1 Mar 2016
OpenSSL support => enabled

Und finaler Test:

# php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); var_dump(curl_exec($ch));'
PayPal_Connection_OKbool(true)

.

Flattr this!