1 问题现象
在使用iptables配置扩展规则的时候,使用-m limit模块的时候,有如下提示:
iptables -A INPUT -p ICMP -s 192.168.2.100 -m limit --limit 1/m --limit-burst=1 -j ACCEPT
iptables v1.8.5 (legacy): Couldn't load match `limit':No such file or directory
Try `iptables -h' or 'iptables --help' for more information.
使用strace来追踪,有如下提示:
strace iptables -A INPUT -p ICMP -s 192.168.2.100 -m limit --limit 1/m --limit-burst=1 -j ACCEPT
execve("/bin/iptables", ["iptables", "-A", "INPUT", "-p", "ICMP", "-s", "192.168.2.100", "-m", "limit", "--limit", "1/m", "--limit-burst=1", "-j", "ACCEPT"], 0x7fc7a05f28 /* 11 vars */) = 0
brk(NULL) = 0x55aab57000
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "tls/aarch64/libip4tc.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)......中间省略若干.......
lseek(3, 0, SEEK_CUR) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=2932, ...}) = 0
read(3, "# Internet (IP) protocols\n#\n# Up"..., 4096) = 2932
close(3) = 0
newfstatat(AT_FDCWD, "/usr/lib/xtables/libipt_limit.so", 0x7fd4c94308, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/xtables/libxt_limit.so", 0x7fd4c94308, 0) = -1 ENOENT (No such file or directory)
write(2, "iptables v1.8.5 (legacy): ", 26iptables v1.8.5 (legacy): ) = 26
write(2, "Couldn't load match `limit':No s"..., 54Couldn't load match `limit':No such file or directory
) = 54
write(2, "\n", 1
) = 1
write(2, "Try `iptables -h' or 'iptables -"..., 61Try `iptables -h' or 'iptables --help' for more information.
) = 61
exit_group(2) = ?
+++ exited with 2 +++
从strace提示来看,是缺少libipt_limit.so或者libxt_limit.so动态库文件。
2 交叉编译动态库
在iptables官网找到对应版本的工具源码包。
由于我使用的版本是v1.8.5,因此就以v1.8.5版本为例,其他版本参考该流程即可。
下载的是bz2格式的压缩包,linux下可以使用如下命令解压:
tar -xjf iptables-1.8.5.tar.bz2
解压源码包后配置一下交叉编译工具路径。注意:需要根据自己交叉编译工具的具体路径做配置。
export PATH=$PATH:/opt/prebuilts/host/gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu/bin/
配置configure
./configure --prefix=/home/temp --enable-devel --host=aarch64-linux CC=aarch64-linux-gnu-gcc
如果该处没有报错,就可以执行
make
make结束后,执行
sudo make install
然后到/home/temp路径下就可以看到生成的工具和动态库了。
/home/temp$ tree
.
|-- bin
| `-- iptables-xml -> /home/temp/sbin/xtables-legacy-multi
|-- include
| |-- libiptc
| | |-- ipt_kernel_headers.h
| | |-- libip6tc.h
| | |-- libiptc.h
| | |-- libxtc.h
| | `-- xtcshared.h
| |-- xtables-version.h
| `-- xtables.h
|-- lib
| |-- libip4tc.la
| |-- libip4tc.so -> libip4tc.so.2.0.0
| |-- libip4tc.so.2 -> libip4tc.so.2.0.0
| |-- libip4tc.so.2.0.0
| |-- libip6tc.la
| |-- libip6tc.so -> libip6tc.so.2.0.0
| |-- libip6tc.so.2 -> libip6tc.so.2.0.0
| |-- libip6tc.so.2.0.0
| |-- libxtables.la
| |-- libxtables.so -> libxtables.so.12.3.0
| |-- libxtables.so.12 -> libxtables.so.12.3.0
| |-- libxtables.so.12.3.0
| |-- pkgconfig
| | |-- libip4tc.pc
| | |-- libip6tc.pc
| | |-- libiptc.pc
| | `-- xtables.pc
| `-- xtables
| |-- libipt_CLUSTERIP.so
| |-- libipt_DNAT.so
| |-- libipt_ECN.so
| |-- libipt_LOG.so
| |-- libipt_MASQUERADE.so
| |-- libipt_NETMAP.so
| |-- libipt_REDIRECT.so
| |-- libipt_REJECT.so
| |-- libipt_SNAT.so
| |-- libipt_TTL.so
| |-- libipt_ULOG.so
| |-- libipt_ah.so
| |-- libipt_icmp.so
| |-- libipt_realm.so
| |-- libipt_ttl.so
| |-- libxt_AUDIT.so
| |-- libxt_CHECKSUM.so
| |-- libxt_CLASSIFY.so
| |-- libxt_CONNMARK.so
| |-- libxt_CONNSECMARK.so
| |-- libxt_CT.so
| |-- libxt_DSCP.so
| |-- libxt_HMARK.so
| |-- libxt_IDLETIMER.so
| |-- libxt_LED.so
| |-- libxt_MARK.so
| |-- libxt_NFLOG.so
| |-- libxt_NFQUEUE.so
| |-- libxt_NOTRACK.so -> libxt_CT.so
| |-- libxt_RATEEST.so
| |-- libxt_SECMARK.so
| |-- libxt_SET.so
| |-- libxt_SYNPROXY.so
| |-- libxt_TCPMSS.so
| |-- libxt_TCPOPTSTRIP.so
| |-- libxt_TEE.so
| |-- libxt_TOS.so
| |-- libxt_TPROXY.so
| |-- libxt_TRACE.so
| |-- libxt_addrtype.so
| |-- libxt_bpf.so
| |-- libxt_cgroup.so
| |-- libxt_cluster.so
| |-- libxt_comment.so
| |-- libxt_connbytes.so
| |-- libxt_connlimit.so
| |-- libxt_connmark.so
| |-- libxt_conntrack.so
| |-- libxt_cpu.so
| |-- libxt_dccp.so
| |-- libxt_devgroup.so
| |-- libxt_dscp.so
| |-- libxt_ecn.so
| |-- libxt_esp.so
| |-- libxt_hashlimit.so
| |-- libxt_helper.so
| |-- libxt_ipcomp.so
| |-- libxt_iprange.so
| |-- libxt_ipvs.so
| |-- libxt_length.so
| |-- libxt_limit.so
| |-- libxt_mac.so
| |-- libxt_mark.so
| |-- libxt_multiport.so
| |-- libxt_nfacct.so
| |-- libxt_osf.so
| |-- libxt_owner.so
| |-- libxt_physdev.so
| |-- libxt_pkttype.so
| |-- libxt_policy.so
| |-- libxt_quota.so
| |-- libxt_rateest.so
| |-- libxt_recent.so
| |-- libxt_rpfilter.so
| |-- libxt_sctp.so
| |-- libxt_set.so
| |-- libxt_socket.so
| |-- libxt_standard.so
| |-- libxt_state.so -> libxt_conntrack.so
| |-- libxt_statistic.so
| |-- libxt_string.so
| |-- libxt_tcp.so
| |-- libxt_tcpmss.so
| |-- libxt_time.so
| |-- libxt_tos.so
| |-- libxt_u32.so
| `-- libxt_udp.so
|-- sbin
| |-- ip6tables-apply -> iptables-apply
| |-- iptables -> xtables-legacy-multi
| |-- iptables-legacy -> xtables-legacy-multi
| |-- iptables-legacy-restore -> xtables-legacy-multi
| |-- iptables-legacy-save -> xtables-legacy-multi
| |-- iptables-restore -> xtables-legacy-multi
| |-- iptables-save -> xtables-legacy-multi
| `-- xtables-legacy-multi
`-- share
`-- man
|-- man1
| `-- iptables-xml.1
`-- man8
|-- ip6tables-apply.8
|-- ip6tables-restore.8
|-- ip6tables-save.8
|-- ip6tables.8
|-- iptables-apply.8
|-- iptables-extensions.8
|-- iptables-restore.8
|-- iptables-save.8
`-- iptables.811 directories, 129 files
然后将生成的libxt_limit.so动态库拷贝到板端/usr/lib/xtables路径下。
scp libxt_limit.so root@192.168.2.11:/usr/lib/xtables/
然后再次执行iptables配置规则,发现报错如旧。
strace iptables -A INPUT -p ICMP -s 192.168.32.23 -m limit --limit 1/m --limit-burst=1 -j ACCEPT
[ 715.714837] mounted system vfs_write: sh(1555) modify mmcblk0p11 on /home/root/.ash_history
execve("/bin/iptables", ["iptables", "-A", "INPUT", "-p", "ICMP", "-s", "192.168.32.23", "-m", "limit", "--limit", "1/m", "--limit-burst=1", "-j", "ACCEPT"], 0x7ffaab1d78 /* 12 vars */) = 0
brk(NULL) = 0x3404f000.....省略部分log.....
read(3, "# Internet (IP) protocols\n#\n# Up"..., 4096) = 2932
close(3) = 0
newfstatat(AT_FDCWD, "/usr/lib/xtables/libipt_limit.so", 0x7fc3e448a8, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/xtables/libxt_limit.so", {st_mode=S_IFREG|0711, st_size=9144, ...}, 0) = 0
openat(AT_FDCWD, "/usr/lib/xtables/libxt_limit.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0000\f\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0711, st_size=9144, ...}) = 0
mmap(NULL, 72760, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f95f17000
mprotect(0x7f95f19000, 61440, PROT_NONE) = 0
mmap(0x7f95f28000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f95f28000
close(3) = 0
socket(AF_INET, SOCK_RAW, IPPROTO_RAW) = 3
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
newfstatat(AT_FDCWD, "/proc/net/ip_tables_names", {st_mode=S_IFREG|0440, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
statfs("/proc/net/ip_tables_names", {f_type=PROC_SUPER_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
getsockopt(3, SOL_IP, IPT_SO_GET_REVISION_MATCH, 0x7fc3e44768, [30]) = -1 ENOENT (No such file or directory)
close(3) = 0
write(2, "iptables v1.8.5 (legacy): ", 26iptables v1.8.5 (legacy): ) = 26
write(2, "Couldn't load match `limit':No s"..., 54Couldn't load match `limit':No such file or directory
) = 54
write(2, "\n", 1
) = 1
write(2, "Try `iptables -h' or 'iptables -"..., 61Try `iptables -h' or 'iptables --help' for more information.
) = 61
exit_group(2) = ?
+++ exited with 2 +++
其实这时候,已经找到libxt_limit.so库了。
再往下接着看,发现是socket没有成功。
出现IPT_SO_GET_REVISION_MATCH这个socket提示的时候,说明是kernel的配置没有打开。到kernel的config文件中确认一下。
可以看到,确实是CONFIG_NETFILTER_XT_MATCH_LIMIT配置没有打开。将该配置项打开,编译一个新的镜像烧录板卡中。
重新执行规则配置。
iptables -A INPUT -p ICMP -s 192.168.2.100 -m limit --limit 1/m --limit-burst=1 -j ACCEPT
不会再报错。