认识
官网:https://www.strongswan.org/
文档:https://www.strongswan.org/documentation.html ⇒ https://docs.strongswan.org/docs/latest/index.html
仓库:https://github.com/strongswan
strongSwan is a comprehensive implementation of the Internet Key Exchange (IKE) protocols that allows securing IP traffic in policy- and route-based IPsec scenarios from simple to very complex. The strongSwan source code is licensed under the GPLv2 with commercial licensing options available. 简而言之,我们能够 strongSwan 来提供 IPSec VPN 服务。
组成
VPN 使用 Linux Kernel 的原生 IPsecStack 实现。
配置文件
WIP
性质
支持 IKEv1、IKEv2 协议。
应用
L2TP over IPSec
通过 strongSwan + xl2tpd 搭建
环境描述:CentOS 7.3;strongSwan x86_64 5.7.1;xl2tpd x86_64 1.3.8;
WIP 通过 strongSwan + xl2tpd 搭建 L2TP over IPSec 服务;
IPsec/L2TP VPN Strongswan Site-Site on Debian 8
站点到站点直接的 VPN 连接
L2TP/IPSec 配置教程
使用脚本配置 VPN
ipsec.conf – IPsec 的配置和连接
配置文件描述
可选的 ipsec.conf 文件指定了 strongSwan IPsec 子系统的大多数配置和控制信息。主要的例外是身份验证的机密;见 ipsec.secrets(5)。其内容不是安全敏感的。
该文件是一个文本文件,由一个或多个部分组成。空格后跟“#”后跟任何到行末尾是注释,而被忽略,空行不包含在部分内。
包含 include 和文件名的行(由空格分隔)将替换为该文件的内容。如果文件名不是完整路径名,则认为它与包含包含文件的目录相关。这种包含可以嵌套。可能只提供一个文件名,它可能不包含空格,但它可能包含 shell 通配符(参见 sh(1));例如:
包含工具的目的主要是为了使连接或连接集的信息与主配置文件分开。这允许更改这些连接描述,将其复制到所涉及的其他安全网关等,而不必经常从配置文件中提取它们然后将它们插回到配置文件中。还要注意,还允许将“单个逻辑部分”(例如连接描述)分成“几个实际部分”的参数(如下所述)。
部分如下形式的一行开头:
其中 type 表示后面的部分类型,name 是一个任意名称,用于区分该部分与相同类型的部分。以空格开头的所有后续非空行都是该部分的一部分。合并具有相同名称的相同类型的部分。
部分内的行通常是形式
(注意前面的强制空格)。在“=”的两侧可以有空白区域。参数名称特定于部分类型。
空值表示参数的系统默认值(如果有的话),即它大致相当于完全省略参数行。这可能有助于清除从%default部分继承的设置或通过参数(参见下文)。value 可以包含单个空格(额外的空格减少到一个空格)。要保留写入的空格,请将整个值括在双引号(”)中;在这样的值中,双引号本身可以通过在它们前面添加”\“字符进行转义。双引号字符串可以跨越多行,通过用”\“字符结束行。(后续的行不必以空格开头,因为它将被保留)。此外,以下控制字符可以用双引号字符串编码:\n, \r, \t, \b, \f。
数值被指定为“整数”(数字序列)或“小数”(数字序列可选地后跟“.”和另一个数字序列)。
目前有一个参数可用于任何类型的部分:
名称为 %default 的节指定相同类型的节的默认值。这其中的所有参数都由该类型的所有其他部分继承。
目前有三种类型的部分:config 部分指定 IPsec 的一般配置信息;conn 部分指定 IPsec 连接;而 ca 部分指定证书颁发机构的特殊属性。
CONFIG 部分
目前,IPsec 软件已知的唯一 config 部分是名为 setup 的 config 部分,即 config setup,其中包含软件启动时使用的信息。在 config setup 部分中当前接受的参数名称为:
cachecrls = yes | no
如果启用,通过 HTTP 或 LDAP 获取的证书吊销列表(CRL)将在 /etc/ipsec.d/crls/ 中缓存,在从证书颁发机构的公钥派生的唯一文件名下。
charondebug = <debug list>
应该记录多少 charon 调试输出。可以指定包含 type/level 对的逗号分隔列表,例如:dmn 3,ike 1,net -1。可接受的 type 值有:dmn,mgr,ike,chd,job,cfg,knl,net,asn,enc,lib,esp,tls,tnc,imc,imv,pts;可接受的 level 由:-1,0,1,2,3,4(silent, audit, control, controlmore, raw, private)。默认情况下,所有 type 的 level 都设置为 1。有关更多灵活性,请参阅 strongswan.conf(5)中的「LOGGER CONFIGURATION」部分。
strictcrlpolicy = yes | ifuri | no
定义是否必须有新的 CRL 才能使基于 RSA 签名的对等身份验证成功。IKEv2 另外识别 ifuri,如果至少定义了一个 CRL URI 则为 yes,如果没有知道 URI 则为 no。
uniqueids = yes | no | never | replace | keep
特定参与者 ID 是否应该保持唯一,任何新的 IKE_SA 使用被认为替换使用该 ID 的所有旧 ID 的 ID;可接受的值是 yes(默认值),no,never。参与者 ID 通常是唯一的,因此使用相同 ID 的新 IKE_SA 几乎总是用于替换旧 ID。no 和 never 之间的区别在于,如果选项为 no,守护程序将在接收 INITIAL_CONTACT 通知时替换旧的 IKE_SAs,但如果从未配置,则将忽略这些通知。守护进程还接受与 yes 相同的值 replace,并且值保持拒绝新的 IKE_SA 设置并保持先前建立的副本。
CONN 部分
conn 部分包含连接规范,定义使用 IPsec 进行的网络连接。给定的 name 是任意的,用于标识连接。这是一个简单的例子:
leftsubnet=10.1.0.0/16
right=192.168.0.2
rightsubnet=10.1.0.0/16
keyingtries=%forever
auto=add
关于术语的说明:有两种通信方式:用户 IP 数据包的传输;用于键控,密钥更新和一般控制的网关到网关协商。控制连接的路径在 IKEv1 中称为“ISAKMP SA”,在 IKEv2 协议中称为“IKE SA”。正在协商的内核级数据路径称为“IPsec SA”或“Child SA”。strongSwan 之前使用了两个独立的键控守护进程,pluto 和 charon。本手册不再讨论 pluto 选项,而只讨论自 StrongSwan 5.0 同时支持 IKEv1 和 IKEv2 的 charon。
为了避免对配置文件进行微不足道的编辑以适应连接中涉及的每个系统,连接规范是按照左右参与者的方式编写的,而不是根据本地和远程方式编写的。哪个参与者被认为是左或右是任意的;对于每个连接描述,尝试确定本地端点是否应该充当左端点或右端点。这是通过将为两个端点定义的 IP 地址与分配给本地网络接口的 IP 地址进行匹配来完成的。如果找到匹配,则匹配的角色(左或右)将被视为本地角色。如果在启动期间未找到匹配项,则将左侧视为本地匹配项。这允许在两端使用相同的连接规范。有些情况下没有对称性;一个很好的约定是左侧用于本地侧,右侧用于远侧(第一个字母是一个很好的助记符)。
许多参数涉及一个参与者或另一个参与者;这里仅列出左边的那些,但是名称以 left 开头的每个参数都有一个 right 对应物,其描述相同,但左右颠倒。
除非标记为“(必需)”,否则参数是可选的。
CONN 参数
除非另有说明,否则对于工作连接,通常两端必须完全同意这些参数的值。
also = <name>
引入 conn 部分 <name>
aaa_identity = <id>
定义 IKEv2 EAP 身份验证期间使用的 AAA 后端的标识。如果 EAP 客户端使用验证服务器标识的方法(例如 EAP-TLS),但它与 IKEv2 网关标识不匹配,则这是必需的。
aggressive = yes | no
是否使用 IKEv1 Aggressive 或 Main Mode(默认值)。
ah = <cipher suites>
用于连接的以逗号分隔的 AH 算法列表,例如,sha1-sha256-modp1024。符号是完整性[-dhgroup]。对于 IKEv2,可以在单个提议中包含相同类型的多个算法(由-分隔)。IKEv1 仅包含提案中的第一个算法。只能使用 ah 或 esp 关键字,不支持 AH+ESP 包。
没有默认的 AH 密码套件,因为默认使用 ESP。守护程序将其广泛的默认提议添加到配置的值。要将其限制为已配置的提议,可以在末尾添加感叹号(!!)。
如果指定了 dh-group,则设置 CHILD_SA/Quick 模式并且重新加密包括单独的 Diffie-Hellman 交换(有关详细信息,请参阅 esp 关键字)。
auth = <value>
由 pluto IKEv1 守护程序使用,它来为 ESP 加密数据包使用 AH 完整性保护,但在 charon 中不支持。关键字 ah 指定用于 AH 的完整性保护的算法,但没有加密。不支持 AH + ESP 捆绑包。
authby = pubkey | rsasig | ecdsasig | psk | secret | never | xauthpsk | xauthrsasig
这两个安全网关应该如何相互验证;可接受的值是:
- psk, secret,用于预共享密钥;
- pubkey,(默认)公钥签名;
- rsasig,RSA 数字签名;
- ecdsasig,椭圆曲线 DSA 签名;
- never,如果永远不会尝试或接受协商,则可以使用 never(对于仅有分流的 conn 非常有用)。
- xauthpsk, xauthrsasig,IKEv1 还支持 xauthpsk 和 xauthrsasig 值,除了基于”共享机密“或”数字 RSA 签名“的 IKEv1 主模式之外,它还将启用扩展认证(XAUTH)。
数字签名在各方面都优于共享机密。
不推荐使用此参数,因为两个对等方不需要就 IKEv2 中的身份验证方法达成一致。请改用 leftauth 参数来定义身份验证方法。
auto = ignore | add | route | start
在 IPsec 启动时,应该自动完成哪些操作(如果有的话);当前接受的值是 add,route,start,ignore(默认值):
- add,加载连接而不启动它。
- route,加载连接并安装内核陷阱。如果在 leftsubnet 和 rightsubnet 之间检测到流量,则建立连接。
- start,加载连接并立即启动。
- ignore,忽略连接。这等于从配置文件中删除连接。仅在本地相关,其他目的不需要就此达成一致。
closeaction = none | clear | hold | restart
定义远程对等方意外关闭 CHILD_SA 时要采取的操作(有关值的含义,请参阅 dpdaction)。如果对等方使用 reauthentication 或 uniquids 检查,则不应使用 closeaction,因为这些事件可能在不需要时触发定义的操作。
compress = yes | no
是否建议在连接上进行 IPComp 压缩内容(链路级压缩对加密数据不起作用,因此要有效,必须在加密前进行压缩);可接受的值是 yes 和 no(默认值)。值为 yes 会导致守护程序同时提出压缩和解压缩,并且更喜欢压缩。值为 no 会阻止守护程序提出或接受压缩。
dpdaction = none | clear | hold | restart
控制”死亡对等检测协议“(DPD,RFC 3706)的使用,其中周期性地发送 R_U_THERE 通知消息(IKEv1)或空的 INFORMATIONAL 消息(IKEv2)以检查 IPsec 对等体的活跃性。值 clear,hold,restart 都会激活 DPD 并确定要在超时时执行的操作。使用 clear,在连接后关闭,不再采取进一步措施。hold 会安装陷阱策略,该策略将捕获匹配的流量并尝试按需重新协商连接。restart 将立即触发尝试重新协商连接。默认值为 none,禁用活动发送 DPD 消息。
dpddelay = 30s | <time>
定义 R_U_THERE messages/INFORMATIONAL 交换发送给对等体的周期时间间隔。仅在未收到其他流量时才会发送这些流量。在 IKEv2 中,值 0 不发送任何其他 INFORMATIONAL 消息,仅使用标准消息(例如重定密消息)来检测死亡对等体。
dpdtimeout = 150s | <time>
定义超时间隔,之后在不活动的情况下删除与对等体的所有连接。这仅适用于 IKEv1,在 IKEv2 中应用默认重传超时,因为每个交换用于检测死对等体。
inactivity = <time>
定义超时间隔,如果 CHILD_SA 未发送或接收任何流量,则关闭 CHILD_SA。在 CHILD_SA 重新加密期间重置不活动计数器。这意味着不活动超时必须小于重新加密间隔才能产生任何效果。
eap_identity = <id>
定义客户端用于回复 EAP 身份请求的身份。如果在 EAP 服务器上定义,则定义的标识将在 EAP 身份验证期间用作对等标识。特殊值 %identity 使用 EAP Identity 方法向客户端询问 EAP 身份。如果未定义,则 IKEv2 标识将用作 EAP 标识。
esp = <cipher suites>
用于连接的以逗号分隔的 ESP 加密 / 认证算法列表,例如,aes128-sha256。符号是加密完整性[-dhgroup] [-esnmode]。对于 IKEv2,可以在单个提议中包含相同类型的多个算法(由-分隔)。IKEv1 仅包含提案中的第一个算法。只能使用 ah 或 esp 关键字,不支持 AH+ESP 包。
默认为 aes128-sha256。守护程序将其广泛的默认提议添加到此默认值或配置的值。要将其限制为已配置的提议,可以在末尾添加感叹号(!)。
注意:作为响应者,守护程序默认选择同级也支持的第一个已配置的提议。这可以通过 strongswan.conf(5)更改为选择由对等方发送的第一个可接受的提议。为了限制响应者只接受特定的密码套件,可以使用严格的标志(!,感叹号),例如:aes256-sha512-modp4096!
如果指定了 dh-group,则 CHILD_SA/Quick 模式重新加密和初始协商将使用指定的组进行单独的 Diffie-Hellman 交换。但是,对于 IKEv2,使用 IKE_SA 隐式创建的 CHILD_SA 的键将始终从 IKE_SA 的密钥材料派生。因此,此处指定的任何 DH 组仅在稍后重新生成 CHILD_SA 或使用单独的 CREATE_CHILD_SA 交换创建时才适用。因此,建立 SA 时可能不会立即注意到建议不匹配,但可能会在以后导致重新生成失败。
对于 esnmode 的有效值是 esn 和 noesn。指定两者协商对等体的扩展序列号支持,默认为 noesn。
forceencaps = yes | no
即使没有检测到 NAT 情况,也强制对 ESP 数据包进行 UDP 封装。这可能有助于克服限制性防火墙。为了强制对等体封装数据包,NAT 检测有效负载是伪造的。
fragmentation = yes | accept | force | no
是否使用 IKE 分片(根据 RFC 7383 的专有 IKEv1 扩展或 IKEv2 分段)。可接受的值是 yes(默认值),accept,force,no。如果设置为 yes,并且对等体支持它,则超大 IKE 消息将以片段形式发送。如果设置为 accept,则会向对等方通知对碎片的支持,但守护程序不会以碎片形式发送自己的消息。如果设置为 force(仅支持 IKEv1),则初始 IKE 消息将在必要时进行分段。最后,将该选项设置为 no 将禁用宣布对此功能的支持。
请注意,无论此选项的值如何(即使设置为 no),始终接受对等方发送的碎片化 IKE 消息。
ike = <cipher suites>
要使用的以逗号分隔的 IKE/ISAKMP SA 加密 / 认证算法列表,例如,aes128-sha256-modp3072。表示法是 encryption-integrity[-prf]-dhgroup。如果没有给出 PRF,则定义的完整性算法用于 PRF。prf 关键字与完整性算法相同,但具有 prf 前缀(例如 prfsha1,prfsha256,prfaesxcbc)。
在 IKEv2 中,可以包括多个算法和提议,例如 aes128-aes256-sha1-modp3072-modp2048,3des-sha1-md5-modp1024。
默认为 aes128-sha256-modp3072。守护程序将其广泛的默认提议添加到此默认值或配置的值。要将其限制为已配置的提议,可以在末尾添加感叹号(!)。
注意:作为响应者,守护程序接受从对等方收到的第一个支持的提议。为了限制响应者只接受特定的密码套件,可以使用严格的标志(!,感叹号),例如:aes256-sha512-modp4096!
ikedscp = 000000 | <DSCP field>
差分服务字段代码点,用于设置从此连接发送的传出 IKE 数据包。该值是一个六位二进制编码字符串,用于定义要设置的 Codepoint,如 RFC 2474 中所定义。
ikelifetime = 3h | <time>
连接的密钥信道(ISAKMP 或 IKE SA)在重新协商之前应该持续多长时间。另见下面的 EXPIRY/REKEY。
installpolicy = yes | no
决定是否由 charon 守护程序为给定连接在内核中安装了 IPsec 策略。和平合作,例如使用想要控制内核策略的 Mobile IPv6 守护程序 mip6d。可接受的值是 yes(默认值)和 no。
keyexchange = ike | ikev1 | ikev2
应该使用哪个密钥交换协议来启动连接。标有 ike 的连接在启动时使用 IKEv2,但在响应时接受任何协议版本。
keyingtries = 3 | <number> | %forever
在放弃之前,应该进行多少次尝试(整数或永远不变)来协商连接,或替换连接(默认 3)。值 %forever 意味着“永不放弃”。仅在本地相关,其他目的不需要就此达成一致。
type = tunnel | transport | transport_proxy | passthrough | drop
连接的类型;当前接受的值:
- tunnel(默认值),表示主机到主机,主机到子网,子网到子网的隧道;
- transport,表示主机到主机的传输方式;
- transport_proxy,表示特殊的 Mobile IPv6 传输代理模式;
- passthrough,表示根本不应该进行 IPsec 处理;
- drop,表示应丢弃数据包。
参考文献
StrongSwan Homepage
Download Page
ipsec.secrets – 用于 IKE/IPsec 身份验证的机密
文件描述
文件 ipsec.secrets 包含一个机密表。这些机密被 StrongSwan 的网络密钥交换(IKE)守护程序 pluto(IKEv1)和 charon(IKEv2)使用,来验证其他主机。
保护这些机密至关重要。该文件应由超级用户拥有,其权限应设置为阻止其他人访问。
文件内容
该文件是一系列条目并包含指令。如下示例:
# /etc/ipsec.secrets - strongSwan IPsec secrets file 192.168.0.1 %any : PSK "v+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL" : RSA moonKey.pem alice@strongswan.org : EAP "x3.dEhgN" carol : XAUTH "4iChxLT3" dave : XAUTH "ryftzG4A" # get secrets from other files include ipsec.*.secrets
如上示例包含了可能在一个 ipsec.secrets 文件中出现的三种类型的内容:机密条目;注释;包含(include)指令。
注释
行末尾的空格将被忽略。在行的开头或空白之后,如果是“#”,则其后直到行尾的文本被视为注释。
包含指令
指令 include 导致在继续当前文件之前处理指定文件的内容。文件名受 sh(1)中的“globbing”影响,因此每个具有匹配名称的文件都会被处理。包含可以嵌套到适度的深度(当前为 10)。如果文件名不以 / 开头,则包含当前文件的目录将添加到名称前面。include 指令是以 include 开头的一行,后跟空白,后跟文件名(不能包含空格)。
机密条目
文件中的每个条目都是由可选的”ID 选择器“,后跟一个“机密”的形式组成。这两个部分由冒号(:)分隔,冒号被空格包围。如果未指定“ID 选择器”,则该行必须以冒号开头。
”ID 选择器“可以是 IP 地址、完全限定域名、用户@FQDN、%any、%any6(以后可能会有其他类型)。
匹配”ID 选择器“非常简单:它们必须相同。在“Road Warrior(经常出差的人)”连接的情况下,如果没有找到对等 ID 的相等匹配,并且它是 IP 地址的形式,则选择器%any将匹配对等方的 IP 地址(如果 IPv4 的情况);在 IPv6 情况中,%any6将匹配对等方的 IP 地址。目前,可以使用过时的符号 0.0.0.0 代替 %any。
在 IKEv1 中,在通过预共享密钥进行认证的情况下出现了额外的复杂性:响应者将需要在对等的 ID 有效载荷被解码之前查找“机密”,因此使用的“ID 选择器”将是 IP 地址。
为了验证两台主机之间的连接,将使用最匹配主机和对等 ID 的条目。没有选择器的条目将匹配任何主机和对等体。更具体地说,如果“ID 选择器”与主机的 ID 匹配(不考虑对等体),则具有一个选择器的条目将匹配主机和对等体。更具体地说,如果主机 ID 和对等 ID 分别与选择器之一匹配,则具有多个选择器的条目将匹配主机和对等体。如果密钥用于非对称认证技术(即诸如 RSA 的公共密钥系统),则具有多个选择器的条目将匹配主机和对等体,即使仅主机 ID 与选择器匹配(假设选择器是主机所有标识符)。只要他们就机密或私钥达成一致,两个条目就是最佳匹配是可以接受的。
通过预共享机密进行认证要求两个系统都找到相同的机密(机密实际上不是由 IKE 协议传输的)。如果主机和对等体都出现在选择器列表中,则相同的条目将适用于两个系统,因此可以使用系统之间的逐字复制。这自然延伸到共享相同机密的较大群体。因此,对于 PSK 认证,多选择器条目是最适合的。
通过 RSA 等公钥系统进行身份验证,需要每个主机都有自己的私钥。主机可以合理地为不同的接口和不同的对等体使用不同的私钥。但是在系统之间共享条目是不正常的。因此,无选择器和单选择器形式的入口通常对公钥认证有意义。
条目的“机密”部分必须以表示密钥类型的标记开头。目前支持以下类型的机密:
RSA defines an RSA private key
ECDSA defines an ECDSA private key
P12 defines a PKCS#12 container
EAP defines EAP credentials
NTLM defines NTLM credentials
XAUTH defines XAUTH credentials
PIN defines a smartcard PIN
下面给出了每种机密的详细信息。
TYPES OF SECRETS
[ <selectors> ] : PSK <secret>
预共享密钥最方便地表示为字符序列,由双引号字符(”)分隔。序列不能包含换行符或双引号字符。
或者,预共享机密可以表示为十六进制或 Base64 编码的二进制值。以 0x 开头的字符序列被解释为十六进制数字序列。类似地,以 0 开头的字符序列被解释为 Base64 编码的二进制数据
: RSA <private key file> [ <passphrase> | %prompt ]
: ECDSA <private key file> [ <passphrase> | %prompt ]
对于私钥文件,接受相对于 /etc/ipsec.d/private 的绝对路径或路径。如果私钥文件已加密,则必须定义密码。可以使用密码短语 %prompt,而不是密码短语,然后在需要解密密钥时使守护进程向用户询问密码。
: P12 <PKCS#12 file> [ <passphrase> | %prompt ]
对于 PKCS#12 文件,接受相对于 /etc/ipsec.d/private 的绝对路径或路径。如果容器已加密,则必须定义passphrase。可以使用密码短语 %prompt,而不是密码短语,然后在需要解密容器时使守护进程向用户询问密码。从容器中提取私钥,客户端和 CA 证书。在连接集中使用此类客户端证书,该证书的主题之一是 leftid。
<user id> : EAP <secret>
机密的格式与 PSK 机密的格式相同。
EAP 机密仅限 IKEv2。
<user id> : NTLM <secret>
机密的格式与 PSK 机密的格式相同,但机密存储为 NTLM 哈希,即 MD4(UTF-16LE(机密)),而不是明文。
NTLM 机密只能与 eap-mschapv2 插件一起使用。
[ <servername> ] <username> : XAUTH <password>
密码的格式与 PSK 机密的格式相同。XAUTH 机密只是 IKEv1。
: PIN %smartcard[<slot nr>[@<module>]]:<keyid> <pin code> | %prompt
智能卡选择器始终需要 keyid 来唯一地选择正确的密钥。插槽号定义令牌上的插槽,模块名称指的是在 strongswan.conf(5)中定义的模块名称。可以指定 %prompt,而不是静态指定 pin 代码,这会导致守护进程向用户询问 pin 代码。
注意事项
如果 ID 为 0.0.0.0,则匹配 %any;如果它是 0::0,它将匹配 %any6。
相关手册
ipsec.conf(5), strongswan.conf(5), ipsec(8)
参考文献
man 5 ipsec.secrets