Orange 使用文档0.6.3

Docs / All

Orange提供了各种API用于实现第三方需求, 如:

默认的API Server在7777端口监听,详细使用方法参看API部分。


to be continued…


启动Orange后,浏览器输入http://localhost:9999即可访问内置的Dashboard。

从v0.1.1版本开始,Orange Dashboard(默认在9999端口监听)可开启授权验证,只有通过成功登录的账户才能使用控制台。

请注意,目前仅当选择storemysql时,才能使用该功能。

其相关的配置在orange.conf中:

 "dashboard": {
    "auth": false, //是否开启授权验证,开启时需要先登录才能使用Dashboard
    "session_secret": "y0ji4pdj61aaf3f11c2e65cd2263d3e7e5", // 用于加密cookie的盐,自行更改即可
    "whitelist": [//不需要判断是否登录的白名单url, 用户无需修改
        "^/auth/login$",
        "^/error/$"
    ]
}

在MySQL表dashboard_user中存储了Dashboard的用户信息,请导入该表到库中,参见sql文件install/orange-v0.6.3.sql

默认的管理员用户名和密码如下,登录后可更改密码或添加其他用户:

用户名:admin
密码:orange_admin

使用方法同URL重定向API, 只是规则的字段有所差异。


说明

//失败情况
{
    success: false,
    msg: "错误描述"
}

//成功情况
{
    success: true,
    msg: "描述信息",
    data: {} //相关数据
}

插件基本信息API

请求方式

URI Method
/plugins Get

参数

返回结果

{
  "success": true, //API请求是否成功
  "data": {
    "plugins": {
      "monitor": {//插件名称
        "enable": true, //是否开启
        "active_selector_count": 1, //开启的选择器数目
        "inactive_selector_count": 0, //关闭的选择器数目
        "active_rule_count": 1, //开启的规则数目
        "inactive_rule_count": 0, //开启的规则数目
        "name": "monitor" // 插件名称
      },
      "rate_limiting": {
        "enable": true,
        "active_selector_count": 1,
        "inactive_selector_count": 0,
        "inactive_rule_count": 0,
        "name": "rate_limiting",
        "active_rule_count": 1
      },
      "key_auth": {
        "enable": false,
        "active_selector_count": 1,
        "inactive_selector_count": 0,
        "inactive_rule_count": 0,
        "name": "key_auth",
        "active_rule_count": 2
      },
      "basic_auth": {
        "enable": true,
        "active_selector_count": 1,
        "inactive_selector_count": 0,
        "inactive_rule_count": 0,
        "name": "basic_auth",
        "active_rule_count": 2
      },
      "kvstore": {
        "enable": true,
        "name": "kvstore"
      },
      "divide": {
        "enable": true,
        "active_selector_count": 1,
        "inactive_selector_count": 1,
        "inactive_rule_count": 0,
        "name": "divide",
        "active_rule_count": 0
      },
      "stat": {
        "active_selector_count": 0,
        "inactive_selector_count": 0,
        "inactive_rule_count": 0,
        "name": "stat",
        "active_rule_count": 0
      },
      "waf": {
        "enable": true,
        "active_selector_count": 0,
        "inactive_selector_count": 2,
        "inactive_rule_count": 0,
        "name": "waf",
        "active_rule_count": 0
      },
      "property_rate_limiting": {
        "enable": false,
        "active_selector_count": 1,
        "inactive_selector_count": 0,
        "inactive_rule_count": 0,
        "name": "property_rate_limiting",
        "active_rule_count": 0
      },
      "rewrite": {
        "enable": false,
        "active_selector_count": 1,
        "inactive_selector_count": 0,
        "inactive_rule_count": 0,
        "name": "rewrite",
        "active_rule_count": 2
      },
      "signature_auth": {
        "enable": false,
        "active_selector_count": 0,
        "inactive_selector_count": 0,
        "inactive_rule_count": 0,
        "name": "signature_auth",
        "active_rule_count": 0
      },
      "redirect": {
        "enable": true,
        "active_selector_count": 0,
        "inactive_selector_count": 1,
        "inactive_rule_count": 0,
        "name": "redirect",
        "active_rule_count": 0
      }
    }
  }
}

分流、AB测试插件: 继承了Nginx Upstream的用法, 通过条件判断模块做到更细粒度的流量分流。

选择器和规则相关的API使用方法同URL重定向API, 只是规则的字段有所差异。


使用方法同URL重定向API, 只是规则的字段有所差异。


自定义监控: 用于对“筛选”出来的流量进行统计、监控。

1) 开启或关闭此插件

请求方式

URI Method
/monitor/enable Post

参数

