Custom website #1

This is an architecture I designed for a corporate web site. The application was written by a 3rd party and used php, symfony and MySQL. The application consisted of 2 parts, a public webserver part and a content-management part. Both applications were contained within the same document root. Security required access of the content-management system (cms) to be restricted to the internal network. The public webservers were to be placed in the DMZ.

The cms required read-write access to the MySQL database. The public web servers only required read-only access to the database. An existing MySQL database was to be used, which was contained inside the internal network.

I needed to come up with an architecture that provided:

    • High Availability. The existing MySQL servers (on the internal network) were already configured in an Active/Passive role using failover.

    • Public Access from the DMZ. The public web servers required access to the database used by the cms.

    • The public web servers and the cms must be separate systems.

    • The public web servers must be configured for HA.

    • The public web servers must scale.

    • Security. The cms database must not be altered from any of the public web servers.

I would have preferred a design based on my other web cluster architectures and added shared storage for all the public web servers. As it currently stands, each public web server is in a shared-nothing configuration. This means that any code updates must be applied, individually to each public web server. As for the web-site content, a majority of it comes from the MySQL database. Therefore content changes are globally seen by all public web servers without the need of copying files to them.

What I considered to be a serious security issue and weak-link in the design was the requirement of the public web servers access to a MySQL database on the internal network. This was resolved by configuring each public web server with MySQL replication. Each public web server was configured with a read-only MySQL slave server. This accomplished some HA goals:

    • If the internal network crashed, each public web server would continue to operate.

    • If the firewall crashed, each public web server would continue to operate.

    • If both internal MySQL masters failed, the public web servers would continue to operate.

The only other issue was how to get MySQL replication data from the internal network to the public web servers in the DMZ. The ideal solution is to use autossh on the active cms server (the active MySQL master), to open an ssh tunnel to each of the public web servers. Each public web server would have it's mysql slave configured to connect to a loopback address that is actually the receiving end of the ssh tunnel originated from the active cms server. Though this incurs additional administration on the active cms in the form of a separate ssh tunnel to each public web-server, I feel the added overhead is warrented with the security this provides. It was later decided to open the MySQL port on the firewall, and restrict access to the public web servers. This provides simplicity in the administration. I configured each of the public web servers with a read-only MySQL account, used by the php application, to further enforce security. Therefore, there is no write capabilities to the MySQL database from any of the public web servers. This also simplifies the scale out of the public web servers. We merely add another public web server and configure it as a MySQL replication slave server to handle scaling.

The following diagram depicts the architecture I designed: