Apache httpd VirtualHost Config

Introduction

The Apache HTTP Server is one of the world’s most popular servers. The term “Virtual Host” refers to running more than one web site on a single server. For example if you had two companies, one named “Company A” and the other “Company B”, and both had domain names “www.companyA.com” and “www.companyB.com” respectively; then you could use a single server to host the web sites for both companies using the VirtualHost configuration directive of the Apache httpd server. This blog describes setting up Virtual Hosts on Apache 2.2 on a CentOS server.

Enable Named Based Virtual Hosting

There are 2 ways you can enable Virtual Hosting, one is based on name resolution, the other is IP resolution. With IP resolution, you specify the “ServerName” directive as an IP address, and then incoming requests for the specified IP address are directed to that VirtualHost. With name resolution, the name is mapped to the “ServerName”.

Given the two companies example, the following changes should be made to the “httpd.conf” file. In my case, I’m using CentOS (Linux distro) which is similar to Red Hat Enterprise Linux. Configuration files for Debian or other Linux distros might be a bit different. To edit the httpd config file, enter vi /etc/httpd/conf/httpd.conf and make the following config changes:

...
NameVirtualHost *:80
...
<VirtualHost *:80>
   ServerAdmin myName@companyA.com
   DocumentRoot /var/www/html/A/web
   ServerName www.companyA.com
   <Directory />
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
   </Directory>
   ErrorLog logs/CompanyA-error_log
   CustomLog logs/CompanyA-access_log common
</VirtualHost>
<VirtualHost *:80>
   ServerAdmin myName@companyB.com
   DocumentRoot /var/www/html/B/web
   ServerName www.companyB.com
   <Directory />
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
   </Directory>
   ErrorLog logs/CompanyB-error_log
   CustomLog logs/CompanyB-access_log common
</VirtualHost>
...

In the above example, there are two separate DocumentRoots which are “A/web” and “B/web” respectively for the two companies. The directives within the Directory directives I show above are typical when using a Symfony project. You may use different directives depending on your requirements.

Once you make changes to your http.conf file, you will need to restart the Apache httpd server. This is done by issuing the command service httpd restart. Make sure you get the green OK indicators.

Testing the Config

So let’s presume you’ve made the above changes in a test environment and you want to verify that it’s going to work. On another machine (or the same machine), you will need to edit the hosts file and add in the name of both “companyA” and “companyB”. On a Linux machine you will need to edit the “/etc/hosts” file, and on Windows you need to edit “C:\Windows\system32\drivers\etc\hosts”. Open that file and make the following entries:

192.168.1.20 www.companyA.com
192.168.1.20 www.companyB.com

In the above example, “192.168.1.20” is the IP address of the Apache HTTP server and “www.companyA.com” is the name that we will resolve.

Now on your test machine, open a browser and type in: http://www.companyA.com/

This will send the request to the first Virtual Host. Then if in the same browser you enter in http://www.companyB.com this will resolve to the second Virtual host.

This should be enough to get you started with Virtual Hosts. Good luck!

CodeProject

Symfony & Eclipse IDE

Introduction

Eclipse is a free IDE used for software development. It’s not necessarily the most popular one, but it’s free and easy to use, plus it supports many languages and is open source and easy to customize. There is a lot of support available, so if you have problems it’s very easy to find out and fix the problems.

Symfony is a popular PHP web framework. I have personally evaluated it against a few other frameworks and find it to be one of the best and easiest to use out there.

This blog is about setting up your Eclipse IDE environment to work with Symfony.

Remote Systems Explorer

In my typical environment, Symfony is installed on a server (RHEL or CentOS) and my Eclipse IDE is on a remote client. I normally use Windows client, but the usage of Eclipse on Linux should be similar.

In Eclipse, select “Window > Show View > Other…”; then expand the “Remote Systems” folder and click on “Remote Systems”. Normally, I’ll move this window to the left pane of Eclipse. Then to add a SSH connection to your server that hosts Symfony, perform the following steps:

  1. Right-click in the Remote Systems pane and select “New Connection…”.
  2. Select “SSH Only” and click “Next >”.
  3. Enter in the “Host name”, which can be a DNS name or an IP address.
  4. Enter a “Connection name”. This can be whatever you like, and make it a suitable name to identify the host easily to you.
  5. Then at this point you can click the “Finish” button to complete adding the connection.

