1
0
Fork 0
forked from infra/ansible

Add Ansible playbook to toggle Koji HTTP access with nftables

Signed-off-by: Samyak Jain <samyak.jn11@gmail.com>
This commit is contained in:
Samyak Jain 2026-07-07 12:06:10 +05:30
commit d9e7279830

View file

@ -0,0 +1,133 @@
---
# Quick toggle for Koji HTTP access via nftables.
# Run with: -e "koji_action=block|unblock|status" -e "koji_hosts=koji|koji_stg"
# Optional: -e "koji_http_port_override=80"
- name: Toggle Koji HTTP access using nftables
hosts: "{{ koji_hosts | default('koji_stg:koji:koji_riscv') }}"
user: root
gather_facts: true
vars_files:
- /srv/web/infra/ansible/vars/global.yml
- "{{ private }}/vars.yml"
- /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml
vars:
koji_http_port: "{{ koji_http_port_override | default('80') }}"
nft_table: "inet filter"
nft_chain: "input"
nft_set: "koji_http_block_src"
nft_comment: "koji-http-block"
is_staging: "{{ inventory_hostname in groups['koji_stg'] or inventory_hostname in groups.get('koji_stg_rdu3', []) }}"
proxy_hostnames: "{{ is_staging | ternary(['proxy01.stg.rdu3.fedoraproject.org', 'proxy02.stg.rdu3.fedoraproject.org'], ['proxy01.rdu3.fedoraproject.org', 'proxy10.rdu3.fedoraproject.org']) }}"
pre_tasks:
- name: Validate koji_action
ansible.builtin.fail:
msg: "Usage: -e 'koji_action=block|unblock|status'"
when: koji_action is not defined or koji_action not in ['block', 'unblock', 'status']
tags: always
tasks:
- name: Resolve proxy IPs
ansible.builtin.command:
cmd: "getent ahostsv4 {{ item }} | awk '{print $1; exit}'"
register: proxy_resolution
loop: "{{ proxy_hostnames }}"
changed_when: false
failed_when: proxy_resolution.stdout == ""
- name: Set proxy IP list
ansible.builtin.set_fact:
proxy_ips: "{{ proxy_resolution.results | map(attribute='stdout') | list }}"
- name: Block Koji HTTP from proxies
when: koji_action == 'block'
block:
- name: Ensure nftables table exists
ansible.builtin.command:
cmd: "nft add table {{ nft_table }}"
register: nft_table_add
changed_when: nft_table_add.rc == 0
failed_when: nft_table_add.rc != 0 and 'File exists' not in nft_table_add.stderr
- name: Ensure nftables chain exists
ansible.builtin.command:
cmd: "nft add chain {{ nft_table }} {{ nft_chain }} '{ type filter hook input priority 0; policy accept; }'"
register: nft_chain_add
changed_when: nft_chain_add.rc == 0
failed_when: nft_chain_add.rc != 0 and 'File exists' not in nft_chain_add.stderr
- name: Ensure nftables set exists
ansible.builtin.command:
cmd: "nft add set {{ nft_table }} {{ nft_set }} '{ type ipv4_addr; comment \"{{ nft_comment }}\"; }'"
register: nft_set_add
changed_when: nft_set_add.rc == 0
failed_when: nft_set_add.rc != 0 and 'File exists' not in nft_set_add.stderr
- name: Ensure drop rule exists
ansible.builtin.command:
cmd: "nft add rule {{ nft_table }} {{ nft_chain }} tcp dport {{ koji_http_port }} ip saddr @{{ nft_set }} drop comment \"{{ nft_comment }}\""
register: nft_rule_add
changed_when: nft_rule_add.rc == 0
failed_when: nft_rule_add.rc != 0 and 'File exists' not in nft_rule_add.stderr
- name: Add proxy IPs to nftables set
ansible.builtin.command:
cmd: "nft add element {{ nft_table }} {{ nft_set }} '{ {{ proxy_ips | join(', ') }} }'"
register: nft_add_elements
changed_when: nft_add_elements.rc == 0
failed_when: nft_add_elements.rc != 0 and 'File exists' not in nft_add_elements.stderr
- name: Report block action
ansible.builtin.debug:
msg: "Blocked tcp/{{ koji_http_port }} from {{ proxy_ips | join(', ') }}"
- name: Unblock Koji HTTP from proxies
when: koji_action == 'unblock'
block:
- name: Flush nftables set (if present)
ansible.builtin.command:
cmd: "nft flush set {{ nft_table }} {{ nft_set }}"
register: nft_set_flush
changed_when: nft_set_flush.rc == 0
failed_when: nft_set_flush.rc != 0 and 'No such file or directory' not in nft_set_flush.stderr
- name: Find drop rule handle
ansible.builtin.shell:
cmd: set -o pipefail && nft -a list chain {{ nft_table }} {{ nft_chain }} | awk '/tcp dport {{ koji_http_port }}.* @{{ nft_set }}.* drop/ {print $NF}'
register: rule_handle
changed_when: false
failed_when: false
- name: Delete drop rule by handle
ansible.builtin.command:
cmd: "nft delete rule {{ nft_table }} {{ nft_chain }} handle {{ rule_handle.stdout }}"
when: rule_handle.stdout != ""
- name: Report unblock action
ansible.builtin.debug:
msg: "Unblocked tcp/{{ koji_http_port }}"
- name: Show current nftables status
when: koji_action == 'status'
block:
- name: Show table
ansible.builtin.command:
cmd: "nft list table {{ nft_table }}"
register: table_status
changed_when: false
failed_when: false
- name: Show set
ansible.builtin.command:
cmd: "nft list set {{ nft_table }} {{ nft_set }}"
register: set_status
changed_when: false
failed_when: false
- name: Report status
ansible.builtin.debug:
msg: |
{{ table_status.stdout if table_status.rc == 0 else '(no table)' }}
{{ set_status.stdout if set_status.rc == 0 else '(no set)' }}