I ran into an issue today with trying to restrict page access by IP address from within an Apache .htaccess file.  It was brought on by a site I host continuing to have an old employee getting in and messing with the WordPress website, along with phpMyAdmin.

I thought it would be a quick fix so I opened up the .htaccess files in the phpMyAdmin directory and /wp-admin and added the following:

order deny,allow
deny from all
allow from xx.xxx.xxx.xx

Great all set, went to test and I wasn’t able to access the page even though it was my IP address.  So looked a little more, oh I’m on Apache 2.4.6 not Apache 2.2.  The old order, deny, allow commands had been deprecated in 2.4.  Ok, so new syntax for Apache 2.4 is the following:

<RequireAny>
Require ip 1.1.1.1
Require ip 2.2.2.2
</RequireAny>

Ok, saved that off and should be good to go now.  Still a no go.  Spent about an hour messing with different syntax’s I found on Google and methods of doing this in the .htaccess file and the .conf files, on and on and on.  Then it hit me….this EC2 instance sits behind and Elastic Load Balance (ELB).  So the reason I can’t get it is the request hits the ELB, then the ELB forwards the request on to the EC2 instance. When that happens the EC2 instance see’s the ELB’s IP address which is not mine and blocks me.

Alright, so how can we get my actual IP vs the ELB’s?  Took a few tries but was able to accomplish it with the below:

SetEnvIF X-Forwarded-For "1.1.1.1" AllowIP
SetEnvIF X-Forwarded-For "2.2.2.2" AllowIP
 
<RequireAny>
Require env AllowIP
</RequireAny>

Finally, it works!

I spent a couple of hours on this and there was a lot of information on how to do this if it’s a traditional setup, but little on how to do when behind a load balancer.

4 Comments

  • Ragnar Kurm says:

    I needed a solution for IP ranges, and I came up with this:

    # Pick IP from X-Forwarded-For
    RemoteIPHeader X-Forwarded-For
    # The earlier statement kills X-Forwarded-For, put it back to restore logging and any site functionality that depends on it.
    SetEnv X-Forwarded-For ${REMOTE_ADDR}

    # List you ranges
    Require ip 1.2.0.0/16
    Require ip 11.22.00.00/16
    # Must have explicit denied in the end for RequireAny
    Require all denied

    • Ragnar Kurm says:

      The site eats away tags and spaces… I try again replacing HTML-style tags with {…}.

      # Pick IP from X-Forwarded-For
      RemoteIPHeader X-Forwarded-For
      # The earlier statement kills X-Forwarded-For, put it back to restore logging and any site functionality that depends on it.
      SetEnv X-Forwarded-For ${REMOTE_ADDR}

      {Location ~ “^/the/path”}
      {RequireAny}
      # List you ranges
      Require ip 1.2.0.0/16
      Require ip 11.22.00.00/16
      # Must have explicit denied in the end for RequireAny
      Require all denied
      {/RequireAny}
      {/Location}

  • Ragnar Kurm says:

    Shouting too early, restoring ‘X-Forwarded-For’ still does not work.
    Unfortunately this forum does not allow editing.

  • Ragnar Kurm says:

    To keep X-Forwarded-For intact:

    Instead of:
    SetEnv X-Forwarded-For ${REMOTE_ADDR}

    Use rather:
    # We have to do this by storing the Remote_Addr EARLY into temporary variable.
    SetEnvIf Remote_Addr “(.*)” CLIENT_IP=$1
    # And restore it LATE after ‘RemoteIPHeader’ has done it’s job.
    RequestHeader set X-Forwarded-For “%{CLIENT_IP}e”

Leave a Reply