Wednesday, June 26, 2013

Nginx Reverse SSL Proxy with PHP

This trick introduce the way of creating nginx reverse SSL proxy that works with PHP in load balancing environment.

Example network structure

nginx_reverse_proxy

1. Nginx proxy config file for ssl connection
define upsteam in nginx.conf

upstream example.com{        ip_hash;        server 192.168.0.1:8000 max_fails=3 fail_timeout=8;        server 192.168.0.2:8000 max_fails=3 fail_timeout=8;        server 192.168.0.3:8000 max_fails=3 fail_timeout=8;}

define the example.com.conf

server {    listen       443;    server_name  example.com;    index  index.php index.html index.htm;    ssl                  on;    ssl_certificate      /etc/ssl/example.com/example.com.crt;    ssl_certificate_key  /etc/ssl/example.com/example.com.key;    ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;    ssl_ciphers HIGH:!ADH:!MD5:!aNULL:!eNULL:!MEDIUM:!LOW:!EXP:!kEDH;    ssl_session_timeout  10m;    ssl_prefer_server_ciphers   on;    proxy_set_header Cookie $http_cookie;    location / {        proxy_pass http://example.com; #here is the upstreams that defined in upsteam block        proxy_next_upstream     error timeout invalid_header http_500;        proxy_connect_timeout   2;        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-Proto https;        add_header              Front-End-Https   on;    }}

2. Web server behind the proxy
2.1. Install pecl_http extension with pecl install pecl_http. (This extension allow you to obtain headers from cgi mode, ideally for php-fpm)

2.2. In PHP script, use

if($_SERVER['HTTP_X_FORWARDED_PROTO']=='https' || (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')){    //SSL detected}

To check if the request is from https

Friday, June 14, 2013

Get PHP function body as string

This piece of code can return the method body from a class

public static function getFunctionString($class, $function){  $func = new ReflectionMethod($class,$function);   $filename = $func->getFileName();   $start_line = $func->getStartLine();  $end_line = $func->getEndLine()-1;  $length = $end_line - $start_line;  $source = file($filename);  $body = implode("", array_slice($source, $start_line, $length));  return $body;}

When to use:

Extract the function details & execute in other another class when the function contains self::func();

Eg:

class A{   private static $var_a = 1;  public static function a(){     self::func();  }  public static function func(){     echo self::$var_a;  }}

In class B, we need to call function a from Class A

class B{   private static $var_a=2;  public static function b(){     eval(getFunctionString('A', 'a'));  }}B::b();//will output 2