2017年2月5日 星期日

Lighttpd Reverse Proxy To Nginx

Lighttpd Reverse Proxy To Nginx

環境參數:

  • OS:FreeBSD i386 , 10.3-RELEASE-p11
  • CPU:Intel(R) Core(TM)2 Duo CPU @ 3.00GHz
  • RAM:4096 MB
  • 主機:
    1. 外部主機:outside_ip1 , 192.168.0.1
    2. 內部主機:192.168.0.2(lighttpd),192.168.0.3(nginx)
    3. 其它主機:8.8.8.8
    4. 網址1:url1.com.tw
    5. 網址2:url2.com.tw
    6. 網址3:url3.com.tw
    7. 網址a:external.com.tw

任務目的及架構

現有與外面連接的外部主機(192.168.0.1),以PPPOe撥接ADSL,並透過Hub與內部網路主機(192.168.0.2)相連接。
我們不希望內部主機直接與網路連接,並透過外部主機提供WWW服務。作法有很多,諸如利用Apache Reverse Proxy、IPFW或IPTABLES等機制都能作到,本文主要探討以Lighttpd擔任Reverse Proxy Server,以達到:
1. 連接到內部的 Nginx Web Server 的網站服務。
2. 連接到外部其它網站。

內部轉址1,系統負載低,採Lighttpd

Created with Raphaël 2.1.2外部網址1轉到內部主機 port 80url1.com.tw(Lighttpd)url1.com.tw(Lighttpd)Lighttpd(192.168.0.2:80)Lighttpd(192.168.0.2:80)-> 透過Lighttpd proxy

內部轉址2,系統負載高,採Nginx

Created with Raphaël 2.1.2外部網址2轉到內部主機 port 88url2.com.tw(Lighttpd)url2.com.tw(Lighttpd)Nginx(192.168.0.3:88)Nginx(192.168.0.3:88)-> 透過Lighttpd proxy

外部轉址a,純粹轉址

Created with Raphaël 2.1.2外部網址a轉到外部其它主機url3.com.tw(Lighttpd)url3.com.tw(Lighttpd)其它主機urla.com.tw其它主機urla.com.tw-> 透過Lighttpd proxy

Lighttpd 前端設置

Lighttpd 的設定include非常彈性,端看您如何配置。本例將mod_proxy皆由/usr/local/etc/lighttpd/conf.d/lighttpd-proxy.conf控制及設定。

首先在modules.conf定義引proxy設定檔(lighttpd-proxy.conf)

$ sudo vi /usr/local/etc/lighttpd/modules.conf
# mod_proxy預設檔名是:conf.d/proxy.conf,備而不用,先開啟新檔案名稱:lighttpd-proxy.conf
include "conf.d/lighttpd-proxy.conf"
  • lighttpd-proxy.conf 要引用mod_proxy模組功能,記得要加入:*server.modules += ( “mod_proxy” )這段文字只能加入一次,否則會出現重覆引用錯誤
    接著設定三種情境的Lighttpd Reverse Proxy:
$ sudo vi /usr/local/etc/lighttpd/conf.d/lighttpd-proxy.conf
#######################################################
##
##  Proxy Module 
## --------------- 
## http://www.lighttpd.net/documentation/proxy.html
##

# 啟用mod_proxy模組

server.modules += ( "mod_proxy" )

# 內部轉址1,外部網址1轉到內部主機 Lighttpd port 80
$HTTP["host"] == "url1.com.tw" {
proxy.server = ( "" =>
                ( 
                   (
                     "host" => "192.168.0.2",
                     "port" => 80
                   )
                )
            )
}

# 內部轉址2,外部網址2轉到內部主機 Nginx port 88
$HTTP["host"] == "url2.com.tw" {
proxy.server = ( "" =>
                ( 
                   (
                     "host" => "192.168.0.3",
                     "port" => 88
                   )
                )
            )
}

# 外部轉址a,直接將所有來訪 url.outside.domain的連線導向到IP:8.8.8.8 Port:80的其它外部網站
$HTTP["host"] == "url.outside.domain" {
proxy.server = ( "" =>
                ( 
                   (
                     "host" => "8.8.8.8",
                     "port" => 80
                   )
                )
            )
  }

Nginx 內部主機設置