名称 类型 说明
enable int 0关闭1开启

返回结果

{
    "msg":"succeed to disable plugin",
    "success":true
}

2) 获取所有配置信息

请求方式

URI Method
/monitor/config Get

参数

返回结果

{
  "msg": "succeed to get configuration in this node",
  "data": {
    "enable": true,//插件是否启用
    "selectors": [//选择器列表
      {
        "enable": true,//选择器是否启用
        "rules": [//该选择器下的"规则"列表
          {
            "enable": true,//本条规则是否启用
            "id": "aa502670-e428-462e-a4ac-b41c74b88a14",
            "judge": {// "条件判断模块"配置
              "type": 0,// 见下文描述
              "conditions": [//条件列表
                {
                  "type": "URI",
                  "operator": "match",
                  "value": "^/monitor/"
                }
              ]
            },
            "time": "2017-02-18 13:15:20",//规则新建或更改时间
            "name": "monitor",// 规则名称
            "handle": {// "处理模块"配置
              "log": false,// 是否记录日志
              "continue": true// 匹配完该条规则后是否继续后续匹配
            }
          },
          {
            "enable": true, //本条规则是否启用
            "id": "D26E0C12-C687-4004-82C7-9AF258FE6470", //规则id
            "judge": { // "条件判断模块"配置
                "type": 3, // 见下文描述
                "expression": "(v[1] or v[2]) and v[3]", // 见下文描述
                "conditions": [// 见下文描述
                    {
                        "type": "URI",
                        "operator": "match",
                        "value": "/abc"
                    },{
                        "type": "Header",
                        "operator": "=",
                        "name": "uid",
                        "value": "123"
                    },{
                        "type": "Host",
                        "operator": "=",
                        "value": "127.0.0.1"
                    }
                ]
            },
            "time": "2016-05-04 18:57:23",//规则新建或更改时间
            "name": "/abc",// 规则名称
            "handle": { // "处理模块"配置
                "log": false, // 是否记录日志
                "continue": true // 匹配完该条规则后是否继续后续匹配
            }
           }
        ],
        "time": "2017-02-14 22:22:50",
        "handle": {
          "log": true,
          "continue": true
        },
        "type": 0,//0指该选择器是“全流量”选择器, 1指该选择器有一个“条件判断”模块,筛选出的流量才能进入此选择器
        "judge": [],//条件判断模块的配置
        "name": "全流量选择器",
        "id": "173250E2-9EA0-4AF9-BD2E-D400BF2C03A3"
      }
    ]
  },
  "success": true
}

3) 获取选择器信息

请求方式

URI Method 说明
/monitor/selectors Get Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

返回结果

{
  "data": {
    "enable": false, //该插件是否启用
    "meta": {// 该插件的一些基础配置
      "selectors": [ //该插件的所有”选择器“列表
        "173250E2-9EA0-4AF9-BD2E-D400BF2C03A3" //选择器id
      ]
    },
    "selectors": {//选择器详情
      "173250E2-9EA0-4AF9-BD2E-D400BF2C03A3": {
        "enable": true, //该选择器是否启用
        "rules": [ //该选择器下的所有规则id列表
          "aa502670-e428-462e-a4ac-b41c74b88a14"
        ],
        "time": "2017-02-14 22:22:50",
        "handle": { //该选择器的”处理模块“配置
          "log": true, //是否记录日志
          "continue": true //当该选择器退出时,是否继续执行后续选择器
        },
        "type": 0, //0指选择器是“全流量”选择器, 1指该选择器有一个“条件判断”模块,筛选出的流量才能进入此选择器
        "judge": [], //条件判断模块的配置, 这里因为是“全流量”选择器,故为空
        "name": "全流量选择器",
        "id": "173250E2-9EA0-4AF9-BD2E-D400BF2C03A3"//选择器id
      }
    }
  },
  "success": true
}

4) 创建选择器

请求方式

URI Method 说明
/monitor/selectors Post Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector string 要创建的选择器的详细信息

示例(创建一个筛选出所有访问abc.com的流量, 则参数selector的值应为如下字符串):

{
    "name": "过滤abc.com流量",
    "type": 1,
    "judge": {
        "type": 0,
        "conditions": [
            {
                "type": "Host",
                "operator": "=",
                "value": "abc.com"
            }
        ]
    },
    "handle": {
        "continue": true,
        "log": false
    },
    "enable": true
}

返回结果

{"msg":"succeed to create selector","success":true} //失败时success为false

5) 修改选择器信息

请求方式

URI Method 说明
/monitor/selectors Put Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector string 要修改后的选择器的详细信息

示例(我们把上文中创建的选择器做下修改,添加一个过滤条件, 参数selector的值应为如下字符串):

