How to install Apache 2.4 on Debian 7

Many people seem to be afraid of mixing stable with testing, but frankly, testing is fairly stable in its own right, and with proper preferences and solution checking, you can avoid the “stability drift” that puts your core packages on the unstable path.

“Testing is fairly stable??”, you ask. Yes. In order for a package to migrate from unstable to testing, it has to have zero open bugs for 10 consecutive days. Chances are that, especially for the more popular packages, somebody is going to submit a bug report for an unstable version if something is wrong.

Even if you don’t want to mix the environments, it’s still nice to have the option there in case you run into some thing that requires a newer version than what is in stable.

Here’s what I recommend for setting this up:

First, create the following files in /etc/apt/preferences.d:

security.pref:

Package: *
Pin: release l=Debian-Security
Pin-Priority: 1000

stable.pref:

Package: *
Pin: release a=stable
Pin-Priority: 995

testing.pref:

Package: *
Pin: release a=testing
Pin-Priority: 750

unstable.pref:

Package: *
Pin: release a=unstable
Pin-Priority: 50

experimental.pref:

Package: *
Pin: release a=experimental
Pin-Priority: 1

(Don’t be afraid of the unstable/experimental stuff here. The priorities are low enough that it’s never going to automatically install any of that stuff. Even the testing branch will behave, as it’s only going to install the packages you want to be in testing.)

Now, creating a matching set for /etc/apt/sources.list.d:

security.list:

deb     http://security.debian.org/         stable/updates  main contrib non-free
deb     http://security.debian.org/         testing/updates main contrib non-free

stable.list:

deb     http://mirror.steadfast.net/debian/ stable main contrib non-free
deb-src http://mirror.steadfast.net/debian/ stable main contrib non-free
deb     http://ftp.us.debian.org/debian/    stable main contrib non-free
deb-src http://ftp.us.debian.org/debian/    stable main contrib non-free

testing.list: Same as stable.list, except with testing.

unstable.list: Same as stable.list, except with unstable.

experimental.list: Same as stable.list, except with experimental.

You can replace the steadfast.net mirror with whatever you want. I’d recommend using netselect-aptto figure out the fastest mirror, and use that for your first choice. The ftp.us.debian.org can be used as a backup. It’s also important to use the terms stable, testing, unstable, etc., instead of squeeze, wheezy, sid, etc., since stable is a moving target and when it comes time to upgrade to the latest stable, apt/aptitude will figure that out automatically.

You can also add a oldstable in sources.lists.d and preferences.d (use a priority of 1), though this moniker will tend to expire and disappear before the next stable cycle. In cases like that, you can use http://archive.debian.org/debian/ and “hardcode” the Debian version (etch, lenny, etc.).

To install the testing version of a package, simply use aptitude install lib-foobar-package/testing, or just jump into aptitude’s GUI and select the version inside of the package details (hit enter on the package you’re looking at).

If you get complaints of package conflicts, look at the solutions first. In most cases, the first one is going to be “don’t install this version”. Learn to use the per-package accept/reject resolver choices. For example, if you’re installing foobar-package/testing, and the first solution is “don’t install foobar-package/testing”, then mark that choice as rejected, and the other solutions will never veer to that path again. In cases like these, you’ll probably have to install a few other testing packages.

If it’s getting too hairy (like it’s trying to upgrade libc or the kernel or some other huge core system), then you can either reject those upgrade paths or just back out of the initial upgrade altogether. Remember that it’s only going to upgrade stuff to testing/unstable if you allow it to.


Thank you Brendan Byrd.

Apache MPM-ITK vs MPM-Event vs MPM-Worker vs MPM-Prefork

Ever wondered what are all these MPMs? Let us find out.

1. Apache MPM-ITK: is based on the traditional prefork MPM, which means it’s non-threaded; in short, this means you can run non-thread-aware code (like many PHP extensions) without problems. On the other hand, you lose out to any performance benefit you’d get with threads, of course; you’d have to decide for yourself if that’s worth it or not. You will also take an additional performance hit over prefork, since there’s an extra fork per request.
• allows you to run each of your vhost under a separate uid and gid