內部主機可由Apache、Nginx或Lighttpd來擔任,端看實際需求及系統資源自由調配,依照各Server的特性來指派轉址目的服務主機。

Lighttpd 虛擬主機 NameBased Vhosts設定

較輕負載大多是單純的HTML服務,筆者偏好採用 Lighttpd,故外部轉址1到內部主機時就使用 Lighttpd,但因 Lighttpd Server 也有多台的虛擬主機,為能準確達成外部連至指定的虛擬主機,設定如下:

$ sudo vi /usr/local/etc/lighttpd/lighttpd.conf
# 虛擬主機設定
include "/usr/local/etc/lighttpd/vhosts.d/lighttpd-vhosts.conf"

因為前端Lighttpd是將內部轉址1導向到192.168.0.2:80的Lighttpd,所以在虛擬主機設定檔要跟在$SERVER[“socket”] == “192.168.0.2:80”區段之後,參考如下:

# sudo vi /usr/local/etc/lighttpd/vhosts.d/lighttpd-vhosts.conf
#+---------------------------------------------------------------
# /usr/local/etc/lighttpd/vhost.d/lighttpd-vhosts.conf
# Lighttpd vhost conf
#------------------------------------------------------------------------------
# 第1台預設主機IP:192.168.0.9 Port 80

  $SERVER["socket"] == "192.168.0.9:80" {

    server.document-root = "/data/htdocs/default-ip9" 

      # 符合第1台主機IP的虛擬主機,凡是訪問tiger.com.tw的就轉到這台主機設定
      $HTTP["host"] == "tiger.com.tw" {
        server.document-root = "/data/htdocs/tiger.com.tw"
      }

  }

# 第2台主機IP:192.168.0.2 Port 80

  $SERVER["socket"] == "192.168.0.2:80" {

    server.document-root = "/data/htdocs/default-ip2" 

    # 符合第2台主機IP的虛擬主機,凡是訪問url1.com.tw的就轉到這台主機設定
    $HTTP["host"] == "url1.com.tw" {
        server.document-root = "/data/htdocs/url1.com.tw"
    }

  }

Nginx 虛擬主機 NameBased Vhosts設定

Nginx 搭配FastCGI(PHP FPM)的作法在此不多記載,主要探討虛擬主機的設定方法。

$ sudo vi/usr/local/etc/nginx/nginx.conf
# 加入這行,以引用所有的虛擬主機設定檔
include /usr/local/etc/nginx/site_enabled/*.conf;

不論 Nginx 主設定檔(/usr/local/etc/nginx/nginx.conf)或其它虛擬主機如何設定,Nginx 必先找尋先以英文字母排列結果最先讀取的主機內容為預設主機,所以要檔名編排上要多加留意。

#-----------------------------------------------------------------------------+
server {
        listen 192.168.0.3:88;
        server_name url2.com.tw;
        server_name_in_redirect off;
        root /data/htdocs/url2.com.tw;
        access_log   /data/weblogs/url2.com.tw-access.log;
        error_log    /data/weblogs/url2.com.tw-error.log;
        index index.php index.html; 

        location / {
                try_files $uri $uri/ /index.php?q=$uri&$args;
                proxy_read_timeout 300;
                autoindex on;
        }

        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php-fpm.sock;
            fastcgi_index index.php;
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_param SCRIPT_FILENAME /data/htdocs/url2.com.tw/$fastcgi_script_name;
            include fastcgi_params;
            fastcgi_read_timeout 300;
        }

        location ~* ^.+\.(ico|js|gif|jpg|jpeg|png|bmp)$ {
          expires 30d;
        }

        location ~ /\.ht {
            deny all;
        }

        error_page 404 /404.html;

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
                root /usr/local/www/nginx;
        }
}

結語

本實作記錄並非刻意將簡單的反向代理機制複雜化,一般而言只要簡單的Apache Reverse Proxy(外部)搭配內部的Apache服務主機即可達到轉址目的。
然而隨著網路多元化的演進,適度的應用輕量級的Lighttpd或高負載的Nginx是必要的,僅將實作的過程記錄。

本文大網

活本來沒有什麼好與壞,只要你願意怎樣填滿它,它就隨同而行。


EmoticonEmoticon