{
    "name": "过滤abc.com流量下URI以/user开始的流量",
    "type": 1,
    "judge": {
        "type": 1,
        "conditions": [
            {
                "type": "Host",
                "operator": "=",
                "value": "abc.com"
            },
            {
                "type": "URI",
                "operator": "match",
                "value": "^/user"
            }
        ]
    },
    "handle": {
        "continue": true,
        "log": false
    },
    "enable": true,
    "id": "b7af8982-11a4-44f9-8777-8a35ef56fa75"
}

返回结果

{"msg":"succeed to update selector","success":true} //失败时success为false

6) 删除选择器

请求方式

URI Method 说明
/monitor/selectors Delete Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector_id string 要删除的选择器id

返回结果

{
    "success": true,
    "msg": "succeed to delete selector"
}

7) 添加规则

请求方式

URI Method 说明
/monitor/selectors/:id/rules Post Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector_id string 此参数从URI里获取,即:id属性, 表示在该选择器下添加规则
rule string 该参数从form data表单里获取, 表示要添加的rule的字符串

示例(创建一个监控以user开头且含有某个header标识的流量):

{
    "name": "监控以/user开头且header里flag为1的流量",
    "judge": {
        "type": 1,
        "conditions": [
            {
                "type": "URI",
                "operator": "match",
                "value": "^/user"
            },
            {
                "type": "Header",
                "name": "flag",
                "operator": "=",
                "value": "1"
            }
        ]
    },
    "handle": {
        "continue": true,
        "log": false
    },
    "enable": true
}

返回结果

{"msg":"succeed to create rule","success":true}

8) 修改规则

请求方式

URI Method 说明
/monitor/selectors/:id/rules Put Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector_id string 此参数从URI里获取,即:id属性, 表示要修改的规则位于该选择器下
rule string 该参数从form data表单里获取,指修改后的”规则”

修改上文创建的规则:

{
    "name": "监控以/user/abc开头且header里flag为1的流量",
    "judge": {
        "type": 1,
        "conditions": [
            {
                "type": "URI",
                "operator": "match",
                "value": "^/user/abc"
            },
            {
                "type": "Header",
                "name": "flag",
                "operator": "=",
                "value": "1"
            }
        ]
    },
    "handle": {
        "continue": true,
        "log": false
    },
    "enable": true,
    "id": "db7b0cb0-5274-46f7-bd93-9f91a44b8f0b"
}

返回结果

{"msg":"ok","success":true}

9) 删除规则

请求方式

URI Method 说明
/monitor/selectors/:id/rules Delete Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector_id string 此参数从URI里获取,即:id属性, 表示要删除的规则位于该选择器下
rule_id string 指要删除的”规则”的id

返回结果

{"msg":"succeed to delete rule","success":true}

10) 获取满足某条规则的请求的统计信息

请求方式

URI Method
/monitor/stat Get

参数

名称 类型 说明
rule_id string 指要获取统计数据的”规则”的id

返回结果

{
    "success": true,
    "data": {
        "average_traffic_read": 0, //请求平均读流量,bytes
        "request_2xx": 0,
        "average_traffix_write": 0, //请求平均写流量,bytes
        "request_4xx": 0,
        "request_5xx": 0,
        "traffic_read": 0,//读总流量,kb
        "request_3xx": 0,
        "traffic_write": 0,//写总流量,kb
        "total_request_time": 0, //总请求时间,s
        "average_request_time": 0, //平均响应时间,ms
        "total_count": 0 //总请求数
    }
}

11) 获取数据库中此插件的最新配置

请求方式

URI Method
/monitor/fetch_config Get

参数

返回结果

{
  "msg": "succeed to fetch config from store",
  "data": {
    "monitor.selector.173250E2-9EA0-4AF9-BD2E-D400BF2C03A3.rules": [
      {
        "enable": true,
        "handle": {
          "log": false,
          "continue": true
        },
        "id": "aa502670-e428-462e-a4ac-b41c74b88a14",
        "time": "2017-02-18 13:15:20",
        "name": "monitor",
        "judge": {
          "type": 0,
          "conditions": [
            {
              "type": "URI",
              "operator": "match",
              "value": "^/monitor/"
            }
          ]
        }
      }
    ],
    "monitor.selectors": {
      "173250E2-9EA0-4AF9-BD2E-D400BF2C03A3": {
        "enable": true,
        "id": "173250E2-9EA0-4AF9-BD2E-D400BF2C03A3",
        "judge": [],
        "handle": {
          "log": true,
          "continue": true
        },
        "type": 0,
        "time": "2017-02-14 22:22:50",
        "name": "全流量选择器",
        "rules": [
          "aa502670-e428-462e-a4ac-b41c74b88a14"
        ]
      }
    },
    "monitor.enable": false,
    "monitor.meta": {
      "selectors": [
        "173250E2-9EA0-4AF9-BD2E-D400BF2C03A3"
      ]
    }
  },
  "success": true
}

