Forum Moderators: phranque

Message Too Old, No Replies

Moving htaccess to httpd configuration

         

csdude55

8:11 am on Nov 10, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm using the magic of Apache to move my htaccess to configuration, which (in theory) should help things to run faster.

[documentation.cpanel.net...]

I have a few questions:

1. Is there any disadvantage to have multiple files at /etc/apache2/conf.d/userdata/ (eg, "security.conf", "compress.conf", "mysqlinjection.conf", etc)? This would certainly make it easier for me to maintain any over time. I suspect that there's no disadvantage, other than maybe causing a restart to be a tad slower, but I wanted to make sure.

2. Assuming it's OK to have multiple files, can I control the order in which they are loaded?

For example, right now my .htaccess has several rules for each section of my site, and once one rule has matched then I have [L] to stop future rules from matching. If I create a series of site-specific files at /etc/apache2/conf.d/userdata/ssl/2_4/[user]/[domain]/, one for each feature of my site, then it would definitely be easier to maintain, but if there's a risk of a rule matching in the wrong section then I'll have to spend a lot more time reviewing everything.

3. Following that, can I use RewriteEngine on in one .conf, and then use rules in all of the other files without turning it on again?

phranque

8:45 am on Nov 10, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



1. Is there any disadvantage to have multiple files at /etc/apache2/conf.d/userdata/ (eg, "security.conf", "compress.conf", "mysqlinjection.conf", etc)? This would certainly make it easier for me to maintain any over time. I suspect that there's no disadvantage, other than maybe causing a restart to be a tad slower, but I wanted to make sure.

i doubt the additional overhead of opening additional files during startup would be significantly measurable.
it would be far outweighed by possible advantages in configuration management.

2. Assuming it's OK to have multiple files, can I control the order in which they are loaded?

the files will be loaded in the order of the Include directives.
if your Include directives use a wildcard in the file path:
Shell-style (fnmatch()) wildcard characters can be used in the filename or directory parts of the path to include several files at once, in alphabetical order.

(source: https://httpd.apache.org/docs/2.4/mod/core.html#include )

but if there's a risk of a rule matching in the wrong section then I'll have to spend a lot more time reviewing everything.

i would carefully read and understand the [L] flag documentation:
https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_l

3. Following that, can I use RewriteEngine on in one .conf, and then use rules in all of the other files without turning it on again?

you need to have a RewriteEngine on directive for each virtual host in which you wish to use rewrite rules.

(source: https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteengine )

lucy24

6:19 pm on Nov 10, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



if there's a risk of a rule matching in the wrong section then I'll have to spend a lot more time reviewing everything
Please explain in a little more detail what you mean by “section”.

In general, it’s safest to have just one set of RewriteRules along any given filepath (meaning physical path, which may or may not coincide with “directories” in the URL). Sure, 2.4 does expand the options for inheritability, but that just creates more things to keep track of. And, last time I checked, Apache still doesn't let you nest <Directory> sections.

If you’re going to end up with RewriteRules lying loose in config--most likely in a VirtualHost envelope--don’t forget to change any patterns that involve ^ since this behaves differently when not in a Directory section (including but not limited to .htaccess).

csdude55

11:17 pm on Nov 10, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Cool, @phranque, alphabetical... so presumably I could use numbers and name them something like "1_security.conf", "2_mysqlinjection.conf", and so on.

you need to have a RewriteEngine on directive for each virtual host in which you wish to use rewrite rules.

I can probably do this for myself tonight and find out, but just in case you know: does that mean that each .conf fie in the same directory needs "RewriteEngine on"? Or can I put it in "1_security.conf" and then use it in "2_mysqlinjection.conf"?

Please explain in a little more detail what you mean by “section”.

@lucy24, I mean, features of my site.

In my .htaccess, I have all of my security stuff first (mostly using [F] to block exploit attempts, injections, etc), then I have "Legacy" stuff to make sure old links redirect to the right locations. Then there is a section of general rewrites (eg, RewriteRule ^apple-touch-icon- /apple-touch-icon.png [L]).

Then there's a section for my classifieds, doing things like RewriteRule ^(?:classifieds/)?autos/?$ /classifieds/list.php?cat=autos [QSA,NC,L] (making it a pretty URL).

Then there's a section for my message boards, doing things like RewriteRule ^board/[a-z-]+/(\d+)/?$ /board/view/index.php?id=$1 [NC,QSA,L] (making it a pretty URL with the subject in the link).

And in my new build, I have a section with a bunch of ENV variables being set.

And so on. So I would inevitably have "3_general.conf", "4_classifieds.conf", "5_board.conf", and so on.

I think that, long term, it would be easier for me to have these all separated out so that, for example, if I add a new domain and need to add a new ENV variable, I can just modify that .conf and not risk a typo taking down the whole site.

phranque

12:00 am on Nov 11, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



does that mean that each .conf fie in the same directory needs "RewriteEngine on"?

it means you need a "RewriteEngine on" to occur before any other mod_rewrite directives will be processed.
extras don't hurt, so you can put one in each file to be safe.

(eg, RewriteRule ^apple-touch-icon- /apple-touch-icon.png [L])

which reminds me:
don’t forget to change any patterns that involve ^ since this behaves differently when not in a (directory context)


you will want to use something like this instead here - and elsewhere:
RewriteRule ^/apple-touch-icon- /apple-touch-icon.png [L]

csdude55

8:29 pm on Nov 11, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



i would carefully read and understand the [L] flag documentation:

I'm spinning off just a little bit here, @phranque, but the link says:

If you are using RewriteRule in either .htaccess files or in <Directory> sections, it is important to have some understanding of how the rules are processed. The simplified form of this is that once the rules have been processed, the rewritten request is handed back to the URL parsing engine to do what it may with it.

Am I correct in understanding that this is NOT the case when I move it to the .CONF?

Should I use [END] to come to a screeching halt instead of [L]?

I'm specifically looking at these rules that I have at the top of my .htaccess but will be moving to .CONF:

## cPanel fix, exclude DCV checks from future RewriteRules
## note, cPanel plugs these lines in to EVERY RewriteRule >:-( so I'm trying to make that unnecessary
RewriteCond %{REQUEST_URI} ^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} ^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$

