Portfolio / hacktuts / apache / loadbalance.txt

Load Balance VMware VDI
=======================

You need to load balance a new VDI environment and are encountering problems
with using Microsoft NLB? This might be because you are using a Cisco UCS 
environment attached to a new Nexus 7000 Series with a known bug preventing
you from adding a static multicast MAC address? Or you might not want to 
violate RFC's by using Microsoft NLB? Or you do not have the money for a 
physical load balancer? Or you might prefer a cleaner solution? Look no further! 
You can simply use Apache + mod_proxy + mod_proxy_balancer to do the work for you!

UPDATE (10/20/11): Cisco is planning an update for the Nexus 7000 Series that
                   will support static multicast MAC entries.

NOTES
=====
1) I am showing you a basic httpd.conf configuration for a RHEL 5.x machine. 
2) I am using Apache Version 2.2.15.
3) I removed most of the modules (I might be able to trim more.):
4) In reality you probably don't want to have your SSL vhosts mixed in with
   your plaintext vhosts but I did because I wanted a slim configuration file.
5) You probably want to secure your configuration before putting it into
   production.
6) For the sanitized httpd.conf configuration you want to change the 
   following to suit your environment:

   X.X.X.X --> Your IP.
   DOMAIN --> Your domain.
   tld --> Your Top Level Domain (edu,com,org,etc.)
   vdi --> Change to your liking. 
   SOMESECURESUBNET --> Change to a subnet or IP that you consider secure.
   vconnection0 --> Change to your first View Connection machine.
   vconnection1 --> Change to your second View Connection machine.

   * - you can add more servers if you need to. A similar setup should work
       for security servers (I haven't been able to penetrate the ICE problem).

7) This configuration works for VDI 4.1 and is subject to breakage because 
   the ProxyPass options might change.
8) This is unsupported (VMware KB Article #1007133).
9) There are alternatives such as the appliance from ORBIT IT-Solutions.

Here is my (sanitized) httpd.conf configuration: 

### Section 1: Global Environment
ServerTokens Prod
ServerRoot "/etc/httpd"
PidFile run/httpd.pid
Timeout 60
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       256
MaxRequestsPerChild  4000
</IfModule>

<IfModule worker.c>
StartServers         4
MaxClients         300
MinSpareThreads     25
MaxSpareThreads     75
ThreadsPerChild     25
MaxRequestsPerChild  0
</IfModule>

Listen X.X.X.X:80
Listen X.X.X.X:443

LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_alias_module modules/mod_authn_alias.so
LoadModule authn_anon_module modules/mod_authn_anon.so
LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_owner_module modules/mod_authz_owner.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule include_module modules/mod_include.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule usertrack_module modules/mod_usertrack.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
LoadModule info_module modules/mod_info.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule dir_module modules/mod_dir.so
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule substitute_module modules/mod_substitute.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so

