Skip to content

Commit

Permalink
add a template that will dynamically assign networks
Browse files Browse the repository at this point in the history
include documentation on how to use the role
  • Loading branch information
kayiwa committed Dec 20, 2024
1 parent 1a767d7 commit 9c93e16
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 27 deletions.
104 changes: 88 additions & 16 deletions roles/ufw_firewall/README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,98 @@
# UFW Firewall Role
## UFW Firewall Role

This Ansible role configures the Uncomplicated Firewall (UFW) on our Linux systems. It allows you to define allowed and denied networks and ports, making it easy to manage your firewall rules. Further descriptions of the networks will be on [IT-Handbook](https://github.com/pulibrary/pul-it-handbook)
The `ufw_firewall` Ansible role configures UFW (Uncomplicated Firewall) to allow or deny traffic to specified networks and ports based on dynamic, parameterized variables. It supports flexible definitions of allowed networks and ports, enabling easy customization for specific environments, such as campus networks or library systems.

This role dynamically generates UFW rules, sets default policies, and ensures outgoing traffic is allowed while controlling incoming traffic as specified.

***

## Features

1. **Dynamic Rule Generation**:

* Define firewall rules based on networks and ports using variables.
* Parametrize ports for different services (e.g., `ssh`, `web`) for easy reuse and customization.

2. **Default Policies**:

* Allows outgoing traffic by default.
* Drops all other incoming traffic unless explicitly permitted.

3. **Template-Driven Configuration**:

* Generates UFW rules dynamically using Jinja2 templates.
* Supports multiple network groups (e.g., `campus_and_vpn` and `libnet`).

4. **Customizable Ports**:

* Easily update port numbers for specific services like `SSH` or `HTTP` using variables.

***

## Requirements

- Ansible 2.9 or higher
- Supported Operating Systems:
- Rocky Linux (tested on 9)
- Ubuntu (tested on jammy)
* Ansible >= 2.9
* Target system running a UFW-compatible operating system (e.g., Ubuntu)

***

## Role Variables

the examples below allow ssh, http, and redis to those CIDR subnets. For ssh make sure you use the [defaults/main.yml](defaults/main.yml) example or you will lose access to your VM
The role uses the following variables for customization:

### 1. **Network Definitions**

Define the networks [All defined here][../../group_vars/all/vars.yml] you want to allow traffic from, grouped logically by purpose:

```yaml
ufw_firewall_rules:
- protocol: tcp
source: "{{ ufw_campus_and_vpn }}"
port: 80
action: ACCEPT
- protocol: tcp
source: "{{ ufw_libnet }}"
port: 22
action: ACCEPT
ufw_campus_and_vpn:
- name: "Princeton Wired Private"
network: 10.249.64.0/18
- name: "Princeton VPN Subnet 1"
network: 172.20.95.0/24

ufw_libnet:
- name: "PU Subnet - LibNet"
network: 128.112.200.0/21
```
### 2. **Ports**
Specify the ports for each service:
```yaml
ufw_firewall_ports:
ssh: 22
web: 5342 # Replace with the port for your web service
```
## Usage
### Example Playbook
```yaml
---

- hosts: servers
roles:
- { role: roles/ufw_firewall }
```
***
## Verification
To verify the configuration, you can:
1. Check UFW status on endpoint:
```bash
sudo ufw status verbose
```

2. Inspect iptables rules on endpoint:

```bash
sudo iptables -L -n -v
```
3 changes: 3 additions & 0 deletions roles/ufw_firewall/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ ufw_firewall_rules:
port: 22
protocol: tcp
allowed_cidrs: "{{ ufw_campus_and_vpn }}"

ufw_campus_and_vpn: []
ufw_libnet: []
# example of http in your group_vars/project
# - service: http
# port: 80
Expand Down
4 changes: 4 additions & 0 deletions roles/ufw_firewall/handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
# handlers file for roles/ufw_firewall
- name: Reload UFW
ansible.builtin.command: ufw reload
changed_when: false

- name: Reload sysctl
ansible.builtin.command: sysctl -p
35 changes: 25 additions & 10 deletions roles/ufw_firewall/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
---
# Main tasks for ufw_firewall role
- name: UFW | Install UFW
- name: UFW| Install UFW
ansible.builtin.package:
name: ufw
state: present

- name: UFW | Enable UFW
ansible.builtin.command: ufw --force enable
changed_when: false
- name: UFW | Enable IP forwarding in sysctl
ansible.builtin.lineinfile:
path: /etc/sysctl.conf
regexp: '^net.ipv4.ip_forward='
line: 'net.ipv4.ip_forward=1'
notify: Reload sysctl

- name: UFW | Set default forward policy to ACCEPT
ansible.builtin.lineinfile:
path: /etc/default/ufw
regexp: '^DEFAULT_FORWARD_POLICY='
line: 'DEFAULT_FORWARD_POLICY="ACCEPT"'
notify: Reload UFW

- name: UFW | Deploy custom before.rules
ansible.builtin.template:
Expand All @@ -27,9 +37,14 @@
mode: "0644"
notify: Reload UFW

- name: UFW | Ensure default forward policy
ansible.builtin.lineinfile:
path: /etc/default/ufw
regexp: '^DEFAULT_FORWARD_POLICY='
line: 'DEFAULT_FORWARD_POLICY="ACCEPT"'
notify: Reload UFW
- name: UFW | Enable UFW
ansible.builtin.command: ufw --force enable
changed_when: false

- name: UFW | Allow all outgoing traffic in UFW
ansible.builtin.command: ufw default allow outgoing
changed_when: false

- name: UFW | Reload sysctl settings
ansible.builtin.command: sysctl -p
changed_when: false
9 changes: 9 additions & 0 deletions roles/ufw_firewall/templates/before.rules.j2
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]

# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT
# quickly process packets for which we already have a connection
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

### RULES ###
{% for item in ufw_firewall_rules %}
Expand Down
16 changes: 15 additions & 1 deletion roles/ufw_firewall/vars/main.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
---
# vars file for roles/ufw_firewall

ufw_firewall_rules: >
{%- set rules = [] -%}
{%- for network in ufw_campus_and_vpn -%}
{{ rules.append({'protocol': 'tcp', 'source': network, 'port': 22, 'action': 'ACCEPT'}) }}
{{ rules.append({'protocol': 'tcp', 'source': network, 'port': ufw_firewall_ports.ssh, 'action': 'ACCEPT'}) }}
{%- endfor -%}
{{ rules }}
ufw_firewall_after_rules: []

ufw_firewall_ports:
ssh: 22

# example of opening ports for web template
# {%- for network in ufw_libnet -%}
# {{ rules.append({'protocol': 'tcp', 'source': network, 'port': ufw_firewall_ports.web, 'action': 'ACCEPT'}) }}
# {%- endfor -%}
# example of defining ports for web template
# ufw_firewall_ports:
# web: 80

0 comments on commit 9c93e16

Please sign in to comment.