Good practice using the .htaccess file

In principle, you should only use .htaccess files when you do not have access to the main server configuration file. For example, the misconception that user authentication should always be done in .htaccess files is widespread. It is also often argued in recent years that mod_rewrite directives should be defined in .htaccess files. This is simply wrong. You can configure user authentication at the primary server configuration level, and this is the preferred method. Similarly, the mod_rewrite directives will work better, in many ways, in the context of the main server.

.Htaccess files should only be used when content providers need to change the server configuration at the directory level, but do not have root access on the server system. If the server administrator does not want to make constant configuration changes, it may be interesting to allow individual users to make these changes themselves through .htaccess files. This is particularly true if the ISP hosts many user sites on a single server, and wants these users to be able to modify their own configurations.

However, in general, it is best to avoid using .htaccess files. Any configuration item you might want to put in a .htaccess file, can also be put, and with the same efficiency, in a section of the configuration file of your main server.

There are two main reasons to avoid using .htaccess files:

  • The first is related to performance. When the AllowOverride directive is set to allow the use of .htaccess files, httpd will look for their presence in each directory. Thus, allowing the use of .htaccess files is already in itself a cause of performance degradation, whether you actually use these files or not! In addition, the .htaccess file is loaded into memory each time a document is queried. Also note that httpd should look for .htaccess files in all top-level directories, in order to gather all the directives that apply to the current directory (See how directives are applied). For example, if a file is being queried from a / www / htdocs / example directory, httpd should look for the following files:

    /.htaccess /www/.htaccess /www/htdocs/.htaccess /www/htdocs/exemple/.htaccess

    As a result, each access to a file in this directory requires 4 additional file system accesses to search for .htaccess files, even if none of these files are present. Note that this example can only occur if .htaccess files have been allowed for the / directory, which is rarely the case.

  • The second reason to avoid using .htaccess files is related to security. If you allow users to change the server configuration, there may be consequences for which you will have no control. Think carefully before giving this privilege to your users. Also note that not giving users the privileges they need will result in increased support requests. Make sure you have clearly informed your users of the level of privileges you have assigned to them. Specifying exactly how you defined the AllowOverride directive and directing users to the corresponding documentation will help you avoid future confusion.

  • Reference:

VirtualHost

The principle of VirtualHost is to allow on the same instance apache to offer several website. Apache was the forerunner of servers offering this method of virtual servers based on IP addresses, which greatly helped this popularity.

There are 2 types of VirtualHost:

  • Based on IP (IP Base): As indicated by the term IP, the server must have different IP address / port pairs for each virtual server per IP. The machine can have multiple physical connections to the network, or use virtual interfaces that are supported by most modern operating systems (See the operating system documentation for details, including "IP aliases" and the command "ifconfig" to enable them), and / or use multiple port numbers. According to the Apache HTTP Server terminology, the use of a single IP address with multiple TCP ports is also similar to IP-based virtual hosting.

  • Name Base: Virtual servers over IP use the IP address of the connection to determine which virtual server should respond. Therefore, you must have different IP addresses for each server. With virtual hosting by name, the server relies on the information provided by the client in the HTTP headers of its requests. The technique presented here allows you to have different virtual servers shared on the same IP address.

With the shortage of IP address available on the internet the use of virtual host IP base are less and less used especially for websites (without https encryption).

Let's see how to configure the 2 types, you will find that this is very similar :).

Virtual servers by IP

To be able to define an IP VirtualHost base you have to have several IPs, otherwise you use virtual servers based on the name. Conceptually VirtualHost based on the port of connection are considered as VirtualHost IP base, I mention it however in the heat of the action on the configuration we do not notice the difference.

    $ sudo ifconfig       eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:01                   inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0                 inet6 addr: fe80::42:acff:fe11:1/64 Scope:Link                 UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1                 RX packets:547 errors:0 dropped:0 overruns:0 frame:0                 TX packets:322 errors:0 dropped:0 overruns:0 carrier:0                 collisions:0 txqueuelen:0                  RX bytes:48132 (48.1 KB)  TX bytes:49572 (49.5 KB)       lo        Link encap:Local Loopback                   inet addr:127.0.0.1  Mask:255.0.0.0                 inet6 addr: ::1/128 Scope:Host                 UP LOOPBACK RUNNING  MTU:65536  Metric:1                 RX packets:0 errors:0 dropped:0 overruns:0 frame:0                 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                 collisions:0 txqueuelen:0                  RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

