共享秘钥模式下XAUTH验证流程

2023-11-27 22:40

本文主要是介绍共享秘钥模式下XAUTH验证流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

以下根据strongswan代码中的testing/tests/ikev1/xauth-psk/中的测试环境,来看一下XAUTH验证流程。拓扑结构如下:

在这里插入图片描述

拓扑图中使用到的设备包括:虚拟网关moon和主机carol及dave。

moon网关配置

moon的配置文件:/etc/ipsec.conf,内容如下。注意此处keyexchange字段的值,使用ikev1版本协议。在名称为rw的连接配置中,leftauth和rightauth字段都指定了psk共享秘钥认证,另外rightauth2的值xauth,表明执行第二级的XAUTH认证。

conn %defaultkeyexchange=ikev1conn rwleft=PH_IP_MOONleftid=@moon.strongswan.orgleftsubnet=10.1.0.0/16leftauth=pskleftfirewall=yesright=%anyrightauth=pskrightauth2=xauth

PSK模式和XAUTH认证的秘钥信息保存在文件/etc/ipsec.secrets中,内容如下。对于ID值为carol@strongswan.org和dave@strongswan.org的连接使用不同的XAUTH秘钥。

moon.strongswan.org %any : PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jLcarol@strongswan.org : XAUTH "4iChxLT3"dave@strongswan.org  : XAUTH "ryftzG4A"

配置文件/etc/strongswan.conf中的插件xauth-generic负责处理XAUTH相关认证工作。其相关代码位于目录:strongswan-5.8.1/src/libcharon/plugins/xauth_generic/。

charon {load = random nonce aes sha1 sha2 hmac curve25519 xauth-generic kernel-netlink socket-default updown stroke
}

主机配置

carol主机的配置文件:/etc/ipsec.conf,内容如下。其中与网关moon使用相同的ikev1版本协议以及共享秘钥psk认证。此外,leftauth2的值xauth表明本机将进行第二级的XAUTH认证。

conn %defaultkeyexchange=ikev1conn homeleft=PH_IP_CAROLleftid=carol@strongswan.orgleftauth=pskleftauth2=xauthleftfirewall=yesright=PH_IP_MOONrightsubnet=10.1.0.0/16rightid=@moon.strongswan.orgrightauth=pskauto=add

PSK秘钥和XAUTH秘钥保存在carol主机文件/etc/ipsec.secrets中,如下所示。可见其与moon网关的/etc/ipsec.secrets文件中指定的秘钥相同,否则无法完成认证。

: PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jLcarol@strongswan.org : XAUTH "4iChxLT3" 

此外,carol主机的strongswan.conf文件中同样加载了xauth-generic插件。dave主机的配置与carol基本系统,区别在于一些主机相关选项和XAUTH秘钥的差别。

连接建立流程

分别在三台机器上启动strongswan进程,以及在carol和dave主机上启动home连接。

moon::ipsec start
carol::ipsec start
dave::ipsec start
moon::expect-connection rw
carol::expect-connection home
carol::ipsec up home
dave::expect-connection home
dave::ipsec up home

在ikev1的主模式第一报文中,carol主机通告了对XAUTH的支持,如下报文,

在这里插入图片描述

接下来在回复报文中,moon网关同样通告了对XAUTH的支持,如下。

在这里插入图片描述

之后XAUTH认证在第一阶段Main模式和第二阶段Quick模式之间开始进行,其增加了4个Config配置模式的报文来完成XAUTH认证。

在这里插入图片描述

第一个报文由moon网关发到carol的请求报文,类型为:ISAKMP_CFG_REQUEST(1),其请求两个属性:XAUTH_USER_NAME(16521)和XAUTH_USER_PASSWORD(16522)。

在这里插入图片描述

第二个报文为carol的回复报文,类型为:ISAKMP_CFG_REPLY(2),其在属性XAUTH_USER_NAME和XAUTH_USER_PASSWORD中分别携带自身的用户名(carol@strongswan.org)和秘钥(4iChxLT3)。此与moon网关配置的秘钥相同。
在这里插入图片描述

第三个报文为moon网关发送的验证结果报文,类型为:ISAKMP_CFG_SET(3),其中属性XAUTH_STATUS表明,此次认证成功(值为1)。

在这里插入图片描述

最好一个报文为carol对验证结果的确认,类型为:ISAKMP_CFG_ACK(4),其中属性XAUTH_STATUS带有长度为0的值(无值)。

在这里插入图片描述

状态信息

使用ip命令在moon和sun网关上查看创建的GRE隧道设备,ikey和okey两个方向的值都为42。

moon:~# ip -d link show gre-moon
24: gre-moon@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1472 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000link/gre 192.168.0.1 peer 192.168.0.2 promiscuity 0 gre remote 192.168.0.2 local 192.168.0.1 ttl inherit ikey 0.0.0.42 okey 0.0.0.42 addrgenmode eui64 numtxqueues 1 gso_max_size 65536 gso_max_segs 65535 
moon:~#sun:~# ip -d link show gre-sun
26: gre-sun@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1472 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000link/gre 192.168.0.2 peer 192.168.0.1 promiscuity 0 gre remote 192.168.0.1 local 192.168.0.2 ttl inherit ikey 0.0.0.42 okey 0.0.0.42 addrgenmode eui64 numtxqueues 1 gso_max_size 65536 gso_max_segs 65535 
sun:~# 

