Admin Books

DOWNLOAD Free e-Books for Linux Admin Servers :

How to Automate Virtualmin Virtual Host Creation with Nginx Proxy in Front, and Apache Behind on Centos

Install EPEL Repo :


Extra Packages for Enterprise Linux (or EPEL) is a Fedora Special Interest Group that creates, maintains, and manages a high quality set of additional packages for Enterprise Linux, including, but not limited to, Red Hat Enterprise Linux (RHEL),CentOS and Scientific Linux (SL). How do I enable it under CentOS 6 or RHLE 6 server?

You need to install the following rpms as per your Enterprise Linux version. Use the wget command to download rpm files.
If you are running an EL6 version, enter:

$ cd /tmp
$ wget http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
# rpm -ivh epel-release-6-5.noarch.rpm
If you are running an EL5 version, enter:

$ cd /tmp
$ wget http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm
# rpm -ivh epel-release-5-4.noarch.rpm

RHEL 5/ CentOS 5 user type the following command to protect packages:

# yum install yum-protectbase.noarch

This plugin allows certain repositories to be protected. Packages in the protected repositories can't be overridden by packages in non-protected repositories even if the non-protected repo has a later version.

If you are running an EL4 version, enter:

$ cd /tmp
$ wget http://download.fedoraproject.org/pub/epel/4/i386/epel-release-4-10.noarch.rpm
# rpm -ivh epel-release-4-10.noarch.rpm

-------------

next

Install Nginx from EPEL repo


yum search nginx

and...

    [root@vps15 tmp]# yum install nginx
    [root@vps15 tmp]# service nginx stop

    [root@vps15 tmp]# cd /etc/nginx
    [root@vps15 nginx]# nano proxy.conf

Now create the file /etc/nginx/proxy.conf and add the following to it:

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header        X-Forwarded-Host        $http_host;

client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffers           32 4k;

Those are the standard settings. You may have to adjust the numbers to best fit your site's needs.

Open /etc/nginx/nginx.conf and edit it to match the following (adjust to your server's needs)

user apache;
worker_processes  2;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    # multi_accept on;
}