12) 将数据库中最新配置更新到此Orange节点

请求方式

URI Method 说明
/monitor/sync Post Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

返回结果

{"msg":"succeed to load config from store","success":true}

基于属性的访问控制: 对含有某些特征的请求做访问控制, 具体可参看pr#58

选择器和规则相关的API使用方法同URL重定向API, 只是规则的字段有所差异。


使用方法同URL重定向API, 只是规则的字段有所差异。


URL重定向: 将请求redirect到其它网址

1) 开启或关闭此插件

请求方式

URI Method
/redirect/enable Post

参数

名称 类型 说明
enable int 0关闭1开启

返回结果

{
    "msg":"succeed to disable plugin",
    "success":true
}

2) 获取所有配置信息

请求方式

URI Method
/redirect/config Get

参数

返回结果

{
  "msg": "succeed to get configuration in this node",
  "data": {
    "enable": true,
    "selectors": [
      {
        "enable": false,
        "id": "1C4A9916-B3BD-4E95-8108-3FBCFF08BEBD",
        "time": "2016-11-13 17:14:32",
        "handle": {
          "log": false,
          "continue": true
        },
        "type": 0,
        "judge": [],
        "name": "全流量选择器",
        "rules": [
          {
            "enable": true,
            "handle": {
              "trim_qs": true,
              "redirect_status": "301",
              "url_tmpl": "https://www.baidu.com/s?wd=",
              "log": true
            },
            "id": "a6451360-efab-41e1-968b-dc95fb479c39",
            "judge": {
              "type": 2,
              "conditions": [
                {
                  "type": "URI",
                  "operator": "match",
                  "value": "/to_baidu"
                },
                {
                  "type": "Query",
                  "operator": "=",
                  "name": "to_baidu",
                  "value": "1"
                }
              ]
            },
            "time": "2017-04-06 19:28:43",
            "name": "将/to_baidu重定向到baidu.com",
            "extractor": {
              "type": 2,
              "extractions": [
                {
                  "type": "Query",
                  "name": "search"
                }
              ]
            }
          }
        ]
      }
    ]
  },
  "success": true
}

3) 获取选择器信息

请求方式

URI Method 说明
/redirect/selectors Get Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

返回结果

{
  "data": {
    "enable": true,
    "meta": {
      "selectors": [
        "1C4A9916-B3BD-4E95-8108-3FBCFF08BEBD"
      ]
    },
    "selectors": {
      "1C4A9916-B3BD-4E95-8108-3FBCFF08BEBD": {
        "enable": false,
        "id": "1C4A9916-B3BD-4E95-8108-3FBCFF08BEBD",
        "time": "2016-11-13 17:14:32",
        "handle": {
          "log": false,
          "continue": true
        },
        "type": 0,
        "judge": [],
        "name": "全流量选择器",
        "rules": [
          "a6451360-efab-41e1-968b-dc95fb479c39"
        ]
      }
    }
  },
  "success": true
}

4) 创建选择器

请求方式

URI Method 说明
/redirect/selectors Post Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector string 要创建的选择器的详细信息

示例(创建一个筛选出所有访问abc.com的流量, 则参数selector的值应为如下字符串):

{
    "name": "筛选abc.com的流量",
    "type": 1,
    "judge": {
        "type": 0,
        "conditions": [
            {
                "type": "Host",
                "operator": "=",
                "value": "abc.com"
            }
        ]
    },
    "handle": {
        "continue": true,
        "log": false
    },
    "enable": true
}

返回结果

{"msg":"succeed to create selector","success":true} //失败时success为false

5) 修改选择器信息

请求方式

URI Method 说明
/redirect/selectors Put Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector string 要修改后的选择器的详细信息

示例(我们把上文中创建的选择器做下修改,添加一个过滤条件, 参数selector的值应为如下字符串):

{
    "name": "过滤abc.com流量下URI以/user开始的流量",
    "type": 1,
    "judge": {
        "type": 1,
        "conditions": [
            {
                "type": "Host",
                "operator": "=",
                "value": "abc.com"
            },
            {
                "type": "URI",
                "operator": "match",
                "value": "^/user"
            }
        ]
    },
    "handle": {
        "continue": true,
        "log": false
    },
    "enable": true,
    "id": "b7af8982-11a4-44f9-8777-8a35ef56fa75"
}

返回结果