使用ip route命令查看为gre-moon虚拟接口添加的路由信息,目的网段10.2.0.0/16(bob主机所在网段)的流量路由到gre-moon接口。

moon:~# ip route
default via 192.168.0.254 dev eth0 onlink 
10.1.0.0/16 dev eth1 proto kernel scope link src 10.1.0.1 
10.2.0.0/16 dev gre-moon scope link 
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.1 
moon:~# 

XAUTH通用插件

文件:strongswan-5.8.1/src/libcharon/plugins/xauth_generic/xauth_generic.c为此处使用的xauth_generic插件的实现代码。函数xauth_generic_create_server将创建一个xauth认证服务器,

xauth_generic_t *xauth_generic_create_server(identification_t *server, identification_t *peer, char *profile)
{       private_xauth_generic_t *this;INIT(this,.public = {.xauth_method = { .initiate = _initiate_server,.process = _process_server,.get_identity = _get_identity,.destroy = _destroy,},},.server = server->clone(server),.peer = peer->clone(peer),);

初始化函数initiate_server如下,其将创建类型为CFG_REQUEST的报文(对应以上的ISAKMP_CFG_REQUEST报文),并且添加两个配置属性XAUTH_USER_NAME和XAUTH_USER_PASSWORD,但是这两个数据的值都为空(chunk_empty)。此即以上提到的moon网关发送的第一个XAUTH报文。

METHOD(xauth_method_t, initiate_server, status_t, private_xauth_generic_t *this, cp_payload_t **out)
{cp_payload_t *cp;cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REQUEST);cp->add_attribute(cp, configuration_attribute_create_chunk(PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_NAME, chunk_empty));cp->add_attribute(cp, configuration_attribute_create_chunk(PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_PASSWORD, chunk_empty));*out = cp;return NEED_MORE;
}

函数process_server负责由认证客户端的回复消息中获取用户名和秘钥属性值,并与服务端的用户秘钥进行对比,验证是否相等。

METHOD(xauth_method_t, process_server, status_t, private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out)
{enumerator = in->create_attribute_enumerator(in);while (enumerator->enumerate(enumerator, &attr)){switch (attr->get_type(attr)){case XAUTH_USER_NAME:user = attr->get_chunk(attr);break;case XAUTH_USER_PASSWORD:pass = attr->get_chunk(attr);while (enumerator->enumerate(enumerator, &shared, NULL, NULL)){if (chunk_equals_const(shared->get_key(shared), pass)){status = SUCCESS;

以下函数xauth_generic_create_peer用于创建一个认证客户端结构。与以上的服务端不同,此处的initiate_peer函数为空,客户端不需要进行初始化。

xauth_generic_t *xauth_generic_create_peer(identification_t *server, identification_t *peer, char *profile)
{private_xauth_generic_t *this;INIT(this,.public =  {.xauth_method = {.initiate = _initiate_peer,.process = _process_peer,.get_identity = _get_identity,.destroy = _destroy,},},.server = server->clone(server),.peer = peer->clone(peer),

客户端处理函数process_peer负责处理服务器的认证消息,这里创建CFG_REPLY类型的回复消息,增加XAUTH_USER_NAME和XAUTH_USER_PASSWORD两个属性字段,并且赋予相应的值。

METHOD(xauth_method_t, process_peer, status_t, private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out)
{cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REPLY);enumerator = in->create_attribute_enumerator(in);while (enumerator->enumerate(enumerator, &attr)){switch (attr->get_type(attr)){case XAUTH_USER_NAME:cp->add_attribute(cp, configuration_attribute_create_chunk(PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_NAME,this->peer->get_encoding(this->peer)));break;case XAUTH_USER_PASSWORD:shared = lib->credmgr->get_shared(lib->credmgr, type, this->peer, this->server);cp->add_attribute(cp, configuration_attribute_create_chunk(PLV1_CONFIGURATION_ATTRIBUTE, attr->get_type(attr),shared->get_key(shared)));

XAUTH任务

XAUTH任务处理代码位于:strongswan-5.8.1/src/libcharon/sa/ikev1/tasks/xauth.c文件中,与以上的xauth插件类似,函数xauth_create首先创建一个private_xauth_t结构,并根据第二个参数initiator的值,创建initiator或者responder任务。

xauth_t *xauth_create(ike_sa_t *ike_sa, bool initiator)
{private_xauth_t *this;INIT(this,.initiator = initiator,.ike_sa = ike_sa,.status = XAUTH_FAILED,);if (initiator) {this->public.task.build = _build_i;this->public.task.process = _process_i;} else {this->public.task.build = _build_r;this->public.task.process = _process_r;

函数build_i_status负责创建XAUTH的认证结果报文,类型为CFG_SET,增加属性XAUTH_STATUS。

METHOD(task_t, build_i_status, status_t, private_xauth_t *this, message_t *message)
{cp_payload_t *cp;cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_SET);cp->add_attribute(cp,configuration_attribute_create_value(XAUTH_STATUS, this->status));message->add_payload(message, (payload_t *)cp);

函数build_r_ack负责创建XAUTH的认证结果却认报文(即XAUTH的第四个报文),类型为CFG_ACK,属性XAUTH_STATUS的值为空(chunk_empty)。

METHOD(task_t, build_r_ack, status_t, private_xauth_t *this, message_t *message)
{cp_payload_t *cp;cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_ACK);cp->set_identifier(cp, this->identifier);cp->add_attribute(cp,configuration_attribute_create_chunk(PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_STATUS, chunk_empty));message->add_payload(message, (payload_t *)cp);

以下build_i函数,如果当前xauth结构没有关联认证方法,使用load_method进行关联,即上一节介绍的xauth_generic通用方法。之后调用方法的initiate函数,对于认证服务器的角色,initiate函数为:initiate_server函数;但是对于认证客户端而言,其initiate函数initiate_peer实际上为空,参见以上的介绍。前者initiate_server函数返回值为NEED_MORE。

METHOD(task_t, build_i, status_t, private_xauth_t *this, message_t *message)
{if (!this->xauth){cp_payload_t *cp = NULL;this->xauth = load_method(this);if (!this->xauth) {return FAILED;}switch (this->xauth->initiate(this->xauth, &cp)){case NEED_MORE:break;case SUCCESS:DESTROY_IF(cp);if (add_auth_cfg(this, NULL, FALSE) && allowed(this)) {this->status = XAUTH_OK;}this->public.task.process = _process_i_status;return build_i_status(this, message);default:return FAILED;}message->add_payload(message, (payload_t *)cp);return NEED_MORE;

函数process_r为认证客户端的处理服务器报文所使用。根据认证服务器的报文类型CFG_REQUEST或者CFG_SET进行不同的处理。对于CFG_REQUEST报文,需要调用xauth_generic插件的process函数指针进行处理,即函数process_peer。最后启动build任务,即build_r_ack函数创建回复报文。

METHOD(task_t, process_r, status_t, private_xauth_t *this, message_t *message)
{if (cp->get_type(cp) == CFG_REQUEST) {switch (this->xauth->process(this->xauth, cp, &this->cp)) {case NEED_MORE:return NEED_MORE;case SUCCESS:case FAILED:default:break;}this->cp = NULL;return NEED_MORE;}if (cp->get_type(cp) == CFG_SET) {configuration_attribute_t *attribute;enumerator_t *enumerator;enumerator = cp->create_attribute_enumerator(cp);while (enumerator->enumerate(enumerator, &attribute)) {if (attribute->get_type(attribute) == XAUTH_STATUS) {this->status = attribute->get_value(attribute);}}enumerator->destroy(enumerator);if (this->status == XAUTH_OK && add_auth_cfg(this, this->xauth->get_identity(this->xauth), TRUE)) {DBG1(DBG_IKE, "XAuth authentication of '%Y' (myself) successful", this->xauth->get_identity(this->xauth));} else {DBG1(DBG_IKE, "XAuth authentication of '%Y' (myself) failed", this->xauth->get_identity(this->xauth));}}this->identifier = cp->get_identifier(cp);this->public.task.build = _build_r_ack;

strongswan版本: 5.8.1
内核版本: 5.0

END

这篇关于共享秘钥模式下XAUTH验证流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/428574

相关文章

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

opencv图像处理之指纹验证的实现

《opencv图像处理之指纹验证的实现》本文主要介绍了opencv图像处理之指纹验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、简介二、具体案例实现1. 图像显示函数2. 指纹验证函数3. 主函数4、运行结果三、总结一、

Linux samba共享慢的原因及解决方案

《Linuxsamba共享慢的原因及解决方案》:本文主要介绍Linuxsamba共享慢的原因及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux samba共享慢原因及解决问题表现原因解决办法总结Linandroidux samba共享慢原因及解决

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

Spring AI ectorStore的使用流程

《SpringAIectorStore的使用流程》SpringAI中的VectorStore是一种用于存储和检索高维向量数据的数据库或存储解决方案,它在AI应用中发挥着至关重要的作用,本文给大家介... 目录一、VectorStore的基本概念二、VectorStore的核心接口三、VectorStore的

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

大数据spark3.5安装部署之local模式详解

《大数据spark3.5安装部署之local模式详解》本文介绍了如何在本地模式下安装和配置Spark,并展示了如何使用SparkShell进行基本的数据处理操作,同时,还介绍了如何通过Spark-su... 目录下载上传解压配置jdk解压配置环境变量启动查看交互操作命令行提交应用spark,一个数据处理框架

在VSCode中本地运行DeepSeek的流程步骤

《在VSCode中本地运行DeepSeek的流程步骤》本文详细介绍了如何在本地VSCode中安装和配置Ollama和CodeGPT,以使用DeepSeek进行AI编码辅助,无需依赖云服务,需要的朋友可... 目录步骤 1:在 VSCode 中安装 Ollama 和 CodeGPT安装Ollama下载Olla