什么是Luci呢?先直观的感受一下,打开web浏览器,输入R2的网关地址,然后出现了一个web登录界面,这个就是Openwrt Luci的应用。

  那么到底什么是Luci呢?在这里我先给大家一个公式:Luci = lua + uci,然后接下来我针对这个公式去讲解什么是Luci。

  首先简单介绍一下什么是lua和uci;lua是一门编程语言,在后面你会看到它长什么样子,uci(Unified Configuration Interface)是Openwrt的配置框架。

  那么到这里能不能大致猜到Luci是什么了?没错,Luci就是这两者的结合,简单理解就是基于lua语言去实现配置Openwrt。

  我们再回过头来看这个web界面,是不是感觉和家里路由器的配置web界面很相近呀,细心一点看,会看到路径除了IP地址外,还有"/cgi-bin/luci",这里留个伏笔,后面我们会讲到为什么是这个路径。

  那么接下来我们就来看luci的基本用法,以及工作原理,让大家对Luci有一个初步的认识。

  • 初识Luci

  输入账号密码(一般默认是root,root)登录页面,登录后的界面类似于这样:

  从页面上可以看到我们设备的固件、内核版本以及内存等相关信息。

  点击Status => Routes,我们可以看到设备上的路由信息:

  更多的Luci界面的配置细节,我在这里就不过多阐述,后续结合代码的时候再来看部分Luci的配置,接下来我们来看一下Luci的工作原理。

  回到第一个问题,我们在浏览器里输入网关地址“192.168.1.1”,但是为什么Luci的路径是“http://192.168.1.1/cgi-bin/luci”,那么当我们在web输入网关地址后,页面是在哪里被调用的呢?在这里我们就要引入一个概念uhttpd,那么这个uhttpd是个什么东东呢?

   uhttpd是一个轻量级的web服务器,由于其可以和Openwrt的配置框架UCI结合到一起,因此默认被用于OpenWrt的Web管理接口LuCI。
我们都知道,网站都是被部署在一台台服务器,PC等设备上的,我们的设备访问网站时,先是通过网络访问到部署这个网站的服务器,然后服务器的web服务再返回页面给我们;也就是说如果服务器没有web服务,我们是访问不了网页的哦。
  • 接下来我们来看一下uhttpd的UCI配置
root@LEDE:/# cat /etc/config/uhttpd
config uhttpd 'main'
list listen_http '0.0.0.0:80'    #http协议IPV4的监听端口80
list listen_http '[::]:80'      #http协议IPV6的监听端口为443
list listen_https '0.0.0.0:443'
list listen_https '[::]:443'
option redirect_https ''
option home '/www'         #指定根路径
option rfc1918_filter ''
option max_requests '' #最大请求数
option max_connections '' #最大TCP连接数
option cert '/etc/uhttpd.crt' #HTTPS连接的证书路径
option key '/etc/uhttpd.key' #HTTPS连接的私钥路径
option cgi_prefix '/cgi-bin' #cgi脚本的路径,这个路径又是home的相对路径,即/www/cgi-bin
option lua_prefix '/luci' #lua解释器路径,这个路径又是home的相对路径,即/www/luci
option lua_handler '/usr/lib/lua/luci/sgi/uhttpd.lua' #lua runtime初始化的路径
option script_timeout ''
option network_timeout ''
option http_keepalive ''
option tcp_keepalive ''
option ubus_prefix '/ubus' config cert 'defaults'
option days ''
option bits ''
option country 'ZZ'
option state 'Somewhere'
option location 'Unknown'
option commonname 'LEDE'

  当然我们也可以通过uci的命令去查看:

root@LEDE:/www/cgi-bin# uci show uhttpd
uhttpd.main=uhttpd
uhttpd.main.listen_http='0.0.0.0:80' '[::]:80'
uhttpd.main.listen_https='0.0.0.0:443' '[::]:443'
uhttpd.main.redirect_https=''
uhttpd.main.home='/www'
uhttpd.main.rfc1918_filter=''
uhttpd.main.max_requests=''
uhttpd.main.max_connections=''
uhttpd.main.cert='/etc/uhttpd.crt'
uhttpd.main.key='/etc/uhttpd.key'
uhttpd.main.cgi_prefix='/cgi-bin'
uhttpd.main.lua_prefix='/luci'
uhttpd.main.lua_handler='/usr/lib/lua/luci/sgi/uhttpd.lua'
uhttpd.main.script_timeout=''
uhttpd.main.network_timeout=''
uhttpd.main.http_keepalive=''
uhttpd.main.tcp_keepalive=''
uhttpd.main.ubus_prefix='/ubus'
uhttpd.defaults=cert
uhttpd.defaults.days=''
uhttpd.defaults.bits=''
uhttpd.defaults.country='ZZ'
uhttpd.defaults.state='Somewhere'
uhttpd.defaults.location='Unknown'
uhttpd.defaults.commonname='LEDE'

  细看一下,是不是和"/etc/config/uhttpd"里面的uhttpd的配置是一样的,没错,现在我们已经接触到Openwrt的UCI框架了。

  实际上Openwrt里面的所有配置都是在"/etc/config"目录下,我们看一下有哪些配置:

root@LEDE:/etc/config# ls
aria2 firewall luci network sysstat uhttpd
dhcp hd-idle mtkhnat qos system wireless
dropbear kdump mwan3 rpcd ucitrack

  这些配置就构成了整个Openwrt的配置,而管理这些配置的框架正是UCI,我们可以简单去理解,就是UCI = /etc/config/,这样的好处就是方便统一配置,不过你配置什么,只管去"/etc/config"目录下找对应需要配置的服务就好了,而且都是使用uci的方式,十分方便;相比Ubuntu等Linux其它衍生系统的配置文件来讲是要方便和简单很多,后面讲Ubuntu系统的时候,大家就能感受到。

  到这里大家应该对UCI有一个初步的认识了,接下来我们通过继续看uhttpd的那个问题,去认识lua语言,然后让大家更加理解 Luci = lua + uci 这个公式。

  由上面uhttpd的配置来看,当我们通过web的方式访问R2时,uhttpd会导向"/www"的路径,那么我们来看看R2上的"/www"里面有什么。

root@LEDE:/www# ls
/cgi-bin index.html /luci-static
root@LEDE:/www# cat index.html
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="refresh" content="0; URL=/cgi-bin/luci" />
</head>
<body style="background-color: white">
<a style="color: black; font-family: arial, helvetica, sans-serif;" href="/cgi-bin/luci">LuCI - Lua Configuration Interface</a>
</body>
</html>
root@LEDE:/www#

  能看到,"/www"路径下面有个index.html,同时打印出“index.html”的内容,可以看到这个内容“href="/cgi-bin/luci”,原来是这里把网关导向了“/cgi-bin/luci”;那么我们再来看看这个路径里面又有什么?

root@LEDE:/www/cgi-bin# ls         #这里有个luci的脚本
luci
root@LEDE:/www/cgi-bin# cat luci #打印luci这个脚本的内容,可以看到这个脚本里的内容就是lua语言写的
#!/usr/bin/lua
require "luci.cacheloader"
require "luci.sgi.cgi"
luci.dispatcher.indexcache = "/tmp/luci-indexcache"
luci.sgi.cgi.run()

  这个路径下面放着一个lua的脚本,脚本里面调用了这个接口“luci.sgi.cgi.run()”,那么这个接口执行的函数在哪里呢,在这里:

root@LEDE:/usr/lib/lua/luci/sgi# ls
cgi.lua uhttpd.lua
root@LEDE:/usr/lib/lua/luci/sgi# cat cgi.lua
-- Copyright Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0. *************** function run()
local r = luci.http.Request(
luci.sys.getenv(),
limitsource(io.stdin, tonumber(luci.sys.getenv("CONTENT_LENGTH"))),
ltn12.sink.file(io.stderr)
) local x = coroutine.create(luci.dispatcher.httpdispatch)
local hcache = ""
local active = true while coroutine.status(x) ~= "dead" do
local res, id, data1, data2 = coroutine.resume(x, r) if not res then
print("Status: 500 Internal Server Error")
print("Content-Type: text/plain\n")
print(id)
break;
end if active then
if id == then
io.write("Status: " .. tostring(data1) .. " " .. data2 .. "\r\n")
elseif id == then
hcache = hcache .. data1 .. ": " .. data2 .. "\r\n"
elseif id == then
io.write(hcache)
io.write("\r\n")
elseif id == then
io.write(tostring(data1 or ""))
elseif id == then
io.flush()
io.close()
active = false
elseif id == then
data1:copyz(nixio.stdout, data2)
data1:close()
end
end
end
end

  run()函数就在cgi.lua里面;现在我们可以初步了解到,lua语言就是这样被Luci使用的。

  那么我们再整体看一下整个访问流程:web(输入网关地址)==> uhttpd调用"/www/index.html" ==> index.html重定向到"/cgi-bin/luci" ==> luci被启动。讲到这里可能大家对Luci有一个初步的认识了,由于Luci涉及lua语言,这门语言不像Java,C普及率那么高,我这里暂时也点到为止,更多Luci的知识后续有时间我会继续和大家一起研究。

  Luci Github:https://github.com/openwrt/luci