{"msg":"succeed to update selector","success":true} //失败时success为false

6) 删除选择器

请求方式

URI Method 说明
/redirect/selectors Delete Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector_id string 要删除的选择器id

返回结果

{
    "success": true,
    "msg": "succeed to delete selector"
}

7) 添加规则

请求方式

URI Method 说明
/redirect/selectors/:id/rules Post Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector_id string 此参数从URI里获取,即:id属性, 表示在该选择器下添加规则
rule string 该参数从form data表单里获取, 表示要添加的rule的字符串

示例(将/to_baidu重定向到baidu.com):

{
    "name": "将/to_baidu重定向到baidu.com",
    "judge": {
        "type": 0,
        "conditions": [
            {
                "type": "URI",
                "operator": "match",
                "value": "/to_baidu"
            }
        ]
    },
    "extractor": {
        "type": 2,
        "extractions": [
            {
                "type": "Query",
                "name": "search"
            }
        ]
    },
    "handle": {
        "url_tmpl": "https://www.baidu.com/s?wd=",
        "trim_qs": true,
        "redirect_status": "301",
        "log": true
    },
    "enable": true
}

返回结果

{"msg":"succeed to create rule","success":true}

8) 修改规则

请求方式

URI Method 说明
/redirect/selectors/:id/rules Put Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector_id string 此参数从URI里获取,即:id属性, 表示要修改的规则位于该选择器下
rule string 该参数从form data表单里获取,指修改后的”规则”

修改上文创建的规则, 增加一个判断条件,当这两个条件任一个为真是则跳转到baidu.com:

{
    "name": "将/to_baidu重定向到baidu.com",
    "judge": {
        "type": 2,
        "conditions": [
            {
                "type": "URI",
                "operator": "match",
                "value": "/to_baidu"
            },
            {
                "type": "Query",
                "name": "to_baidu",
                "operator": "=",
                "value": "1"
            }
        ]
    },
    "extractor": {
        "type": 2,
        "extractions": [
            {
                "type": "Query",
                "name": "search"
            }
        ]
    },
    "handle": {
        "url_tmpl": "https://www.baidu.com/s?wd=",
        "trim_qs": true,
        "redirect_status": "301",
        "log": true
    },
    "enable": true,
    "id": "a6451360-efab-41e1-968b-dc95fb479c39"
}

返回结果

{"msg":"ok","success":true}

9) 删除规则

请求方式

URI Method 说明
/redirect/selectors/:id/rules Delete Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

名称 类型 说明
selector_id string 此参数从URI里获取,即:id属性, 表示要删除的规则位于该选择器下
rule_id string 指要删除的”规则”的id

返回结果

{"msg":"succeed to delete rule","success":true}

10) 获取数据库中此插件的最新配置

请求方式

URI Method
/redirect/fetch_config Get

参数

返回结果

{
    "msg": "succeed to fetch config from store",
    "data": {
        "redirect.meta": {
            "selectors": [
                "1C4A9916-B3BD-4E95-8108-3FBCFF08BEBD"
            ]
        },
        "redirect.enable": true,
        "redirect.selectors": {
            "1C4A9916-B3BD-4E95-8108-3FBCFF08BEBD": {
                "enable": false,
                "judge": [],
                "rules": [
                    "a6451360-efab-41e1-968b-dc95fb479c39"
                ],
                "handle": {
                    "log": false,
                    "continue": true
                },
                "type": 0,
                "time": "2016-11-13 17:14:32",
                "name": "全流量选择器",
                "id": "1C4A9916-B3BD-4E95-8108-3FBCFF08BEBD"
            }
        },
        "redirect.selector.1C4A9916-B3BD-4E95-8108-3FBCFF08BEBD.rules": [
            {
                "enable": true,
                "handle": {
                    "trim_qs": true,
                    "redirect_status": "301",
                    "url_tmpl": "https://www.baidu.com/s?wd=",
                    "log": true
                },
                "id": "a6451360-efab-41e1-968b-dc95fb479c39",
                "judge": {
                    "type": 2,
                    "conditions": [
                        {
                            "type": "URI",
                            "operator": "match",
                            "value": "/to_baidu"
                        },
                        {
                            "type": "Query",
                            "operator": "=",
                            "name": "to_baidu",
                            "value": "1"
                        }
                    ]
                },
                "time": "2017-04-06 19:28:43",
                "name": "将/to_baidu重定向到baidu.com",
                "extractor": {
                    "type": 2,
                    "extractions": [
                        {
                            "type": "Query",
                            "name": "search"
                        }
                    ]
                }
            }
        ]
    },
    "success": true
}

11) 将数据库中最新配置更新到此Orange节点

