Tutorials

Configure Apache as a Reverse Proxy Using mod_proxy on Ubuntu

Table of Contents

Introduction

Apache is the most popular HTTP server which comes with access to a very wide range of powerful extensions. Apache can be configured as a proxy to redirect HTTP traffic to other servers. When Apache is configured as a reverse proxy, it receives HTTP requests from the internet, and forwards them to another server to process the request. This server, often referred to as a backend server, sends a response through the proxy back to the client.

A proxy server is one which forwards client requests to another server instead of fulfilling them itself. There are two main types:

  1. A forward proxy forwards to an arbitrary destination, typically on behalf of a particular set of clients.
  2. A reverse proxy forwards to a fixed destination, typically on behalf of arbitrary clients.

In this tutorial, we will learn how to set up Apache on Ubuntu-14.04 server and use it as a reverse-proxy to welcome incoming connections and redirect them to another server. For this purpose, we will use mod_proxy extension and other related Apache modules.

Requirements

  • A server running Ubuntu-14.04
  • A static IP Address for your server

Install Apache

Let's start making sure that your Ubuntu-14.04 server is fully up to date. You can update your server by running the following command:

sudo apt-get update -y
sudo apt-get upgrade -y

With the server up to date, you can continue the process and install Apache on your server.

You can install Apache by simply running the following command:

sudo apt-get install apache2 -y

Once Apache has been installed, start the Apache service and configure it to start automatically when the server boots:

sudo /etc/init.d/apache2 start
sudo update-rc.d apache2 defaults

Install mod_proxy and other modules

mod_proxy is the Apache module that implements a proxy/gateway for Apache HTTP Server, supporting a number of popular protocols as well as several different load balancing algorithms. It is used to manage connections and redirect them.

You can install mod_proxy and its dependencies using the following command:

sudo apt-get install libapache2-mod-proxy-html libxml2-dev -y

Let's continue with installing the build-essential package for application building. This package can be used to install certain things from source.

Run the following command to install build-essential package:

sudo apt-get install -y build-essential

Configure Apache for Proxy

Before configuring Apache, you will need to enable some necessary modules.

Run the following command to get a list of available Apache modules:

sudo a2enmod

You should see the list of all the modules:

Your choices are: access_compat actions alias allowmethods asis auth_basic auth_digest auth_form authn_anon authn_core authn_dbd authn_dbm authn_file authn_socache authnz_ldap authz_core authz_dbd authz_dbm authz_groupfile authz_host authz_owner authz_user autoindex buffer cache cache_disk cache_socache cgi cgid charset_lite data dav dav_fs dav_lock dbd deflate dialup dir dump_io echo env expires ext_filter file_cache filter headers heartbeat heartmonitor include info lbmethod_bybusyness lbmethod_byrequests lbmethod_bytraffic lbmethod_heartbeat ldap log_debug log_forensic lua macro mime mime_magic mpm_event mpm_prefork mpm_worker negotiation php5 proxy proxy_ajp proxy_balancer proxy_connect proxy_express proxy_fcgi proxy_fdpass proxy_ftp proxy_html proxy_http proxy_scgi proxy_wstunnel ratelimit reflector remoteip reqtimeout request rewrite sed session session_cookie session_crypto session_dbd setenvif slotmem_plain slotmem_shm socache_dbm socache_memcache socache_shmcb speling ssl status substitute suexec unique_id userdir usertrack vhost_alias xml2enc
Which module(s) do you want to enable (wildcards ok)?

Next, you can run the following commands to enable the modules one by one:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_ajp
sudo a2enmod rewrite
sudo a2enmod deflate
sudo a2enmod headers
sudo a2enmod proxy_balancer
sudo a2enmod proxy_connect
sudo a2enmod proxy_html

Next, you will need to disable Apache default configuration file 000-default.conf and create a new virtual host file inside the /etc/apache2/sites-available directory to set up "proxying" functionality.

To disable the 000-default file, run:

sudo a2dissite 000-default

Then, create a new virtual host file:

sudo nano /etc/apache2/sites-available/proxy-host

Add the following lines to suit your needs:

<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
  ProxyPreserveHost On
  # Servers to proxy the connection, or
  # List of application servers Usage
  ProxyPass / http://server-ip-address:8080/
  ProxyPassReverse / http://server-ip-address:8080/
  ServerName localhost
</VirtualHost>

Save and close the file.

Enable new virtual host file:

sudo a2ensite proxy-host

You will also need to tell Apache to listen on port 8080.

You can do this by editing the ports.conf file:

sudo nano /etc/apache2/ports.conf

Add the following line:

Listen 8080

Save the file and restart Apache.

sudo /etc/init.d/apache2 restart

Proxying should be working for you now. When you access the URL http://server-ip-address:80 in a browser, it will show the application which is running on http://server-ip-address:8080. The browser is not aware that the application is running on port 8080.

Enable SSL Reverse-Proxy Support

If you want to enable SSL support to your Reverse-Proxy connections, then you will need to enable the SSL module first.

To enable this module, run:

sudo a2enmod ssl

After you have enabled SSL, you’ll have to restart the Apache service for the change to be recognized.

sudo /etc/init.d/apache2 restart

Next, you will need to generate self-signed certificate. For testing purposes, you will need to generate a private key (ca.key) with 2048 bit encryption.

To do this, run:

sudo openssl genrsa -out ca.key 2048

Then generate a certificate signing request (ca.csr) using the following command:

sudo openssl req -nodes -new -key ca.key -out ca.csr

You should see the following output:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:GUJARAT
Locality Name (eg, city) []:AHMEDABAD
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ITC
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:HITESH JETHVA
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Lastly, generate a self-signed certificate (ca.crt) of X509 type valid for 365 keys.

sudo openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt

Create a directory to place the certificate files we have created.

sudo mkdir /etc/apache2/ssl

Next, copy all certificate files to the /etc/apache2/ssl directory.

sudo cp ca.crt ca.key ca.csr /etc/apache2/ssl/

Now all the certificates are ready. The next thing to do is to set up the Apache to display the new certificate.

For this, you need to create new virtual host file proxy-ssl-host.conf

nano /etc/apache2/sites-available/proxy-ssl-host.conf

Add the following content:

<VirtualHost *:443>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine On
        # Set the path to SSL certificate
        # Usage: SSLCertificateFile /path/to/cert.pem
        SSLCertificateFile /etc/apache2/ssl/ca.crt
        SSLCertificateKeyFile /etc/apache2/ssl/ca.key
        ProxyPreserveHost On
        ProxyPass /var/www/ http://server-ip-address:8080/
        ProxyPassReverse /var/www/ http://server-ip-address:8080/
        ServerName localhost
</VirtualHost>

Save and close the file.

Enable new virtual host file:

sudo a2ensite proxy-ssl-host.conf

Now, restart the Apache service to make this change take effect:

sudo /etc/init.d/apache2 restart

That’s it. You can now access your server using the URL https://server-ip-address.