【玩转开源】BananaPi R2 —— 第四篇 Openwrt Luci 初探的更多相关文章

  1. 【玩转开源】BananaPi R2 —— 第三篇 基于Openwrt开发一个简单的路由器

    上一篇讲解了R2的网口配置,这一篇我们以BananaPi R2为例子来实现一个简单的路由器:那么一个简单的路由器应该具备什么样的功能呢?最简单的说就是wan+lan+ap这三个功能. 首先wan+la ...

  2. 【玩转开源】BananaPi R2 —— 第一篇 Openwrt安装

    最近手上拿到一块香蕉派的R2,这块板子可以用作路由器,所以决定在板子上面跑一下Openwrt. R2的外观长这个样子,看起来还是比较酷的: 硬件介绍 CPU 是MTK的4核芯片mt7623n,搭配mt ...

  3. 【玩转开源】BananaPi R2 —— 第二篇 Openwrt 网口配置分析

    上次和大家分享了如何烧录和安装Openwrt到BananaPi R2,运行Openwrt的R2目前就具备路由器的功能了,这次我们来看看R2运行Openwrt的性能如何,同时也会讲解一些常用的网络知识. ...

  4. Excel催化剂开源第50波-Excel与PowerBIDeskTop互通互联之第四篇

    答应过的全盘分享,也必承诺到底,此篇PowerBI功能分享的最后一篇,讲述如何导出数据模型的元数据,笔者定义其为模型的数据字典. 此篇对应功能实现出自:第6波-导出PowerbiDesktop模型数据 ...

  5. 第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理

    温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发 第三篇 :微信公众 ...

  6. 第四篇 SQL Server代理配置数据库邮件

    本篇文章是SQL Server代理系列的第四篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.SQL Serve ...

  7. 第十四篇 Integration Services:项目转换

    本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...

  8. 【玩转开源】Linux C 检测网口热插拔

    int NetDetect(char *net_name, int *statue) { int ret = 0; ; struct ifreq ifr; skfd = socket(AF_INET, ...

  9. 【译】第十四篇 Integration Services:项目转换

    本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...

随机推荐

  1. OpenCV和selenum实现点击操作

    import cv2 as cv import numpy as np from PIL import Image, ImageDraw, ImageFont import os from selen ...

  2. PAT 甲级真题题解(1-62)

    准备每天刷两题PAT真题.(一句话题解) 1001 A+B Format  模拟输出,注意格式 #include <cstdio> #include <cstring> #in ...

  3. Linux-KVM虚拟化

    kvm安装 1.在宿主机上准备好yum(只需要本地镜像yum就可以) 2.查看CPU是否支持inter或AMD的虚拟技术 # cat /proc/cpuinfo |grep -E "vmx| ...

  4. SQLServer版本

  5. ansible-playbook用法

    一.playbook用法 1.playbook的执行文件为YAML语言编写,所以文件名为xxx.yml.YAML语法可以参考https://docs.ansible.com/ansible/lates ...

  6. Java 集合系列之二:List基本操作

    1. Java List 1. Java List重要观点 Java List接口是Java Collections Framework的成员. List允许您添加重复元素. List允许您拥有'nu ...

  7. Redis源码 - 事件管理

    Redis 的事件分类 分类 描述 定时器 线程内定时响应,更新缓存时间.关闭非活动的客户端连接等等 pipe 线程间通信,用于其他线程通知主线程退出aeApiPoll() unixsocket 本地 ...

  8. 080、Weave Scope 容器地图(2019-04-28 周日)

    参考https://www.cnblogs.com/CloudMan6/p/7655294.html   Weave Scope 的最大特点是会自动生成一张 Docker 容器地图,让我们能够直接的理 ...

  9. 第31月第10天 tableview头部空白 Other Linker Flags rtmp

    1.ios10 tableview头部空白 if (@available(iOS 11.0, *)) { self.tableView.contentInsetAdjustmentBehavior = ...

  10. easyui 菜单树搜索

    //树形菜单搜索方法    function searchTree(treeObj,parentNode,searchCon){        var children;        for(var ...