As you can see there is only one IP address defined (172.17.0.1), we will add the IP 172.17.0.10. We will add this IP, as an alias IP on the map eth0, we will give it the name eth0: 1, this is the most common method. For information we could very well also define the alias with a name such as eth0: moodle. I will demonstrate too.

    $ sudo ifconfig eth0:1 172.17.0.10     $ sudo ifconfig        eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:01                   inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0                 inet6 addr: fe80::42:acff:fe11:1/64 Scope:Link                 UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1                 RX packets:547 errors:0 dropped:0 overruns:0 frame:0                 TX packets:322 errors:0 dropped:0 overruns:0 carrier:0                 collisions:0 txqueuelen:0                  RX bytes:48132 (48.1 KB)  TX bytes:49572 (49.5 KB)       eth0:1    Link encap:Ethernet  HWaddr 02:42:ac:11:00:01                 inet addr:172.17.0.10  Bcast:172.17.255.255  Mask:255.255.0.0                 UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1       lo        Link encap:Local Loopback                   inet addr:127.0.0.1  Mask:255.0.0.0                 inet6 addr: ::1/128 Scope:Host                 UP LOOPBACK RUNNING  MTU:65536  Metric:1                 RX packets:0 errors:0 dropped:0 overruns:0 frame:0                 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                 collisions:0 txqueuelen:0                  RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Demonstration with a name as an alias:

    $ sudo ifconfig eth0:moodle 172.17.0.5       eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:01                   inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0                 inet6 addr: fe80::42:acff:fe11:1/64 Scope:Link                 UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1                 RX packets:547 errors:0 dropped:0 overruns:0 frame:0                 TX packets:322 errors:0 dropped:0 overruns:0 carrier:0                 collisions:0 txqueuelen:0                  RX bytes:48132 (48.1 KB)  TX bytes:49572 (49.5 KB)       eth0:1    Link encap:Ethernet  HWaddr 02:42:ac:11:00:01                 inet addr:172.17.0.10  Bcast:172.17.255.255  Mask:255.255.0.0                 UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1       eth0:moodle Link encap:Ethernet  HWaddr 02:42:ac:11:00:01                 inet addr:172.17.0.5  Bcast:172.17.255.255  Mask:255.255.0.0                 UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

Now that we have 2 IP addresses even 3: P, we will be able to define a virtual server on IP 172.17.0.1 AND 172.17.0.10 or 172.17.0.5.

WARNING: I made the configuration of IP ephemeral, indeed, the next reboot the machine will have only its main IP. To make this configuration permanent validate with the distribution you use, for Ubuntu here is a link IP configuration alias.

We will precede the realization of the first VitualHost for the IP 172.17.0.1, we will call it the site A: P (the inspiration is not present today: P). Following the Ubuntu / Debian principle, we will create the file under the / etc / apache2 / sites-available directory, using a meaningful name.

    $ cat /etc/apache2/sites-available/siteA.conf                  ServerAdmin webmaster@localhost             DocumentRoot /data/vhosts/siteA                                  Options Indexes FollowSymLinks                     AllowOverride None                     Require all granted                  

We keep it simple, as you can see, the first line contains the IP address AND the listening port. I will do the same operation for site B.

    $ cat /etc/apache2/sites-available/siteB.conf                  ServerAdmin webmaster@localhost             DocumentRoot /data/vhosts/siteB                                  Options Indexes FollowSymLinks                     AllowOverride None                     Require all granted                  

Basically we find the same configuration with 2 separate root directory

  • /data/vhosts/siteA

  • /data/vhosts/siteB

