Raw rules not persisted with default config
Opened this issue Β· 4 comments
π» Brief Description
Using raw 'SOME_RULE'
does not persist rules with Debian/Ubuntu. /etc/iptables/rules.v4
is created but it is not enforced. Setup fails kitchen test
and I have to manually do iptables-restore
(a hack in code does not work). I have tested this on both a KVM system (I thought it was libvirt) and a Docker system (I thought it was Docker) but I have tried putting the firewall recipe directives both before and after those installs, and those are common use cases anywayβ they should not interfere with the managed firewall.
π₯ Cookbook version
depends 'firewall', '~>2.7.1'
π©βπ³ Chef-Infra Version
16.10.17
(pinned for stability)
Version of chef-client in your environment.
π© Platform details
vagrant@virt-generic-debian10:~$ uname -a
Linux virt-generic-debian10 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 GNU/Linux
vagrant@virt-generic-ubuntu2004:~$ uname -a
Linux virt-generic-ubuntu2004 5.4.0-74-generic #83-Ubuntu SMP Sat May 8 02:35:39 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Host is Ubuntu 21.04 running Kitchen and vagrant libvirt provider (because we use KVM in prod).
Steps To Reproduce
my_cookbook::firewall.rb
include_recipe "firewall"
ssh_port = node[:my_cookbook][:sshd][:port]
ssh_interface = node[:my_cookbook][:sshd][:interface]
common_rules = [
'-P INPUT DROP',
'-P FORWARD DROP',
'-P OUTPUT ACCEPT',
"-A INPUT -i lo -m comment --comment \"allow loopback\" -j ACCEPT",
"-A INPUT -p icmp -m icmp --icmp-type any -j DROP",
"-A INPUT -i #{ssh_interface} -p tcp -m tcp -m multiport --dports #{ssh_port} -m state --state NEW,ESTABLISHED -m comment --comment ssh -j ACCEPT",
"-A OUTPUT -p tcp -m tcp -m multiport --dports #{ssh_port} -m state --state RELATED,ESTABLISHED -m comment --comment ssh -j ACCEPT",
"-A OUTPUT -o lo -j ACCEPT",
]
service "ufw" do
action :stop
end
service "ufw" do
action :disable
end
firewall "default" do
action :install
end
i = 1
common_rules.each do |rule|
firewall_rule "common_rules" do
raw rule
position i
end
i += 1
end
attributes::firewall.rb
default[:my_cookbook][:sshd][:port] = 22
default[:my_cookbook][:sshd][:interface] = 'eth0'
default['firewall']['ubuntu_iptables'] = true
default['firewall']['redhat7_iptables'] = true
default['firewall']['allow_loopback'] = true
default['firewall']['allow_icmp'] = false
default['firewall']['allow_ssh'] = false
default['firewall']['ipv6_enabled'] = false
integration::firewall_test.rb
common_rules = [
'-P INPUT DROP',
'-P FORWARD DROP',
'-P OUTPUT ACCEPT',
'-A INPUT -i lo -m comment --comment "allow loopback" -j ACCEPT',
'-A INPUT -p icmp -m icmp --icmp-type any -j DROP',
'-A INPUT -i eth0 -p tcp -m tcp -m multiport --dports 22 -m state --state NEW,ESTABLISHED -m comment --comment ssh -j ACCEPT',
'-A OUTPUT -o lo -j ACCEPT',
]
unwanted_rules = [
'-A INPUT -p tcp -m tcp -m multiport --dports 22 -m comment --comment "allow world to ssh" -j ACCEPT'
]
control 'any node' do
describe iptables do
common_rules.each do |expected|
it { should have_rule(expected) }
end
unwanted_rules.each do |unwanted|
it { should_not have_rule(unwanted) }
end
end
describe service('ufw') do
it { should_not be_enabled }
it { should_not be_running }
end
describe service('netfilter-persistent') do
it { should be_enabled }
it { should be_running }
end
impact 1.0
title 'any node firewall basic rules'
desc 'iptables is not configured properly'
end
kvm.rb
%w{ qemu-kvm libvirt-daemon-system virtinst virt-manager virt-viewer bridge-utils cloud-image-utils libguestfs-tools ifupdown screen }.each do |pkg|
package pkg do
action :install
end
end
# [snip - there's a lot more here I will add if necessary but trying to MVP here]
docker.rb
docker_service 'default' do
action [ :create, :start ]
end
.kitchen.yml
---
driver:
name: vagrant
provider: libvirt
provisioner:
name: chef_zero
product_name: chef
product_version: 16.10.17
always_update_cookbooks: true
chef_license: accept
verifier:
name: inspec
platforms:
- name: generic/debian10
- name: generic/ubuntu2004
suites:
- name: example
run_list:
- recipe[my_cookbook::kvm]
- recipe[my_cookbook::docker]
- recipe[my_cookbook::firewall]
verifier:
inspec_tests:
- test/integration/firewall
attributes:
my_cookbook:
sshd:
port: 22 # https://serverfault.com/a/746699/182753
interface: eth0
π Expected behavior
The firewall is configured with the expected rules and passes all tests.
β Actual behavior
Profile: tests from {:path=>"/home/celiyah/Code/my_cookbook/chef/test/integration/firewall"} (tests from {:path=>".home.celiyah.Code.my_cookbook.chef.test.integration.firewall"})
Version: (not specified)
Target: ssh://vagrant@192.168.121.104:22
Γ any node: any node firewall basic rules (5 failed)
Γ Iptables is expected to have rule "-P INPUT DROP"
expected Iptables to have rule "-P INPUT DROP"
β Iptables is expected to have rule "-P FORWARD DROP"
β Iptables is expected to have rule "-P OUTPUT ACCEPT"
Γ Iptables is expected to have rule "-A INPUT -i lo -m comment --comment \"allow loopback\" -j ACCEPT"
expected Iptables to have rule "-A INPUT -i lo -m comment --comment \"allow loopback\" -j ACCEPT"
Γ Iptables is expected to have rule "-A INPUT -p icmp -m icmp --icmp-type any -j DROP"
expected Iptables to have rule "-A INPUT -p icmp -m icmp --icmp-type any -j DROP"
Γ Iptables is expected to have rule "-A INPUT -i eth0 -p tcp -m tcp -m multiport --dports 22 -m state --state NEW,ESTABLISHED -m comment --comment ssh -j ACCEPT"
expected Iptables to have rule "-A INPUT -i eth0 -p tcp -m tcp -m multiport --dports 22 -m state --state NEW,ESTABLISHED -m comment --comment ssh -j ACCEPT"
Γ Iptables is expected to have rule "-A OUTPUT -o lo -j ACCEPT"
expected Iptables to have rule "-A OUTPUT -o lo -j ACCEPT"
β Iptables is expected not to have rule "-A INPUT -p tcp -m tcp -m multiport --dports 22 -m comment --comment \"allow world to ssh\" -j ACCEPT"
β Service ufw is expected not to be enabled
β Service ufw is expected not to be running
β Service netfilter-persistent is expected to be enabled
β Service netfilter-persistent is expected to be running
Profile Summary: 5 successful controls, 1 control failure, 0 controls skipped
Test Summary: 54 successful, 5 failures, 0 skipped
Add any other context about the problem here. e.g. related issues or existing pull requests.
You probably will notice I've contributed before :) not above submitting a PR but I do not understand what is happening here. UFW is disabled as expected. netfilter-persistent is enabled as expected. :onfire:
vagrant@virt-generic-debian10:~$ sudo iptables -S
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-USER
-N DOCKER-ISOLATION-STAGE-2
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-USER -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
Didn't know where to fit this in above. This is on a Docker host; the libvirt host has the libvirt rules. But in both cases these should be gone, and the firewall
cookbook rules in their place.
I really recommend you use the iptables cookbooks instead of this cookbook as it works much better with iptables.
I had tried it in a branch, but they don't support the raw rules. Let me give it another shotβ thanks, @ramereth
@chaim1221 FWIW we're trying to get that cookbook good enough to eventually be pulled into as a native resource