分类:默认分类

Linux capabilities

  • 对于权限细节参考man 7 capabilities;
  • 对于-+= eip操作符参考 man 3 cap_from_text;
  • 文档中命令setcap、getcap等都可以通过man命令查看;

我需要在VS Code 调试NuttX应用,它的Sim应用需要cap_net_raw,cap_net_admin权限,否则就无法正常操作HCI设备。

当然网上有一些帖子尝试将VS Code或者GDB运行在root用户,显然这样操作是非常不优雅的。

所以这里尝试给需要调试的应用利用linux capabilities直接给可执行文件设置权限。

此时运行程序,可以通过capsh或者getcaps检查进程确认已经设置成功。

此时通过VS Code启动调试后发现其却没有了需要的文件权限。

看起来是父进程/usr/bin/gdb 启动nuttx进程的时候并没有使用其文件文件属性。

直接测试了gdb ./nuttx确认和上面现象一致,strace确认其通过ptrace创建进程。

怀疑这里是gdb进程没有cap_sys_ptrace权限,添加后再次通过VS Code启用nuttx调试发现其进程已经具有我们需要的权限。

udp发送ip端口发送不可达

众所周知,udp是无连接的,所以忽略udp接收方状态,是否监听对应udp端口以及ip是否存在,直接向udp发送数据,会发生什么?

为了搞清楚这个问题,我们尝试在局域网建立收发设备,然后抓包分析。

从抓包来看,udp数据正常发出。对端设备回复icmp指示端口不可达。

当我们把接收端设备关机,此时udp数据正常发出,直到arp连续三次请求失败。此时抓包显示udp包已经不发送了。

此时,我们跟踪sytem call 确定,发用户空间的sendto 接口仍然显示成功。

此时通过查看arp缓存确定ip状态已经标记为INCOMPLETE。

尝试手动更新arp缓存的mac地址和状态到REACHABLE。

此时udp又重新发了出来。

值得一提的是,在路由器查看arp缓存,发现不管设备断开多久,状态都不会变更为INCOMPLETE而始终是STALE。

一次无效的运维

这里记录一次无效的运维,称之为无效,更多的是我人为原因引起的。

1月2号阿里云提示服务器执行恶意脚本,当时正在休元旦,直接忽略。

1月4号上班的时候查看了完整提示,分析了启动上下文,确定服务器被redis恶意注入矿机脚本。能够被注入原因很简单,把无认证的redis直接暴露了在公网,因为该服务器是从其他公司过户过来,稳定运行了5年,接手后保持原来的端口安全策略也没有注意。

第一时间分析了该脚本启动脚本,发现其破坏了大量系统安全策略,同时预留了大量系统认证的后门,例如:

  • 安装矿机应用;

  • 杀死阿里云安全组件;
  • 关闭selinux,开门狗等系统安全组件;
  • 预留ssh认证公钥,预留系统系统登录账号;

而该脚本注入应该是利用redis持久化,把keys保存在了/etc/crontab,好在我们应用工作在docker,并未关闭掉阿里的安全组件,所以阿里第一时间通知我。同时,该脚本只是注入矿机执行,并没有破坏原来的系统应用,也算是盗亦有道了。

正常来说我只要按照该脚本关闭矿机启动,删除应用,恢复安全策略就行了,但是手贱顺便按照阿里提示升级了网络类型从经典网络到专有网络,噩梦就此开始。

之所以升级网络类型,是因为这前后阿里曾打电话告知,3月份之前不升级会导致网络不可用,这台机器几年不运维一次,所以干脆一劳永逸。

升级完网络类型后服务启动异常,第一时间没有定位到原因,所以直接考虑恢复快照。

第一时间提了阿里工单,但是阿里解决...

OpenID over OAuth2.0 详解

需要在Thingsboard上面加OAuth Server功能。

如上是一开始的需求,但是随着深入理解,这里的OAuth Server并不正确,所以需要先科普知识。

对于OAuth ,参考OAuth2.0,里framework里面并没有定义OAuth Server 角色。它定义了4个角色

  • Resource Ower;

    资源拥有者;

  • Resource Server;

    资源服务器,对外提供访问接口;

  • Client

    客户端,需要访问资源的对象;

  • Authorization Server;

    授权服务器;