We will activate the configuration files, always following the Ubuntu principle by making a symbolic link from the / etc / apache2 / sites-enabled directory to the files contained in the / etc / apache2 / sites-available directory.

    $ cd /etc/apache2/sites-enabled     $ sudo ln -s ../sites-available/siteA.conf .     $ sudo ln -s ../sites-available/siteB.conf .

Let's perform a syntax validation of the configuration files to make sure we have not made a mistake.

    $ sudo apachectl configtest     AH00112: Warning: DocumentRoot [/data/vhosts/siteA] does not exist     AH00112: Warning: DocumentRoot [/data/vhosts/siteB] does not exist     Syntax OK

I wanted to take the opportunity to demonstrate the benefit of using apache validation, it is able to identify problems. In this case the directories of the websites are not present. We will proceed to the realization of the directories as well as the creation of an index file to allow us to identify the 2 sites.

    $ sudo mkdir -p /data/vhosts/siteA     $ sudo mkdir -p /data/vhosts/siteB     $ cat /data/vhosts/siteA/index.html     Le site A     $ cat /data/vhosts/siteB/index.html     Le site B

A small syntactic validation for the road ...

    $ sudo apachectl configtest     Syntax OK

We can start the service:

    $ sudo /etc/init.d/apache2 restart

If we use our browser we will see for URLs: http://172.17.0.1 and http://172.17.0.10 websites:

>It is thus possible to have N site for each IP address available on the system, because when receiving an apache HTTP request will process it using the configuration file with the specific IP. G As you can see while we were viewing the default Ubuntu / Debian page now, we only see Site A when we access the URL http://172.17.0.1. Although we have not disabled the default configuration in the /etc/apache2/sites-enabled/000-default.conf file. Let's take a moment to see the contents of the files:

                 ServerAdmin webmaster@localhost             DocumentRoot /data/www                              Options Indexes FollowSymLinks                 AllowOverride None                 Require all granted                                           Options FollowSymLinks                 AllowOverride AuthConfig                          ErrorLog ${APACHE_LOG_DIR}/error.log             CustomLog ${APACHE_LOG_DIR}/access.log combined     

The VirtualHost instruction is dialed with an asterisk and the port (*: 80) which indicates that this virtual server is valid for all IP addresses on port 80. As we have been more specific in indicating the VirtualHost with IP these The last ones have priorities.

Virtual Servers by Name

As mentioned in the introduction unfortunately with the limited number of IP address (IPv4) available on the internet it is complicated to have an IP address per site. With virtual hosting by name, the server relies on the information provided by the client in the HTTP headers of its requests. The technique presented here allows you to have different virtual servers shared on the same IP address.

Virtual hosting by name is usually easier because you simply configure your DNS server for each domain to point to the IP address you have, and configure your Apache HTTP server to recognize these domains. It also reduces the shortage of IP addresses. Therefore, you should use virtual hosting by name, except in case you use equipment that requires IP-based hosting. The historical reasons for IP-based hosting for the support of some customers no longer apply to a general-purpose web server.

Query processing process

  • Explanation from the apache site It is important to know that the first step of the name-based virtual server resolution is an IP-based resolution. The name-based virtual server resolution simply chooses the virtual server based on the most appropriate name, limiting itself to the most suitable candidates from an IP perspective. IP-based resolution is not applicable if you use a wildcard character (*) for the IP address in all VirtualHost directives.

    When a request arrives, the server will look for the section argument that has the best (most exact) match to the IP address / port pair used in the request. If multiple virtual servers have this same IP address / port pair, Apache will then compare the values of the ServerName and ServerAlias directives with the server name present in the request.

    If you do not set a ServerName directive for a name-based virtual server, the server will default to the fully qualified domain name (FQDN) deduced from the system host name. This configuration without an explicit server name may lead to errors in the choice of the virtual server to use and is deprecated.

  • Now my version: P, it's up to you to choose the clearest. When the client using his browser makes a request to the website, the first step is the DNS resolution, if we take the site www.bob.com the resolution will give the IP: 198.100.146.119. The apache server must have a virtual server configure on this IP address. It can be with the IP specify such as or a more general configuration using a wildcard. If the apache server receives a request for the VirtualHost with the IP address and find that there is more than one definition for this same VirtualHost as the system does not know for which site the request is destined it looks at the header of the request. Indeed when the browser has sent the request on the internet in addition to using the IP to join the server he also asked www.bob.com. Apache will read the VirtualHost configuration files in search of the site name. It will look for 2 ServerName variable which is unique and ServerAlias ​​this input allows to define several name to the virtual server. The system provides the most specific site, if it does not find the name of the site in the set of configuration files matching the IP it will provide one of the virtual servers depending on the loading of the files.