http {
    include       /etc/nginx/mime.types;

    access_log  /var/log/nginx/access.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

I created/edited the default host file to handle any domains that do not have a specific config file:

(use your own server's ip ! )

my /etc/nginx/sites-available/default ,is below :

server {
    listen 12.34.56.78:80 default;
    server_name  _;
    access_log /var/log/nginx/default.access.log;
    error_log /var/log/nginx/default.error.log;

    location / {
        proxy_pass http://12.34.56.78:9091;
        include /etc/nginx/proxy.conf;
   }
}

    Now create a virtual host file. I created one for each of my domains and named them like domain.com.conf so that my Virtualmin script can automatically handle creating them (see below).

    So for example, create /etc/nginx/sites-available/mydomain.com.conf:

    server {
        listen 12.34.56.78:80;
        server_name www.mydomain.com mydomain.com foo.mydomain.com bar.mydomain.com;
        access_log /var/log/virtualmin/mydomain.com_nginx_access_log;
        error_log  /var/log/virtualmin/mydomain.com_nginx_error_log;
        location / {
            proxy_pass http://12.34.56.78:9091;
            include /etc/nginx/proxy.conf;
        }

        location ~* ^.+\.(jpe?g|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mp3)$ {
            expires 30d;
            root /home/mydomainuser/public_html;
        }
    }

Enable each of your site conf:


sudo ln -s /etc/nginx/sites-available/mydomain.com.conf /etc/nginx/sites-enabled/mydomain.com.conf

Of course you will replace 12.34.56.78 with your server's IP address (if you are using a host with multiple IPs, be sure to use the correct one for this host!). Also change mydomain.com and add any other server names to the server_name directive. Now for the proxy_pass, normally this would 127.0.0.1:9091 (9091 being the port we are going to configure apache to run on). But like I said earlier, I still want Virtualmin to be fully functional without me having to manually edit the apache config files after Virtualmin created them to force apache to listen to 127.0.0.1. So I am leaving both open to the world and thus apache will listen to the host's IP address.

Test your configs with:

nginx -t -c /etc/nginx/nginx.conf





    [root@vps15 sites-available]# nginx -t -c /etc/nginx/nginx.conf
    the configuration file /etc/nginx/nginx.conf syntax is ok
    configuration file /etc/nginx/nginx.conf test is successful
   
    



You should get a success message. If you get errors fix it before starting nginx.

Start/restart nginx:

sudo /etc/init.d/nginx restart

or :

service nginx restart

 Configuring Apache Behind Nginx to Handle PHP


We need to now configure Apache to listen to port 9091 and to tell it to use the correct IP address in the logs and in the $_SERVER var for PHP.

Open /etc/httpd/conf/httpd.conf

and change

NameVirtualHost 12.34.56.78:80 to 12.34.56.78:9091

and change

Listen 80 to Listen 9091

Open all the config files in /etc/apache2/sites-available and change to

Change All your VirtualHost :80> entry to :9091> in the /etc/httpd/conf/httpd.conf

If you have configured Keep-Alive support in Apache you should disable it since it is already enabled in nginx.
Change KeepAlive On to KeepAlive Off in /etc/httpd/conf/httpd.conf (CentOS) or /etc/apache2/apache2.conf (Debian/Ubuntu).
You can also disable the mod_deflate module since nginx already provides gzip compression. A good practice is to disable all unused Apache modules to reserve more system resources.

    [root@vps15 conf]# nginx -t
    the configuration file /etc/nginx/nginx.conf syntax is ok
    configuration file /etc/nginx/nginx.conf test is successful
    [root@vps15 conf]# apachectl configtest
    Syntax OK

Install mod_rpaf so that apache knows the true IP address of the user accessing the site:


    yum install gcc gcc-c++ make httpd-devel pcre pcre-devel nano lsof

    wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz

#or get the latest rpaf module by:

#wget http://sysoev.ru/nginx/nginx-0.6.36.tar.gz

    tar xf mod_rpaf-0.6.tar.gz

    cd mod_rpaf-0.6

    /usr/sbin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

    [root@vps15 tmp]# cd mod_rpaf-0.6

    [root@vps15 mod_rpaf-0.6]# /usr/sbin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

    /usr/lib/apr-1/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -fno-strict-aliasing  -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -pthread -I/usr/include/httpd  -I/usr/include/apr-1   -I/usr/include/apr-1   -c -o mod_rpaf-2.0.lo mod_rpaf-2.0.c && touch mod_rpaf-2.0.slo

    /usr/lib/apr-1/build/libtool --silent --mode=link gcc -o mod_rpaf-2.0.la  -rpath /usr/lib/httpd/modules -module -avoid-version    mod_rpaf-2.0.lo

    /usr/lib/httpd/build/instdso.sh SH_LIBTOOL='/usr/lib/apr-1/build/libtool' mod_rpaf-2.0.la /usr/lib/httpd/modules

    /usr/lib/apr-1/build/libtool --mode=install cp mod_rpaf-2.0.la /usr/lib/httpd/modules/

    cp .libs/mod_rpaf-2.0.so /usr/lib/httpd/modules/mod_rpaf-2.0.so

    cp .libs/mod_rpaf-2.0.lai /usr/lib/httpd/modules/mod_rpaf-2.0.la

    cp .libs/mod_rpaf-2.0.a /usr/lib/httpd/modules/mod_rpaf-2.0.a

    chmod 644 /usr/lib/httpd/modules/mod_rpaf-2.0.a

    ranlib /usr/lib/httpd/modules/mod_rpaf-2.0.a

    PATH="$PATH:/sbin" ldconfig -n /usr/lib/httpd/modules

    ----------------------------------------------------------------------

    Libraries have been installed in:

       /usr/lib/httpd/modules

    If you ever happen to want to link against installed libraries

    in a given directory, LIBDIR, you must either use libtool, and

    specify the full pathname of the library, or use the `-LLIBDIR'

    flag during linking and do at least one of the following:

       - add LIBDIR to the `LD_LIBRARY_PATH' environment variable

         during execution

       - add LIBDIR to the `LD_RUN_PATH' environment variable

         during linking

       - use the `-Wl,--rpath -Wl,LIBDIR' linker flag

       - have your system administrator add LIBDIR to `/etc/ld.so.conf'

    See any operating system documentation about shared libraries for

    more information, such as the ld(1) and ld.so(8) manual pages.
    ----------------------------------------------------------------------

    chmod 755 /usr/lib/httpd/modules/mod_rpaf-2.0.so

    [root@vps15 mod_rpaf-0.6]#

    nano /etc/httpd/conf/httpd.conf

add below LoadModule block:

    LoadModule rpaf_module /usr/lib/httpd/modules/mod_rpaf-2.0.so

    <IfModule mod_rpaf-2.0.c>

      RPAFenable On

      RPAFsethostname On

      RPAFproxy_ips 127.0.0.1  12.34.56.78

      RPAFheader X-Real-IP

    </IfModule>



Its important to add your server's IP address(es) to the RPAFproxy_ips directive as if you do not, $_SERVER['REMOTE_ADDR'] will always be your server's IP address which can be bad for scripts that rely on this (like php based firewalls).

    [root@vps15 mod_rpaf-0.6]# apachectl configtest

    Syntax OK

    [root@vps15 mod_rpaf-0.6]# service httpd restart

    Stopping httpd:                                            [  OK  ]

    Starting httpd:                                            [  OK  ]

     [root@vps15 mod_rpaf-0.6]# service nginx restart
    Stopping nginx:                                            [FAILED]
    Starting nginx:                                            [  OK  ]

Configuring Virtualmin to Automate Nginx Virtual Host Config



    Now we have to make some changes to Virtualmin and its config files.

    First we need to edit all the existing servers to use the new apache port.

    So open each file in /etc/webmin/virtual-server/domains (each file represents a server) and change web_port=80 to web_port=9091.

    Now, login to Virtualmin and go to Server Settings -> Server Templates -> click on your default template -> choose Apache website from the template section dropdown -> change Port number for virtual hosts to 9091 then click Save and Next.
    Restart webmin:
    sudo /etc/init.d/webmin restart



Choose Log file rotation from the template section dropdown, choose Log files below for the Additional files to rotate field. Add the following to the field's textbox:

/var/log/virtualmin/${DOM}_nginx_access_log

/var/log/virtualmin/${DOM}_nginx_error_log

Note, that you will need to manually add the nginx log files to logrotate for existing domains. You can use Webmin -> System -> Log File Rotation to do so.

example:

/var/log/virtualmin/my.another.domain.com_nginx_error_log

/var/log/virtualmin/my.another.domain.com_nginx_access_log

set them to rotate weekly and test by "rotate now" button.

--------------

Automating Virtualmin for nginx proxy configuration



Now I didn't want to manually create new virtual host files for nginx each time Virtualmin created a server. So, I created a little script to do it for me.

First, I created a template file /etc/nginx/sites-available/template_vhost.conf which has the following in it:

server {
    listen {SITE_IP}:80;
    server_name www.{DOM} {DOM};
    access_log /var/log/virtualmin/{DOM}_nginx_access_log;
    error_log  /var/log/virtualmin/{DOM}_nginx_error_log;

    location / {
        proxy_pass http://{SITE_IP}:9091;
        include /etc/nginx/proxy.conf;
    }

    location ~* ^.+\.(jpe?g|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mp3)$ {
        expires 30d;
        root {HOME}/public_html;
    }
}

Now, I created a script that Virtualmin will run after it creates/deletes/modifies a server. File name is

/usr/local/bin/trigger_nginx_modify.sh  as below:

#!/bin/sh
NGINX_CONF_FILE="/etc/nginx/sites-available/${VIRTUALSERVER_DOM}.conf "

if [ "$VIRTUALSERVER_ACTION" = "CREATE_DOMAIN" ]; then
 if [ "${VIRTUALSERVER_WEB}" = "1" ];
 then
  cp /etc/nginx/sites-available/template_vhost.conf $NGINX_CONF_FILE

  perl -pi -e "s#{DOM}#$VIRTUALSERVER_DOM#g" $NGINX_CONF_FILE
  perl -pi -e "s#{SITE_IP}#$VIRTUALSERVER_IP#g" $NGINX_CONF_FILE
  perl -pi -e "s#{HOME}#$VIRTUALSERVER_HOME#g" $NGINX_CONF_FILE
  ln -s $NGINX_CONF_FILE /etc/nginx/sites-enabled/${VIRTUALSERVER_DOM}.conf
  /etc/init.d/nginx reload
 fi


elif [ "$VIRTUALSERVER_ACTION" = "DELETE_DOMAIN" ]; then
        if [ "${VIRTUALSERVER_WEB}" = "1" ];
        then
      rm /etc/nginx/sites-enabled/${VIRTUALSERVER_DOM}.conf
      rm /etc/nginx/sites-available/${VIRTUALSERVER_DOM}.conf
      rm /var/log/virtualmin/${VIRTUALSERVER_DOM}_nginx_*
            /etc/init.d/nginx reload
     fi


elif [ "$VIRTUALSERVER_ACTION" = "MODIFY_DOMAIN" ]; then
        if [ "${VIRTUALSERVER_WEB}" = "1" ];
        then
      if [ ! -f $NGINX_CONF_FILE ]; then
           cp /etc/nginx/sites-available/template_vhost.conf $NGINX_CONF_FILE
          perl -pi -e "s#{DOM}#$VIRTUALSERVER_DOM#g" $NGINX_CONF_FILE
          perl -pi -e "s#{SITE_IP}#$VIRTUALSERVER_IP#g" $NGINX_CONF_FILE
          perl -pi -e "s#{HOME}#$VIRTUALSERVER_HOME#g" $NGINX_CONF_FILE
          ln -s $NGINX_CONF_FILE /etc/nginx/sites-enabled/${VIRTUALSERVER_DOM}.conf
      fi
     fi

     if [ "$VIRTUALSERVER_DOM" != "$VIRTUALSERVER_OLDSERVER_DOM" ]; then
         if [ "${VIRTUALSERVER_WEB}" = "1" ];
         then
       OLD_NGINX_CONF_FILE=/etc/nginx/sites-available/${VIRTUALSERVER_OLDSERVER_DOM}.conf
       mv $OLD_NGINX_CONF_FILE $NGINX_CONF_FILE
       rm /etc/nginx/sites-enabled/${VIRTUALSERVER_OLDSERVER_DOM}.conf
          perl -pi -e "s#$VIRTUALSERVER_OLDSERVER_DOM#$VIRTUALSERVER_DOM#g" $NGINX_CONF_FILE
          perl -pi -e "s#$VIRTUALSERVER_OLDSERVER_IP#$VIRTUALSERVER_IP#g" $NGINX_CONF_FILE
          perl -pi -e "s#$VIRTUALSERVER_OLDSERVER_HOME#$VIRTUALSERVER_HOME#g" $NGINX_CONF_FILE
       ln -s /etc/nginx/sites-available/${VIRTUALSERVER_DOM}.conf /etc/nginx/sites-enabled/${VIRTUALSERVER_DOM}.conf
      fi
     fi

        if [ "${VIRTUALSERVER_WEB}" = "1" ];
        then
         /etc/init.d/nginx reload
     fi
fi
----

chmod 777 /usr/local/bin/trigger_nginx_modify_config.sh

Now go to Virtualmin -> System Settings -> Virtualmin Configuration -> choose Actions upon server and user creation from the category dropdown and add /usr/local/bin/trigger_nginx_modify_config.sh to "Command to run after making changes to a server." Now Virtualmin will automatically manage the nginx host file for you.

That should do it!

Test your nginx from outside of your server using this tool:
http://andrew.hedges.name/experiments/what-server/



References:

https://help.ubuntu.com/community/Nginx/ReverseProxy
http://www.dikant.de/2008/07/10/nginx-as-a-reverse-proxy-for-apache/
https://www.virtualmin.com/node/19887
http://hartlessbydesign.com/blog/view/206-virtualmin-apache-and-nginx-reverse-proxy.html
http://olex.openlogic.com/wazi/2011/add-a-nginx-reverse-proxy-to-your-lamp-setup/
http://www.cyberciti.biz/faq/fedora-sl-centos-redhat6-enable-epel-repo/
http://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/
http://www.cyberciti.biz/faq/rhel-fedora-centos-linux-enable-epel-repo/
http://code.google.com/p/scriptz/wiki/NginxAndApache
http://terra-byte.org/content/how-set-vps-nginx-php-mysql-phpmyadmin-mail-server-ftp-webmin-memcached-and-eaccelerator-and
http://www.admin-server.ru/blog/content/view/18/1/
http://terra-byte.org/content/how-set-vps-nginx-php-mysql-phpmyadmin-mail-server-ftp-webmin-memcached-and-eaccelerator-and
http://www.howtoforge.com/reduce-apache-load-with-nginx-rhel5.2
http://stderr.net/apache/rpaf/download/


No comments:

Post a Comment