Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 139 additions & 54 deletions ansible/roles/router_iptables/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
---
- name: "Enable ipv4 forward"
sysctl:
name: net.ipv4.ip_forward
value: "1"
sysctl_set: true

- name: Allow wireguard input traffic (game)
iptables:
chain: INPUT
Expand All @@ -15,75 +21,128 @@
protocol: udp
jump: ACCEPT

- name: "Enable ipv4 forward"
sysctl:
name: net.ipv4.ip_forward
value: "1"
sysctl_set: true
- name: Create FW_RATELIMIT chain
iptables:
chain: FW_RATELIMIT
chain_management: true
state: present

- name: Allow related/established forward traffic
- name: Create FW_CONNTRACK chain
iptables:
chain: FW_CONNTRACK
chain_management: true
state: present

- name: Create FW_INTERNAL chain
iptables:
chain: FW_INTERNAL
chain_management: true
state: present

- name: Create FW_ROUTER_NETS chain
iptables:
chain: FW_ROUTER_NETS
chain_management: true
state: present

- name: Create FW_TEAM_NETS chain
iptables:
chain: FW_TEAM_NETS
chain_management: true
state: present

- name: Create FW_ROUTER chain
iptables:
chain: FW_ROUTER
chain_management: true
state: present

- name: Create FW_TEAM_NO_MASQ chain
iptables:
table: nat
chain: FW_TEAM_NO_MASQ
chain_management: true
state: present

- name: Insert FW_RATELIMIT into FORWARD
iptables:
chain: FORWARD
ctstate: [RELATED, ESTABLISHED]
jump: ACCEPT
in_interface: router
jump: FW_RATELIMIT

- name: Insert FW_CONNTRACK into FORWARD
iptables:
chain: FORWARD
jump: FW_CONNTRACK

- name: Insert FW_INTERNAL into FORWARD
iptables:
chain: FORWARD
out_interface: internal
jump: FW_INTERNAL

- name: Insert FW_ROUTER_NETS into FORWARD
iptables:
chain: FORWARD
out_interface: router
jump: FW_ROUTER_NETS

- name: Insert FW_TEAM_NETS into FORWARD
iptables:
chain: FORWARD
out_interface: team+
jump: FW_TEAM_NETS

- name: Insert FW_ROUTER into FORWARD
iptables:
chain: FORWARD
out_interface: router
jump: FW_ROUTER

- name: Insert FW_TEAM_NO_MASQ into POSTROUTING
iptables:
table: nat
chain: POSTROUTING
out_interface: router
jump: FW_TEAM_NO_MASQ

- name: "Capture iptables-save output"
shell: "iptables-save"
register: iptablessave

- name: "Insert limit bw internal"
shell: "iptables -I FORWARD -i router -o internal -m hashlimit --hashlimit-above 10mb/s --hashlimit-burst 20mb --hashlimit-mode srcip --hashlimit-name bwi --hashlimit-srcmask 24 -j DROP"
when: '"-A FORWARD -i router -o internal -m hashlimit --hashlimit-above 10mb/s --hashlimit-burst 20mb --hashlimit-mode srcip --hashlimit-name bwi --hashlimit-srcmask 24 -j DROP" not in iptablessave.stdout'
shell: "iptables -I FW_RATELIMIT -i router -o internal -m hashlimit --hashlimit-above 10mb/s --hashlimit-burst 20mb --hashlimit-mode srcip --hashlimit-name bwi --hashlimit-srcmask 24 -j DROP"
when: '"-A FW_RATELIMIT -i router -o internal -m hashlimit --hashlimit-above 10mb/s --hashlimit-burst 20mb --hashlimit-mode srcip --hashlimit-name bwi --hashlimit-srcmask 24 -j DROP" not in iptablessave.stdout'

- name: "Insert limit bw other"
shell: "iptables -I FORWARD -i router ! -o internal -m hashlimit --hashlimit-above 5mb/s --hashlimit-burst 10mb --hashlimit-mode srcip --hashlimit-name bw --hashlimit-srcmask 24 -j DROP"
when: '"-A FORWARD -i router ! -o internal -m hashlimit --hashlimit-above 5mb/s --hashlimit-burst 10mb --hashlimit-mode srcip --hashlimit-name bw --hashlimit-srcmask 24 -j DROP" not in iptablessave.stdout'
shell: "iptables -I FW_RATELIMIT -i router ! -o internal -m hashlimit --hashlimit-above 5mb/s --hashlimit-burst 10mb --hashlimit-mode srcip --hashlimit-name bw --hashlimit-srcmask 24 -j DROP"
when: '"-A FW_RATELIMIT -i router ! -o internal -m hashlimit --hashlimit-above 5mb/s --hashlimit-burst 10mb --hashlimit-mode srcip --hashlimit-name bw --hashlimit-srcmask 24 -j DROP" not in iptablessave.stdout'

