TL; DR
Esta manhã eu encontrei este mesmo problema ao tentar configurar o iptables:
[root@office-pc /]# iptables -t nat -A POSTROUTING -o enp0s31f6 -j MASQUERADE
iptables v1.6.0: can't initialize iptables table 'nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
Estou usando a versão do iptables:
[root@office-pc /]# pacman -Q iptables
iptables 1.6.0-1
O que aconteceu?
O módulo do kernel ip_tables realmente existe?
[root@office-pc /]# /lib/modules/'uname -r'/kernel/net/ipv4/netfilter/ip_tables.ko
bash: /lib/modules/4.8.13-1-ARCH/kernel/net/ipv4/netfilter/ip_tables.ko: No such file or directory
[root@office-pc /]# modprobe ip_tables
modprobe: FATAL: Module ip_tables not found in directory /lib/modules/4.8.13-1-ARCH
hmmm .... Parece que desapareceu! Vamos descobrir:
1. Qual kernel meu computador está usando?
2. Suporta iptables?
[root@office-pc /]# uname -r
4.8.13-1-ARCH
[root@office-pc /]# cat /proc/sys/kernel/osrelease
4.8.13-1-ARCH
[root@office-pc /]# zgrep IPTABLES /proc/config.gz
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP6_NF_IPTABLES=m
Ok .... Isso é estranho porque é um kernel padrão do Arch Linux e suporta iptables.
Vamos dar uma olhada para ver se há algum módulo do netfilter disponível (eu ficaria muito surpreso se não houvesse porque é muito improvável que algo os apague):
[root@office-pc /]# ls /lib/modules/*/kernel/net/*/netfilter/
/lib/modules/4.9.11-1-ARCH/kernel/net/bridge/netfilter/:
ebt_802_3.ko.gz ebtables.ko.gz ebt_dnat.ko.gz ebt_log.ko.gz ebt_pkttype.ko.gz ebt_vlan.ko.gz nft_reject_bridge.ko.gz
ebtable_broute.ko.gz ebt_among.ko.gz ebt_ip6.ko.gz ebt_mark.ko.gz ebt_redirect.ko.gz nf_log_bridge.ko.gz
ebtable_filter.ko.gz ebt_arp.ko.gz ebt_ip.ko.gz ebt_mark_m.ko.gz ebt_snat.ko.gz nf_tables_bridge.ko.gz
ebtable_nat.ko.gz ebt_arpreply.ko.gz ebt_limit.ko.gz ebt_nflog.ko.gz ebt_stp.ko.gz nft_meta_bridge.ko.gz
/lib/modules/4.9.11-1-ARCH/kernel/net/ipv4/netfilter/:
arptable_filter.ko.gz ip_tables.ko.gz nf_conntrack_ipv4.ko.gz nf_nat_pptp.ko.gz nft_dup_ipv4.ko.gz
arp_tables.ko.gz ipt_ah.ko.gz nf_defrag_ipv4.ko.gz nf_nat_proto_gre.ko.gz nft_masq_ipv4.ko.gz
arpt_mangle.ko.gz ipt_CLUSTERIP.ko.gz nf_dup_ipv4.ko.gz nf_nat_snmp_basic.ko.gz nft_redir_ipv4.ko.gz
iptable_filter.ko.gz ipt_ECN.ko.gz nf_log_arp.ko.gz nf_reject_ipv4.ko.gz nft_reject_ipv4.ko.gz
iptable_mangle.ko.gz ipt_MASQUERADE.ko.gz nf_log_ipv4.ko.gz nf_tables_arp.ko.gz
iptable_nat.ko.gz ipt_REJECT.ko.gz nf_nat_h323.ko.gz nf_tables_ipv4.ko.gz
iptable_raw.ko.gz ipt_rpfilter.ko.gz nf_nat_ipv4.ko.gz nft_chain_nat_ipv4.ko.gz
iptable_security.ko.gz ipt_SYNPROXY.ko.gz nf_nat_masquerade_ipv4.ko.gz nft_chain_route_ipv4.ko.gz
/lib/modules/4.9.11-1-ARCH/kernel/net/ipv6/netfilter/:
ip6table_filter.ko.gz ip6t_ah.ko.gz ip6t_mh.ko.gz nf_conntrack_ipv6.ko.gz nf_reject_ipv6.ko.gz nft_redir_ipv6.ko.gz
ip6table_mangle.ko.gz ip6t_eui64.ko.gz ip6t_NPT.ko.gz nf_defrag_ipv6.ko.gz nf_tables_ipv6.ko.gz nft_reject_ipv6.ko.gz
ip6table_nat.ko.gz ip6t_frag.ko.gz ip6t_REJECT.ko.gz nf_dup_ipv6.ko.gz nft_chain_nat_ipv6.ko.gz
ip6table_raw.ko.gz ip6t_hbh.ko.gz ip6t_rpfilter.ko.gz nf_log_ipv6.ko.gz nft_chain_route_ipv6.ko.gz
ip6table_security.ko.gz ip6t_ipv6header.ko.gz ip6t_rt.ko.gz nf_nat_ipv6.ko.gz nft_dup_ipv6.ko.gz
ip6_tables.ko.gz ip6t_MASQUERADE.ko.gz ip6t_SYNPROXY.ko.gz nf_nat_masquerade_ipv6.ko.gz nft_masq_ipv6.ko.gz
Então, há uma pista aqui; parece que tenho um kernel errado (existem módulos do kernel para a versão do kernel: /lib/modules/4.9.11-1 que não combina com o kernel rodando no meu computador - 4.9.13-1). Então vamos verificar se existem módulos disponíveis para o kernel rodando na minha máquina:
[root@office-pc /]# ls /lib/modules/4.8.13-1-ARCH
ls: cannot access '/lib/modules/4.8.13-1-ARCH': No such file or directory
Não! Então, é mais provável que essa seja a causa raiz do problema; o kernel rodando na minha máquina não possui nenhum módulo carregável (não é bom). Vamos tentar consertá-lo atualizando (no meu caso, rebaixando) o kernel, porque estou usando o kernel padrão do Arch Linux que está sob controle de versão pacman. Eu posso simplesmente executar o pacman para atualizá-lo (se você estiver usando um kernel customizado um problema que você será capaz de resolver):
[root@office-pc /]# sudo pacman -S linux
...
Packages (1) linux-4.9.11-1
...
Ótimo! O pacman irá instalar o kernel 4.9.11-1, que é o que eu quero (eu tenho módulos para este kernel - não tenho idéia de como acabei obtendo o Kernel 4.9.13). Deixe o pacman concluir a instalação.
Finalmente, eu preciso ter certeza de que este kernel será usado ao inicializar a máquina. Então eu preciso atualizar o gerenciador de boot (estou usando o systemd-boot).
- Eu tenho uma partição de inicialização que é montada em / boot
- Apague o arquivo loader.conf: /boot/loader/loader.conf (ele será atualizado ao executar o bootctl abaixo e o bootctl não irá atualizá-lo se já existir)
- Execute o bootctl para atualizar o gerenciador de inicialização:
[root@office-pc /]$ bootctl --path=/boot install
Agora reinicialize o computador ... Quando ele for reinicializado, ele deve usar o novo kernel (desclassificado)!
Uma vez que você inicializou e você efetuou login, verifique a versão do kernel para assegurar que o kernel correto está sendo executado:
[matt@office-pc /]$ uname -r
4.9.11-1-ARCH
Agora tente executar o comando original (para configurar o compartilhamento de internet do iptables)
[matt@office-pc /]$ sudo iptables -t nat -A POSTROUTING -o enp0s31f6 -j MASQUERADE
[matt@office-pc /]$ sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[matt@office-pc /]$ sudo iptables -A FORWARD -i enp0s20f0u4u3 -o enp0s31f6 -j ACCEPT
Woo-hoo Problema corrigido! (note que entrei como usuário root para corrigir esse problema - eu não recomendaria fazer isso a menos que você tenha certeza de que sabe o que está fazendo!)