IPsec 配置备忘 Part4 - Virtual IP

第四篇主要讲一下怎么给客户端下发内网 IP ~
Part1 传送门Part2 传送门Part3 传送门

Virtual IP (VIP)

接 Part3,有了 Tunnel 模式以后我们实际使用的 IP 地址就不用受制于机器的实际 IP 了。但是手动给每个客户端手动分配一个地址显然是不切实际的。于是我们可以使用 Virtual IP 功能自动向连入的客户端分配一个内网 IP,就像 DHCP 或者 SLAAC 那样。

场景配置

与之前完全对称的配置不同,使用 Virtual IP 时需要区分服务端和客户端。先在服务端配置将要分配的 IP,然后由客户端发起连接,服务端就会将配置好的 IP 分发出去。我使用 HostA 作为服务端,HostB 作为客户端。HostA 将会给 HostB 分配 IPv4 与 IPv6 各一个。使用的 Virtual IP 段是fd01::100-fd01::20010.10.10.100-10.10.10.150

hosta$ ip -br addr
eth1         UP             fd00::1/64 fd01::1/128 10.10.10.1/32

hostb$ ip -br addr
eth1         UP             fd00::2/64

和 Part3 相比,HostA 这里有一些与之前不同的地方,一是内部 IP 全部放在了 eth1 上(而不是 lo 上);二是内部 IP 的前缀长度都是最大值;三是增加了一个 IPv4 的内部 IP,用于和分配的 IPv4 Virtual IP 通信。同时 HostB 也不再手工分配fd01开头的内部 IP 了,将由 strongSwan 自动配置。

当连接建立后,我们应该能看到在 HostB 的 eth1 上出现两个新的,自动分配的 IP。且分配到的 IPv4 地址与 10.10.10.1 之间的通信是加密的,分配到的 IPv6 地址与 fd01::1 之间的通信是加密的。

[娱乐向] Samsung 980 Pro RAID 性能测试

三星的新 SSD 980 Pro 已经发售一段时间了,前两天看到 Amazon 上 1TB 有货,赶紧下单两条。今天到货,于是装机测一波速度。打算用来做系统盘,所以自然就是用来组 RAID-0 咯。于是用 fio 分别测试了一下 btrfs 和 mdadm 组 RAID 的性能。测试完全不严谨,参数是用脸滚键盘滚出来的,放出来仅供各位一乐,为什么是娱乐向你看数据就知道了。同时拉上了打酱油的 960 Evo(我现在的系统盘),以及完全是搞笑用的/dev/shm

场景 连续读取(MiB/s) 连续写入(MiB/s) 4K 随机读取(kIOPS) 4K 随机写入(kIOPS)
980 Pro 单盘 EXT4 6370 4725 330 125
980 Pro 单盘 BTRFS 6264 2720 137 63.7
980 Pro mdadm RAID-0 EXT4 12186 9426 298 115
980 Pro BTRFS RAID0 5937 3932 133 63.3
/dev/shm 6290 5541 792 571
960 Evo 单盘 XFS 2963 410 199 31.3

Emmmm, mdadm RAID0 比内存快……这很合理……以及 btrfs 你的 RAID 性能还能更烂一点吗?

IPsec 配置备忘 Part3 - Tunnel 模式

第三篇简单介绍一下 IPsec 的 Tunnel 模式,没看过前两篇的快去看~
Part1 传送门Part2 传送门

Tunnel 模式简介

Tunnel mode header layout 前两篇中我们使用的都是 Transport 模式,但是实际使用中,更常用的是 Tunnel 模式。Transport 模式只加密四层及以上数据,而不修改 IP 头,原始的 IP 头将会原样传输。这意味着我们只能进行点对点传输,因为只有一个 IP 头,我们无法告知对方服务器我们实际要访问的地址。Tunnel 模式则是连原始的 IP 头也一起加密,然后再在前端添加一个新的 IP 头,这样服务器在收到数据包后,可以解密并读取内部的 IP 头,再转发给实际的目标服务器。

IPsec 配置备忘 Part2 - 证书

作为系列的第二篇文章,讲解基本的证书原理和配置方法。没看过第一部分的快去看~
传送门:IPsec 配置备忘 Part1

证书认证基础