- name: "Insert limit conn internal"
shell: "iptables -I FORWARD -i router -o internal -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 2/sec --hashlimit-burst 10 --hashlimit-mode srcip,dstip --hashlimit-name subnewconns -j DROP"
when: '"-A FORWARD -i router -o internal -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 2/sec --hashlimit-burst 10 --hashlimit-mode srcip,dstip --hashlimit-name subnewconns -j DROP" not in iptablessave.stdout'
shell: "iptables -I FW_RATELIMIT -i router -o internal -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 2/sec --hashlimit-burst 10 --hashlimit-mode srcip,dstip --hashlimit-name subnewconns -j DROP"
when: '"-A FW_RATELIMIT -i router -o internal -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 2/sec --hashlimit-burst 10 --hashlimit-mode srcip,dstip --hashlimit-name subnewconns -j DROP" not in iptablessave.stdout'

- name: "Insert limit conn other"
shell: "iptables -I FORWARD -i router ! -o internal -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 50/sec --hashlimit-burst 100 --hashlimit-mode srcip,dstip --hashlimit-name newconns -j DROP"
when: '"-A FORWARD -i router ! -o internal -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 50/sec --hashlimit-burst 100 --hashlimit-mode srcip,dstip --hashlimit-name newconns -j DROP" not in iptablessave.stdout'
shell: "iptables -I FW_RATELIMIT -i router ! -o internal -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 50/sec --hashlimit-burst 100 --hashlimit-mode srcip,dstip --hashlimit-name newconns -j DROP"
when: '"-A FW_RATELIMIT -i router ! -o internal -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 50/sec --hashlimit-burst 100 --hashlimit-mode srcip,dstip --hashlimit-name newconns -j DROP" not in iptablessave.stdout'

- name: Allow related/established forward traffic
iptables:
chain: FORWARD
chain: FW_CONNTRACK
ctstate: [RELATED, ESTABLISHED]
jump: ACCEPT

- name: Allow all internal traffic
iptables:
chain: FORWARD
chain: FW_INTERNAL
in_interface: internal
out_interface: internal
jump: ACCEPT

# this is a pretty hacky workaround, but the execution of the iptables-module in ansible is just painfully slow
- name: Prevent masquerading for intra-team traffic part
shell: "iptables -t nat -A POSTROUTING -s 10.1.{{ item }}.0/24 -d 10.1.{{ item }}.0/24 -o router -j RETURN"
when: '"-A POSTROUTING -s 10.1."+item+".0/24 -d 10.1."+item+".0/24 -o router -j RETURN" not in iptablessave.stdout'
with_sequence: start=1 end=255

- name: Masquerade outgoing traffic on the router interface
iptables:
table: nat
chain: POSTROUTING
out_interface: router
jump: MASQUERADE

- name: DNAT the flag submission IP to the engine
iptables:
table: nat
chain: PREROUTING
destination: 10.0.13.37
jump: DNAT
to_destination: 192.168.1.0

- name: Allow pinging the flag submission endpoint from vulnboxes
iptables:
chain: FORWARD
chain: FW_INTERNAL
in_interface: router
out_interface: internal
destination: 192.168.1.0
Expand All @@ -93,7 +152,7 @@

- name: Allow pinging the flag submission endpoint from vpn connections
iptables:
chain: FORWARD
chain: FW_INTERNAL
in_interface: team+
out_interface: internal
destination: 192.168.1.0
Expand All @@ -103,7 +162,7 @@

- name: Allow flag submission traffic from vulnboxes
iptables:
chain: FORWARD
chain: FW_INTERNAL
in_interface: router
out_interface: internal
destination: 192.168.1.0
Expand All @@ -113,7 +172,7 @@

- name: Allow flag submission traffic from vpn connections
iptables:
chain: FORWARD
chain: FW_INTERNAL
in_interface: team+
out_interface: internal
destination: 192.168.1.0
Expand All @@ -123,7 +182,7 @@

- name: Allow enoctfportal traffic from vulnboxes
iptables:
chain: FORWARD
chain: FW_INTERNAL
in_interface: router
out_interface: internal
destination: 192.168.1.0
Expand All @@ -133,34 +192,60 @@

- name: Allow enoctfportal traffic from vpn connections
iptables:
chain: FORWARD
chain: FW_INTERNAL
in_interface: team+
out_interface: internal
destination: 192.168.1.0
protocol: tcp
destination_port: "5001"
jump: ACCEPT


# this is a pretty hacky workaround, but the execution of the iptables-module in ansible is just painfully slow
- name: Allow intra-team traffic part 1 (time-based)
shell: "iptables -A FW_ROUTER_NETS -s 10.1.{{ item }}.0/24 -d 10.1.{{ item }}.0/24 -o router -m time --datestart {{ vulnbox_access_time }} -j ACCEPT"
# when: '"-A FW_ROUTER_NETS -s 10.1."+item+".0/24 -d 10.1."+item+".0/24 -o router -j ACCEPT" not in iptablessave.stdout' # TODO: this is broken, needs to be revisited
with_sequence: start=1 end=255

- name: Allow intra-team traffic part 2 (time-based)
shell: "iptables -A FW_TEAM_NETS -s 10.1.{{ item }}.0/24 -d 10.1.{{ item }}.0/24 -o team+ -m time --datestart {{ vulnbox_access_time }} -j ACCEPT"
# when: '"-A FW_TEAM_NETS -s 10.1."+item+".0/24 -d 10.1."+item+".0/24 -o router -j ACCEPT" not in iptablessave.stdout' # TODO: this is broken, needs to be revisited
with_sequence: start=1 end=255


- name: Allow traffic from the internal network to teams
iptables:
chain: FORWARD
chain: FW_ROUTER
in_interface: internal
out_interface: router
jump: ACCEPT

- name: Open game network (time-based)
shell: "iptables -A FW_ROUTER -o router -m time --datestart {{ network_open_time }} --datestop {{ network_close_time }} -j ACCEPT"
when: '"-A FW_ROUTER -o router -m time --datestart {{ network_open_time }} --datestop {{ network_close_time }} -j ACCEPT" not in iptablessave.stdout'


- name: DNAT the flag submission IP to the engine
iptables:
table: nat
chain: PREROUTING
destination: 10.0.13.37
jump: DNAT
to_destination: 192.168.1.0

# this is a pretty hacky workaround, but the execution of the iptables-module in ansible is just painfully slow
- name: Allow intra-team traffic part 1 (time-based)
shell: "iptables -A FORWARD -s 10.1.{{ item }}.0/24 -d 10.1.{{ item }}.0/24 -o router -m time --datestart {{ vulnbox_access_time }} -j ACCEPT"
# when: '"-A FORWARD -s 10.1."+item+".0/24 -d 10.1."+item+".0/24 -o router -j ACCEPT" not in iptablessave.stdout' # TODO: this is broken, needs to be revisited
- name: Prevent masquerading for intra-team traffic part
shell: "iptables -t nat -A FW_TEAM_NO_MASQ -s 10.1.{{ item }}.0/24 -d 10.1.{{ item }}.0/24 -o router -j RETURN"
when: '"-A FW_TEAM_NO_MASQ -s 10.1."+item+".0/24 -d 10.1."+item+".0/24 -o router -j RETURN" not in iptablessave.stdout'
with_sequence: start=1 end=255

- name: Allow intra-team traffic part 2 (time-based)
shell: "iptables -A FORWARD -s 10.1.{{ item }}.0/24 -d 10.1.{{ item }}.0/24 -o team+ -m time --datestart {{ vulnbox_access_time }} -j ACCEPT"
# when: '"-A FORWARD -s 10.1."+item+".0/24 -d 10.1."+item+".0/24 -o router -j ACCEPT" not in iptablessave.stdout' # TODO: this is broken, needs to be revisited
with_sequence: start=1 end=255
- name: Masquerade outgoing traffic on the router interface
iptables:
table: nat
chain: POSTROUTING
out_interface: router
jump: MASQUERADE

- name: Open game network (time-based)
shell: "iptables -A FORWARD -o router -m time --datestart {{ network_open_time }} --datestop {{ network_close_time }} -j ACCEPT"

- name: Persist iptables config
include_role:
Expand Down
Loading