2. Apache MPM-Event: is designed to allow more requests to be served simultaneously by passing off some processing work to supporting threads, freeing up the main threads to work on new requests. It is based on the worker MPM, which implements a hybrid multi-process multi-threaded server. Run-time configuration directives are identical to those provided by worker.
• multi-process multi-threaded server

3. Apache MPM-Worker: implements a hybrid multi-process multi-threaded server. By using threads to serve requests, it is able to serve a large number of requests with fewer system resources than a process-based server.
• stability of a process-based server by keeping multiple processes available, each with many threads

4. Apache MPM-Prefork: implements a non-threaded, pre-forking web server. Each server process may answer incoming requests, and a parent process manages the size of the server pool.
• for sites that need to avoid threading for compatibility with non-thread-safe libraries.
• best MPM for isolating each request, so that a problem with a single request will not affect any other.

Mod_SPDY with Ubuntu 14.04 x64 and Apache 2.4

Since MOD_SPDY was packaged (deb/rpm) up to Apache 2.2, you’ll have to compile from source in order to enable it in Apache 2.4.X.

After several tries, this gentleman here nailed it:

$ cd /tmp
$ sudo apt-get -y install git g++ libapr1-dev libaprutil1-dev curl patch binutils make devscripts
$ git clone https://github.com/eousphoros/mod-spdy.git
$ cd mod-spdy/src
$ ./build_modssl_with_npn.sh
$ chmod +x ./build/gyp_chromium
$ make BUILDTYPE=Release
$ service apache2 stop
$ cd /usr/lib/apache2/modules
$ mv mod_ssl.so mod_ssl.so.bak
$ cd /tmp/mod-spdy/src
$ sudo cp mod_ssl.so /usr/lib/apache2/modules
$ service apache2 start
$ sudo a2enmod ssl
$ service apache2 restart
$ sudo cp out/Release/libmod_spdy.so /usr/lib/apache2/modules/mod_spdy.so
$ echo "LoadModule spdy_module /usr/lib/apache2/modules/mod_spdy.so" | sudo tee /etc/apache2/mods-available/spdy.load
$ echo "SpdyEnabled on" | sudo tee /etc/apache2/mods-available/spdy.conf
$ sudo a2enmod spdy
$ service apache2 restart

PS: don’t use mod_php with SPDY!


Michael writes

Also, I needed to install libpcre3 and libpcre3-dev to get past the “Configuring Apache mod_ssl” in the ./build_modssl_with_npn.sh script (pcre-config for libpcre was not found).

You feedback is continuously appreciated.

Use strong SSL for your web server: apache, nginx or lighttpd

Strong Ciphers for:

Apache

SSLCipherSuite AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3
SSLCompression off
SSLHonorCipherOrder On
SSLUseStapling on # Requires Apache >= 2.4
SSLStaplingCache "shmcb:logs/stapling-cache(150000)" # Requires >= Apache 2.4
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set X-Frame-Options DENY

Nginx:

ssl_ciphers 'AES256+EECDH:AES256+EDH';
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache  builtin:1000  shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
add_header X-Frame-Options DENY;
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
resolver_timeout 5s;

Lighttpd:

ssl.honor-cipher-order = "enable"
ssl.cipher-list = "AES256+EECDH:AES256+EDH"
ssl.use-compression = "disable"
setenv.add-response-header = (
    "Strict-Transport-Security" => "max-age=63072000; includeSubDomains",
    "X-Frame-Options" => "DENY"
)
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"

If you need to support Windows XP, use these:
Apache:

SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 
SSLProtocol All -SSLv2 -SSLv3
SSLCompression off
SSLHonorCipherOrder On
SSLUseStapling on # Requires Apache >= 2.4
SSLStaplingCache "shmcb:logs/stapling-cache(150000)" # Requires >= Apache 2.4
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set X-Frame-Options DENY

Nginx:

ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache  builtin:1000  shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
add_header X-Frame-Options DENY;
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
resolver_timeout 5s;

Lighttpd:

ssl.honor-cipher-order = "enable"
ssl.cipher-list = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"
ssl.use-compression = "disable"
setenv.add-response-header = ("Strict-Transport-Security" => "max-age=63072000; includeSubDomains")
setenv.add-response-header = ("X-Frame-Options" => "DENY")
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
Mirror of: https://cipherli.st/

Apache nginx style config: apache2-mod-worker with PHP5-FPM

Did you know that you can run the old fart apache2 server as a “nginx + php5-fpm”? Will publish some blitz.io values for better comparison.

Here we’ll get a working apache2 server which will pass the php requests to php5-fpm, acting as a static file serving… server. Why not using nginx, you might ask? I’m too lazy to convert .htaccess to a .nginx-compatible-file.conf.

1. apt-get install apache2 apache2-bin apache2-data apache2-mpm-worker apache2-utils libapache2-mod-fcgid libapache2-mod-ruid2

This version does NOT understand php at all. If you’d like your “mpm” to dance with builtin php, go with apache2-mod-prefork + libapache2-mod-php5.

  1. Scroll inside apache config /etc/apache2/conf-available/php5-fpm.conf and paste these lines:
<IfModule mod_fastcgi.c>
 AddHandler php5-fcgi .php
 Action php5-fcgi /php5-fcgi
 Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
 FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization
</IfModule>
<Directory /usr/lib/cgi-bin>
 Require all granted
</Directory>

The IfModule explains to apache where it can find the php executable. Don’t forget to enable the necessary mods:

  • a2enmod actions fastcgi alias

and to enable (activate) the config file above:

  • a2enconf php5-fpm
  1. Go into /etc/php5/fpm/pool.d/www-conf and tweak the parameters to your desired needs. This may include
  • setting a timeout
  • setting a limit for spawned children & a total number of requests it will serve each and every one

Your phpinfo(); should work from this point.

Later edit:

Nginx + PHP5-FPM results:

This rush generated 7,651 successful hits in 30 seconds and we transferred 21.83 MB of data in and out of your app. The average hit rate of 310.93/second translates to about 26,864,640 hits/day.
The average response time was 599 ms.
This test was aborted at 28 seconds.
RESPONSE TIMES
  • FASTEST: 276 MS
  • SLOWEST: 1,081 MS
  • AVERAGE: 599 MS
TEST CONFIGURATION
  • REGION: VIRGINIA
  • DURATION: 30 SECONDS
  • LOAD: 1-1000 USERS
OTHER STATS
  • AVG. HITS: 311 /SEC
  • DATA TRANSFERED:21.83MB
HITS

This rush generated 7,651 successful hits. The number of hits includes all the responses listed below. For example, if you only want HTTP 200 OK responses to count as Hits, then you can specify --status 200 in your rush.

CODE TYPE DESCRIPTION AMOUNT
200 HTTP OK 2075
404 HTTP Not Found 5576

Apache2-mod-worker + PHP5-FPM results

ANALYSIS
This rush generated 1,243 successful hits in 30 seconds and we transferred 11.73 MB of data in and out of your app. The average hit rate of 43.57/second translates to about 3,764,160 hits/day.
The average response time was 2,945 ms.
This test was aborted at 28 seconds.
You've got bigger problems, though: 51.41% of the users during this rushexperienced timeouts or errors!
RESPONSE TIMES
  • FASTEST: 110 MS
  • SLOWEST: 4,363 MS
  • AVERAGE: 2,945 MS
TEST CONFIGURATION
  • REGION: IRELAND
  • DURATION: 30 SECONDS
  • LOAD: 1-1000 USERS
OTHER STATS
  • AVG. HITS: 44 /SEC
  • DATA TRANSFERED: 11.73MB
  • HITS 48.59% (1243)
  • ERRORS 17.51% (448)
  • TIMEOUTS 33.89% (867)
 HITS

This rush generated 1,243 successful hits. The number of hits includes all the responses listed below. For example, if you only want HTTP 200 OK responses to count as Hits, then you can specify --status 200 in your rush.

CODE TYPE DESCRIPTION AMOUNT
200 HTTP OK 1243
HITS
  • HTTP 200 OK 100% (1243)
 ERRORS

The first error happened at 27.5 seconds into the test when the number of concurrent users was at 916. Errors are usually caused by resource exhaustion issues, like running out of file descriptors or the connection pool size being too small (for SQL databases).

CODE TYPE DESCRIPTION AMOUNT
23 TCP Connection timeout 448 ERRORS
  • CONNECTION TIMEOUT 100% (448)

This is the result i got on a 4vCores VPS, 1024MB RAM and 512MB vSwap along with 100GB HDD.

Good luck at learning nginx syntax!