Let's make a small example to have some practice.

We will create name-based virtual servers for the IP address 172.17.0.1, we will perform some tests with the other IP address to demonstrate the difference in processing.

Let's start by associating a virtual server name with site A, so I edit the file /etc/apache2/sites-available/siteA.conf

    $ cat  siteA.conf              ServerAdmin webmaster@localhost         ServerName www.linux202-siteA.com         ServerAlias linux202-siteA.com         ServerAlias toto.linux202-siteA.com         DocumentRoot /data/vhosts/siteA                      Options Indexes FollowSymLinks             AllowOverride None             Require all granted                   $ sudo apachectl configtest && sudo /etc/init.d/apache2 restart

If we use a browser to see the website we will have an error because there is no DNS associated with this name, so we will modify our / etc / hosts file to "simulate" the name resolution. This change is to be realized on the client machine which at the browser to consult the web pages. And this is only a workaround because unfortunately I did not win the lottery I did not buy domain names for training ;-).

So before changing the / etc / hosts file:

    client $ ping www.linux202-siteA.com     ping: unknown host www.linux202-siteA.com     client $ vim /etc/hosts     client $ cat /etc/hosts     $ cat /etc/hosts     #     # /etc/hosts: static lookup table for host names     #     #           127.0.0.1       localhost.localdomain   localhost     ::1             localhost.localdomain   localhost     172.17.0.1      www.linux202-siteA.com linux202-siteA.com toto.linux202-siteA.com     client $ ping www.linux202-siteA.com     PING www.linux202-siteA.com (172.17.0.1) 56(84) bytes of data.     64 bytes from www.linux202-siteA.com (172.17.0.1): icmp_seq=1 ttl=64 time=0.102 ms

Following this small change if we retry a connection with the browser we will have the page siteA available

o far so good the system works as expected, however as mentioned earlier we only sum up in name-based virtual server if there is more than one definition of the same VirtualHost with the same IP. In our case we only have the siteA with the definition of IP 172.17.0.1. We will proceed to the creation of the site C, start with the configuration file /etc/apache2/sites-available/siteC.conf.

    $ cat siteC.conf                  ServerAdmin webmaster@localhost             ServerName www.siteC.com             ServerAlias siteC.com             DocumentRoot /data/vhosts/siteC                              Options Indexes FollowSymLinks                 AllowOverride None                 Require all granted                  

We will proceed to the creation of the directory of the site and the small page of index for visualized the site.

    $ sudo mkdir /data/vhosts/siteC     $ cat /data/vhosts/siteC/index.html     Le site C

Activation of the configuration, validation of the configuration and reloading of the apache configuration.

    $ cd /etc/apache2/sites-enabled     $ sudo ln -s ../sites-available/siteC.conf .     $ sudo apachectl configtest && sudo /etc/init.d/apache2 restart

This was for the server part, we will modify the file / etc / hosts of our client machine to simulate the DNS resolution.

    $ sudo vim /etc/hosts     $ cat /etc/hosts     #     # /etc/hosts: static lookup table for host names     #     #           127.0.0.1       localhost.localdomain   localhost     ::1             localhost.localdomain   localhost     172.17.0.1      www.linux202-siteA.com linux202-siteA.com toto.linux202-siteA.com     172.17.0.1      www.siteC.com siteC.com      $ ping siteC.com     PING www.siteC.com (172.17.0.1) 56(84) bytes of data.     64 bytes from www.linux202-siteA.com (172.17.0.1): icmp_seq=1 ttl=64 time=0.102 ms