我们在 Part1 中看到,PSK 认证的基本思路是使用一个只有通信双方才知道的暗号,如果能确认对方确实知道这个暗号,那么认证就成功了。证书认证的思路非常不同:假设 A 需要向 B 证明自己的身份,同时 A 知道 B 信任 C,那么 A 可以向 C 索取一份“介绍信”,当 B 询问 A 的身份时,A 可以向 B 展示这份 C 出具的“介绍信”,如果 B 能够确认这份“介绍信”确实是由 C 出具的,那么认证就成功了。注意这个认证是单向的,假设 A 也信任 C,那么 B 也可以通过向 C 索取“介绍信”来向 A 证明自己的身份。在 PKI 体系中,A 和 B 持有各自的“私钥”,C 作为 Certificate Authority (CA) 向 A/B 颁发证书(即“介绍信”)。同时,CA 也会向自己颁发一份证书并分发给 A/B,A/B 使用 CA 的证书来确认 B/A 出示的证书确实为 C 所颁发。

IPsec 配置备忘 Part1 - IKEv2 基础

俗话说得好,配置 IPsec 隧道只有零次和无数次,在被 strongSwan 折磨了 N 次以后,我终于决定要把之前试过的配置都记录下来,于是就有了这个系列。我计划基本上每个 PART 会介绍一个(或几个)特定场景下的配置,配置文件样例以 strongSwan vici 为主,之后可能会介绍 iOS, Android 或者是 Mikrotik 路由器的配置方法,如果我能坚持不鸽写到那里的话(画外音:你这 FLAG 立得……) FLAG 回收了。如果各位有想看的配置场景欢迎留言告诉我,会考虑先写。

IKEv2 与 IPsec 基础

严格来说 IKEv2 不是 VPN,它的全称是 Internet Key Exchange,只是一种用于交换密钥的协议罢了。密钥在计算机里一般就表示为一串固定长度的二进制数据,密钥交换就是指在两台设备之间约定一个相同的二进制串,就像两个密友之间约定暗号一样。一旦密钥交换完毕,IKE 的使命就结束了,具体怎么用约定好的密钥加密数据不是 IKE 解决的问题。在 Linux 系统上,实际的数据包加密解密是由内核的 XFRM 框架负责的,你可以使用ip xfrm命令看到配置好的密钥以及加解密使用的算法。事实上,不使用 IKEv2 而完全手动“交换”密钥是可行的,比如朴素VPN:一个纯内核级静态隧道。你可以看到作者直接使用ip xfrm {policy,state} add指令设定密钥,然后内核就会自动用设定的密钥加密流量。

然而,手动管理内核状态是复杂的,人工分发密钥也不怎么安全,这时就轮到 strongSwan 登场啦(或者说,任何实现了 IKE 的 Daemon 服务)。两台服务器的 strongSwan 使用 IKEv2 协议交换密钥,解决了密钥分发的问题。随后 strongSwan 会把交换得来的密钥设定进内核,这样内核就会自动加密指定的流量了。

从数据包层面上看,IKE 是7层协议,密钥交换使用特殊的 UDP 包完成。而一般被加密的数据包会使用 ESP 封装,ESP 头一般紧跟在 IP 头后。ESP 也可以被封装进 UDP 用以穿越 NAT。

没有 TUN 设备

内核 XFRM 的工作方式和基于 TUN 设备的 VPN 很不一样。一般基于 TUN 的 VPN 会加密所有进入 TUN 设备的流量,因此你可以直接使用路由表来控制哪些流量走 VPN,哪些不走。而 XFRM 的匹配基于策略(i.e. 源地址+目标地址+一些别的),如果某个数据包匹配到了一个策略,这个数据包就会根据这个策略指定的方式被加密。

比方说有A [fd00::1]B [fd00::2],如果你从 A 发送一个数据包到 B,普通情况下这个数据包是明文的。如果你在 A 配置了src=fd00::1,dst=fd00::2,encrypt=<...>的策略并再发一个数据包,这个包就会自动被加密。B 收到了这个数据包,但是它并不知道该如何解密,所以你必须同时在 B 配置一条src=fd00::1,dst=fd00::2,decrypt=<...>的策略,这样 B 才能解密。对于从 B 到 A 的流量也需要类似的两条策略。使用 IKEv2 的话,这些策略 strongSwan 都会自动帮你设置好,无需操心。于是你会发现,尽管我们仍然在使用节点本身的 IP,但是流量却已经被加密了。