请求方式

URI Method 说明
/redirect/sync Post Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数

返回结果

{"msg":"succeed to load config from store","success":true}

使用方法同URL重定向API, 只是规则的字段有所差异。


Signature Auth鉴权: 根据请求里提取出的签名字段,判断请求是否合法, 具体参见issues#72

API使用方法同URL重定向API, 只是规则的字段有所差异。


全局统计插件API: 用于获取当前Orange节点的运行状态, 如工作路径、程序版本、启动时间、总请求数、连接数等等。

当前默认为开启状态,暂不提供关闭功能。

请求方式

URI Method
/stat/status Get

参数

返回结果

{
  "data": {
    "total_count": 16194, //总请求数
    "worker_count": 4,
    "con_reading": "0",
    "request_4xx": 16194,
    "ngx_lua_version": "0.10.6",
    "request_3xx": 0,
    "nginx_version": "1.11.2",
    "total_success_count": 0,
    "load_timestamp": 1491468071,
    "con_writing": "1",
    "request_2xx": 0,
    "ngx_prefix": "/usr/local/orange/", //工作路径
    "con_rw": 1,
    "con_active": "2",
    "address": "127.0.0.1",
    "traffic_write": 4611705,
    "traffic_read": 615746,
    "start_time": 1491468071,
    "timestamp": 1491469927,
    "con_idle": "1",
    "request_5xx": 0,
    "total_request_time": 94 //总请求耗时,秒
  },
  "success": true
}

WAF防火墙: 对筛选出的流量做访问控制, 如禁止某种类型的访问。

选择器和规则相关的API使用方法同URL重定向API, 只是规则的字段有所差异。

获取防火墙统计信息

请求方式

URI Method
/waf/stat Get

参数

返回结果

{
    "data": {
        "statistics": [{
            "count": 7, //命中规则的请求个数
            "rule_id": "C4DDC90B-F05C-4F69-94E1-6FCBC4F88392",// 规则id
        }]
    },
    "success": true
}

每个条件的格式如下:

{
    "type": "",
    "operator": "",
    "name":"", //可能为空
    "value": ""
}

实例:

{
    "type": "Header",
    "operator": "=",
    "name": "uid",
    "value": "123"
},
{
    "type": "Host",
    "operator": "=",
    "value": "127.0.0.1"
}

以下针对每个条件的格式作解释:

type即要匹配的数据来源,也就是支持的条件提取方式,目前包括以下几种:

operator即匹配符,指的是要对提取出的值做的操作,包含:

name, 当type为K/V型的来源,如”Header”、”Query”、”PostParams”时此字段不为空,即要从这项来源中提取值对应的key。

value即要匹配的目标值,需要拿提取出的值来跟这个值使用operator做匹配操作。


Orange各模块使用的一些匹配项、匹配符和表达式概念。

匹配项

匹配符

表达式


每个提取器的格式如下:

{
    "type": "",
    "name": ""
},

实例:

{
    "type": "Query",
    "name": "username"
},
{
    "type": "Header",
    "name": "id"
} 

以下针对每个条件的格式作解释:

type即要提取的数据来源,目前包括以下几种:

name指的是如果是K/V行的提取来源,name指要提取的key

如以下示例要提取QueryString里的username这个变量:

{
    "type": "Query",
    "name": "username"
}

变量提取模块,是一系列变量提取器的集合,一般格式如下:

"extractor": {
    "type": 1,//提取器类型,1指索引式提取,2指模板式提取
    "extractions": [
        {//一个提取器
            "type": "Query",
            "name": "wd"
        },
        {
            "type": "Header",
            "name": "from",
            "default": "this_is_default_value"
        }
    ]
}

关于两种变量提取器的描述,可以参看#issues15


后续处理模块,它包含了一些后续处理需要的配置、参数等信息,比如是否需要记录日志、响应状态码、要跳转到的URL、要代理的下游upstream server等等。详细请参看各个插件的配置。


关于Orange设计相关的公开分享请参看OpenResty Con 2016PPT


条件判断模块,是一系列匹配条件和使用方式的集合。它由以下几部分组成


规则rule是Orange中的一个概念,它一般用来筛选出部分请求并对其做各种处理。

一条规则可能包括一个条件判断模块、一个变量提取模块和一个后续处理模块

一般情况下,插件的一条规则会包含条件判断模块和一个处理模块,根据需要选择是否使用变量提取模块,如分流插件就需要变量提取模块,但防火墙插件则不需要。 若用户需要自定义插件,也可使用条件判断模块变量提取模块这些基础功能。

下面通过一个具体的实例看一下它的组成。

格式

重定向插件的一条规则的结构为例,介绍如下(以json格式描述):