Validate now with a browser ....

Woww magic !!

Quick process recall, configuration selection

  1. The customer via the browser asked for the site www.siteC.com

  2. The browser to perform a DNS resolution in order to communicate on the Internet and transmit the packet to the correct web server.

  3. The apache server has received the request on the IP address 172.17.0.1

  4. He found that there was 2 configuration for this same IP address contained in the file /etc/apache2/sites-enabled/siteA.conf and /etc/apache2/sites-enabled/siteC.conf.

  5. The system thus apache to analyze the content of the client request to identify in the header of the HTTP packets (according to the http protocol) which site name was requested.

  6. With this information apache tried to find this domain name in the definition of virtual servers by querying the ServerName and ServerAlias directives in the files /etc/apache2/sites-enabled/siteA.conf and / etc / apache2 / sites-enabled / siteC.conf.

  7. Apache found in the file /etc/apache2/sites-enabled/siteC.conf the definition in the ServerName statement www.siteC.com

  8. Apache to consult the files of the site defined in the DocumentRoot is / data / vhosts / siteC, found the file index.html and transmitted to the browser.

Great, but what if he had not found a ServerName and ServerAlias?!?!

Let's realize the test, because this is important it is a common mistake: P.

I am going to edit the file / etc / hosts for simulated another DNS resolution for the name site-noname.com

    $ sudo vim /etc/hosts     $ cat /etc/hosts     #     # /etc/hosts: static lookup table for host names     #     #           127.0.0.1       localhost.localdomain   localhost     ::1             localhost.localdomain   localhost     172.17.0.1      www.linux202-siteA.com linux202-siteA.com toto.linux202-siteA.com     172.17.0.1      www.siteC.com siteC.com      172.17.0.1      www.site-noname.com site-noname.com #     # /etc/hosts: static lookup table for host names     #     #           127.0.0.1       localhost.localdomain   localhost     ::1             localhost.localdomain   localhost     172.17.0.1      www.linux202-siteA.com linux202-siteA.com toto.linux202-siteA.com     172.17.0.1      www.siteC.com siteC.com      172.17.0.1      www.site-noname.com site-noname.com      $ ping site-noname.com     PING www.site-noname.com (172.17.0.1) 56(84) bytes of data.

Let's use the browser now

>It is thus possible to have N site for each IP address available on the system, because when receiving an apache HTTP request will process it using the configuration file with the specific IP. G As you can see while we were viewing the default Ubuntu / Debian page now, we only see Site A when we access the URL http://172.17.0.1. Although we have not disabled the default configuration in the /etc/apache2/sites-enabled/000-default.conf file. Let’s take a moment to see the contents of the files:

 ServerAdmin webmaster@localhost 
DocumentRoot /data/www Options Indexes FollowSymLinks AllowOverride None Require all granted Options FollowSymLinks AllowOverride AuthConfig ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined

 

The VirtualHost instruction is dialed with an asterisk and the port (*: 80) which indicates that this virtual server is valid for all IP addresses on port 80. As we have been more specific in indicating the VirtualHost with IP these The last ones have priorities.

Virtual Servers by Name

As mentioned in the introduction unfortunately with the limited number of IP address (IPv4) available on the internet it is complicated to have an IP address per site. With virtual hosting by name, the server relies on the information provided by the client in the HTTP headers of its requests. The technique presented here allows you to have different virtual servers shared on the same IP address.

Virtual hosting by name is usually easier because you simply configure your DNS server for each domain to point to the IP address you have, and configure your Apache HTTP server to recognize these domains. It also reduces the shortage of IP addresses. Therefore, you should use virtual hosting by name, except in case you use equipment that requires IP-based hosting. The historical reasons for IP-based hosting for the support of some customers no longer apply to a general-purpose web server.

