关签的博客

尝试记录一些东西

简单模拟弱网的终极解决方案

(原文撰写于 2022 年 9 月) 因为 Linux 下的 tc 流量整形只能对出口流量进行配置。若要双向流量限制,只能通过之前的方案:使用一台作为路由的主机当作网关来控制另一台主机,在路由主机上配置 tc 策略进行双向出口 (路由->WAN, 路由->内部主机) 流量整形。 但是这里有一个缺点,那就是很麻烦。除非你想作为一个专门的网管,对内部网络进行配置,然而大多数情况下,其实只需要有一台测试的 Linux 临时配置一下而已。 那么有没有一种很爽的方式来解决这个问题呢?那肯定是有的。 虚拟以太网设备 Linux 内置了创建虚拟以太网设备的支持。通过 ip-link 可以添加虚拟的以太网设备,下列命令可以创建一组虚拟以太网接口: ip link add dev veth type veth peer name vpeer veth 和 vpeer 设备互为对端。可以对其分配 ip 地址等正常网络设备的操作。 网络命名空间 同时 Linux 也支持网络命名空间 ip-netns,网络命名空间作为网络堆栈的一个副本。包含自己的路由,防火墙和网络设备。通过配置可用的网络命名空间,就可以在单个主机上配置一个包可以通过两次防火墙! 通过将虚拟以太网设备的 vpeer 端设备移动到网络命名空间中,并且配置正确的 ip 和 默认路由规则。在网络命名空间中就可以访问外部网络: ip netns add myns # 创建命名空间 ip link set vpeer netns myns # 移动 vpeer 到命名空间中 双向流量控制 目标进程启动在网络命名空间中,然后直接在两个虚拟以太网设备上通过 tc 配置流量规则,则可以实现双向流量控制:网络命名空间中的 vpeer 设备上配置,则意味着是命名空间中的内部到外部的流量进行整形。veth 设备则是配置外部网络到命名空间内部的流量整形。...

February 21, 2024

CentOS 中的 iptables 与 firewalld 防火墙基本策略

(原文撰写于 2021 年 11 月) 在 CentOS 中的 firewalld 是基于 iptables 和一些其它程序构建的,firewalld 使用了一些更加友好的配置方式来实现了对 iptables 操作。同时还扩展了一些 iptables 本身不支持的功能,例如定时防火墙规则。完整的程序以及库依赖见 firewalld 官网 https://firewalld.org/。 ptables 通过操作 Linux 内核 netfilter 模块来针对网络包处理。 在操作命令之前请临时关闭机器的 firewalld 防火墙,同时需要确保有物理机的访问权限(或者虚拟机中的物理终端操作权限),有些规则会屏蔽 SSH 22 端口的访问导致无法后续操作。 # 停用 firewalld systemctl stop firewalld iptables 基础概念和操作 策略链 (Policy Chain) iptables 的过滤规则是通过匹配策略链上的规则来决定不同情况下对包的处理,包含了三种策略链: INPUT: 通过此链来控制传入的连接和包,例如允许来自某些 IP 的 SSH 传入连接。 FORWARD: 转发控制链接,如果你需要在机器上配置路由功能时会用到此链。 OUTPUT: 传出链,当前主机发送请求到外部时匹配此链,通常没有特殊需求时也不会给它配置特殊规则。 可以通过下列命令来查看当前设置的 iptables 规则: ~]# iptables -S -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT 策略链默认行为 对应的策略链会有默认的行为。意味着定义了未匹配任何规则的时,链对数据包的处理。...

February 21, 2024

KCP 协议基本数据结构和算法介绍

(原文撰写于 2022 年 6 月) 在特定的应用场合,单纯的使用 TCP 不能满足需要。直接使用 UDP 数据报不能保证数据的可靠性,常需要在应用层基于 UDP 实现一套可靠的传输协议。 直接使用 KCP 协议是一种选择,它实现了健全的自动重传协议,并在此之上提供了自由的参数调整。通过配置参数和合适的调用方式来适应不同场景的需求。 KCP 简介: KCP是一个快速可靠协议,能以比 TCP 浪费 10%-20% 的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据包的发送方式,以 callback的方式提供给 KCP。 连时钟都需要外部传递进来,内部不会有任何一次系统调用。 整个协议只有 ikcp.h, ikcp.c两个源文件,可以方便的集成到用户自己的协议栈中。也许你实现了一个P2P,或者某个基于 UDP的协议,而缺乏一套完善的ARQ可靠协议实现,那么简单的拷贝这两个文件到现有项目中,稍微编写两行代码,即可使用。 本文对 KCP 协议的基础收发流程、拥塞窗口、超时算法作简单介绍,并同时提供了参考的示例代码。 参阅的 KCP 的版本为撰写文章时的最新版本。本文不会完全贴上所有KCP的源代码,会在关键处添加指向源代码相应位置的链接。 基本结构参考 IKCPSEG 结构 IKCPSEG 结构用于存储发送和接收的数据段状态。 IKCPSEG 所有字段描述: struct IKCPSEG { /* 队列节点,IKCPSEG 作为一个队列元素,此结构指向了队列后前后元素 */ struct IQUEUEHEAD node; /* 会话编号 */ IUINT32 conv; /* 指令类型 */ IUINT32 cmd; /* 分片号 (fragment) 发送数据大于 MSS 时将被分片,0为最后一个分片. 意味着数据可以被recv,如果是流模式,所有分片号都为0 */ IUINT32 frg; /* 窗口大小 */ IUINT32 wnd; /* 时间戳 */ IUINT32 ts; /* 序号 (sequence number) */ IUINT32 sn; /* 未确认的序号 (unacknowledged) */ IUINT32 una; /* 数据长度 */ IUINT32 len; /* 重传时间 (resend timestamp) */ IUINT32 resendts; /* 重传的超时时间 (retransmission timeout) */ IUINT32 rto; /* 快速确认计数 (fast acknowledge) */ IUINT32 fastack; /* 发送次数 (transmit) */ IUINT32 xmit; /* 数据内容 */ char data[1]; }; 结构末尾的 data 字段用于索引结构体尾部的数据,额外分配的内存扩展了运行时的 data 字段数组的实际长度 (ikcp....

February 20, 2024

My First Post

因 wordpress 管理复杂和备份不便,且交互不是必要的。此站点重新做了部署。

February 20, 2024