0

Running apache 2.2.6. I'm setting up a development environment.

dev and production will be hosted on the same machine, same IP address.

DNS entries like prod.domain.com and dev.domain.com point to the same IP.

*** Imprortant: it is required that dev and prod are otherwise completely separate. Each will run it's own apache instance. Each will use it's own apache configuration.

Each, prod and dev, will host http and https.

I have this set up and working, but not as restrictive as I'd like.

For instance, the production config:

NameVirtualHost *:80
NameVirtualHost *:443

<VirtualHost *:80 >
  ServerName prod.domain.com
  # ... etc
</VirtualHost>

<VirtualHost *:443 >
  ServerName prod.domain.com
  # ... etc
</VirtualHost>

The dev site is set up similarly, using ports 8080 and 4443.

Each site works fine. But assuming both apaches are running, one can also hit "cross-site" by mistake. So, inadvertently hitting prod.domain.com:8080 successfully returns a page from the dev site. It would be much better if this failed completely.

This is a bit more difficult to solve (for me) because of the need for two apache configs. If all in one, the single process would have full knowledge of everything.

So, I tried to solve this with brute force, including virtual hosts for the "other" site, with something that would fail, like no access to documentroot. But apache then inexplicably finds the "wrong" virtual host.

Here's the full config for production, with the dummy dev configs.

NameVirtualHost *:80
NameVirtualHost *:443

# ----------------------------------------------
# DUMMY HOSTS

<VirtualHost *:8080 >
  ServerName dev.domain.com:8080
  DocumentRoot /tmp/
  <Directory /tmp/ >
    Order deny,allow
    Deny from all
  </Directory>
</VirtualHost>

<VirtualHost *:4443 >
  ServerName dev.domain.com:4443
  DocumentRoot /tmp/
  <Directory /tmp/ >
    Order deny,allow
    Deny from all
  </Directory>
</VirtualHost>

# ----------------------------------------------
# REAL PRODUCTION HOSTS

<VirtualHost *:80 >
ServerName prod.domain.com:80
DocumentRoot /something/valid/
<Directory /something/valid/>
  Order allow,deny
  Allow from all
</Directory>
</VirtualHost>

<VirtualHost *:443 >
ServerName prod.domain.com:443
DocumentRoot /something/valid/

<Directory /something/valid/>
  Order allow,deny
  Allow from all
</Directory>

#  .... other valid ssl setup

</VirtualHost>

Here's the strange thing. With this configuration, a prod.domain.com:80 hit succeeds. But a prod.domain.com:443 hit fails, because it finds the dev.domain.com:4443 instead. I've also tried removing the port from the ServerName, but it still doesn't work.

Sorry for the long question. Hopefully this is enough information. Thanks in advance for any help.

2
  • Did you check to make sure another config file isn't be processed? /etc/apache2/conf.d /etc/apache2/extras /etc/apache2/sites-enabled /etc/apache2/httpd.conf /etc/apache2/apache2.conf are some of them to watch for it
    – Jeremy L
    Mar 3, 2010 at 2:57
  • Thanks. Yes, no other configs. Config is specified explicitly in apachectl -- each environment has it's own apachectl, and everything is fully pathed.
    – joe
    Mar 3, 2010 at 4:03

3 Answers 3

2

My condolences to you for having to use the same physical system for development and production. That sounds awkward. Also makes testing Apache with a newer OS installation tough.

The ports used on the development server are not specified with the NameVirtualHost, so Apache doesn't match them using virtual hosting. Try:

NameVirtualHost *:80
NameVirtualHost *:443

<VirtualHost *:80>
  ServerName dev.domain.com
</VirtualHost>

<VirtualHost *:443>
  ServerName dev.domain.com
</VirtualHost>

<VirtualHost *:80>
ServerName prod.domain.com
</VirtualHost>

<VirtualHost *:443>
ServerName prod.domain.com
</VirtualHost>

To block accidental cross-site linking, you can use mod_rewrite to block access from the other server. So the production server will deny access from the development server (hostname), and vise-versa. An article with some details on the mod_rewrite engine.

Otherwise block the development server's IP address either with an external / existing firewall, or by using a netfilter / iptables ACL rule, so users from the Internet (or end-users) cannot access it.

2
  • Thanks! My apologies, I mucked up the config I posted. I actually had the ports specified exactly as you say. All works, but so does inadvertent cross-site. I believe what I want to do is possible, but I need to upgrade Apache2 from 2.2.6 to 2.2.12, and openssl to 0.9j. According to information in the Apache2 mod_ssl FAQ: httpd.apache.org/docs/2.2/ssl/ssl_faq.html#vhosts2 NameVirtualHost relies on the client sending a Host: entry in the header. But older apache/ssl doesn't have ability to see that in the SSL layer. No host entry means first config w/port is used. Thanks again!
    – joe
    Mar 3, 2010 at 6:20
  • If that fixes your problem, you can submit your own answer (solution) to your question. Also, please consider editing your question to correct the mistake with the ports, and perhaps re-word the last paragraph to clarify that the SSL access is/was broken. Good luck.
    – mctylr
    Mar 3, 2010 at 23:13
0

What about using ServerAlias directive to make sure someone doesn't drop the prefix?

0

You can also use mod_rewrite for your original problem. For example, here is what you could add to the "prod" virtual host configuration :

RewriteEngine On
RewriteCond %{HTTP_HOST} !=prod.domain.com.
RewriteRule ^(.*)$ - [F,L]

The RewriteCond will match any HTTP request whose requested host is not prod.domain.name, and the RewriteRule will answer the request with a 403 HTTP error code (Forbidden). F is for "forbidden". That way, if someone tries to access dev.domain.com and apache still wants to serve the "prod" website, the request will be answered with a 403 error code.

You must log in to answer this question.