Query processing process

  • Explanation from the apache site It is important to know that the first step of the name-based virtual server resolution is an IP-based resolution. The name-based virtual server resolution simply chooses the virtual server based on the most appropriate name, limiting itself to the most suitable candidates from an IP perspective. IP-based resolution is not applicable if you use a wildcard character (*) for the IP address in all VirtualHost directives.

    When a request arrives, the server will look for the section argument that has the best (most exact) match to the IP address / port pair used in the request. If multiple virtual servers have this same IP address / port pair, Apache will then compare the values of the ServerName and ServerAlias directives with the server name present in the request.

    If you do not set a ServerName directive for a name-based virtual server, the server will default to the fully qualified domain name (FQDN) deduced from the system host name. This configuration without an explicit server name may lead to errors in the choice of the virtual server to use and is deprecated.

  • Now my version: P, it’s up to you to choose the clearest. When the client using his browser makes a request to the website, the first step is the DNS resolution, if we take the site www.bob.com the resolution will give the IP: 198.100.146.119. The apache server must have a virtual server configure on this IP address. It can be with the IP specify such as or a more general configuration using a wildcard. If the apache server receives a request for the VirtualHost with the IP address and find that there is more than one definition for this same VirtualHost as the system does not know for which site the request is destined it looks at the header of the request. Indeed when the browser has sent the request on the internet in addition to using the IP to join the server he also asked www.bob.com. Apache will read the VirtualHost configuration files in search of the site name. It will look for 2 ServerName variable which is unique and ServerAlias this input allows to define several name to the virtual server. The system provides the most specific site, if it does not find the name of the site in the set of configuration files matching the IP it will provide one of the virtual servers depending on the loading of the files.

Let’s make a small example to have some practice.

We will create name-based virtual servers for the IP address 172.17.0.1, we will perform some tests with the other IP address to demonstrate the difference in processing.

Let’s start by associating a virtual server name with site A, so I edit the file /etc/apache2/sites-available/siteA.conf

$ cat siteA.conf  ServerAdmin webmaster@localhost
ServerName www.linux202-siteA.com ServerAlias linux202-siteA.com ServerAlias toto.linux202-siteA.com DocumentRoot /data/vhosts/siteA  Options Indexes FollowSymLinks AllowOverride None Require all granted 
 $ sudo apachectl configtest && sudo /etc/init.d/apache2 restart

If we use a browser to see the website we will have an error because there is no DNS associated with this name, so we will modify our / etc / hosts file to “simulate” the name resolution. This change is to be realized on the client machine which at the browser to consult the web pages. And this is only a workaround because unfortunately I did not win the lottery I did not buy domain names for training ;-).

So before changing the / etc / hosts file:

client $ ping www.linux202-siteA.com ping: unknown host www.linux202-siteA.com client $ vim /etc/hosts client $ cat /etc/hosts $ cat /etc/hosts # # /etc/hosts: static lookup table for host names # # 127.0.0.1 localhost.localdomain localhost ::1 localhost.localdomain localhost 172.17.0.1 www.linux202-siteA.com linux202-siteA.com toto.linux202-siteA.com client $ ping www.linux202-siteA.com PING www.linux202-siteA.com (172.17.0.1) 56(84) bytes of data. 64 bytes from www.linux202-siteA.com (172.17.0.1): icmp_seq=1 ttl=64 time=0.102 ms

Following this small change if we retry a connection with the browser we will have the page siteA available

o far so good the system works as expected, however as mentioned earlier we only sum up in name-based virtual server if there is more than one definition of the same VirtualHost with the same IP. In our case we only have the siteA with the definition of IP 172.17.0.1. We will proceed to the creation of the site C, start with the configuration file /etc/apache2/sites-available/siteC.conf.

$ cat siteC.conf  ServerAdmin webmaster@localhost ServerName www.siteC.com ServerAlias siteC.com DocumentRoot /data/vhosts/siteC  Options Indexes FollowSymLinks AllowOverride None Require all granted  

We will proceed to the creation of the directory of the site and the small page of index for visualized the site.

