Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raw rules not persisted with default config #233

Open
chaim1221 opened this issue Jun 12, 2021 · 4 comments
Open

Raw rules not persisted with default config #233

chaim1221 opened this issue Jun 12, 2021 · 4 comments

Comments

@chaim1221
Copy link
Contributor

chaim1221 commented Jun 12, 2021

👻 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://[email protected]: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:

@chaim1221
Copy link
Contributor Author

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.

@ramereth
Copy link
Contributor

I really recommend you use the iptables cookbooks instead of this cookbook as it works much better with iptables.

@chaim1221
Copy link
Contributor Author

I had tried it in a branch, but they don't support the raw rules. Let me give it another shot— thanks, @ramereth

@ramereth
Copy link
Contributor

@chaim1221 FWIW we're trying to get that cookbook good enough to eventually be pulled into as a native resource

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants