Archive for category Apache

Reducing TIME_WAIT sockets in Nginx and Apache

Edit /etc/sysctl.conf and add

# Enables fast recycling of TIME_WAIT sockets.
# (Use with caution according to the kernel documentation!)
net.ipv4.tcp_tw_recycle = 1

# Allow reuse of sockets in TIME_WAIT state for new connections
# only when it is safe from the network stack’s perspective.
net.ipv4.tcp_tw_reuse = 1

After this run in terminal

sysctl -p




1 Comment

Fighting Back PHP Reverse Shell

To avoid PHP reverse shell, just disable some functions in your php.ini, and restrict PHP working directory:


allow_url_fopen = Off
allow_url_include = Off

disable_functions = apache_get_modules, exec,apache_get_version, apache_getenv, apache_lookup_uri, apache_note, apache_request_headers, apache_reset_timeout, apache_response_headers, apache_setenv, c, chgrp, chmod, chown, debugger_off, debugger_on, define_syslog_var, disk_free_space, dl, escapeshellarg, escapeshellcmd,ftok, ftpexec, gid, glob, highlight_file, hypot, ini_alter, ini_get_all, ini_restore, leak, limit, link, list, listen, ls, mkdir, mysql_list_dbs, openlog, passthru, pclose, pcntl_exec, pfsockpoen, pg_host, phpinfo, popen, pos, posix_access, posix_getcwd, posix_getgid, posix_getpid, posix_getpwnam, posix_getpwuid, posix_getsid, posix_getuid, posix_i, posix_kill, posix_mkfifo, posix_mknod, posix_setgid, posix_setp, posix_setsid, posix_setuid, posix_times, posix_uname, print_rdl, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, ps_aux, ps_fill, readfile, readlink, safe_dir, satty, scandir, set_time, shell_exe, shell_exec, show_source, symlink, symlink, syslog, system, virtual

To websites that does not require PHP or provide public upload areas (where the folder owner is the apache user), add this to your virtual host in http.conf
<VirtualHost *>

php_value register_globals “Off”
php_value session.cache_limiter   “nocache”

php_admin_value open_base_dir /home/wvirt/

php_admin_flag safe_mode “On”

<Directory “/home/wvirt/”>
<FilesMatch “\.(?i:php)$”>
Order allow,deny
Deny from all
Satisfy All

Leave a comment

Apache SSL with Virtual Hosts Using SNI

SSL with Virtual Hosts Using SNI


Using name-based virtual hosts with SSL adds another layer of complication. Without the SNI extension, it’s not generally possible (though a subset of virtual host might work). With SNI, it’s necessary to consider the configuration carefully to ensure security is maintained.

(Note: this page is just about support that comes with the Apache web server. Alternatives such as [WWW] mod_gnutls are another topic.)

The Problem

The problem with using named virtual hosts over SSL is that named virtual hosts rely on knowing what hostname is being requested, and the request can’t be read until the SSL connection is established. The ordinary behavior, then, is that the SSL connection is set up using the configuration in the default virtual host for the address where the connection was received.

While Apache can renegotiate the SSL connection later after seeing the hostname in the request (and does), that’s too late to pick the right server certificate to use to match the request hostname during the initial handshake, resulting in browser warnings/errors about certificates having the wrong hostname in them.

And while it’s possible to put multiple hostnames in a modern certificate and just use that one certificate in the default vhost, there are many hosting providers who are hosting far too many sites on a single address for that to be practical for them.

Server Name Indication

The solution is an extension to the SSL protocol called Server Name Indication ([WWW] RFC 4366), which allows the client to include the requested hostname in the first message of its SSL handshake (connection setup). This allows the server to determine the correct named virtual host for the request and set the connection up accordingly from the start.

With SNI, you can have many virtual hosts sharing the same IP address and port, and each one can have its own unique certificate (and the rest of the configuration).

Prerequisites to use SNI

  • Use OpenSSL 0.9.8f or later
  • Build OpenSSL with the TLS Extensions option enabled (option enable-tlsext; OpenSSL 0.9.9 might have this enabled by default).
  • Apache must have been built with that OpenSSL (./configure –with-ssl=/path/to/your/openssl). In that case, mod_ssl will automatically detect the availability of the TLS extensions and support SNI.
  • Apache must use that OpenSSL at run-time, which might require setting LD_LIBRARY_PATH or equivalent to point to that OpenSSL, maybe in bin/envvars. (You’ll get unresolved symbol errors at Apache startup if Apache was built with SNI but isn’t finding the right openssl libraries at run-time.)

How can you tell if your Apache build supports SNI? If you configure multiple name-based virtual hosts for an address where SSL is configured, and SNI isn’t built into your Apache, then upon Apache startup a message like “You should not use name-based virtual hosts in conjunction with SSL!!” will occur in the error log. If SNI is built in, then the error log will show “[warn] Init: Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366)”.

The client browser must also support SNI. Here are some browsers that do:

  • Mozilla Firefox 2.0 or later
  • Opera 8.0 or later (with TLS 1.1 enabled)
  • Internet Explorer 7.0 or later (on Vista, not XP)
  • Google Chrome
  • Safari 3.2.1 on Mac OS X 10.5.6

(per [WWW] Wikipedia)

Changes in configuration to use SNI

There is one new directive related to using SNI with name-based virtual hosts, SSLStrictSNIVHostCheck, which controls whether to allow non SNI clients to access a name-based virtual host. (Link to Apache doc for that directive)

The first (default) vhost for SSL name-based virtual hosts must include TLSv1 as a permitted protocol, otherwise Apache will not accept the SNI information from the client and it will be as if the client did not support SNI at all.

Since the first (default) vhost will be used for any request where the provided server name doesn’t match another vhost, it is important that the first vhost have the most restrictive access control, otherwise clients can access restricted resources by sending a request for any unknown hostname. (This isn’t actually any different from using virtual hosts without SSL.)

Environment variables

When Apache supports SNI and the client provided the hostname using SNI, the new environment variable SSL_TLS_SNI will be set to the hostname that the client provided.


SNI/Request hostname mismatch, or SNI provides hostname and request doesn’t.

This is a browser bug. Apache will reject the request with a 400-type error.

Client doesn’t support SNI.

If Apache has SNI support, and a request without the SNI hostname is received for a name-based virtual host over SSL, and SSLStrictSNIVHostCheck is on, it will be rejected (403) and this message logged:

[error] No hostname was provided via SNI for a name based virtual host

If SSLStrictSNIVHostCheck is off, then the request will be handled as if the server did not have SNI support; see above.


Server configuration

# Ensure that Apache listens on port 443
Listen 443

# Listen for virtual host requests on all IP addresses
NameVirtualHost *:443

# Go ahead and accept connections for these vhosts
# from non-SNI clients
SSLStrictSNIVHostCheck off

<VirtualHost *:443>
  # Because this virtual host is defined first, it will
  # be used as the default if the hostname is not received
  # in the SSL handshake, e.g. if the browser doesn't support
  # SNI.
  DocumentRoot /www/example1

  # Other directives here


<VirtualHost *:443>
  DocumentRoot /www/example2

  # Other directives here




Apache Security Model

An excellent visual resource to learn about apache methods.

Leave a comment

Apache – Setting the MaxClients Directive

It’s important to specify MaxClients on the basis of the resources your machine has. The MaxClients directive sets the limit on the number of simultaneous requests that can be supported. No more than this number of child server processes will be created. To configure more than 256 clients, you must edit the HARD_SERVER_LIMIT entry in httpd.h and recompile Apache.

With a plain Apache server, it doesn’t matter much if you run many child processes—the processes are about 1 MB each (most of it shared), so they don’t eat a lot of RAM. The situation is different with mod_perl, where the processes can easily grow to 10 MB and more. For example, if you have MaxClientsset to 50, the memory usage becomes 50 × 10 MB = 500 MB.Do you have 500 MB of RAM dedicated to the mod_perl server?

With a high MaxClients, if you get a high load the server will try to serve all requests immediately. Your CPU will have a hard time keeping up, and if the child size multiplied by the number of running children is larger than the total available RAM, your server will start swapping. The swapping will slow down everything, which will lead to more swapping, slowing down everything even more, until eventually the machine will die. It’s important that you take pains to ensure that swapping does not normally happen. Swap space is an emergency pool, not a resource to be used routinely. If you are low on memory and you badly need it, buy it. Memory is cheap.

We want the value of MaxClients to be as small as possible, because in this way we can limit the resources used by the server’s children. Since we can restrict each child’s process size, as discussed later, the calculation of MaxClients is straightforward:


So if we have 400 MB for the mod_perl server to use, we can set MaxClients to 40 if we know that each child is limited to 10 MB of memory.

You may be wondering what will happen to your server if there are more concurrent users than MaxClients. This situation is pointed out by the following warning message in the error_log file:

[Sat May 18 13:40:35 2002] [error] server reached MaxClients setting,
consider raising the MaxClients setting

Technically there is no problem—any connection attempts over the MaxClients limit will normally be queued, up to a number based on the ListenBacklog directive. When a child process is freed at the end of a different request, the next waiting connection will be served.

But it is an error, because clients are being put in the queue rather than getting served immediately, despite the fact that they do not get an error response. The error can be allowed to persist to balance available system resources and response time, but sooner or later you will need to get more RAM so you can start more child processes. The best approach is to prevent this situation from arising in the first place, and if it keeps on happening you should start worrying about it.

The approximate real memory used can be calculated by adding up all the unshared memory of the client processes plus the memory of the parent process, or, if the latter is unknown, the maximum shared memory size of a single child process, which is smaller than the memory size of the parent process but good enough for our calculations. We have also devised the following formula:


where Total_RAM is of course the estimated total RAM available to the web server.

Let’s perform some calculations, first with sharing in place:

Total_RAM                = 500Mb
Max_Process_Size         =  10Mb
Min_Shared_RAM_per_Child =   4Mb

then with no sharing in place:


With sharing in place, if your numbers are similar to the ones in our example, you can have 64% more servers without buying more RAM (82 compared to 50).

If you improve sharing and the sharing level is maintained throughout the child’s life, you might get:

Total_RAM            = 500Mb
Max_Process_Size     =  10Mb

Shared_RAM_per_Child =   8Mb


Depicts requests per second versus MaxClients. Looking at this figure, you can see that with a concurrency level of 300, the performance is almost identical for MaxClients values of 150 and 200, but it goes down for the value of 100 (not enough processes) and are even worse for the value of 250 (too many processes competing over CPU cycles). Note that we have kept the server fully loaded, since the number of concurrent requests was always higher than the number of available processes, which means that some requests were queued rather than responded to immediately. When the number of processes went above 200, more and more time was spent by the processes in the sleep state and context switching, enlarging the latency of response generation. On the other hand, with only 100 available processes, the CPU was not fully loaded and we had plenty of memory available. You can see that in our case, a MaxClients value of 150 is close to optimal.

Figure 11-1

This leads us to an interesting discovery, which we can summarize in the following way: increasing your RAM might not improve the performance if your CPU is already fully loaded with the current number of processes. In fact, if you start more processes, you will get a degradation in performance. On the other hand, if you decide to upgrade your machine with a very powerful CPU but you don’t add enough memory, the machine will use swap memory or the CPU will be under-used; in any case, the performance will be poor. Whenever you opt for a more powerful CPU, you must always budget for enough extra memory to ensure that the CPU’s greater processing power is fully utilized. It is generally best to add more memory in the first place to see if that helps with performance problems (assuming you follow our tuning advice as well).

To discover the right configuration for your server, you should run benchmarks on a machine with identical hardware to the one that you are going to use in production. Try to simulate the probable loads your machine will experience. Remember that the load will be variable, and plan accordingly. Experiment with the configuration parameters under different loads to discover the optimal balance of CPU and RAM use for your machine. When you change the processor or add RAM, retest the configuration to see how to change the settings to get the best from the new hardware.

You can tune your machine using reports like the one in our example, by analyzing either the requests per second (rps) column, which shows the throughput of your server, or the average processing time (avtime) column, which can be seen as the latency of your server. Take more samples to build nicer linear graphs, and pick the value of MaxClients where the curve reaches a maximum value for a throughput graph or reaches the minimum value for a latency graph.