|
2 | 2 | # vim: ft=sls
|
3 | 3 |
|
4 | 4 | # Firewall management module
|
5 |
| -{% from "iptables/map.jinja" import firewall with context %} |
6 |
| -{% set install = firewall.install %} |
7 |
| -{% set strict_mode = firewall.strict %} |
8 |
| -{% set global_block_nomatch = firewall.block_nomatch %} |
9 |
| -{% set packages = firewall.pkgs %} |
10 |
| -{% set ipv4 = 'IPv4' %} |
11 |
| -{% set ipv6 = 'IPv6' %} |
12 |
| -{% set protocols = [ipv4] %} |
13 |
| -{% if firewall.get('ipv6', False) %} |
14 |
| -{% do protocols.append(ipv6) %} |
15 |
| -{% endif %} |
16 |
| -{% set suffixes = {ipv4: '', ipv6: '_ipv6'} %} |
| 5 | +{%- from "iptables/map.jinja" import firewall with context %} |
| 6 | +{%- set install = firewall.install %} |
| 7 | +{%- set strict_mode = firewall.strict %} |
| 8 | +{%- set global_block_nomatch = firewall.block_nomatch %} |
| 9 | +{%- set packages = firewall.pkgs %} |
| 10 | +{%- set ipv4 = 'IPv4' %} |
| 11 | +{%- set ipv6 = 'IPv6' %} |
| 12 | +{%- set protocols = [ipv4] %} |
| 13 | +{%- if firewall.get('ipv6', False) %} |
| 14 | +{%- do protocols.append(ipv6) %} |
| 15 | +{%- endif %} |
| 16 | +{%- set suffixes = {ipv4: '', ipv6: '_ipv6'} %} |
17 | 17 |
|
18 | 18 | {%- if firewall.enabled %}
|
19 |
| - {%- if install %} |
20 |
| - # Install required packages for firewalling |
21 |
| - iptables_packages: |
22 |
| - pkg.installed: |
23 |
| - - pkgs: |
24 |
| - {%- for pkg in packages %} |
25 |
| - - {{pkg}} |
26 |
| - {%- endfor %} |
27 |
| - {%- endif %} |
28 |
| -
|
29 |
| - {%- if strict_mode %} |
30 |
| - # If the firewall is set to strict mode, we'll need to allow some |
31 |
| - # that always need access to anything |
32 |
| - {%- for protocol in protocols %} |
33 |
| - iptables_allow_localhost{{suffixes[protocol]}}: |
34 |
| - iptables.append: |
35 |
| - - table: filter |
36 |
| - - chain: INPUT |
37 |
| - - jump: ACCEPT |
38 |
| - {%- if protocol == ipv4 %} |
39 |
| - - source: 127.0.0.1 |
40 |
| - {%- else %} |
41 |
| - - source: ::1 |
42 |
| - - family: ipv6 |
43 |
| - {%- endif %} |
44 |
| - - save: True |
45 |
| -
|
46 |
| - # Allow related/established sessions |
47 |
| - iptables_allow_established{{suffixes[protocol]}}: |
48 |
| - iptables.append: |
49 |
| - - table: filter |
50 |
| - - chain: INPUT |
51 |
| - - jump: ACCEPT |
52 |
| - - match: conntrack |
53 |
| - - ctstate: 'RELATED,ESTABLISHED' |
54 |
| - {%- if protocol == ipv6 %} |
55 |
| - - family: ipv6 |
56 |
| - {%- endif %} |
57 |
| - - save: True |
| 19 | +{%- if install %} |
| 20 | +# Install required packages for firewalling |
| 21 | +iptables_packages: |
| 22 | + pkg.installed: |
| 23 | + - pkgs: |
| 24 | +{%- for pkg in packages %} |
| 25 | + - {{pkg}} |
| 26 | +{%- endfor %} |
| 27 | +{%- endif %} |
58 | 28 |
|
59 |
| - # Set the policy to deny everything unless defined |
60 |
| - enable_reject_policy{{suffixes[protocol]}}: |
61 |
| - iptables.set_policy: |
62 |
| - - table: filter |
63 |
| - - chain: INPUT |
64 |
| - - policy: DROP |
65 |
| - {%- if protocol == ipv6 %} |
66 |
| - - family: ipv6 |
67 |
| - {%- endif %} |
68 |
| - - require: |
69 |
| - - iptables: iptables_allow_localhost{{suffixes[protocol]}} |
70 |
| - - iptables: iptables_allow_established{{suffixes[protocol]}} |
71 |
| - {%- endfor %} |
72 |
| - {%- endif %} |
| 29 | +{%- if strict_mode %} |
| 30 | +# If the firewall is set to strict mode, we'll need to allow some |
| 31 | +# that always need access to anything |
| 32 | +{%- for protocol in protocols %} |
| 33 | +iptables_allow_localhost{{suffixes[protocol]}}: |
| 34 | + iptables.append: |
| 35 | + - table: filter |
| 36 | + - chain: INPUT |
| 37 | + - jump: ACCEPT |
| 38 | +{%- if protocol == ipv4 %} |
| 39 | + - source: 127.0.0.1 |
| 40 | +{%- else %} |
| 41 | + - source: ::1 |
| 42 | + - family: ipv6 |
| 43 | +{%- endif %} |
| 44 | + - save: True |
73 | 45 |
|
74 |
| - # Generate ipsets for all services that we have information about |
75 |
| - {%- for protocol in protocols %} |
76 |
| - {%- for service_name, service_details in firewall.get('services' + suffixes[protocol], {}).items() %} |
77 |
| - {% set block_nomatch = service_details.get('block_nomatch', False) %} |
78 |
| - {% set interfaces = service_details.get('interfaces','') %} |
79 |
| - {% set protos = service_details.get('protos',['tcp']) %} |
80 |
| - {% if service_details.get('comment', False) %} |
81 |
| - {% set comment = '- comment: ' + service_details.get('comment') %} |
82 |
| - {% else %} |
83 |
| - {% set comment = '' %} |
84 |
| - {% endif %} |
| 46 | +# Allow related/established sessions |
| 47 | +iptables_allow_established{{suffixes[protocol]}}: |
| 48 | + iptables.append: |
| 49 | + - table: filter |
| 50 | + - chain: INPUT |
| 51 | + - jump: ACCEPT |
| 52 | + - match: conntrack |
| 53 | + - ctstate: 'RELATED,ESTABLISHED' |
| 54 | +{%- if protocol == ipv6 %} |
| 55 | + - family: ipv6 |
| 56 | +{%- endif %} |
| 57 | + - save: True |
85 | 58 |
|
86 |
| - # Allow rules for ips/subnets |
87 |
| - {%- for ip in service_details.get('ips_allow', ['0.0.0.0/0']) %} |
88 |
| - {%- if interfaces == '' %} |
89 |
| - {%- for proto in protos %} |
90 |
| - iptables_{{service_name}}_allow_{{ip}}_{{proto}}{{suffixes[protocol]}}: |
91 |
| - iptables.insert: |
92 |
| - - position: 1 |
93 |
| - - table: filter |
94 |
| - - chain: INPUT |
95 |
| - - jump: ACCEPT |
96 |
| - - source: {{ ip }} |
97 |
| - - dport: {{ service_name }} |
98 |
| - - proto: {{ proto }} |
99 |
| - {%- if protocol == ipv6 %} |
100 |
| - - family: ipv6 |
101 |
| - {%- endif %} |
102 |
| - - save: True |
103 |
| - {{ comment }} |
104 |
| - {%- endfor %} |
105 |
| - {%- else %} |
106 |
| - {%- for interface in interfaces %} |
107 |
| - {%- for proto in protos %} |
108 |
| - iptables_{{service_name}}_allow_{{ip}}_{{proto}}_{{interface}}{{suffixes[protocol]}}: |
109 |
| - iptables.insert: |
110 |
| - - position: 1 |
111 |
| - - table: filter |
112 |
| - - chain: INPUT |
113 |
| - - jump: ACCEPT |
114 |
| - - i: {{ interface }} |
115 |
| - - source: {{ ip }} |
116 |
| - - dport: {{ service_name }} |
117 |
| - - proto: {{ proto }} |
118 |
| - {%- if protocol == ipv6 %} |
119 |
| - - family: ipv6 |
120 |
| - {%- endif %} |
121 |
| - - save: True |
122 |
| - {{ comment }} |
123 |
| - {%- endfor %} |
124 |
| - {%- endfor %} |
125 |
| - {%- endif %} |
126 |
| - {%- endfor %} |
| 59 | +# Set the policy to deny everything unless defined |
| 60 | +enable_reject_policy{{suffixes[protocol]}}: |
| 61 | + iptables.set_policy: |
| 62 | + - table: filter |
| 63 | + - chain: INPUT |
| 64 | + - policy: DROP |
| 65 | +{%- if protocol == ipv6 %} |
| 66 | + - family: ipv6 |
| 67 | +{%- endif %} |
| 68 | + - require: |
| 69 | + - iptables: iptables_allow_localhost{{suffixes[protocol]}} |
| 70 | + - iptables: iptables_allow_established{{suffixes[protocol]}} |
| 71 | +{%- endfor %} |
| 72 | +{%- endif %} |
127 | 73 |
|
128 |
| - {%- if not strict_mode and global_block_nomatch or block_nomatch %} |
129 |
| - # If strict mode is disabled we may want to block anything else |
130 |
| - {%- if interfaces == '' %} |
131 |
| - {%- for proto in protos %} |
132 |
| - iptables_{{service_name}}_deny_other_{{proto}}{{suffixes[protocol]}}: |
133 |
| - iptables.append: |
134 |
| - - position: last |
135 |
| - - table: filter |
136 |
| - - chain: INPUT |
137 |
| - - jump: REJECT |
138 |
| - - dport: {{ service_name }} |
139 |
| - - proto: {{ proto }} |
140 |
| - {%- if protocol == ipv6 %} |
141 |
| - - family: ipv6 |
142 |
| - {%- endif %} |
143 |
| - - save: True |
144 |
| - {{ comment }} |
145 |
| - {%- endfor %} |
146 |
| - {%- else %} |
147 |
| - {%- for interface in interfaces %} |
148 |
| - {%- for proto in protos %} |
149 |
| - iptables_{{service_name}}_deny_other_{{proto}}_{{interface}}{{suffixes[protocol]}}: |
150 |
| - iptables.append: |
151 |
| - - position: last |
152 |
| - - table: filter |
153 |
| - - chain: INPUT |
154 |
| - - jump: REJECT |
155 |
| - - i: {{ interface }} |
156 |
| - - dport: {{ service_name }} |
157 |
| - - proto: {{ proto }} |
158 |
| - {%- if protocol == ipv6 %} |
159 |
| - - family: ipv6 |
160 |
| - {%- endif %} |
161 |
| - - save: True |
162 |
| - {{ comment }} |
163 |
| - {%- endfor %} |
164 |
| - {%- endfor %} |
165 |
| - {%- endif %} |
| 74 | +# Generate ipsets for all services that we have information about |
| 75 | +{%- for protocol in protocols %} |
| 76 | +{%- for service_name, service_details in firewall.get('services' + suffixes[protocol], {}).items() %} |
| 77 | +{%- set block_nomatch = service_details.get('block_nomatch', False) %} |
| 78 | +{%- set interfaces = service_details.get('interfaces','') %} |
| 79 | +{%- set protos = service_details.get('protos',['tcp']) %} |
| 80 | +{%- if service_details.get('comment', False) %} |
| 81 | +{%- set comment = '- comment: ' + service_details.get('comment') %} |
| 82 | +{%- else %} |
| 83 | +{%- set comment = '' %} |
| 84 | +{%- endif %} |
166 | 85 |
|
167 |
| - {%- endif %} |
| 86 | +# Allow rules for ips/subnets |
| 87 | +{%- for ip in service_details.get('ips_allow', ['0.0.0.0/0']) %} |
| 88 | +{%- if interfaces == '' %} |
| 89 | +{%- for proto in protos %} |
| 90 | +iptables_{{service_name}}_allow_{{ip}}_{{proto}}{{suffixes[protocol]}}: |
| 91 | + iptables.insert: |
| 92 | + - position: 1 |
| 93 | + - table: filter |
| 94 | + - chain: INPUT |
| 95 | + - jump: ACCEPT |
| 96 | + - source: {{ ip }} |
| 97 | + - dport: {{ service_name }} |
| 98 | + - proto: {{ proto }} |
| 99 | +{%- if protocol == ipv6 %} |
| 100 | + - family: ipv6 |
| 101 | +{%- endif %} |
| 102 | + - save: True |
| 103 | + {{ comment }} |
| 104 | +{%- endfor %} |
| 105 | +{%- else %} |
| 106 | +{%- for interface in interfaces %} |
| 107 | +{%- for proto in protos %} |
| 108 | +iptables_{{service_name}}_allow_{{ip}}_{{proto}}_{{interface}}{{suffixes[protocol]}}: |
| 109 | + iptables.insert: |
| 110 | + - position: 1 |
| 111 | + - table: filter |
| 112 | + - chain: INPUT |
| 113 | + - jump: ACCEPT |
| 114 | + - i: {{ interface }} |
| 115 | + - source: {{ ip }} |
| 116 | + - dport: {{ service_name }} |
| 117 | + - proto: {{ proto }} |
| 118 | +{%- if protocol == ipv6 %} |
| 119 | + - family: ipv6 |
| 120 | +{%- endif %} |
| 121 | + - save: True |
| 122 | + {{ comment }} |
| 123 | +{%- endfor %} |
| 124 | +{%- endfor %} |
| 125 | +{%- endif %} |
| 126 | +{%- endfor %} |
168 | 127 |
|
169 |
| - {%- endfor %} |
170 |
| - {%- endfor %} |
| 128 | +{%- if not strict_mode and global_block_nomatch or block_nomatch %} |
| 129 | +# If strict mode is disabled we may want to block anything else |
| 130 | +{%- if interfaces == '' %} |
| 131 | +{%- for proto in protos %} |
| 132 | +iptables_{{service_name}}_deny_other_{{proto}}{{suffixes[protocol]}}: |
| 133 | + iptables.append: |
| 134 | + - position: last |
| 135 | + - table: filter |
| 136 | + - chain: INPUT |
| 137 | + - jump: REJECT |
| 138 | + - dport: {{ service_name }} |
| 139 | + - proto: {{ proto }} |
| 140 | +{%- if protocol == ipv6 %} |
| 141 | + - family: ipv6 |
| 142 | +{%- endif %} |
| 143 | + - save: True |
| 144 | + {{ comment }} |
| 145 | +{%- endfor %} |
| 146 | +{%- else %} |
| 147 | +{%- for interface in interfaces %} |
| 148 | +{%- for proto in protos %} |
| 149 | +iptables_{{service_name}}_deny_other_{{proto}}_{{interface}}{{suffixes[protocol]}}: |
| 150 | + iptables.append: |
| 151 | + - position: last |
| 152 | + - table: filter |
| 153 | + - chain: INPUT |
| 154 | + - jump: REJECT |
| 155 | + - i: {{ interface }} |
| 156 | + - dport: {{ service_name }} |
| 157 | + - proto: {{ proto }} |
| 158 | +{%- if protocol == ipv6 %} |
| 159 | + - family: ipv6 |
| 160 | +{%- endif %} |
| 161 | + - save: True |
| 162 | + {{ comment }} |
| 163 | +{%- endfor %} |
| 164 | +{%- endfor %} |
| 165 | +{%- endif %} |
| 166 | +{%- endif %} |
| 167 | +{%- endfor %} |
| 168 | +{%- endfor %} |
171 | 169 |
|
172 |
| - # Generate rules for NAT |
173 |
| - {%- for service_name, service_details in firewall.get('nat', {}).items() %} |
174 |
| - {%- for ip_s, ip_ds in service_details.get('rules', {}).items() %} |
175 |
| - {%- for ip_d in ip_ds %} |
176 |
| - iptables_{{service_name}}_allow_{{ip_s}}_{{ip_d}}: |
177 |
| - iptables.append: |
178 |
| - - table: nat |
179 |
| - - chain: POSTROUTING |
180 |
| - - jump: MASQUERADE |
181 |
| - - o: {{ service_name }} |
182 |
| - - source: {{ ip_s }} |
183 |
| - - destination: {{ ip_d }} |
184 |
| - - save: True |
185 |
| - {%- endfor %} |
186 |
| - {%- endfor %} |
187 |
| - {%- endfor %} |
| 170 | +# Generate rules for NAT |
| 171 | +{%- for service_name, service_details in firewall.get('nat', {}).items() %} |
| 172 | +{%- for ip_s, ip_ds in service_details.get('rules', {}).items() %} |
| 173 | +{%- for ip_d in ip_ds %} |
| 174 | +iptables_{{service_name}}_allow_{{ip_s}}_{{ip_d}}: |
| 175 | + iptables.append: |
| 176 | + - table: nat |
| 177 | + - chain: POSTROUTING |
| 178 | + - jump: MASQUERADE |
| 179 | + - o: {{ service_name }} |
| 180 | + - source: {{ ip_s }} |
| 181 | + - destination: {{ ip_d }} |
| 182 | + - save: True |
| 183 | +{%- endfor %} |
| 184 | +{%- endfor %} |
| 185 | +{%- endfor %} |
188 | 186 |
|
189 |
| - # Generate rules for whitelisting IP classes |
190 |
| - {%- for protocol in protocols %} |
191 |
| - {%- for service_name, service_details in firewall.get('whitelist', {}).items() %} |
192 |
| - {%- for ip in service_details.get('ips_allow', []) %} |
193 |
| - iptables_{{service_name}}_allow_{{ip}}{{suffixes[protocol]}}: |
194 |
| - iptables.append: |
195 |
| - - table: filter |
196 |
| - - chain: INPUT |
197 |
| - - jump: ACCEPT |
198 |
| - - source: {{ ip }} |
199 |
| - {%- if protocol == ipv6 %} |
200 |
| - - family: ipv6 |
201 |
| - {%- endif %} |
202 |
| - - save: True |
203 |
| - {%- endfor %} |
204 |
| - {%- endfor %} |
205 |
| - {%- endfor %} |
| 187 | +# Generate rules for whitelisting IP classes |
| 188 | +{%- for protocol in protocols %} |
| 189 | +{%- for service_name, service_details in firewall.get('whitelist' + suffixes[protocol], {}).items() %} |
| 190 | +{%- for ip in service_details.get('ips_allow', []) %} |
| 191 | +iptables_{{service_name}}_allow_{{ip}}{{suffixes[protocol]}}: |
| 192 | + iptables.append: |
| 193 | + - table: filter |
| 194 | + - chain: INPUT |
| 195 | + - jump: ACCEPT |
| 196 | + - source: {{ ip }} |
| 197 | + {%- if protocol == ipv6 %} |
| 198 | + - family: ipv6 |
| 199 | + {%- endif %} |
| 200 | + - save: True |
| 201 | +{%- endfor %} |
| 202 | +{%- endfor %} |
| 203 | +{%- endfor %} |
206 | 204 |
|
207 |
| -{% else %} # Firewall is disabled by default |
| 205 | +{%- else %} # Firewall is disabled by default |
208 | 206 | firewall_disabled:
|
209 | 207 | test.show_notification:
|
210 | 208 | - name: Firewall is disabled by default
|
|
0 commit comments