I suggest then creating a sftp filter for just the web folder, instead of you having to expand each of the folders every time you need to re-establish a connection to the remote server. In these steps I’ll presume you have Apache (httpd) installed, which has a specific path under the var folder.

  1. Right-click on “Sftp Files” and select “New > Filter…”.
  2. In the File Filter, enter the folder path as “/var/www/html” (path for Apache), then click “Next >”.
  3. Enter the “Filter name” as “WEB Root” (or whatever you prefer to call it), then click “Finish”.
  4. Then click on the “WEB Root” filter, and notice it prompts you to authenticate.
  5. Enter your username (User ID) and password on the remote host, and make sure the “Save password” button is checked.
  6. The filter expands to show you all directories under the WEB Root folder.

One point about the above connection and sftp filter: If you are not part of the root user group, or you are not the root user on the remote server, you will not be able to save files within the WEB Root folder using Eclipse. The easy workaround for this is to create a Development Environment described below.

Development Environment

As mentioned above, if you not the root user on the remote server, and for example you normally have to use “sudo” to save (or copy) files in the WEB Root folder, you will not be able to save files use Remote System Explorer in Eclipse. A good developer will always test their code in a Development Environment first to make sure everything works properly before deploying to the Production Environment, and this is what I will describe here.

Typically at Taft College, we use RHEL for our Production servers, and I will use CentOS as a Development Environment, since it is based on RHEL (although not quite similar). I setup CentOS in VirtualBox on my desktop, and I install everything as the root user. Then I setup Eclipse to connect as the root user, and I fully test my code on this test virtual machine. Once I’m ready to deploy my code, I use WinSCP to copy and transfer from my Development Environment to a sub folder in my HOME directory on the Production RHEL server. Then I use PuTTY to login to the Production server and use sudo to copy over the new or changed files to the Symfony sub directories. This whole process can be done quite quickly, and once you’ve done it a few times, it seems so easy to do.

 

Installing OCI8 on RHEL

Introduction

If you plan to use PHP to connect to an Oracle database, then you’ll want to install OCI8, which is a pecl extension for Oracle. You can also use PDO_OCI as mentioned in The Underground PHP and Oracle Manual, however Oracle does not contribute to PDO_OCI; if you look this up (for example on stackoverflow), you’ll find a number of users have had various problems getting PDO_OCI to work. So installing OCI8 is highly recommended!

Stop Apache

Run the following command to stop Apache:

sudo service httpd stop

Install Instant Client

Go to Oracle’s instant client download page, and select the link for you Linux architecture. You’ll have to click on the “Accept License Agreement” radio button, and you’ll have to download it somewhere and then transfer it to your Red hat Enterprise Linux Server (RHEL). RHEL distro doesn’t have a GUI, but just CLI, so the easiest way might be to transfer via scp. Download the latest version and both the “basic” and “devel” RPMs.

After copying the instant client RPMs to your home directory, run the following commands to install the RPMs:

sudo rpm -Uvh oracle-instantclient12.1-basic*
sudo rpm -Uvh oracle-instantclient12.1-devel*

You then need to set the ORACLE_HOME environment variable:

cd ~
vi .bashrc
ORACLE_HOME=/usr/lib/oracle/12.1/client64
export ORACLE_HOME
:wq!

Install Pear & Devel

In order to install OCI8, you first need to get pecl. Also pecl will need the development packages. Run the following commands:

sudo yum install php70u-pear php70u-devel

Install OCI8

At this point you should be ready to install OCI8:

pecl install oci8

Observe the output carefully, and make sure no errors are shown. If any errors are shown, you might have to review the above to make sure you haven’t missed anything, also you might want to read through The Underground PHP Oracle Manual.

Then when oci8 is installed, you now need to edit the PHP config file to add the compiled oci8.so file:

sudo vi /etc/php.ini
extension=oci8.so

Add “extension=oci8.so” at the very bottom of the file.

Verifying OCI8 is Installed

First restart Apache:

sudo service httpd restart