{
    "enable": true,
    "name": "用户访问重定向",
    "id": "F7F73D94-AEEB-4B61-9E59-AEDBF200B941",
    "time": "2016-05-04 16:05:03",
    "judge": {
        "type": 1,
        "conditions": [
            {
                "type": "URI",
                "operator": "match",
                "value": "^/user"
            }
        ]
    },
    "extractor": {
        "type": 1,
        "extractions": [
            {
                "type": "Query",
                "name": "username"
            },
            {
                "type": "Header",
                "name": "id"
            }
        ]
    },
    "handle": {
        "trim_qs": false,
        "url_tmpl": "/u/${2}/${1}",
        "log": true
    }
}

字段描述

各个字段的解释如下:

enable

是否开启这条规则

name

规则名称

id

这条规则的id,用于修改和删除

time

添加或者更改时间

judge

条件判断模块,用于筛选请求,详见规则适配器

extractor

变量提取模块,用于提取出请求中的变量供后续使用,详见变量提取模块

handle

这条规则对应的后续处理,如果这条规则有一个下游触发动作,此值不为空。不同的插件这个字段所包含的属性可能不同。

如重定向插件的该字段包括以下属性:

log: 当执行这个动作时,是否要记录日志
url_tmpl: 后续要redirect到的url模板,可在里面使用`变量提取模块`提取出来的值
trim_qs: 是否要清除原始请求的QueryString

judge.conditions

条件集合,每个条件即为对某项值的判断,这个值是从HTTP请求中提取出来的。详见匹配条件

extractor.extractions

从哪些项中提取变量。详见变量提取器


选择器selector ,它可能包括多个rule,即是一个rule group, 选择器内置了一个条件筛选模块(这个模块的概念和使用方法等同于rule里的judge模块),可以将流量进行初步划分。

在多个插件里(比如URL重定向插件、WAF插件、自定义监控插件)都使用了选择器来将流量进行第一步划分, 在流量被一个选择器命中后才会进入它内部的规则过滤。

使用选择器的目的是减少不必要的规则判断,进一步提高性能。


欢迎使用Orange,使用过程中如碰到问题,请到Github进行提问。

关于Orange的公开分享请参看OpenResty Con 2016

关于

Orange是一个基于OpenResty的API Gateway,提供API及自定义规则的监控和管理,如访问统计、流量切分、API重定向、API鉴权、WEB防火墙等功能。Orange可用来替代前置机中广泛使用的Nginx/OpenResty, 在应用服务上无痛前置一个功能丰富的网关系统。它有以下特性:

API

内置插件以HTTP Restful形式开放全部API,详细可查看API文档

注意

Licence

Orange采用MIT协议开源

其它


如何做?

  1. Fork 源码
  2. 克隆Fork后的仓库至你的电脑

     $ git clone https://github.com/<username>/orange.git
    
  3. 创建一个特性分支

     $ git checkout -b new_feature
    
  4. 在new_feature分支上对Orange进行修改
  5. 提交分支:

     $ git push origin new_feature
    
  6. 创建pull request, 并描述具体的改动

注意事项

问题反馈

在使用Orange过程中碰到任何问题,可以到 GitHub 上提问

贡献者

排名不分先后。


提示restynginx命令找不到

Orange提供的默认脚本以及orange cli工具依赖restynginx命令, restynginx命令都是在安装OpenResty时安装的, 如果使用过程中提示找不到, 应该将这两个命令加入到环境变量中。

默认的Dashboard登录账户是什么?

在开启权限验证的情况下, Dashboard需要登录才可使用, 用户名:admin 密码:orange_admin, 登录后再修改或添加其他普通账户即可。

Orange依赖的OpenResty版本是多少?

Orange的监控插件需要统计http的某些状态数据,所以需要编译OpenResty时添加--with-http_stub_status_module。由于使用了*_block指令,所以OpenResty的版本最好在1.9.7.3以上.

全局统计插件不可用?

安装OpenResty时需要开启--with-http_stub_status_module.

Orange是否支持集群?

start.sh脚本无法启动

找不到libuuid.so

Orange现在依赖libuuid来生成规则id,centos用户可尝试使用yum install libuuid-devel安装,其他用户请自行google对应平台的安装方式。

注意: Orange v0.6.0+ 已移除对libuuid的依赖。


Orange是基于插件设计的,基本思想是通过实现各种插件灵活的在Nginx/OpenResty的各个执行阶段进行逻辑处理。

Orange提供的默认插件功能如下:

其它插件,用户可根据具体需要按规范编写即可。

典型使用案例

