diff --git a/README.md b/README.md index a3474de..07809cc 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,5 @@ ## [ftp域名服务器配置](apache-config-second-header.md) +## [新版序列号设计说明](linx_serial/serial.md) ## + diff --git a/linx_serial/images/check_serial.odg b/linx_serial/images/check_serial.odg new file mode 100644 index 0000000..56eccfc Binary files /dev/null and b/linx_serial/images/check_serial.odg differ diff --git a/linx_serial/images/check_serial.png b/linx_serial/images/check_serial.png new file mode 100644 index 0000000..e8c3e28 Binary files /dev/null and b/linx_serial/images/check_serial.png differ diff --git a/linx_serial/images/new_serialnum.odg b/linx_serial/images/new_serialnum.odg new file mode 100644 index 0000000..190d6cd Binary files /dev/null and b/linx_serial/images/new_serialnum.odg differ diff --git a/linx_serial/images/new_serialnum.png b/linx_serial/images/new_serialnum.png new file mode 100644 index 0000000..afc79b9 Binary files /dev/null and b/linx_serial/images/new_serialnum.png differ diff --git a/linx_serial/serial.md b/linx_serial/serial.md new file mode 100644 index 0000000..b801e18 --- /dev/null +++ b/linx_serial/serial.md @@ -0,0 +1,198 @@ +# 新版Linx_serialnum设计说明书 # + +## 1 引言 ## + +### 1.1 编写目的 ### + +本文档为新版序列号设计说明文档,作为编码、文档编写、及测试的依据。 + +### 1.2 项目概述 ### + +* 为便于技术支持的实施,修改添加序列号不需重启即可生效的机制。 + +* 修改新版序列号的key,原序列号在新系统中将不再适用。 + +* 原序列号只有在开机启动时才会触发检测/proc/cmdline中序列号是否正确,正确则网络可启用。新添加的序列号检测机制,当触发linxsn_trigger时,会调用函数检测/etc/default/grub中配置的序列号,若正确则网络可启用。 + +## 2 总体设计 ## + +1. 原有机制的兼容 + + 保留原有的开机启动检测内核参数(/proc/cmdline)中的序列号是否正确的检测机制。 + +2. 更换原序列号的加密密钥key + + 由于序列号生成工具外流,导致对外安装的系统管理缺失。故需将序列号工具进行后台管理,更换密钥key,只有通过odoo进行申请,才会由后台工具生成可用序列号。 + +3. 添加开机状态下添加序列号生效机制 + + 由于序列号配置后需要重启系统才能生效,导致实施时间拉长,降低效率。为提高实施效率及查看序列号信息,添加序列号检测记录/proc/linxsn和不需重启系统的序列号生效机制。 + +4. 添加虚拟机序列号检测 + + 添加虚拟机序列号检测机制:若为虚拟机,则序列号为通过uuid进行生成,相对应的要添加虚拟机序列号检测。(原序列号类型分为:时间序列号和mac地址永久序列号) + +5. 无root模式下的配置问题 + + 在无root模式下,需sysadmin用户可对序列号进行修改及触发生效。 + +### 2.1 总体结构图 ### + +总体结构框架图: + +![new_linx_serialnum](images/new_serialnum.png) + +检测序列号详解图: + +![new_linx_serialnum](images/check_serial.png) + +添加需求及限制条件:(待补充) + +* 在/proc/linxsn中记录序列号、为时间序列号(到期时间)或者永久序列号。 + +* 当检测为时间序列号时,检测出时间何时到期,打印提示。 + +* 添加虚拟机序列号检测(新类型序列号,检测为虚拟机,则通过uuid生成序列号)。序列号会有三种类型,即:时间序列号、mac地址永久序列号、虚拟机序列号。 + +### 2.2 运行环境 ### + +该软件系统的运行环境:Linx-6.0.42.41 + +## 3 功能模块设计实现 ## + +逐个说明各个模块的实现设计。 + +### 3.1 cmdline内核参数检测机制 ### + +原有序列号检测机制:开机启动网络时,检测/proc/cmdline内核参数中的序列号。获取到序列号后,通过解密检测序列号是否正确。(可参考内核序列号的pantch:linx_serial.patch) + + +```C +// __setup这条宏在Linux Kernel中使用最多的地方就是定义处理Kernel的启动参数的函数及数据结构,宏定义如下: + +#define __setup(str, fn) \ +__setup_param(str, fn, fn, 0) + +``` + +截取如下为获取/proc/cmdline中的序列号: + +```C +static int __init linxsn_setup(char *str) +{ + unsigned int len; + memset(linxsn_buf, 0, LINXSN_LEN + 1); + + len = strlen(str); + if ((len == LINXSN_LEN)||(len == OLD_LINXSN_LEN)) { + strcpy(linxsn_buf, str); + } else { + printk(KERN_WARNING "linx serial number length does \ +not match, the length shuld be %d instead of %d", LINXSN_LEN, len); + } + + linx_debug("linxsn_buf: %s", linxsn_buf); + return 1; +} +__setup("linx_serial=", linxsn_setup); +``` + +### 3.2 获取配置文件序列号参数 ### + +内核中打开文件函数:filp_open()在kernel中可以打开文件,其原形如下: + +```C +struct file* filp_open(const char* filename, int open_mode, int mode); + +``` + +该函数返回strcut file*结构指针,供后继函数操作使用,该返回值用IS_ERR()来检验其有效性。 + +参数说明 + +filename: 表明要打开或创建文件的名称(包括路径部分)。在内核中打开的文件时需要注意打开的时机,很容易出现需要打开文件的驱动很早就加载并打开文件,但需要打开的文件所在设备还没有挂载到文件系统中,而导致打开失败。 + +open_mode: 文件的打开方式,其取值与标准库中的open相应参数类似,可以取O_CREAT,O_RDWR,O_RDONLY等。 + +mode: 创建文件时使用,设置创建文件的读写权限,其它情况可以匆略设为0 + +### 3.3 触发检测机制 ### + +proc文件的创建。创建方法是调用以下函数: + +```C +static inline struct proc_dir_entry *proc_create\ + (const char *name, mode_t mode,struct proc_dir_entry *parent, const struct file_operations *proc_fops); + +/* + name就是要创建的文件名。 + mode是文件的访问权限,以UGO的模式表示。 + parent与proc_mkdir中的parent类似。也是父文件夹的proc_dir_entry对象。 + proc_fops就是该文件的操作函数。 +*/ +``` + +mytest_proc_fops的定义。 + +```C +static const struct file_operations mytest_proc_fops = { +.open = mytest_proc_open, +.read = seq_read, +.write = mytest_proc_write, //做此函数去判断写入的触发值,正确则调用函数处理 +.llseek = seq_lseek, +.release = single_release, +}; +``` + +### 3.4 网络ioctl调用检测序列号机制 ### + +在网络的ioctl函数中,添加序列号检测,通过判断检测序列号的返回值,确定网络是否可用。 + +查看下述代码,只需在触发检测中,检测序列号正确则调用函数设置check_linxsn_flag=1即可。 + +```C + diff -Nurp linux-2.6.32.41.orig//net/ipv4/devinet.c linux-2.6.32.41/net/ipv4/devinet.c + --- linux-2.6.32.41.orig//net/ipv4/devinet.c 2013-06-19 01:12:17.000000000 +0000 + +++ linux-2.6.32.41/net/ipv4/devinet.c 2013-06-19 01:50:08.000000000 +0000 + @@ -62,6 +62,19 @@ + #include + #include + + +#ifdef CONFIG_LINX_SERIAL + +#include + + + +/* + + * check_linxsn_flag + + * 0: need first linx_serial_check + + * 1: linxsn check correct + + * 2: linxsn check incorrect + + * + + */ + +static int check_linxsn_flag = 0; + +#endif + + + static struct ipv4_devconf ipv4_devconf = { + .data = { + [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, + @@ -590,6 +603,19 @@ int devinet_ioctl(struct net *net, unsig + char *colon; + int ret = -EFAULT; + int tryaddrmatch = 0; + +#ifdef CONFIG_LINX_SERIAL + + if (check_linxsn_flag == 0) { + + ret = linx_serial_check(); + + if (ret == -1) { + + check_linxsn_flag = 2; + + printk(KERN_INFO "linx serial number check failed."); + + return -EINVAL; + + } + + check_linxsn_flag = 1; + + } else if (check_linxsn_flag == 2) { + + return -EINVAL; + + } + +#endif + + /* + * Fetch the caller's info block into kernel space + +```