最近动态

学习笔记

kubernetes nginx ingress custom 401/500 page

在k8s中,通常会使用ingress的方式将内部服务进行暴露,与此同时会加上鉴权的功能,如:Basic Auth、Oauth2和JWT等等。

使用方法

在Ingress资源的metadata的annotations中增加nginx.ingress.kubernetes.io/auth-url来指定鉴权的地址。如:nginx.ingress.kubernetes.io/auth-url: http://10.11.0.123:8081/api-auth

这样一来,我们在编写/api-auth这个接口的时候,可以根据请求头拿到客户端的认证信息,进而判断是否对其请求进行放行,返回状态码为200即为放行,nginx会将客户端的请求转发到对应的后端服务;返回状态码为401即表示没有授权,nginx直接对其拦截,并返回给客户端默认的响应。

响应Header头:

1
2
3
4
HTTP/2 401
date: Mon,21 Feb 2022 06:42:41 GMT
content-type: text/html
content-length: 574

响应Body体:

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->

但是客户端仅知道请求是因为授权问题被拒绝了,但是不知道具体的原因,如果需要得知具体的拒绝原因,可以按照如下方法进行优化。

优化方法

因为nginx中没有直接获取upsream返回结果的方法(可通过重新编译,用Lua实现),但是可获取到响应头,所以我们利用响应头来返回拒绝的原因。

首先,在/api-auth中,增加一个响应头my_auth_error,内容可以直接填写您需要返回给客户端的原因,我这里会填入一个json串的Base64编码值。

然后我们回到nginx-ingress的配置文件,增加两个声明:nginx.ingress.kubernetes.io/configuration-snippetnginx.ingress.kubernetes.io/server-snippet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
metadata:
# 此处省略N个字
annotations:
nginx.ingress.kubernetes.io/auth-url: http://10.11.0.123:8081/api-auth
nginx.ingress.kubernetes.io/configuration-snippet: |
error_page 401 = @ingress_service_custom_error_401;

auth_request_set $my_auth_error $upstream_http_wwd_auth_error;
auth_request_set $my_auth_error_content_type $upstream_http_content_type;
auth_request_set $my_auth_status $upstream_status;
nginx.ingress.kubernetes.io/server-snippet: |
location @ingress_service_custom_error_401 {
internal;

# Decode auth response header
set_decode_base64 $my_auth_error_decoded $my_auth_error;

# Return the error from auth service if any
if ($my_auth_error_decoded != ""){
add_header Content-Type $my_auth_error_content_type always;
return 401 $my_auth_error_decoded;
}

# Fall back to default nginx response
return 401;
}
# 此处省略N个字

配置解释

configuration-snippet用来对location进行自定义配置,上面对401的错误页面定义了一个@ingress_service_custom_error_401,然后增加了3个变量my_auth_errormy_auth_error_content_typemy_auth_status分别取值自定义响应头、响应类型和响应状态码。

server-snippet用来对server块进行自定义配置,上面相当于在server块增加了一个location,该location即为401时的默认响应,其中会对my_auth_error进行base64解码,然后判断解码内容,若其内容为空,则直接返回最初的默认401页面,否则在响应头中增加Content-Type为具体的自定义类型,并返回401状态码和自定义响应Body。

如此一来,就可以实现nginx-ingress根据auth接口响应的结果来执行不同的行为。最终实现不同的效果。

响应头:

1
2
3
4
5
HTTP/2 401
date: Mon, 21 Feb 2022 07:14:36 GMT
content-type: text/html
content-length: 51
content-type: application/json

响应Body体:

1
2
3
4
5
{
"message": "用户未登录",
"code": 14,
"data": null
}

参考资料

Custom response for Ingress-Nginx External Authentication

阅读剩下更多

默认配图
学习笔记

记一次使用CGo的Golang项目交叉编译遇到的问题及解决步骤

本篇文章对我在交叉编译EasyDarwin项目到Arrch64架构的Linux上做了简单的记录和总结,总体上遇到的问题分为那么几类: 1. 项目依赖库的缺失和更新 2. syscall.Dup2方法不存在 3. CGO的交叉编译支持 4. 执行二进制文件却提示:No such file or directory

阅读剩下更多

记一次使用CGo的Golang项目交叉编译遇到的问题及解决步骤
学习笔记

利用FFmpeg处理鱼眼视频分成4个方向的视野画面

介绍

首先,FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它的功能强大,这里就不多做阐述了。

本次实验主要是为了学习FFmpeg的Filter功能,它提供了很多音视频的特效处理,比如:视频的缩放、翻转、叠加等等。常用的Filter有:

  • Scale:画面的缩放
  • Overlay:画面的叠加
  • Crop:画面的裁剪
  • More:查看更多

我们可以通过命令查看全部Filter的简介:

1
ffmpeg -filters

实验

原始材料

我们手里现在有一段鱼眼镜头录制的视频源文件,命名:original.mp4。我们先来看看它长什么样子:

out

尝试球形转方形

这一步,我暂时还没找到一个很好的方法把其展平成一个广角镜头全景的画面,但是我使用v360这个filter通过不断修改参数,得到了一个比较满意的部分画面的方形画面。

该Filter的基本参数格式如下:

1
v360=input:output:format_1:arg_name=value

其中inputoutput分别是原始投影格式和目标投影格式,这里我们是从鱼眼视频转换为常规视频,所以要填入的参数为:

1
v360=input=fisheye:output=flat # 都有哪些投影格式,可以通过ffmpeg -h filter=v360获取查看

format_1是指具体要设置的格式,这里我并没有用到。arg_namevalue指具体的参数项和值。

我的使用例子:

1
v360=input=fisheye:output=flat:ih_fov=180:iv_fov=180:h_fov=90:v_fov=60:w=720:h=360:pitch=45

解释一下,其中ih_foviv_fov分别表示设置的输入横向视野范围和输入纵向视野范围,我这里都设置为180度;h_fovv_fov分别表示设置的输出横向视野范围和输出纵向视野范围,我这里设置横向90度,纵向60度。然后还设置了输出画面的宽高为720x360,俯仰旋转角(pitch)为45度。

我的个人理解(个人瞎猜),就如同人眼可接受光的范围,理论上横向和纵向都能够覆盖180度的范围,但是我们在眼球不转动的情况下,有效的水平视野大概是90度,纵向视野60度。因为这个是我具体调参的出来的个人觉得比较好的参数条件,所以不具有权威性!哈哈!

那么现在能输出一个什么样的画面呢?

up

Nice!这就已经很像一个普通摄像头的画面了。那么如何得到其它几个方向的画面呢?前面我们有提到,FFmpeg可以使画面旋转!如果我先将原始画面旋转一下,让其它几个方向的画面都转到上面,然后转换画面不就行了吗?

画面旋转

FFmpeg有个Filter叫做transpose。它可以非常简单的完成画面的旋转或翻转:

阅读剩下更多

利用FFmpeg处理鱼眼视频分成4个方向的视野画面
学习笔记

自建CA服务器学习笔记

​ 我人生中的第一次遇到证书问题并加以解决,还是在大约3年前,那时还专门写了一篇文章《解决Chrome更新到63后.dev/.app后缀域名强制HTTPS的问题》。当时是因为本地开发环境一直都是用的.dev后缀结尾的域名,一直都是以http://www.test.dev的方式进行本地web开发。那天浏览器突然提示访问不安全的网站,此处黑人问号?? Chrome强制.dev后缀的域名都得走https,无奈之下,不想更换后缀的我走上了自签发https证书的道路,但当时直接使用了开源工具,并没有深入研究。

​ 日月如梭,今时今日的我已经不再是那个年少的小孩!日常工作中免不了与SSL/TLS这玩意儿打交道,除了访问web用https外,只要与建立加密连接有关的统统都少不了证书和秘钥。这次需要自建CA服务器并签发下级证书以达到加密访问的目的,那么这次的笔记将会成为以后温习的主要文献了。(哈哈哈)

阅读剩下更多

默认配图
学习笔记

ESP-Touch智能配网是如何实现的

写在前面

近年来物联网发展迅速,目前依旧是比较热门的领域,现今世界处处都是物联网,可谓无处不物联(哈哈,扯远了!)。我接触物联网这块比较晚,去年才开始入门,最早的实战项目就是将传感器上云,借助腾讯的物联网通信平台,我可以对传感器进行远程控制以及读取传感器采集到的数据。当然,这些都离不开网络(Internet)。设备上云的首要前提就是接入互联网,而接入互联网的方式有很多种(如:有线网络、无线WiFi、NB-IoT、移动蜂窝2G/3G/4G等),不同场景下自然有各自合适的网络接入方式。

我们现在生活中的很多智能家电都是通过WiFi接入的,不用我说大家也能举很多例子(像小米智能家居有小爱同学、空气净化器、电视、冰箱、洗衣机等blablabla~),这些设备刚到手的时候你一般都需要按照指导说明去下载个APP,然后绑定设备给设备配网,给设备配网可不像给手机连上WiFi那么容易,毕竟你买的小爱同学不能接鼠标键盘,也没有操作系统给你用。那么配网是如何完成的呢?

快速配网的两种途径:

  1. SoftAP配网
  2. SmartConfig配网

第一种很好理解,就类似给自己家里的路由器配置网络,你首先通过WiFi或者网线连接你家路由器,然后进入http://192.168.xxx.xxx进行Web可视化配置,也有一些小型单片机,自己搭载了一个WiFi模组以AP模式运行,你通过指定的APP就可以与其建立通信并发送配置信息过去。但是这种配网方式比较繁琐,用户体验较差。

