共享秘钥模式下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

相关文章

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请