最近CentOS7
服务器上遇到一个系统崩溃:
1 | [92957.332974] BUG: unable to handle kernel NULL pointer dereference at 0000000000000a30 |
Keep learning, keep living...
最近CentOS7
服务器上遇到一个系统崩溃:
1 | [92957.332974] BUG: unable to handle kernel NULL pointer dereference at 0000000000000a30 |
SSH
不仅可以使用远程管理主机,还可以利用SSH
客户端和SSH
服务器之间的加密连接为其他服务实际中继服务,这一般称为SSH隧道(SSH Tunneling)
或者SSH端口转发
。
SSH
端口转发分为三种类型:
无论是哪种端口转发,整个过程都涉及四个角色:
这些角色进程并不要求都位于独立主机上,它们可以位于同一台主机上,使用localhost
或者127.0.0.1
进行网络访问。
本文基于这4种角色来简要说明这三种端口转发的过程。三种端口转发都依赖SSH客户端
和SSH服务器
建立一个加密连接在二者之间转发数据。
近期我们的BASH
脚本中遇到一个BUG,最终分析到是变量值为空时没有用""
包裹导致的。
我们使用一个测试脚本来进行分析。测试脚本t.sh
内容如下:
1 | #!/bin/bash |
测试脚本的执行结果如下:
1 | [root@default ~]# bash t.sh |
可以看到当变量$kof
为空时,第一个if
语句块中的语句没有被执行,而第二个if
语句块中的语句被执行了。这两个语句块的差别就在于第二个语句块中的$kof
变量用""
进行了包裹。
近期遇到一个服务器上内核模块无法卸载的问题。执行rmmod
命令返回错误信息:
1 | Device or resource busy |
通过Google搜索,发现其他人也遇到过类似的问题,原因基本指向是编译内核模块的gcc
版本和编译内核的gcc
版本不一致。
于是开始检查我们的环境。
seccomp
代表secure computing
,是早在2.6.12
版本就引入到内核的特性,用来限制进程可以使用的系统调用
。它作用于进程里的线程(task
)。
最初,seccomp
只允许使用read
, write
, _exit
, sigreturn
4个系统调用,调用其他系统调用时,内核会发送SIGKILL
信号终止进程。当时seccomp
的提出主要是想用于出租空闲的CPU算力。这种模式叫做STRICT
模式。它限制过于严格,在实际应用上并没有太多发展。Linus Torvald
甚至建议把它从内核中砍掉。
OTP
是One Time Password
的缩写,是进一步加强身份认证的安全性的校验方法, 一般配合常规密码一起使用。OTP
动态生成,只使用一次。手机验证码就是典型的OTP
方式。用户请求一个短信验证码, 服务器随机生成一个验证码,然后临时存储起来,通过短信发送给用户。用户在系统上输入验证码发送回服务器,服务器根据临时存储的验证码进行校验。
生成OTP
业内有许多标准算法,比如SHA-1
。所有这些算法都包括两部分输入:
种子值(seed)
:静态值,和帐号关联的密钥可变因子(moving factor)
:每次生成OTP
都变化的部分之前的文章<<使用eBPF和BCC调查创建文件的进程>>介绍了基于BCC
来实现eBPF
程序。BCC
实现了对eBPF
的封装,用户态部分提供Python API, 内核态部分使用的eBPF
程序还是通过C
语言来实现。运行时BCC
会把eBPF
的C
程序编译成字节码、加载到内核执行,最后再通过用户空间的前端程序获取执行状态。
可以在BCC
的BPF
调用中,指定参数debug=4
, 我们可以看到BCC
的执行过程, 如:
1 | from bcc import BPF |
eBPF
编程的门槛还是比较高的,在当前还是快速发展的情况,API也还不稳定,对程序员的C
语言、编译过程和内核等知识都有比较高的要求。BCC
把这些都封装起来给用户提供了一个更为简单的使用框架。但本身也存在的一些问题,比如:
eBPF: extended Berkeley Packet Filter
是对BPF
(现在称为cBPF: classic BPF
)的扩展, 现在尽管还叫做BPF
, 但应用场景已经远远超过了它的名称的范畴。它的应用范围的扩大主要得益于这几方面:
BPF
字节码虚拟机扩展为一个通用的执行引擎JIT
支持,可以直接将字节码指令转成内核可执行的原生指令运行这样在安全性、可编程性和性能方面的提升都使得eBPF
在包过滤以外的其他领域获取巨大的应用空间。
在我们的一个CentOS 7.8
系统上,/tmp
目录下偶尔会有一些随机名称的文件产生。业务比较久远,已经不清楚这些文件的来源,需要确定是哪个进程在创建它们。
Linux
以VFS: Virtual File System
通用文件模型的方式在物理存储介质上的文件系统和用户接口之间建立一个虚拟文件系统的抽象层。其中最重要的两个结构是:
inode
: 存放文件的一般信息,每个inode
结构都有自己的编号,这个号码唯一标识了文件系统中的文件。dentry
: 存放文件名称信息,以及与对应文件进行链接的有关信息。VFS
创建文件的最主要的步骤是:
dentry
结构inode
结构并分配inode
编号inode
编号和文件名映射关系保存在所分配的dentry
结构中dentry
写入到父目录的数据区SOCKS
是一个比较简单的通用代理协议,用于在客户端与服务器之间代理网络数据包。最新的版本是5
, 所以一般叫做SOCKS5
,协议规范是RFC1928。但SOCKS5
并不兼容之前的SOCKS4
和SOCKS4A
。SOCKS5
在SOCKS4
的基础上添加了UDP
转发功能和校验
机制。
SOCKS5
的工作过程简单可以归纳为协商、请求、和转发三个阶段。以TCP
代理场景来看, 一般流程是:
SOCKS5
支持不同的请求类型,包括CONNECT
, BIND
, UDPASSOCIATE
等。其中,2-4完成协商阶段,5-7完成请求阶段,之后进入转发阶段。
当前常用的校验方法是USERNAME/PASSWORD
(RFC1929)和GSS-API
(RFC1961),具体的校验过程是由不同校验方法来自定义的。
使用USERNAME/PASSWORD
校验方法的TCP
代理时序图如下:
我们的业务Docker
镜像是在centos/systemd镜像基础上构建的,业务进程由systemd
来启动。最近需要对业务逻辑进行改造,需要识别传入的环境变量。看上去是相当简单的改动,但在我们的进程中加入读取环境变量的逻辑却发现读取不到传入的变量内容,最终定位原因是在systemd
的环境变量的处理。