第二种就比较高级了,你只需要打开设备的配网开关,并在你的手机上连接即将给设备配置的WiFi网络,然后在App或者小程序上输入对应的密码并点击开始,设备能够在很短的时间内(大约7~30s)就可以完成网络的配置。

这篇文章我将以我自己的学习成果来讲述SmartConfig配网的整个过程

阅读剩下更多

ESP-Touch智能配网是如何实现的
开放平台

腾讯云物联网通信平台设备动态注册鉴权流程

前置条件

物联网平台

  1. 在物联网平台创建新产品(普通产品),认证方式选用“秘钥认证”。
  2. 在产品设置中打开动态注册配置开关,并允许自动创建设备。
  3. 记录产品ID和产品秘钥(ProductID/ProductSecret)。

设备端

  1. 命名设备的唯一标识(如设备MAC、IMEI号、芯片ID等)即DeviceName。
  2. 将物联网平台获取的产品ID和产品秘钥烧录至设备中。

注册流程

第一步:生成验签参数

1
2
3
4
deviceName: #设备名称
nonce: #随机整数
productId: #产品ID
timestamp: #时间戳

拼接字符串“deviceName=%s&nonce=%d&productId=%s&timestamp=%d”,使用HMAC_SHA1算法,ProductSecret作为Key对字符串进行摘要,然后使用Base64编码该摘要获得验签参数(Signature)的值

阅读剩下更多

默认配图
算法

线性插值算法之一维数组矩阵

此篇文章用于记录工作中所需的数据插值算法:线性插值(以两个相邻数据的均值作为中间值插入两数之间)

惊喜预览图:

原始数据:原始采集动图一次插值数据:1次插值数据动图二次插值数据:2次插值数据动图

现有数据是一个8x8的温度矩阵(值为真实温度的100倍),存放在一个长度为64的一维数组中,测试数据如下:

1
2275,2250,2350,2350,2325,2350,2325,2400,2325,2275,2350,2350,2350,2350,2325,2350,2275,2300,2325,2350,2325,2300,2350,2325,2200,2275,2250,2275,2325,2275,2300,2275,2250,2250,2225,2250,2275,2325,2325,2350,2200,2250,2275,2250,2300,2275,2300,2325,2200,2250,2200,2250,2375,2325,2250,2250,2100,2125,2225,2300,2450,2325,2200,2225

问题分析

将8x8的矩阵利用插值算法转化成15x15(8个数据中插入7个虚拟值)矩阵根本思路:

  1. 将8x8的数据进行横向插值为一个15x8的数组;
  2. 将15x8的数字进行纵向插值为一个15x15的数组;

转化公式的分析:

先将问题简化,分析一个4x4的矩阵:

阅读剩下更多

默认配图
Linux

Linux配置网卡(静态)IP地址

上一篇记录了在OrangePi-Zero连接WIFI的过程,今天试着给自带默认网卡配置一下静态IP地址,以方便在整个局域网内能够访问设备。

首先

还是得通过ssh等方式登录Server,然后查看网卡的名称。执行ifconfig命令,找到eth开头的网卡,我这里是eth0

再者

使用vim编辑文件/etc/network/interfaces,增加新行如下:

阅读剩下更多

默认配图
开发板

OrangePi Zero 简单连接WIFI的方法

有幸拿到可爱的小玩意儿“OrangePi_Zero”,也烧写了多个系统去体验,其中可以直接刷写OpenWrt,然后通过web管理界面启用WIFI功能。不过我需要的不是路由器,我需要的是能够连接WIFI的小型Server。

首先

通过ssh等方式登录server,然后查看无线网卡的名称。这里使用iwconfig命令,如果无线网卡正常安装且驱动正常的话,你能够看到一个以wlan开头+数字的的网卡,记住这个名字(我这里是wlan5)。

再者

使用vim编辑文件/etc/network/interfaces,内容如下:

阅读剩下更多

默认配图
学习笔记

利用Dockerfile创建PHP7.3环境镜像

关于Docker以及Dockerfile

Docker容器就不详细介绍了,把它理解成类似“虚拟机”的一种介质吧。至于如何创建一个镜像,主要有两种方法:1. 从现有的镜像基础上,创建容器并自定义后Commit成镜像;2. 利用Dockerfile,根据自己的需要,如同写shell脚本一般,将自己需要搭建的容器环境所需的指令一条一条的汇集成指令集,然后让Docker根据Dockerfile来自动创建你想要的镜像

创建自己的PHP7.3镜像

下载PHP源码:https://www.php.net/downloads.php

我这里下载了php-7.3.6.tar.bz2

阅读剩下更多

默认配图
返回顶部