$ sudo mkdir /data/vhosts/siteC $ cat /data/vhosts/siteC/index.html Le site C

Activation of the configuration, validation of the configuration and reloading of the apache configuration.

$ cd /etc/apache2/sites-enabled $ sudo ln -s ../sites-available/siteC.conf . $ sudo apachectl configtest && sudo /etc/init.d/apache2 restart

This was for the server part, we will modify the file / etc / hosts of our client machine to simulate the DNS resolution.

$ sudo vim /etc/hosts $ cat /etc/hosts # # /etc/hosts: static lookup table for host names # # 127.0.0.1 localhost.localdomain localhost ::1 localhost.localdomain localhost 172.17.0.1 www.linux202-siteA.com linux202-siteA.com toto.linux202-siteA.com 172.17.0.1 www.siteC.com siteC.com $ ping siteC.com PING www.siteC.com (172.17.0.1) 56(84) bytes of data. 64 bytes from www.linux202-siteA.com (172.17.0.1): icmp_seq=1 ttl=64 time=0.102 ms

Validate now with a browser ….

Woww magic !!

Quick process recall, configuration selection

  1. The customer via the browser asked for the site www.siteC.com
  2. The browser to perform a DNS resolution in order to communicate on the Internet and transmit the packet to the correct web server.
  3. The apache server has received the request on the IP address 172.17.0.1
  4. He found that there was 2 configuration for this same IP address contained in the file /etc/apache2/sites-enabled/siteA.conf and /etc/apache2/sites-enabled/siteC.conf.
  5. The system thus apache to analyze the content of the client request to identify in the header of the HTTP packets (according to the http protocol) which site name was requested.
  6. With this information apache tried to find this domain name in the definition of virtual servers by querying the ServerName and ServerAlias directives in the files /etc/apache2/sites-enabled/siteA.conf and / etc / apache2 / sites-enabled / siteC.conf.
  7. Apache found in the file /etc/apache2/sites-enabled/siteC.conf the definition in the ServerName statement www.siteC.com
  8. Apache to consult the files of the site defined in the DocumentRoot is / data / vhosts / siteC, found the file index.html and transmitted to the browser.

Great, but what if he had not found a ServerName and ServerAlias?!?!

Let’s realize the test, because this is important it is a common mistake: P.

I am going to edit the file / etc / hosts for simulated another DNS resolution for the name site-noname.com

$ sudo vim /etc/hosts $ cat /etc/hosts # # /etc/hosts: static lookup table for host names #
# 127.0.0.1 localhost.localdomain localhost ::1 localhost.localdomain localhost 172.17.0.1 www.linux202-siteA.com linux202-siteA.com toto.linux202-siteA.com 172.17.0.1 www.siteC.com siteC.com 172.17.0.1 www.site-noname.com site-noname.com # # /etc/hosts: static lookup table for host names #
# 127.0.0.1 localhost.localdomain localhost ::1 localhost.localdomain localhost 172.17.0.1 www.linux202-siteA.com linux202-siteA.com toto.linux202-siteA.com 172.17.0.1 www.siteC.com siteC.com 172.17.0.1 www.site-noname.com site-noname.com $ ping site-noname.com PING www.site-noname.com (172.17.0.1) 56(84) bytes of data.

Let’s use the browser now

The system has chosen the first virtual server it has found! Be careful with this behavior you can have surprises.

Earlier version: Before version 2.4 you must specify the IP addresses that will be used with name-based virtual servers with the NameVirtualHost statement


This covers the demonstration of a virtual server based on the name in HTTP, we can always consult the site on the IP 172.17.0.10 without problem. It is possible to have a mix configuration on the same server!

  • Reference: http://httpd.apache.org/docs/2.4/fr/vhosts/name-based.html

Organization of websites

Now that we have the opportunity to put several websites, we must be careful that it does not quickly become a big management problem. I am going to give you a suggestion of organization of structure, this is the fruit of several years' experience. I met constraints and requests from users who led me to set up this organization, as always free to you to adapt it for your needs. I will take the opportunity to cover other configuration with explanations why I opted for this configuration.

