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

在之前的两篇文章中:

使用 Linux 内置 tc 命令来模拟弱网环境

创建一台 Linux 路由器设备以模拟弱网环境

因为 Linux 下的 tc 流量整形只能对出口流量进行配置。若要双向流量限制,只能通过之前的方案:使用一台作为路由的主机当作网关来控制另一台主机,在路由主机上配置 tc 策略进行双向出口 (路由->WAN, 路由->内部主机) 流量整形。

但是这里有一个缺点,那就是很麻烦。除非你想作为一个专门的网管,对内部网络进行配置,然而大多数情况下,其实只需要有一台测试的 Linux 临时配置一下而已。

那么有没有一种很爽的方式来解决这个问题呢?那肯定是有的。

阅读更多

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

(本文Github地址为: learning-kcp-protocol)

在特定的应用场合,单纯的使用 TCP 不能满足需要。直接使用 UDP 数据报不能保证数据的可靠性,常需要在应用层基于 UDP 实现一套可靠的传输协议。

直接使用 KCP 协议是一种选择,它实现了健全的自动重传协议,并在此之上提供了自由的参数调整。通过配置参数和合适的调用方式来适应不同场景的需求。

KCP 简介:

KCP是一个快速可靠协议,能以比 TCP 浪费 10%-20% 的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据包的发送方式,以 callback的方式提供给 KCP。 连时钟都需要外部传递进来,内部不会有任何一次系统调用。
整个协议只有 ikcp.h, ikcp.c两个源文件,可以方便的集成到用户自己的协议栈中。也许你实现了一个P2P,或者某个基于 UDP的协议,而缺乏一套完善的ARQ可靠协议实现,那么简单的拷贝这两个文件到现有项目中,稍微编写两行代码,即可使用。

本文对 KCP 协议的基础收发流程、拥塞窗口、超时算法作简单介绍,并同时提供了参考的示例代码。

参阅的 KCP 的版本为撰写文章时的最新版本。本文不会完全贴上所有KCP的源代码,会在关键处添加指向源代码相应位置的链接。

阅读更多

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

在 CentOS 中的 firewalld 是基于 iptables 和一些其它程序构建的,firewalld 使用了一些更加友好的配置方式来实现了对 iptables 操作。同时还扩展了一些 iptables 本身不支持的功能,例如定时防火墙规则。完整的程序以及库依赖见 firewalld 官网 https://firewalld.org/

iptables 通过操作 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

策略链默认行为

对应的策略链会有默认的行为。意味着定义了未匹配任何规则的时,链对数据包的处理。

使用如下命令查看当前策略链的行为(同时输出了未匹配此链的数据包数量和流量)。

~]# iptables -L -v | grep policy
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
Chain OUTPUT (policy ACCEPT 821 packets, 293K bytes)

如果当前的策略链的行为不是如上所示,可以通过下列命令来设置接受所有数据的行为:

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

可以尝试如下命令丢弃所有情况下的包:

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

注意:此时外部主机将无法访问主机,同时主机内部也无法访问外部。

阅读更多