---


# ---
# Remount Filesystem writable
# ---

- name: Remount "/ro/" writable
  shell: remountrw

# ---
# Install/Uodate git firewall repository
# ---

- name: Install/update firewall repository
  git:
    repo: '{{ git_firewall_repository.repo }}'
    dest: '{{ git_firewall_repository.dest }}'
  when: git_firewall_repository is defined and git_firewall_repository|length > 0


# ---
# Some Checks
# ---

- name: Check if file '/ro/etc/ipt-firewall/main_ipv4.conf' exists
  stat:
    path: /ro/etc/ipt-firewall/main_ipv4.conf
  register: main_ipv4_exists

- name: Check if file '/ro/etc/ipt-firewall/main_ipv6.conf' exists
  stat:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
  register: main_ipv6_exists

- name: Check if file '/ro/etc/ipt-firewall/interfaces_ipv4.conf' exists
  stat:
    path: /ro/etc/ipt-firewall/interfaces_ipv4.conf
  register: interfaces_ipv4_exists

- name: Check if file '/ro/etc/ipt-firewall/interfaces_ipv6.conf' exists
  stat:
    path: /ro/etc/ipt-firewall/interfaces_ipv6.conf
  register: interfaces_ipv6_exists


# ---
# Adjust some lines
# ---

- name: addjust line 'zoom_udp_ports' (IPv4)
  lineinfile:
    path: /ro/etc/ipt-firewall/main_ipv4.conf
    regexp: '^zoom_udp_ports='
    line: 'zoom_udp_ports="$standard_zoom_udp_ports"'
  when:
    - main_ipv4_exists.stat.exists
  notify:
    - Restart IPv4 Firewall

- name: addjust line 'zoom_udp_ports' (IPv6)
  lineinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    regexp: '^zoom_udp_ports='
    line: 'zoom_udp_ports="$standard_zoom_udp_ports"'
  when: 
      - main_ipv6_exists.stat.exists
  notify:
    - Restart IPv6 Firewall

- name: addjust line 'jitsi_udp_ports' (IPv4)
  lineinfile:
    path: /ro/etc/ipt-firewall/main_ipv4.conf
    regexp: '^jitsi_udp_ports='
    line: 'jitsi_udp_ports="$standard_jitsi_udp_ports"'
  when:
    - main_ipv4_exists.stat.exists
  notify:
    - Restart IPv4 Firewall

- name: addjust line 'jitsi_udp_ports' (IPv6)
  lineinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    regexp: '^jitsi_udp_ports='
    line: 'jitsi_udp_ports="$standard_jitsi_udp_ports"'
  when: 
      - main_ipv6_exists.stat.exists
  notify:
    - Restart IPv6 Firewall

- name: addjust line 'bigbluebutton_udp_ports' (IPv4)
  lineinfile:
    path: /ro/etc/ipt-firewall/main_ipv4.conf
    regexp: '^bigbluebutton_udp_ports='
    line: 'bigbluebutton_udp_ports="$standard_bigbluebutton_udp_ports"'
  when:
    - main_ipv4_exists.stat.exists
  notify:
    - Restart IPv4 Firewall

- name: addjust line 'bigbluebutton_udp_ports' (IPv6)
  lineinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    regexp: '^bigbluebutton_udp_ports='
    line: 'bigbluebutton_udp_ports="$standard_bigbluebutton_udp_ports"'
  when: 
      - main_ipv6_exists.stat.exists
  notify:
    - Restart IPv6 Firewall

- name: addjust line 'adjust_kernel_parameters' (IPv6)
  lineinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    regexp: '^adjust_kernel_parameters='
    line: '#adjust6_kernel_parameters=true'
  when: 
      - main_ipv6_exists.stat.exists
  notify:
    - Restart IPv6 Firewall

- name: addjust line 'protect_against_several_attack' (IPv6)
  lineinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    regexp: '^protect_against_several_attacks='
    line: '#protect6_against_several_attacks=true'
  when: 
      - main_ipv6_exists.stat.exists
  notify:
    - Restart IPv6 Firewall


# ---
# Block Routers
# ---