尽管我们还不知道明确这角色的区分,但是我们需求更接近Authorization Server。

接下来理解OAuth2.0 的协议流程。

看图理解,比较简单。

  • A 客户端发起受保护源请求;
  • B 资源拥有者同意访问,返回授权码;
  • C 客户端通过该授权码继续请求;
  • D 授权服务器分配访问访问令牌;
  • E 客户端通过令牌完成保护资源的访问;
  • F 完成保护资源的访问;

对于过程B,区分不同授权类型(Grant Type),详细参考rfc6749#section-1.3. Authorization Grant,对于OAuth2.0 用以登录,也就是Thingsboard 的OAuth login功能,其实采用了这里的4.1. Authorization Code Grant

在该类型下,OAuth login完整交互流程如下。

这里引入...

socat

http://www.dest-unreach.org/socat/

socat 是一个命令行工具,用以建立一个双向字节流交换数据。该字节流又可以被构造成不同地址类型,大量的地址选项也同样可以被作用于该流,因此socat非常强大。

filan 是一个打印文件描述符的工具,已经被重构用以调试socat,当然,也可以另做它用。

procan 是一个打印进程信息的工具,同样被重构用以调试socat。

socat 实例包含如下生命周期。

init 阶段解析命令参数,初始化日志打印;

open阶段打开第一个地址并且转发到第二个地址字节流,此阶段可能会阻塞,因此类似socks的复杂地址选项,需要在连接请求或认证对话框完成后才会开始下一阶段。

transfer阶段通过select 参数观察源地址流的读写操作,当可读或者可写时,socat完成到目的流数据转发。

当任意一方流eof,closing阶段开始,socat 主动发送eof操作到对等需要关闭的另外一方尝试优雅的关闭它的写操作的字节流,在运行的时间范围内,socat也可能会继续传输数据到另外一个方向,直到所有的通道被关闭。

命令的地址参数为用户给socat 建立字节流的必要信息。

一个地址规范通常包含一个地址类型的关键词,零或者多个地址参数通过":"间隔,零或者多个地址选项通过","间隔。

关键词指定地址类型(tcp4、open、exec),而对于一些关键字存在...

在linux 下通过vscode调试elf可执行文件

elf 是linux 下可执行可链接文件(executable and linkable format)。通过gcc/make 我们很容易编译出我们需要的elf文件,借助vscode可以在ubuntu图形化调试该程序,再也不用在gdb命令操作了。

如下是elf文件结构,包含文件头(elf header)和代码、数据区索引表(program header table、section header table)和对应代码区、数据区。

明白了如上文件结构,还需要具体解答如下疑惑。

  • 什么文件可以被调试?

    通过file命令对比可以知道用以调试的文件包含 with debug_info。

    可以被调试的文件。

  • debug 版本额外包含什么信息?

    如上可调式的elf文件中增加包含 debug_aranges、debug_info等7个section存储包含数组、文件信息、行数、字符串、宏等调试信息。

    可以通过 --debug-dump=aranges/info/abbrev/line/str/ranges/macro分别显示对应的 区信息。

  • 如何设置debug/release 版本?

    知道了用以调试的程序信息,那么如何编译对应程序的debug版本,通常来说编gcc的 -gdebug 选项和-O优化选项:

有了如上elf文件认识,接下来就是vscode debug程序了,成功编译可执行文件后,通过vscode 建立工程添...

在局域网建立.local域名

需要理解linux下面的几个概念。

主机名,默认保存在/etc/hosname,可以通过命令hostname查看和更改。

本地域名文件,配置后再本机立即生效。默认地,会设置本机hostname到hosts使之映射到127.0.0.1。同样地,局域网内也可以通过http://hostname 到该机器。