Include conf.d/*.conf
User apache
Group apache




### Section 2: 'Main' server configuration
ServerAdmin StylusEater@MYDOMAIN.tld
ServerName vdi.MYDOMAIN.tld:80
UseCanonicalName Off
DocumentRoot "/var/www/html"

<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>

<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

DirectoryIndex index.html index.html.var
AccessFileName .htaccess

<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</Files>

TypesConfig /etc/mime.types
DefaultType text/plain

HostnameLookups Off
ErrorLog logs/error_log
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
CustomLog logs/access_log combined
ServerSignature Off

AddDefaultCharset UTF-8

AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl

AddHandler type-map var

AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

Alias /error/ "/var/www/error/"

BrowserMatch "Mozilla/2" nokeepalive
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0

BrowserMatch "Microsoft Data Access Internet Publishing Provider"
redirect-carefully
BrowserMatch "MS FrontPage" redirect-carefully
BrowserMatch "^WebDrive" redirect-carefully
BrowserMatch "^WebDAVFS/1.[0123]" redirect-carefully
BrowserMatch "^gnome-vfs/1.0" redirect-carefully
BrowserMatch "^XML Spy" redirect-carefully
BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully




### Section 3: Virtual Hosts

NameVirtualHost X.X.X.X:80
NameVirtualHost X.X.X.X:443

<VirtualHost X.X.X.X:80>
    ServerAdmin StylusEater@MYDOMAIN.tld
    DocumentRoot /var/www/html/vdi.MYDOMAIN.tld
    ServerName vdi.MYDOMAIN.tld 
    ErrorLog logs/vdi.MYDOMAIN.tld-error_log
    CustomLog logs/vdi.MYDOMAIN.tld-access_log common

    Redirect permanent / http://vdi.MYDOMAIN.tld

</VirtualHost>

<VirtualHost X.X.X.X:443>
    ServerAdmin StylusEater@MYDOMAIN.tld
    DocumentRoot /var/www/html/vdi.MYDOMAIN.tld
    ServerName vdi.MYDOMAIN.tld
    ErrorLog logs/vdi.MYDOMAIN.tld-ssl-error_log
    CustomLog logs/vdi.MYDOMAIN.tld-ssl-access_log \
              "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    #LogLevel Debug

    SetEnvIf User-Agent ".*MSIE.*" \
             nokeepalive ssl-unclean-shutdown \
             downgrade-1.0 force-response-1.0

    SSLEngine on
    SSLProxyEngine On
    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
    SSLCertificateFile /etc/pki/tls/certs/vdi.MYDOMAIN.tld.crt
    SSLCertificateKeyFile /etc/pki/tls/private/vdi.MYDOMAIN.tld.key_nopass
    SSLCertificateChainFile /etc/ssl/certs/Apache_Plesk_Install.txt

    ProxyRequests Off
    ProxyPreserveHost On

    <Location /status>
        SetHandler balancer-manager

        Order Deny,Allow
        Deny from all
        Allow from SOMESECURESUBNET 
    </Location>

    Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED

    <Proxy balancer://vdi>
        BalancerMember https://vconnection0.MYDOMAIN.tld route=v0 min=50 max=300 loadfactor=50 timeout=30 keepalive=On 
        BalancerMember https://vconnection1.MYDOMAIN.tld route=v1 min=50 max=300 loadfactor=50 timeout=30 keepalive=On
        ProxySet stickysession=ROUTEID
        ProxySet nofailover=On
        ProxySet maxattempts=1
        ProxySet lbmethod=bybusyness
        ProxySet timeout=5
    </Proxy>

    ## FORWARD ##
    ProxyPass /status !
    ProxyPass /styles/clientlaunch-default/style.css balancer://vdi/styles/clientlaunch-default/style.css
    ProxyPass /styles/clientlaunch-default/fixpng.js balancer://vdi/styles/clientlaunch-default/fixpng.js
    ProxyPass /styles/clientlaunch-default/1x62_gradient.png balancer://vdi/styles/clientlaunch-default/1x62_gradient.png
    ProxyPass /styles/clientlaunch-default/176x62_vmwareview.png balancer://vdi/styles/clientlaunch-default/176x62_vmwareview.png
    ProxyPass /styles/clientlaunch-default/99x62_vmware.png balancer://vdi/styles/clientlaunch-default/99x62_vmware.png
    ProxyPass /styles/default/cookieFunctions.js balancer://vdi/styles/default/cookieFunctions.js
    ProxyPass /broker/xml balancer://vdi/broker/xml
    ProxyPass /admin/amf balancer://vdi/admin/amf
    ProxyPass /admin balancer://vdi/admin
    ProxyPass /favicon.ico balancer://vdi/favicon.ico
    ProxyPass /images/install-step1.png balancer://vdi/images/install-step1.png
    ProxyPass /images/install-step2.png balancer://vdi/images/install-step2.png
    ProxyPass /images/install-step3.png balancer://vdi/images/install-step3.png
    ProxyPass /images/install-step4.png balancer://vdi/images/install-step4.png
    ProxyPass /images/install-step5.png balancer://vdi/images/install-step5.png
    ProxyPass /portlets/client/images/install-step1.png balancer://vdi/portlets/client/images/install-step1.png
    ProxyPass /portlets/client/images/install-step2.png balancer://vdi/portlets/client/images/install-step2.png
    ProxyPass /portlets/client/images/install-step3.png balancer://vdi/portlets/client/images/install-step3.png
    ProxyPass /portlets/client/images/install-step4.png balancer://vdi/portlets/client/images/install-step4.png
    ProxyPass /portlets/client/images/install-step5.png balancer://vdi/portlets/client/images/install-step5.png
    ProxyPass /downloads/VMware-viewclient.dmg balancer://vdi/downloads/VMware-viewclient.dmg
    ProxyPass /downloads/VMware-viewclient.exe balancer://vdi/downloads/VMware-viewclient.exe
    ProxyPass / balancer://vdi

</VirtualHost>

<VirtualHost X.X.X.X:80>
    ServerAdmin StylusEater@MYDOMAIN.tld
    DocumentRoot /var/www/html/vdi.MYDOMAIN.tld
    ServerName vdi.MYDOMAIN.tld
    ErrorLog logs/vdi.MYDOMAIN.tld-error_log
    CustomLog logs/vdi.MYDOMAIN.tld-access_log common

    Redirect permanent / https://vdi.MYDOMAIN.tld/
    Redirect permanent /admin https://vdi.MYDOMAIN.tld/admin

</VirtualHost>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.