- name: Check if String 'drop_syn_flood..' (IPv4) is present
  shell: grep -q -E "^#?drop_syn_flood=" /ro/etc/ipt-firewall/main_ipv4.conf
  register: drop_syn_flood_ipv4_present
  when: main_ipv4_exists.stat.exists
  failed_when: "drop_syn_flood_ipv4_present.rc > 1"
  changed_when: "drop_syn_flood_ipv4_present.rc > 0"

- name: Adjust file '/ro/etc/ipt-firewall/main_ipv4.conf' (drop_syn_flood)
  blockinfile:
    path: /ro/etc/ipt-firewall/main_ipv4.conf
    insertafter: '^#?\s*protect_against_several_attacks=true'
    block: |

      # Protection against syn-flooding
      #
      #drop_syn_flood=false

      # - I have to say that fragments scare me more than anything.
      # - Sending lots of non-first fragments was what allowed Jolt2  to effectively "drown"
      # - Firewall-1. Fragments can be overlapped, and the subsequent interpretation of such
      # - fragments is very OS-dependent (see this paper for details).
      # - I am not going to trust any fragments.
      # - Log fragments just to see if we get any, and deny them too
      # -
      # - !! 'drop_fragments' does not work within telekom mobile connections !!
      # -
      #drop_fragments=true

      # drop new packages without syn flag
      #
      #drop_new_not_sync=true

      # drop invalid packages
      #
      #drop_invalid_state=true

      # drop packages with unusal flags
      #
      #drop_invalid_flags=true

      # Refuse private addresses on extern interfaces
      #
      # Refuse packets claiming to be from a
      #   Class A private network
      #   Class B private network
      #   Class C private network
      #   loopback interface
      #   Class D multicast address
      #   Class E reserved IP address
      #   broadcast address
      #drop_spoofed=true

      # Don't allow spoofing from that server
      #
      #drop_spoofed_out=true

      # Refusing packets claiming to be to the loopback interface protects against
      # source quench, whereby a machine can be told to slow itself down by an icmp source
      # quench to the loopback.
      #drop_ext_to_lo=true
    marker: "# Marker set by modify-ipt-gateway.yml (drop_syn_flood)"
  when: 
    - main_ipv4_exists.stat.exists
    - drop_syn_flood_ipv4_present is changed

- name: Check if String 'drop6_syn_flood..' (IPv6) is present
  shell: grep -q -E "^#?drop6_syn_flood=" /ro/etc/ipt-firewall/main_ipv6.conf
  register: drop6_syn_flood_ipv6_present
  when: main_ipv6_exists.stat.exists
  failed_when: "drop6_syn_flood_ipv6_present.rc > 1"
  changed_when: "drop6_syn_flood_ipv6_present.rc > 0"

- name: Adjust file '/ro/etc/ipt-firewall/main_ipv6.conf' (drop6_syn_flood)
  blockinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    insertafter: '^#?\s*protect6_against_several_attacks=true'
    block: |

      # Protection against syn-flooding
      #
      #drop6_syn_flood=false

      # drop new packages without syn flag
      #
      #drop6_new_not_sync=true

      # drop invalid packages
      #
      #drop6_invalid_state=true

      # drop packages with unusal flags
      #
      #drop6_invalid_flags=true

      # Refuse spoofed packets pretending to be from your IP address.
      #
      #drop6_from_own_ip=true

      # Refuse private addresses on extern interfaces
      #
      #drop6_spoofed=true
    marker: "# Marker set by modify-ipt-gateway.yml (drop6_syn_flood)"
  when: 
    - main_ipv6_exists.stat.exists
    - drop6_syn_flood_ipv6_present is changed


# ---
# Block UDP/TCP Ports out
# ---

- name: Check if String 'block_udp_extern_out_ports..' (IPv4) is present
  shell: grep -q -E "^block_udp_extern_out_ports=" /ro/etc/ipt-firewall/main_ipv4.conf
  register: block_udp_extern_out_ports_ipv4_present
  when: main_ipv4_exists.stat.exists
  failed_when: "block_udp_extern_out_ports_ipv4_present.rc > 1"
  changed_when: "block_udp_extern_out_ports_ipv4_present.rc > 0"

