Forum Moderators: phranque
SetEnvIf Remote_Addr ^107\.20\.0\.0\/14 bad_range
SetEnvIf Remote_Addr ^107\.21\.1\.8$ !bad_range # DuckDuckBot
deny from env=bad_range SetEnvIf Remote_Addr ^107\.20\.0\.0\/14 bad_range
SetEnvIf Remote_Addr ^107\.21\.1\.8$ !bad_range # DuckDuckBot
<RequireAll>
Require not env=bad_range
</RequireAll> <RequireAll>
Require all granted
<RequireNone>
Require env keep_out
Require env bad_protocol
Require env bad_range
[et cetera]
</RequireNone>
</RequireAll>
The preliminary “Require all granted” is equivalent to "Allow from all” in the old Allow,Deny ordering. Require ip 37.187
Require ip 45.145
and so on--assuming a RequireNone envelope--exactly the way you used to say “Deny from 37.187” and so on. In fact, if you have a whole lot of them you can just globally replace in a text editor. SetEnvIf Remote_Addr ^107\.20\.0\.0\/14 bad_rangeWaitwaitwait? You can do this? I thought SetenvIf worked only with Regular Expressions, in this case
<RequireAll>
Require all granted </RequireAll> <RequireNone>
</RequireNone> Waitwaitwait? You can do this?
Order Allow,Deny
Allow from all
SetEnvIf Accept ^$ no_accept
SetEnvIf Accept-Charset ^$ no_accept-charset
SetEnvIf Accept-Encoding ^$ no_accept-encoding
SetEnvIf Accept-Language ^$ no_accept-language
SetEnvIf Connection ^$ no_connection
BrowserMatchNoCase bingbot !no_accept
BrowserMatchNoCase bingbot !no_accept-charset
BrowserMatchNoCase bingbot !no_accept-encoding
BrowserMatchNoCase bingbot !no_accept-language
BrowserMatchNoCase bingbot !no_connection
Deny from env=no_accept
Deny from env=no_accept-charset
Deny from env=no_accept-encoding
Deny from env=no_accept-language
Deny from env=no_connection SetEnvIf Remote_Addr (^107\.20\.0\.0\/14|^23\.20\.0\.0\/14|^50\.16\.0\.0\/14|etc) bad_range Require not 123.123.123.123 123.123.123.123 123.123.123.123 123.123.123.123 If, as I understand it, Apache runs each module separately - all SetEnvIf directives, then all mod_rewrite, etc., it seems there wouldn't be any reason not to so long as all internal directives were consistent with their outer envelopes.Since each module is an island, the server doesn't care what order you put things in. You could even interlace directives from a bunch of different modules; the server will ignore everything except the mod it's currently working on. (I do not, of course, recommend that you do this. Just saying you could if you wanted to. If, say, the site administration was about to be taken over by someone you dislike and you wanted to get them off to a miserable start.)
Like the bumblebee, apparently, at least on 2.2.Slowly, clumsily and loudly, but it works? I’ll be darned. I’ll try it on my test site one day. Incidentally, I doubt you need to escape the / slash, although it does no harm. Generally you only need to escape it if the / slash itself serves as a RegEx delimiter, as in javascript and one or two obscure Apache mods that I don't personally use.
is there any reason SetInvIf would dislike a configuration likeDunno, never tried it :) But I really doubt it would make the server throw a fit. At worst it just wouldn't work, so go ahead and try. And you could almost certainly put the ^ opening anchor outside the parentheses, since it applies to every item.
at the moment my host implemented http/2 my header control section blew up the server. I determined that by stripping my .htaccess file to the bone, then adding back each section until the header controls proved to be the culpritHow odd and alarming. Mine went to http/2 a while back but I don't think anything changed. Possibly some detail of header logging, but then again that might be a php upgrade that just happened to come around the same time. Did you check each header item individually? Maybe there's some particular header that http/2 dislikes.
How odd and alarming. Did you check each header item individually? Maybe there's some particular header that http/2 dislikes
SetEnvIf Remote_Addr (^107\.20\.0\.0\/14|^23\.20\.0\.0\/14|^50\.16\.0\.0\/14|etc) bad_range <if " -R '23.21.227.69' || -R '40.88.21.235' || -R '50.16.241.113' || -R '50.16.241.114' || -R '50.16.241.117' || -R '50.16.247.234' || -R '52.5.190.19' || -R '52.204.97.54' || -R '54.197.234.188' || -R '54.208.100.253' || -R '54.208.102.37' || -R '107.21.1.8' ">
SetEnvIfExpr "%{REMOTE_ADDR} =~ /(.+)/" ips=duck:$0
BrowserMatch DuckDuckBot duck bot=duck
BrowserMatch DuckDuckGo-Favicons-Bot duck bot=iconduck
Require env duck
</if> I haven't yet seen it replicated in the 2.4 Require directivesYou can still say things like
Require ip 51.15 51.68 51.91 51.161
exactly like the former “Deny from” construction. (What I, personally, like to do is group each /8 on a single line.) Note the quirk that, since this is not a RegEx, “15” only means .15 and not .151 and so on.
Order Allow,Deny
Allow from all
BrowserMatchNoCase 2icommerce bad_bot
BrowserMatchNoCase 4SeoHuntBot bad_bot
BrowserMatchNoCase 7Siters bad_bot
BrowserMatchNoCase 80bot bad_bot
BrowserMatchNoCase 80legs bad_bot
BrowserMatchNoCase 8LEGS bad_bot
BrowserMatchNoCase A6-Indexer bad_bot
Deny from env=bad_bot
<RequireAll>
Require all granted
<RequireNone>
BrowserMatchNoCase 2icommerce bad_bot
BrowserMatchNoCase 4SeoHuntBot bad_bot
BrowserMatchNoCase 7Siters bad_bot
BrowserMatchNoCase 80bot bad_bot
BrowserMatchNoCase 80legs bad_bot
BrowserMatchNoCase 8LEGS bad_bot
BrowserMatchNoCase A6-Indexer bad_bot
Require env=bad_bot
</RequireNone>
</RequireAll>
<RequireAll>
Require all granted
BrowserMatchNoCase 2icommerce bad_bot
BrowserMatchNoCase 4SeoHuntBot bad_bot
BrowserMatchNoCase 7Siters bad_bot
BrowserMatchNoCase 80bot bad_bot
BrowserMatchNoCase 80legs bad_bot
BrowserMatchNoCase 8LEGS bad_bot
BrowserMatchNoCase A6-Indexer bad_bot
Require not env=bad_bot
</RequireAll> <Directory /var/www/html>
<RequireAny>
<RequireAll>
Require all granted
Require not ip 104.197.51.76
Require not ip 54.242.250.203
Require not env bad_bot
Require not env spam_ref
</RequireAll>
<RequireAny>
Require ip 131.253.24.0/22
Require ip 131.253.46.0/23
Require env good_ref
Require env good_bot
</RequireAny>
</RequireAny>
</Directory> Order Allow,Deny
Allow from all
BrowserMatchNoCase 2icommerce bad_bot
Deny from env=bad_bot Require env bad_range Require ip 131.253.46.0/23
Require env good_ref
Require env good_bot I can only use the identical Apache 2.2 syntax (which, who knows, may indeed also be Apache 2.4 syntax);
Order Allow,Deny
Allow from all
BrowserMatchNoCase 2icommerce bad_bot
Deny from env=bad_botIs this the way you've been accustomed to do it in 2.2? Be aware that what you have there is: There simply isn't going to be anyI wish you would stop saying it in those words, because Require isn't a SetEnvIf directive. Any Require directive has to be inside a <RequireSomething> envelope, while any SetEnvIf directive has to not be inside the envelope.
Require env bad_range
or
Require ip 131.253.46.0/23
Require env good_ref
Require env good_bot
within any SetEnvIf sections
Well, the SetEnvIf parts are identical; it's the Allow/Deny that changes.
Is this the way you've been accustomed to do it in 2.2?
it encourages the idea that the two mods are in some way connected, when in fact they're not.
Are you positive that your server is, in fact, on 2.4?
I wish you would stop saying it in those words, because Require isn't a SetEnvIf directive. Any Require directive has to be inside a <RequireSomething> envelope, while any SetEnvIf directive has to not be inside the envelope.
Require all denied inside a FilesMatch envelope but with no Require envelopes, verified by a test file. The SetEnvIf and BrowserMatch (same thing) sections are the only ones where I'm using the deny language; in all other denial situations - well, the FilesMatch and IPs are the only ones - I'm using Require. # allow letsencrypt but block other nasties
<if "! (%{HTTP_USER_AGENT} =~ m#letsencrypt.org#)">
BrowserMatch [\"\'\$%&\*~#\{\}\[\]\<\>\?\|\\\!] useragent=symbol:$0
</if>
# block bad user-agents
BrowserMatchNoCase curl|(go-)?http-?client|fetch|grab|HTTrack|extract|indy\slibrary|java|larbin|libwww|perl|php|python|scan|wget|winhttp useragent=fetch:$0
# block stupid/injection symbols in URI
SetEnvIf REQUEST_URI (\=|\@|\[|\]|\^|\`|\{|\}|\~) badrequri=uri_sym:$0
SetEnvIfNoCase REQUEST_URI (\'|%0A|%0D|%27|%3C|%3E|%00) badrequri=uri_sym:$0
# reject bad query-strings
<if " %{QUERY_STRING} =~ m#(md5|benchmark|debug|union|select|insert|cast|session|set|declare|drop|update)#i ">
SetEnvIfExpr "%{QUERY_STRING} =~ /(.+)/" query=inject:$0
</if>
# block bad referers
SetEnvIfNoCase Referer \}__test|base64_decode|bash|chr\(|disconnectHandlers|echo|eval\(|EXEC\(\@S\)|JDatabaseDriverMysqli|JSimplepieFactory|\$_REQUEST|JFactory|getConfig refer=code:$0
# if not known bot, flag as bad
<if " ! %{HTTP_USER_AGENT} =~ m#((Apple|bing|Exa|Google|istella|Twitter)bot|(Mojeek|Seznam|Yandex)Bot|BingPreview|DuckDuck|facebook|letsencrypt|Linespider|Qwantify|Vagabondo|Yeti)# && ! %{REQUEST_URI} =~ m#/robots\.txt#">
BrowserMatch .{0,10}([Bb]ot|[Cc]rawl|rank|review|spider).{0,10} bot_is=bad_robot:$0
</if>
# and finally, block on the set-env values above
# (some of these are not shown in the code above for brevity)
Require env favicon
Require env netsurf
Require expr %{REQUEST_URI} =~ m#/robots\.txt#
Require expr %{REQUEST_URI} =~ m#favicon\.ico|apple-touch-icon\.png|apple-touch-icon-precomposed\.png#i
<RequireAll>
Require method GET POST HEAD
<RequireNone>
Require env bot_is
Require env useragent
Require env badua
Require env badrequri
Require env refer
Require env query
Require env BlockCountry
</RequireNone>
</RequireAll>
<RequireAll>
Require all granted
<RequireNone>
Require ip 13.66.
Require ip 13.66.139.139
</RequireNone>
</RequireAll> <RequireAll>
Require all granted
Require not ip 13.66.
Require not ip 13.66.139.139
</RequireAll> neitherIs it possible there are other access-control rules along the same (physical) filepath)? I think I mentioned earlier in this thread that I ran into this issue after converting to Require syntax, and it took a while before I remembered that certain subdirectories had their own htaccess files. (Since you can't have a <Directory> section in htaccess, specialized access controls--or different Options settings--can only be done by giving selected directories their own little supplementary htaccess.)
...
nor
...
are actually blocking either the IPs shown above
13.66.139.139 - - [09/Mar/2021:05:19:48 -0800] "GET /blah/blah/2017/11/blah.jpg HTTP/1.1" 200 207485 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
157.55.39.158 - - [09/Mar/2021:05:27:05 -0800] "GET /2012/01/23/blah/ HTTP/1.1" 200 57095 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
13.66.139.3 - - [09/Mar/2021:05:57:42 -0800] "GET /2011/11/30/blah/ HTTP/1.1" 403 4266 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
157.55.39.146 - - [09/Mar/2021:06:09:34 -0800] "GET /2013/02/06/blah/ HTTP/1.1" 403 4266 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
change the double negative <RequireNone> constructionYou do have a knack for saying things that make me anxious, don’t you. To me, “double negative” would mean something like
<Directory>
<RequireAll>
Blah blah
</RequireAll>
</Directory> SetEnvIfNoCase User-Agent "^Bandit" bad_bot
SetEnvIfNoCase User-Agent "^Baiduspider" bad_bot
SetEnvIfNoCase User-Agent "^BatchFTP" bad_bot
SetEnvIfNoCase User-Agent "^Bigfoot" bad_bot
SetEnvIfNoCase User-Agent "^Black.Hole" bad_bot
Order Allow,Deny
Allow from All
Deny from env=bad_bot <Directory> wrapper around the whole shooting matchYikes. I thought this was all happening in htaccess--which, in effect, is its own <Directory> wrapper.
But I worried that maybe the "Allow from all" somehow preempted and precluded my new Require directives, so I commented out both the Order and Allow lines leaving only the Deny line.Now, wait a minute. There shouldn't be ANY lines using Allow/Deny syntax in the same htaccess/Directory as lines with Require syntax.
Yikes. I thought this was all happening in htaccess--which, in effect, is its own <Directory> wrapper.
Now, wait a minute. There shouldn't be ANY lines using Allow/Deny syntax in the same htaccess/Directory as lines with Require syntax.