原文针对OpenBSD4.9,现在已经是5.9了,有些内容重新做了修订。

Nginx("engine x")是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP 代理服务器 。Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的Rambler.ru 站点开发的,它已经在该站点运行超过四年多了。Igor 将源代码以类BSD许可证的形式发布。自Nginx 发布四年来,Nginx已经因为它的稳定性、丰富的功能集、 示例配置文件和低系统资源的消耗而闻名了。目前国内各大门户网站已经部署了Nginx,如新浪、网易、腾讯等;国内几个重要的视频分享网站也部署了Nginx,如六房间、酷6等。

经过几年的发展,nginx的市场占有率稳步上升,截至2013年,市场份额占有率为15.52%(netcraft统计),微软的IIS为16.69%。nginx不日即可超越IIS。

反向代理

nginx的优势在于处理静态页面,其速度非常恐怖,apache根本不是对手,IIS之流就更别提了。现在,nginx+apache这套组合非常流行,其中nginx放在前端做反向代理,后台使用apache处理动态请求。

为什么要反向代理?反向代理的作用主要是:

  1. 缓存静态内容,减轻后端动态处理压力;

  2. 减速上传;

  3. 规范请求,减少攻击。

然而,我之所以应用反向代理的理由很简单,公网IP太少,但是公司内对外发布的网页很多,需要通过域名+后缀的方式来区分不同的互联网应用,所以要用到反向代理。

编译

$ cd /usr/src
$ sudo wget http://nginx.org/download/nginx-1.2.2.tar.gz

编译nginx时需用到pcre这个软件包。若尚未安装,$ sudo pkg_add -i pcre轻松搞定。

$ sudo tar -xzvf nginx-1.2.2.tar.gz
$ sudo nginx-1.2.2
$ sudo ./configure --prefix=/var/www --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/sbin/nginx --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-log-path=logs/access.log --error-log-path=logs/error.log --http-client-body-temp-path=/var/www/cache/client_body_temp --http-proxy-temp-path=/var/www/cache/proxy_temp --http-fastcgi-temp-path=/var/www/cache/fastcgi_temp --http-scgi-temp-path=/var/www/cache/scgi_temp --http-uwsgi-temp-path=/var/www/cache/uwsgi_temp --user=www --group=www --with-http_gzip_static_module --with-http_ssl_module --with-http_stub_status_module --with-ipv6 --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module

$ sudo make && make install

配置

本文仅涉及到反向代理

$ sudo vim /etc/nginx/nginx.conf
user  www www;
worker_processes  1;
error_log  logs/error.log;
pid        /var/run/nginx.pid;
events {
    worker_connections  64;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format   main '$request_time $remote_addr $cookie_SUV [$time_local]  $status '
                      '"$request" $body_bytes_sent "$http_referer"';
    access_log  logs/access.log  main buffer=32k;
    error_log  logs/error.log;
    sendfile        on;
    keepalive_timeout  65;
    upstream cmk_syjk {
      server 10.8.0.97;
    }
    server {
        listen 80;
        server_name monitor.linuxabc.net.cn;
        location /syjk {
            proxy_pass http://cmk_syjk;
            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;
            client_max_body_size 10m;
            client_body_buffer_size 128k;
            proxy_connect_timeout 90;
            proxy_send_timeout 90;
            proxy_read_timeout 90;
            proxy_buffer_size 4k;
            proxy_buffers 4 32k;
            proxy_busy_buffers_size 64k;
            proxy_temp_file_write_size 64k;
        }
    }
}

用户通过http://monitor.linxuabc.net.cn/syjk/check_mk这个url来访问一个check_mk的网站。

配置完毕后检查一下配置是否正确:

$ sudo nginx -t

常用操作

  • 测试配置

    $ sudo nginx -t
  • 启动

    $ sudo nginx

    或者

    $ sudo /etc/rc.d/nginx start
  • 刷新配置

    $ sudo nginx -s reload`或`$ sudo /etc/rc.d/nginx reload
  • 重启

    $ sudo kill -HUP `cat /var/run/nginx.pid`
  • 停止

    $ sudo nginx -s stop

    $ sudo /etc/rc.d/nginx stop

配置pf

$ sudo vim /etc/pf.conf
$ext_if = "fxp0"
$ext_if = "fxp1"
public_ip = "your.public.ip"
server_1 = "192.168.0.1"
server_2 = "192.168.0.2"
...
pass in on $ext_if inet proto tcp to $public_ip port 80 \
     rdr-to $proxy port 80
pass quick on $lan_if inet proto tcp to $server_1 port 80
pass quick on $lan_if inet proto tcp to $server_2 port 80
...

在该配置中,server_1跑的是blog服务,server_2跑的是wiki服务。

  • 当外网用户访问`http://wiki.linuxabc.net.cn`的时候,nginx捕获到这一请求,由nginx向位于内网的server_1:80发起request,并将内容反馈给用户;

  • 当外网用户访问`http://blog.linuxabc.net.cn`的时候,nginx捕获到这一请求,由nginx向位于内网的server_2:80发起request,并将内容反馈给用户;

FAQ

安装后,如何查看编译时的参数?

$ sudo nginx -V

bad privsep dir permissions on /web_cache (17: File exists)stat(/nonexistent) failed (2: No such file or directory)是什么意思?

多半是因为nginx.conf文件中的user option设置错误。