- name: Adjust file '/ro/etc/ipt-firewall/main_ipv4.conf' (block_udp_extern_out_ports)
  blockinfile:
    path: /ro/etc/ipt-firewall/main_ipv4.conf
    insertafter: '^#?\s*block_upnp_traffic_out'
    block: |


      # =============
      # --- Block UDP Ports out
      # =============

      # - UDP Ports to block (only extern out)
      # -
      # - Comma separated list of udp ports
      # -
      block_udp_extern_out_ports=""


      # =============
      # --- Block TCP Ports out
      # =============

      # - TCP Ports to block (only extern out)
      # -
      # - Comma separated list of tcp ports
      # -
      block_tcp_extern_out_ports=""
    marker: "# Marker set by modify-ipt-gateway.yml (block_udp_extern_out_ports)"
  when: 
    - main_ipv4_exists.stat.exists
    - block_udp_extern_out_ports_ipv4_present is changed

- name: Check if String 'block_udp_extern_out_ports..' (IPv6) is present
  shell: grep -q -E "^block_udp_extern_out_ports=" /ro/etc/ipt-firewall/main_ipv6.conf
  register: block_udp_extern_out_ports_ipv6_present
  when: main_ipv6_exists.stat.exists
  failed_when: "block_udp_extern_out_ports_ipv6_present.rc > 1"
  changed_when: "block_udp_extern_out_ports_ipv6_present.rc > 0"

- name: Adjust file '/ro/etc/ipt-firewall/main_ipv6.conf' (block_udp_extern_out_ports)
  blockinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    insertafter: '^#?\s*block_upnp_traffic_out'
    block: |


      # =============
      # --- Block UDP Ports out
      # =============

      # - UDP Ports to block (only extern out)
      # -
      # - Comma separated list of udp ports
      # -
      block_udp_extern_out_ports=""


      # =============
      # --- Block TCP Ports out
      # =============

      # - TCP Ports to block (only extern out)
      # -
      # - Comma separated list of tcp ports
      # -
      block_tcp_extern_out_ports=""
    marker: "# Marker set by modify-ipt-gateway.yml (block_udp_extern_out_ports)"
  when: 
    - main_ipv6_exists.stat.exists
    - block_udp_extern_out_ports_ipv6_present is changed



# ---
# jitsi video conference service
# ---

- name: Check if String 'jitsi_tcp_ports=..' (IPv4) is present
  shell: grep -q -E "^jitsi_tcp_ports=" /ro/etc/ipt-firewall/main_ipv4.conf
  register: jitsi_service_ipv4_present
  when: main_ipv4_exists.stat.exists
  failed_when: "jitsi_service_ipv4_present.rc > 1"
  changed_when: "jitsi_service_ipv4_present.rc > 0"

- name: Adjust file '/ro/etc/ipt-firewall/main_ipv4.conf' (jitsi service)
  blockinfile:
    path: /ro/etc/ipt-firewall/main_ipv4.conf
    insertafter: '^#?\s*mumble_ports'
    block: |
      
      # ======
      # - Jitsi Video Conference Service
      # ======

      # - Jitsi Video Conference Service Gateway
      # -
      # - NOT YET IMPLEMENTED
      # -
      local_jitsi_video_conference_service=false

      # - Jitsi Video Conference Service Ports
      # -
      # - TCP 80:    Webinterface.
      # - TCP 443:   Webinterface (SSL)
      # -
      # - UDP 10000-20000:   Virtual Media for Remote Console
      # -
      jitsi_tcp_ports="$standard_jitsi_tcp_ports"
      jitsi_udp_ports="$standard_jitsi_udp_port_range"
    marker: "# Marker set by modify-ipt-gateway.yml (jitsi service)"
  when: 
    - main_ipv4_exists.stat.exists
    - jitsi_service_ipv4_present is changed

- name: Check if String 'jitsi_tcp_ports=..' (IPv6) is present
  shell: grep -q -E "^jitsi_tcp_ports=" /ro/etc/ipt-firewall/main_ipv6.conf
  register: jitsi_service_ipv6_present
  when: main_ipv6_exists.stat.exists
  failed_when: "jitsi_service_ipv6_present.rc > 1"
  changed_when: "jitsi_service_ipv6_present.rc > 0"

- name: Adjust file '/ro/etc/ipt-firewall/main_ipv6.conf' (jitsi service)
  blockinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    insertafter: '^#?\s*mumble_ports'
    block: |
      
      # ======
      # - Jitsi Video Conference Service
      # ======

      # - Jitsi Video Conference Service Gateway
      # -
      # - NOT YET IMPLEMENTED
      # -
      local_jitsi_video_conference_service=false

      # - Jitsi Video Conference Service Ports
      # -
      # - TCP 80:    Webinterface.
      # - TCP 443:   Webinterface (SSL)
      # -
      # - UDP 10000-20000:   Virtual Media for Remote Console
      # -
      jitsi_tcp_ports="$standard_jitsi_tcp_ports"
      jitsi_udp_ports="$standard_jitsi_udp_port_range"
    marker: "# Marker set by modify-ipt-gateway.yml (jitsi service)"
  when: 
    - main_ipv6_exists.stat.exists
    - jitsi_service_ipv6_present is changed


# ---
# TURN Server (Stun Server) (for Nextcloud 'talk' app)
# ---

- name: Check if String 'nc_turn_ports=..' (IPv4) is present
  shell: grep -q -E "^nc_turn_ports=" /ro/etc/ipt-firewall/main_ipv4.conf
  register: nc_turn_service_ipv4_present
  when: main_ipv4_exists.stat.exists
  failed_when: "nc_turn_service_ipv4_present.rc > 1"
  changed_when: "nc_turn_service_ipv4_present.rc > 0"

