RewriteCond doesn't let my IP address through - apache

I want to restrict access to my dev site to just my IP address. (eg 123.123.123.123)
I have the following in my .htaccess file. However I still get redirected to /dev_site_notice.html.
Am I specifying this correctly?
SetEnvIf X-Forwarded-Proto https HTTPS=on
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.123
RewriteCond %{REQUEST_URI} !/dev_site_notice.html$ [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
RewriteRule .* /dev_site_notice.html [R=302,L]

SetEnvIf X-Forwarded-Proto https HTTPS=on
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.123
If you are checking for the X-Forwarded-Proto header in the SetEnvIf directive then it implies you are behind a proxy server (otherwise this directive should be removed). If this is the case then the REMOTE_ADDR server variable is the IP address of the proxy, not the client IP address.
If (and only if) you are behind a proxy then you should be checking the X-Forwarded-For HTTP request header instead. For example:
RewriteCond %{HTTP:X-Forwarded-For} !^123\.123\.123\.123($|\D)
Note that the X-Forwarded-For header can contain multiple (comma-separated) IP addresses, depending on whether the request has gone through several proxies. The client-IP is usually first (left-most), but you may need to confirm this with the proxy. For this reason, the regex should not end with $ (not that your original regex did anyway), but rather ($|\D) (end-of-string OR not a digit).
The X-Forwarded-For header is the defacto standard, but it can vary from proxy to proxy. It is the proxy server that sets this header, when the request passes through.

Related

RewriteCond for ipv6 subnet under .htaccess

i'm having a question related to ipv6 address that reach a website.
The apache logs, shows clients x-forward ips under ipv4 and ipv6
This website is protected under .htaccess via a ipv4 whitelist for each allowed subnet.
Example :
RewriteCond %{HTTP:X-FORWARDED-FOR} !^123\.45\.67
RewriteCond %{HTTP:X-FORWARDED-FOR} !^123\.45\.68
RewriteCond %{HTTP:X-FORWARDED-FOR} !^123\.45\.69
How can i do the same for a ipv6 prefix , since the following does not seems to work
RewriteCond %{HTTP:X-FORWARDED-FOR} !^\[1234:123:123::/48\]
If i specify the ipv6 client ip in the rewritecond it works. But only for a period of time until his ipv6 address gets renewed.
Could you try:
RewriteCond expr "! %{HTTP:X-FORWARDED-FOR} -ipmatch '1234:123:123::/48'"
It implies Apache >= 2.4, native (meaning without the use of an expression) RewriteCond does not handle IP range/CIDR notation.
It didn't work.
Couldn't i achieve it by using the following regex by applying the same principle as the ipv4 conditions listed above where a substring of the value of the X-Forwarded-for is represented ?
RewriteCond %{HTTP:X-FORWARDED-FOR} !^1234:123:123

Port forwarding in apache with additional parameter

How can I forward all incoming requests on one port say 8000 to another port say 8081, & add a static parameter in all request url while forwarding so that I can check for that specific parameter in my script?
Try with below rules in your root htaccess,
RewriteEngine On
RewriteCond %{SERVER_PORT} ^8000$
RewriteRule ^$ http://%{HTTP_HOST}:8081%{REQUEST_URI}?param=value [QSA,L]

RewriteRule + HTTPS redirect for specific requests

I have setup the htaccess file to handle users requests with a specific rule and generic requests with other rules:
# users requests (i.e. users/login.html)
RewriteRule ^users/([^/]+)\.html$ mvc.php?rt=users/$1 [L,QSA,NC]
# generic requests (controller/action/id.html)
RewriteRule ^([^/]+)/([^/]+)/([^/]+)\.html$ mvc.php?rt=$1/$2&id=$3 [L,QSA,NC]
# generic requests (controller/action/)
RewriteRule ^([^/]+)/([^/]+)/$ mvc.php?rt=$1/$2 [L,QSA,NC]
# generic requests (controller/id.html)
RewriteRule ^([^/]+)/([^/]+)\.html$ mvc.php?rt=$1&id=$2 [L,QSA,NC]
# generic requests (controller.html)
RewriteRule ^([^/]+)\.html$ mvc.php?rt=$1 [L,QSA,NC]
RewriteRule ^$ mvc.php?rt=index [L,QSA,NC]
This works fine, and URL translation is handled correctly. My goal is now to force all users requests to be sent over HTTPS. I'm trying to setup a redirect rule as described in RewriteHTTPToHTTPS. I know this is not the recomended solution, but my server doesn't seem to support VirtualHost statements. Here is my code:
# users http to https
RewriteCond %{HTTPS} !=on
RewriteRule ^users(.*) https://%{SERVER_NAME}/users$1 [R,L]
Unfortunately this doesn't seem to work because I needed to insert the L flag after all rules, which causes the processing to stop when the rule is met. So, if the http-to-https rule is inserted first in htaccess, this rule is met and user specific rule is ignored (and viceversa for other case). Is there a way to both:
handle users requests with a specific rule
force users requests to be sent over HTTPS
with htaccess rules?
For many reasons my advice is to :
- do 301 redirect to https on all http requests
- use HSTS on all https answer
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
or
<VirtualHost *:80>
ServerAlias *
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]
</VirtualHost>
And in the 443 Virtualhost :
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
WARNING : Set the Strict-Transport-Security ONLY when the https works on all webpage. You can try with 3600 (10 minutes) in the begining if you are not sure. The "includeSubDomains" will for https for all subdomains and "preload" will allow your website to be added to the preload list of browsers.
If you have a login page do not forget the Secure attribute on the cookies (without it the cookie will be sent with insecure http request too).
Why ?
- Because without HSTS someone can force the browser to do a request to http://example.com/mysecurepage and then intercept the http request before you answer a 301, and respond the same page than the one you respond, but with http links instead. This attack is called sslstrip and the only thing that can prevent it is HSTS (preloaded if possible)
- With HSTS protect you if you forgot to add the secure attribute on cookies (but not all browser know HSTS, that's why it's still important to use the secure attribute!)
- Because it's easy to miss which pages must be mark secure :
if a page ask for personal data (email, name, ...) then in most European country you have the obligation to secure it ; sometimes, a page do not ask personal data but display it ; sometime the fact that the content of the page is public do not mean the visitor accept that anyone know he visits it.
- With HTTP2 and SPDY encrypted page can be served faster than not encrypted one: https://istlsfastyet.com/