对于那些必须使用路由表或是策略匹配不是很有效的场景, Route-based IPsec VPN 也是存在的。我也许会在未来的某一期讲。

Linux + Windows 10 多系统安装 U 盘

Update: Windows 的引导程序似乎有些问题,如果在同一块 U 盘上写入多个 ISO 分区的话,似乎引导会错乱,最终启动的安装程序版本不是引导程序所在分区的版本。所以暂时一个 U 盘还是只能放一个 Windows 版本。垃圾巨硬。

日常折腾中总免不了要用 LiveCD 修理一下系统,或者是重装一下 Windows 之类的。这时候制作一个引导用的 U 盘基本是最方便的选项了。有不少工具都能创建 U 盘引导,比如 ArchLinux 的 ISO 镜像可以直接用dd写入,Windows 的安装盘也能用 Rufus 创建。不过在使用上还是有些不便,比如dd会覆盖整个U盘,在ISO之外不能再存储其他文件。Rufus 只能在 Windows 上运行,而且一只 U 盘也只能放一份 ISO。于是尝试搞明白怎么把 Linux 的 LiveCD 和 Windows 的安装 ISO 写入到同一只 U 盘就很有必要了。

我个人使用的设备都支持 UEFI,所以这里制作的启动盘也只支持 UEFI 启动,需要 MBR 模式启动的读者请往它处寻。当然,Secure Boot 是要关掉的。制作过程我使用 Linux,纯 Windows 用户现在也可以退出了。基本上,我们需要创建一个 EFI 系统分区(EFI System Partition, ESP),其中包含基本的引导程序(Grub2)和 Linux LiveCD 的 ISO 文件。由于 Windows 的安装程序无法以 ISO 形式被引导,因此我们需要给每个 Windows ISO 文件创建一个分区,并将 ISO 中的内容解压进去。但是分区一旦创建不像文件那么好修改,所以创建每个 Windows ISO 分区的时候我都留了一些额外空间,以备以后 ISO 大小变化,这也意味着这些空间就基本浪费了。That's sad but I guess it's how things work.

另外,购买一个优质的 U 盘还是有必要的,不然不管是创建启动盘还是安装系统都会慢得让你痛不欲生。建议用之前先给 U 盘测一下速,什么拷贝速度只有 2MB/s 的金士顿可以直接进垃圾桶了。至于 U 盘大小取决于你要放多少个 ISO 文件和多少个 Windows 分区,一般 Linux 镜像大小在 500MB~3GB 的都有,Windows 10 的分区一般每个需要 5~6GB.

在 Raspberry Pi 4B 上安装 ArchLinux

Neofetch
很久之前就买了一个树莓派,不过一直在吃灰,正好最近有空就再拿出来折腾一下。原装系统是 32 位的,那么就必定要换一个 64 位的啦,不然对不起这 64 位的 CPU 呀。秉承“Arch大法好”的理念,我就决定用 Archlinux ARM 了。我非常建议先用原版系统更新 Bootloader 和 EEPROM到最新版本。这样可以避免各种奇怪的 bug 和使用一些新加入的功能,比如从网络启动什么的。

ArchLinux ARM 其实已经提供了树莓派的安装教程,基本上只要跟着做即可,我用的是 AArch64 镜像,并且把根文件系统从 ext4 换成了 f2fs,希望在 SD 卡上能有一点点加成效果。装完以后发现串口没有输出,自然不能忍,继续折腾。RPi 4B 一共有两个串口控制器,一个 PL011,另一个被称作 MiniUART。默认情况下,PL011 连接到蓝牙模块,并且 MiniUART 被禁用,但是我们可以通过 config.txt 加载 dtb overlay 来调整。一些常见的配置有:

  • 启用 MiniUART 串口,PL011 继续负责蓝牙
  • 禁用蓝牙,让 PL011 负责串口通信
  • 启用 MiniUART,让 MiniUART 负责蓝牙,PL011 负责串口

但是 ArchLinux ARM 使用 U-Boot 来启动内核,并不遵循 config.txt (╯°Д°)╯ ┻━┻

那么我们只能把 U-Boot 干掉了 (<ゝω・)☆