http/2.0 sslciphersuites alias crypto wars part three

It has been a while since I wrote part two of the crypto wars. Luckily Peter Mosmans has backported ChaCha20 and Poly1305 ciphers of OpenSSL 1.1.0 to 1.0.2 on github so that at least Chrome browser can use 256 bit encryption over HTTP/2

However on the httpd dev mailing list there are a few people already talking about making changes to APR and httpd so that it will compile with OpenSSL 1.1.0

The config for that is:

SSLProtocol -all +TLSv1 +TLSv1.1 +TLSv1.2 
SSLCompression Off 
SSLHonorCipherOrder On 
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA

Why 256 bit? 128 bit hasn’t been cracked yet. The answer is that the collection of data and the data will decrypted when the time has come with a new generation of computers.

http/2.0 sslciphersuites alias crypto wars part two

With the upcoming mod_h2 the httpd apache module for HTTP/2.0 support there is a must to have ECDHE-RSA-AES128-GCM-SHA256 in the SSLCipherSuite[1]. So SSLHonorCipherOrder Off can’t be used. That leaves the connection with only 128 bit encryption instead of 256 bit.

My hope is that the browsers will support soon a 256 Cipher

 

[1] https://http2.github.io/http2-spec/#rfc.section.9.2.2

Apache 2.4 Disallow access to a certain location if a query string is set

Disallow access / require an IP to a certain location if a query string is set

 <LocationMatch ^/test.php>
        <If "%{QUERY_STRING} =~ /action=login/">
            Require ip 192.168.178.100
        </If>
    </LocationMatch>

http://localhost/test.php works for everyone.

http://localhost/test.php?action=login works only for the ip 192.168.178.100

The “new” Apache 2.4 is different if you compare it to the 2.2 version of things. But once you understand it, it makes things easier and more readable. With 2.2 you would have needed more lines and mod_rewrite to get that working. See also Apache 2.4.x Better than rewriting

SSLCipherSuite alias crypto wars

Choosing the correct SSL cipher can be very difficult. Having the best encryption, still fast, having a “Modern compatibility”.

 

The current best solustion is with all browsers to have 256 bit encryption ( Chrome is currently the only browser that uses only 128 bit with this config).
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK

— Edit —

Chrome might barf about a not modern config, hoever the encryption is not 256 in all cases. That is why I switched back to

SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:!LOW:!MD5:!aNULL:!eNULL:!3DES:!EXP:!PSK:!SRP:!DSS

Public Key Pinning php for httpd apache

Public Key Pinning Extension for HTTP (HPKP) on Apache2. HPKP tries to detect MITM attacks with valid certificates. The browser stores the hash code in the internal storage and verifies the public key against that sum.

Since it is not that easy to create a public pin under windows, here is a php script that does this

<?php
// openssl x509 -in example.crt -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64
if(!isset($argv['1'])){
    die('certificate not set');
}
$certificate = $argv['1'];
$public_key = openssl_get_publickey(file_get_contents($certificate));
$public_key_details = openssl_pkey_get_details($public_key);
$public_key_pem = $public_key_details['key'];

//Convert PEM to DER before SHA1'ing
$string_start = '-----BEGIN PUBLIC KEY-----';
$string_end = '-----END PUBLIC KEY-----';
$pem_trimed = substr($public_key_pem, (strpos($public_key_pem, $string_start)+strlen($string_start)), (strlen($public_key_pem) - strpos($public_key_pem, $string_end))*(-1));
$der = base64_decode($pem_trimed);

// 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= is an empty hash
echo PHP_EOL. "Header always set Public-Key-Pins 'pin-sha256=\"" . base64_encode(openssl_digest($der,'sha256',true)) ."\"; pin-sha256=\"bZ3qT75yZLagDEADBEEF0h3KAseeheXXJ5dliOfLB2A=\"; max-age=5184000'". PHP_EOL;

Add that config statement to correct SSL vhost

 

C:\>php public_pinning.php example.crt
<VirtualHost *:443>
	ServerName example.com
    ServerAlias www.example.com
Header always set Public-Key-Pins "pin-sha256=\"bZ3qT75yZLagDEADBEEF0h3KAseeheXXJ5dliOfLB2A=\"; "pin-sha256=\"sef3575yZLagDEADBEEF0h3KAseeheXXJ5dliOfLdfe=\"; max-age=5184000"

How to set up git over apache 2.4 on Windows

How to set up git apache 2.4 on Windows

At my first shot I was abl to glone the repo but I wasn’t able to push into the repo. Setting the LogLevel to debug showed: AH01215: Service not enabled: ‘receive-pack’: C:/Program Files (x86)/Git/libexec/git-core/git-http-backend.exe

Googling suggested to enable WebDAV. I doubted that but tried it anyway. Trail and error! It did not work about. The git client showed a 403 -> an access or authentication error.   The authentication triggered something in my mind. So I searched for the auth variable that git uses. Et voilà: Git uses the remote user in a different way.
SetEnv REMOTE_USER $REDIRECT_REMOTE_USER
The following set up is not secure, just for local testing. It requires  a http authentication ;)