Trying to tidy up .htaccess and remove hard-coding of domain name

I have the below configurations set up in a .htaccess file.
Instead of hard-coding the domain name (domain.com), can I use the domain of the current request and prevent hard-coding of the domain name?
Also, is that safe? Hard-coding guarantees the correct domain of course, but I'm trying to think if the 'grab current domain name' method might cause other issues (especially with the first two examples below).
# Allow cross-domain requests
#
SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.com)$" origin_is=$0
Header add Access-Control-Allow-Origin %{origin_is}e env=origin_is
Header add Access-Control-Allow-Credentials: true
# CSP
#
Header set Content-Security-Policy "default-src 'none'; connect-src http://domain.com https://domain.com;"
# Set domain name as a variable
#
RewriteRule .* - [E=domain_name:domain.com]
# Redirect non-secure (HTTP) traffic to secure (HTTPS)
#
RewriteCond %{ENV:HTTPS} !on [NC]
RewriteRule ^(.*)$ https://%{ENV:domain_name}/$1 [R=301,L]
You can just use %{HTTP_HOST} env variable which is already populated by Apache.
RewriteCond %{ENV:HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

Enforce https + remove www + redirect aliases to main domain name on Apache 2

Client site uses several domains leading to the same content, which is bad for SEO ("duplicated content").
example.com, www.example.com, foo.com, foo.example.com, www.foo.com and www.foo.example.com
Also, the site must now use https on all requests.
So the task now is to enforce the sole use of https://foo.example.com as the SSL certificate is for *.example.com. All other domains should be redirected to https://foo.example.com
I'm trying to implement these requirements via url rewriting in the website's root folder .htaccess file.
Rewritecond %{HTTP_HOST} !^example\.com
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
It works, except for one use case: http://example.com
Requests pointing to http://example.com/hello do not get rewritten to the https://example.com.
So I tried
RewriteCond %{HTTPS} !^on [OR]
Rewritecond %{HTTP_HOST} !^example\.com
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
But i get a "redirection loop" error. It means the conditions are always true, but why?
server details
Server: LAMP (Apache 2) on Red Hat Enterprise Linux Server release 6.5
UPDATE
I think my rewriting rules are correct, the issue occurs upstream. System administrator informed me that their network redirects 443 requests to the local machine's :80 port. Also, phpinfo() on a https url shows no presence of SSL flags ( HTTPS= on does not appear in phpinfo()).