Loading...


Related Products


Date Published: February 10, 2022

Best practices on setting up an edit domain

Issue

What is an edit domain, and how would it help my workflow?

Resolution

An edit domain can be extremely useful for giving editors a place to work, while maintaining the primary site's content and cache. An edit domain gives you even more control over when content moves to your primary servers, and also reduces cache changes. This helps secure your site and keeps your site responding quickly.

Basic Setup

The initial setup is simple. Create another domain for your site that is called edit.sitename.com, and have that be the only domain that editors go to. The edit domain should not be a multisite, but rather another domain that uses the same sites directory as the main site. This is easily done in Drupal 7+ with sites.php. Acquia-hosted customers will need to add the edit domain to our balancer as well.

The new edit domain is exposed to editors either through a public DNS record, or preferably a private one (if your company is running its own DNS). A small editorial staff can also do individual /etc/hosts file editing. If you're using a public DNS, Acquia recommends using .htaccess access control through allowlisted IPs (see the following benefits and uses). For more information on using an .htaccess file, read Protecting Drupal's fleshy underbelly with .htaccess.

With the new domain set up, you then add logic like this in the settings.php file:

$is_edit_domain = FALSE;
$forwarded_host = (empty($_SERVER['HTTP_X_FORWARDED_HOST'])) ? $_SERVER['HTTP_HOST'] : $_SERVER['HTTP_X_FORWARDED_HOST'];

if (strpos($forwarded_host, 'edit') !== FALSE) {
  $is_edit_domain = TRUE;
}

$conf['is_edit_domain'] = $is_edit_domain;

Once this is completed, you can add any other logic you need in settings.php, and modules can use variable_get('is_edit_domain', FALSE) to check if the current domain is an edit domain and adjust themselves accordingly. At this point, you have a "public" domain (www.sitename.com) and an "edit" domain (edit.sitename.com). You're now ready to start customizing their behavior.

Benefits and Uses

You can fully customize anything about the application that can be set either in settings.php or in a module. Common examples are PHP memory limits, Drupal variables (especially caching settings and session life times), and different module behavior.

We recommend sticking strictly to settings.php changes as much as possible, because having modules change their logic based on the domain can be confusing and difficult to maintain. If checking by module is necessary, have the module logic be controlled by a variable that you set in settings.php rather than having the module do the domain checks. This will ensure that later changes are easier to propagate.

Blank User Roles

You may have users come to the edit domain instead of the public domain; ensure that anyone who logs in on the public domain has no roles associated with them. This keeps the edit site more secure and can help sites that use a CDN (when you don't want admin content cached in the CDN).

Note

On Acquia Cloud, blank user roles require special care. Setting table prefixes in settings.php is not allowed. You can do it as long as you add acquia_hosting_db_choose_active() after modifying the $databases array.

Blocking Acce

With this approach, you should also block acce to privileged paths on the public domain in .htaccess. Examples of URLs and files that should be blocked include /user/admin/node/scripts/profile/includes*.php (if possible), cron.phpinstall.phpupdate.phpxmlrpc.php, and .gitignore. The rules should be placed in the rewrite rules section of your .htaccess file and should first be tested in a non-Production environment.

Restrict access to the edit domain to a select few IPs or IP ranges. This is especially important if you don't have an internal DNS server and the domain is in the public DNS. This will prevent people from bypassing the public domain and going to edit. See Blocking access using rewrites for an example. The sample code below blocks most of the sensitive paths, and creates redirects for paths that users need to be kept away from:

# Redirect any direct request for index.php and no query string to /
# The no query string part makes sure that clean URLs rewrites are
# not victims because they will have q=something
RewriteCond %{QUERY_STRING} ^$
# Protect files and directories from prying eyes.
RedirectMatch 404 "\.(engine|inc|info|install|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format)$"

# Disallow various other files
RedirectMatch 404 (README\.txt|INSTALL\.txt|CHANGELOG\.txt|COPYRIGHT\.txt|INSTALL\.mysql\.txt|INSTALL\.pgsql\.txt|LICENSE\.txt|MAINTAINERS\.txt|UPGRADE\.txt)

# Disallow admin paths
Redirect 404 /admin
Redirect 404 /scripts
Redirect 404 /profile
Redirect 404 /includes
Redirect 404 /cron.php
Redirect 404 /install.php
Redirect 404 /update.php
Redirect 404 /xmlrpc.php

# Disallow access to the feed modules import path
Redirect 404 /import

# disable direct access to nodes with their canonical URLs
Redirect 404 /node

# Protect webform uploads
Redirect 404 /sites/default/files/webform

# Protect Taxonomy lists
Redirect 404 /taxonomy

# Make any PHP request a 404, except for our 404 page which is PHP and the main index
RewriteCond %{REQUEST_URI} !^/sites/default/themes/themename/404/page-not-found\.php
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_URI} \.(php)$
RewriteCond %{REQUEST_URI} !^404\.%1$
RewriteRule ^(.*)$ 404.%1 [R=404,L]

# All others where a file is missing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/sites/default/files/
RewriteCond %{REQUEST_URI} \.(png|gif|jpe?g|s?html?|css|js|cgi|ico|swf|flv|dll)$
RewriteCond %{REQUEST_URI} !^404.%1$
RewriteRule ^(.*)$ 404.%1 [R=404,L]

# Redirect any direct request for index.php and no query string to /
# The no query string part makes sure that clean URLs rewrites are
# not victims because they will have q=something
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^index.php$   / [R=301,L]

In addition, you can modify the code above to add a rule that conditionally affects one or more of your website's environments, for example:

RewriteCond %{ENV:AH_SITE_ENVIRONMENT} ^(dev|test|prod)$

Although the example code includes Dev, Test, and Production environments by default, you can modify the rule to include only those environments that you require.

Server Tuning

On rare occasions, it may be necessary to tune the server editorial staff to the degree that it is no longer feasible to use the same hardware. It is possible to have the edit domain be a standalone server cluster that shares only the same code and database. This approach is not recommended, because it is more complex, and it is usually better to have more "small" servers distributing the load than a few "big" ones doing the heavy work.

Gotchas

Content editors need to make sure that any links they are putting in manually are relative and don't include the edit domain.

Depending on how media, especially images, are embedded, that content may reference the edit domain. The Pathologic module can fix this.

If there is an aggressive CDN in front of the public domain, editors have to be careful to not log in on the public domain as themselves (and especially not as User ID 1). Blank user roles can help with that.

Did not find what you were looking for?

If this content did not answer your questions, try searching or contacting our support team for further assistance.

Back to Section navigation