Enjoy!......

 
  • This is the best description I have seen for configuring Apache as a reverse proxy on Ubuntu.

    One thing I am having a problem with is that I have been unable to remove or change a configuration.

    I have two instances on Amazon ec2. One was running Ubuntu 16.04 (LTS) while the other was running Amazon Linux AMI. They were on the same virtual private cloud and I had LAMP installed on both. I followed the directions, outlined above, to enable app1 to point to the Amazon Linux AMI instance which had a private IP address of 10.0.1.27. Specifically, I edited /etc/apache2/sites-available/proxy-host.conf to consist of the following.

    <virtualhost *:80=""> ServerAdmin webmaster@localhost DocumentRoot /var/www/html/ ErrorLog ${APACHE_LOG_DIR}/error.log <br/> CustomLog ${APACHE_LOG_DIR}/access.log combined ProxyPreserveHost On # Servers to proxy the connection, or # List of application servers Usage ProxyPass /app1/ http://10.0.1.27:8080/ ProxyPass / http://10.0.1.110:8080/ ServerName localhost </virtualhost>

    Then, after I restart apache I could simply enter the following code, on a web page of the current server

  • Whatever
  • and the web page Whatever.php, on the server with the private IP 10.0.1.27, was displayed on my browser when I clicked the Whatever button.

    However, I terminated the instance, with the private IP address 10.0.1.27, and replaced it with a Ubuntu 16.04 (LTS) server with IP address 10.0.1.7. I therefore changed the /etc/apache2/sites-available/proxy-host.conf to

    <virtualhost *:80=""> ServerAdmin webmaster@localhost DocumentRoot /var/www/html/ ErrorLog ${APACHE_LOG_DIR}/error.log <br/> CustomLog ${APACHE_LOG_DIR}/access.log combined ProxyPreserveHost On # Servers to proxy the connection, or # List of application servers Usage ProxyPass /app1/ http://10.0.1.7:8080/ ProxyPass / http://10.0.1.110:8080/ ServerName localhost </virtualhost>

    I then entered the following

    sudo a2dissite proxy-host.conf sudo a2ensite proxy-host.conf sudo service apache2 reload sudo service apache2 restart

    However, when I click on the "Whatever" button, I get the 503 error.

    Service Unavailable

    The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.

    Apache/2.4.18 (Ubuntu) Server at 52.207.143.84 Port 80 It appears that it is still trying to access the instance with the private IP address 10.0.1.27.

    How do I make app1 point to the instance, with the private IP address 10.0.1.7, instead?

  • Thanks a lot,

    you should change for sudo nano /etc/apache2/sites-available/proxy-host.conf

  • Thank you for your reply. I changed /etc/apache2/sites-available/proxy-host.conf to

    <virtualhost *:80=""> 
          ServerAdmin webmaster@localhost
         DocumentRoot /var/www/html/ 
         ErrorLog ${APACHE_LOG_DIR}/error.log 
         CustomLog ${APACHE_LOG_DIR}/access.log combined
         ProxyPreserveHost On 
        # Servers to proxy the connection, or 
        # List of application servers Usage
         ProxyPass /app1/ http://10.0.1.7:8080/
         ProxyPass / http://10.0.1.110:8080/
         ServerName localhost 
     </virtualhost>
    

    I then entered the following

    sudo a2dissite proxy-host.conf 
    sudo a2ensite proxy-host.conf 
    sudo service apache2 reload 
    sudo service apache2 restart
    

    However, when I click on the "Whatever" button, I get the 503 error.

    Service Unavailable
    
    The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.
    
    Apache/2.4.18 (Ubuntu) Server at 52.207.143.84 Port 80
    

    It appears that it is still trying to access the instance with the private IP address 10.0.1.27.

  • The problem was solved by replacing 8080 with 80. Additionally /etc/apache2/sites-available/proxy-host.conf could be much simpler. To wit

    <virtualhost *:80> 
          ServerAdmin webmaster@localhost
         DocumentRoot /var/www/html/ 
         ErrorLog ${APACHE_LOG_DIR}/error.log 
         CustomLog ${APACHE_LOG_DIR}/access.log combined
         ProxyPreserveHost On 
        # Servers to proxy the connection, or 
        # List of application servers Usage
         ProxyPass /app1/ http://10.0.1.7:8080/
    </virtualhost>
    
  • Hey, I am on my centos 6 vps I think disabling Apache default is not a good idea moreover I have website already running but I just need the reverse proxy for my 3 applications only not all of them. So what should I do? and it is not allowed to add virtual host directly...https://stackoverflow.com/questions/6900306/how-do-i-add-virtual-hosts-the-right-way-while-running-whm

  • hey, i configured apache proxy server on ubuntu but still my apache reverse proxy server showing its default page.. my proxy server not redirecting to main web server. what will be the problem.

  • Log In, Add a Comment