Then create a phpinfo() file in your Apache Document root folder, so you can access it via web browser. Then open in any browser, and then search for “oci8”. Make sure that it is enabled.

Apache & Symfony on RHEL

Introduction

For a Symfony (an mvc framework) based project that I’m currently working, I’ve had to install Apache (2.2) and Symfony 3 (and PHP 7) on Red Hat Enterprise Linux (RHEL). This blog outlines the steps I had to go through. This may be helpful for someone in the future.

Install/Configure Apache

Installing Apache on RHEL is as simple as running the following command:

yum install httpd

You need to prepend the above command with “sudo” if you don’t have admin privileges (which is typical).

Once installed, you’ll need to edit the config file:

vi /etc/httpd/conf/httpd.conf

If you notice when using vi that comments are shown with a incredibly hard to read dark blue color, then you’ll want to edit your “~/.vimrc” file to at least add “:color desert”. You can read more about it in my vim runtime control blog article.

Edit the httpd.conf file to at least make these changes:

ServerAdmin youremail@somedomain.com
...
# Use hostname if dns can be used, otherwise use IP address.
ServerName machine.host.name:80
#ServerName 192.168.0.10:80

That’s enough config until we install Symfony. Use “:wq!” to save the changes.

Install PHP 7.0

By default, RHEL would install PHP 5.x (probably PHP 5.3 at this time), and this may not actually work for most modern PHP frameworks. PHP 7.0 has about a 2 times performance increase over PHP 5.x and it’s becoming readily adopted. Thus it’s highly recommended to install PHP 7.0 these days.

To install PHP 7.0 on RHEL, you’ll need to enable the EPEL and IUS repositories. Use the following commands (run in your home directory) to first install EPEL:

wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
sudo rpm -Uvh epel-release-*.rpm

Then install the IUS repo:

wget https://centos6.iuscommunity.org/ius-release.rpm
sudo rpm -Uvh ius-release*.rpm

When you’re using yum to search for PHP 7.0 items to install, you need to search for “php70u”. This identifies PHP 7 verses PHP 5, which is simply “php”. Now to install PHP 7 and some of the requirements needed for Symfony (and other PHP frameworks), run the following command:

sudo yum install php70u-cli php70u-json php70u-ldap php70u-mbstring php70u-pdo php70u-mysqlnd php70u-xml php70u-process

After running the above command, run “php -v” to verify it shows PHP version 7.

Install MariaDB

You should probably now be using MariaDB instead of MySQL. If you’re not sure why MariaDB is preferable, read the MariaDB article on Wikipedia. On RHEL, you’ll need to add a repository file. First go to: https://downloads.mariadb.org/mariadb/repositories/ and follow the instructions by selecting a Linux Distro and selecting the latest stable version of MariaDB.

Copy the text generated and paste it into the repo file that you will create with vi:

sudo vi /etc/yum.repos.d/MariaDB.repo

Save the file in vi (“:wq!”), then run the following command:

yum install MariaDB-server MariaDB-client

After install, start the service:

sudo service mysql start

Verify it starts correctly. If it doesn’t, try to figure out why before proceeding. Then change the root password to something more secure (especially if this is going to be a production machine). Use the following command, where newpassword is what you want to change the new password to:

sudo mysqladmin -u root password newpassword

Install Composer

Composer is a dependency management software for PHP, and is needed for Symfony and many other PHP frameworks. Run the following commands:

cd ~
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '92102166af5abdb03f49ce52a40591073a7b859a86e8ff13338cf7db58a19f7844fbc0bb79b2773bf30791e935dbd938') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"composer

This creates a “composer.phar” in your home directory. You need to copy it to the “/usr/local/bin” folder to make it globally available:

sudo mv composer.phar /usr/local/bin/composer

Run the command “composer” to verify it works.

Install Symfony Binary

Now install the latest Symfony binary. Don’t use the Symfony available with yum, since that is typically really old. Change to your home directory and run the following:

cd ~
sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
sudo chmod a+x /usr/local/bin/symfony

Now, change to your Apache root web folder:

cd /var/www/html

Then let’s create a new Symfony project. This is a sample project that you can try out, and get to know how Symfony works:

symfony new testproject

