Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

We have a forward-facing linux box running Apache HTTP server that is acting as a reverse proxy for several back-end servers. The servers are accessed through specific domain names and ports and are set up as virtual hosts within Apache as such:

Listen 8001
Listen 8002

<Virtualhost *:8001>
    ServerName service.one.mycompany.com

    ProxyPass / http://internal.one.mycompany.com:8001/
    ProxyPassReverse / http://internal.one.mycompany.com:8001/

    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
    RewriteRule .* - [F]
</Virtualhost>

<Virtualhost *:8002>
    ServerName service.two.mycompany.com

    ProxyPass / http://internal.two.mycompany.com:8002/
    ProxyPassReverse / http://internal.two.mycompany.com:8002/

    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
    RewriteRule .* - [F]
</Virtualhost>

The proxy server has only one IP address, and both domains are pointing to it. Accessing internal.one via service.one works fine, as does accessing internal.two via service.two.

Now the problem is that Apache does not take the requesting domain into account when accessing the virtual hosts. What I mean is that both domains work for both ports: requests for service.one:8002 proxies to internal.two:8002, and requests for service.two:8001 proxies to internal.one:8001, where ideally both these requests should be denied.

I can get around this by creating more virtual hosts that explicitly deny these requests:

NameVirtualHost *:8001
NameVirtualHost *:8002

<Virtualhost *:8001>
        ServerName service.two.mycompany.com
        Redirect permanent / http://errorpage.mycompany.com/
</Virtualhost>
<Virtualhost *:8002>
        ServerName service.one.mycompany.com
        Redirect permanent / http://errorpage.mycompany.com/
</Virtualhost>

But this is not an ideal solution, since we plan to add more services to the proxy, and each new port would need to be explicitly denied on all the other domains, and each new domain would need to be explicitly denied on all ports it is not utilizing. As we add more services, the number of virtual hosts can get out of hand quickly.

My question, then, is whether there is a better way? Can we explicitly tie specific ports to specific domains in a virtual host so that only that domain-port combination is processed, and all other combinations are not?

Things I’ve tried:

  • Adding NameVirtualHost *:8001, etc. without the additional virtual hosts.
  • Setting ProxyRequests On and Off, as well as ProxyPreserveHost On and Off
  • Adding the server name or IP address to the virtual host header, e.g. <VirtualHost service.one.mycompany.com:8001>
  • Using the <proxy> directive inside the virtual host directive.
  • Lots and lots of googling.

The proxy server is running CentOS 6.2 64-bit, Apache HTTPD server 2.2.15. As mentioned, the proxy server has only one IP address, and all the domains we are using are pointing to it.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

Apache is always going to want a default fallback for a given port, which is what you are seeing now. So even though the servername doesn't match, it is its last/only resort. That is the reason why there is a 000-default catch-all as standard.

You could use mod_rewrite in the vhost config to explicitly block/redirect any domain that doesn't match.

RewriteCond %{SERVER_NAME} !my.domain.com
RewriteRule (.*)$ http://my.domain.com$1 [L,R=301]
share|improve this answer
    
Thanks for the explanation, I understand it a bit better now. When I use the above rewrite rules, though, I get redirect loops. It seems %{SERVER_NAME} isn't being passed as I expect it to be. Adding <VirtualHost _default_:*> also doesn't seem to affect anything. I have a few more ideas now, though, so I'll keep plugging away at it. –  theJoe Jun 28 '12 at 13:18
    
Try using %{HTTP_HOST} - but the theory is the same. And for a default vhost, you can just use <VirtualHost *> –  MageStackDay Needs You ... Jun 28 '12 at 13:29
    
Using <VirtualHost *> accepts everything, but it's working now using the redirect rules and %{HTTP_HOST}. This will remove the need for the additional virtual hosts. Thanks, I will mark this as answered. –  theJoe Jun 28 '12 at 17:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.