Read Only or Immutable Files in AEM
Description description
Environment
Experience Manager
Issue/Symptoms
When Adobe Managed Services (AMS) provisions a system they roll out a baseline configuration that makes everything functional and secure. These are things that the AMS wants to ensure stay as a baseline of functionality and security. To accomplish this, some files are marked as read-only and immutable to avoid you changing them.
The layout doesn’t prevent you from altering their behavior and overriding any changes you need. Instead of changing these files, overlay your own file that supersedes the original.
This also allows you to be reassured that when AMS patches the Dispatchers with the latest fixes and security enhancements, they won’t alter your files. Then you can continue to benefit from the improvements and adopt only the changes you’d like.
As illustrated in the picture above, immutable files are not stopping you from playing the game. They just stop you from hurting your performance and keep you in the lane. This method allows us the few very key features:
- Customizations are handled in their own safe spaces
- Overlay of custom changes mirrors that of overlay methods in AEM
- Patching AMS configurations can be done without altering customizations
- Testing base install vs customized configurations can be done simultaneously to help discern if the issues are caused by customizations or something else Which Files?
Here is a typical list of files deployed with a Dispatcher:
/etc/httpd/
├── conf
│ └── httpd.conf
├── conf.d
│ ├── available_vhosts
│ │ ├── 000_unhealthy_author.vhost
│ │ ├── 000_unhealthy_publish.vhost
│ │ ├── aem_author.vhost
│ │ ├── aem_flush.vhost
│ │ ├── aem_health.vhost
│ │ ├── aem_lc.vhost
│ │ └── aem_publish.vhost
│ ├── dispatcher_vhost.conf
│ ├── enabled_vhosts
│ │ ├── aem_author.vhost -> /etc/httpd/conf.d/available_vhosts/aem_author.vhost
│ │ ├── aem_flush.vhost -> /etc/httpd/conf.d/available_vhosts/aem_flush.vhost
│ │ ├── aem_health.vhost -> /etc/httpd/conf.d/available_vhosts/aem_health.vhost
│ │ └── aem_publish.vhost -> /etc/httpd/conf.d/available_vhosts/aem_publish.vhost
│ ├── logformat.conf
│ ├── remoteip.conf
│ ├── rewrites
│ │ ├── base_rewrite.rules
│ │ └── xforwarded_forcessl_rewrite.rules
│ ├── security.conf
│ ├── variables
│ │ └── ams_default.vars
│ └── whitelists
│ └── 000_base_whitelist.rules
├── conf.dispatcher.d
│ ├── available_farms
│ │ ├── 000_ams_author_farm.any
│ │ ├── 001_ams_lc_farm.any
│ │ └── 999_ams_publish_farm.any
│ ├── cache
│ │ ├── ams_author_cache.any
│ │ ├── ams_author_invalidate_allowed.any
│ │ ├── ams_publish_cache.any
│ │ └── ams_publish_invalidate_allowed.any
│ ├── clientheaders
│ │ ├── ams_author_clientheaders.any
│ │ ├── ams_common_clientheaders.any
│ │ ├── ams_lc_clientheaders.any
│ │ └── ams_publish_clientheaders.any
│ ├── dispatcher.any
│ ├── enabled_farms
│ │ ├── 000_ams_author_farm.any -> /etc/httpd/conf.dispatcher.d/available_farms/000_ams_author_farm.any
│ │ └── 999_ams_publish_farm.any -> /etc/httpd/conf.dispatcher.d/available_farms/999_ams_publish_farm.any
│ ├── filters
│ │ ├── ams_author_filters.any
│ │ ├── ams_lc_filters.any
│ │ └── ams_publish_filters.any
│ ├── renders
│ │ ├── ams_author_renders.any
│ │ ├── ams_lc_renders.any
│ │ └── ams_publish_renders.any
│ └── vhosts
│ ├── ams_author_vhosts.any
│ ├── ams_lc_vhosts.any
│ └── ams_publish_vhosts.any
├── conf.modules.d
│ ├── 01-cgi.conf
│ └── 02-dispatcher.conf
└── modules -> ../../usr/lib64/httpd/modules
└── mod_dispatcher.so
To determine which files are immutable you can run the following command on a Dispatcher to see:
$ lsattr -Rl /etc/httpd 2 > /dev/null | grep Immutable
Here is a sample response of which files are immutable:
/etc/httpd/conf/httpd.conf Immutable
/etc/httpd/conf.d/available_vhosts/aem_author.vhost Immutable
/etc/httpd/conf.d/available_vhosts/aem_publish.vhost Immutable
/etc/httpd/conf.d/available_vhosts/aem_lc.vhost Immutable
/etc/httpd/conf.d/available_vhosts/aem_flush.vhost Immutable
/etc/httpd/conf.d/available_vhosts/aem_health.vhost Immutable
/etc/httpd/conf.d/available_vhosts/000_unhealthy_author.vhost Immutable
/etc/httpd/conf.d/available_vhosts/000_unhealthy_publish.vhost Immutable
/etc/httpd/conf.d/rewrites/base_rewrite.rules Immutable
/etc/httpd/conf.d/rewrites/xforwarded_forcessl_rewrite.rules Immutable
/etc/httpd/conf.d/whitelists/000_base_whitelist.rules Immutable
/etc/httpd/conf.d/dispatcher_vhost.conf Immutable
/etc/httpd/conf.d/logformat.conf Immutable
/etc/httpd/conf.d/security.conf Immutable
/etc/httpd/conf.modules.d/02-dispatcher.conf Immutable
/etc/httpd/conf.dispatcher.d/available_farms/000_ams_author_farm.any Immutable
/etc/httpd/conf.dispatcher.d/available_farms/999_ams_publish_farm.any Immutable
/etc/httpd/conf.dispatcher.d/available_farms/001_ams_lc_farm.any Immutable
/etc/httpd/conf.dispatcher.d/cache/ams_author_cache.any Immutable
/etc/httpd/conf.dispatcher.d/cache/ams_author_invalidate_allowed.any Immutable
/etc/httpd/conf.dispatcher.d/cache/ams_publish_cache.any Immutable
/etc/httpd/conf.dispatcher.d/cache/ams_publish_invalidate_allowed.any Immutable
/etc/httpd/conf.dispatcher.d/clientheaders/ams_author_clientheaders.any Immutable
/etc/httpd/conf.dispatcher.d/clientheaders/ams_publish_clientheaders.any Immutable
/etc/httpd/conf.dispatcher.d/clientheaders/ams_common_clientheaders.any Immutable
/etc/httpd/conf.dispatcher.d/clientheaders/ams_lc_clientheaders.any Immutable
/etc/httpd/conf.dispatcher.d/filters/ams_author_filters.any Immutable
/etc/httpd/conf.dispatcher.d/filters/ams_publish_filters.any Immutable
/etc/httpd/conf.dispatcher.d/filters/ams_lc_filters.any Immutable
/etc/httpd/conf.dispatcher.d/renders/ams_author_renders.any Immutable
/etc/httpd/conf.dispatcher.d/renders/ams_publish_renders.any Immutable
/etc/httpd/conf.dispatcher.d/renders/ams_lc_renders.any Immutable
/etc/httpd/conf.dispatcher.d/vhosts/ams_author_vhosts.any Immutable
/etc/httpd/conf.dispatcher.d/vhosts/ams_publish_vhosts.any Immutable
/etc/httpd/conf.dispatcher.d/vhosts/ams_lc_vhosts.any Immutable
/etc/httpd/conf.dispatcher.d/dispatcher.any Immutable
Resolution resolution
How to make changes?
Variables
Variables allow you to make functional changes without changing the configuration files themselves. Certain elements of the configuration can be adjusted by adjusting the values of variables. One example that is highlighted from the file /etc/httpd/conf.d/dispatcher_vhost.conf
is shown here:
Include /etc/httpd/conf.d/variables/ams_default.vars
<IfModule disp_apache2.c>
DispatcherConfig conf.dispatcher.d/dispatcher.any
DispatcherLog logs/dispatcher.log
DispatcherLogLevel ${DISP_LOG_LEVEL}
DispatcherDeclineRoot 0
DispatcherUseProcessedURL 1
</IfModule>
See how the DispatcherLogLevel
directive has a variable of DISP_LOG_LEVEL
instead of the normal value you’d see there. Above that section of code you’ll also see an include statement to a variables file. The variable file /etc/httpd/conf.d/variables/ams_default.vars
is where you want to look next. Here are the contents of that variables file:
Define DISP_LOG_LEVEL info
Define AUTHOR_WHITELIST_ENABLED 0
Define PUBLISH_WHITELIST_ENABLED 0
Define LIVECYCLE_WHITELIST_ENABLED 0
Define AUTHOR_FORCE_SSL 1
Define PUBLISH_FORCE_SSL 0
Define LIVECYCLE_FORCE_SSL 1
You see above that the current value of DISP_LOG_LEVEL
variable is ‘info’. You can adjust this to trace or debug, or the number value/level of your choice. Now, everywhere that controls the log level adjusts automatically.
Overlay Method
Please understand the top level include files because these are your starting place of making any customizations. To start with a simple example, you have a scenario where you want to add a new domain name that is intended to point at this Dispatcher. The domain example let’s use is we-retail.adobe.com.
Start by copying an existing configuration file to a new one where we can add our changes:
$ cp /etc/httpd/conf.d/available_vhosts/aem_publish.vhost /etc/httpd/conf.d/available_vhosts/weretail_publish.vhost
You copied the existing aem_publish.vhost
file because it already has what you need to make things work and you don’t want to re-invent an already strong start. Now you edit the new weretail.vhost file and make the needed changes.
Before:
<VirtualHost *:80>
ServerName publish
ServerAlias ${PUBLISH_DEFAULT_HOSTNAME}
DocumentRoot ${PUBLISH_DOCROOT}
<IfModule mod_headers.c>
Header always add X-Dispatcher ${DISP_ID}
Header always add X-Vhost "publish"
Header merge X-Frame-Options SAMEORIGIN "expr=%{resp:X-Frame-Options}!='SAMEORIGIN'"
Header merge X-Content-Type-Options nosniff "expr=%{resp:X-Content-Type-Options}!='nosniff'"
Header append Vary User-Agent env=!dont-vary
</IfModule>
....... SNIP.......
</VirtualHost>
After:
<VirtualHost *:80>
ServerName weretail-publish
ServerAlias we-retail.adobe.com
DocumentRoot ${PUBLISH_DOCROOT}
<IfModule mod_headers.c>
Header always add X-Dispatcher ${DISP_ID}
Header always add X-Vhost "werteail-publish"
Header merge X-Frame-Options SAMEORIGIN "expr=%{resp:X-Frame-Options}!='SAMEORIGIN'"
Header merge X-Content-Type-Options nosniff "expr=%{resp:X-Content-Type-Options}!='nosniff'"
Header append Vary User-Agent env=!dont-vary
</IfModule>
....... SNIP.......
</VirtualHost>
Now you have updated our ServerName and ServerAlias to match the new domain names, as well as updating other breadcrumb headers. Let’s now enable our new file to allow Apache to know to use our new file:
$ cd /etc/httpd/conf.d/enabled_vhosts/; ln -s ../available_vhosts/weretail_publish.vhost .
Now Apache webserver knows that a domain is something it should yield traffic for, but you still need to inform the Dispatcher module that it has a new domain name to honor. Start by creating a new *_vhost.any file /etc/httpd/conf.dispatcher.d/vhosts/weretail_vhosts.any and inside that file put in the domain name that you want to honor:
"we-retail.adobe.com"
Now, you need to make a new farm file that uses our new vhost entry file, and you’ll start by copying a strong start file to our own new one.
$ cp /etc/httpd/conf.dispatcher.d/available_farms/999_ams_publish_farm.any /etc/httpd/conf.dispatcher.d/available_farms/400_weretail_publish_farm.any
Lets show the changes you’ll need to make to this farm file
Before:
/publishfarm {
/virtualhosts {
$include "/etc/httpd/conf.dispatcher.d/vhosts/ams_publish_vhosts.any"
}
........SNIP.........
}
After:
/weretailpublishfarm {
/virtualhosts {
$include "/etc/httpd/conf.dispatcher.d/vhosts/weretail_publish_vhosts.any"
}
........SNIP.........
}
Now you have updated the farm name, and the include it uses in the /virtualhosts section of the farm configuration. You need to enable this new farm file so it can use it in the running configuration:
$ cd /etc/httpd/conf.dispatcher.d/enabled_farms/; ln -s ../available_farms/400_weretail_publish_farm.any .
Now you would just reload the webserver service and use our new domain!
Note:
Notice, you only changed the pieces you needed to change and leveraged the existing includes and code that came with the baseline configuration files. You only have to delineate on the element you need to change. Makes thing much easier and allows us to maintain less code