diff --git a/roles/firewall/defaults/main.yaml b/roles/firewall/defaults/main.yaml index 4cca7e0..00da283 100644 --- a/roles/firewall/defaults/main.yaml +++ b/roles/firewall/defaults/main.yaml @@ -11,6 +11,10 @@ firewall_iptables_persistent_package_state: present firewall_iptables_persistent_service_state: started firewall_iptables_persistent_service_enabled: true +firewall_ulogd_package_state: present +firewall_ulogd_service_state: started +firewall_ulogd_service_enabled: true + firewall_iptables_persistent_plugin_path: /usr/share/netfilter-persistent/plugins.d firewall_ipset_save_path: /etc/iptables/ipset @@ -25,6 +29,11 @@ firewall_iptables_input_policy_v6: DROP firewall_iptables_output_policy_v6: ACCEPT firewall_iptables_forward_policy_v6: DROP +firewall_use_ulogd: true +firewall_ulogd_nflog_group: 1 +firewall_ulogd_syslog_facility: LOG_LOCAL0 +firewall_ulogd_syslog_level: LOG_INFO + firewall_drop_icmp_flood: true firewall_limit_icmp_flood_seconds: 1 firewall_limit_icmp_flood_hitcount: 6 diff --git a/roles/firewall/handlers/main.yaml b/roles/firewall/handlers/main.yaml index eacf086..d67082e 100644 --- a/roles/firewall/handlers/main.yaml +++ b/roles/firewall/handlers/main.yaml @@ -31,3 +31,8 @@ - name: iptables-persistent command: /usr/sbin/netfilter-persistent save + +- name: restart ulogd + service: + name: "{{ firewall_ulogd_service_name }}" + state: restarted diff --git a/roles/firewall/tasks/main.yaml b/roles/firewall/tasks/main.yaml index 716729a..3f0f31c 100644 --- a/roles/firewall/tasks/main.yaml +++ b/roles/firewall/tasks/main.yaml @@ -22,6 +22,26 @@ name: "{{ firewall_ipset_package_name }}" state: "{{ firewall_ipset_package_state }}" +- name: install ulogd + package: + name: "{{ firewall_ulogd_package_name }}" + state: "{{ firewall_ulogd_package_state }}" + +- name: configure ulogd + template: + src: ulogd.conf.j2 + dest: "{{ firewall_ulogd_config_path }}" + owner: root + group: root + mode: 0600 + notify: restart ulogd + +- name: manage ulogd service + service: + name: "{{ firewall_ulogd_service_name }}" + state: "{{ firewall_ulogd_service_state }}" + enabled: "{{ firewall_ulogd_service_enabled }}" + - name: patch iptables-persistent service for ipset template: src: 14-ipset.j2 diff --git a/roles/firewall/templates/ip6tables.j2 b/roles/firewall/templates/ip6tables.j2 index 3514800..9f1554e 100644 --- a/roles/firewall/templates/ip6tables.j2 +++ b/roles/firewall/templates/ip6tables.j2 @@ -4,11 +4,19 @@ :OUTPUT {{ firewall_iptables_output_policy_v6 }} -N LOG_ACCEPT +{% if firewall_use_ulogd %} +-A LOG_ACCEPT -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j NFLOG --nflog-group {{ firewall_ulogd_nflog_group }} --nflog-prefix "[iptables ACCEPT] " +{% else %} -A LOG_ACCEPT -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j LOG --log-prefix "[iptables ACCEPT] " --log-level info +{% endif %} -A LOG_ACCEPT -j ACCEPT -N LOG_DROP +{% if firewall_use_ulogd %} +-A LOG_DROP -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j NFLOG --nflog-group {{ firewall_ulogd_nflog_group }} --nflog-prefix "[iptables DROP] " +{% else %} -A LOG_DROP -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j LOG --log-prefix "[iptables DROP] " --log-level info +{% endif %} -A LOG_DROP -p tcp -m tcp -m comment --comment "reject tcp6" -j REJECT --reject-with tcp-reset -A LOG_DROP -p udp -m udp -m comment --comment "drop udp6" -j DROP -A LOG_DROP -m comment --comment "reject all inet6" -j REJECT --reject-with icmp6-adm-prohibited @@ -16,7 +24,11 @@ {% if firewall_limit_ssh %} -N LIMIT_SSH -A LIMIT_SSH -m recent --set --name SSH --rsource +{% if firewall_use_ulogd %} +-A LIMIT_SSH -m recent --update --seconds {{ firewall_limit_ssh_seconds }} --hitcount {{ firewall_limit_ssh_hitcount }} --name SSH --rsource -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j NFLOG --nflog-prefix "[iptables SSH BRUTE] " +{% else %} -A LIMIT_SSH -m recent --update --seconds {{ firewall_limit_ssh_seconds }} --hitcount {{ firewall_limit_ssh_hitcount }} --name SSH --rsource -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j LOG --log-prefix "[iptables SSH BRUTE] " --log-level info +{% endif %} -A LIMIT_SSH -p tcp -m tcp -m recent --update --seconds {{ firewall_limit_ssh_seconds }} --hitcount {{ firewall_limit_ssh_hitcount }} --name SSH --rsource -j SET --add-set cooloff_v6 src -A LIMIT_SSH -p tcp -m tcp -m set --match-set cooloff_v6 src -m comment --comment "rate limit ssh 22/tcp" -j REJECT --reject-with tcp-reset -A LIMIT_SSH -j ACCEPT @@ -25,7 +37,11 @@ {% if firewall_drop_icmp_flood %} -N ICMP_FLOOD -A ICMP_FLOOD -m recent --set --name ICMP --rsource +{% if firewall_use_ulogd %} +-A ICMP_FLOOD -m recent --update --seconds {{ firewall_limit_icmp_flood_seconds }} --hitcount {{ firewall_limit_icmp_flood_hitcount }} --name ICMP --rsource --rttl -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j NFLOG --nflog-prefix "[iptables ICMP FLOOD] " +{% else %} -A ICMP_FLOOD -m recent --update --seconds {{ firewall_limit_icmp_flood_seconds }} --hitcount {{ firewall_limit_icmp_flood_hitcount }} --name ICMP --rsource --rttl -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j LOG --log-prefix "[iptables ICMP FLOOD] " --log-level info +{% endif %} -A ICMP_FLOOD -m recent --update --seconds {{ firewall_limit_icmp_flood_seconds }} --hitcount {{ firewall_limit_icmp_flood_hitcount }} --name ICMP --rsource --rttl -m comment --comment "drop icmpv6 flood" -j REJECT --reject-with icmp6-adm-prohibited -A ICMP_FLOOD -j ACCEPT {% endif %} diff --git a/roles/firewall/templates/iptables.j2 b/roles/firewall/templates/iptables.j2 index e49271d..7b2bd89 100644 --- a/roles/firewall/templates/iptables.j2 +++ b/roles/firewall/templates/iptables.j2 @@ -4,11 +4,19 @@ :OUTPUT {{ firewall_iptables_output_policy }} -N LOG_ACCEPT +{% if firewall_use_ulogd %} +-A LOG_ACCEPT -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j NFLOG --nflog-group {{ firewall_ulogd_nflog_group }} --nflog-prefix "[iptables ACCEPT] " +{% else %} -A LOG_ACCEPT -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j LOG --log-prefix "[iptables ACCEPT] " --log-level info +{% endif %} -A LOG_ACCEPT -j ACCEPT -N LOG_DROP +{% if firewall_use_ulogd %} +-A LOG_DROP -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j NFLOG --nflog-group {{ firewall_ulogd_nflog_group }} --nflog-prefix "[iptables DROP] " +{% else %} -A LOG_DROP -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j LOG --log-prefix "[iptables DROP] " --log-level info +{% endif %} -A LOG_DROP -p tcp -m tcp -m comment --comment "reject tcp" -j REJECT --reject-with tcp-reset -A LOG_DROP -p udp -m udp -m comment --comment "drop udp" -j DROP -A LOG_DROP -m comment --comment "reject all" -j REJECT --reject-with icmp-admin-prohibited @@ -16,7 +24,11 @@ {% if firewall_limit_ssh %} -N LIMIT_SSH -A LIMIT_SSH -m recent --set --name SSH --rsource +{% if firewall_use_ulogd %} +-A LIMIT_SSH -m recent --update --seconds {{ firewall_limit_ssh_seconds }} --hitcount {{ firewall_limit_ssh_hitcount }} --name SSH --rsource -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j NFLOG --nflog-prefix "[iptables SSH BRUTE] " +{% else %} -A LIMIT_SSH -m recent --update --seconds {{ firewall_limit_ssh_seconds }} --hitcount {{ firewall_limit_ssh_hitcount }} --name SSH --rsource -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j LOG --log-prefix "[iptables SSH BRUTE] " --log-level info +{% endif %} -A LIMIT_SSH -p tcp -m tcp -m recent --update --seconds {{ firewall_limit_ssh_seconds }} --hitcount {{ firewall_limit_ssh_hitcount }} --name SSH --rsource -j SET --add-set cooloff_v4 src -A LIMIT_SSH -p tcp -m tcp -m set --match-set cooloff_v4 src -m comment --comment "rate limit ssh 22/tcp" -j REJECT --reject-with tcp-reset -A LIMIT_SSH -j ACCEPT @@ -25,7 +37,11 @@ {% if firewall_drop_icmp_flood %} -N ICMP_FLOOD -A ICMP_FLOOD -m recent --set --name ICMP --rsource +{% if firewall_use_ulogd %} +-A ICMP_FLOOD -m recent --update --seconds {{ firewall_limit_icmp_flood_seconds }} --hitcount {{ firewall_limit_icmp_flood_hitcount }} --name ICMP --rsource --rttl -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j NFLOG --nflog-prefix "[iptables ICMP FLOOD] " +{% else %} -A ICMP_FLOOD -m recent --update --seconds {{ firewall_limit_icmp_flood_seconds }} --hitcount {{ firewall_limit_icmp_flood_hitcount }} --name ICMP --rsource --rttl -m limit --limit {{ firewall_log_limit }} --limit-burst {{ firewall_log_limit_burst }} -j LOG --log-prefix "[iptables ICMP FLOOD] " --log-level info +{% endif %} -A ICMP_FLOOD -m recent --update --seconds {{ firewall_limit_icmp_flood_seconds }} --hitcount {{ firewall_limit_icmp_flood_hitcount }} --name ICMP --rsource --rttl -m comment --comment "drop icmp flood" -j REJECT --reject-with icmp-admin-prohibited -A ICMP_FLOOD -j ACCEPT {% endif %} diff --git a/roles/firewall/templates/ulogd.conf.j2 b/roles/firewall/templates/ulogd.conf.j2 new file mode 100644 index 0000000..16aa6a5 --- /dev/null +++ b/roles/firewall/templates/ulogd.conf.j2 @@ -0,0 +1,26 @@ +[global] + +# logfile for status messages +#logfile="syslog" + +# loglevel: debug(1), info(3), notice(5), error(7) or fatal(8) (default 5) +#loglevel=3 + +plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so" +plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inpflow_NFCT.so" +plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so" +plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2STR.so" +plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_PRINTPKT.so" +plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_PRINTFLOW.so" +plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_SYSLOG.so" +plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so" + +# this is a stack for logging packets to syslog after a collect via NFLOG +stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,sys1:SYSLOG + +[log1] +group={{ firewall_ulogd_nflog_group | default(0) }} + +[sys1] +facility={{ firewall_ulogd_syslog_facility | default("LOG_LOCAL0") }} +level={{ firewall_ulogd_syslog_level | default("LOG_INFO") }} diff --git a/roles/firewall/vars/Ubuntu.yaml b/roles/firewall/vars/Ubuntu.yaml index c538b58..18d2fbb 100644 --- a/roles/firewall/vars/Ubuntu.yaml +++ b/roles/firewall/vars/Ubuntu.yaml @@ -1,2 +1,7 @@ --- firewall_iptables_persistent_service_name: netfilter-persistent.service + +firewall_ulogd_package_name: ulogd2 +firewall_ulogd_service_name: ulogd2 + +firewall_ulogd_config_path: /etc/ulogd.conf