以下使用案例对于成体系、各职责/配置比较健全的团队来说可能并不存在,但仍可能具有一些参考意义。

Case 1

想象下面的场景:

这时,通过Orange的rewrite/redirect插件就能很方便的解决这个问题,并且实时生效无需重启或是reload:

Case 2

在内部系统中,大量模块或者异构的子系统之间都是通过HTTP交互的,这时不可避免的要引入一个七层负载,选型最多的基本上也就是Nginx了。对于内部网关的管理,可能存在的问题:

Orange提供的WAF插件可以解决这个问题:

此外, Orange还提供了HTTP Basic Authorization和Key Authorization来对API进行动态鉴权

Case 3

应用的AB测试或者流量切分,虽然业界已经有很多方案可供参考,各个公司或团队也有相应实现,Orange给出了另一种动态解决方案


变量提取模块是多个插件中都使用到的一个模块, 它主要用来从请求中提取出各种信息, 比如query string, form表单里的字段, 某个header头等等。

它支持两种提取方式:

关于变量提取方式的设计可参看issues#15

索引式提取

顾名思义, 索引式提取的含义是将提取出的所有变量按照顺序保存在一个数组中, 后续以下标的方式来使用。

比如我们在”变量提取模块”提取了三个值:

那么之后就可以通过${1}、${2}、${3}来使用, 其中

模板式提取

模板时提取主要为了解决索引式提取必须要按序使用的问题, 并且当需要从uri中提取多个值时索引式提取方式并不友好。

如以下示例, 我们提取了四个值:

则之后我们可以通过以下方式来使用:

注意, 若从URI中提取, 仍然要根据顺序来使用, 如{{uri.v1}}、{{uri.v2}}、{{uri.v3}}.


条件判断模块是多个插件中都使用到的一个模块, 它主要用来筛选出目标流量。

对于PostPrams类型的条件, 当前只支持Content-Typeapplication/x-www-form-urlencoded的POST请求。

条件判断模块有四种类型:

其中, 每个条件都支持8种数据来源的8种操作符运算, 可自由搭配。

单一条件匹配

单一条件匹配非常简单, 比如我们想筛选出来自某个IP的流量, 只需:

比如想筛选出访问某个域名的流量, 只需:

and匹配

支持多个条件作and运算,如果结果为真, 则表示该请求命中这个规则, 即筛选出了这部分流量。

比如我们想筛选出来自10.3.2.1访问my_domain.com的请求, 只需:

比如我们想筛选出访问/user这个URI并且query中含有id这个参数, 并且其值大于1234的请求, 只需:

or匹配

or匹配与and匹配类似, 不过是对所有条件作运算。

复杂匹配

注意: 复杂匹配可使用lua条件运算来筛选流量, 但其性能相较于上文几种方式会有下降, 应优先选择前三种流量筛选方式。

复杂匹配需要配置一个表达式,名为expression, 表达式中每个值的格式为v[index], 比如v[1]对应的就是第一个条件的值。

比如我们需要筛选出以下流量:

我们只需如下配置即可:

(v[1] or v[2]) and v[3],即前两个条件至少一个为真并且第三个条件为真时,规则为真, 这时这个请求就被筛选出来了。


自定义监控: 用于对“筛选”出来的流量进行统计、监控。

当前的监控指标有:

示例

监控/user开头的请求流量, 则配置规则如下:

查看监控:


URL重定向主要用于将访问站A的请求redirect到站B, 比较典型的应用是代理某些API。

示例

比如我们要将访问/to_baidu的请求代理到baidu.com, 可如下配置

之后访问/to_baidu?search=abc就会被重定向到https://www.baidu.com/s?wd=abcd

关于图中”规则”的配置请阅读条件判断模块的使用, 关于”处理”时参数值的使用请阅读变量提取模块的使用

特别说明的是:

对于红线标出的值(即要redirect到的地址)需要是一个完整的URL(带域名), 而不能是URI。 若对此概念有混淆感,请首先搞清楚redirectrewrite的区别。


URI重写主要用于站内请求的重写,比如将/user/create重写为/u/new, 当时用浏览器访问被重写的URI时, 浏览器地址栏的URL并不会发生变化, 请特别注意它与URL重定向插件的区别。

示例

比如我们要将访问/rewrite/的请求重写成访问/to_rewrite/的请求, 可如下配置

之后访问/rewrite?a=123时, 真正访问的是/to_rewrite/123

关于图中”规则”的配置请阅读条件判断模块的使用, 关于”变量”、”处理”时参数值的使用请阅读变量提取模块的使用

特别说明的是:

对于红线标出的值(即要rewrite到的地址)需要是一个URI, 而不能是URL。 请特别注意它与”重定向”的区别。