# cPanel also includes these, but I exclude /.well-known below so they're not necessary
# RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
# RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
# RewriteCond %{REQUEST_URI} ^/\.well-known/cpanel-dcv/[0-9a-zA-Z_-]+$
# RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/(?:\ Ballot169)?
RewriteRule ^ - [L]

## also exclude /.well-known, 403.php, 404.php
## should I totally exclude /.well-known? Or should I only worry about the 4 that cPanel defines?
RewriteRule ^\.well-known|40[34]\.php$ - [L]

phranque

12:56 am on Nov 12, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Am I correct in understanding that this is NOT the case when I move it to the .CONF?

unless it is in a <Directory> envelope.

Should I use [END] to come to a screeching halt instead of [L]?

only you can determine if it is necessary, but since it is not rewriting to a different path it is unlikely there would be subsequent rewrite processing.

I'm specifically looking at these rules that I have at the top of my .htaccess but will be moving to .CONF

that second RewriteRule needs to specify a leading slash to match anything in server config or virtual host context.

csdude55

4:59 am on Nov 12, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



that second RewriteRule needs to specify a leading slash to match anything in server config or virtual host context.

Hold up. Wait a minute. (Issa chopper... LOL)

I thought that I was supposed to remove the opening / in .CONF files?

phranque

6:33 am on Nov 12, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I thought that I was supposed to remove the opening / in .CONF files?

it is precisely the opposite of that.

read carefully the What is matched? section here:
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule

csdude55

7:40 am on Nov 12, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Man, I always find the docs to be so confusing. The terminology of In VirtualHost context and In per-directory context is unnecessarily confusing. I swear, I've read it 10 times and it still doesn't make sense. Even when I read it out loud.

If I understand correctly, though... when I use a .CONF file for all sites, located at /etc/apache2/conf.d/userdata/ (which I take to mean "in VirtualHost context"), then I should have an opening /. But when I use a .CONF for a specific account or domain, located at /etc/apache2/conf.d/userdata/ssl/2_4/[user]/[domain]/ (which I take to mean "in per-directory context"), then I should not have an opening /?

phranque

7:56 am on Nov 12, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



it is very simple.
per directory context means within a <Directory> envelope or in a .htaccess file.
period.

context is described completely and unambiguously here:
https://httpd.apache.org/docs/2.4/mod/directive-dict.html#Context

csdude55

8:22 am on Nov 12, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I guess it's confusing because the files I'm working with are in neither a <VirtualHost> nor <Directory> container. I'm guessing that httpd.conf has a command somewhere to include any file in these directories? So I guess it's technically in a <VirtualHost> container, I just don't see it.

But my main takeaway, then, is that it has an opening / in any of the contexts that I'm using, so I can copy and paste directly from .htaccess to the .CONF file and it's all good.

phranque

9:04 am on Nov 12, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



RewriteRule also works in server config context, so it doesn't have to be in a <VirtualHost> container or a <Directory> container.

make sure your included .conf files aren't included from within a directory context.

lucy24

4:42 pm on Nov 12, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



make sure your included .conf files aren't included from within a directory context.
If you start the filepath with a / it shouldn't make any difference ... would it? (Happily, in this particular detail apache syntax seems to be identical to the familiar html linking syntax: if you start with / it means root--whether server or site--while if you don't, it becomes a relative link.)

Think carefully about what your RewriteRules are doing. If you have one set of them in the general config file, any given site will then encounter two sets of RewriteRules, since there are always site-specific ones as well. Some things, like canonicalization redirects, can be made to apply globally if all sites use the same naming format (for example, consistently with or without www), but is it really worth it? Generic access control, in particular, can probably be done more efficiently by means other than mod_rewrite.

I think it's pretty uncommon to have RewriteRules genuinely lying loose in config, not in an envelope of any kind. At a minimum you'd expect them to be in the <Directory> where all sites are kept: for example on shared hosting there might be something called /sites/ or /users/

phranque

10:14 pm on Nov 12, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



make sure your included .conf files aren't included from within a directory context.
If you start the filepath with a / it shouldn't make any difference ... would it? (Happily, in this particular detail apache syntax seems to be identical to the familiar html linking syntax: if you start with / it means root--whether server or site--while if you don't, it becomes a relative link.)

if a .conf file is included within a <Directory> container, aren't the directives within that .conf file also treated as if in directory context?
if so, the RewriteRule Pattern should have the path information removed.

lucy24

10:52 pm on Nov 12, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Oh, oops, I was thinking about the server not being able to find the file in the first place to include it, not about what's in the file when you get there. Yes, I should think that once you're inside a <Directory> envelope, everything is treated as being inside that envelope, regardless of whether it's raw text in the main config file, or in some included file. (Isn't that the whole point of includes, regardless of environment? “Pull in this extra stuff which is too bulky for the containing file, and then treat it exactly as if it had been in the containing file.”)

Frankly, the idea of rewrite-anything being way down deep in an included file makes me uneasy, but that may just be me.