httpd local virtualhost example - apache

-- Original post ---
I'd like to setup a dev env to play with some apache features. I'm running httpd on fedora.
I added to hosts local redirects
# cat /etc/hosts
127.0.0.1 example1.com
127.0.0.1 example2.com
# cmkdir /var/www/example1; echo "Hello from /var/www/example1/index.html" > /var/www/example1/index.html
# cmkdir /var/www/example2; echo "Hello from /var/www/example2/index.html" > /var/www/example2/index.html
# cmkdir /var/www/example2/sub ; echo "Hello from /var/www/example2/sub/index.html" > /var/www/example2/sub/index.html
# cvi /etc/httpd/conf/httpd.conf
<VirtualHost _default_:80>
DocumentRoot "/var//www/html"
</VirtualHost>
<VirtualHost 127.0.0.1:80>
DocumentRoot "/var/www/example1"
ServerName example1.com
</VirtualHost>
<VirtualHost 127.0.0.1:80>
DocumentRoot "/var/www/example2"
ServerName example2.com
</VirtualHost>
<VirtualHost 127.0.0.1:80>
DocumentRoot "/var/www/example2/sub"
ServerName sub.example2.com
ServerPath "/sub/"
RewriteEngine On
RewriteRule "^(/sub/.*)" "/var/www/example2$1"
</VirtualHost>
# capachectl -t ; apachectl restart
# curl localhost
Hello from /var/www/html/index.html
# curl example1.com
Hello from /var/www/example1/index.html
# curl example2.com
Hello from /var/www/example2/index.html
# curl sub.example2.com
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">
... ( lots of stuff different from the one i echoed) ...
If I do the same thing in local firefox - localhost works as expected, example1.com works as expected, but sub.example2.com redirects me to example2.com.
Can you please help me to figure out how to configure a local sub-domain? What is missing? Based on https://httpd.apache.org/docs/2.4/vhosts/examples.html I believe what I did is correct.
-- Edit / Update ---
If I follow the advice below from Newbie and change only the rewrite rule, without making any other changes from the setup above:
<VirtualHost 127.0.0.1:80>
DocumentRoot "/var/www/example2/sub"
ServerName sub.example2.com
ServerPath "/sub/"
# RewriteEngine On
# RewriteRule "^(/sub/.*)" "/var/www/example2$1"
</VirtualHost>
I get :
# curl sub.example2.com
curl: (6) Could not resolve host: sub.example2.com
If I
# cat /etc/hosts | grep sub
127.0.0.1 example2.com sub.example2.com
It works as expected
#curl example2.com
Hello from /var/www/example2/index.html
# curl sub.example2.com
Hello from /var/www/example2/sub/index.html
Still this seems to be strange setup. I don't want to create /etc/hosts record for each sub-domain... Shouldn't it be possible to handle this situation only via the httpd VirtualHost setting, without changing the DNS settings locally or even worse - adding C records in the DNS of a domain(if not localhost)? Any hint what I'm doing wrong? How can I get sub.example1.com to work without modifying the dns settings?
Regards,
Pavel

I believe I found out the answer to my question ...
** How to run locally sub-domains?**
/etc/hosts does not support wild cards(*.example2.com) and one needs to setup a local dns proxy server like dnsmasq for example. Otherwise for dev purposes you have to list (and then maintain :/ ) the sub-domains one-by-one in the /etc/hosts for local dev purposes.
How to run the sub-domains via official DNS records for domain ?
Seems laziest approach is to setup DNS settings having:
example2.com A the-server-IP
example2.com MX 0 example2.com
*.example2.com CNAME example2.com
Looking forward to your comments, if there is smarter approach.
If you agree this is the way to go - please accept the answer, so other members know it is the way to go.
Regards, Pavel

Remove the rewrite rule, it is used for redirecting so you have a loop.
<VirtualHost 127.0.0.1:80> DocumentRoot "/var/www/example2/sub" ServerName sub.example2.com ServerPath "/sub/"

Let me know if you run into problems.This dns would be able to work with your regular browsing since for all names it can't resolve it would check with googles dns and save it into its file.
install bind
apt-get install bind9 -y
cd /etc/bind
vim named.conf.options
And uncomment forwarders and two rows bellow and instead of 0.0.0.0 enter google's dns IP (8.8.8.8).
service bind9 restart
vim named.conf.options
zone "YOURDOMAIN NAME" {
type master;
file "db.site.com";
notify yes;
};
cp db.local /var/cache/bind/db.site.com
cd /var/cache/bind/
vim db.site.com
$TTL 604800
# IN SOA admin. admin.itlink.edu. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
IN NS ns.YOURDOMAINNAMEHERE.
IN A 192.168.1.10 replace this with the IP of your PC that has apache installed
ns A 192.168.1.10 replace this with the IP of your PC that has apache installed
www A 192.168.1.10 replace this with the IP of your PC that has
service bind9 restart

Related

Request to apache2 server always redirects to /var/www (Index of /) site

I am currently trying to setup an virtual hosts following this tutorial on DigitalOcean.
The dummy-site I am trying to serve is under /var/www/example/html/index.html. I have not registered an official domain but setup /etc/hosts/ to resolve example.com to the IP address of my server.
I created another conf file called example.conf under /etc/apache2/sites-available and enabled it with sudo a2ensite example.conf and disabled the 000-default.conf.
Now whenever I go to example.com in my browser I get served:
.
This is the same page I would get when directly going to the IP address of my server. Only when I got directly to example.com/example/html I get served the correct index.html.
My current config looks like this:
<VirtualHost *:80>
ServerAdmin admin#example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
And my /etc/hosts file on my laptop like this:
#<ip-address> <hostname.domain.org> <hostname>
<server-ip> example.com
There are some other folders inside /var/www/ as the company I rented the server from had some maintenance sites preinstalled, but that shouldn't matter in this situation. (See edit, this did actually matter).
It feels like I am missing something obvious here, but I can't find a solution for my problem.
Edit:
The obvious thing I was missing, was that 2 additional sites where enabled by default as well.
One had the following contents:
# 10_froxlor_ipandport_<ip-address>.conf
# Created 28.11.2019 21:05
# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.
<VirtualHost <ip-address>:80>
DocumentRoot "/var/www/"
ServerName <predefined Server name>
</VirtualHost>
After disabling all the other sites, the request to example.com actually went to the right index.html.
I figure, that the above enabled site actually matched the request coming from my browser and showed the www root directory.
The obvious thing I was missing, was that 2 additional sites where enabled by default as well.
One had the following contents:
# 10_froxlor_ipandport_<ip-address>.conf
# Created 28.11.2019 21:05
# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.
<VirtualHost <ip-address>:80>
DocumentRoot "/var/www/"
ServerName <predefined Server name>
</VirtualHost>
After disabling all the other sites, the request to example.com actually went to the right index.html.
I figure, that the above enabled site actually matched the request coming from my browser and showed the www root directory.

Interfacing Docker containers apps with an existing Apache web server