<VirtualHost *:80>
    ServerName git.local.apachehaus.de
    DocumentRoot "/Users/mario/work/git"
    CustomLog "C:\nul" common

    SetEnv GIT_PROJECT_ROOT /Users/mario/work/git
    SetEnv GIT_HTTP_EXPORT_ALL true
    SetEnv REMOTE_USER $REDIRECT_REMOTE_USER

    ScriptAliasMatch "(?x)^/(.*/(HEAD | info/refs | objects/(info/[^/]+ | [0-9a-f]{2}/[0-9a-f]{38} | pack/pack-[0-9a-f]{40}.(pack|idx)) | git-(upload|receive)-pack))$" "C:/Program Files (x86)/git/libexec/git-core/git-http-backend.exe/$1"

    <Directory "/Users/mario/work/git">
        Options Indexes FollowSymLinks ExecCGI
        AllowOverride All
        Require all granted
    </Directory>
    <Directory "C:/Program Files (x86)/git/libexec/git-core/">
        Options ExecCGI
    </Directory>
    <Directory />
        Options Indexes FollowSymLinks ExecCGI
        Require all granted
    </Directory>
</VirtualHost>

fcgid x-httpd-php-source highlighting

The new way running PHP on apache not as a module but over fcgid can increase the performance on a multicore CPU system and it is possible to run the PHP process not as the apache user (often www-data), but for example as the ftp user. So when apache creates a file the owner is not www-data, but the ftp user.
I’ve seen many setups allowing ExecCGI  for the vhost. That is a bad practice. It is much better allow it only for the needed files.

<VirtualHost *:80>
    ServerName example.local
    DocumentRoot "/Users/mario/www"
    CustomLog "C:\nul" common
    <IfModule fcgid_module>
        FcgidPassHeader Authorization
        <Files ~ "\.php$">
            Options ExecCGI
            AddHandler fcgid-script .php
            FcgidWrapper "C:/users/mario/php5/php-cgi.exe" .php
        </Files>
    </IfModule>
    <Directory "/Users/mario/www>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

With the module it was possible to highlight PHP file with x-httpd-php-source. That option is not available with fcgid. So I had to think how to enable with but not going back to the module which often crashed my apache.

 

What works is to use the php parameters on the command line.

        <Files ~ "\.phps$">
            Options ExecCGI
            AddHandler fcgid-script .php
            FcgidWrapper "C:/users/mario/php5/php-cgi.exe -s" .php
        </Files>

 

A full example on Windows.

<IfModule fcgid_module>
    FcgidConnectTimeout 10
    FcgidMaxProcesses 300
    FcgidMaxProcessesPerClass 300
    FcgidOutputBufferSize 64
    ProcessLifeTime 0
    FcgidMaxRequestsPerProcess 0
    FcgidMinProcessesPerClass 0
    FcgidFixPathinfo 0
    FcgidProcessLifeTime 0
    FcgidZombieScanInterval 20
    FcgidMaxRequestLen 536870912
    FcgidIOTimeout 120
    FcgidTimeScore 3
</IfModule>

<VirtualHost *:80>
    ServerName example.local
    DocumentRoot "/Users/mario/www"
    CustomLog "C:\nul" common
    <IfModule fcgid_module>
        FcgidInitialEnv PHPRC "C:\\Users\mario\\php5"
        FcgidInitialEnv PATH "C:\\Users\mario\\php5;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;"
        FcgidInitialEnv SystemRoot "C:\\Windows"
        FcgidInitialEnv SystemDrive "C:"
        FcgidInitialEnv TEMP "C:\\WINDOWS\\TEMP"
        FcgidInitialEnv TMP "C:\\WINDOWS\\TEMP"
        FcgidInitialEnv windir "C:\\WINDOWS"
        FcgidPassHeader Authorization
        <Files ~ "\.php$">
            Options ExecCGI
            AddHandler fcgid-script .php
            FcgidWrapper "C:/users/mario/php5/php-cgi.exe" .php
        </Files>
        <Files ~ "\.phps$">
            Options ExecCGI
            AddHandler fcgid-script .php
            FcgidWrapper "C:/users/mario/php5/php-cgi.exe -s" .php
        </Files>
    </IfModule>
    <Directory "/Users/mario/www>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

On Linux is is just a little different

 

FCGIWrapper /usr/bin/php5-cgi .php

and only

FcgidPassHeader Authorization

Apache 2.4 global IP blocking list for all vhosts

It is a pain in the ass to set a bunch of IP adresses in each vhost or where ever you need it. But with Apache 2.4 it is quiet easy to have a global list and use that anywhere in your config.

 

Define BADIPS "188.40 46.4 176.9 46.166 46.21 78.46 91.207.7.21 0.0.0.0 91.207.7.182"
<VirtualHost *:80>
    ServerName mariobrandt.de
    ServerAlias www.mariobrandt.de
    DocumentRoot /var/www/
    FileETag MTime Size
    <Directory /var/www/>
        Options Indexes FollowSymLinks Multiviews ExecCGI
        AllowOverride None
    <RequireAll>
    Require all granted
    Require not ip ${BADIPS}
    </RequireAll>
        AddHandler fcgid-script .php
        FCGIWrapper /usr/bin/php5-cgi .php
    </Directory>
    ErrorLog /var/log/apache2/mario_error.log
    LogLevel warn

    CustomLog /var/log/apache2/mario_access.log combined

</VirtualHost>

Archive for category apache

Archives by Month: