cfnetwork
Version information
This version is compatible with:
- Puppet Enterprise 2019.8.x, 2019.7.x, 2019.5.x, 2019.4.x, 2019.3.x, 2019.2.x, 2019.1.x, 2019.0.x, 2018.1.x, 2017.3.x, 2017.2.x, 2017.1.x, 2016.5.x, 2016.4.x
- Puppet >=4.7.0 <7.0.0
- ,
Start using this module
Add this module to your Puppetfile:
mod 'codingfuture-cfnetwork', '1.3.1'
Learn more about managing modules with a PuppetfileDocumentation
cfnetwork
Description
The module exclusively configures system network interfaces, related sysctl items and system firewall. The module is designed to be used with Hiera-like data providers.
Concept
Each network interface has a unique name. This identifier is used in firewall port definition to specify the interface to apply the rule.
There are predefined interface names:
'local'
- assign rule to loopback interface'any'
- assign rule to all interfaces, unless src or dst is specified. See below.
Each firewall rule name has format of "interface:service"
. Optionally, additional tag can be
specified like "interface:service:tag"
. Such format allows resource to be defined multiple
times with no name clash and no need for explicit virtual resource processing.
!!! ALL CONNECTIONS ARE BLOCKED BY DEFAULT, EVEN LOCAL !!!
The module is designed without actual firewall implementation to serve as abstract API for plug&play firewall rules definition. For example:
- this module automatically enables DNS clients and services, if '$local' or '$serve' is configured
- cfauth module automatically enables incoming SSH connections on configured ports from admin hosts
- cfsystem module automatically defines rules for NTP, APT repositories, APT cache, puppet, etc.
- [cfdb] module allows outgoing database connections for particular users.
Examples:
class { 'cfnetwork':
main => {
device => 'eth0',
address => [
'128.0.0.2/24',
'128.0.0.3/24',
'128.0.0.4/24',
],
gateway => '128.0.0.1',
},
dns => ['8.8.8.8', '8.8.4.4'],
is_router => true,
}
cfnetwork::iface { 'dmz1':
device => 'eth2',
address => '128.0.1.2/24',
# no gateway
}
cfnetwork::iface { 'dmz2':
device => 'eth3',
address => '128.0.2.2/24',
# no gateway
}
cfnetwork::describe_service { myservice':
server => ['tcp/123', 'udp/234']
}
cfnetwork::describe_service { myhttp':
server => ['tcp/80', 'tcp/443']
}
# allow incoming for myservice on auto-detected dmz1 and dmz2 ifaces
# note: still, please consider using explicit ifaces
cfnetwork::service_port { 'any:myservice':
src => [
'128.0.1.0/24',
'128.0.2.0/24',
'ipset:myclients',
]
}
# allow client request on main interface
cfnetwork::client_port { 'main:myhttp:tag1': }
# duplicate, no worry
cfnetwork::client_port { 'main:myhttp:tag2': }
# allow client request on dmz2
cfnetwork::client_port { 'dmz2:myhttp': }
# Allow clients from dmz1 to dmz2
cfnetwork::router_port { 'dmz1/dmz2:myhttp': }
# DNAT external to dmz2
cfnetwork::dnat_port { 'main/dmz2:myhttp':
to_dst => 'dmz2server',
}
cfnetwork::ipset { 'myclients':
addr => [
'128.0.3.0/24',
]
}
cfnetwork::ipset { 'otherset':
addr => [
'128.0.4.0/24',
'ipset:myclients',
]
}
The same using Hiera:
# someconfig.yaml
classes:
- cfnetwork
cfnetwork::main:
device: eth0
address:
- '128.0.0.2/24'
- '128.0.0.3/24'
- '128.0.0.4/24'
gateway: '128.0.0.1'
cfnetwork::dns:
- '8.8.8.8'
- '8.8.4.4'
cfnetwork::is_router: true
cfnetwork::ifaces:
dmz1:
device: eth1
address: '128.0.1.1/24'
dmz2:
device: eth2
address: '128.0.2.1/24'
cfnetwork::describe_services:
myservice:
server:
- 'tcp/123'
- 'udp/234'
myhttp: { server: [ 'tcp/80', 'tcp/443' ] }
cfnetwork::service_ports:
'any:myservice':
src:
- '128.0.1.0/24'
- '128.0.2.0/24'
- 'ipset:myclients'
cfnetwork::client_ports:
'main:myhttp:tag1': {}
'main:myhttp:tag2': {}
'dmz2:myhttp': {}
cfnetwork::router_ports
'dmz1/dmz2:myhttp': {}
cfnetwork::dnat_ports:
'main/dmz2:myhttp': {}
cfnetwork::ipsets:
myclients:
addr:
- '128.0.3.0/24'
otherset:
addr:
- '128.0.4.0/24'
- 'ipset:myclients'
'any' interface matching rules
If client port has 'src' property set then rule is applied only to matching interfaces. If server port has 'dst' property set then rule is applied only to matching interfaces.
A matching interface is one of:
- 'address' and 'extra_addresses' of interface subnets matches 'dst'
- otherwise default interface is used, which is 'gateway' property defined
Public interface notes
- All not routable private networks will be dropped for incoming and outgoing packets
- Automatic SNAT to
address
enabled for all valid destinations with unroutable source address - Default policy is DROP. For private interfaces default policy is REJECT
ipset notes
- Main name pattern:
[a-z][a-z0-9_]
- Referred as "ipset:<main_name' (e.g.
ipset:admins
) - Allowed in any
src/dst/to_dst
of port types - Allowed in
addr
of other ipsets - Additional entries can be defined with partial definition:
- Partial name pattern:
<main_name>:[a-z][a-z0-9_]
- It's not allowed to refer to partial names
- Note:
type
attribute must match the main definition
- Partial name pattern:
Dependency on configured firewall
Please depend on Anchor['cfnetwork:firewall']
, if you need new firewal configuration before
some processing.
Technical Support
- Example configuration
- Free & Commercial support: support@codingfuture.net
Setup
Up to date installation instructions are available in Puppet Forge: https://forge.puppet.com/codingfuture/cfnetwork
Please use librarian-puppet or cfpuppetserver module to deal with dependencies.
There is a known r10k issue RK-3 which prevents automatic dependencies of dependencies installation.
Examples
Please check codingufuture/puppet-test for example of a complete infrastructure configuration and Vagrant provisioning.
Implicitly created resources
cfnetwork::ipsets:
blacklist:
type: net
dynamic: true
whitelist:
type: net
dynamic: true
localnet:
type: net
addr:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 'fd00::/8'
cfnetwork::describe_services:
'dns':
server: [ 'tcp/53', 'udp/53' ]
client: 'any'
'http':
server: [ 'tcp/80' ]
client: 'any'
'https':
server: [ 'tcp/443' ]
client: 'any'
'cfhttp':
server: [ 'tcp/80', 'tcp/443' ]
client: 'any'
'alltcp':
server: 'tcp/1:65535'
client: 'any'
comment: "Use to open all TCP ports (e.g. for local)"
'alludp':
server: 'udp/1:65535'
client: 'any'
comment: "Use to open all UDP ports (e.g. for local)"
'allports':
server: [ 'udp/1:65535', 'tcp/1:65535']
client: 'any'
comment: "Use to open all TCP and UDP ports (e.g. for local)"
cfnetwork::service_ports:
'local:dns': {}
comment: 'only in $serve or $local mode'
"${cfnetwork::service_face}:dns":
comment: 'only in $serve mode'
cfnetwork::client_ports:
'any:dns:dnsmasq':
user: 'dnsmasq'
comment: 'only in $serve or $local mode'
'any:dns:cfnetwork':
dst: $cfnetwork::dns
comment: 'unless in $serve or $local mode'
'any:dns:cfnetwork':
comment: 'only if no DNS servers are configured'
'{iface}:dhcp:cfnetwork':
comment: "for IPv4 ifaces with method=dhcp"
'{iface}:dhcpv6:cfnetwork':
comment: "for IPv6 ifaces with method=dhcp"
cfnetwork::router_ports:
# for each cfnetwork::dnat_port
anchor:
'cfnetwork:firewall'
Classes and resources types
cfnetwork
class
main
Main network interface configuration, see cfnetwork::iface for details. Can be defined separately.dns
DNS server list. Can be defined directly with one of cfnetwork::iface. Special values:- '$local' - Setup own DNS cache - '$serve' - Same as '$recure', but also serve clients on $service_face
- 'ifaces' Create cfnetwork::iface resources, if set
- 'describe_services' Create cfnetwork::describe_services resources, if set
- 'service_ports' Create cfnetwork::service_port resources, if set
- 'client_ports' Create cfnetwork::client_port resources, if set
- 'dnat_ports' Create cfnetwork::dnat_port resources, if set
- 'router_ports' Create cfnetwork::router_port resources, if set
- 'is_router' =
false
If true, enables packet forwarding and other related sysctl - 'optimize_10gbe' =
false
If true, optimizes network stack for 10+ Gbit network - 'firewall_provider' =
'auto'
Module name, implementing fireall provider. Its value is a soft dependency. 'cffirehol' is used by default for Linux - 'export_resources' =
true
If true, resources are exported to PuppetDB as well service_face
='any'
- the interface to listen for client of configured serviceshosts = undef
- arbitrary definition of custom /etc/hosts entries based onhost
typehosts_locality = 'localtion'
- either 'location' or 'pool' for static hosts selectionprefer_ipv4 = true
- prefer IPv4 address resolution over IPv6dnnsec = on
- control systemd-resolved DNSSEC option
cfnetwork::iface
type
device
=$title
- system interface device name, e.g. 'eth0'method
= 'static' - address setup method ('static' of 'dhcp'). Please avoid DHCP as possible. Note: it is allowed to specify 'net/prefix' address as firewall hint for private interfacesaddress
- list of IPv4 and IPv6 addresses with /netprefix- (string)
- (array)
routes
- additional routes, if any- (string) - maps to
network
in hash below - (hash)
network
- network address to routevia
- gateway to use, if anymetric
- metric to set, if any
- (string) - maps to
gateway
- default gateway to setup. Only one iface must have one.- (string) either IPv4 or IPv6 address
- (array) one IPv4 and one IPv6 address
dns_servers
- DNS servers to use. Only one iface should have one.domain
- DNS search domain, auto-detect by default- Bridge setup:
bridge_ports
- Indicates a bridge device. List of participating ports.bridge_stp
- enabled STP, if setbridge_fd
- forwarding delay
- Bonding setup:
bond_slaves
- slave device listbond_primary
- primary slavebond_mode
- bonding mode, see modinfo bondingbond_miimon
= MII monitoring interval, see modinfo bonding
preup
list of arbitrary commands to execute before bringing the interface up (not recommended, preferup
)up
list of arbitrary commands to execute after interface is updown
list of arbitrary commands to execute before interface goes downpostdown
list of arbitrary commands to execute after interface gets downipv6 = false
control IPv6 support on the interfacefalse
- disable IPv6true
- enable IPv6'auto'
- enable IPv6, if explicitly configured'only'
- enable IPv6 and disable IPv4
force_public
- firewall-specific. Force mark the interface as public, even if it has address from private range, what is useful in cloud environments with suboptimal NAT.debian_template
='cfnetwork/debian_iface.epp'
- supply own template for non-standard interface setupcustom_args
- provide custom arguments to custom$debian_template
cfnetwork::ipset
type
Define ipset
item.
- Title:
- Main name:
[a-z][a-z0-9_]*
(e.g. "blacklist") - Partial additions to the main list:
<main_name>:[a-z][a-z0-9_]*
(e.g. "blacklist:attackers", "blacklist:spam")
- Main name:
$addr
- mixes list of IPv4 & IPv6 addresses and other ipsets in formipset:<main_name>
$type = 'net'
- eitherip
ornet
. Seeman ipset
$dynamic = false
- notify firewall that additional addresses can be added dynamically (e.g. dynamic list of attackers)$comment = undef
- arbitrary comment
cfnetwork::describe_service
type
Describe service to use in firewall rules.
- Title:
<service>
server
- list of server-side ports in format "protocol/port", example: 'tcp/80', 'udp/53'client
= 'default' - list of client-side ports, 'default' - firewall-specific (all ports or 1024-65535)
cfnetwork::client_port type
Define allowed outgoing connection for on .
- Title:
<iface>:<service>[:<tag>]
src
- list of allowed source addresses, if anydst
- list of allowed destination addresses, if anyuser
- list of allowed system user namesgroup
- list of allowed system group namescomment
- arbitrary comment
cfnetwork::service_port
type
Define allowed incoming connection for on .
- Title:
<iface>:<service>[:<tag>]
src
- list of allowed source addresses, if anydst
- list of allowed destination addresses, if anycomment
- arbitrary comment
cfnetwork::router_port
type
Define allowed routing connection from to for .
- Title:
<iface>/<outface>:<service>[:<tag>]
src
- list of allowed source addresses, if anydst
- list of allowed destination addresses, if anycomment
- arbitrary comment
cfnetwork::dnat_port
type
Destination Network Address Translation to for . Note: implicit cfnetwork::route_port is defined - no need to define one manually.
- Title:
<iface>/<outface>:<service>[:<tag>]
src
- list of allowed source addresses, if anydst
- list of allowed destination addresses, if anyto_dst
- DNAT to specific address(s)to_port
- (int) re-assign port, if neededcomment
- arbitrary comment
cfnetwork::dnsmasq
class
Tune automatically installed dnsmasq
, if $local
or $serve
.
$upstream = ['8.8.8.8', '8.8.4.4']
- upstream servers, Public Google DNS by default$dnssec = true
- if true, enable DNSSEC validation on dnsmasq$memlimit = '8M'
- systemd memory limit for dnsmasq service$custom_config = ''
- any arbitrary text to include in dnsmasq.conf
cfnetwork::sysctl
class
Self-explanatory sysctl settings with their defaults, unless specially noted:
$enable_bridge_filter
=!$::cfnetwork::is_router
Only if false, loadsbridge
module and disable netfilter calls on bridges. Use routing instead of bridges, if you really need to do filtering or enable it. After enabling, you will need to cleanup sysctl.conf and setup values manually.$rp_filter
=1
$netdev_max_backlog
=30000
if$cfnetwork::optimize_10gbe
else2000
$tcp_fin_timeout
=3
Note: it can be too aggressive$tcp_keepalive_time
=300
$tcp_keepalive_probes
=3
$tcp_keepalive_intvl
=15
$tcp_max_syn_backlog
=4096
$tcp_no_metrics_save
=1
$tcp_rfc1337
=1
$tcp_sack
=1
$tcp_slow_start_after_idle
=0
$tcp_synack_retries
=2
$tcp_syncookies
=1
$tcp_timestamps
=1
$tcp_tw_recycle
=1
$tcp_tw_reuse
=1
$tcp_window_scaling
=1
$file_max
= 256 per every 4MB of RAM$somaxconn
= 2048 per every 1GB of RAM$ip_local_port_range
='2000 65535'
$rmem_max
=212992
Note: it does not apply to TCP$wmem_max
=212992
Note: it does not apply to TCP$rmem_default
=$rmem_max
$wmem_default
=$wmem_max
$tcp_rmem_max
=67108864
if$cfnetwork::optimize_10gbe
else16777216
$tcp_wmem_max
=67108864
if$cfnetwork::optimize_10gbe
else16777216
$tcp_rmem_default
=$tcp_rmem_max / 128
Please note, you have to setup manually, if$tcp_rmem_max
is set$tcp_wmem_default
=$tcp_wmem_max / 128
Please note, you have to setup manually, if$tcp_wmem_max
is set$nf_conntrack_max
=undef
Note: recent kernels do good autoconfig$nf_conntrack_expect_max
=undef
Note: recent kernels do good autoconfig$nf_conntrack_generic_timeout
=600
$nf_conntrack_tcp_timeout_syn_sent
=20
Note: it can be too aggressive$nf_conntrack_tcp_timeout_syn_recv
=10
Note: it can be too aggressive$nf_conntrack_tcp_timeout_established
=1200
Note: it can be too aggressive$nf_conntrack_tcp_timeout_last_ack
=5
Note: it can be too aggressive$nf_conntrack_tcp_timeout_time_wait
=3
Note: it can be too aggressive$nf_conntrack_tcp_loose
=0
Note: you don't want to set 1 with pedantic firewall$nf_conntrack_tcp_be_liberal
=0
Note: you don't want to set 1 with pedantic firewall$nf_conntrack_tcp_max_retrans
=3
Note: it can be too aggressive$nf_conntrack_udp_timeout
=30
Note: it can be too aggressive$nf_conntrack_udp_timeout_stream
=60
Note: it can be too aggressive$nf_conntrack_icmp_timeout
=30
Public API
Cfnetwork::Bindaddress
- type alias for bind address nameCfnetwork::Ifacename
- type alias for interface nameCfnetwork::Port
- type alias for network port Integercfnetwork::bind_address(arg)
- get bind address for specified arg, where:- 'iface' - first address of Cfnetwork::Iface[iface] resource
- 'iface:N' - address #N of Cfnetwork::Iface[iface] resource
cfnetwork::fw_face(arg)
- extract firewall interface name from Cfnetwork::Bindaddress
Change Log
All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning.
1.3.1 (2019-06-17)
- NEW: cfnetwork::dnssec option to control systemd-resolved DNSSEC
1.3.0 (2019-04-14)
- CHANGED: to allow dash in domain names
- CHANGED: cfnetwork::ipset to also force fetching hosts
- FIXED: host names to allow underscores and hyphens (DNS assumption)
- FIXED: to update resolved.conf for systemd-resolved
1.1.0 (2018-12-09)
- CHANGED: updated for Ubuntu 18.04 Bionic support
- FIXED: to define cfnetwork::dns_servers for systemd-resolved case
- FIXED: to define http, https and cfhttp inside cfnetwork
- NEW: cfnetwork::hosts_locality feature
- NEW: cfnetwork::prefer_ipv4 feature
1.0.1 (2018-04-30)
- CHANGED: remove silent for sysctl what leads to implicit issues
- FIXED: improved bridge sysctl handling
0.12.2 (2018-03-19)
- FIXED: added post-modprobe delay to workaround sysctl failures due to race condition
- FIXED: to remove 0/0 & ::/0 implicit routes from DHCP interfaces (fixes cffirehol logic)
0.12.1
- CHANGED: improved DNS service security with ipset:localnet
- NEW: ipset:localnet feature
0.12.0
- FIXED: minor Puppet 5 issue in sort_ipv
0.11.8
- CHANGED: not to set deprecated 'net.ipv4.tcp_tw_recycle'
0.11.7
- FIXED: to excluded bundler-related stuff
0.11.6
- FIXED: not to show warning forced DNSSEC disable, unless dnsmasq is used
0.11.5
- FIXED: to forcibly disable DNSSEC for <Stretch & <Xenial due to bug in dnsmasq
0.11.4
- FIXED: added missing DNSSEC root anchor to dnsmasq config
0.11.3
- NEW: Puppet 5.x support
- NEW: Ubuntu Zesty support
0.11.2
- Fixed 'cfsystem::bind_address' to support undefined 'local' face
0.11.1
- BROKEN
0.11.0
- Andded 'cfnetwork:firewall' anchor
- Added a new 'cfnetwork::bind_address' API to properly retrieve iface bind address
- Deprecated 'cf_get_iface_address'
- Added automatic creation of host entries for each interface and additional addresses
- Added cfnetwork::hosts parameter
- Added cfnetwork:pre-firewall anchor
- Added fetch of exported host entries used in firewall
- Changed to allow failed to resolve DNS entries in firewall config not to break bootstrap
- Changed prune of unknown /etc/hosts entries
- Improved cf_location/cf_location_pool support on initial deployment when facts are not set (lookup of cfsystem parameters)
- Changed $firewall_provider to 'auto' by default
0.10.1
- Minor improvement for error reporting of internal features
- Allowed to specify expected DHCP address range as firewall hint
- Fixed to allow DNS queries to all destinations if DNS servers are not set
- Changed to use dnsmasq instead of abandoned pdnsd NOTE: dnsmasq has no recursive resolver
- Renamed '$recurse' to '$local' to better reflect dnsmasq behavior
- Disabling IPv6 DHCP, if IPv6 = 'auto'
0.10.0
- Much better support for IPv6 now
- Small redesign of cfnetwork::iface parameters
extra_routes
&extra_addresses
are deprecated nowaddress
- can list multiple addresses nowgateway
- can list multiple entries (one for IPv4 and one for IPv6)routes
- any additional routes
- Fixed
routes
/extra_routes
paramter type for Struct case - Improved handling of DHCP interfaces
- Fixed to use IPv6 "auto" method, if 'static' is missing IP address
0.9.11
- Implemented support for ipsets
- Automatic newer puppet-lint fixes
- Fixed puppet-lint and metadata-json-lint warnings
- Enforced strict parameter types
0.9.10
- Fixed minor rare issue with new Puppet 4.6.x release
0.9.9
- Added an explicit dependency of resolv.conf on pdnsd
0.9.8
- Updated supported OS list
0.9.7
- Minor fixes for strict mode
0.9.6
- Fixed systems with kernel 3.18+ to load br_netfilter to properly setup sysctl
0.9.5
- Fixed issue of missing default parameters in DB of exported port/host. It is a workaround for: PUP-6014
- Fixed pdnsd to serve /etc/hosts entries for all domains
- Fixed to properly refresh pdnsd on new exported host getting added
0.9.4
- Fixed to fully generate resolv.conf overriding all dynamic changes
- Changed sysctl configuration to use PuppetLabs approved augeas module
0.9.3
- Fixed outdated root DNS server list in pdnsd config
- Fixed cfnetwork::iface:extra_routes to support plain string, but not only arrays
- Fixed to enforce current DNS settings in /etc/resolv.conf
0.9.2
- Added hiera.yaml version 4 support
- Fixed to use 'local' instead of 'lo' interface for DNS service
0.9.1
- Fixed error with DHCP interfaces
- Added possibility to provide custom debian interface template
- Changed to export resources by default (requires PuppetDB)
0.9.0
Initial release
Dependencies
- puppetlabs-stdlib (>= 5.2.0 <6.0.0)
- herculesteam/augeasproviders_sysctl (>= 2.3.1 <3.0.0)
CodingFuture Infrastructure Automation Project cfnetwork: Intelligent Network & Firewall Configuration module Copyright 2016-2019 (c) Andrey Galkin Contacts: * support@codingfuture.net * andvgal@gmail.com Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.