I am fairly new to Docker and I have some trouble to understand how to make my "contained" apps accessible from the internet.
[my current configuration] two web sites (in /var/www/html) + standard Apache + some tweeking I would like to be applied to everything new I deploy (headers CSP based rewriting, SSL certificate renewal with Certbot, etc etc). I am fairly happy with my current conf.
[my two apps] Both are standalone applications (only requiring a db).
-official wordpress image. (-> new domain name)
-a django based app packed with a gunicorn server based on this tutorial (-> subdomain of an existing domain )
[the issue] If I bind both apps on, say, ports 8080 and 8000, browsers wont be able to reach it, for DNS servers do not handle ports (from what I understood, correct me if I am wrong). If I bind then on standard ports, I'll have a conflict with my existing Apache.
How would you deal with it? Can I redirect to containers' internal ip with a mod_proxy of some kind? Is there a cleaner-easier-safer way to do it?
<VirtualHost *:443>
ServerName sub.mydomain.io
Redirect "/" "http://172.17.0.2/"
ErrorLog /var/log/apache2/error.zarebski.io.com.log
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/mydomain.io/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.io/privkey.pem
</VirtualHost>
In case of multiple applications running on different ports and different local IP addresses the recommended method is using Reverse Proxy
Basically you configure your apache to forward requests to those services, i.e.:
<VirtualHost *:443>
ServerName sub.mydomain.io
ProxyPass "/wordpress" "http://172.17.0.2:8080/"
ProxyPass "/django" "http://172.17.0.2:8000/"
ErrorLog /var/log/apache2/error.mydomain.io.com.log
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/mydomain.io/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.io/privkey.pem
</VirtualHost>
If you have multpile external domain you can use Name Based Virtual hosts
Well, it took me a while to figure things out, for there was two main corner cases. I'll stick to one case: the wordpress image
<VirtualHost *:443>
ServerName new_domain.eu
ProxyPass / http://localhost:8081/
<Location />
AddOutputFilterByType SUBSTITUTE text/html
SetOutputFilter proxy-html
ProxyPassReverse /
Substitute "s|http://localhost:8081/|https://new_domain.eu/|i"
RequestHeader unset Accept-Encoding
</Location>
SSLCertificateFile /etc/letsencrypt/live/new_domain.eu/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/new_domain.eu/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
[First of all], I could not access container from their local ip (i.e 172.7.0.3:80, not sure why), so I used the localhost port defined while setting the container up:
docker run -e WORDPRESS_DB_PASSWORD=thePassWord --name wordpress --link wordpressdb:mysql -p 8081:80 -v "$PWD/html":/var/www/html -d wordpress
[secondly] the tricky part was, then, to handle properly relative urls (e.g. some/path/to/css), for these were not accessible. Apparently, this is a well known issue. This part was the longest: things changed a lot around Apache 2.4 and the syntax is not well documented. Basically,
Substitute "s|http://localhost:8081/|https://new_domain.eu/|i"
replace all urls in html so that relative resources (css, js, png, etc etc) could be properly accessed.
[possible improvements] I am not quite happy with port 8081 being visible from the external world. It means that the app could be accessed from this very port, bypassing the rules I setted up in apache.conf. I fixed the issue by adding an iptables rule
iptables -A INPUT -p tcp -s localhost --dport 8081 -j ACCEPT
iptables -A INPUT -p tcp --dport 8081 -j DROP
Not quite elegant so if anyone has a suggestion, let me know.
\//_

Multiple vhosts on one and the same docker container

