Chapter 3. Working with Web Servers
In this chapter, we will cover the following recipes:
- Installing and configuring the Apache web server
- Serving dynamic contents with PHP
- Hosting multiple websites with a virtual domain
- Securing web traffic with HTTPS
- Installing Nginx with PHP_FPM
- Setting Nginx as a reverse proxy
- Load balancing with Nginx
- Setting HTTPs on Nginx
- Benchmarking and performance tuning of Apache
- Securing the web server
- Troubleshooting the web server
Introduction
A web server is a tool that publishes documents on a network, generally the Internet. HTTP is called a language of the Internet and web servers, apart from browsers, are native speakers of HTTP. Web servers generally listen on one or multiple ports for requests from clients and accept requests in the form of URLs and HTTP headers. On receiving a request, web servers look for the availability of the requested resource and return the contents to the client. The term web server can refer to one or multiple physical servers or a software package, or both of them working together.
Some well known web servers include the Apache web server, Microsoft IIS, and Nginx. Apache web server is the most popular web server package available across platforms such as Windows and Linux. It is an open source project and freely available for commercial use. Nginx, which is again an open source web server project, started to overcome the problems in a high-load environment. Because of its lightweight resource utilization and ability to scale even on minimal hardware, Nginx quickly became a well known name. Nginx offers a free community edition as well as a paid commercial version with added support and extra features. Lastly, Microsoft IIS is a web server specifically designed for Windows servers. Apache still has the major share in the web server market, with Nginx rapidly taking over with some other notable alternatives such as lighttpd and H2O.
Apache is a modularized web server that can be extended by dynamically loading extra modules as and when required. This provides the flexibility to run a bare minimum web server or a fully featured box with modules to support compression, SSL, redirects, language modules, and more. Apache provides multiple connection processing algorithms called
multi-processing modules (MPM). It provides an option to create a separate single threaded process for each new request (mpm_prefork
), a multi-threaded process that can handle multiple concurrent requests (mpm_worker
), or the latest development of mpm_event
, which separates the active and idle connections.
Nginx can be considered the next generation of web servers. Its development started to solve the C10k problem, that is, handling ten thousand connections at a time. Apache, being a process-driven model, has some limitations when handling multiple concurrent connections. Nginx took advantage of the event-driven approach with asynchronous, non-blocking connection handling algorithms. A new connection request is handled by a worker process and placed in an event loop where they are continuously checked for events. The events are processed asynchronously. This approach enables Nginx to run with a much lower memory footprint and lower CPU use. It also eliminates the overload of starting a new process for a new connection. A single worker process started by Nginx can handle thousands of concurrent connections.
Tip
It is possible that some terms used throughout this chapter are unknown to you. It is not possible to explain everything in a Cookbook format. A quick Google search for a term will give you more details on them.
Both Apache and Nginx can be configured to process dynamic contents. Apache provides respective language processors such as mod_php
and mod_python
to process dynamic contents within the worker process itself. Nginx depends on external processors and uses CGI protocols to communicate with external processors. Apache can also be configured to use an external language processor over CGI, but the choice depends on performance and security considerations.
While both Apache and Nginx provide various similar features, they are not entirely interchangeable. Each one has its own pros and cons. Where Nginx excels at serving static contents, Apache performs much better processing dynamic contents. Many web administrators prefer to use Apache and Nginx together.
Note
Nginx is commonly used as a frontend caching/reverse proxy handling client requests and serving static contents, while Apache is used as a backend server processing dynamic contents.
Nginx handles a large number of connections and passes limited requests of dynamic contents to backend Apache servers. This configuration also allows users to scale horizontally by adding multiple backend servers and setting Nginx as a load balancer.
In this chapter, we will be working with both Apache and Nginx servers. We will learn how to set up Apache with PHP as a language for dynamic contents. We will look at some important configurations of Apache. Later, we will set up Nginx with an optional PHP processor, PHP_FPM, and configure Nginx to work as a reverse proxy and load balancer. We will also look at performance and security configurations for both the servers.
Installing and configuring the Apache web server
In this recipe, we will simply install the Apache web server from the Ubuntu package repository. We will also look at the basic configuration options and set up our first web page.
Getting ready
You will need access to a root account or an account with sudo
privileges.
I will be using Apache to refer to the Apache web server. The Apache web server is the most popular project by the Apache Foundation and is generally known as just Apache.
How to do it…
Follow these steps to install and configure the Apache web server:
- Install Apache2 from the Ubuntu package repository:
$ sudo apt-get update $ sudo apt-get install apache2
- Check if Apache2 has installed successfully. The command
wget
should download theindex.html
file:$ wget 127.0.0.1
- You can also open a browser on a local machine and point it to the server IP address. You should see a default It works! page customized for Ubuntu:
- Now, let's proceed with creating our first virtual host. First create a directory structure. Change the directory to
/var/www/
and create a new directory for the contents of our site:$ cd /var/www $ sudo mkdir example.com
- Change the ownership and group of the directory
example.com
:$ sudo chown ubuntu:www-data example.com
- Set the file permissions to secure web contents:
$ sudo chmod 750 example.com
- Create the required directories under the
example.com
directory:$ cd example.com $ mkdir public_html
- Create a
index.html
file under thepublic_html
directory:$ echo '<b>Hello World ...</b>' > public_html/index.html
- Next, we need to set up a new virtual host under the Apache configuration.
- Copy the default Virtual Host file under
/etc/apache2/sites-available
and use it as a starting point for our configuration:$ cd /etc/apache2/sites-available $ sudo cp 000-default.conf example.com.conf
- Edit
example.com.conf
to match it with the following example. Change the parameters as per your requirements: - Save the changes and exit
example.com.conf
. - If you are using the same port as the default
VirtualHost
, do not forget to disable the default one:$ sudo a2dissite 000-default.conf
- Finally, enable our new
VirtualHost
witha2ensite
and reload Apache:$ sudo a2ensite example.com.conf $ sudo service apache2 reload
- Start your browser and point it to the domain or IP address of your server:
How it works…
The Apache package for Ubuntu is included in the default package repository. We need a single command to install the Apache web server. Installation creates a structure of configuration files under /etc/apache2
and a sample web page under /var/www/html
.
As mentioned in the default It works! page, Apache2 does not use a single configuration file such as httpd.conf
in older versions, but rather separates its configuration across multiple configuration files. These files are named after their respective uses. apache2.conf
is now a main configuration file and creates a central configuration by including all other files.
conf-available
, mods-available,
and sites-available
contain configuration snippets and other files for global configurations, modules, and virtual hosts respectively. These configurations are selectively activated under their enabled counterparts with symbolic links for each configuration to be enabled.
envvars
contains all environment variables and default values for Apache to work.
ports.conf
defines the ports Apache should listen on.
The default web page is created under the /var/www/html
directory.
In this recipe, we have created our virtual host for the domain name example.com
and hosted it under the directory /var/www/example.com
. Next, we have to change the owner and default group of this directory to the user, ubuntu
and group, www-data
. This grants full access to the user ubuntu
and allows read and execute access to the group www-data
. If you have observed the contents of the envvars
file, you may have noticed that the variable APACHE_RUN_GROUP
is set to www-data
. This means Apache process will be started as the group www-data
. By setting a default group, we have allowed Apache process to read the contents of the example.com
directory. We have also enabled write access to the logs
directory so that Apache processes can log to this directory.
After creating the virtual host configuration and setting the respective options, all we need to do is enable a new virtual host or site. Apache2 provides the respective commands to enable or disable configurations, modules, and sites. a2ensite
will be used to enable the site from options available under sites-available
. Basically, this will create a symbolic link under the sites-enabled
directory to a specified site configuration. Similarly, a2dissite
will disable the site by removing the symbolic link from the sites-enabled
directory. Similar commands are available to work with configurations and modules.
There's more…
You may want to get rid of the warning that says Could not reliably determine the server's fully qualified domain name
. This warning appears because the Apache process could not find the default FQDN for this server. You can set the default FQDN simply by creating a new configuration file and then enabling this new configuration:
- Create a new file under the
conf-available
directory:$ sudo vi /etc/apache2/conf-available/fqdn.conf
- Add a server name variable to this file:
ServerName localhost
- Save the changes and enable this configuration:
$ sudo a2enconf fqdn
- Reload the Apache server:
$ sudo service apache2 reload
HTTP version 2 support
If you are looking for HTTP2 support, Apache does provide a separate module for that. Apache version 2.4.17 ships with a module, mod_http2
, that implements the latest HTTP version, HTTP2. It is still an experimental implementation and needs to be enabled manually. This version of Apache (2.4.17) is available with Ubuntu Xenial (16.04) in the default package repository. If you are using Ubuntu 14.04, you can use the external repository as follows:
$ sudo add-apt-repository -y ppa:ondrej/apache2
Once the required version of Apache is installed, you can enable mod_http2
as follows:
$ sudo a2enmod http2
Next, edit the specific virtual host file to enable the HTTP2 protocol for a specific site. Note that you need to configure your site to use an SSL/TLS connection:
<VirtualHost *:443> Protocols h2 http/1.1 ... </VirtualHost>
Finally, restart your Apache server:
$ sudo service apache2 restart
H2O, the new name in web servers, is developed around the HTTP2 protocol. It does support both HTTP 1.1 and a stable implementation of the HTTP2 protocol. You may want to check this out as your local or development server.
See also
You can read more by following the links:
- There is a good Q and A about permissions for web directory at http://serverfault.com/questions/357108/what-permissions-should-my-website-files-folders-have-on-a-linux-webserver
- You can find more details about installing the Apache web server at https://help.ubuntu.com/lts/serverguide/httpd.html
- Apache official documentation - http://httpd.apache.org/docs/2.4/
Getting ready
You will need access to a root account or an account with sudo
privileges.
I will be using Apache to refer to the Apache web server. The Apache web server is the most popular project by the Apache Foundation and is generally known as just Apache.
How to do it…
Follow these steps to install and configure the Apache web server:
- Install Apache2 from the Ubuntu package repository:
$ sudo apt-get update $ sudo apt-get install apache2
- Check if Apache2 has installed successfully. The command
wget
should download theindex.html
file:$ wget 127.0.0.1
- You can also open a browser on a local machine and point it to the server IP address. You should see a default It works! page customized for Ubuntu:
- Now, let's proceed with creating our first virtual host. First create a directory structure. Change the directory to
/var/www/
and create a new directory for the contents of our site:$ cd /var/www $ sudo mkdir example.com
- Change the ownership and group of the directory
example.com
:$ sudo chown ubuntu:www-data example.com
- Set the file permissions to secure web contents:
$ sudo chmod 750 example.com
- Create the required directories under the
example.com
directory:$ cd example.com $ mkdir public_html
- Create a
index.html
file under thepublic_html
directory:$ echo '<b>Hello World ...</b>' > public_html/index.html
- Next, we need to set up a new virtual host under the Apache configuration.
- Copy the default Virtual Host file under
/etc/apache2/sites-available
and use it as a starting point for our configuration:$ cd /etc/apache2/sites-available $ sudo cp 000-default.conf example.com.conf
- Edit
example.com.conf
to match it with the following example. Change the parameters as per your requirements: - Save the changes and exit
example.com.conf
. - If you are using the same port as the default
VirtualHost
, do not forget to disable the default one:$ sudo a2dissite 000-default.conf
- Finally, enable our new
VirtualHost
witha2ensite
and reload Apache:$ sudo a2ensite example.com.conf $ sudo service apache2 reload
- Start your browser and point it to the domain or IP address of your server:
How it works…
The Apache package for Ubuntu is included in the default package repository. We need a single command to install the Apache web server. Installation creates a structure of configuration files under /etc/apache2
and a sample web page under /var/www/html
.
As mentioned in the default It works! page, Apache2 does not use a single configuration file such as httpd.conf
in older versions, but rather separates its configuration across multiple configuration files. These files are named after their respective uses. apache2.conf
is now a main configuration file and creates a central configuration by including all other files.
conf-available
, mods-available,
and sites-available
contain configuration snippets and other files for global configurations, modules, and virtual hosts respectively. These configurations are selectively activated under their enabled counterparts with symbolic links for each configuration to be enabled.
envvars
contains all environment variables and default values for Apache to work.
ports.conf
defines the ports Apache should listen on.
The default web page is created under the /var/www/html
directory.
In this recipe, we have created our virtual host for the domain name example.com
and hosted it under the directory /var/www/example.com
. Next, we have to change the owner and default group of this directory to the user, ubuntu
and group, www-data
. This grants full access to the user ubuntu
and allows read and execute access to the group www-data
. If you have observed the contents of the envvars
file, you may have noticed that the variable APACHE_RUN_GROUP
is set to www-data
. This means Apache process will be started as the group www-data
. By setting a default group, we have allowed Apache process to read the contents of the example.com
directory. We have also enabled write access to the logs
directory so that Apache processes can log to this directory.
After creating the virtual host configuration and setting the respective options, all we need to do is enable a new virtual host or site. Apache2 provides the respective commands to enable or disable configurations, modules, and sites. a2ensite
will be used to enable the site from options available under sites-available
. Basically, this will create a symbolic link under the sites-enabled
directory to a specified site configuration. Similarly, a2dissite
will disable the site by removing the symbolic link from the sites-enabled
directory. Similar commands are available to work with configurations and modules.
There's more…
You may want to get rid of the warning that says Could not reliably determine the server's fully qualified domain name
. This warning appears because the Apache process could not find the default FQDN for this server. You can set the default FQDN simply by creating a new configuration file and then enabling this new configuration:
- Create a new file under the
conf-available
directory:$ sudo vi /etc/apache2/conf-available/fqdn.conf
- Add a server name variable to this file:
ServerName localhost
- Save the changes and enable this configuration:
$ sudo a2enconf fqdn
- Reload the Apache server:
$ sudo service apache2 reload
HTTP version 2 support
If you are looking for HTTP2 support, Apache does provide a separate module for that. Apache version 2.4.17 ships with a module, mod_http2
, that implements the latest HTTP version, HTTP2. It is still an experimental implementation and needs to be enabled manually. This version of Apache (2.4.17) is available with Ubuntu Xenial (16.04) in the default package repository. If you are using Ubuntu 14.04, you can use the external repository as follows:
$ sudo add-apt-repository -y ppa:ondrej/apache2
Once the required version of Apache is installed, you can enable mod_http2
as follows:
$ sudo a2enmod http2
Next, edit the specific virtual host file to enable the HTTP2 protocol for a specific site. Note that you need to configure your site to use an SSL/TLS connection:
<VirtualHost *:443> Protocols h2 http/1.1 ... </VirtualHost>
Finally, restart your Apache server:
$ sudo service apache2 restart
H2O, the new name in web servers, is developed around the HTTP2 protocol. It does support both HTTP 1.1 and a stable implementation of the HTTP2 protocol. You may want to check this out as your local or development server.
See also
You can read more by following the links:
- There is a good Q and A about permissions for web directory at http://serverfault.com/questions/357108/what-permissions-should-my-website-files-folders-have-on-a-linux-webserver
- You can find more details about installing the Apache web server at https://help.ubuntu.com/lts/serverguide/httpd.html
- Apache official documentation - http://httpd.apache.org/docs/2.4/
How to do it…
Follow these steps to install and configure the Apache web server:
- Install Apache2 from the Ubuntu package repository:
$ sudo apt-get update $ sudo apt-get install apache2
- Check if Apache2 has installed successfully. The command
wget
should download theindex.html
file:$ wget 127.0.0.1
- You can also open a browser on a local machine and point it to the server IP address. You should see a default It works! page customized for Ubuntu:
- Now, let's proceed with creating our first virtual host. First create a directory structure. Change the directory to
/var/www/
and create a new directory for the contents of our site:$ cd /var/www $ sudo mkdir example.com
- Change the ownership and group of the directory
example.com
:$ sudo chown ubuntu:www-data example.com
- Set the file permissions to secure web contents:
$ sudo chmod 750 example.com
- Create the required directories under the
example.com
directory:$ cd example.com $ mkdir public_html
- Create a
index.html
file under thepublic_html
directory:$ echo '<b>Hello World ...</b>' > public_html/index.html
- Next, we need to set up a new virtual host under the Apache configuration.
- Copy the default Virtual Host file under
/etc/apache2/sites-available
and use it as a starting point for our configuration:$ cd /etc/apache2/sites-available $ sudo cp 000-default.conf example.com.conf
- Edit
example.com.conf
to match it with the following example. Change the parameters as per your requirements: - Save the changes and exit
example.com.conf
. - If you are using the same port as the default
VirtualHost
, do not forget to disable the default one:$ sudo a2dissite 000-default.conf
- Finally, enable our new
VirtualHost
witha2ensite
and reload Apache:$ sudo a2ensite example.com.conf $ sudo service apache2 reload
- Start your browser and point it to the domain or IP address of your server:
How it works…
The Apache package for Ubuntu is included in the default package repository. We need a single command to install the Apache web server. Installation creates a structure of configuration files under /etc/apache2
and a sample web page under /var/www/html
.
As mentioned in the default It works! page, Apache2 does not use a single configuration file such as httpd.conf
in older versions, but rather separates its configuration across multiple configuration files. These files are named after their respective uses. apache2.conf
is now a main configuration file and creates a central configuration by including all other files.
conf-available
, mods-available,
and sites-available
contain configuration snippets and other files for global configurations, modules, and virtual hosts respectively. These configurations are selectively activated under their enabled counterparts with symbolic links for each configuration to be enabled.
envvars
contains all environment variables and default values for Apache to work.
ports.conf
defines the ports Apache should listen on.
The default web page is created under the /var/www/html
directory.
In this recipe, we have created our virtual host for the domain name example.com
and hosted it under the directory /var/www/example.com
. Next, we have to change the owner and default group of this directory to the user, ubuntu
and group, www-data
. This grants full access to the user ubuntu
and allows read and execute access to the group www-data
. If you have observed the contents of the envvars
file, you may have noticed that the variable APACHE_RUN_GROUP
is set to www-data
. This means Apache process will be started as the group www-data
. By setting a default group, we have allowed Apache process to read the contents of the example.com
directory. We have also enabled write access to the logs
directory so that Apache processes can log to this directory.
After creating the virtual host configuration and setting the respective options, all we need to do is enable a new virtual host or site. Apache2 provides the respective commands to enable or disable configurations, modules, and sites. a2ensite
will be used to enable the site from options available under sites-available
. Basically, this will create a symbolic link under the sites-enabled
directory to a specified site configuration. Similarly, a2dissite
will disable the site by removing the symbolic link from the sites-enabled
directory. Similar commands are available to work with configurations and modules.
There's more…
You may want to get rid of the warning that says Could not reliably determine the server's fully qualified domain name
. This warning appears because the Apache process could not find the default FQDN for this server. You can set the default FQDN simply by creating a new configuration file and then enabling this new configuration:
- Create a new file under the
conf-available
directory:$ sudo vi /etc/apache2/conf-available/fqdn.conf
- Add a server name variable to this file:
ServerName localhost
- Save the changes and enable this configuration:
$ sudo a2enconf fqdn
- Reload the Apache server:
$ sudo service apache2 reload
HTTP version 2 support
If you are looking for HTTP2 support, Apache does provide a separate module for that. Apache version 2.4.17 ships with a module, mod_http2
, that implements the latest HTTP version, HTTP2. It is still an experimental implementation and needs to be enabled manually. This version of Apache (2.4.17) is available with Ubuntu Xenial (16.04) in the default package repository. If you are using Ubuntu 14.04, you can use the external repository as follows:
$ sudo add-apt-repository -y ppa:ondrej/apache2
Once the required version of Apache is installed, you can enable mod_http2
as follows:
$ sudo a2enmod http2
Next, edit the specific virtual host file to enable the HTTP2 protocol for a specific site. Note that you need to configure your site to use an SSL/TLS connection:
<VirtualHost *:443> Protocols h2 http/1.1 ... </VirtualHost>
Finally, restart your Apache server:
$ sudo service apache2 restart
H2O, the new name in web servers, is developed around the HTTP2 protocol. It does support both HTTP 1.1 and a stable implementation of the HTTP2 protocol. You may want to check this out as your local or development server.
See also
You can read more by following the links:
- There is a good Q and A about permissions for web directory at http://serverfault.com/questions/357108/what-permissions-should-my-website-files-folders-have-on-a-linux-webserver
- You can find more details about installing the Apache web server at https://help.ubuntu.com/lts/serverguide/httpd.html
- Apache official documentation - http://httpd.apache.org/docs/2.4/
How it works…
The Apache package for Ubuntu is included in the default package repository. We need a single command to install the Apache web server. Installation creates a structure of configuration files under /etc/apache2
and a sample web page under /var/www/html
.
As mentioned in the default It works! page, Apache2 does not use a single configuration file such as httpd.conf
in older versions, but rather separates its configuration across multiple configuration files. These files are named after their respective uses. apache2.conf
is now a main configuration file and creates a central configuration by including all other files.
conf-available
, mods-available,
and sites-available
contain configuration snippets and other files for global configurations, modules, and virtual hosts respectively. These configurations are selectively activated under their enabled counterparts with symbolic links for each configuration to be enabled.
envvars
contains all environment variables and default values for Apache to work.
ports.conf
defines the ports Apache should listen on.
The default web page is created under the /var/www/html
directory.
In this recipe, we have created our virtual host for the domain name example.com
and hosted it under the directory /var/www/example.com
. Next, we have to change the owner and default group of this directory to the user, ubuntu
and group, www-data
. This grants full access to the user ubuntu
and allows read and execute access to the group www-data
. If you have observed the contents of the envvars
file, you may have noticed that the variable APACHE_RUN_GROUP
is set to www-data
. This means Apache process will be started as the group www-data
. By setting a default group, we have allowed Apache process to read the contents of the example.com
directory. We have also enabled write access to the logs
directory so that Apache processes can log to this directory.
After creating the virtual host configuration and setting the respective options, all we need to do is enable a new virtual host or site. Apache2 provides the respective commands to enable or disable configurations, modules, and sites. a2ensite
will be used to enable the site from options available under sites-available
. Basically, this will create a symbolic link under the sites-enabled
directory to a specified site configuration. Similarly, a2dissite
will disable the site by removing the symbolic link from the sites-enabled
directory. Similar commands are available to work with configurations and modules.
There's more…
You may want to get rid of the warning that says Could not reliably determine the server's fully qualified domain name
. This warning appears because the Apache process could not find the default FQDN for this server. You can set the default FQDN simply by creating a new configuration file and then enabling this new configuration:
- Create a new file under the
conf-available
directory:$ sudo vi /etc/apache2/conf-available/fqdn.conf
- Add a server name variable to this file:
ServerName localhost
- Save the changes and enable this configuration:
$ sudo a2enconf fqdn
- Reload the Apache server:
$ sudo service apache2 reload
HTTP version 2 support
If you are looking for HTTP2 support, Apache does provide a separate module for that. Apache version 2.4.17 ships with a module, mod_http2
, that implements the latest HTTP version, HTTP2. It is still an experimental implementation and needs to be enabled manually. This version of Apache (2.4.17) is available with Ubuntu Xenial (16.04) in the default package repository. If you are using Ubuntu 14.04, you can use the external repository as follows:
$ sudo add-apt-repository -y ppa:ondrej/apache2
Once the required version of Apache is installed, you can enable mod_http2
as follows:
$ sudo a2enmod http2
Next, edit the specific virtual host file to enable the HTTP2 protocol for a specific site. Note that you need to configure your site to use an SSL/TLS connection:
<VirtualHost *:443> Protocols h2 http/1.1 ... </VirtualHost>
Finally, restart your Apache server:
$ sudo service apache2 restart
H2O, the new name in web servers, is developed around the HTTP2 protocol. It does support both HTTP 1.1 and a stable implementation of the HTTP2 protocol. You may want to check this out as your local or development server.
See also
You can read more by following the links:
- There is a good Q and A about permissions for web directory at http://serverfault.com/questions/357108/what-permissions-should-my-website-files-folders-have-on-a-linux-webserver
- You can find more details about installing the Apache web server at https://help.ubuntu.com/lts/serverguide/httpd.html
- Apache official documentation - http://httpd.apache.org/docs/2.4/
There's more…
You may want to get rid of the warning that says Could not reliably determine the server's fully qualified domain name
. This warning appears because the Apache process could not find the default FQDN for this server. You can set the default FQDN simply by creating a new configuration file and then enabling this new configuration:
- Create a new file under the
conf-available
directory:$ sudo vi /etc/apache2/conf-available/fqdn.conf
- Add a server name variable to this file:
ServerName localhost
- Save the changes and enable this configuration:
$ sudo a2enconf fqdn
- Reload the Apache server:
$ sudo service apache2 reload
HTTP version 2 support
If you are looking for HTTP2 support, Apache does provide a separate module for that. Apache version 2.4.17 ships with a module, mod_http2
, that implements the latest HTTP version, HTTP2. It is still an experimental implementation and needs to be enabled manually. This version of Apache (2.4.17) is available with Ubuntu Xenial (16.04) in the default package repository. If you are using Ubuntu 14.04, you can use the external repository as follows:
$ sudo add-apt-repository -y ppa:ondrej/apache2
Once the required version of Apache is installed, you can enable mod_http2
as follows:
$ sudo a2enmod http2
Next, edit the specific virtual host file to enable the HTTP2 protocol for a specific site. Note that you need to configure your site to use an SSL/TLS connection:
<VirtualHost *:443> Protocols h2 http/1.1 ... </VirtualHost>
Finally, restart your Apache server:
$ sudo service apache2 restart
H2O, the new name in web servers, is developed around the HTTP2 protocol. It does support both HTTP 1.1 and a stable implementation of the HTTP2 protocol. You may want to check this out as your local or development server.
See also
You can read more by following the links:
- There is a good Q and A about permissions for web directory at http://serverfault.com/questions/357108/what-permissions-should-my-website-files-folders-have-on-a-linux-webserver
- You can find more details about installing the Apache web server at https://help.ubuntu.com/lts/serverguide/httpd.html
- Apache official documentation - http://httpd.apache.org/docs/2.4/
HTTP version 2 support
If you are looking for HTTP2 support, Apache does provide a separate module for that. Apache version 2.4.17 ships with a module, mod_http2
, that implements the latest HTTP version, HTTP2. It is still an experimental implementation and needs to be enabled manually. This version of Apache (2.4.17) is available with Ubuntu Xenial (16.04) in the default package repository. If you are using Ubuntu 14.04, you can use the external repository as follows:
$ sudo add-apt-repository -y ppa:ondrej/apache2
Once the required version of Apache is installed, you can enable mod_http2
as follows:
$ sudo a2enmod http2
Next, edit the specific virtual host file to enable the HTTP2 protocol for a specific site. Note that you need to configure your site to use an SSL/TLS connection:
<VirtualHost *:443> Protocols h2 http/1.1 ... </VirtualHost>
Finally, restart your Apache server:
$ sudo service apache2 restart
H2O, the new name in web servers, is developed around the HTTP2 protocol. It does support both HTTP 1.1 and a stable implementation of the HTTP2 protocol. You may want to check this out as your local or development server.
You can read more by following the links:
- There is a good Q and A about permissions for web directory at http://serverfault.com/questions/357108/what-permissions-should-my-website-files-folders-have-on-a-linux-webserver
- You can find more details about installing the Apache web server at https://help.ubuntu.com/lts/serverguide/httpd.html
- Apache official documentation - http://httpd.apache.org/docs/2.4/
See also
You can read more by following the links:
- There is a good Q and A about permissions for web directory at http://serverfault.com/questions/357108/what-permissions-should-my-website-files-folders-have-on-a-linux-webserver
- You can find more details about installing the Apache web server at https://help.ubuntu.com/lts/serverguide/httpd.html
- Apache official documentation - http://httpd.apache.org/docs/2.4/
Serving dynamic contents with PHP
In this recipe, we will learn how to install PHP and set it to work alongside the Apache web server. We will install PHP binaries and then the Apache module mod_php
to support PHP-based dynamic contents.
Getting ready
You will need access to a root account or an account with sudo
privileges.
The Apache web server should be installed and working properly.
How to do it…
Follow these steps to serve dynamic contents with PHP:
- Install PHP7 and the Apache module for PHP support:
$ sudo apt-get update $ sudo apt-get install -y php7.0 libapache2-mod-php7.0
- Check if PHP is properly installed and which version has been installed:
$ php -v
- Create
index.php
under thepublic_html
directory of our site:$ cd /var/www/example.com/public_html $ vi index.php
- Add the following contents to
index.php
:<?php echo phpinfo(); ?>
- Save and exit the
index.php
file. - Open
example.com.conf
fromsites-available
:$ sudo vi /etc/apache2/sites-available/example.com.conf
- Add the following line under the
VirtualHost
directive:DirectoryIndex index.php index.html
- Save the changes and reload Apache:
$ sudo service apache2 reload
- Now, access your site with your browser, and you should see a page with information regarding the installed PHP:
How it works…
Here, we have installed PHP binaries on our server along with the Apache module libapache2-mod-php7.0
to support dynamic content coded in PHP. A module, mod_php
, runs inside Apache process and processes PHP scripts from within Apache itself. For mod_php
to work, Apache needs to run with the mpm_prefork
module. PHP setup completes all these settings and restarts the Apache server:
After we have installed PHP and mod_php
, we simply need to create a PHP script. We have created index.php
with little code to display phpinfo
. At this stage, if you have both index.html
and index.php
under the same directory; by default, index.html
will take over and be rendered first. You will need to explicitly specify index.php
to access the page as http://127.0.0.1/index.php
. We have set a directive, DirectoryIndex
, under Apache Virtual Host to set index.php
as a default index file.
PHP settings
All PHP settings are listed under its own configuration file, php.ini
. PHP comes with two sets of configurations, as follows:
/usr/lib/php/7.0/php.ini-development
The /usr/lib/php/7.0/php.ini-productionDevelopment
file is customized for a development environment and enables options like display_errors
. For production systems, you can use the configuration file, php.ini-production
.
The preceding files can be treated as a reference configuration that ships with the PHP installation. A copy of php.ini-production
can be found under /etc/php/7.0
. Apache and CLI configurations are separated in respective directories. You can directly edit settings under these files or simply use default files by creating a symbolic link to the development or production file as follows:
$ cd /etc/php/7.0/apache2 $ sudo mv php.ini php.ini.orig $ sudo ln -s /usr/lib/php/7.0/php.ini-development php.ini
There's more…
Along with PHP, Apache supports various other scripting languages for dynamic content. You can install modules for Perl, Python, Ruby, and other scripting languages.
Add Python support:
$ sudo apt-get install libapache2-mod-python
Add Perl support:
$ sudo apt-get install libapache2-mod-perl2
Add Ruby support:
$ sudo apt-get install libapache2-mod-passenger
Installing the LAMP stack
If you are interested in installing the entire LAMP stack, then Ubuntu provides a single command to do so. Use the following command to install Apache, PHP, and MySQL collectively:
$ sudo apt-get install lamp-server^
Notice the caret symbol at the end of the command. If you miss this symbol, apt
will return an error saying package not found
.
Note
lamp-server
is set in the Ubuntu repository as a task to install and configure Apache, PHP, and MySQL collectively. The caret symbol in apt-get
command is used to specify the task rather than the package. Alternatively, you can use the tasksel
command as $ sudo tasksel install lamp-server
. Tasksel is a program used to ease the installation of packages that are commonly used together.
Upgrading PHP under Ubuntu 14
As of Ubuntu 14.10, Ubuntu does not provide a package for PHP7 in its repository, but you can use a Debian package repository to upgrade your PHP version. This repository is maintained by Ondřej Surý.
Use the following commands to upgrade to PHP 7:
$ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get install php7.0
Check the PHP version after installation completes:
$ php -v
Getting ready
You will need access to a root account or an account with sudo
privileges.
The Apache web server should be installed and working properly.
How to do it…
Follow these steps to serve dynamic contents with PHP:
- Install PHP7 and the Apache module for PHP support:
$ sudo apt-get update $ sudo apt-get install -y php7.0 libapache2-mod-php7.0
- Check if PHP is properly installed and which version has been installed:
$ php -v
- Create
index.php
under thepublic_html
directory of our site:$ cd /var/www/example.com/public_html $ vi index.php
- Add the following contents to
index.php
:<?php echo phpinfo(); ?>
- Save and exit the
index.php
file. - Open
example.com.conf
fromsites-available
:$ sudo vi /etc/apache2/sites-available/example.com.conf
- Add the following line under the
VirtualHost
directive:DirectoryIndex index.php index.html
- Save the changes and reload Apache:
$ sudo service apache2 reload
- Now, access your site with your browser, and you should see a page with information regarding the installed PHP:
How it works…
Here, we have installed PHP binaries on our server along with the Apache module libapache2-mod-php7.0
to support dynamic content coded in PHP. A module, mod_php
, runs inside Apache process and processes PHP scripts from within Apache itself. For mod_php
to work, Apache needs to run with the mpm_prefork
module. PHP setup completes all these settings and restarts the Apache server:
After we have installed PHP and mod_php
, we simply need to create a PHP script. We have created index.php
with little code to display phpinfo
. At this stage, if you have both index.html
and index.php
under the same directory; by default, index.html
will take over and be rendered first. You will need to explicitly specify index.php
to access the page as http://127.0.0.1/index.php
. We have set a directive, DirectoryIndex
, under Apache Virtual Host to set index.php
as a default index file.
PHP settings
All PHP settings are listed under its own configuration file, php.ini
. PHP comes with two sets of configurations, as follows:
/usr/lib/php/7.0/php.ini-development
The /usr/lib/php/7.0/php.ini-productionDevelopment
file is customized for a development environment and enables options like display_errors
. For production systems, you can use the configuration file, php.ini-production
.
The preceding files can be treated as a reference configuration that ships with the PHP installation. A copy of php.ini-production
can be found under /etc/php/7.0
. Apache and CLI configurations are separated in respective directories. You can directly edit settings under these files or simply use default files by creating a symbolic link to the development or production file as follows:
$ cd /etc/php/7.0/apache2 $ sudo mv php.ini php.ini.orig $ sudo ln -s /usr/lib/php/7.0/php.ini-development php.ini
There's more…
Along with PHP, Apache supports various other scripting languages for dynamic content. You can install modules for Perl, Python, Ruby, and other scripting languages.
Add Python support:
$ sudo apt-get install libapache2-mod-python
Add Perl support:
$ sudo apt-get install libapache2-mod-perl2
Add Ruby support:
$ sudo apt-get install libapache2-mod-passenger
Installing the LAMP stack
If you are interested in installing the entire LAMP stack, then Ubuntu provides a single command to do so. Use the following command to install Apache, PHP, and MySQL collectively:
$ sudo apt-get install lamp-server^
Notice the caret symbol at the end of the command. If you miss this symbol, apt
will return an error saying package not found
.
Note
lamp-server
is set in the Ubuntu repository as a task to install and configure Apache, PHP, and MySQL collectively. The caret symbol in apt-get
command is used to specify the task rather than the package. Alternatively, you can use the tasksel
command as $ sudo tasksel install lamp-server
. Tasksel is a program used to ease the installation of packages that are commonly used together.
Upgrading PHP under Ubuntu 14
As of Ubuntu 14.10, Ubuntu does not provide a package for PHP7 in its repository, but you can use a Debian package repository to upgrade your PHP version. This repository is maintained by Ondřej Surý.
Use the following commands to upgrade to PHP 7:
$ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get install php7.0
Check the PHP version after installation completes:
$ php -v
How to do it…
Follow these steps to serve dynamic contents with PHP:
- Install PHP7 and the Apache module for PHP support:
$ sudo apt-get update $ sudo apt-get install -y php7.0 libapache2-mod-php7.0
- Check if PHP is properly installed and which version has been installed:
$ php -v
- Create
index.php
under thepublic_html
directory of our site:$ cd /var/www/example.com/public_html $ vi index.php
- Add the following contents to
index.php
:<?php echo phpinfo(); ?>
- Save and exit the
index.php
file. - Open
example.com.conf
fromsites-available
:$ sudo vi /etc/apache2/sites-available/example.com.conf
- Add the following line under the
VirtualHost
directive:DirectoryIndex index.php index.html
- Save the changes and reload Apache:
$ sudo service apache2 reload
- Now, access your site with your browser, and you should see a page with information regarding the installed PHP:
How it works…
Here, we have installed PHP binaries on our server along with the Apache module libapache2-mod-php7.0
to support dynamic content coded in PHP. A module, mod_php
, runs inside Apache process and processes PHP scripts from within Apache itself. For mod_php
to work, Apache needs to run with the mpm_prefork
module. PHP setup completes all these settings and restarts the Apache server:
After we have installed PHP and mod_php
, we simply need to create a PHP script. We have created index.php
with little code to display phpinfo
. At this stage, if you have both index.html
and index.php
under the same directory; by default, index.html
will take over and be rendered first. You will need to explicitly specify index.php
to access the page as http://127.0.0.1/index.php
. We have set a directive, DirectoryIndex
, under Apache Virtual Host to set index.php
as a default index file.
PHP settings
All PHP settings are listed under its own configuration file, php.ini
. PHP comes with two sets of configurations, as follows:
/usr/lib/php/7.0/php.ini-development
The /usr/lib/php/7.0/php.ini-productionDevelopment
file is customized for a development environment and enables options like display_errors
. For production systems, you can use the configuration file, php.ini-production
.
The preceding files can be treated as a reference configuration that ships with the PHP installation. A copy of php.ini-production
can be found under /etc/php/7.0
. Apache and CLI configurations are separated in respective directories. You can directly edit settings under these files or simply use default files by creating a symbolic link to the development or production file as follows:
$ cd /etc/php/7.0/apache2 $ sudo mv php.ini php.ini.orig $ sudo ln -s /usr/lib/php/7.0/php.ini-development php.ini
There's more…
Along with PHP, Apache supports various other scripting languages for dynamic content. You can install modules for Perl, Python, Ruby, and other scripting languages.
Add Python support:
$ sudo apt-get install libapache2-mod-python
Add Perl support:
$ sudo apt-get install libapache2-mod-perl2
Add Ruby support:
$ sudo apt-get install libapache2-mod-passenger
Installing the LAMP stack
If you are interested in installing the entire LAMP stack, then Ubuntu provides a single command to do so. Use the following command to install Apache, PHP, and MySQL collectively:
$ sudo apt-get install lamp-server^
Notice the caret symbol at the end of the command. If you miss this symbol, apt
will return an error saying package not found
.
Note
lamp-server
is set in the Ubuntu repository as a task to install and configure Apache, PHP, and MySQL collectively. The caret symbol in apt-get
command is used to specify the task rather than the package. Alternatively, you can use the tasksel
command as $ sudo tasksel install lamp-server
. Tasksel is a program used to ease the installation of packages that are commonly used together.
Upgrading PHP under Ubuntu 14
As of Ubuntu 14.10, Ubuntu does not provide a package for PHP7 in its repository, but you can use a Debian package repository to upgrade your PHP version. This repository is maintained by Ondřej Surý.
Use the following commands to upgrade to PHP 7:
$ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get install php7.0
Check the PHP version after installation completes:
$ php -v
How it works…
Here, we have installed PHP binaries on our server along with the Apache module libapache2-mod-php7.0
to support dynamic content coded in PHP. A module, mod_php
, runs inside Apache process and processes PHP scripts from within Apache itself. For mod_php
to work, Apache needs to run with the mpm_prefork
module. PHP setup completes all these settings and restarts the Apache server:
After we have installed PHP and mod_php
, we simply need to create a PHP script. We have created index.php
with little code to display phpinfo
. At this stage, if you have both index.html
and index.php
under the same directory; by default, index.html
will take over and be rendered first. You will need to explicitly specify index.php
to access the page as http://127.0.0.1/index.php
. We have set a directive, DirectoryIndex
, under Apache Virtual Host to set index.php
as a default index file.
PHP settings
All PHP settings are listed under its own configuration file, php.ini
. PHP comes with two sets of configurations, as follows:
/usr/lib/php/7.0/php.ini-development
The /usr/lib/php/7.0/php.ini-productionDevelopment
file is customized for a development environment and enables options like display_errors
. For production systems, you can use the configuration file, php.ini-production
.
The preceding files can be treated as a reference configuration that ships with the PHP installation. A copy of php.ini-production
can be found under /etc/php/7.0
. Apache and CLI configurations are separated in respective directories. You can directly edit settings under these files or simply use default files by creating a symbolic link to the development or production file as follows:
$ cd /etc/php/7.0/apache2 $ sudo mv php.ini php.ini.orig $ sudo ln -s /usr/lib/php/7.0/php.ini-development php.ini
There's more…
Along with PHP, Apache supports various other scripting languages for dynamic content. You can install modules for Perl, Python, Ruby, and other scripting languages.
Add Python support:
$ sudo apt-get install libapache2-mod-python
Add Perl support:
$ sudo apt-get install libapache2-mod-perl2
Add Ruby support:
$ sudo apt-get install libapache2-mod-passenger
Installing the LAMP stack
If you are interested in installing the entire LAMP stack, then Ubuntu provides a single command to do so. Use the following command to install Apache, PHP, and MySQL collectively:
$ sudo apt-get install lamp-server^
Notice the caret symbol at the end of the command. If you miss this symbol, apt
will return an error saying package not found
.
Note
lamp-server
is set in the Ubuntu repository as a task to install and configure Apache, PHP, and MySQL collectively. The caret symbol in apt-get
command is used to specify the task rather than the package. Alternatively, you can use the tasksel
command as $ sudo tasksel install lamp-server
. Tasksel is a program used to ease the installation of packages that are commonly used together.
Upgrading PHP under Ubuntu 14
As of Ubuntu 14.10, Ubuntu does not provide a package for PHP7 in its repository, but you can use a Debian package repository to upgrade your PHP version. This repository is maintained by Ondřej Surý.
Use the following commands to upgrade to PHP 7:
$ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get install php7.0
Check the PHP version after installation completes:
$ php -v
PHP settings
All PHP settings are listed under its own configuration file, php.ini
. PHP comes with two sets of configurations, as follows:
/usr/lib/php/7.0/php.ini-development
The /usr/lib/php/7.0/php.ini-productionDevelopment
file is customized for a development environment and enables options like display_errors
. For production systems, you can use the configuration file, php.ini-production
.
The preceding files can be treated as a reference configuration that ships with the PHP installation. A copy of php.ini-production
can be found under /etc/php/7.0
. Apache and CLI configurations are separated in respective directories. You can directly edit settings under these files or simply use default files by creating a symbolic link to the development or production file as follows:
$ cd /etc/php/7.0/apache2 $ sudo mv php.ini php.ini.orig $ sudo ln -s /usr/lib/php/7.0/php.ini-development php.ini
Along with PHP, Apache supports various other scripting languages for dynamic content. You can install modules for Perl, Python, Ruby, and other scripting languages.
Add Python support:
$ sudo apt-get install libapache2-mod-python
Add Perl support:
$ sudo apt-get install libapache2-mod-perl2
Add Ruby support:
$ sudo apt-get install libapache2-mod-passenger
Installing the LAMP stack
If you are interested in installing the entire LAMP stack, then Ubuntu provides a single command to do so. Use the following command to install Apache, PHP, and MySQL collectively:
$ sudo apt-get install lamp-server^
Notice the caret symbol at the end of the command. If you miss this symbol, apt
will return an error saying package not found
.
Note
lamp-server
is set in the Ubuntu repository as a task to install and configure Apache, PHP, and MySQL collectively. The caret symbol in apt-get
command is used to specify the task rather than the package. Alternatively, you can use the tasksel
command as $ sudo tasksel install lamp-server
. Tasksel is a program used to ease the installation of packages that are commonly used together.
Upgrading PHP under Ubuntu 14
As of Ubuntu 14.10, Ubuntu does not provide a package for PHP7 in its repository, but you can use a Debian package repository to upgrade your PHP version. This repository is maintained by Ondřej Surý.
Use the following commands to upgrade to PHP 7:
$ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get install php7.0
Check the PHP version after installation completes:
$ php -v
There's more…
Along with PHP, Apache supports various other scripting languages for dynamic content. You can install modules for Perl, Python, Ruby, and other scripting languages.
Add Python support:
$ sudo apt-get install libapache2-mod-python
Add Perl support:
$ sudo apt-get install libapache2-mod-perl2
Add Ruby support:
$ sudo apt-get install libapache2-mod-passenger
Installing the LAMP stack
If you are interested in installing the entire LAMP stack, then Ubuntu provides a single command to do so. Use the following command to install Apache, PHP, and MySQL collectively:
$ sudo apt-get install lamp-server^
Notice the caret symbol at the end of the command. If you miss this symbol, apt
will return an error saying package not found
.
Note
lamp-server
is set in the Ubuntu repository as a task to install and configure Apache, PHP, and MySQL collectively. The caret symbol in apt-get
command is used to specify the task rather than the package. Alternatively, you can use the tasksel
command as $ sudo tasksel install lamp-server
. Tasksel is a program used to ease the installation of packages that are commonly used together.
Upgrading PHP under Ubuntu 14
As of Ubuntu 14.10, Ubuntu does not provide a package for PHP7 in its repository, but you can use a Debian package repository to upgrade your PHP version. This repository is maintained by Ondřej Surý.
Use the following commands to upgrade to PHP 7:
$ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get install php7.0
Check the PHP version after installation completes:
$ php -v
Installing the LAMP stack
If you are interested in installing the entire LAMP stack, then Ubuntu provides a single command to do so. Use the following command to install Apache, PHP, and MySQL collectively:
$ sudo apt-get install lamp-server^
Notice the caret symbol at the end of the command. If you miss this symbol, apt
will return an error saying package not found
.
Note
lamp-server
is set in the Ubuntu repository as a task to install and configure Apache, PHP, and MySQL collectively. The caret symbol in apt-get
command is used to specify the task rather than the package. Alternatively, you can use the tasksel
command as $ sudo tasksel install lamp-server
. Tasksel is a program used to ease the installation of packages that are commonly used together.
Upgrading PHP under Ubuntu 14
As of Ubuntu 14.10, Ubuntu does not provide a package for PHP7 in its repository, but you can use a Debian package repository to upgrade your PHP version. This repository is maintained by Ondřej Surý.
Use the following commands to upgrade to PHP 7:
$ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get install php7.0
Check the PHP version after installation completes:
$ php -v
Upgrading PHP under Ubuntu 14
As of Ubuntu 14.10, Ubuntu does not provide a package for PHP7 in its repository, but you can use a Debian package repository to upgrade your PHP version. This repository is maintained by Ondřej Surý.
Use the following commands to upgrade to PHP 7:
$ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get install php7.0
Check the PHP version after installation completes:
$ php -v
Hosting multiple websites with a virtual domain
Setting multiple domains on a single server is a very commonly asked question. In fact, it is very easy to do this with virtual host. In this recipe, we will set up two domains on a single server and set up a sub-domain as well. We will also look at IP-based virtual hosts.
Getting ready
You will need access to a root account or an account with sudo
privileges.
You will need the Apache server installed and working. This recipe describes configuration for Apache version 2.4
You may need a DNS set up if you want to access configured domains over the Internet.
We will set up two domains, namely example1.dom
and example2.com
, and a sub-domain, dev.example1.com
.
How to do it…
Follow these steps to host multiple websites with a virtual domain:
- Change the directory to
/var/www
and create a directory structure for the required domains and sub-domain. Also create a blankindex.html
for each domain:$ cd /var/www $ sudo mkdir -p example1.com/public_html $ sudo touch example1.com/public_html $ sudo cp -R example1.com example2.com $ sudo cp -R example1.com dev.example1.com
- Change the directory ownership and file permissions on the newly created directories:
$ sudo chown -R ubuntu:www-data example* $ sudo chown -R ubuntu:www-data dev.example1.com $ chmod 750 -R example* $ chmod 750 -R dev.example1.com
Tip
Note the use of the wildcard syntax (
chmod 750 -R example*
). You can use a similar syntax with various other commands in Linux and save some repeated typing or copy and paste work. - Edit the
index.html
file for each domain with the respective text: - Next, we need to create virtual host configuration for each domain. Change the directory to
/etc/apache2/sites-available
and copy the default virtual host file000-default.conf
:$ cd /etc/apache2/sites-available $ sudo cp 000-default.conf example1.com.conf
- Edit the new virtual host file and set
ServerName
,DocumentRoot
, and other variables to match your environment. The final file should look something like this:<VirtualHost *:80> ServerName example1.com ServerAlias www.example1.com DocumentRoot /var/www/example1.com/public_html ... </VirtualHost>
- Now copy this virtual host file to create
example2.com.conf
anddev.example1.com.conf
and modify the respective settings in each of them. You need to update theserverName
,serverAlias
, andDocumentRoot
parameters. - Here, we are done with the setup and configuration part. Now enable the virtual hosts and reload the Apache server for the settings to take effect:
$ sudo a2ensite example* $ sudo a2ensite dev.example1.com.conf $ sudo service apache2 reload
- You can check all enabled virtual hosts with the following command:
$ sudo a2query -s
- Next, to test our setup, we need to configure the hosts' setup on the local system. Open and edit the
/etc/hosts
file and add host entries. If you have Windows as your local system, you can find thehosts
file under%systemroot%\System32\drivers\etc
: - Finally, try to access domains by their names. You should see text entered in the respective
index.html
files for each domain:
How it works…
Multiple domain hosting works with the concept of NamedVirtualHost. We have configured virtual hosts with ServerName and ServerAlias. When a client sends a request with a domain name, it sends a host name in the request headers. This host name is used by Apache to determine the actual virtual host to serve this request. If none of the available virtual hosts match the requested host header, then the default virtual host or the first virtual host will be used to serve the request.
In this example, we have used hosts file to map test domain names with local IP. With the actual domain name, you need to point DNS servers to the IP address of your web server. Generally, all popular hosting providers host their own DNS servers. You need to add these DNS servers to your domain setting with domain registrar. Then, on your hosting side, you need to set respective A records and CNAME records. An A record points to an IP address and the CNAME record is an alias for the A record used for pointing a subdomain to an A record. Your hosting provider should give you details on how to configure domains and subdomains.
In previous versions of Apache server, you might need to enable NameVirtualHost
under the configuration file. Find a line similar to #NameVirtualHost 172.20.30.40
and uncomment it by removing the #
symbol at the start.
You can also set up IP-based virtual hosts. If you have multiple IP addresses available on your server, you can set the virtual host to listen on a particular IP address. Use the following steps to set up an IP-based virtual host:
- Get a list of the available IP addresses:
$ ifconfig | grep "inet addr" ubuntu@ubuntu:~$ ifconfig | grep "inet addr" inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet addr:192.168.56.102 Bcast:192.168.56.255 Mask:255.255.255.0 inet addr:127.0.0.1 Mask:255.0.0.0
- Edit the virtual host configuration and set it to match the following:
Listen 80 <VirtualHost 192.168.56.102> DocumentRoot /var/www/example1.com/public_html ServerName example1.com </VirtualHost>
See also
- Apache documentation at https://httpd.apache.org/docs/2.2/vhosts/examples.html
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
Getting ready
You will need access to a root account or an account with sudo
privileges.
You will need the Apache server installed and working. This recipe describes configuration for Apache version 2.4
You may need a DNS set up if you want to access configured domains over the Internet.
We will set up two domains, namely example1.dom
and example2.com
, and a sub-domain, dev.example1.com
.
How to do it…
Follow these steps to host multiple websites with a virtual domain:
- Change the directory to
/var/www
and create a directory structure for the required domains and sub-domain. Also create a blankindex.html
for each domain:$ cd /var/www $ sudo mkdir -p example1.com/public_html $ sudo touch example1.com/public_html $ sudo cp -R example1.com example2.com $ sudo cp -R example1.com dev.example1.com
- Change the directory ownership and file permissions on the newly created directories:
$ sudo chown -R ubuntu:www-data example* $ sudo chown -R ubuntu:www-data dev.example1.com $ chmod 750 -R example* $ chmod 750 -R dev.example1.com
Tip
Note the use of the wildcard syntax (
chmod 750 -R example*
). You can use a similar syntax with various other commands in Linux and save some repeated typing or copy and paste work. - Edit the
index.html
file for each domain with the respective text: - Next, we need to create virtual host configuration for each domain. Change the directory to
/etc/apache2/sites-available
and copy the default virtual host file000-default.conf
:$ cd /etc/apache2/sites-available $ sudo cp 000-default.conf example1.com.conf
- Edit the new virtual host file and set
ServerName
,DocumentRoot
, and other variables to match your environment. The final file should look something like this:<VirtualHost *:80> ServerName example1.com ServerAlias www.example1.com DocumentRoot /var/www/example1.com/public_html ... </VirtualHost>
- Now copy this virtual host file to create
example2.com.conf
anddev.example1.com.conf
and modify the respective settings in each of them. You need to update theserverName
,serverAlias
, andDocumentRoot
parameters. - Here, we are done with the setup and configuration part. Now enable the virtual hosts and reload the Apache server for the settings to take effect:
$ sudo a2ensite example* $ sudo a2ensite dev.example1.com.conf $ sudo service apache2 reload
- You can check all enabled virtual hosts with the following command:
$ sudo a2query -s
- Next, to test our setup, we need to configure the hosts' setup on the local system. Open and edit the
/etc/hosts
file and add host entries. If you have Windows as your local system, you can find thehosts
file under%systemroot%\System32\drivers\etc
: - Finally, try to access domains by their names. You should see text entered in the respective
index.html
files for each domain:
How it works…
Multiple domain hosting works with the concept of NamedVirtualHost. We have configured virtual hosts with ServerName and ServerAlias. When a client sends a request with a domain name, it sends a host name in the request headers. This host name is used by Apache to determine the actual virtual host to serve this request. If none of the available virtual hosts match the requested host header, then the default virtual host or the first virtual host will be used to serve the request.
In this example, we have used hosts file to map test domain names with local IP. With the actual domain name, you need to point DNS servers to the IP address of your web server. Generally, all popular hosting providers host their own DNS servers. You need to add these DNS servers to your domain setting with domain registrar. Then, on your hosting side, you need to set respective A records and CNAME records. An A record points to an IP address and the CNAME record is an alias for the A record used for pointing a subdomain to an A record. Your hosting provider should give you details on how to configure domains and subdomains.
In previous versions of Apache server, you might need to enable NameVirtualHost
under the configuration file. Find a line similar to #NameVirtualHost 172.20.30.40
and uncomment it by removing the #
symbol at the start.
You can also set up IP-based virtual hosts. If you have multiple IP addresses available on your server, you can set the virtual host to listen on a particular IP address. Use the following steps to set up an IP-based virtual host:
- Get a list of the available IP addresses:
$ ifconfig | grep "inet addr" ubuntu@ubuntu:~$ ifconfig | grep "inet addr" inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet addr:192.168.56.102 Bcast:192.168.56.255 Mask:255.255.255.0 inet addr:127.0.0.1 Mask:255.0.0.0
- Edit the virtual host configuration and set it to match the following:
Listen 80 <VirtualHost 192.168.56.102> DocumentRoot /var/www/example1.com/public_html ServerName example1.com </VirtualHost>
See also
- Apache documentation at https://httpd.apache.org/docs/2.2/vhosts/examples.html
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
How to do it…
Follow these steps to host multiple websites with a virtual domain:
- Change the directory to
/var/www
and create a directory structure for the required domains and sub-domain. Also create a blankindex.html
for each domain:$ cd /var/www $ sudo mkdir -p example1.com/public_html $ sudo touch example1.com/public_html $ sudo cp -R example1.com example2.com $ sudo cp -R example1.com dev.example1.com
- Change the directory ownership and file permissions on the newly created directories:
$ sudo chown -R ubuntu:www-data example* $ sudo chown -R ubuntu:www-data dev.example1.com $ chmod 750 -R example* $ chmod 750 -R dev.example1.com
Tip
Note the use of the wildcard syntax (
chmod 750 -R example*
). You can use a similar syntax with various other commands in Linux and save some repeated typing or copy and paste work. - Edit the
index.html
file for each domain with the respective text: - Next, we need to create virtual host configuration for each domain. Change the directory to
/etc/apache2/sites-available
and copy the default virtual host file000-default.conf
:$ cd /etc/apache2/sites-available $ sudo cp 000-default.conf example1.com.conf
- Edit the new virtual host file and set
ServerName
,DocumentRoot
, and other variables to match your environment. The final file should look something like this:<VirtualHost *:80> ServerName example1.com ServerAlias www.example1.com DocumentRoot /var/www/example1.com/public_html ... </VirtualHost>
- Now copy this virtual host file to create
example2.com.conf
anddev.example1.com.conf
and modify the respective settings in each of them. You need to update theserverName
,serverAlias
, andDocumentRoot
parameters. - Here, we are done with the setup and configuration part. Now enable the virtual hosts and reload the Apache server for the settings to take effect:
$ sudo a2ensite example* $ sudo a2ensite dev.example1.com.conf $ sudo service apache2 reload
- You can check all enabled virtual hosts with the following command:
$ sudo a2query -s
- Next, to test our setup, we need to configure the hosts' setup on the local system. Open and edit the
/etc/hosts
file and add host entries. If you have Windows as your local system, you can find thehosts
file under%systemroot%\System32\drivers\etc
: - Finally, try to access domains by their names. You should see text entered in the respective
index.html
files for each domain:
How it works…
Multiple domain hosting works with the concept of NamedVirtualHost. We have configured virtual hosts with ServerName and ServerAlias. When a client sends a request with a domain name, it sends a host name in the request headers. This host name is used by Apache to determine the actual virtual host to serve this request. If none of the available virtual hosts match the requested host header, then the default virtual host or the first virtual host will be used to serve the request.
In this example, we have used hosts file to map test domain names with local IP. With the actual domain name, you need to point DNS servers to the IP address of your web server. Generally, all popular hosting providers host their own DNS servers. You need to add these DNS servers to your domain setting with domain registrar. Then, on your hosting side, you need to set respective A records and CNAME records. An A record points to an IP address and the CNAME record is an alias for the A record used for pointing a subdomain to an A record. Your hosting provider should give you details on how to configure domains and subdomains.
In previous versions of Apache server, you might need to enable NameVirtualHost
under the configuration file. Find a line similar to #NameVirtualHost 172.20.30.40
and uncomment it by removing the #
symbol at the start.
You can also set up IP-based virtual hosts. If you have multiple IP addresses available on your server, you can set the virtual host to listen on a particular IP address. Use the following steps to set up an IP-based virtual host:
- Get a list of the available IP addresses:
$ ifconfig | grep "inet addr" ubuntu@ubuntu:~$ ifconfig | grep "inet addr" inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet addr:192.168.56.102 Bcast:192.168.56.255 Mask:255.255.255.0 inet addr:127.0.0.1 Mask:255.0.0.0
- Edit the virtual host configuration and set it to match the following:
Listen 80 <VirtualHost 192.168.56.102> DocumentRoot /var/www/example1.com/public_html ServerName example1.com </VirtualHost>
See also
- Apache documentation at https://httpd.apache.org/docs/2.2/vhosts/examples.html
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
How it works…
Multiple domain hosting works with the concept of NamedVirtualHost. We have configured virtual hosts with ServerName and ServerAlias. When a client sends a request with a domain name, it sends a host name in the request headers. This host name is used by Apache to determine the actual virtual host to serve this request. If none of the available virtual hosts match the requested host header, then the default virtual host or the first virtual host will be used to serve the request.
In this example, we have used hosts file to map test domain names with local IP. With the actual domain name, you need to point DNS servers to the IP address of your web server. Generally, all popular hosting providers host their own DNS servers. You need to add these DNS servers to your domain setting with domain registrar. Then, on your hosting side, you need to set respective A records and CNAME records. An A record points to an IP address and the CNAME record is an alias for the A record used for pointing a subdomain to an A record. Your hosting provider should give you details on how to configure domains and subdomains.
In previous versions of Apache server, you might need to enable NameVirtualHost
under the configuration file. Find a line similar to #NameVirtualHost 172.20.30.40
and uncomment it by removing the #
symbol at the start.
You can also set up IP-based virtual hosts. If you have multiple IP addresses available on your server, you can set the virtual host to listen on a particular IP address. Use the following steps to set up an IP-based virtual host:
- Get a list of the available IP addresses:
$ ifconfig | grep "inet addr" ubuntu@ubuntu:~$ ifconfig | grep "inet addr" inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet addr:192.168.56.102 Bcast:192.168.56.255 Mask:255.255.255.0 inet addr:127.0.0.1 Mask:255.0.0.0
- Edit the virtual host configuration and set it to match the following:
Listen 80 <VirtualHost 192.168.56.102> DocumentRoot /var/www/example1.com/public_html ServerName example1.com </VirtualHost>
See also
- Apache documentation at https://httpd.apache.org/docs/2.2/vhosts/examples.html
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
See also
- Apache documentation at https://httpd.apache.org/docs/2.2/vhosts/examples.html
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
Securing web traffic with HTTPS
HTTP is a non-secure protocol commonly used to communicate over the Web. The traffic is transferred in plain text form and can be captured and interpreted by a third-party attacker. Transport Layer Security and Secure Socket Layer protocols (TLS/SSL) can be used to secure the traffic between client and server. These protocols encapsulate normal traffic in an encrypted and secure wrapper. It also validates the identity of the client and server with SSL keys, certificates, and certification authorities.
When HTTP is combined with TLS or SSL, it is abbreviated as HTTPS or HTTP secure. Port 443
is used as a standard port for secured HTTP communication. Nearly all leading web servers provide inbuilt support for enabling HTTPS. Apache has a module called mod_ssl
that enables the use of HTTPS.
To set up your servers with SSL/TLS encrypted traffic, you will need an SSL certificate and a key pair that can be used to encrypt traffic. Generally, the certificate and keys are obtained from a trusted signing authority. They charge you some fees to verify your ownership of the web property and allocate the required signed certificates. You can also generate self-signed certificates for internal use. Few certification authorities provide a free SSL certificate. Recently, Mozilla has started a free and automated certificate authority named Let's Encrypt. At the time of writing, the service is in public beta and has started allocating certificates. Let's Encrypt offers a client that can be used to obtain certificates and set up automated renewal. You can also find various unofficial clients for Apache and Nginx servers.
In this recipe, we will learn how to create our own self-signed certificate and set up the Apache server to serve contents over a secure channel.
Getting ready
You will need access to a root account or an account with sudo
privileges. I assume that you have the Apache server preinstalled. You will also need OpenSSL installed.
Make sure your firewall, if any, allows traffic on port 443
. Check Chapter 2, Networking, Securing network with uncomplicated firewall recipe for more details on Uncomplicated Firewall.
How to do it…
Follow these steps to secure web traffic with HTTPS:
- First, we will start by creating a self-signed SSL certificate. Create a directory under
/etc/apache2
to hold the certificate and key:$ sudo mkdir /etc/apache2/ssl
- Change to the new directory and enter the following command to create a certificate and SSL key:
$ cd /etc/apache2/ssl $ sudo openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout ssl.key -out ssl.crt
- This will prompt you to enter some information about your company and website. Enter the respective details and press Enter for each prompt:
- After you are done with it, you can check the generated certificate and key:
$ ls -l
- Next, we need to configure Apache to use SSL. We will enable SSL for the previously created virtual host.
- Open the Virtual Host configuration file,
example.com.conf
. After removing comments, it should look similar to the following: - Now, copy the entire
<VirtualHost *:80> ... </VirtualHost>
tag and paste it at the end of the file. - Under the newly copied contents, change the port from
80
to443
. - Add the following lines below the
DocumentRoot
line. This will enable SSL and specify the path to the certificate and key:SSLEngine on SSLCertificateFile /etc/apache2/ssl/ssl.crt SSLCertificateKeyFile /etc/apache2/ssl/ssl.key
- The final file should look something like this:
- Save the changes, exit
example.com.conf
, and enable themod_ssl
module on the Apache server:$ sudo a2enmod ssl
- Next, enable the Virtual Host
example.com
. If it's already enabled, it will return a message sayingsite example.com already enabled
:$ sudo a2ensite example.com.conf
- Reload the Apache server for the changes to take effect:
$ sudo service apache2 reload
- Now, open your browser on the client system and point it to your domain name or IP address with HTTPS at the start:
https://example.com
- Your browser may return an error saying Invalid Certification Authority. This is fine as we are using a self-signed certificate. Click Advanced and then click Proceed to example.com to open a specified page:
- Once the page is loaded completely, find the padlock icon in the upper right corner of the browser and click on it. The second section with the green lock icon will display the encryption status. Now your communication with the server is encrypted and secure:
How it works…
We have created a self-signed certificate to secure an HTTP communication. The key will be used to encrypt all communication with clients. Another thing to note is that we have defined a separate Virtual Host entry on port 443
. This Virtual Host will be used for all requests that are received over port 443
. At the same time, we have allowed non-secured HTTP communication for the same Virtual Host. To disable non-secure communication on port 80
, you can simply comment out the original Virtual Host configuration. Alternatively, you can separate both configurations into two files and enable or disable with the a2ensite
and a2dissite
commands.
Some of the parameters used for generating a key and certificate are as follows:
- nodes
specifies that we do not want to use a passphrase for a key.- days
this specifies the number of days the certificate is valid for. Our certificate is valid for 365 days, that is, a year.- newkey rsa:2048
this option is used to generate a certificate along with a private key.rsa:2048
specifies the 2048 bit long RSA private key.
I have modified the existing Virtual Host entry to demonstrate the minimal configuration required to enable secure HTTP communication. You can always use the default secure Virtual Host configuration available under sites-available/default-ssl.conf
. This file provides some additional parameters with respective comments.
The certificate created in this recipe will not be trusted over the Internet but can be used for securing local or internal communication. For production use, it is advisable to get a certificate signed from an external, well known certification authority. This will avoid the initial errors in browsers.
There's more…
To get a signed certificate from an external certification authority, you will need a CSR document.
The following are the steps to generate a CSR:
- Generate a key for the CSR:
$ openssl genrsa -des3 -out server.key 2048
- You will be asked to enter a passphrase for the key and then verify it. They will be generated with name
server.key
. - Now, remove the passphrase from the key. We don't want to enter a passphrase each time a key is used:
$ openssl rsa -in server.key -out server.key.insecure $ mv server.key server.key.secure $ mv server.key.insecure server.key
- Next, create the CSR with the following command:
$ openssl req -new -key server.key -out server.csr
- A CSR file is created with the name
server.csr
, and now you can submit this CSR for signing purposes.
See also
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
- Check out the certificates and security in the Ubuntu server guide at https://help.ubuntu.com/lts/serverguide/certificates-and-security.html
- How to set up client verification at http://askubuntu.com/questions/511149/how-to-setup-ssl-https-for-your-site-on-ubuntu-linux-two-way-ssl
- Apache documentation on SSL configuration at http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- Free SSL certificate with Mozilla Let's Encrypt at https://letsencrypt.org/getting-started/
- Easily generate SSL configuration for your web server at Mozilla SSL Configuration Generator at https://mozilla.github.io/server-side-tls/ssl-config-generator/
Getting ready
You will need access to a root account or an account with sudo
privileges. I assume that you have the Apache server preinstalled. You will also need OpenSSL installed.
Make sure your firewall, if any, allows traffic on port 443
. Check Chapter 2, Networking, Securing network with uncomplicated firewall recipe for more details on Uncomplicated Firewall.
How to do it…
Follow these steps to secure web traffic with HTTPS:
- First, we will start by creating a self-signed SSL certificate. Create a directory under
/etc/apache2
to hold the certificate and key:$ sudo mkdir /etc/apache2/ssl
- Change to the new directory and enter the following command to create a certificate and SSL key:
$ cd /etc/apache2/ssl $ sudo openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout ssl.key -out ssl.crt
- This will prompt you to enter some information about your company and website. Enter the respective details and press Enter for each prompt:
- After you are done with it, you can check the generated certificate and key:
$ ls -l
- Next, we need to configure Apache to use SSL. We will enable SSL for the previously created virtual host.
- Open the Virtual Host configuration file,
example.com.conf
. After removing comments, it should look similar to the following: - Now, copy the entire
<VirtualHost *:80> ... </VirtualHost>
tag and paste it at the end of the file. - Under the newly copied contents, change the port from
80
to443
. - Add the following lines below the
DocumentRoot
line. This will enable SSL and specify the path to the certificate and key:SSLEngine on SSLCertificateFile /etc/apache2/ssl/ssl.crt SSLCertificateKeyFile /etc/apache2/ssl/ssl.key
- The final file should look something like this:
- Save the changes, exit
example.com.conf
, and enable themod_ssl
module on the Apache server:$ sudo a2enmod ssl
- Next, enable the Virtual Host
example.com
. If it's already enabled, it will return a message sayingsite example.com already enabled
:$ sudo a2ensite example.com.conf
- Reload the Apache server for the changes to take effect:
$ sudo service apache2 reload
- Now, open your browser on the client system and point it to your domain name or IP address with HTTPS at the start:
https://example.com
- Your browser may return an error saying Invalid Certification Authority. This is fine as we are using a self-signed certificate. Click Advanced and then click Proceed to example.com to open a specified page:
- Once the page is loaded completely, find the padlock icon in the upper right corner of the browser and click on it. The second section with the green lock icon will display the encryption status. Now your communication with the server is encrypted and secure:
How it works…
We have created a self-signed certificate to secure an HTTP communication. The key will be used to encrypt all communication with clients. Another thing to note is that we have defined a separate Virtual Host entry on port 443
. This Virtual Host will be used for all requests that are received over port 443
. At the same time, we have allowed non-secured HTTP communication for the same Virtual Host. To disable non-secure communication on port 80
, you can simply comment out the original Virtual Host configuration. Alternatively, you can separate both configurations into two files and enable or disable with the a2ensite
and a2dissite
commands.
Some of the parameters used for generating a key and certificate are as follows:
- nodes
specifies that we do not want to use a passphrase for a key.- days
this specifies the number of days the certificate is valid for. Our certificate is valid for 365 days, that is, a year.- newkey rsa:2048
this option is used to generate a certificate along with a private key.rsa:2048
specifies the 2048 bit long RSA private key.
I have modified the existing Virtual Host entry to demonstrate the minimal configuration required to enable secure HTTP communication. You can always use the default secure Virtual Host configuration available under sites-available/default-ssl.conf
. This file provides some additional parameters with respective comments.
The certificate created in this recipe will not be trusted over the Internet but can be used for securing local or internal communication. For production use, it is advisable to get a certificate signed from an external, well known certification authority. This will avoid the initial errors in browsers.
There's more…
To get a signed certificate from an external certification authority, you will need a CSR document.
The following are the steps to generate a CSR:
- Generate a key for the CSR:
$ openssl genrsa -des3 -out server.key 2048
- You will be asked to enter a passphrase for the key and then verify it. They will be generated with name
server.key
. - Now, remove the passphrase from the key. We don't want to enter a passphrase each time a key is used:
$ openssl rsa -in server.key -out server.key.insecure $ mv server.key server.key.secure $ mv server.key.insecure server.key
- Next, create the CSR with the following command:
$ openssl req -new -key server.key -out server.csr
- A CSR file is created with the name
server.csr
, and now you can submit this CSR for signing purposes.
See also
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
- Check out the certificates and security in the Ubuntu server guide at https://help.ubuntu.com/lts/serverguide/certificates-and-security.html
- How to set up client verification at http://askubuntu.com/questions/511149/how-to-setup-ssl-https-for-your-site-on-ubuntu-linux-two-way-ssl
- Apache documentation on SSL configuration at http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- Free SSL certificate with Mozilla Let's Encrypt at https://letsencrypt.org/getting-started/
- Easily generate SSL configuration for your web server at Mozilla SSL Configuration Generator at https://mozilla.github.io/server-side-tls/ssl-config-generator/
How to do it…
Follow these steps to secure web traffic with HTTPS:
- First, we will start by creating a self-signed SSL certificate. Create a directory under
/etc/apache2
to hold the certificate and key:$ sudo mkdir /etc/apache2/ssl
- Change to the new directory and enter the following command to create a certificate and SSL key:
$ cd /etc/apache2/ssl $ sudo openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout ssl.key -out ssl.crt
- This will prompt you to enter some information about your company and website. Enter the respective details and press Enter for each prompt:
- After you are done with it, you can check the generated certificate and key:
$ ls -l
- Next, we need to configure Apache to use SSL. We will enable SSL for the previously created virtual host.
- Open the Virtual Host configuration file,
example.com.conf
. After removing comments, it should look similar to the following: - Now, copy the entire
<VirtualHost *:80> ... </VirtualHost>
tag and paste it at the end of the file. - Under the newly copied contents, change the port from
80
to443
. - Add the following lines below the
DocumentRoot
line. This will enable SSL and specify the path to the certificate and key:SSLEngine on SSLCertificateFile /etc/apache2/ssl/ssl.crt SSLCertificateKeyFile /etc/apache2/ssl/ssl.key
- The final file should look something like this:
- Save the changes, exit
example.com.conf
, and enable themod_ssl
module on the Apache server:$ sudo a2enmod ssl
- Next, enable the Virtual Host
example.com
. If it's already enabled, it will return a message sayingsite example.com already enabled
:$ sudo a2ensite example.com.conf
- Reload the Apache server for the changes to take effect:
$ sudo service apache2 reload
- Now, open your browser on the client system and point it to your domain name or IP address with HTTPS at the start:
https://example.com
- Your browser may return an error saying Invalid Certification Authority. This is fine as we are using a self-signed certificate. Click Advanced and then click Proceed to example.com to open a specified page:
- Once the page is loaded completely, find the padlock icon in the upper right corner of the browser and click on it. The second section with the green lock icon will display the encryption status. Now your communication with the server is encrypted and secure:
How it works…
We have created a self-signed certificate to secure an HTTP communication. The key will be used to encrypt all communication with clients. Another thing to note is that we have defined a separate Virtual Host entry on port 443
. This Virtual Host will be used for all requests that are received over port 443
. At the same time, we have allowed non-secured HTTP communication for the same Virtual Host. To disable non-secure communication on port 80
, you can simply comment out the original Virtual Host configuration. Alternatively, you can separate both configurations into two files and enable or disable with the a2ensite
and a2dissite
commands.
Some of the parameters used for generating a key and certificate are as follows:
- nodes
specifies that we do not want to use a passphrase for a key.- days
this specifies the number of days the certificate is valid for. Our certificate is valid for 365 days, that is, a year.- newkey rsa:2048
this option is used to generate a certificate along with a private key.rsa:2048
specifies the 2048 bit long RSA private key.
I have modified the existing Virtual Host entry to demonstrate the minimal configuration required to enable secure HTTP communication. You can always use the default secure Virtual Host configuration available under sites-available/default-ssl.conf
. This file provides some additional parameters with respective comments.
The certificate created in this recipe will not be trusted over the Internet but can be used for securing local or internal communication. For production use, it is advisable to get a certificate signed from an external, well known certification authority. This will avoid the initial errors in browsers.
There's more…
To get a signed certificate from an external certification authority, you will need a CSR document.
The following are the steps to generate a CSR:
- Generate a key for the CSR:
$ openssl genrsa -des3 -out server.key 2048
- You will be asked to enter a passphrase for the key and then verify it. They will be generated with name
server.key
. - Now, remove the passphrase from the key. We don't want to enter a passphrase each time a key is used:
$ openssl rsa -in server.key -out server.key.insecure $ mv server.key server.key.secure $ mv server.key.insecure server.key
- Next, create the CSR with the following command:
$ openssl req -new -key server.key -out server.csr
- A CSR file is created with the name
server.csr
, and now you can submit this CSR for signing purposes.
See also
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
- Check out the certificates and security in the Ubuntu server guide at https://help.ubuntu.com/lts/serverguide/certificates-and-security.html
- How to set up client verification at http://askubuntu.com/questions/511149/how-to-setup-ssl-https-for-your-site-on-ubuntu-linux-two-way-ssl
- Apache documentation on SSL configuration at http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- Free SSL certificate with Mozilla Let's Encrypt at https://letsencrypt.org/getting-started/
- Easily generate SSL configuration for your web server at Mozilla SSL Configuration Generator at https://mozilla.github.io/server-side-tls/ssl-config-generator/
How it works…
We have created a self-signed certificate to secure an HTTP communication. The key will be used to encrypt all communication with clients. Another thing to note is that we have defined a separate Virtual Host entry on port 443
. This Virtual Host will be used for all requests that are received over port 443
. At the same time, we have allowed non-secured HTTP communication for the same Virtual Host. To disable non-secure communication on port 80
, you can simply comment out the original Virtual Host configuration. Alternatively, you can separate both configurations into two files and enable or disable with the a2ensite
and a2dissite
commands.
Some of the parameters used for generating a key and certificate are as follows:
- nodes
specifies that we do not want to use a passphrase for a key.- days
this specifies the number of days the certificate is valid for. Our certificate is valid for 365 days, that is, a year.- newkey rsa:2048
this option is used to generate a certificate along with a private key.rsa:2048
specifies the 2048 bit long RSA private key.
I have modified the existing Virtual Host entry to demonstrate the minimal configuration required to enable secure HTTP communication. You can always use the default secure Virtual Host configuration available under sites-available/default-ssl.conf
. This file provides some additional parameters with respective comments.
The certificate created in this recipe will not be trusted over the Internet but can be used for securing local or internal communication. For production use, it is advisable to get a certificate signed from an external, well known certification authority. This will avoid the initial errors in browsers.
There's more…
To get a signed certificate from an external certification authority, you will need a CSR document.
The following are the steps to generate a CSR:
- Generate a key for the CSR:
$ openssl genrsa -des3 -out server.key 2048
- You will be asked to enter a passphrase for the key and then verify it. They will be generated with name
server.key
. - Now, remove the passphrase from the key. We don't want to enter a passphrase each time a key is used:
$ openssl rsa -in server.key -out server.key.insecure $ mv server.key server.key.secure $ mv server.key.insecure server.key
- Next, create the CSR with the following command:
$ openssl req -new -key server.key -out server.csr
- A CSR file is created with the name
server.csr
, and now you can submit this CSR for signing purposes.
See also
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
- Check out the certificates and security in the Ubuntu server guide at https://help.ubuntu.com/lts/serverguide/certificates-and-security.html
- How to set up client verification at http://askubuntu.com/questions/511149/how-to-setup-ssl-https-for-your-site-on-ubuntu-linux-two-way-ssl
- Apache documentation on SSL configuration at http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- Free SSL certificate with Mozilla Let's Encrypt at https://letsencrypt.org/getting-started/
- Easily generate SSL configuration for your web server at Mozilla SSL Configuration Generator at https://mozilla.github.io/server-side-tls/ssl-config-generator/
There's more…
To get a signed certificate from an external certification authority, you will need a CSR document.
The following are the steps to generate a CSR:
- Generate a key for the CSR:
$ openssl genrsa -des3 -out server.key 2048
- You will be asked to enter a passphrase for the key and then verify it. They will be generated with name
server.key
. - Now, remove the passphrase from the key. We don't want to enter a passphrase each time a key is used:
$ openssl rsa -in server.key -out server.key.insecure $ mv server.key server.key.secure $ mv server.key.insecure server.key
- Next, create the CSR with the following command:
$ openssl req -new -key server.key -out server.csr
- A CSR file is created with the name
server.csr
, and now you can submit this CSR for signing purposes.
See also
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
- Check out the certificates and security in the Ubuntu server guide at https://help.ubuntu.com/lts/serverguide/certificates-and-security.html
- How to set up client verification at http://askubuntu.com/questions/511149/how-to-setup-ssl-https-for-your-site-on-ubuntu-linux-two-way-ssl
- Apache documentation on SSL configuration at http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- Free SSL certificate with Mozilla Let's Encrypt at https://letsencrypt.org/getting-started/
- Easily generate SSL configuration for your web server at Mozilla SSL Configuration Generator at https://mozilla.github.io/server-side-tls/ssl-config-generator/
See also
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
- Check out the certificates and security in the Ubuntu server guide at https://help.ubuntu.com/lts/serverguide/certificates-and-security.html
- How to set up client verification at http://askubuntu.com/questions/511149/how-to-setup-ssl-https-for-your-site-on-ubuntu-linux-two-way-ssl
- Apache documentation on SSL configuration at http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- Free SSL certificate with Mozilla Let's Encrypt at https://letsencrypt.org/getting-started/
- Easily generate SSL configuration for your web server at Mozilla SSL Configuration Generator at https://mozilla.github.io/server-side-tls/ssl-config-generator/
Installing Nginx with PHP_FPM
In this recipe, we will learn how to install and set up Nginx as a web server. We will also install PHP to be able to serve dynamic content. We need to install PHP_FPM (FastCGI Process Manager), as Nginx doesn't support the native execution of PHP scripts. We will install the latest stable version available from the Nginx package repository.
Getting ready
You will need access to a root account or an account with sudo
privileges.
How to do it…
Follow these steps to install Nginx with PHP_FPM:
- Update the
apt
package repository and install Nginx. As of writing this Ubuntu 16.04 repository contains latest stable release of Nginx with version 1.10.0:$ sudo apt-get update $ sudo apt-get install nginx
- Check if Nginx is properly installed and running:
$ sudo service nginx status
- Check the installed version of Nginx:
$ nginx -v
- You may want to point your browser to the server IP or domain. You should see a default Nginx welcome page:
- Next, proceed with installing PHP_FPM:
$ sudo apt-get install php7.0-fpm
- Configure Nginx to use the PHP processor. Nginx sites are listed at
/etc/nginx/sites-available
. We will modify the default site:$ sudo nano /etc/nginx/sites-available/default
- Find a line stating the priority of the
index
file and addindex.php
as a first option:index index.php index.html index.htm;
- Next, add the following two
location
directives:location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock ; }
- Save the changes and exit the file. It should look similar to this:
- Change the PHP settings to disable
PATH_TRANSLATED
support. Find an option,cgi.fix_pathinfo
, and uncomment it with the value set to0
:$ sudo nano /etc/php/7.0/fpm/php.ini cgi.fix_pathinfo=0
- Now, restart PHP_FPM and Nginx for the changes to take effect:
$ sudo service php7.0-fpm restart $ sudo service nginx restart
- Create an
index.php
file with some PHP code in it at the path mentioned in the default site configuration:$ sudo nano /var/www/html/index.php <?php phpinfo(); ?>
- Open your browser and point it to your server. You should see the result of your PHP script:
How it works…
Here, we have installed the latest stable version of the Nginx server with PHP_FPM to support dynamic content scripted with PHP. The Ubuntu repository for version 16.04 contains the latest stable release of Nginx, So installing Nginx is as easy as a single command. If you are interested in more recent versions Nginx maintains their own package repository for mainline packages. You just need to add repository, the rest of the installation process is similar to a single apt-get install nginx
command.
Note
If you are running the Apache server on the same machine, you may want to change the default port Nginx runs on. You can find these settings under site configurations, located at /etc/nginx/sites-available
. Nginx creates default site configuration with the filename set to default
. Find the lines that start with listen
and change the port from its default, 80
, to any port number of your choice.
After installing Nginx, we need to configure it to support dynamic content. Here, we have selected PHP as a dynamic content processor. PHP is a popular scripting language and very commonly used with web servers for dynamic content processing. You can also add support for other modules by installing their respective processors. After installing PHP_FPM, we have configured Nginx to use PHP_FPM and pass all PHP requests to the FPM module on a socket connection.
We have used two location blocks in configuration. The first block search is for static content, such as files and directories, and then if nothing matches, the request is forwarded to index.php
, which is in turn forwarded to the FastCGI module for processing. This ensures that Nginx serves all static content without executing PHP, and only requests that are not static files and directories are passed to the FPM module.
The following is a brief description of the parameters used under FastCGI configuration:
- The parameter
try_files
configures Nginx to return404
pages, that is, the page not found error, for any requests that do not match website content. This is limited to static files. - With the parameter
fastcgi_param
, you can forward the script name and query string to the PHP FPM process. - One more optional parameter is
cgi.fix_pathinfo=0
, under the PHP configuration filephp.ini
. By default, PHP is set to search for the exact script filename and then search for the closest match if the exact name is not found. This may become a security risk by allowing an attacker to execute random scripts with simple guesswork for script names. We have disabled this by setting its value to0
.
Finally, after we restart PHP_FPM and Nginx, our server is ready to process static as well as dynamic content. All static content will be handled by Nginx itself, and requests for URLs that end with .php
will be forwarded to PHP_FPM for processing. Nginx may cache the processed result for future use.
There's more…
If you are running Ubuntu 12.10, you may need to install the following dependencies before adding the Nginx repository to the installation sources:
- Install
python-software-properties
andsoftware-properties-common
:$ sudo apt-get install python-software-properties $ sudo apt-get install software-properties-common
- You may want to remove your Apache installation completely. Use the following commands to remove Apache:
$ sudo service apache2 stop $ sudo apt-get remove --purge apache2 apache2-utils apache2.2-bin apache2-common
Nginx maintains their own package repositories for stable and mainline releases. These repositories can be used to get the latest updates of Nginx as and when available. Use the stable repository, - $ sudo add-apt-repository ppa:nginx/stable
.
Use the mainline repository - $ sudo add-apt-repository ppa:nginx/development
.
See also
- Common Nginx pitfalls at http://wiki.nginx.org/Pitfalls
- Nginx Quick start guide at http://wiki.nginx.org/QuickStart
Getting ready
You will need access to a root account or an account with sudo
privileges.
How to do it…
Follow these steps to install Nginx with PHP_FPM:
- Update the
apt
package repository and install Nginx. As of writing this Ubuntu 16.04 repository contains latest stable release of Nginx with version 1.10.0:$ sudo apt-get update $ sudo apt-get install nginx
- Check if Nginx is properly installed and running:
$ sudo service nginx status
- Check the installed version of Nginx:
$ nginx -v
- You may want to point your browser to the server IP or domain. You should see a default Nginx welcome page:
- Next, proceed with installing PHP_FPM:
$ sudo apt-get install php7.0-fpm
- Configure Nginx to use the PHP processor. Nginx sites are listed at
/etc/nginx/sites-available
. We will modify the default site:$ sudo nano /etc/nginx/sites-available/default
- Find a line stating the priority of the
index
file and addindex.php
as a first option:index index.php index.html index.htm;
- Next, add the following two
location
directives:location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock ; }
- Save the changes and exit the file. It should look similar to this:
- Change the PHP settings to disable
PATH_TRANSLATED
support. Find an option,cgi.fix_pathinfo
, and uncomment it with the value set to0
:$ sudo nano /etc/php/7.0/fpm/php.ini cgi.fix_pathinfo=0
- Now, restart PHP_FPM and Nginx for the changes to take effect:
$ sudo service php7.0-fpm restart $ sudo service nginx restart
- Create an
index.php
file with some PHP code in it at the path mentioned in the default site configuration:$ sudo nano /var/www/html/index.php <?php phpinfo(); ?>
- Open your browser and point it to your server. You should see the result of your PHP script:
How it works…
Here, we have installed the latest stable version of the Nginx server with PHP_FPM to support dynamic content scripted with PHP. The Ubuntu repository for version 16.04 contains the latest stable release of Nginx, So installing Nginx is as easy as a single command. If you are interested in more recent versions Nginx maintains their own package repository for mainline packages. You just need to add repository, the rest of the installation process is similar to a single apt-get install nginx
command.
Note
If you are running the Apache server on the same machine, you may want to change the default port Nginx runs on. You can find these settings under site configurations, located at /etc/nginx/sites-available
. Nginx creates default site configuration with the filename set to default
. Find the lines that start with listen
and change the port from its default, 80
, to any port number of your choice.
After installing Nginx, we need to configure it to support dynamic content. Here, we have selected PHP as a dynamic content processor. PHP is a popular scripting language and very commonly used with web servers for dynamic content processing. You can also add support for other modules by installing their respective processors. After installing PHP_FPM, we have configured Nginx to use PHP_FPM and pass all PHP requests to the FPM module on a socket connection.
We have used two location blocks in configuration. The first block search is for static content, such as files and directories, and then if nothing matches, the request is forwarded to index.php
, which is in turn forwarded to the FastCGI module for processing. This ensures that Nginx serves all static content without executing PHP, and only requests that are not static files and directories are passed to the FPM module.
The following is a brief description of the parameters used under FastCGI configuration:
- The parameter
try_files
configures Nginx to return404
pages, that is, the page not found error, for any requests that do not match website content. This is limited to static files. - With the parameter
fastcgi_param
, you can forward the script name and query string to the PHP FPM process. - One more optional parameter is
cgi.fix_pathinfo=0
, under the PHP configuration filephp.ini
. By default, PHP is set to search for the exact script filename and then search for the closest match if the exact name is not found. This may become a security risk by allowing an attacker to execute random scripts with simple guesswork for script names. We have disabled this by setting its value to0
.
Finally, after we restart PHP_FPM and Nginx, our server is ready to process static as well as dynamic content. All static content will be handled by Nginx itself, and requests for URLs that end with .php
will be forwarded to PHP_FPM for processing. Nginx may cache the processed result for future use.
There's more…
If you are running Ubuntu 12.10, you may need to install the following dependencies before adding the Nginx repository to the installation sources:
- Install
python-software-properties
andsoftware-properties-common
:$ sudo apt-get install python-software-properties $ sudo apt-get install software-properties-common
- You may want to remove your Apache installation completely. Use the following commands to remove Apache:
$ sudo service apache2 stop $ sudo apt-get remove --purge apache2 apache2-utils apache2.2-bin apache2-common
Nginx maintains their own package repositories for stable and mainline releases. These repositories can be used to get the latest updates of Nginx as and when available. Use the stable repository, - $ sudo add-apt-repository ppa:nginx/stable
.
Use the mainline repository - $ sudo add-apt-repository ppa:nginx/development
.
See also
- Common Nginx pitfalls at http://wiki.nginx.org/Pitfalls
- Nginx Quick start guide at http://wiki.nginx.org/QuickStart
How to do it…
Follow these steps to install Nginx with PHP_FPM:
- Update the
apt
package repository and install Nginx. As of writing this Ubuntu 16.04 repository contains latest stable release of Nginx with version 1.10.0:$ sudo apt-get update $ sudo apt-get install nginx
- Check if Nginx is properly installed and running:
$ sudo service nginx status
- Check the installed version of Nginx:
$ nginx -v
- You may want to point your browser to the server IP or domain. You should see a default Nginx welcome page:
- Next, proceed with installing PHP_FPM:
$ sudo apt-get install php7.0-fpm
- Configure Nginx to use the PHP processor. Nginx sites are listed at
/etc/nginx/sites-available
. We will modify the default site:$ sudo nano /etc/nginx/sites-available/default
- Find a line stating the priority of the
index
file and addindex.php
as a first option:index index.php index.html index.htm;
- Next, add the following two
location
directives:location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock ; }
- Save the changes and exit the file. It should look similar to this:
- Change the PHP settings to disable
PATH_TRANSLATED
support. Find an option,cgi.fix_pathinfo
, and uncomment it with the value set to0
:$ sudo nano /etc/php/7.0/fpm/php.ini cgi.fix_pathinfo=0
- Now, restart PHP_FPM and Nginx for the changes to take effect:
$ sudo service php7.0-fpm restart $ sudo service nginx restart
- Create an
index.php
file with some PHP code in it at the path mentioned in the default site configuration:$ sudo nano /var/www/html/index.php <?php phpinfo(); ?>
- Open your browser and point it to your server. You should see the result of your PHP script:
How it works…
Here, we have installed the latest stable version of the Nginx server with PHP_FPM to support dynamic content scripted with PHP. The Ubuntu repository for version 16.04 contains the latest stable release of Nginx, So installing Nginx is as easy as a single command. If you are interested in more recent versions Nginx maintains their own package repository for mainline packages. You just need to add repository, the rest of the installation process is similar to a single apt-get install nginx
command.
Note
If you are running the Apache server on the same machine, you may want to change the default port Nginx runs on. You can find these settings under site configurations, located at /etc/nginx/sites-available
. Nginx creates default site configuration with the filename set to default
. Find the lines that start with listen
and change the port from its default, 80
, to any port number of your choice.
After installing Nginx, we need to configure it to support dynamic content. Here, we have selected PHP as a dynamic content processor. PHP is a popular scripting language and very commonly used with web servers for dynamic content processing. You can also add support for other modules by installing their respective processors. After installing PHP_FPM, we have configured Nginx to use PHP_FPM and pass all PHP requests to the FPM module on a socket connection.
We have used two location blocks in configuration. The first block search is for static content, such as files and directories, and then if nothing matches, the request is forwarded to index.php
, which is in turn forwarded to the FastCGI module for processing. This ensures that Nginx serves all static content without executing PHP, and only requests that are not static files and directories are passed to the FPM module.
The following is a brief description of the parameters used under FastCGI configuration:
- The parameter
try_files
configures Nginx to return404
pages, that is, the page not found error, for any requests that do not match website content. This is limited to static files. - With the parameter
fastcgi_param
, you can forward the script name and query string to the PHP FPM process. - One more optional parameter is
cgi.fix_pathinfo=0
, under the PHP configuration filephp.ini
. By default, PHP is set to search for the exact script filename and then search for the closest match if the exact name is not found. This may become a security risk by allowing an attacker to execute random scripts with simple guesswork for script names. We have disabled this by setting its value to0
.
Finally, after we restart PHP_FPM and Nginx, our server is ready to process static as well as dynamic content. All static content will be handled by Nginx itself, and requests for URLs that end with .php
will be forwarded to PHP_FPM for processing. Nginx may cache the processed result for future use.
There's more…
If you are running Ubuntu 12.10, you may need to install the following dependencies before adding the Nginx repository to the installation sources:
- Install
python-software-properties
andsoftware-properties-common
:$ sudo apt-get install python-software-properties $ sudo apt-get install software-properties-common
- You may want to remove your Apache installation completely. Use the following commands to remove Apache:
$ sudo service apache2 stop $ sudo apt-get remove --purge apache2 apache2-utils apache2.2-bin apache2-common
Nginx maintains their own package repositories for stable and mainline releases. These repositories can be used to get the latest updates of Nginx as and when available. Use the stable repository, - $ sudo add-apt-repository ppa:nginx/stable
.
Use the mainline repository - $ sudo add-apt-repository ppa:nginx/development
.
See also
- Common Nginx pitfalls at http://wiki.nginx.org/Pitfalls
- Nginx Quick start guide at http://wiki.nginx.org/QuickStart
How it works…
Here, we have installed the latest stable version of the Nginx server with PHP_FPM to support dynamic content scripted with PHP. The Ubuntu repository for version 16.04 contains the latest stable release of Nginx, So installing Nginx is as easy as a single command. If you are interested in more recent versions Nginx maintains their own package repository for mainline packages. You just need to add repository, the rest of the installation process is similar to a single apt-get install nginx
command.
Note
If you are running the Apache server on the same machine, you may want to change the default port Nginx runs on. You can find these settings under site configurations, located at /etc/nginx/sites-available
. Nginx creates default site configuration with the filename set to default
. Find the lines that start with listen
and change the port from its default, 80
, to any port number of your choice.
After installing Nginx, we need to configure it to support dynamic content. Here, we have selected PHP as a dynamic content processor. PHP is a popular scripting language and very commonly used with web servers for dynamic content processing. You can also add support for other modules by installing their respective processors. After installing PHP_FPM, we have configured Nginx to use PHP_FPM and pass all PHP requests to the FPM module on a socket connection.
We have used two location blocks in configuration. The first block search is for static content, such as files and directories, and then if nothing matches, the request is forwarded to index.php
, which is in turn forwarded to the FastCGI module for processing. This ensures that Nginx serves all static content without executing PHP, and only requests that are not static files and directories are passed to the FPM module.
The following is a brief description of the parameters used under FastCGI configuration:
- The parameter
try_files
configures Nginx to return404
pages, that is, the page not found error, for any requests that do not match website content. This is limited to static files. - With the parameter
fastcgi_param
, you can forward the script name and query string to the PHP FPM process. - One more optional parameter is
cgi.fix_pathinfo=0
, under the PHP configuration filephp.ini
. By default, PHP is set to search for the exact script filename and then search for the closest match if the exact name is not found. This may become a security risk by allowing an attacker to execute random scripts with simple guesswork for script names. We have disabled this by setting its value to0
.
Finally, after we restart PHP_FPM and Nginx, our server is ready to process static as well as dynamic content. All static content will be handled by Nginx itself, and requests for URLs that end with .php
will be forwarded to PHP_FPM for processing. Nginx may cache the processed result for future use.
There's more…
If you are running Ubuntu 12.10, you may need to install the following dependencies before adding the Nginx repository to the installation sources:
- Install
python-software-properties
andsoftware-properties-common
:$ sudo apt-get install python-software-properties $ sudo apt-get install software-properties-common
- You may want to remove your Apache installation completely. Use the following commands to remove Apache:
$ sudo service apache2 stop $ sudo apt-get remove --purge apache2 apache2-utils apache2.2-bin apache2-common
Nginx maintains their own package repositories for stable and mainline releases. These repositories can be used to get the latest updates of Nginx as and when available. Use the stable repository, - $ sudo add-apt-repository ppa:nginx/stable
.
Use the mainline repository - $ sudo add-apt-repository ppa:nginx/development
.
See also
- Common Nginx pitfalls at http://wiki.nginx.org/Pitfalls
- Nginx Quick start guide at http://wiki.nginx.org/QuickStart
There's more…
If you are running Ubuntu 12.10, you may need to install the following dependencies before adding the Nginx repository to the installation sources:
- Install
python-software-properties
andsoftware-properties-common
:$ sudo apt-get install python-software-properties $ sudo apt-get install software-properties-common
- You may want to remove your Apache installation completely. Use the following commands to remove Apache:
$ sudo service apache2 stop $ sudo apt-get remove --purge apache2 apache2-utils apache2.2-bin apache2-common
Nginx maintains their own package repositories for stable and mainline releases. These repositories can be used to get the latest updates of Nginx as and when available. Use the stable repository, - $ sudo add-apt-repository ppa:nginx/stable
.
Use the mainline repository - $ sudo add-apt-repository ppa:nginx/development
.
See also
- Common Nginx pitfalls at http://wiki.nginx.org/Pitfalls
- Nginx Quick start guide at http://wiki.nginx.org/QuickStart
See also
- Common Nginx pitfalls at http://wiki.nginx.org/Pitfalls
- Nginx Quick start guide at http://wiki.nginx.org/QuickStart
Setting Nginx as a reverse proxy
Apache and Nginx are two popular open source web servers. Both are very powerful, but at the same time have their own disadvantages as well. Apache is not good at handling high load environments with multiple concurrent requests and Nginx does not have inbuilt support for dynamic content processing. Many administrators overcome these problems by using both Apache and Nginx together. Nginx handles all incoming requests and only passes requests for dynamic content to Apache. Additionally, Nginx can provide a catching option which enables the server to respond to a request with results from a similar previous request. This helps to reduce the overall response time and minimize the load sent to Apache.
In this recipe, we will learn how to set up a web server configured with a reverse proxy. We will use Nginx as a reverse proxy, which will serve all static content and pass the requests for dynamic content to Apache.
Getting ready
You will need access to a root account or an account with sudo
privileges.
I assume that Apache is installed and running with a virtual host, example.com
.
How to do it…
Follow these steps to set Nginx as a reverse proxy:
- Install Nginx with the following command:
$ sudo apt-get update $ sudo apt-get install nginx
- Create a new site configuration under
/etc/nginx/sites-available
and add the following content to it:$ sudo nano /etc/nginx/sites-available/reverse_proxy server { listen 80; root /var/www/example.com; index index.php index.html index.htm; server_name example.com; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080; } location ~* \.(js|css|jpg|jpeg|png|svg|html|htm)$ { expires 30d; } location ~ /\.ht { deny all; } }
- Enable this new configuration by creating a symbolic link under
sites-enabled
:$ sudo ln -s /etc/nginx/sites-available/reverse_proxy \ /etc/nginx/sites-enabled/reverse_proxy
- Optionally, disable the default site by removing the symbolic link from
sites-enabled
:$ sudo rm /etc/nginx/sites-enabled/default
- Next, we need to change the Apache settings to listen on port
8080
. This will leave port80
to be used by Nginx:$ sudo nano /etc/apache2/ports.conf listen 127.0.0.1:8080
- Also change
NameVirtualHost
, if you are using it:NameVirtualHost 127.0.0.1:8080
- Change the virtual hosts settings to listen on port
8080
:$ sudo nano /etc/apache2/sites-available/example.com <VirtualHost 127.0.0.1:8080> ServerName example.com ServerAdmin webmaster@example.com DocumentRoot /var/www/example.com/public_html </VirtualHost>
- Save the changes and restart Apache for the changes to take effect:
$ sudo service apache2 restart
- Now, restart Nginx:
$ sudo service nginx restart
- Check for open ports with the following command:
$ sudo netstat -pltn
- Open your browser and point it to the IP address of your server. It should load the page configured under the Apache virtual host,
example.com
.
How it works…
With the proxy_pass
parameter, we have simply asked Nginx to pass all requests for PHP scripts to Apache on 127.0.0.1
on port 8080
. Then, we set Apache to listen on the loopback IP and port 8080
, which will receive requests forwarded by Nginx and process them with an internal PHP processor. All non-PHP content will still be served by Nginx from the /var/www
directory. The try_files $uri $uri/ /index.php;
option sets Nginx to search for the file with a specified name and then look for the folder; lastly, if both file and folder are not found, send the request to index.php
, which will then be processed by Apache.
Other options used with proxy pass ensures that Apache and PHP scripts receive the actual hostname and IP of the client and not of the Nginx server. You can use an additional module named libapache2-mod-rpaf
on Apache. This module provides an option to set a proxy IP address and rename the parameters sent by the proxy server. You can install the module with the following command:
$ sudo apt-get install libapache2-mod-rpaf
The configuration file for this module is available at /etc/apache2/mods-available/rpaf.conf
.
You can find various other proxy options and their respective explanations in the Nginx documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Finally, with Nginx set as a frontend, Apache will not have to interact directly with HTTP clients. You may want to disable some of the Apache modules that will not be used in this setup:
$ sudo a2dismod deflate cgi negotiation autoindex
As always, do not forget to reload Apache after any changes.
There's more…
Nginx can be set to cache the response received from the backend server and thereby minimize repeated requests on backend servers, as well as the response time. Nginx can cache the content in local files and serve new requests from the cache. The cache can be invalidated or even disabled based on the request received. To enable caching, add the following settings to the Nginx site configuration:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=backend-cache:8m max_size=50m; proxy_cache_key "$scheme$request_method$host$request_uri$args"; server { ## add other settings heres location / { proxy_pass 127.0.0.1:8080; proxy_cache backend-cache; proxy_cache_bypass $http_cache_control; add_header X-Proxy-Cache $upstream_cache_status; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; } }
You may need to create the proxy path directory /data/nginx/cache
and set the appropriate file permissions. Set the directory ownership to www-data
and restrict permissions to 700
. You can use any location for cache data and not necessarily /data/nginx/cache
.
This configuration sets the cache validity of 10 minutes, which is quite a lengthy period. This will work if you have static content that rarely changes. Instead, if you are serving dynamic content that is frequently updated, then you can take advantage of microcaching by setting the cache validity to a very small period of a few seconds. Add the following parameters to further improve your caching configuration for microcaching:
proxy_cache_lock on
: Queues additional requests while the cache is being updatedproxy_cache_use_stale updating
: Uses stale data while the cache is being updated
HAProxy and Varnish
HAProxy and Varnish are other popular options for the reverse proxy and the caching proxy, respectively. Both of them can offer improved performance when compared with Nginx. HAProxy can also be used as a Layer 4 and Layer 7 load balancer. We covered HAProxy in Chapter 2, Networking, in the Load Balancing with HAProxy recipe.
See also
- Nginx admin guide on reverse proxies at https://www.nginx.com/resources/admin-guide/reverse-proxy/
- Understanding Nginx proxying, load balancing, and caching at https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- Nginx proxy module documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Getting ready
You will need access to a root account or an account with sudo
privileges.
I assume that Apache is installed and running with a virtual host, example.com
.
How to do it…
Follow these steps to set Nginx as a reverse proxy:
- Install Nginx with the following command:
$ sudo apt-get update $ sudo apt-get install nginx
- Create a new site configuration under
/etc/nginx/sites-available
and add the following content to it:$ sudo nano /etc/nginx/sites-available/reverse_proxy server { listen 80; root /var/www/example.com; index index.php index.html index.htm; server_name example.com; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080; } location ~* \.(js|css|jpg|jpeg|png|svg|html|htm)$ { expires 30d; } location ~ /\.ht { deny all; } }
- Enable this new configuration by creating a symbolic link under
sites-enabled
:$ sudo ln -s /etc/nginx/sites-available/reverse_proxy \ /etc/nginx/sites-enabled/reverse_proxy
- Optionally, disable the default site by removing the symbolic link from
sites-enabled
:$ sudo rm /etc/nginx/sites-enabled/default
- Next, we need to change the Apache settings to listen on port
8080
. This will leave port80
to be used by Nginx:$ sudo nano /etc/apache2/ports.conf listen 127.0.0.1:8080
- Also change
NameVirtualHost
, if you are using it:NameVirtualHost 127.0.0.1:8080
- Change the virtual hosts settings to listen on port
8080
:$ sudo nano /etc/apache2/sites-available/example.com <VirtualHost 127.0.0.1:8080> ServerName example.com ServerAdmin webmaster@example.com DocumentRoot /var/www/example.com/public_html </VirtualHost>
- Save the changes and restart Apache for the changes to take effect:
$ sudo service apache2 restart
- Now, restart Nginx:
$ sudo service nginx restart
- Check for open ports with the following command:
$ sudo netstat -pltn
- Open your browser and point it to the IP address of your server. It should load the page configured under the Apache virtual host,
example.com
.
How it works…
With the proxy_pass
parameter, we have simply asked Nginx to pass all requests for PHP scripts to Apache on 127.0.0.1
on port 8080
. Then, we set Apache to listen on the loopback IP and port 8080
, which will receive requests forwarded by Nginx and process them with an internal PHP processor. All non-PHP content will still be served by Nginx from the /var/www
directory. The try_files $uri $uri/ /index.php;
option sets Nginx to search for the file with a specified name and then look for the folder; lastly, if both file and folder are not found, send the request to index.php
, which will then be processed by Apache.
Other options used with proxy pass ensures that Apache and PHP scripts receive the actual hostname and IP of the client and not of the Nginx server. You can use an additional module named libapache2-mod-rpaf
on Apache. This module provides an option to set a proxy IP address and rename the parameters sent by the proxy server. You can install the module with the following command:
$ sudo apt-get install libapache2-mod-rpaf
The configuration file for this module is available at /etc/apache2/mods-available/rpaf.conf
.
You can find various other proxy options and their respective explanations in the Nginx documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Finally, with Nginx set as a frontend, Apache will not have to interact directly with HTTP clients. You may want to disable some of the Apache modules that will not be used in this setup:
$ sudo a2dismod deflate cgi negotiation autoindex
As always, do not forget to reload Apache after any changes.
There's more…
Nginx can be set to cache the response received from the backend server and thereby minimize repeated requests on backend servers, as well as the response time. Nginx can cache the content in local files and serve new requests from the cache. The cache can be invalidated or even disabled based on the request received. To enable caching, add the following settings to the Nginx site configuration:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=backend-cache:8m max_size=50m; proxy_cache_key "$scheme$request_method$host$request_uri$args"; server { ## add other settings heres location / { proxy_pass 127.0.0.1:8080; proxy_cache backend-cache; proxy_cache_bypass $http_cache_control; add_header X-Proxy-Cache $upstream_cache_status; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; } }
You may need to create the proxy path directory /data/nginx/cache
and set the appropriate file permissions. Set the directory ownership to www-data
and restrict permissions to 700
. You can use any location for cache data and not necessarily /data/nginx/cache
.
This configuration sets the cache validity of 10 minutes, which is quite a lengthy period. This will work if you have static content that rarely changes. Instead, if you are serving dynamic content that is frequently updated, then you can take advantage of microcaching by setting the cache validity to a very small period of a few seconds. Add the following parameters to further improve your caching configuration for microcaching:
proxy_cache_lock on
: Queues additional requests while the cache is being updatedproxy_cache_use_stale updating
: Uses stale data while the cache is being updated
HAProxy and Varnish
HAProxy and Varnish are other popular options for the reverse proxy and the caching proxy, respectively. Both of them can offer improved performance when compared with Nginx. HAProxy can also be used as a Layer 4 and Layer 7 load balancer. We covered HAProxy in Chapter 2, Networking, in the Load Balancing with HAProxy recipe.
See also
- Nginx admin guide on reverse proxies at https://www.nginx.com/resources/admin-guide/reverse-proxy/
- Understanding Nginx proxying, load balancing, and caching at https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- Nginx proxy module documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
How to do it…
Follow these steps to set Nginx as a reverse proxy:
- Install Nginx with the following command:
$ sudo apt-get update $ sudo apt-get install nginx
- Create a new site configuration under
/etc/nginx/sites-available
and add the following content to it:$ sudo nano /etc/nginx/sites-available/reverse_proxy server { listen 80; root /var/www/example.com; index index.php index.html index.htm; server_name example.com; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080; } location ~* \.(js|css|jpg|jpeg|png|svg|html|htm)$ { expires 30d; } location ~ /\.ht { deny all; } }
- Enable this new configuration by creating a symbolic link under
sites-enabled
:$ sudo ln -s /etc/nginx/sites-available/reverse_proxy \ /etc/nginx/sites-enabled/reverse_proxy
- Optionally, disable the default site by removing the symbolic link from
sites-enabled
:$ sudo rm /etc/nginx/sites-enabled/default
- Next, we need to change the Apache settings to listen on port
8080
. This will leave port80
to be used by Nginx:$ sudo nano /etc/apache2/ports.conf listen 127.0.0.1:8080
- Also change
NameVirtualHost
, if you are using it:NameVirtualHost 127.0.0.1:8080
- Change the virtual hosts settings to listen on port
8080
:$ sudo nano /etc/apache2/sites-available/example.com <VirtualHost 127.0.0.1:8080> ServerName example.com ServerAdmin webmaster@example.com DocumentRoot /var/www/example.com/public_html </VirtualHost>
- Save the changes and restart Apache for the changes to take effect:
$ sudo service apache2 restart
- Now, restart Nginx:
$ sudo service nginx restart
- Check for open ports with the following command:
$ sudo netstat -pltn
- Open your browser and point it to the IP address of your server. It should load the page configured under the Apache virtual host,
example.com
.
How it works…
With the proxy_pass
parameter, we have simply asked Nginx to pass all requests for PHP scripts to Apache on 127.0.0.1
on port 8080
. Then, we set Apache to listen on the loopback IP and port 8080
, which will receive requests forwarded by Nginx and process them with an internal PHP processor. All non-PHP content will still be served by Nginx from the /var/www
directory. The try_files $uri $uri/ /index.php;
option sets Nginx to search for the file with a specified name and then look for the folder; lastly, if both file and folder are not found, send the request to index.php
, which will then be processed by Apache.
Other options used with proxy pass ensures that Apache and PHP scripts receive the actual hostname and IP of the client and not of the Nginx server. You can use an additional module named libapache2-mod-rpaf
on Apache. This module provides an option to set a proxy IP address and rename the parameters sent by the proxy server. You can install the module with the following command:
$ sudo apt-get install libapache2-mod-rpaf
The configuration file for this module is available at /etc/apache2/mods-available/rpaf.conf
.
You can find various other proxy options and their respective explanations in the Nginx documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Finally, with Nginx set as a frontend, Apache will not have to interact directly with HTTP clients. You may want to disable some of the Apache modules that will not be used in this setup:
$ sudo a2dismod deflate cgi negotiation autoindex
As always, do not forget to reload Apache after any changes.
There's more…
Nginx can be set to cache the response received from the backend server and thereby minimize repeated requests on backend servers, as well as the response time. Nginx can cache the content in local files and serve new requests from the cache. The cache can be invalidated or even disabled based on the request received. To enable caching, add the following settings to the Nginx site configuration:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=backend-cache:8m max_size=50m; proxy_cache_key "$scheme$request_method$host$request_uri$args"; server { ## add other settings heres location / { proxy_pass 127.0.0.1:8080; proxy_cache backend-cache; proxy_cache_bypass $http_cache_control; add_header X-Proxy-Cache $upstream_cache_status; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; } }
You may need to create the proxy path directory /data/nginx/cache
and set the appropriate file permissions. Set the directory ownership to www-data
and restrict permissions to 700
. You can use any location for cache data and not necessarily /data/nginx/cache
.
This configuration sets the cache validity of 10 minutes, which is quite a lengthy period. This will work if you have static content that rarely changes. Instead, if you are serving dynamic content that is frequently updated, then you can take advantage of microcaching by setting the cache validity to a very small period of a few seconds. Add the following parameters to further improve your caching configuration for microcaching:
proxy_cache_lock on
: Queues additional requests while the cache is being updatedproxy_cache_use_stale updating
: Uses stale data while the cache is being updated
HAProxy and Varnish
HAProxy and Varnish are other popular options for the reverse proxy and the caching proxy, respectively. Both of them can offer improved performance when compared with Nginx. HAProxy can also be used as a Layer 4 and Layer 7 load balancer. We covered HAProxy in Chapter 2, Networking, in the Load Balancing with HAProxy recipe.
See also
- Nginx admin guide on reverse proxies at https://www.nginx.com/resources/admin-guide/reverse-proxy/
- Understanding Nginx proxying, load balancing, and caching at https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- Nginx proxy module documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
How it works…
With the proxy_pass
parameter, we have simply asked Nginx to pass all requests for PHP scripts to Apache on 127.0.0.1
on port 8080
. Then, we set Apache to listen on the loopback IP and port 8080
, which will receive requests forwarded by Nginx and process them with an internal PHP processor. All non-PHP content will still be served by Nginx from the /var/www
directory. The try_files $uri $uri/ /index.php;
option sets Nginx to search for the file with a specified name and then look for the folder; lastly, if both file and folder are not found, send the request to index.php
, which will then be processed by Apache.
Other options used with proxy pass ensures that Apache and PHP scripts receive the actual hostname and IP of the client and not of the Nginx server. You can use an additional module named libapache2-mod-rpaf
on Apache. This module provides an option to set a proxy IP address and rename the parameters sent by the proxy server. You can install the module with the following command:
$ sudo apt-get install libapache2-mod-rpaf
The configuration file for this module is available at /etc/apache2/mods-available/rpaf.conf
.
You can find various other proxy options and their respective explanations in the Nginx documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Finally, with Nginx set as a frontend, Apache will not have to interact directly with HTTP clients. You may want to disable some of the Apache modules that will not be used in this setup:
$ sudo a2dismod deflate cgi negotiation autoindex
As always, do not forget to reload Apache after any changes.
There's more…
Nginx can be set to cache the response received from the backend server and thereby minimize repeated requests on backend servers, as well as the response time. Nginx can cache the content in local files and serve new requests from the cache. The cache can be invalidated or even disabled based on the request received. To enable caching, add the following settings to the Nginx site configuration:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=backend-cache:8m max_size=50m; proxy_cache_key "$scheme$request_method$host$request_uri$args"; server { ## add other settings heres location / { proxy_pass 127.0.0.1:8080; proxy_cache backend-cache; proxy_cache_bypass $http_cache_control; add_header X-Proxy-Cache $upstream_cache_status; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; } }
You may need to create the proxy path directory /data/nginx/cache
and set the appropriate file permissions. Set the directory ownership to www-data
and restrict permissions to 700
. You can use any location for cache data and not necessarily /data/nginx/cache
.
This configuration sets the cache validity of 10 minutes, which is quite a lengthy period. This will work if you have static content that rarely changes. Instead, if you are serving dynamic content that is frequently updated, then you can take advantage of microcaching by setting the cache validity to a very small period of a few seconds. Add the following parameters to further improve your caching configuration for microcaching:
proxy_cache_lock on
: Queues additional requests while the cache is being updatedproxy_cache_use_stale updating
: Uses stale data while the cache is being updated
HAProxy and Varnish
HAProxy and Varnish are other popular options for the reverse proxy and the caching proxy, respectively. Both of them can offer improved performance when compared with Nginx. HAProxy can also be used as a Layer 4 and Layer 7 load balancer. We covered HAProxy in Chapter 2, Networking, in the Load Balancing with HAProxy recipe.
See also
- Nginx admin guide on reverse proxies at https://www.nginx.com/resources/admin-guide/reverse-proxy/
- Understanding Nginx proxying, load balancing, and caching at https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- Nginx proxy module documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
There's more…
Nginx can be set to cache the response received from the backend server and thereby minimize repeated requests on backend servers, as well as the response time. Nginx can cache the content in local files and serve new requests from the cache. The cache can be invalidated or even disabled based on the request received. To enable caching, add the following settings to the Nginx site configuration:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=backend-cache:8m max_size=50m; proxy_cache_key "$scheme$request_method$host$request_uri$args"; server { ## add other settings heres location / { proxy_pass 127.0.0.1:8080; proxy_cache backend-cache; proxy_cache_bypass $http_cache_control; add_header X-Proxy-Cache $upstream_cache_status; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; } }
You may need to create the proxy path directory /data/nginx/cache
and set the appropriate file permissions. Set the directory ownership to www-data
and restrict permissions to 700
. You can use any location for cache data and not necessarily /data/nginx/cache
.
This configuration sets the cache validity of 10 minutes, which is quite a lengthy period. This will work if you have static content that rarely changes. Instead, if you are serving dynamic content that is frequently updated, then you can take advantage of microcaching by setting the cache validity to a very small period of a few seconds. Add the following parameters to further improve your caching configuration for microcaching:
proxy_cache_lock on
: Queues additional requests while the cache is being updatedproxy_cache_use_stale updating
: Uses stale data while the cache is being updated
HAProxy and Varnish
HAProxy and Varnish are other popular options for the reverse proxy and the caching proxy, respectively. Both of them can offer improved performance when compared with Nginx. HAProxy can also be used as a Layer 4 and Layer 7 load balancer. We covered HAProxy in Chapter 2, Networking, in the Load Balancing with HAProxy recipe.
See also
- Nginx admin guide on reverse proxies at https://www.nginx.com/resources/admin-guide/reverse-proxy/
- Understanding Nginx proxying, load balancing, and caching at https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- Nginx proxy module documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
HAProxy and Varnish
HAProxy and Varnish are other popular options for the reverse proxy and the caching proxy, respectively. Both of them can offer improved performance when compared with Nginx. HAProxy can also be used as a Layer 4 and Layer 7 load balancer. We covered HAProxy in Chapter 2, Networking, in the Load Balancing with HAProxy recipe.
- Nginx admin guide on reverse proxies at https://www.nginx.com/resources/admin-guide/reverse-proxy/
- Understanding Nginx proxying, load balancing, and caching at https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- Nginx proxy module documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
See also
- Nginx admin guide on reverse proxies at https://www.nginx.com/resources/admin-guide/reverse-proxy/
- Understanding Nginx proxying, load balancing, and caching at https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- Nginx proxy module documentation at http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Load balancing with Nginx
When an application becomes popular and the number of requests increases beyond the capacity of a single server, we need to scale horizontally. We can always increase the capacity (vertical scaling) of a server by adding more memory and processing power, but a single server cannot scale beyond a certain limit. While adding separate servers or replicas of the application server, we need a mechanism which directs the traffic between these replicas. The hardware or software tool used for this purpose is known as a load balancer. Load balancers work as transparent mechanisms between the application server and client by distributing the requests between available instances. This is a commonly used technique for optimizing resource utilization and ensuring fault tolerant applications.
Nginx can be configured to work as an efficient Layer 7 as well as Layer 4 load balancer. Layer 7 is application layer of HTTP traffic. With Layer 4 support, Nginx can be used to load balance database servers or even XMPP traffic. With version 1.9.0, Nginx has enabled support for Layer 4 load balancing in their open source offerings.
In this recipe, we will learn how to set up Nginx as a load balancer.
Getting ready
You will need access to a root account or an account with sudo
privileges.
You will need a minimum of three servers, as follows:
- An Nginx server, which will be set as a load balancer
- Two or more application servers with a similar code base set up on all
How to do it…
Follow these steps to set load balancing with Nginx:
- I assume that you already have Nginx installed. If not, you can refer to the Installing Nginx with PHP_FPM recipe of this chapter.
- Now, create a new configuration file under
/etc/nginx/sites-available
. Let's call itload_balancer
:$ sudo nano /etc/nginx/sites-available/load_balancer
- Add the following lines to this
load_balancer
file. This is the minimum configuration required to get started with load balancing:upstream backend { server srv1.example.com; server srv2.example.com; server 192.168.1.12:8080; # other servers if any } server { listen 80; location / { proxy_pass http://backend; } }
- Enable this configuration by creating a symlink to
load_balancer
undersites-enabled
:$ sudo ln -s /etc/nginx/sites-available/load_balancer /etc/nginx/sites-enabled/load_balancer
- You may want to disable all other sites. Simply remove the respective links under
sites-enabled
. - Check the configuration for syntax errors:
$ sudo nginx -t
- Now, reload Nginx for the changes to take effect:
$ sudo service nginx reload
- Yes, you are ready to use a load balancer. Open your favorite browser and point it to the IP of your Nginx server. You should see the contents of
example.com
or whatever domain you have used.
How it works…
We have created a very basic configuration for a load balancer. With this configuration, Nginx takes the traffic on port 80
and distributes it between srv1.example.com
and srv2.example.com
. With an upstream directive, we have defined a pool of servers that will actually process the requests. The upstream directive must be defined in a HTTP context. Once the upstream directive is defined, it will be available for all site configurations.
Note
All configuration files defined under sites-available
are combined in the main configuration file, /etc/nginx/nginx.conf
, under the HTTP
directive. This enables us to set other directives in site-specific
configurations without specifying the HTTP
block.
When defining servers under an upstream
directive, you can also use the IP address and port of the application server. This is an ideal configuration, especially when both the load balancer and the application servers are on the same private network, and this will help minimize the communication overhead between Nginx and backend servers.
Next, under the server
block, we have configured Nginx to proxy_pass
all requests to our backend
pool.
While setting backend servers, we have not explicitly specified any load balancing algorithm. Nginx provides various load balancing algorithms that define the server that will receive a particular request. By default, Nginx uses a round-robin algorithm and passes requests to each available server in sequential order. Other available options are as follows:
least_connection
: This passes the request to the host with the fewest active connections.least_time
: Nginx chooses the host with the lowest latency. This option is available with Nginx plus.ip_hash
: A hash of clients' IP addresses, and is used to determined the host to send the request to. This method guarantees that requests with the same IP address are served by the same host, unless the selected host is down.
Hash uses a user defined key to generate a hash value and then uses the hash to determine the processing host.
There's more…
Nginx provides various other load balancing features, such as weighted load balancing, active and passive health checks, backup servers, and session persistence. With the latest commits to the open source version, it now supports TCP load balancing as well. These settings can be updated at runtime with the help of HTTP APIs. The following are a few examples of different load balancing configurations:
- Set server weights:
upstream app-servers { server srv1.example.com weight 3; server srv2.example.com; }
- Health checkups and backup servers:
upstream app-servers { server srv1.example.com max_fails 3 fail_timeout 10; server srv2.example.com fail_timeout 50; 192.168.1.12:8080 backup; }
- Session persistence with cookies:
upstream app-servers { server srv1.example.com; server srv2.example.com; sticky cookie srv_id expires=1h domain=.example.com path=/; }
Check the Nginx load balancing guide for various other load balancing options and their respective details.
See also
- Nginx admin guide for load balancers at https://www.nginx.com/resources/admin-guide/load-balancer
Getting ready
You will need access to a root account or an account with sudo
privileges.
You will need a minimum of three servers, as follows:
- An Nginx server, which will be set as a load balancer
- Two or more application servers with a similar code base set up on all
How to do it…
Follow these steps to set load balancing with Nginx:
- I assume that you already have Nginx installed. If not, you can refer to the Installing Nginx with PHP_FPM recipe of this chapter.
- Now, create a new configuration file under
/etc/nginx/sites-available
. Let's call itload_balancer
:$ sudo nano /etc/nginx/sites-available/load_balancer
- Add the following lines to this
load_balancer
file. This is the minimum configuration required to get started with load balancing:upstream backend { server srv1.example.com; server srv2.example.com; server 192.168.1.12:8080; # other servers if any } server { listen 80; location / { proxy_pass http://backend; } }
- Enable this configuration by creating a symlink to
load_balancer
undersites-enabled
:$ sudo ln -s /etc/nginx/sites-available/load_balancer /etc/nginx/sites-enabled/load_balancer
- You may want to disable all other sites. Simply remove the respective links under
sites-enabled
. - Check the configuration for syntax errors:
$ sudo nginx -t
- Now, reload Nginx for the changes to take effect:
$ sudo service nginx reload
- Yes, you are ready to use a load balancer. Open your favorite browser and point it to the IP of your Nginx server. You should see the contents of
example.com
or whatever domain you have used.
How it works…
We have created a very basic configuration for a load balancer. With this configuration, Nginx takes the traffic on port 80
and distributes it between srv1.example.com
and srv2.example.com
. With an upstream directive, we have defined a pool of servers that will actually process the requests. The upstream directive must be defined in a HTTP context. Once the upstream directive is defined, it will be available for all site configurations.
Note
All configuration files defined under sites-available
are combined in the main configuration file, /etc/nginx/nginx.conf
, under the HTTP
directive. This enables us to set other directives in site-specific
configurations without specifying the HTTP
block.
When defining servers under an upstream
directive, you can also use the IP address and port of the application server. This is an ideal configuration, especially when both the load balancer and the application servers are on the same private network, and this will help minimize the communication overhead between Nginx and backend servers.
Next, under the server
block, we have configured Nginx to proxy_pass
all requests to our backend
pool.
While setting backend servers, we have not explicitly specified any load balancing algorithm. Nginx provides various load balancing algorithms that define the server that will receive a particular request. By default, Nginx uses a round-robin algorithm and passes requests to each available server in sequential order. Other available options are as follows:
least_connection
: This passes the request to the host with the fewest active connections.least_time
: Nginx chooses the host with the lowest latency. This option is available with Nginx plus.ip_hash
: A hash of clients' IP addresses, and is used to determined the host to send the request to. This method guarantees that requests with the same IP address are served by the same host, unless the selected host is down.
Hash uses a user defined key to generate a hash value and then uses the hash to determine the processing host.
There's more…
Nginx provides various other load balancing features, such as weighted load balancing, active and passive health checks, backup servers, and session persistence. With the latest commits to the open source version, it now supports TCP load balancing as well. These settings can be updated at runtime with the help of HTTP APIs. The following are a few examples of different load balancing configurations:
- Set server weights:
upstream app-servers { server srv1.example.com weight 3; server srv2.example.com; }
- Health checkups and backup servers:
upstream app-servers { server srv1.example.com max_fails 3 fail_timeout 10; server srv2.example.com fail_timeout 50; 192.168.1.12:8080 backup; }
- Session persistence with cookies:
upstream app-servers { server srv1.example.com; server srv2.example.com; sticky cookie srv_id expires=1h domain=.example.com path=/; }
Check the Nginx load balancing guide for various other load balancing options and their respective details.
See also
- Nginx admin guide for load balancers at https://www.nginx.com/resources/admin-guide/load-balancer
How to do it…
Follow these steps to set load balancing with Nginx:
- I assume that you already have Nginx installed. If not, you can refer to the Installing Nginx with PHP_FPM recipe of this chapter.
- Now, create a new configuration file under
/etc/nginx/sites-available
. Let's call itload_balancer
:$ sudo nano /etc/nginx/sites-available/load_balancer
- Add the following lines to this
load_balancer
file. This is the minimum configuration required to get started with load balancing:upstream backend { server srv1.example.com; server srv2.example.com; server 192.168.1.12:8080; # other servers if any } server { listen 80; location / { proxy_pass http://backend; } }
- Enable this configuration by creating a symlink to
load_balancer
undersites-enabled
:$ sudo ln -s /etc/nginx/sites-available/load_balancer /etc/nginx/sites-enabled/load_balancer
- You may want to disable all other sites. Simply remove the respective links under
sites-enabled
. - Check the configuration for syntax errors:
$ sudo nginx -t
- Now, reload Nginx for the changes to take effect:
$ sudo service nginx reload
- Yes, you are ready to use a load balancer. Open your favorite browser and point it to the IP of your Nginx server. You should see the contents of
example.com
or whatever domain you have used.
How it works…
We have created a very basic configuration for a load balancer. With this configuration, Nginx takes the traffic on port 80
and distributes it between srv1.example.com
and srv2.example.com
. With an upstream directive, we have defined a pool of servers that will actually process the requests. The upstream directive must be defined in a HTTP context. Once the upstream directive is defined, it will be available for all site configurations.
Note
All configuration files defined under sites-available
are combined in the main configuration file, /etc/nginx/nginx.conf
, under the HTTP
directive. This enables us to set other directives in site-specific
configurations without specifying the HTTP
block.
When defining servers under an upstream
directive, you can also use the IP address and port of the application server. This is an ideal configuration, especially when both the load balancer and the application servers are on the same private network, and this will help minimize the communication overhead between Nginx and backend servers.
Next, under the server
block, we have configured Nginx to proxy_pass
all requests to our backend
pool.
While setting backend servers, we have not explicitly specified any load balancing algorithm. Nginx provides various load balancing algorithms that define the server that will receive a particular request. By default, Nginx uses a round-robin algorithm and passes requests to each available server in sequential order. Other available options are as follows:
least_connection
: This passes the request to the host with the fewest active connections.least_time
: Nginx chooses the host with the lowest latency. This option is available with Nginx plus.ip_hash
: A hash of clients' IP addresses, and is used to determined the host to send the request to. This method guarantees that requests with the same IP address are served by the same host, unless the selected host is down.
Hash uses a user defined key to generate a hash value and then uses the hash to determine the processing host.
There's more…
Nginx provides various other load balancing features, such as weighted load balancing, active and passive health checks, backup servers, and session persistence. With the latest commits to the open source version, it now supports TCP load balancing as well. These settings can be updated at runtime with the help of HTTP APIs. The following are a few examples of different load balancing configurations:
- Set server weights:
upstream app-servers { server srv1.example.com weight 3; server srv2.example.com; }
- Health checkups and backup servers:
upstream app-servers { server srv1.example.com max_fails 3 fail_timeout 10; server srv2.example.com fail_timeout 50; 192.168.1.12:8080 backup; }
- Session persistence with cookies:
upstream app-servers { server srv1.example.com; server srv2.example.com; sticky cookie srv_id expires=1h domain=.example.com path=/; }
Check the Nginx load balancing guide for various other load balancing options and their respective details.
See also
- Nginx admin guide for load balancers at https://www.nginx.com/resources/admin-guide/load-balancer
How it works…
We have created a very basic configuration for a load balancer. With this configuration, Nginx takes the traffic on port 80
and distributes it between srv1.example.com
and srv2.example.com
. With an upstream directive, we have defined a pool of servers that will actually process the requests. The upstream directive must be defined in a HTTP context. Once the upstream directive is defined, it will be available for all site configurations.
Note
All configuration files defined under sites-available
are combined in the main configuration file, /etc/nginx/nginx.conf
, under the HTTP
directive. This enables us to set other directives in site-specific
configurations without specifying the HTTP
block.
When defining servers under an upstream
directive, you can also use the IP address and port of the application server. This is an ideal configuration, especially when both the load balancer and the application servers are on the same private network, and this will help minimize the communication overhead between Nginx and backend servers.
Next, under the server
block, we have configured Nginx to proxy_pass
all requests to our backend
pool.
While setting backend servers, we have not explicitly specified any load balancing algorithm. Nginx provides various load balancing algorithms that define the server that will receive a particular request. By default, Nginx uses a round-robin algorithm and passes requests to each available server in sequential order. Other available options are as follows:
least_connection
: This passes the request to the host with the fewest active connections.least_time
: Nginx chooses the host with the lowest latency. This option is available with Nginx plus.ip_hash
: A hash of clients' IP addresses, and is used to determined the host to send the request to. This method guarantees that requests with the same IP address are served by the same host, unless the selected host is down.
Hash uses a user defined key to generate a hash value and then uses the hash to determine the processing host.
There's more…
Nginx provides various other load balancing features, such as weighted load balancing, active and passive health checks, backup servers, and session persistence. With the latest commits to the open source version, it now supports TCP load balancing as well. These settings can be updated at runtime with the help of HTTP APIs. The following are a few examples of different load balancing configurations:
- Set server weights:
upstream app-servers { server srv1.example.com weight 3; server srv2.example.com; }
- Health checkups and backup servers:
upstream app-servers { server srv1.example.com max_fails 3 fail_timeout 10; server srv2.example.com fail_timeout 50; 192.168.1.12:8080 backup; }
- Session persistence with cookies:
upstream app-servers { server srv1.example.com; server srv2.example.com; sticky cookie srv_id expires=1h domain=.example.com path=/; }
Check the Nginx load balancing guide for various other load balancing options and their respective details.
See also
- Nginx admin guide for load balancers at https://www.nginx.com/resources/admin-guide/load-balancer
There's more…
Nginx provides various other load balancing features, such as weighted load balancing, active and passive health checks, backup servers, and session persistence. With the latest commits to the open source version, it now supports TCP load balancing as well. These settings can be updated at runtime with the help of HTTP APIs. The following are a few examples of different load balancing configurations:
- Set server weights:
upstream app-servers { server srv1.example.com weight 3; server srv2.example.com; }
- Health checkups and backup servers:
upstream app-servers { server srv1.example.com max_fails 3 fail_timeout 10; server srv2.example.com fail_timeout 50; 192.168.1.12:8080 backup; }
- Session persistence with cookies:
upstream app-servers { server srv1.example.com; server srv2.example.com; sticky cookie srv_id expires=1h domain=.example.com path=/; }
Check the Nginx load balancing guide for various other load balancing options and their respective details.
See also
- Nginx admin guide for load balancers at https://www.nginx.com/resources/admin-guide/load-balancer
See also
- Nginx admin guide for load balancers at https://www.nginx.com/resources/admin-guide/load-balancer
Setting HTTPs on Nginx
In this recipe, we will learn how to enable HTTPs communication on the Nginx server.
Getting ready
You will need access to a root account or an account with sudo
privileges.
How to do it…
Follow these steps to set HTTPs on Nginx:
- Obtain a certificate and the related keys from a certification authority or create a self-signed certificate. To create a self-signed certificate, refer to the Securing web traffic with HTTPS recipe in this chapter.
- Create a directory to hold all certificate and keys:
$ sudo mkdir -p /etc/nginx/ssl/example.com
- Move the certificate and keys to the preceding directory. Choose any secure method, such as SCP, SFTP, or any other.
- Create a virtual host entry or edit it if you already have one:
$ sudo nano /etc/nginx/sites-available/example.com
- Match your virtual host configuration with the following:
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name example.com www.example.com; root /var/www/example.com/public_html; index index.php index.html index.htm; ssl on; ssl_certificate /etc/nginx/ssl/example.com/server.crt; ssl_certificate_key /etc/nginx/ssl/example.com/server.key; # if you have received ca-certs.pem from Certification Authority #ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; keepalive_timeout 70; ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers on; ssl_protocols TLSv1.2 TLSv1.1 TLSv1; add_header Strict-Transport-Security "max-age=31536000"; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; } }
- Enable this configuration by creating a symbolic link to it under
sites-enabled
:$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
- Check the configuration for syntax errors:
$ sudo nginx -t
- Reload Nginx for the changes to take effect:
$ sudo service nginx reload
- Open your browser and access the site with domain or IP with HTTPS.
How it works…
When you know some basic configuration parameters, Nginx is quite simple to set up. Here, we have taken a few SSL settings from the default configuration file and added a simple redirection rule to redirect non-HTTPs traffic on port 80
to port 443
. The first server
block takes care of the redirection.
In addition to specifying the server certificate and keys, we have enabled session resumption by setting the cache to be shared across the Nginx process. We also have a timeout value of 5
minutes.
All other settings are common to the Nginx setup. We have allowed the virtual host to match with example.com
, as well as www.example.com
. We have set the index to search index.php
, followed by index.html
and others. With location
directives, we have set Nginx to search for files and directories before forwarding the request to a PHP processor. Note that if you create a self-signed certificate, you will notice your browser complaining about invalid certification authority.
See also
- Nginx HTTPs guide at http://nginx.org/en/docs/http/configuring_https_servers.html
Getting ready
You will need access to a root account or an account with sudo
privileges.
How to do it…
Follow these steps to set HTTPs on Nginx:
- Obtain a certificate and the related keys from a certification authority or create a self-signed certificate. To create a self-signed certificate, refer to the Securing web traffic with HTTPS recipe in this chapter.
- Create a directory to hold all certificate and keys:
$ sudo mkdir -p /etc/nginx/ssl/example.com
- Move the certificate and keys to the preceding directory. Choose any secure method, such as SCP, SFTP, or any other.
- Create a virtual host entry or edit it if you already have one:
$ sudo nano /etc/nginx/sites-available/example.com
- Match your virtual host configuration with the following:
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name example.com www.example.com; root /var/www/example.com/public_html; index index.php index.html index.htm; ssl on; ssl_certificate /etc/nginx/ssl/example.com/server.crt; ssl_certificate_key /etc/nginx/ssl/example.com/server.key; # if you have received ca-certs.pem from Certification Authority #ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; keepalive_timeout 70; ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers on; ssl_protocols TLSv1.2 TLSv1.1 TLSv1; add_header Strict-Transport-Security "max-age=31536000"; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; } }
- Enable this configuration by creating a symbolic link to it under
sites-enabled
:$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
- Check the configuration for syntax errors:
$ sudo nginx -t
- Reload Nginx for the changes to take effect:
$ sudo service nginx reload
- Open your browser and access the site with domain or IP with HTTPS.
How it works…
When you know some basic configuration parameters, Nginx is quite simple to set up. Here, we have taken a few SSL settings from the default configuration file and added a simple redirection rule to redirect non-HTTPs traffic on port 80
to port 443
. The first server
block takes care of the redirection.
In addition to specifying the server certificate and keys, we have enabled session resumption by setting the cache to be shared across the Nginx process. We also have a timeout value of 5
minutes.
All other settings are common to the Nginx setup. We have allowed the virtual host to match with example.com
, as well as www.example.com
. We have set the index to search index.php
, followed by index.html
and others. With location
directives, we have set Nginx to search for files and directories before forwarding the request to a PHP processor. Note that if you create a self-signed certificate, you will notice your browser complaining about invalid certification authority.
See also
- Nginx HTTPs guide at http://nginx.org/en/docs/http/configuring_https_servers.html
How to do it…
Follow these steps to set HTTPs on Nginx:
- Obtain a certificate and the related keys from a certification authority or create a self-signed certificate. To create a self-signed certificate, refer to the Securing web traffic with HTTPS recipe in this chapter.
- Create a directory to hold all certificate and keys:
$ sudo mkdir -p /etc/nginx/ssl/example.com
- Move the certificate and keys to the preceding directory. Choose any secure method, such as SCP, SFTP, or any other.
- Create a virtual host entry or edit it if you already have one:
$ sudo nano /etc/nginx/sites-available/example.com
- Match your virtual host configuration with the following:
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name example.com www.example.com; root /var/www/example.com/public_html; index index.php index.html index.htm; ssl on; ssl_certificate /etc/nginx/ssl/example.com/server.crt; ssl_certificate_key /etc/nginx/ssl/example.com/server.key; # if you have received ca-certs.pem from Certification Authority #ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; keepalive_timeout 70; ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers on; ssl_protocols TLSv1.2 TLSv1.1 TLSv1; add_header Strict-Transport-Security "max-age=31536000"; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; } }
- Enable this configuration by creating a symbolic link to it under
sites-enabled
:$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
- Check the configuration for syntax errors:
$ sudo nginx -t
- Reload Nginx for the changes to take effect:
$ sudo service nginx reload
- Open your browser and access the site with domain or IP with HTTPS.
How it works…
When you know some basic configuration parameters, Nginx is quite simple to set up. Here, we have taken a few SSL settings from the default configuration file and added a simple redirection rule to redirect non-HTTPs traffic on port 80
to port 443
. The first server
block takes care of the redirection.
In addition to specifying the server certificate and keys, we have enabled session resumption by setting the cache to be shared across the Nginx process. We also have a timeout value of 5
minutes.
All other settings are common to the Nginx setup. We have allowed the virtual host to match with example.com
, as well as www.example.com
. We have set the index to search index.php
, followed by index.html
and others. With location
directives, we have set Nginx to search for files and directories before forwarding the request to a PHP processor. Note that if you create a self-signed certificate, you will notice your browser complaining about invalid certification authority.
See also
- Nginx HTTPs guide at http://nginx.org/en/docs/http/configuring_https_servers.html
How it works…
When you know some basic configuration parameters, Nginx is quite simple to set up. Here, we have taken a few SSL settings from the default configuration file and added a simple redirection rule to redirect non-HTTPs traffic on port 80
to port 443
. The first server
block takes care of the redirection.
In addition to specifying the server certificate and keys, we have enabled session resumption by setting the cache to be shared across the Nginx process. We also have a timeout value of 5
minutes.
All other settings are common to the Nginx setup. We have allowed the virtual host to match with example.com
, as well as www.example.com
. We have set the index to search index.php
, followed by index.html
and others. With location
directives, we have set Nginx to search for files and directories before forwarding the request to a PHP processor. Note that if you create a self-signed certificate, you will notice your browser complaining about invalid certification authority.
See also
- Nginx HTTPs guide at http://nginx.org/en/docs/http/configuring_https_servers.html
See also
- Nginx HTTPs guide at http://nginx.org/en/docs/http/configuring_https_servers.html
Benchmarking and performance tuning of Apache
In this recipe, we will learn some performance tuning configurations that may help to squeeze out the last bit of performance from the available hardware. Before diving into performance tuning, we need to evaluate our servers and set a benchmark which can be used to measure improvements after any changes. We will be using a well known HTTP benchmarking tool, Apache Bench (ab). Various other benchmarking tools are available and each one has its own feature set. You can choose the one that best suits your needs.
Getting ready
You will need two systems: one with the web server software installed and another to run Apache Bench. You will need root access or access to an account with similar privileges.
You will also need to modify a few network parameters to handle a large network load. You will also need to set a higher open files limit, in limits.conf
, on both systems. Check the Tuning TCP Stack recipe in Chapter 2, Networking.
How to do it…
- Install the Apache Bench tool. This is available with the package
apache2-utils
:$ sudo apt-get install apache2-utils
- If you need to, you can check all the available options of the
ab
tool as follows:$ ab -h
- Now we are ready to generate network load. Execute the following command to start
ab
:$ ab -n 10000 -c 200 -t 2 -k "http://192.168.56.103/index.php"
It will take some time to complete the command depending on the parameters. You should see similar results to the following (partial) output:
Additionally, you may want to benchmark your server for CPU, memory, and IO performance. Check the Setting performance benchmarks recipe in Chapter 13, Performance Monitoring.
Now that we have a benchmark for server performance with stock installation, we can proceed with performance optimization. The following are some settings that are generally recommended for performance tuning:
- Apache related settings:
- Remove/disable any unused modules
- Enable
mod_gzip
/mod_deflate
- Turn
HostnameLookups
off - Use IP address in configuration files
- Use persistence connection by enabling
keepalive
, then setkeepalive timeout
- Limit the uses of
AllowOverride
or completely disable it withAllowOverride none
- Disable
ExtendedStatus
; this is useful while testing but not in production
- Nginx related settings:
- Set
worker_processes
to the count of your CPU cores or simply set it toauto
- Set the number of
worker_connections
to test multiple values to find the best match for your servers - Set the
keepalive_requests
andkeepalive_timeout
values; these reduce the overhead of creating new connections - Enable idle connections with upstream servers by setting the
keepalive
value - Enable log buffering with buffer and flush parameters to
access_log
; this will reduce IO requests while logging - Reduce the log-level - you can set it to warn the user or display an error while in production
- Set the
sendfile
directive to use an efficientsendfile()
call from the operating system - Enable caching and compression
- Make sure that you track the performance changes after each set of modifications; this way you will have exact knowledge regarding what worked and what not
- You should also tune the TCP stack. The details of the TCP stack settings are covered in Chapter 2, Networking.
- Set
There's more…
Various other tools are available for benchmarking different features of the web server. The following are some well known tools, as well as a few latest additions:
- Httperf: A web server benchmarking tool with some advanced options
- Perfkit: a cloud benchmark tool by Google
- Wrk: https://github.com/wg/wrk
- H2load: HTTP2 load testing tool at https://nghttp2.org/documentation/h2load-howto.html
See also
- Apache performance tuning guide at https://httpd.apache.org/docs/2.4/misc/perf-tuning.html
- Nginx performance tuning guide at https://www.nginx.com/blog/tuning-nginx/
Getting ready
You will need two systems: one with the web server software installed and another to run Apache Bench. You will need root access or access to an account with similar privileges.
You will also need to modify a few network parameters to handle a large network load. You will also need to set a higher open files limit, in limits.conf
, on both systems. Check the Tuning TCP Stack recipe in Chapter 2, Networking.
How to do it…
- Install the Apache Bench tool. This is available with the package
apache2-utils
:$ sudo apt-get install apache2-utils
- If you need to, you can check all the available options of the
ab
tool as follows:$ ab -h
- Now we are ready to generate network load. Execute the following command to start
ab
:$ ab -n 10000 -c 200 -t 2 -k "http://192.168.56.103/index.php"
It will take some time to complete the command depending on the parameters. You should see similar results to the following (partial) output:
Additionally, you may want to benchmark your server for CPU, memory, and IO performance. Check the Setting performance benchmarks recipe in Chapter 13, Performance Monitoring.
Now that we have a benchmark for server performance with stock installation, we can proceed with performance optimization. The following are some settings that are generally recommended for performance tuning:
- Apache related settings:
- Remove/disable any unused modules
- Enable
mod_gzip
/mod_deflate
- Turn
HostnameLookups
off - Use IP address in configuration files
- Use persistence connection by enabling
keepalive
, then setkeepalive timeout
- Limit the uses of
AllowOverride
or completely disable it withAllowOverride none
- Disable
ExtendedStatus
; this is useful while testing but not in production
- Nginx related settings:
- Set
worker_processes
to the count of your CPU cores or simply set it toauto
- Set the number of
worker_connections
to test multiple values to find the best match for your servers - Set the
keepalive_requests
andkeepalive_timeout
values; these reduce the overhead of creating new connections - Enable idle connections with upstream servers by setting the
keepalive
value - Enable log buffering with buffer and flush parameters to
access_log
; this will reduce IO requests while logging - Reduce the log-level - you can set it to warn the user or display an error while in production
- Set the
sendfile
directive to use an efficientsendfile()
call from the operating system - Enable caching and compression
- Make sure that you track the performance changes after each set of modifications; this way you will have exact knowledge regarding what worked and what not
- You should also tune the TCP stack. The details of the TCP stack settings are covered in Chapter 2, Networking.
- Set
There's more…
Various other tools are available for benchmarking different features of the web server. The following are some well known tools, as well as a few latest additions:
- Httperf: A web server benchmarking tool with some advanced options
- Perfkit: a cloud benchmark tool by Google
- Wrk: https://github.com/wg/wrk
- H2load: HTTP2 load testing tool at https://nghttp2.org/documentation/h2load-howto.html
See also
- Apache performance tuning guide at https://httpd.apache.org/docs/2.4/misc/perf-tuning.html
- Nginx performance tuning guide at https://www.nginx.com/blog/tuning-nginx/
How to do it…
- Install the Apache Bench tool. This is available with the package
apache2-utils
:$ sudo apt-get install apache2-utils
- If you need to, you can check all the available options of the
ab
tool as follows:$ ab -h
- Now we are ready to generate network load. Execute the following command to start
ab
:$ ab -n 10000 -c 200 -t 2 -k "http://192.168.56.103/index.php"
It will take some time to complete the command depending on the parameters. You should see similar results to the following (partial) output:
Additionally, you may want to benchmark your server for CPU, memory, and IO performance. Check the Setting performance benchmarks recipe in Chapter 13, Performance Monitoring.
Now that we have a benchmark for server performance with stock installation, we can proceed with performance optimization. The following are some settings that are generally recommended for performance tuning:
- Apache related settings:
- Remove/disable any unused modules
- Enable
mod_gzip
/mod_deflate
- Turn
HostnameLookups
off - Use IP address in configuration files
- Use persistence connection by enabling
keepalive
, then setkeepalive timeout
- Limit the uses of
AllowOverride
or completely disable it withAllowOverride none
- Disable
ExtendedStatus
; this is useful while testing but not in production
- Nginx related settings:
- Set
worker_processes
to the count of your CPU cores or simply set it toauto
- Set the number of
worker_connections
to test multiple values to find the best match for your servers - Set the
keepalive_requests
andkeepalive_timeout
values; these reduce the overhead of creating new connections - Enable idle connections with upstream servers by setting the
keepalive
value - Enable log buffering with buffer and flush parameters to
access_log
; this will reduce IO requests while logging - Reduce the log-level - you can set it to warn the user or display an error while in production
- Set the
sendfile
directive to use an efficientsendfile()
call from the operating system - Enable caching and compression
- Make sure that you track the performance changes after each set of modifications; this way you will have exact knowledge regarding what worked and what not
- You should also tune the TCP stack. The details of the TCP stack settings are covered in Chapter 2, Networking.
- Set
There's more…
Various other tools are available for benchmarking different features of the web server. The following are some well known tools, as well as a few latest additions:
- Httperf: A web server benchmarking tool with some advanced options
- Perfkit: a cloud benchmark tool by Google
- Wrk: https://github.com/wg/wrk
- H2load: HTTP2 load testing tool at https://nghttp2.org/documentation/h2load-howto.html
See also
- Apache performance tuning guide at https://httpd.apache.org/docs/2.4/misc/perf-tuning.html
- Nginx performance tuning guide at https://www.nginx.com/blog/tuning-nginx/
There's more…
Various other tools are available for benchmarking different features of the web server. The following are some well known tools, as well as a few latest additions:
- Httperf: A web server benchmarking tool with some advanced options
- Perfkit: a cloud benchmark tool by Google
- Wrk: https://github.com/wg/wrk
- H2load: HTTP2 load testing tool at https://nghttp2.org/documentation/h2load-howto.html
See also
- Apache performance tuning guide at https://httpd.apache.org/docs/2.4/misc/perf-tuning.html
- Nginx performance tuning guide at https://www.nginx.com/blog/tuning-nginx/
See also
- Apache performance tuning guide at https://httpd.apache.org/docs/2.4/misc/perf-tuning.html
- Nginx performance tuning guide at https://www.nginx.com/blog/tuning-nginx/
Securing the web server
In this recipe, we will learn some steps for securing web server installation.
Getting ready
You will need access to a root account or an account with sudo
privileges.
You may need to have a web server stack installed and running.
How to do it…
Follow these steps to secure the web server:
- Disable any unwanted modules. You can check all enabled modules with the following command:
$ a2query -m
- Disable modules with the following command:
$ sudo a2dismod status
- Hide the web server's identity. For Apache, edit
/etc/apache2/conf-available/security.conf
and set the following values:ServerSignature Off ServerTokens Prod
- You may want to check other options under
security.conf
. - Next, disable the Apache server status page:
$ sudo a2dismod status
- For Nginx, edit
/etc/nginx/nginx.conf
and uncomment the following line:# server_tokens off;
- In production environments, minimize the detail shown on error pages. You can enable the PHP Suhosin module and strict mode.
- Disable directory listing. On Apache, add the following line to the virtual host configuration:
<Directory /var/www/example.com> Options -Indexes </Directory>
- You can also disable directory listing globally by setting
Options -Indexes
in/etc/apache2/apache2.conf
. - Restrict access to the following directories:
<Directory /var/www/ > Order deny,allow # order of Deny and Allow Deny from all # Deny web root for all </Directory>
- Disable directory level settings and the use of
.htaccess
. This also helps improve performance:<Directory /> AllowOverride None # disable use of .htaccess </Directory>
- Disable the following symbolic links:
<Directory /> Options -FollowSymLinks </Directory>
- You can also install
mod_security
andmod_evasive
for added security.mod_security
acts as a firewall by monitoring traffic in real time, whereasmod_evasive
provides protection against Denial of Service attacks by monitoring request data and requester IP. - For Apache, you can install
mod_security
as a plugin module as follows:$ sudo apt-get install libapache2-modsecurity $ sudo a2enmod mod-security
- On Nginx, you need to first compile
mod_security
and then compile Nginx withmod_security
enabled. - Turn of server side includes and CGI scripts:
<Directory /> Options -ExecCGI -Includes </Directory>
- Limit request body, headers, request fields, and max concurrent connections; this will help against DOS attacks.
- Set the following variables on Apache:
TimeOut KeepAliveTimeout RequestReadTimeout LimitRequestBody LimitRequestFields LimitRequestFieldSize LimitRequestLine MaxRequestWorkers
- For Nginx, configure the following variables to control buffer overflow attacks:
client_body_buffer_size client_header_buffer_size client_max_body_size large_client_header_buffers
- Enable logging and periodically monitor logs for any new or unrecognized events:
<VirtualHost *:80> ErrorLog /var/log/httpd/example.com/error_log CustomLog /var/log/httpd/example.com/access_log combined </VirtualHost>
- Set up HTTPs and set it to use modern ciphers. You can also disable the use of SSL and enforce TLS.
How it works…
In this recipe, I have listed the various options available to make your web server more secure. It is not necessary to set all these settings. Disabling some of these settings, especially FollowSymlinks
and AllowOverride
, may not suit your requirements or your environment. You can always choose the settings that apply to your setup.
Various settings listed here are available in their respective configuration files, mostly under /etc/apache2
for the Apache web server and /etc/nginx
for the Nginx server.
Also, do not forget to reload or restart your server after setting these options.
You should also set your Ubuntu environment to be more secure. You can find more details on securing Ubuntu in Chapter 2, Networking.
See also
- Installing
mod_evasive
at https://www.linode.com/docs/websites/apache-tips-and-tricks/modevasive-on-apache - Apache security tips at http://httpd.apache.org/docs/2.4/misc/security_tips.html
- Setting up
mod_security
at https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_security-with-apache-on-debian-ubuntu
Getting ready
You will need access to a root account or an account with sudo
privileges.
You may need to have a web server stack installed and running.
How to do it…
Follow these steps to secure the web server:
- Disable any unwanted modules. You can check all enabled modules with the following command:
$ a2query -m
- Disable modules with the following command:
$ sudo a2dismod status
- Hide the web server's identity. For Apache, edit
/etc/apache2/conf-available/security.conf
and set the following values:ServerSignature Off ServerTokens Prod
- You may want to check other options under
security.conf
. - Next, disable the Apache server status page:
$ sudo a2dismod status
- For Nginx, edit
/etc/nginx/nginx.conf
and uncomment the following line:# server_tokens off;
- In production environments, minimize the detail shown on error pages. You can enable the PHP Suhosin module and strict mode.
- Disable directory listing. On Apache, add the following line to the virtual host configuration:
<Directory /var/www/example.com> Options -Indexes </Directory>
- You can also disable directory listing globally by setting
Options -Indexes
in/etc/apache2/apache2.conf
. - Restrict access to the following directories:
<Directory /var/www/ > Order deny,allow # order of Deny and Allow Deny from all # Deny web root for all </Directory>
- Disable directory level settings and the use of
.htaccess
. This also helps improve performance:<Directory /> AllowOverride None # disable use of .htaccess </Directory>
- Disable the following symbolic links:
<Directory /> Options -FollowSymLinks </Directory>
- You can also install
mod_security
andmod_evasive
for added security.mod_security
acts as a firewall by monitoring traffic in real time, whereasmod_evasive
provides protection against Denial of Service attacks by monitoring request data and requester IP. - For Apache, you can install
mod_security
as a plugin module as follows:$ sudo apt-get install libapache2-modsecurity $ sudo a2enmod mod-security
- On Nginx, you need to first compile
mod_security
and then compile Nginx withmod_security
enabled. - Turn of server side includes and CGI scripts:
<Directory /> Options -ExecCGI -Includes </Directory>
- Limit request body, headers, request fields, and max concurrent connections; this will help against DOS attacks.
- Set the following variables on Apache:
TimeOut KeepAliveTimeout RequestReadTimeout LimitRequestBody LimitRequestFields LimitRequestFieldSize LimitRequestLine MaxRequestWorkers
- For Nginx, configure the following variables to control buffer overflow attacks:
client_body_buffer_size client_header_buffer_size client_max_body_size large_client_header_buffers
- Enable logging and periodically monitor logs for any new or unrecognized events:
<VirtualHost *:80> ErrorLog /var/log/httpd/example.com/error_log CustomLog /var/log/httpd/example.com/access_log combined </VirtualHost>
- Set up HTTPs and set it to use modern ciphers. You can also disable the use of SSL and enforce TLS.
How it works…
In this recipe, I have listed the various options available to make your web server more secure. It is not necessary to set all these settings. Disabling some of these settings, especially FollowSymlinks
and AllowOverride
, may not suit your requirements or your environment. You can always choose the settings that apply to your setup.
Various settings listed here are available in their respective configuration files, mostly under /etc/apache2
for the Apache web server and /etc/nginx
for the Nginx server.
Also, do not forget to reload or restart your server after setting these options.
You should also set your Ubuntu environment to be more secure. You can find more details on securing Ubuntu in Chapter 2, Networking.
See also
- Installing
mod_evasive
at https://www.linode.com/docs/websites/apache-tips-and-tricks/modevasive-on-apache - Apache security tips at http://httpd.apache.org/docs/2.4/misc/security_tips.html
- Setting up
mod_security
at https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_security-with-apache-on-debian-ubuntu
How to do it…
Follow these steps to secure the web server:
- Disable any unwanted modules. You can check all enabled modules with the following command:
$ a2query -m
- Disable modules with the following command:
$ sudo a2dismod status
- Hide the web server's identity. For Apache, edit
/etc/apache2/conf-available/security.conf
and set the following values:ServerSignature Off ServerTokens Prod
- You may want to check other options under
security.conf
. - Next, disable the Apache server status page:
$ sudo a2dismod status
- For Nginx, edit
/etc/nginx/nginx.conf
and uncomment the following line:# server_tokens off;
- In production environments, minimize the detail shown on error pages. You can enable the PHP Suhosin module and strict mode.
- Disable directory listing. On Apache, add the following line to the virtual host configuration:
<Directory /var/www/example.com> Options -Indexes </Directory>
- You can also disable directory listing globally by setting
Options -Indexes
in/etc/apache2/apache2.conf
. - Restrict access to the following directories:
<Directory /var/www/ > Order deny,allow # order of Deny and Allow Deny from all # Deny web root for all </Directory>
- Disable directory level settings and the use of
.htaccess
. This also helps improve performance:<Directory /> AllowOverride None # disable use of .htaccess </Directory>
- Disable the following symbolic links:
<Directory /> Options -FollowSymLinks </Directory>
- You can also install
mod_security
andmod_evasive
for added security.mod_security
acts as a firewall by monitoring traffic in real time, whereasmod_evasive
provides protection against Denial of Service attacks by monitoring request data and requester IP. - For Apache, you can install
mod_security
as a plugin module as follows:$ sudo apt-get install libapache2-modsecurity $ sudo a2enmod mod-security
- On Nginx, you need to first compile
mod_security
and then compile Nginx withmod_security
enabled. - Turn of server side includes and CGI scripts:
<Directory /> Options -ExecCGI -Includes </Directory>
- Limit request body, headers, request fields, and max concurrent connections; this will help against DOS attacks.
- Set the following variables on Apache:
TimeOut KeepAliveTimeout RequestReadTimeout LimitRequestBody LimitRequestFields LimitRequestFieldSize LimitRequestLine MaxRequestWorkers
- For Nginx, configure the following variables to control buffer overflow attacks:
client_body_buffer_size client_header_buffer_size client_max_body_size large_client_header_buffers
- Enable logging and periodically monitor logs for any new or unrecognized events:
<VirtualHost *:80> ErrorLog /var/log/httpd/example.com/error_log CustomLog /var/log/httpd/example.com/access_log combined </VirtualHost>
- Set up HTTPs and set it to use modern ciphers. You can also disable the use of SSL and enforce TLS.
How it works…
In this recipe, I have listed the various options available to make your web server more secure. It is not necessary to set all these settings. Disabling some of these settings, especially FollowSymlinks
and AllowOverride
, may not suit your requirements or your environment. You can always choose the settings that apply to your setup.
Various settings listed here are available in their respective configuration files, mostly under /etc/apache2
for the Apache web server and /etc/nginx
for the Nginx server.
Also, do not forget to reload or restart your server after setting these options.
You should also set your Ubuntu environment to be more secure. You can find more details on securing Ubuntu in Chapter 2, Networking.
See also
- Installing
mod_evasive
at https://www.linode.com/docs/websites/apache-tips-and-tricks/modevasive-on-apache - Apache security tips at http://httpd.apache.org/docs/2.4/misc/security_tips.html
- Setting up
mod_security
at https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_security-with-apache-on-debian-ubuntu
How it works…
In this recipe, I have listed the various options available to make your web server more secure. It is not necessary to set all these settings. Disabling some of these settings, especially FollowSymlinks
and AllowOverride
, may not suit your requirements or your environment. You can always choose the settings that apply to your setup.
Various settings listed here are available in their respective configuration files, mostly under /etc/apache2
for the Apache web server and /etc/nginx
for the Nginx server.
Also, do not forget to reload or restart your server after setting these options.
You should also set your Ubuntu environment to be more secure. You can find more details on securing Ubuntu in Chapter 2, Networking.
See also
- Installing
mod_evasive
at https://www.linode.com/docs/websites/apache-tips-and-tricks/modevasive-on-apache - Apache security tips at http://httpd.apache.org/docs/2.4/misc/security_tips.html
- Setting up
mod_security
at https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_security-with-apache-on-debian-ubuntu
See also
- Installing
mod_evasive
at https://www.linode.com/docs/websites/apache-tips-and-tricks/modevasive-on-apache - Apache security tips at http://httpd.apache.org/docs/2.4/misc/security_tips.html
- Setting up
mod_security
at https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_security-with-apache-on-debian-ubuntu
Troubleshooting the web server
In this recipe, we will cover some common issues with Apache and Nginx and list the basic steps for overcoming those issues. The steps mentioned here are general troubleshooting methods; you may need to change them based on your setup and environment.
Getting ready
You may need root level access to your web server system.
How to do it…
Web server problems can be grouped in a few broad categories, such as a server not working, a particular domain or virtual host is not accessible, problems with a specific module configuration, and access denied errors. The following section lists each of these problems and their possible solutions.
Web server not accessible
- The first step is to check your local Internet connection. Try to access the server from another system from another network.
- Check if the DNS settings point to your web server.
- If your network is working properly, then try to ping to the server IP address.
- On the web server, check the firewall or any other tool that may block communication.
- Open a
telnet
connection to web server on port80
, or whatever port you have used for web server. If you see output similar to following screenshot, then your web server is working: - Make sure that the web server port is not being used by some other process:
$ sudo netstat -plutn
- If required, reload or restart the web server process:
$ sudo service apache2 reload/restart
- Check the Apache/Nginx logs listed under the
/var/log/
directory and view the entire file in a scrollable format:$ less /var/log/apache2/error.log
- See the continuous stream of logs as they are added to the log file:
$ tail -f /var/log/nginx/error.log
- You may want to run Apache with extended log levels. Find the variable
LogLevel
in/etc/apache2/apache2.conf
and set its value todebug
:$ sudo nano /etc/apache2/apache2.conf LogLevel debug
- Run Apache in debug single process mode:
$ sudo apache2ctl -X # debug mode single worker
Virtual host not accessible
- Make sure you have enabled virtual host configuration:
ubuntu@ubuntu:~$ a2query -s example.com (enabled by site administrator)
- Check the virtual host configuration for any syntax errors:
ubuntu@ubuntu:~$ sudo apache2ctl -t Syntax OK
- On Nginx, use the following command:
ubuntu@ubuntu:~$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
- Check the virtual host's details and other Apache configurations:
$ sudo apache2ctl -S
- Make sure your virtual host IP and port configuration matches the one defined with
NamedVirtualHost
. - Check
DocumentRoot
- does it point to proper files?- On Apache:
<VirtualHost *:80> DocumentRoot /var/www/html <VirtualHost>
- On Nginx:
server { root /usr/share/nginx/html; }
- On Apache:
- Crosscheck your
ServerName
andServerAlias
variables - do they match your domain name?- On Apache, these settings should look similar to this:
<VirtualHost *:80> ServerName example.com ServerAlias www.example.com </virtualHost>
- On Nginx, the
ServerName
is defined as this:server { server_name example.com www.example.com; }
- On Apache, these settings should look similar to this:
Access denied or forbidden errors
Check directory permissions for the virtual host root directory. Are they accessible to the web server? Check the web server user and group (commonly www-data
) have ready permissions. If required, you can set permissions with chown
and chmod
commands.
ubuntu@ubuntu:~$ ls -l /var/www/ drwxr-x--- 3 ubuntu www-data 4096 Aug 4 23:00 example.com drwxr-xr-x 2 ubuntu www-data 4096 Aug 2 23:04 public_html
Secondly, make sure that you have properly set directory permissions in the virtual host configuration. Are they restricting file access?
Use the following commands to set directory permissions in the virtual host configuration:
<Directory /var/www/> AllowOverride None Order Deny,Allow Deny from all </Directory>
Apache downloads .php files
Make sure that the mod_php
module is installed and enabled:
ubuntu@ubuntu:~$ ls -l /etc/apache2/mods-available | grep php -rw-r--r-- 1 root root 897 Jul 2 21:26 php7.0.conf -rw-r--r-- 1 root root 59 Jul 2 21:26 php7.0.load ubuntu@ubuntu:~$ a2query -m | grep php php7.0 (enabled by maintainer script)
Getting ready
You may need root level access to your web server system.
How to do it…
Web server problems can be grouped in a few broad categories, such as a server not working, a particular domain or virtual host is not accessible, problems with a specific module configuration, and access denied errors. The following section lists each of these problems and their possible solutions.
Web server not accessible
- The first step is to check your local Internet connection. Try to access the server from another system from another network.
- Check if the DNS settings point to your web server.
- If your network is working properly, then try to ping to the server IP address.
- On the web server, check the firewall or any other tool that may block communication.
- Open a
telnet
connection to web server on port80
, or whatever port you have used for web server. If you see output similar to following screenshot, then your web server is working: - Make sure that the web server port is not being used by some other process:
$ sudo netstat -plutn
- If required, reload or restart the web server process:
$ sudo service apache2 reload/restart
- Check the Apache/Nginx logs listed under the
/var/log/
directory and view the entire file in a scrollable format:$ less /var/log/apache2/error.log
- See the continuous stream of logs as they are added to the log file:
$ tail -f /var/log/nginx/error.log
- You may want to run Apache with extended log levels. Find the variable
LogLevel
in/etc/apache2/apache2.conf
and set its value todebug
:$ sudo nano /etc/apache2/apache2.conf LogLevel debug
- Run Apache in debug single process mode:
$ sudo apache2ctl -X # debug mode single worker
Virtual host not accessible
- Make sure you have enabled virtual host configuration:
ubuntu@ubuntu:~$ a2query -s example.com (enabled by site administrator)
- Check the virtual host configuration for any syntax errors:
ubuntu@ubuntu:~$ sudo apache2ctl -t Syntax OK
- On Nginx, use the following command:
ubuntu@ubuntu:~$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
- Check the virtual host's details and other Apache configurations:
$ sudo apache2ctl -S
- Make sure your virtual host IP and port configuration matches the one defined with
NamedVirtualHost
. - Check
DocumentRoot
- does it point to proper files?- On Apache:
<VirtualHost *:80> DocumentRoot /var/www/html <VirtualHost>
- On Nginx:
server { root /usr/share/nginx/html; }
- On Apache:
- Crosscheck your
ServerName
andServerAlias
variables - do they match your domain name?- On Apache, these settings should look similar to this:
<VirtualHost *:80> ServerName example.com ServerAlias www.example.com </virtualHost>
- On Nginx, the
ServerName
is defined as this:server { server_name example.com www.example.com; }
- On Apache, these settings should look similar to this:
Access denied or forbidden errors
Check directory permissions for the virtual host root directory. Are they accessible to the web server? Check the web server user and group (commonly www-data
) have ready permissions. If required, you can set permissions with chown
and chmod
commands.
ubuntu@ubuntu:~$ ls -l /var/www/ drwxr-x--- 3 ubuntu www-data 4096 Aug 4 23:00 example.com drwxr-xr-x 2 ubuntu www-data 4096 Aug 2 23:04 public_html
Secondly, make sure that you have properly set directory permissions in the virtual host configuration. Are they restricting file access?
Use the following commands to set directory permissions in the virtual host configuration:
<Directory /var/www/> AllowOverride None Order Deny,Allow Deny from all </Directory>
Apache downloads .php files
Make sure that the mod_php
module is installed and enabled:
ubuntu@ubuntu:~$ ls -l /etc/apache2/mods-available | grep php -rw-r--r-- 1 root root 897 Jul 2 21:26 php7.0.conf -rw-r--r-- 1 root root 59 Jul 2 21:26 php7.0.load ubuntu@ubuntu:~$ a2query -m | grep php php7.0 (enabled by maintainer script)
How to do it…
Web server problems can be grouped in a few broad categories, such as a server not working, a particular domain or virtual host is not accessible, problems with a specific module configuration, and access denied errors. The following section lists each of these problems and their possible solutions.
Web server not accessible
- The first step is to check your local Internet connection. Try to access the server from another system from another network.
- Check if the DNS settings point to your web server.
- If your network is working properly, then try to ping to the server IP address.
- On the web server, check the firewall or any other tool that may block communication.
- Open a
telnet
connection to web server on port80
, or whatever port you have used for web server. If you see output similar to following screenshot, then your web server is working: - Make sure that the web server port is not being used by some other process:
$ sudo netstat -plutn
- If required, reload or restart the web server process:
$ sudo service apache2 reload/restart
- Check the Apache/Nginx logs listed under the
/var/log/
directory and view the entire file in a scrollable format:$ less /var/log/apache2/error.log
- See the continuous stream of logs as they are added to the log file:
$ tail -f /var/log/nginx/error.log
- You may want to run Apache with extended log levels. Find the variable
LogLevel
in/etc/apache2/apache2.conf
and set its value todebug
:$ sudo nano /etc/apache2/apache2.conf LogLevel debug
- Run Apache in debug single process mode:
$ sudo apache2ctl -X # debug mode single worker
Virtual host not accessible
- Make sure you have enabled virtual host configuration:
ubuntu@ubuntu:~$ a2query -s example.com (enabled by site administrator)
- Check the virtual host configuration for any syntax errors:
ubuntu@ubuntu:~$ sudo apache2ctl -t Syntax OK
- On Nginx, use the following command:
ubuntu@ubuntu:~$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
- Check the virtual host's details and other Apache configurations:
$ sudo apache2ctl -S
- Make sure your virtual host IP and port configuration matches the one defined with
NamedVirtualHost
. - Check
DocumentRoot
- does it point to proper files?- On Apache:
<VirtualHost *:80> DocumentRoot /var/www/html <VirtualHost>
- On Nginx:
server { root /usr/share/nginx/html; }
- On Apache:
- Crosscheck your
ServerName
andServerAlias
variables - do they match your domain name?- On Apache, these settings should look similar to this:
<VirtualHost *:80> ServerName example.com ServerAlias www.example.com </virtualHost>
- On Nginx, the
ServerName
is defined as this:server { server_name example.com www.example.com; }
- On Apache, these settings should look similar to this:
Access denied or forbidden errors
Check directory permissions for the virtual host root directory. Are they accessible to the web server? Check the web server user and group (commonly www-data
) have ready permissions. If required, you can set permissions with chown
and chmod
commands.
ubuntu@ubuntu:~$ ls -l /var/www/ drwxr-x--- 3 ubuntu www-data 4096 Aug 4 23:00 example.com drwxr-xr-x 2 ubuntu www-data 4096 Aug 2 23:04 public_html
Secondly, make sure that you have properly set directory permissions in the virtual host configuration. Are they restricting file access?
Use the following commands to set directory permissions in the virtual host configuration:
<Directory /var/www/> AllowOverride None Order Deny,Allow Deny from all </Directory>
Apache downloads .php files
Make sure that the mod_php
module is installed and enabled:
ubuntu@ubuntu:~$ ls -l /etc/apache2/mods-available | grep php -rw-r--r-- 1 root root 897 Jul 2 21:26 php7.0.conf -rw-r--r-- 1 root root 59 Jul 2 21:26 php7.0.load ubuntu@ubuntu:~$ a2query -m | grep php php7.0 (enabled by maintainer script)
Web server not accessible
- The first step is to check your local Internet connection. Try to access the server from another system from another network.
- Check if the DNS settings point to your web server.
- If your network is working properly, then try to ping to the server IP address.
- On the web server, check the firewall or any other tool that may block communication.
- Open a
telnet
connection to web server on port80
, or whatever port you have used for web server. If you see output similar to following screenshot, then your web server is working: - Make sure that the web server port is not being used by some other process:
$ sudo netstat -plutn
- If required, reload or restart the web server process:
$ sudo service apache2 reload/restart
- Check the Apache/Nginx logs listed under the
/var/log/
directory and view the entire file in a scrollable format:$ less /var/log/apache2/error.log
- See the continuous stream of logs as they are added to the log file:
$ tail -f /var/log/nginx/error.log
- You may want to run Apache with extended log levels. Find the variable
LogLevel
in/etc/apache2/apache2.conf
and set its value todebug
:$ sudo nano /etc/apache2/apache2.conf LogLevel debug
- Run Apache in debug single process mode:
$ sudo apache2ctl -X # debug mode single worker
Virtual host not accessible
- Make sure you have enabled virtual host configuration:
ubuntu@ubuntu:~$ a2query -s example.com (enabled by site administrator)
- Check the virtual host configuration for any syntax errors:
ubuntu@ubuntu:~$ sudo apache2ctl -t Syntax OK
- On Nginx, use the following command:
ubuntu@ubuntu:~$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
- Check the virtual host's details and other Apache configurations:
$ sudo apache2ctl -S
- Make sure your virtual host IP and port configuration matches the one defined with
NamedVirtualHost
. - Check
DocumentRoot
- does it point to proper files?- On Apache:
<VirtualHost *:80> DocumentRoot /var/www/html <VirtualHost>
- On Nginx:
server { root /usr/share/nginx/html; }
- On Apache:
- Crosscheck your
ServerName
andServerAlias
variables - do they match your domain name?- On Apache, these settings should look similar to this:
<VirtualHost *:80> ServerName example.com ServerAlias www.example.com </virtualHost>
- On Nginx, the
ServerName
is defined as this:server { server_name example.com www.example.com; }
- On Apache, these settings should look similar to this:
Access denied or forbidden errors
Check directory permissions for the virtual host root directory. Are they accessible to the web server? Check the web server user and group (commonly www-data
) have ready permissions. If required, you can set permissions with chown
and chmod
commands.
ubuntu@ubuntu:~$ ls -l /var/www/ drwxr-x--- 3 ubuntu www-data 4096 Aug 4 23:00 example.com drwxr-xr-x 2 ubuntu www-data 4096 Aug 2 23:04 public_html
Secondly, make sure that you have properly set directory permissions in the virtual host configuration. Are they restricting file access?
Use the following commands to set directory permissions in the virtual host configuration:
<Directory /var/www/> AllowOverride None Order Deny,Allow Deny from all </Directory>
Apache downloads .php files
Make sure that the mod_php
module is installed and enabled:
ubuntu@ubuntu:~$ ls -l /etc/apache2/mods-available | grep php -rw-r--r-- 1 root root 897 Jul 2 21:26 php7.0.conf -rw-r--r-- 1 root root 59 Jul 2 21:26 php7.0.load ubuntu@ubuntu:~$ a2query -m | grep php php7.0 (enabled by maintainer script)
Virtual host not accessible
- Make sure you have enabled virtual host configuration:
ubuntu@ubuntu:~$ a2query -s example.com (enabled by site administrator)
- Check the virtual host configuration for any syntax errors:
ubuntu@ubuntu:~$ sudo apache2ctl -t Syntax OK
- On Nginx, use the following command:
ubuntu@ubuntu:~$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
- Check the virtual host's details and other Apache configurations:
$ sudo apache2ctl -S
- Make sure your virtual host IP and port configuration matches the one defined with
NamedVirtualHost
. - Check
DocumentRoot
- does it point to proper files?- On Apache:
<VirtualHost *:80> DocumentRoot /var/www/html <VirtualHost>
- On Nginx:
server { root /usr/share/nginx/html; }
- On Apache:
- Crosscheck your
ServerName
andServerAlias
variables - do they match your domain name?- On Apache, these settings should look similar to this:
<VirtualHost *:80> ServerName example.com ServerAlias www.example.com </virtualHost>
- On Nginx, the
ServerName
is defined as this:server { server_name example.com www.example.com; }
- On Apache, these settings should look similar to this:
Access denied or forbidden errors
Check directory permissions for the virtual host root directory. Are they accessible to the web server? Check the web server user and group (commonly www-data
) have ready permissions. If required, you can set permissions with chown
and chmod
commands.
ubuntu@ubuntu:~$ ls -l /var/www/ drwxr-x--- 3 ubuntu www-data 4096 Aug 4 23:00 example.com drwxr-xr-x 2 ubuntu www-data 4096 Aug 2 23:04 public_html
Secondly, make sure that you have properly set directory permissions in the virtual host configuration. Are they restricting file access?
Use the following commands to set directory permissions in the virtual host configuration:
<Directory /var/www/> AllowOverride None Order Deny,Allow Deny from all </Directory>
Apache downloads .php files
Make sure that the mod_php
module is installed and enabled:
ubuntu@ubuntu:~$ ls -l /etc/apache2/mods-available | grep php -rw-r--r-- 1 root root 897 Jul 2 21:26 php7.0.conf -rw-r--r-- 1 root root 59 Jul 2 21:26 php7.0.load ubuntu@ubuntu:~$ a2query -m | grep php php7.0 (enabled by maintainer script)
Access denied or forbidden errors
Check directory permissions for the virtual host root directory. Are they accessible to the web server? Check the web server user and group (commonly www-data
) have ready permissions. If required, you can set permissions with chown
and chmod
commands.
ubuntu@ubuntu:~$ ls -l /var/www/ drwxr-x--- 3 ubuntu www-data 4096 Aug 4 23:00 example.com drwxr-xr-x 2 ubuntu www-data 4096 Aug 2 23:04 public_html
Secondly, make sure that you have properly set directory permissions in the virtual host configuration. Are they restricting file access?
Use the following commands to set directory permissions in the virtual host configuration:
<Directory /var/www/> AllowOverride None Order Deny,Allow Deny from all </Directory>
Apache downloads .php files
Make sure that the mod_php
module is installed and enabled:
ubuntu@ubuntu:~$ ls -l /etc/apache2/mods-available | grep php -rw-r--r-- 1 root root 897 Jul 2 21:26 php7.0.conf -rw-r--r-- 1 root root 59 Jul 2 21:26 php7.0.load ubuntu@ubuntu:~$ a2query -m | grep php php7.0 (enabled by maintainer script)
Apache downloads .php files
Make sure that the mod_php
module is installed and enabled:
ubuntu@ubuntu:~$ ls -l /etc/apache2/mods-available | grep php -rw-r--r-- 1 root root 897 Jul 2 21:26 php7.0.conf -rw-r--r-- 1 root root 59 Jul 2 21:26 php7.0.load ubuntu@ubuntu:~$ a2query -m | grep php php7.0 (enabled by maintainer script)