mdns 即多播dns(Multicast DNS),mDNS主要实现了在没有传统DNS服务器的情况下使局域网内的主机实现相互发现和通信,使用的端口为5353,遵从dns协议,使用现有的DNS信息结构、名语法和资源记录类型。并且没有指定新的操作代码或响应代码。在局域网中,设备和设备之前相互通信需要知道对方的ip地址的,大多数情况,设备的ip不是静态ip地址,而是通过dhcp协议动态分配的ip 地址,如何设备发现呢,就是要mdns大显身手,例如:现在物联网设备和app之间的通信,要么app通过广播,要么通过组播,发一些特定信息,感兴趣设备应答,实现局域网设备的发现,当然mdns 比这强大。

当mDNS客户端需要解析主机名时,它会发送一个IP多播查询消息,要求具有该名称的主机标识自己。然后该目标机器多播包含其IP地址的消息。然后,该子网中的所有计算机都可以使用该信息来更新其mDNS高速缓存。任何主机都可以通过发送生存时间(TTL)等于零的响应数据包来放弃其对名称...

thingsboard 开发环境建立

  • git

    版本管理工具,注意配置环境变量,保证命令窗口能够直接使用。

  • oracle jdk

  • node.js

    现在安装成功后,需要配置环境变量。保证在cmd窗口node能够直接运行,并且通过node -v 查询版本后修改thingsboa()rd 工程中的pom.xml。

  • maven

    工程是基于maven管理,直接通过idea open,之后会自动下载各种依赖包。

    C:\Users\yuren\.m2\repository

    按需设置maven镜像源,否则下载速度可能不稳定。在maven安装包目录下找到settings.xml更改,详细参考,https://developer.aliyun.com/mvn/guide

  • npm

  • idea intellj

    集成开发环境,内部集成maven。

  • docker
  • postgresql

    D:\my_project\thingsboard\dao\src\main\resources\sql

git clone 整个thingsboard 工程。

成功clone 工程后目录结构如下。

这里阐述thingboard在win下的开发环境快速建立,包含工程建立、编译、调试环境。

  • 装jdk、maven、node、git并且注意配置环境变量,确定命令能够直接运行,同时设置maven、node镜像源;
  • 通过maven编译整...

a64 uboot 代码走读

已经完整梳理主要程序流,对于每个主程序流会按章节阻逐个细化分解。

  • uboot 入口main

    main完成一些状态初始化和标记,之后通过board_init_f和board_init_r 完成早期、中期初始化工作;

  • 对于如上初始化board_init_f主要通过预定义并且初始化的函数指针列表init_sequence_f[]依次执行完成;

    同样地,对于board_init_r 通过预先定义好的init_sequence_r 数组依次完成函数调用;

  • 之后程序进入main_loop 通过解析预定义环境变量bootcmd=x执行后续操作。

    bootcmd的函数实体通过预先定义好命令序列。

    完成boot image的查找查找android 引导分区,为kernel 跳转查找基地址;

    在这里完成boot到kernel 基地址跳转;

详细分析mmc初始化流程。

allwinner a64支持uboot阶段显示静态图片,这里梳理程序结构,确定gac-350未什么未生效,同时确定从boot->rootfs 整个过程显示蓝屏的根本原因。

从如上代码走的来看,lcd完整驱动区分如下层次关系;

此uboot中的disp模块同内核/linux-3.10/drivers/video/sunxi/disp2/disp中的一一对应。

不同的是,内核中的显示驱动通过内核模块的方式加载。也就是,在uboot通过的boardc_r.c ...

windows node 开发环境建立

本文详细介绍基于gac-350 门禁的node windows 开发环境的搭建,以及用以该门禁远程编译调试node工程。

gac-350 smart-device-node 工程代码通过gitlab管理.

gac-350 smart-device-node 通过typescript 编码实现,ts通过解释成js后运行。

集成开发环境使用itellij,习惯vs的可以选择vs201x/vscode.

gac-350 门禁通过supervisor守护node 工程运行,程序入口通过supervisor配置文件到npm start 再到 packge.json 包管理的start命令。

itellij 直接通过 ide itellij idea官方下载,直接双击安装,成功安装后破解参考IntelliJ IDEA 最新注册码

  • 修改本机host文件

  • 添加注册码

node 解释器和sdk通过nodejs.org,成功下载后双击默认安装。

成功安装itellij后通过New->Project->node->Node.js and...