- name: Adjust file '/ro/etc/ipt-firewall/main_ipv4.conf' (nc's turn service)
  blockinfile:
    path: /ro/etc/ipt-firewall/main_ipv4.conf
    insertafter: '^#?\s*jitsi_udp_ports'
    block: |

      # ======
      # - TURN Server (Stun Server) (for Nextcloud 'talk' app)
      # ======

      # - TURN Server (Stun Server) (for Nextcloud 'talk' app)
      # -
      # - NOT YET IMPLEMENTED
      # -
      local_nc_turn_service=""

      # - Ports used by local TURN Server (Stun Server)
      # -
      # - comma separated list
      # -
      nc_turn_ports="$standard_turn_service_ports"
      nc_turn_udp_ports="$standard_turn_service_udp_ports"
    marker: "# Marker set by modify-ipt-gateway.yml (nc's turn service)"
  when: 
    - main_ipv4_exists.stat.exists
    - nc_turn_service_ipv4_present is changed

- name: Check if String 'nc_turn_ports=..' (IPv6) is present
  shell: grep -q -E "^nc_turn_ports=" /ro/etc/ipt-firewall/main_ipv6.conf
  register: nc_turn_service_ipv6_present
  when: main_ipv6_exists.stat.exists
  failed_when: "nc_turn_service_ipv6_present.rc > 1"
  changed_when: "nc_turn_service_ipv6_present.rc > 0"

- name: Adjust file '/ro/etc/ipt-firewall/main_ipv6.conf' (jitsi service)
  blockinfile:
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    insertafter: '^#?\s*jitsi_udp_ports'
    block: |

      # ======
      # - TURN Server (Stun Server) (for Nextcloud 'talk' app)
      # ======

      # - TURN Server (Stun Server) (for Nextcloud 'talk' app)
      # -
      # - NOT YET IMPLEMENTED
      # -
      local_nc_turn_service=""

      # - Ports used by local TURN Server (Stun Server)
      # -
      # - comma separated list
      # -
      nc_turn_ports="$standard_turn_service_ports"
      nc_turn_udp_ports="$standard_turn_service_udp_ports"
    marker: "# Marker set by modify-ipt-gateway.yml (jitsi service)"
  when: 
    - main_ipv6_exists.stat.exists
    - nc_turn_service_ipv6_present is changed


# ---
# Remove Marker set by blockinfile
# ---

- name: Remove marker IPv4 (main_ipv4.conf)
  replace :
    path: /ro/etc/ipt-firewall/main_ipv4.conf
    regexp: "^# Marker set by modify-ipt-gateway.yml.*$"
    replace: ""
  register: marker_ipv4_removed
  #failed_when: "marker_ipv4_removed.rc > 1"
  #changed_when: "marker_ipv4_removed.rc < 1"
  when: 
    - main_ipv4_exists.stat.exists

- name: Remove marker IPv6 (main_ipv6.conf)
  replace :
    path: /ro/etc/ipt-firewall/main_ipv6.conf
    regexp: "^# Marker set by modify-ipt-gateway.yml.*$"
    replace: ""
  register: marker_ipv6_removed
  #failed_when: "marker_ipv6_removed.rc > 1"
  #changed_when: "marker_ipv6_removed.rc < 1"
  when: 
    - main_ipv6_exists.stat.exists

- name: Remove marker IPv4 (interfaces_ipv4.conf)
  replace :
    path: /ro/etc/ipt-firewall/interfaces_ipv4.conf
    regexp: "^# Marker set by modify-ipt-gateway.yml.*$"
    replace: ""
  register: marker_ipv4_removed
  #failed_when: "marker_ipv4_removed.rc > 1"
  #changed_when: "marker_ipv4_removed.rc < 1"
  when: 
    - interfaces_ipv4_exists.stat.exists

- name: Remove marker IPv6 (interfaces_ipv6.conf)
  replace :
    path: /ro/etc/ipt-firewall/interfaces_ipv6.conf
    regexp: "^# Marker set by modify-ipt-gateway.yml.*$"
    replace: ""
  register: marker_ipv6_removed
  #failed_when: "marker_ipv6_removed.rc > 1"
  #changed_when: "marker_ipv6_removed.rc < 1"
  when: 
    - interfaces_ipv6_exists.stat.exists

# ---
# Confiuration Files
# ---

- name: Check if configuration files are latest
  shell: 'diff {{ git_firewall_repository.dest }}/conf/{{ item }} /ro/etc/ipt-firewall/{{ item }} > /dev/null 2>&1'
  changed_when: "diff_script_output.rc > 0"
  # diff_output.rc
  #    0  -> unchanged
  #    1  -> changed
  #    2  -> not present
  failed_when: "diff_script_output.rc > 2"
  when: (git_firewall_repository is defined) and (git_firewall_repository|length > 0)
  loop:
     - default_ports.conf
     - default_ipv4.conf
     - default_ipv6.conf
     - default_basic_behavior.conf
     - include_functions.conf
     - load_modules_ipv4.conf
     - load_modules_ipv6.conf
     - logging_ipv4.conf
     - logging_ipv6.conf
     - post_decalrations.conf
  register: diff_script_output

- name: Ensure configuration files are latest
  command: cp {{ git_firewall_repository.dest }}/conf/{{ item }} /ro/etc/ipt-firewall/{{ item }}
  loop:
     - default_ports.conf
     - default_ipv4.conf
     - default_ipv6.conf
     - default_basic_behavior.conf
     - include_functions.conf
     - load_modules_ipv4.conf
     - load_modules_ipv6.conf
     - logging_ipv4.conf
     - logging_ipv6.conf
     - post_decalrations.conf
  when:
    - (git_firewall_repository is defined) and (git_firewall_repository|length > 0)
    - diff_script_output.changed
  notify:
    - Restart IPv4 Firewall
    - Restart IPv6 Firewall

# ---
# Firewall scripts
# ---

- name: Check if firewall scripts are latest
  shell: 'diff {{ git_firewall_repository.dest }}/{{ item }} /ro/usr/local/sbin/{{ item }} > /dev/null 2>&1'
  changed_when: "diff_script_output.rc > 0"
  # diff_output.rc
  #    0  -> unchanged
  #    1  -> changed
  #    2  -> not present
  failed_when: "diff_script_output.rc > 2"
  when: (git_firewall_repository is defined) and (git_firewall_repository|length > 0)
  loop:
     - ipt-firewall-gateway
     - ip6t-firewall-gateway
  register: diff_script_output

- name: Ensure firewall scripts are latest
  command: cp {{ git_firewall_repository.dest }}/{{ item }} /ro/usr/local/sbin/{{ item }}
  loop:
     - ipt-firewall-gateway
     - ip6t-firewall-gateway
  when:
    - (git_firewall_repository is defined) and (git_firewall_repository|length > 0)
    - diff_script_output.changed
  notify:
    - Restart IPv4 Firewall
    - Restart IPv6 Firewall

# ---
# Remount Filesystem readonly
# ---

- name: Remount "/ro/" readonly
  shell: remountro
  register: remountro_cmd
  failed_when: remountro_cmd.rc != 0 and remountro_cmd.rc != 32
