Author Topic: Tip: usercorner (port 8888) redirect to new subdomain at port 443 with mod_proxy  (Read 8978 times)

mwellnitz

  • Zen Apprentice
  • *
  • Posts: 10
  • Karma: +2/-0
  • http://www.fragen-sie-ihren-administrator.de/
    • View Profile
    • Marcus Linux Blog
It took me nearly 2 days to solve the above issue with zentyal but now it works and i want to share it with you.

The goal
the usercorner (port 8888) has to be redirected to an extra subdomain (port 443) at the same IP address as the current

The plan
First we have to define some dependencies for the specific environment. For this HowTo I take the following:

The solution

create a proxy statement
A ProxyPass/ProxyPassReverse statement will also lead to a running solution but I like that balancer features
Code: [Select]
    <Proxy balancer://usercorner>
        BalancerMember https://localhost:8888/
    </Proxy>
   <Location / >
       ProxyPass balancer://usercorner/
       Order allow,deny
       Allow from all
   </Location>

extend apache module list
a2enmod headers proxy proxy_balancer proxy_connect proxy_html rewrite ssl
apache2ctl graceful

Proxy SSL
To allow access to https://localhost you have to enable SSLProxyEngine. Otherwise you can only connect via http://
Code: [Select]
SSLProxyEngine On
redirect '/' to '/Login/Index'
I don't know why, but when I try to login via '/' after successful login I will be redirected the login again. Starting from '/Login/Index' will have success.
Code: [Select]
        RewriteEngine On
        RewriteRule ^/*$ /Login/Index [R]

password change is only possible via changed referer header
To avoid man in the middle attacks zentyal will deny password changes if the referer header does not match the zentyal connection. (Thanks for the Zentyal Guys for that nice feature but we will break this feature, now)
In our case zentyal will be connected via https://localhost:8888 but the browser will send the referer header https://security.foobar.com.
apaches mod_header can do the trick:
Code: [Select]
        RequestHeader edit Referer security\.foobar\.com localhost:8888 early
        Header edit Location ^https://localhost:8888(/.*)$ https://security.foobar.com$1

Certificates
To avoid certificate errors i recommend to use a wildcard certificate.
Code: [Select]
        SSLEngine on
        SSLCertificateFile    /etc/apache2/ssl.pem/foobar.com/foobar.com.crt
        SSLCertificateKeyFile /etc/apache2/ssl.key/foobar.com/foobar.com.key
        SSLCertificateChainFile /etc/apache2/ssl.crt/ca/foobar.com.ca-bundle

And now the solution
EDIT: while using /etc/apache2/conf.d I had problems with the other vhosts at that domain while extending /etc/apache2/sites-available/ the whole stuff works as espected.
Code: [Select]
## create a file /etc/apache2/sites-available/security.foobar.com.conf
SSLProxyEngine On
<VirtualHost security.foobar.com:443>
        ServerAdmin admin@foobar.com
        ServerName security.foobar.com
        DocumentRoot /srv/www/security.foobar.com
        ErrorLog /var/log/apache2/security.foobar.com-error.log
        CustomLog /var/log/apache2/security.foobar.com-access.log combined
        RewriteEngine On
        RewriteRule ^/*$ /Login/Index [R]
        RequestHeader edit Referer security\.foobar\.com localhost:8888 early
        Header edit Location ^https://localhost:8888(/.*)$ https://security.foobar.com$1
    <Proxy balancer://usercorner>
        BalancerMember https://localhost:8888/
    </Proxy>
   <Location / >
       ProxyPass balancer://usercorner/
       Order allow,deny
       Allow from all
   </Location>
        SSLEngine on
        SSLCertificateFile    /etc/apache2/ssl.pem/foobar.com/foobar.com.crt
        SSLCertificateKeyFile /etc/apache2/ssl.key/foobar.com/foobar.com.key
        SSLCertificateChainFile /etc/apache2/ssl.crt/ca/foobar.com.ca-bundle
</VirtualHost>
Now, you have to enable the new site and restart apache.
Code: [Select]
a2ensite security.foobar.com.conf
apache2ctl restart
comments or improvements are welcome
« Last Edit: July 17, 2013, 09:18:15 am by mwellnitz »
Marcus Wellnitz

christian

  • Guest
That's interesting although I'm doubtful.

Above the general idea that is to share some trick you have deployed (BTW thanks a lot for this) I wonder if technical approach is the correct one.

I was first puzzled with the "extra subdomain" wording until I understood this is not really domain or subdomain but vhost  :-[ I know the subdomain wording is widely used to describe the leftest part of URL but such concept really can't hit me. If I do not make this translation (and effort) from subdomain or domain to host or vhost, I'm often lost. Anyway...

Default listening port for user corner is 8888 so I suppose your proposal to redirect 445 is because you have already customized this, am I correct ?
Furthermore it can't be changed to 443 because default server is already listening on this port but another vhost (as you rightly suggest with your reverse proxy configuration) can do this.

I'm, like you, promoting use of reverse proxy but I wonder if this makes sense for service that is running locally.
I mean, from pure technical standpoint (I didn't investigate what you describe), can't same feature be achieved creating vhost (using Zentyal GUI) and configuring this vhost to point to the right place ?

Very positive aspect of your post is that it shows that reverse proxy can be used to redirect HTTP requests and also rewrite parts, therefore providing great control over what goes through this reverse proxy  :)

One more question if you don't mind  ;)

What's this "certificate error" you describe ?

christian

  • Guest
BTW, what would be nice is that Zentyal provides, like they do for webmail, capability to configure user corner either with default configuration (i.e. as it is today) or using vhost.

mwellnitz

  • Zen Apprentice
  • *
  • Posts: 10
  • Karma: +2/-0
  • http://www.fragen-sie-ihren-administrator.de/
    • View Profile
    • Marcus Linux Blog
Hello Christian,

That's interesting although I'm doubtful.

Above the general idea that is to share some trick you have deployed (BTW thanks a lot for this) I wonder if technical approach is the correct one.
Please test some other approaches. I will be verry pleased if there ist an easy way to get it running
I was first puzzled with the "extra subdomain" wording until I understood this is not really domain or subdomain but vhost  :-[ I know the subdomain wording is widely used to describe the leftest part of URL but such concept really can't hit me. If I do not make this translation (and effort) from subdomain or domain to host or vhost, I'm often lost. Anyway...
In this case I really want to have a new subdomain (yes, technical implemented as vhost) because we have multiple customers with different domains, services and servers. Some services are provided via the above described Zentyal machine and port 443.
So i want to provide a new unique subdomain to all our customers to give them the ability to change their passwords.
A lot of big companies provide internet access to their employes but do not allow access to ports other than 80 and 443.
So I tried to figure out how to access the usercorner via internet, port 443 and an unique subdomain.
Additionally, an unique Domain cant't work because you have to implement unique certificates and browsers without tls feature will get certificate errors when you try to access different domains at the same IP and port.
Default listening port for user corner is 8888 so I suppose your proposal to redirect 445 is because you have already customized this, am I correct ?
Furthermore it can't be changed to 443 because default server is already listening on this port but another vhost (as you rightly suggest with your reverse proxy configuration) can do this.
Thanks for the hint. I can't remember changing the port but i think you're right. I alredy changed it.
I'm, like you, promoting use of reverse proxy but I wonder if this makes sense for service that is running locally.
I mean, from pure technical standpoint (I didn't investigate what you describe), can't same feature be achieved creating vhost (using Zentyal GUI) and configuring this vhost to point to the right place ?
As you can see in my post some deep changes have to be made insight the vhost configuration to get it running with the usercorner. I didn't do a test within zentyal and its vhost feature but in the past i got some bloddy nose when modifiying zentyal created configuration files. So I decided to go a safe way ;-)
At the first impression you're right simply use a vhost and point it to the right place. But when zentyal do some miner changes your configuration will fail. Additionally in our environment we often make use of the reverse proxy feature to prevent application servers to be attacked directly from the internet. With this configuration I'm able to move the configuration to an other server and it will work out-of-the-box, I'm right?
Very positive aspect of your post is that it shows that reverse proxy can be used to redirect HTTP requests and also rewrite parts, therefore providing great control over what goes through this reverse proxy  :)

One more question if you don't mind  ;)

What's this "certificate error" you describe ?
There are two techniques to get encrypted http connections known as 'ssl' and 'tls'.
The new one is 'tls' but It's not supported by a wide range of common (mostly older) browsers. Tls can handle multi domains because the encryption will start at a later communication level but ssl don't.
When a ssl connection will be initiated, first the connection will be secured and then the URL will be send to the server. Therefore the Server has to deliver it's certificate before the client told him which domain he want to contact. The client (Browser) verifies the certificate against the URL. If you are running multiple vhost with different domains only one Domain can be handled correctly via the ssl stack.
I'm right?
With one exception:
If all your domains are subdomains of the same domain and you are providing the same wildard certificate each connection is valid from the browser point of view.
In any other ssl-case (I hope) you will get a certification error (Invalid certificate ... bla, bla, bla...)
« Last Edit: July 12, 2013, 07:54:57 am by mwellnitz »
Marcus Wellnitz

mwellnitz

  • Zen Apprentice
  • *
  • Posts: 10
  • Karma: +2/-0
  • http://www.fragen-sie-ihren-administrator.de/
    • View Profile
    • Marcus Linux Blog
BTW, what would be nice is that Zentyal provides, like they do for webmail, capability to configure user corner either with default configuration (i.e. as it is today) or using vhost.
!THUMBS-UP!
Marcus Wellnitz

christian

  • Guest
We are in line and my points are only minor, almost to be seen as nitpicking (which is not my aim) or rather willingness to clarify details.

In this case I really want to have a new subdomain (yes, technical implemented as vhost) because we have multiple customers with different domains, services and servers. Some services are provided via the above described Zentyal machine and port 443.
So i want to provide a new unique subdomain to all our customers to give them the ability to change their passwords.

Clear enough... let me explain further what I meant:
you want to provide access to https://secure.whatever_domaine/
so far so good. What I'm fighting against is to call this "subdomain". That's it and, at the end, it doesn't matter and should not be seen as blocking point in our debate but I'm convinced that using the right wording helps getting structured ideas, especially for admins not having everything clear in mind (and you are obviously not in this category  ;))
in above URL, what_ever_domain is THE domain and secure is either host or vhost matching either A or better CNAME  record in DNS.
If you had to provide access to URL like:
https://secure.something.whatever_domain/, then something will be the real subdomain.

Quote
There are two techniques to get encrypted http connections known as 'ssl' and 'tls'.
The new one is 'tls' but It's not supported by a wide range of common (mostly older) browsers. Tls can handle multi domains because the encryption will start at a later communication level but ssl don't.
When a ssl connection will be initiated, first the connection will be secured and then the URL will be send to the server. Therefore the Server has to deliver it's certificate before the client told him which domain he want to contact. The client (Browser) verifies the certificate against the URL. If you are running multiple vhost with different domains only one Domain can be handled correctly via the ssl stack.
I'm right?

I fully share, except for what concerns, again, your "domain" wording  ;)

Quote
With one exception:
If all your domains are subdomains of the same domain and you are providing the same wildard certificate each connection is valid from the browser point of view.
In any other ssl-case (I hope) you will get a certification error (Invalid certificate ... bla, bla, bla...)

yes and no  ;) 

HTTPS is, from my standpoint, often misunderstood. Goal is of course to build encryption thanks to tunnelling but also to ensure, as much as possible, that web site you access is really the one you expect to access.
As you rightly explains, on same IP, you can have only one Apache listener on port 443, meaning only one certificate, by design.
Use of generic certificate is one pretty obvious solution but is you do not intend to have too many vhosts (and not too many subdomains  :P), then another option could be to have multi-named certificates using the SubjectAltNames feature. Doing so, client will get more confidence that server he is accessing is exposing service with certificate matching service name.
Another approach, of course, is to use alternate IP but this is not always easy especially when having many services.

With the exception of webmail and usercorner, I don't feel Zentyal is performing very well for what concerns support of web server.
As you have experienced it already, customizing your vhost conf is not very easy neither flexible.

That's where your reverse proxy approach fully makes sense to me: run reverse proxy at Zentyal level and redirect HTTP requests to internal web server(s) running your web sites. It also provides load balancing and fail-over that cannot be provided (for the time being ?) by Zentyal

mwellnitz

  • Zen Apprentice
  • *
  • Posts: 10
  • Karma: +2/-0
  • http://www.fragen-sie-ihren-administrator.de/
    • View Profile
    • Marcus Linux Blog
What I'm fighting against is to call this "subdomain".
Now I got the point :D
So maybe let's say Third-level-Domain?
http://en.wikipedia.org/wiki/Domain_name#Second-level_and_lower_level_domains
Marcus Wellnitz

christian

  • Guest
why not....
another view (BTW, this is the one I'm fully in line with  ;))

anagno

  • Zen Apprentice
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Hi all,

I am trying to do the same using with the new apache and the last zentyal (version 3.4). My settings are:


Code: [Select]
   
RewriteEngine on
SSLProxyEngine on

RewriteRule ^/*$ /Login/Index [R]
RequestHeader edit Referer usercorner\.something\.dtdns\.net 127.0.0.1:8888 early
Header edit Location ^https://127.0.0.1:8888(/.*)$ https://usercorner.something.dtdns.net$1


<Location />
        Require all granted

        ProxyPass https://127.0.0.1:8888/
        ProxyPassReverse https://127.0.0.1:8888/
        ProxyPassReverse https://usercorner.something.dtdns.net/
</Location>


But i am getting these errors:

Code: [Select]
   
[Sat Apr 26 18:09:53.334899 2014] [proxy:error] [pid 2775] (502)Unknown error 502: [client 127.0.0.1:34094] AH01084: pass request body failed to 127.0.0.1:8888 (127.0.0.1)
[Sat Apr 26 18:09:53.335032 2014] [proxy:error] [pid 2775] [client 127.0.0.1:34094] AH00898: Error during SSL Handshake with remote server returned by /Login/Index
[Sat Apr 26 18:09:53.335053 2014] [proxy_http:error] [pid 2775] [client 127.0.0.1:34094] AH01097: pass request body failed to 127.0.0.1:8888 (127.0.0.1) from 127.0.0.1 ()


Any help would be nice :)
Thanks in advance




Marcus

  • Forum Moderator
  • Zen Samurai
  • *****
  • Posts: 395
  • Karma: +12/-0
    • View Profile
    • Professional IT Service
Hey anagno!

It seems that you do have an issue with the SSL negociation... 

Just saying;
One of the usual goal of using mod_proxy is to do some SSL offloading.  So you may want to proxy your request over an unsecured connection (it is local anyways).

Also, based on this thread, there is an obviously bad configuration.  Using the balancer function with a single slave is like non-sens to me.  Why doing some load balancing on a single slave cluster ?!? Simply use the regular proxy fonction...

Could you post your complete vhosts (the one doing the proxy and the 127.0.0.1 one) configuration ?

Some other tips that may help you out figuring the problem;
I wrote a post few years ago on a similar thing.  Reading it may help you a bit:
https://forum.zentyal.org/index.php?topic=3054.0

Best,

Marcus

anagno

  • Zen Apprentice
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Hi Marcus,

Could you post your complete vhosts (the one doing the proxy and the 127.0.0.1 one) configuration ?

Since i have posted all my setting i should explain in more depth what i did and what i want to achieve.
What I want to achieve is to to be able to access the User corner not from the port like https://somethnig.dtdns.net:8888 but from something more friendly like https://usercorner.something.dtdns.net. For that purpose i created a virtual host from the interface of the web server in zentyal with the name: "usercorner.something.dtdns.net" and force it to use ssl. By doing this the server creates a folder in /etc/apache2/sites-available/user-ebox-usercorner.something.dtdns.net where i placed the settings i post and a configuration file in /etc/apache2/sites-available/ebox-usercorner.anagno.dtdns.net.conf which contains:

Code: [Select]
<VirtualHost *:62080>
        ServerAdmin webmaster@adder.adder.lan

        ServerName usercorner.something.dtdns.net:80
        DocumentRoot /srv/www/usercorner.something.dtdns.net

        ErrorLog /var/log/apache2/usercorner.something.dtdns.net-error.log
        CustomLog /var/log/apache2/usercorner.something.dtdns.net-access.log combined

        Redirect permanent / https://usercorner.something.dtdns.net:443/
</VirtualHost>

<VirtualHost *:62443>
        ServerAdmin webmaster@adder.adder.lan

        ServerName usercorner.something.dtdns.net:443
        DocumentRoot /srv/www/usercorner.something.dtdns.net

        SetEnv HTTPS On

        ErrorLog /var/log/apache2/usercorner.anagno.dtdns.net-error.log
        CustomLog /var/log/apache2/usercorner.anagno.dtdns.net-access.log combined

        # Custom configuration goes in this file
        IncludeOptional /etc/apache2/sites-available/user-ebox-usercorner.something.dtdns.net/*
</VirtualHost>


<Directory /srv/www/usercorner.something.dtdns.net>
      Options Indexes FollowSymLinks
      AllowOverride None
      Require all granted
</Directory>




One of the usual goal of using mod_proxy is to do some SSL offloading.  So you may want to proxy your request over an unsecured connection (it is local anyways).


Can you propose a link or a book to search it a bit more. I am not very good with web servers and proxies as you might have guest :)

Also, based on this thread, there is an obviously bad configuration.  Using the balancer function with a single slave is like non-sens to me.  Why doing some load balancing on a single slave cluster ?!? Simply use the regular proxy fonction...

I thought so and for that reason i didn`t include them.

Thanks in advance
 
« Last Edit: April 26, 2014, 07:25:15 pm by anagno »

Marcus

  • Forum Moderator
  • Zen Samurai
  • *****
  • Posts: 395
  • Karma: +12/-0
    • View Profile
    • Professional IT Service
Hey anagno!

Some reading:
https://forum.zentyal.org/index.php/topic,3054.msg19166.html#msg19166

Following the HowTo should achieve your goal.

Best!

Marcus

anagno

  • Zen Apprentice
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Hi Marcus,

Thanks for the link. It helped  :)
The new settings that seems to work are:

Quote
SSLProxyEngine on
ProxyRequests off
ProxyPreserveHost On

<Proxy *>
        Order deny,allow
        Allow from all
</Proxy>

<Location />
        Require all granted

        ProxyPass https://127.0.0.1:8888/
        ProxyPassReverse https://127.0.0.1:8888/
</Location>


Marcus

  • Forum Moderator
  • Zen Samurai
  • *****
  • Posts: 395
  • Karma: +12/-0
    • View Profile
    • Professional IT Service
Hi anagno,

I'm always happy to help a fellow sys admin :)

I would suggest to try it without the "ProxyPassReverse" line.  It should be more secure ;)

Best,

Marcus

anagno

  • Zen Apprentice
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Hi Marcus,

I would suggest to try it without the "ProxyPassReverse" line.  It should be more secure ;)

From what i am reading ProxyPassReserve is rewriting the headers. How can this influence security?

Thanks in advance