I'm trying to run two different domains on one and the same Docker container and port.
The Docker container runs CentOS. docker-compose.yml looks like so:
web:
image: fab/centos
ports:
- "80:80"
volumes:
- ./src/httpd.conf:/etc/httpd/conf/httpd.conf
- ./src:/var/www/html
- ./src/hosts:/etc/hosts
environment:
- VIRTUAL_HOST=dummy.dev,tests.dev
I also declared both .dev domain names inside of /etc/hosts on the host computer (OS X.)
It's been a while since I configured virtual hosts. My understanding was that I just needed to declare them and that Apache would automatically serve the proper files depending on the HTTP HOST being requested.
This is what I have, added at the end of httpd.conf:
<VirtualHost *:80> # first host = default host
DocumentRoot /var/www/html/default
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/dummy
ServerName dummy.dev
ServerAdmin webmaster#dummy.dev
ErrorLog logs/dummy.dev-error_log
CustomLog logs/dummy.dev-access_log common
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/tests
ServerName tests.dev
ServerAdmin webmaster#tests.dev
ErrorLog logs/tests.dev-error_log
CustomLog logs/tests.dev-access_log common
</VirtualHost>
However, in practice, visiting either dummy.dev or tests.dev actually serves /var/www/html/default. This is as if Apache didn't realize which host is being called (though a dump of $_SERVER in PHP does show the expected HTTP_HOST value, i.e.: either 127.0.0.1, dummy.dev or tests.dev depending on which URL I visit.)
What did I miss?
It's unclear to me whether this is an Apache issue or a Docker one.
(Please note this is a different question from how to host multiple apps on the same domain with different port. In my case, I do want the virtual hosts to be all inside/on the same app/port/container.)
Turns out this was an Apache configuration issue.
I needed to explicitly enable domain-named virtualhosts, like so:
NameVirtualHost *:80
This answer helped.
Docker had nothing to do with the matter.
The fab/centos does not exist in public docker hub, so not sure why you are experiencing the issue.
My recommendation would be to take a step back and try to make it work with a simple example.
docker search apache yields eboraas/apache as most starred image, so I'll use that one for the example.
In a test directory, use your sample:
File: httpd.conf
<VirtualHost *:80> # first host = default host
DocumentRoot /var/www/html/default
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/dummy
ServerName dummy.dev
ServerAdmin webmaster#dummy.dev
ErrorLog logs/dummy.dev-error_log
CustomLog logs/dummy.dev-access_log common
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/tests
ServerName tests.dev
ServerAdmin webmaster#tests.dev
ErrorLog logs/tests.dev-error_log
CustomLog logs/tests.dev-access_log common
</VirtualHost>
Then create the vhost websites & the logs directory.
mkdir -p logs; for i in default tests dummy; do mkdir -p $i; echo "hello $i" > $i/index.html; done
Finally, run docker.
docker run -it -v $(pwd):/var/www/html -v $(pwd)/httpd.conf:/etc/apache2/sites-available/000-default.conf -v $(pwd)/logs:/etc/apache2/logs -p 9090:80 --rm --name apache_c eboraas/apache
Note that I use basically the same volumes as you did in your docker-compose.yml, except that I use site-available instead of changing the httpd.conf.
To test, make sure you have tests.dev and dummy.dev in your /etc/hosts pointing at the right Docker IP and test:
$> curl dummy.dev:9090
hello dummy
$> curl tests.dev:9090
hello tests
From this point, build up on top of this by first trying the docker apache image that you are using, then try with your custom /etc/hosts file, then put it back in a docker-compose file
Turn on NameVirtualHost in your httpd config:
File : /etc/httpd/conf/httpd.conf
NameVirtualHost *:80
NameVirtualHost *:443

Set up Apache with multi-domain server with OVH

My question is related to the wrong redirection of multi-domain server.
I have a VPS server on ovh.com with 2 domains names:
site1.com
site2.com
On OVH admin panel, I have set up the DNS zone so that each site return to the IP adress of the server with a type A. Each www.siteX.com have for targetsiteX.com with a type CNAME.
On the server side, I'm using Apache2 and I have created for all a conf file in /etc/apache2/site-available/:
site1.conf
site2.conf
with the same structure:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
ServerName siteX.com
ServerAlias www.siteX.com
DocumentRoot /var/www/siteX
</VirtualHost>
Then I have used the command a2ensite subX.conf or a2ensite siteX.conf and sudo service apache2 restart
The problem I have is that www.site2.com is redirected to site1.com while site2.com is correct and return site2.
The interesting aspect is that www.site2.com? is correctly loading the content of site2 while keeping the www.site2.com/? in the url.
Again, similar to Sub-domain not working, the solution was to disable the default virtualserver:
sudo a2dissite 000-default
Can someone explain the reason ? How to avoid that ?

Connection to localhost fails

I set up /etc/apache2/extra/httpd-vhosts.conf as follows:
# Ensure that Apache listens on port 80
Listen 80
# Listen for virtual host requests on all IP addresses
NameVirtualHost *:80
<VirtualHost *:80>
ServerName localhost
DocumentRoot /Library/WebServer/Documents/
</VirtualHost>
In /Library/WebServer/Documents/ is the standard index.html.en file which was shown perfectly in the browser before I included the httpd-vhosts.conf into my httpd.conf.
The connection to localhost fails using both, Chrome and Firefox. Is the setup correct? What else could go wrong?
I solved the problem. I couldn't state further information because I just didn't know where I could look for the problem. This post put me in the right way:
http://macosx.com/forums/mac-os-x-system-mac-software/299851-apache-wont-start-up.html
sudo apachectl configtest
Gave me an syntax error within the httpd.conf file. After fixing it everything worked. The important thing is the opportunity to run a configtest.