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

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

阅读更多

ESXi 中安装 OpenWrt 并启用路由功能

OpenWrt 是一个面向嵌入式的Linux系统,常用于刷入路由器替换路由器原有系统。

个人部署的虚拟化环境中所有虚拟机需要一个私有的网络地址,ESXi 本身不提供 DHCP 功能,所以只能找其它解决方案。最开始部署了一个 CentOS7 当作路由器,详细请参考 https://linuxhint.com/centos7_router/ 一文。但是不太方便,最终考虑安装专给路由器诞生的 OpenWrt 系统。

准备工作:ESXi (安装目标),ESXi 中的 Windows (Web配置 OpenWrt),CentOS 或其它 Linux (转换官方镜像)。

阅读更多

在游戏系统开发中使用适配器 (Adapter) 模式

在讨论标题问题之前,可以先看一个 VS Code 调试器使用适配器例子:https://code.visualstudio.com/api/extension-guides/debugger-extension

VS Code Debug Architecture
VS Code Debuger Adapter

若要实现一个 VS Code 的调试器,调试器进程通过 Debuger Adapter 库以调试协议与真实的 VS Code 通讯交互来实现。

通过中间的适配器层,调试器与 VS Code 调试UI相互不知道对面的具体实现。

VS Code 只要关注适配器发出的所有协议来作调试响应,而调试器不关注 VS Code 是如何处理这些调试命令的。双端都不知道对面如何处理这些信息,也不必关心。

阅读更多

lua table 源码阅读

近日配置了下终端下的 vim 插件,把 c 相关的开发插件都弄的勉强可以用了,为了熟悉下 GDB 的一些基本操作,就拿读 lua 部分源代码来练手了。

这里所有的内容均基于 lua 5.3 版本。

table 的内部操作定义于文件 ltable.h / ltable.c 中,有以下相关的函数构成:

  • luaH_new : 构造一个新的 table

1.初始化

Table *luaH_new (lua_State *L) {
  GCObject *o = luaC_newobj(L, LUA_TTABLE, sizeof(Table));
  Table *t = gco2t(o);
  t->metatable = NULL;
  t->flags = cast_byte(~0);
  t->array = NULL;
  t->sizearray = 0;
  setnodevector(L, t, 0);
  return t;
}

首先由 lua gc 模块分配一个被托管的垃圾回收对象 GCObject *o, 然后转为一个指向实际的 table 结构的 Table *t 进行初始化操作。

一个 lua table 被分为两个部分:数组部分和哈希表部分。

数组部分的初始化比较粗暴,直接置零。

t->array = NULL;
t->sizearray = 0;

则哈希表的部分由 setnodevector 函数来初始化,由于传入的特殊表大小 0,哈希表部分被指向一个 所有哈希部分为空的 table 所共享的一个静态变量 dummynode (此处为一个宏)

static void setnodevector (lua_State *L, Table *t, unsigned int size) {
  int lsize;
  if (size == 0) {  /* no elements to hash part? */
    t->node = cast(Node *, dummynode);  /* use hashnode 'dummynode' */
    lsize = 0;
  }
  else {
  ....

阅读更多