diff --git a/docs/rolereference.rst b/docs/rolereference.rst index b6e1f6c0af206d87420572173b6a1b4f2fcc11c8..2a193eb80a9cdd7493f92303ce0788f9a1bc2e69 100644 --- a/docs/rolereference.rst +++ b/docs/rolereference.rst @@ -202,6 +202,11 @@ The role implements the following: itself, and provided they know the exact path of the file. * Deploys CA certificate files, normally used for truststore purposes, to ``/etc/ssl/certs/``. +* Installs ferm (for iptables management), configuring a basic firewall which + allows ICMP echo requests (PING), incoming connection on TCP port 22 (SSH), + and also introduces rate-limitting for incoming ICMP echo request pacakges and + (new) TCP connections. The rate-limitting is based on the source IP address, + using the ``iptables hashlimit`` module. Parameters @@ -253,6 +258,17 @@ Parameters on originating (Ansible) host that should be copied to destination server. +**incoming_connection_limit** (string, mandatory) + Rate at which the incoming ICMP echo-request packages and new TCP connections + will be accepted at. The value should be specified in the same format as value + for the ``iptables hashlimit`` option ``--hashlimit-upto``. + +**incoming_connection_limit_burst** (string, mandatory) + Initial burst of packages that should be accepted when the client with + distinct source IP address connects to the server for the first time (usually + higher than ``incoming_connection_limit``), even if it would go above the + specified connection limit. + Examples ~~~~~~~~ @@ -289,6 +305,10 @@ packages on all servers: ca_certificates: - ../certs/truststore.pem + incoming_connection_limit: 2/second + + incoming_connection_limit_burst: 6 + .. _ldap_client: LDAP Client diff --git a/roles/common/files/ferm b/roles/common/files/ferm new file mode 100644 index 0000000000000000000000000000000000000000..c55aaece416ac48d56857e8d2b285e1491560cab --- /dev/null +++ b/roles/common/files/ferm @@ -0,0 +1,13 @@ +# configuration for /etc/init.d/ferm + +# use iptables-restore for fast firewall initialization? +FAST=yes + +# cache the output of ferm --lines in /var/cache/ferm? +CACHE=no + +# additional paramaters for ferm (like --def '=bar') +OPTIONS= + +# Enable the ferm init script? (i.e. run on bootup) +ENABLED="yes" diff --git a/roles/common/files/ferm.conf b/roles/common/files/ferm.conf new file mode 100644 index 0000000000000000000000000000000000000000..7af9b7e5930dfc63ba7a82872a4f125c517a4998 --- /dev/null +++ b/roles/common/files/ferm.conf @@ -0,0 +1 @@ +@include '/etc/ferm/conf.d/'; diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml index 5fcab47bf514e4a8aa47f19facce327965a15050..6f862a1672d5a51670680633b2bac74a2fe21c7c 100644 --- a/roles/common/handlers/main.yml +++ b/roles/common/handlers/main.yml @@ -8,3 +8,6 @@ - name: Update CA certificate cache command: /usr/sbin/update-ca-certificates --fresh + +- name: Restart ferm + service: name=ferm state=restarted \ No newline at end of file diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 4d560b588b072e0380ef263df12f37449bf130c2..20fc0f5292bf9a2cdf2cb5bc7cf84deba5b8befd 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -55,3 +55,28 @@ with_items: ca_certificates notify: - Update CA certificate cache + +- name: Install ferm (for firewall management) + apt: name=ferm state=installed + +- name: Configure ferm init script coniguration file + copy: src=ferm dest=/etc/default/ferm owner=root group=root mode=644 + notify: + - Restart ferm + +- name: Create directory for storing ferm configuration files + file: dest="/etc/ferm/conf.d/" mode=750 state=directory owner=root group=root + +- name: Deploy main ferm configuration file + copy: src=ferm.conf dest=/etc/ferm/ferm.conf + notify: + - Restart ferm + +- name: Deploy ferm base rules + template: src=00-base.conf.j2 dest=/etc/ferm/conf.d/00-base.conf + owner=root group=root mode=640 + notify: + - Restart ferm + +- name: Enable ferm service + service: name=ferm state=started diff --git a/roles/common/templates/00-base.conf.j2 b/roles/common/templates/00-base.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..bf796d9b908f6073d5a7a43d968945d1ca87d77a --- /dev/null +++ b/roles/common/templates/00-base.conf.j2 @@ -0,0 +1,34 @@ +table filter { + chain INPUT { + policy DROP; + interface lo ACCEPT; + # Make sure not to allow flooding via ICMP ping packages by sending them + # to flood chain before state module kicks in. + proto icmp icmp-type echo-request jump flood; + mod state state (ESTABLISHED RELATED) ACCEPT; + # For TCP packages we perform floods checks after state module took care + # of established and related connections. + proto tcp tcp-flags (FIN SYN RST ACK) SYN jump flood; + # Accept some common incoming connections. + proto icmp icmp-type echo-request ACCEPT; + proto tcp dport 22 ACCEPT; + } + + # The flood chain is used for controlling the rate of the incoming connections. + chain flood { + # Rate-limit the ping requests. + proto icmp icmp-type echo-request { + mod hashlimit hashlimit {{ incoming_connection_limit }} hashlimit-burst {{ incoming_connection_limit_burst }} + hashlimit-mode srcip hashlimit-name icmp RETURN; + DROP; + } + # Rate-limit the TCP connections. + proto tcp tcp-flags (FIN SYN RST ACK) SYN { + mod hashlimit hashlimit {{ incoming_connection_limit }} hashlimit-burst {{ incoming_connection_limit_burst }} + hashlimit-mode srcip hashlimit-name icmp RETURN; + LOG; + DROP; + } + } + +} diff --git a/testsite/group_vars/all.yml b/testsite/group_vars/all.yml index ba0be1d66bcb00af2c05d061e90eb49a20025dc9..0d153c73a38d5c1f2cd6dd7c083f00f1a8b1e3d3 100644 --- a/testsite/group_vars/all.yml +++ b/testsite/group_vars/all.yml @@ -25,4 +25,8 @@ common_packages: - debconf-utils ca_certificates: - - "{{ inventory_dir }}/tls/example_ca_chain.pem" \ No newline at end of file + - "{{ inventory_dir }}/tls/example_ca_chain.pem" + +incoming_connection_limit: 2/second + +incoming_connection_limit_burst: 6 \ No newline at end of file