virtual host not working when cloudflare is enabled - apache

Before cloudflare, I was able to access the phpMyAdmin link such as
example.com/ctrl/pmasetup
After CloudFlare, I get a 403 (coming from my own apache server, not CloudFlare's error page)
Forbidden
You don't have permission to access /ctrl/pmasetup on this server.
I feel like I need to add the CloudFlare's reverse proxy somewhere on the server, which I did in /etc/hosts which now looks like:
127.0.0.1 localhost localhost.localdomain
104.25.68.32 example.com <- This is the ip of my site when CloudFlare is enabled on it
I also added it in httpd.conf in the virtual host config:
<VirtualHost *:80>
ServerAdmin support#example.com
DocumentRoot /var/www/example.com
ServerName example.com
ErrorLog logs/example.com-error_log
CustomLog logs/example.com-access_log combinedio
Alias /ctrl /var/www/ctrl
<Location /ctrl>
<RequireAny>
Require all denied
Require ip {my ip}
Require ip 104.25.68.32 <- CloudFlare IP, again
</RequireAny>
</Location>
#Header always set Access-Control-Allow-Origin "http://example.com"
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "*"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
</VirtualHost>
Edit: Even when commenting the entire RequireAny block, I still get a 403 when CloudFlare is enabled.
Edit 2: if inside the location tag I ONLY have Require all granted, then it works. So, how can I disallow everybody BUT the few IP's I put initially?
Edit 3: It most likely is because CloudFlare changes your IP as a visitor, then my apache config doesn't recognize it. Any idea?

EDITED -- See below;
I believe you should allow cloudflare's ip ranges to access the site. After all, the request comes from cloudflare not the client.
CloudFlare's ip ranges can be found on their website at:
https://www.cloudflare.com/ips/
They also provide an easy "text/plain" format following both theses urls:
CloudFlare IPv4 Ranges & CloudFlare IPv6 Ranges
There's also a little tool i know of, for nginx tho, available at:
https://www.8ball.me/nginx/ngx-cfips.zip
EDIT -- I've created a new version since this post. Today actually (2017.05.31). The url is still valid. It's got a --help function detailing how to setup as a cronjob and include into nginx. Same CloudFlare urls are used.

When there is an option denying I believe you need to use RequireAll instead of RequireAny (since RequireAny is the default behaviour in 2.4 so there is no need to specify it like you do). Try it.

Related

change ip address to domain name without redirect

I've been surfing for hours and I have not seen an answer that properly resolves my problem.
I have two pages in two different servers. They have to stay that way. One server has a domain name "domain.com" that show one web and it has a button with a link to the other server with the page ip:port/directory/page.php.
What i need is that, in the second server, even if it's coming from the first server or by direct access,the page always shows in the URL bar as domain.com/page.php, not ip:port/directory/page.php.
I've tried with virtualhost in the first server's httpd-vhost.confarchive, and changing the .htaccess file in ip:port/directory/ with RewriteRule, but nothing properly works.
Thanks for the advice and sorry for my English.
Finally solved using proxypass and proxyreverse in httpd.conf:
ProxyRequests off
ProxyPass /first_server_folder/ http://ip:port/second_server_folder/
ProxyPassReverse /first_server_folder/ http://ip:port/second_server_folder/
<Location /first_server_folder/>
ProxyPassReverse /
RequestHeader unset Accept-Encoding
</Location>

How to protect my server from false proxy requests

I have a website, call it
http://www.example.com
Users create a site for themselves and they each get a sub-domain automatically, so something like
http://user1.example.com
http://user2.example.com
In addition, some users can use their own domain name, by creating a A-Record in their domain name DNS setup to point to my server's IP address.
http://www.myownname.com > 10.10.10.10 (my site's server IP address)
In my Apache VirtualHost, it's set up as follows
<VirtualHost 10.10.10.10:80>
ServerName www.example.com
ServerAlias *
UseCanonicalName Off
DirectoryIndex index.php index.html
DocumentRoot /home/public/
<Directory /home/public/>
Require all granted
Allowoverride ALL
</Directory>
</VirtualHost>
Line "ServerAlias *" is there so that I can catch any domain name pointing to my IP address and then handle it via my site.
Everything is working well up to this point.
Now, recently, I've checked my Apache access log and I see strange access such as follows
10.10.10.10 - - [25/Jul/2014:12:48:04 -0700] "GET http://www.some-random-site.com/ HTTP/1.0" 200 1456
It looks like someone is trying to use my server as a proxy to access other sites. I've read quite a few pages in order to block this proxy requests (e.g. https://wiki.apache.org/httpd/ProxyAbuse)
For example, if I use "default virtual host" to block everything except what's specified in my virtual host, all the custom domain names pointing to my server's IP address doesn't work anymore. But it does block the proxy requests.
How can I block proxy requests, while still being able to allow custom domain names via A-Record (or CNAME) pointing to my IP address?

ProxyPreserveHost seems to do little for me

I see many on the web referring to the use of ProxyPreserveHost On to make sure that a proxied backend receives the original caller's host name. I am using this to tighten my web application's security (Java, Tomcat) whereas it would also be nice if my logs would show where users are actually at. My Tomcat logs now show this – pretty useless:
127.0.0.1 - - [17/Mar/2013:06:32:13 +0100] "GET /webapp/frontend/app/partials/welcome.html HTTP/1.1" 200 54
This is my configuration that does clearly not work as expected:
"/etc/apache2/sites-enabled/000-default"
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass /webapp http://localhost:8080/webapp
ProxyPassReverse /webapp http://localhost:8080/webapp
RewriteEngine On
RewriteRule ^/$ /webapp/frontend/app/ [proxy]
RewriteRule ^/webapp/$ /webapp/frontend/app/ [redirect]
RewriteRule ^/webapp/app/$ /webapp/frontend/app/ [redirect]
(from here on default stuff that was in the 000-default)
Enabled modules:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod rewrite
This is Ubuntu 12.10 running Apache HTTPD 2.2.22.
Your help would be much appreciated.
I assume your concern is that your access log still contains 127.0.0.1 in the client field. This isn't affected by ProxyPreserveHost; this is the IP address of the network end point that connected to Apache. For proxied connections from another server, this is going to always be localhost.
Also, ProxyPreserveHost is about preserving the Host header sent by the client, not about preserving the original IP of the client. In other words, it's about information going the wrong direction for your purposes; it's preserving the name of your server as sent by the client, not the client's IP.
I think your question is the same as this question. I'd add the additional note that you can log the X-Forwarded-For header in your logs using %{X-Forwarded-For}i in your CustomLog configuration.

Apache domain redirect between virtualservers

I've got one dedicated server which I splitted into more virtual servers.
On main server I use standard port for http (80), but for others I was forced to set different ports.
But I've got some spare domains.
What is best way to make invisible redirect to another server when user come through specific domain?
I don't want to use iframes or redirect to another website. I would like domain to act like on shared web hostings. But with different servers.
Is it possible to do?
I know that apache gets information about from which domain user came.
I would like to do it with virtual hosts if it's possible.
<VirtualHost *>
ServerName mydomain
ServerAlias mydomain
some redirection
CustomLog /var/log/apache2/mydomain.access.log combined
ServerAdmin myemail
</VirtualHost>
Thanks in advance :]
Since you have access to the server's config, take a look at the ProxyPass, ProxyPassMatch, and ProxyPassReverse directives that are part of mod_proxy. You'll need to make sure the module is loaded before you can use these directives.
In general, in your mydomain config, say you want to have visitors see the site at http://myother.domain.com/ when they go to http://mydomain/other, you'd just add:
ProxyPass /other http://myother.domain.com/
ProxyPassReverse /other http://myother.domain.com/
The ProxyPassReverse is to ensure proxied location responses get rewritten. For example, if a page at http://myother.domain.com/ returned a 301 redirect to http://myother.domain.com/newimage.gif, this directive will internal rewrite the response's location from http://myother.domain.com/newimage.gif to http://mydomain/other/newimage.gif, for it to be proxied again.
If you have cookie domains that also need rewriting, take a look at ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath.

Why should we create A DNS record for subdomains when we can do it via httpd.conf?

I want to implement a blog in my site with usernames as subdomains like user1.domain.com.
I've read bunch of articles that was mentioned to create an A record like below in DNS:
*.domain.com A 127.0.0.1 ;OR you site ip address
Then use .htaccess to redirect requests from subdomains to a folder in your server.
But I find another approach that was said to just modify your httpd.conf as below:
<VirtualHost *:80>
DocumentRoot /abs/path/to/webroot
ServerName domainname.com
ServerAlias *.domainname.com
<Directory /abs/path/to/webroot>
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Then retrieve subdomains via $_SERVER['HTTP_HOST'].
The question is why should someone use htaccess and put pressure on apache and create A DNS record when we can do a simple thing like ServerAlias *.domainname.com in httpd.conf?
I appreciate in advance for your views.
You need to setup both a wildcard DNS record and configure a server alias in httpd.conf to enable the hosting of arbitrary sub domains. They configure completely different things.
Add the wildcard DNS records is what allows clients to determine the IP address of your sub domain. With the wildcard DNS record about user1.domain.com will resolve to 127.0.0.1. If you do not have a DNS record no user1.domain.com will not be a valid name and it will not resolve to an IP address. the DNS record is to allow clients to connect to your server.
The httpd.conf configuration is local to your Apache server. It does not affect clients. The line ServerAlias *.domainname.com will configure Apache to tell it to process the arbitrary sub domains. Client's will not be directly affected by this setting.
You have added the ServerAlias, but for your computer to find that user1.domain.com and user2.domain.com should resolve to 127.0.0.1, you need to update your HOSTS file or DNS Table.
The configuration you have written is for Apache Server for handling the redirects when the user requests the domain. So, essentially, either you need a Dynamic HOSTS file or a service which resolves *.domain.com to your 127.0.0.1 server.
Hope this helps. :)