Note: If for some reason “symfony” doesn’t run, you may need to run it from the absolute path or run with “sudo” or even using both. i.e. “sudo /usr/local/bin/symfony new testproject”.

The above creates the folder “testproject” under “/var/www/html”. Normally, you run the above commands as a system user not as the “apache” user, so you need to change the user:group of the folder and files. Do this recursively:

sudo chown -R apache:apache testproject

Also set some special permission on the var folder:

sudo setfacl -R -m u:"apache":rwX -m u:apache:rwX var
sudo setfacl -dR -m u:"apache":rwX -m u:apache:rwX var

Let’s go back to update the Apache config.

Apache Config

We need to update the DocumentRoot and Directory directives to the Symfony web folder we created above. The web folder will be under testproject, i.e. “testproject/web”. So make the following changes to the Apache config:

sudo vi /etc/httpd/conf/httpd.conf

DocumentRoot "/var/www/html/testproject/web"
...
<Directory "/var/www/html/testproject/web">
...
    Options Indexes FollowSymLinks MultiViews
...
    AllowOverride All
...
</Directory>

The above changes are needed also for mod_rewrite. Start the Apache server:

sudo service httpd start

Make sure it starts with “[OK]” normally, if not check the logs in “/var/log/httpd/”.

Verify Symfony Requirements

There were a large number of configuration items just performed, so it’s probably a good idea to check the Symfony requirements to verify everything you’ve installed is correct and no further changes are needed. There is a “symfony_requirements” script in the bin folder to achieve this specific purpose. From the “/var/www/html/testproject” folder run:

php bin/symfony_requirements

You should get a green [OK] if everything is fine, otherwise it prints out anything that you need to address.

RHEL SELINUX & IPTABLES

Most likely if you installed Apache fresh, then SELINX won’t be configured for the web folders, and quite possibly iptables are configured. Run the command “sudo iptables -S” to check the iptables configuration. If there is anything other than ACCEPT, and nothing specific to port 80, then most likely this will block your web port. Run “sudo iptables -F” to flush the tables.

The easiest way to quickly disable SELINUX is using “setenforce permissive”.

I’m not giving guidelines here on how to setup iptables or SELINUX, as for a production environment, a lot of thought should be put into correct configuration, and I only intend to show how to use Symfony here.

Checking Everything

Presuming your Apache server is running (run a “sudo service restart” if it is not), you should be able to use wget to check if everything is working “locally”:

cd ~
wget 192.168.0.10

This should copy an “index.html” to your home folder. Use “vi index.html” to check the contents. If you get errors, you need to investigate the problems.

After checking locally, use another machine and enter the hostname or IP address in the URL field of a browser. You should get a Symfony Welcome! message.

 

Apache2 config Broken IE Implementation

I notice in Apache/2.4.7 on Ubuntu in the default SSL config file, the following:


# SSL Protocol Adjustments:
# The safe and default but still SSL/TLS standard compliant shutdown
# approach is that mod_ssl sends the close notify alert but doesn't wait for
# the close notify alert from client. When you need a different shutdown
# approach you can use one of the following variables:
# o ssl-unclean-shutdown:
# This forces an unclean shutdown when the connection is closed, i.e. no
# SSL close notify alert is send or allowed to received. This violates
# the SSL/TLS standard but is needed for some brain-dead browsers. Use
# this when you receive I/O errors because of the standard approach where
# mod_ssl sends the close notify alert.
# o ssl-accurate-shutdown:
# This forces an accurate shutdown when the connection is closed, i.e. a
# SSL close notify alert is send and mod_ssl waits for the close notify
# alert of the client. This is 100% SSL/TLS standard compliant, but in
# practice often causes hanging connections with brain-dead browsers. Use
# this only for browsers where you know that their SSL implementation
# works correctly.
# Notice: Most problems of broken clients are also related to the HTTP
# keep-alive facility, so you usually additionally want to disable
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
# "force-response-1.0" for this.
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown


Notice they refer to Internet Explorer as a “brain-dead browser” and that it has broken HTTP/1.1 implementation. Of course this depends on which version of Internet Exploder that you are using!

Good luck, and make sure you uncheck SSLv3.0 and disable TLSv1.0 for your own protection (enable TLSv1.1/TLSv1.2).