Organization of virtual server directories

Let's start with the directory structure that will host the website. Here is a representation of the directory structure:

        /data/              /vhost/                    /siteA/                          /docroot/                          /logs/                          /privates/                          /uploads/                    /siteB/                    /siteC/

Now let's take a few minutes to read the structure, I like to have all the VirtualHost under the same directory. Because this allows me to set permissions with the Directory statement from the root and this is reflected on all child directories. This allows me to be more restrictive and eventually allow more options depending on the directory.

Each site has the same structure again this simplifies management later:

  • docroot: Contains the web site it is the directory that will be associated with the DocumentRoot configuration. This will be the root directory of the site.

  • logs: Over time I have noticed that web developers like to have access to logs, whether to analyze errors or simply see the activity in real time. We will ensure permissions on this directory so that it is only read, as a precaution.

  • privates: This directory is not accessible from the Internet, this directory can be used by the developer to store files for internal use only on the server. We could find for example a configuration file to establish a connection to the BD. We do not want anyone to retrieve this file through a browser because it guesses the name. I leave you the task of testing your servers: P. If you have a config.conf file for example in the inc directory under the DocumentRoot definition, you will find that everyone can have it: - /. Of course this directory is totally useless if the administrator of the site does not use it: - /.

  • uploads: This directory has write permissions to apache and allows writing by the web application. It is not always possible to use it, because some applications want to have it under the docroot so you have to see according to your applications. I put it in place, because this allows the developer to have an available directory without contacting me for a change of permission.

Here is a little script to create directories, be careful this is really a starting point, I invite you to modify it to add the definition of permissions for the docroot directory, ... What I want to emphasize with the creation of a script is that everything must be done to automate manual operations. Because if you do this often, sometimes you will make a mistake in the name of the directory, a permissions error, ... 2 possibilities is open to you, make scripts or use a configuration management system such as ansible or puppet, we will see these systems later!

    #!/bin/bash     #     ##############################################     # Vars     VHOSTS_BASE=/data/vhosts     APACHE_GROUP=www-data     LST_REPS_VHOSTS="docroot logs privates uploads"     # Arguments passer sur la ligne de commande.     VHOST_TO_CREATE=$@     if [ "$VHOST_TO_CREATE" == "" ]; then             echo "ERROR: Il n'y a pas d'argument avec un ou plusieurs site a creer "             echo "$0 siteA "              echo "$0 siteA siteB siteC"             exit 1     fi     for site in $VHOST_TO_CREATE     do             echo "sudo mkdir -p $VHOSTS_BASE/$site"             for rep in $LST_REPS_VHOSTS             do                     echo "sudo mkdir $VHOSTS_BASE/$site/$rep"                     if [ "$rep" == "uploads" ] ; then                             echo "sudo chmod g=rwX $VHOSTS_BASE/$site/$rep"                              echo "sudo chown :$APACHE_GROUP $VHOSTS_BASE/$site/$rep"                             fi # if uploads             done #for rep     done # for vhosts

Apache configuration for virtual servers

We now have the directory structure, we will set up the appropriate apache configuration.

We will define a default configuration that will be inherited by all virtual sites. Still following the structure of Ubuntu / Debian we will define the file /etc/apache2/conf-available/vhosts_base.conf. We will define the configuration for the directory / data / vhosts /.

Here is the contents of the file: /etc/apache2/conf-available/vhosts_base.conf

    # Configuration par default qui sera appliquer par default a l'ensemble des vhosts                  Options None             AllowOverride None             Require all denied     

In this case I disable all options, we will come back to this when configuring a virtual server and I disable the ability to use .htaccess files. This for a question of performance AND security. In addition, I block directory access with the statement Require all denied. I realize this operation so that one is obliged to define specifically the directories accessible from internet.

If you found mistakes in the article you are welcome to say it in the comments. Nobody is perfect.We are all here to learn and progress.

Every comments with hate and disgrace contents will be erased.

Thanks and enjoy.