eBPF 入门:在内核里跑沙箱程序

eBPF 让你在不改内核源码、不重启的情况下,把沙箱化的程序注入内核执行。可以用来做网络观测、安全监控、性能追踪,甚至在内核态直接丢包或者修改 syscall 返回值。这篇文章从 bpf() 系统调用讲起,写一个统计 TCP 连接数的例子。

// tcptop.bpf.c — 统计 TCP 连接
SEC("kprobe/tcp_connect")
int trace_connect(struct pt_regs *ctx) {
    struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx);
    u32 pid = bpf_get_current_pid_tgid();
    bpf_printk("connect pid=%d\n", pid);
    return 0;
}
→ 继续阅读

写一个 TCP 协议栈,从零开始

用户态 TCP 协议栈听起来很唬人,但其实核心就几个状态机:连接建立(三次握手)、滑动窗口、重传超时。用 TUN 设备从内核偷包出来,在用户态处理。Rust 写这个特别合适——所有权模型天然防止 buffer 越界,async/await 让状态机清晰可读。

enum State { Listen, SynRcvd, Established, FinWait1, ... }
impl Connection {
    fn on_packet(&mut self, ip: Ipv4Packet, tcp: TcpPacket) {
        match self.state {
            State::Listen => self.handle_syn(tcp),
            State::SynRcvd => self.handle_ack(tcp),
            ...
        }
    }
}
→ 继续阅读

WebAssembly 不是给你跑浏览器的

WASM 被浏览器广告绑架太久了。它的真正价值是通用轻量沙箱:接近原生的执行速度、线性内存模型、无标准库依赖。想象一下把插件系统换成 WASM——用户上传的代码跑在隔离沙箱里,CPU/内存严格限额,比你手写 DSL 安全得多。WASI 标准正在把 WASM 推向服务端。

;; WAT — WebAssembly Text Format
(module
  (func $fib (param i32) (result i32)
    (if (i32.le_s (local.get 0) (i32.const 1))
      (return (local.get 0)))
    ;; fib(n-1) + fib(n-2)
    ...
  )
)
→ 继续阅读

TTL 的奇怪用法:ping 测路由跳数之外的玩法

TTL(Time To Live)不是时间,是跳数。每过一个路由器减 1,减到 0 就回 ICMP Time Exceeded。traceroute 就是故意发 TTL=1,2,3... 来逐跳探测路由。但还有一些冷门用法:用 TTL 判断对方 OS(Linux 默认 64,Windows 128),或者故意设低 TTL 做安全边界——包出不了机房就过期了。

$ ping -t 1 8.8.8.8      # TTL=1,默认网关就会返回超时
$ traceroute -n xblj.top  # 逐跳探测
$ ping -c1 xblj.top | grep ttl  # ttl=47 → 64-47=17 跳
→ 继续阅读