From b4328bc000fab675ea61819daef360bfcb9c2911 Mon Sep 17 00:00:00 2001 From: Matthias Baur Date: Mon, 20 Aug 2018 13:38:46 +0200 Subject: [PATCH] (MODULES-7681) Add support for bytecode property This commit adds support for Berkeley Paket Filter iptables rules. --- README.markdown | 10 +++++--- lib/puppet/provider/firewall/ip6tables.rb | 4 +-- lib/puppet/provider/firewall/iptables.rb | 3 ++- lib/puppet/type/firewall.rb | 8 ++++++ spec/acceptance/bytecode_spec.rb | 31 +++++++++++++++++++++++ 5 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 spec/acceptance/bytecode_spec.rb diff --git a/README.markdown b/README.markdown index cc0dff3..7a3a803 100644 --- a/README.markdown +++ b/README.markdown @@ -435,12 +435,12 @@ This type enables you to manage firewall rules within Puppet. * `ip6tables`: Ip6tables type provider * Required binaries: `ip6tables-save`, `ip6tables`. - * Supported features: `address_type`, `connection_limiting`, `dnat`, `hop_limiting`, `icmp_match`, `interface_match`, `iprange`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfirstfrag`, `ishasmorefrags`, `islastfrag`, `length`, `log_level`, `log_prefix`, `log_uid`, `mark`, `mask`, `mss`, `owner`, `pkttype`, `queue_bypass`, `queue_num`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `string_matching`, `tcp_flags`, `hashlimit`. + * Supported features: `address_type`, `connection_limiting`, `dnat`, `hop_limiting`, `icmp_match`, `interface_match`, `iprange`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfirstfrag`, `ishasmorefrags`, `islastfrag`, `length`, `log_level`, `log_prefix`, `log_uid`, `mark`, `mask`, `mss`, `owner`, `pkttype`, `queue_bypass`, `queue_num`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `string_matching`, `tcp_flags`, `hashlimit`, `bpf`. * `iptables`: Iptables type provider * Required binaries: `iptables-save`, `iptables`. * Default for `kernel` == `linux`. - * Supported features: `address_type`, `clusterip`, `connection_limiting`, `dnat`, `icmp_match`, `interface_match`, `iprange`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfragment`, `length`, `log_level`, `log_prefix`, `log_uid`, `mark`, `mask`, `mss`, `netmap`, `nflog_group`, `nflog_prefix`, `nflog_range`, `nflog_threshold`, `owner`, `pkttype`, `queue_bypass`, `queue_num`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `string_matching`, `tcp_flags`. + * Supported features: `address_type`, `clusterip`, `connection_limiting`, `dnat`, `icmp_match`, `interface_match`, `iprange`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfragment`, `length`, `log_level`, `log_prefix`, `log_uid`, `mark`, `mask`, `mss`, `netmap`, `nflog_group`, `nflog_prefix`, `nflog_range`, `nflog_threshold`, `owner`, `pkttype`, `queue_bypass`, `queue_num`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `string_matching`, `tcp_flags`, `bpf`. **Autorequires:** @@ -524,7 +524,9 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov * `netmap`: The ability to map entire subnets via source or destination nat rules. -* `hashlimit`: The ability to use the hashlimit-module +* `hashlimit`: The ability to use the hashlimit-module. + +* `bpf`: The ability to use Berkeley Paket Filter rules. #### Parameters @@ -537,6 +539,8 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov * `burst`: Rate limiting burst value (per second) before limit checks apply. Values must match '/^\d+$/'. Requires the `rate_limiting` feature. +* `bytecode`: Match using Linux Socket Filter. Expects a BPF program in decimal format. This is the format generated by the nfbpf_compile utility. This parameter is only supported by operatingsystems using nftables (in general Linux kernel 3.13, RedHat 7 (and derivates) with 3.10). + * `clusterip_new`: Create a new ClusterIP. You always have to set this on the first rule for a given ClusterIP. Requires the `clusterip` feature. * `clusterip_hashmode`: Specify the hashing mode. Valid values are sourceip, sourceip-sourceport, sourceip-sourceport-destport. Requires the `clusterip` feature. diff --git a/lib/puppet/provider/firewall/ip6tables.rb b/lib/puppet/provider/firewall/ip6tables.rb index d3c1b3c..67f171b 100644 --- a/lib/puppet/provider/firewall/ip6tables.rb +++ b/lib/puppet/provider/firewall/ip6tables.rb @@ -162,7 +162,7 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6 hashlimit_htable_max: '--hashlimit-htable-max', hashlimit_htable_expire: '--hashlimit-htable-expire', hashlimit_htable_gcinterval: '--hashlimit-htable-gcinterval', - + bytecode: '-m bpf --bytecode', } # These are known booleans that do not take a value, but we want to munge @@ -257,5 +257,5 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6 :set_mark, :match_mark, :connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone, :src_cc, :dst_cc, :hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst, :hashlimit_mode, :hashlimit_srcmask, :hashlimit_dstmask, :hashlimit_htable_size, - :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :name] + :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :bytecode, :name] end diff --git a/lib/puppet/provider/firewall/iptables.rb b/lib/puppet/provider/firewall/iptables.rb index 15c99d1..776aa3e 100644 --- a/lib/puppet/provider/firewall/iptables.rb +++ b/lib/puppet/provider/firewall/iptables.rb @@ -167,6 +167,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa hashlimit_htable_max: '--hashlimit-htable-max', hashlimit_htable_expire: '--hashlimit-htable-expire', hashlimit_htable_gcinterval: '--hashlimit-htable-gcinterval', + bytecode: '-m bpf --bytecode', } # These are known booleans that do not take a value, but we want to munge @@ -300,7 +301,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone, :src_cc, :dst_cc, :hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst, :hashlimit_mode, :hashlimit_srcmask, :hashlimit_dstmask, :hashlimit_htable_size, - :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :name + :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :bytecode, :name ] def insert diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb index 55e6502..4535a56 100644 --- a/lib/puppet/type/firewall.rb +++ b/lib/puppet/type/firewall.rb @@ -68,6 +68,7 @@ Puppet::Type.newtype(:firewall) do feature :queue_num, 'Which NFQUEUE to send packets to' feature :queue_bypass, 'If nothing is listening on queue_num, allow packets to bypass the queue' feature :hashlimit, 'Hashlimit features' + feature :bpf, 'Berkeley Paket Filter feature' # provider specific features feature :iptables, 'The provider provides iptables features.' @@ -1703,6 +1704,13 @@ Puppet::Type.newtype(:firewall) do PUPPETCODE end + newproperty(:bytecode, required_features: :iptables) do + desc <<-PUPPETCODE + Match using Linux Socket Filter. Expects a BPF program in decimal format. + This is the format generated by the nfbpf_compile utility. + PUPPETCODE + end + autorequire(:firewallchain) do reqs = [] protocol = nil diff --git a/spec/acceptance/bytecode_spec.rb b/spec/acceptance/bytecode_spec.rb new file mode 100644 index 0000000..6a5df95 --- /dev/null +++ b/spec/acceptance/bytecode_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper_acceptance' + +# --bytecode is only supported by operatingsystems using nftables (in general Linux kernel 3.13, RedHat 7 (and derivates) with 3.10) +# Skipping those from which we know they would fail. +describe 'bytecode property', unless: (fact('osfamily') == 'RedHat' && fact('operatingsystemmajrelease') < '7') || + (fact('operatingsystem') == 'OracleLinux' && fact('operatingsystemmajrelease') <= '7') || + (fact('operatingsystem') == 'SLES' && fact('operatingsystemmajrelease') <= '11') do + describe 'bytecode' do + context '4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0' do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '102 - test': + action => 'accept', + bytecode => '4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0', + chain => 'OUTPUT', + proto => 'all', + table => 'filter', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp, catch_failures: true) + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A OUTPUT -m bpf --bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0" -m comment --comment "102 - test" -j ACCEPT}) + end + end + end + end +end -- 2.45.2