1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
- name: Set up firewall
  tags: ufw
  hosts: lotus-land-story
  tasks:

    - name: Enable ufw
      community.general.ufw:
        state: enabled

    - name: Allow access from tailscale
      community.general.ufw:
        rule: allow
        interface_in: tailscale0
      notify: Reload ufw

    - name: Get docker network for ufw
      community.docker.docker_network:
        name: lotus_land_story
      register: docker_network

    - name: Allow access from docker network
      community.general.ufw:
        rule: allow
        from_ip: "{{ docker_network.network.IPAM.Config[0].Subnet }}"
      notify: Reload ufw

    # for gitea from work laptop
    - name: Allow SSH access
      community.general.ufw:
        rule: allow
        name: OpenSSH
      notify: Reload ufw

    - name: Disable password auth via SSH
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: ^PasswordAuthentication
        line: PasswordAuthentication no
      notify: Restart ssh

  handlers:
    - name: Import restarts
      ansible.builtin.import_tasks: restarts.yml


# Can use `fail2ban-client status sshd` to check on this
- name: Set up Fail2Ban
  tags: fail2ban
  hosts: lotus-land-story
  tasks:

    - name: Install Fail2Ban
      ansible.builtin.apt:
        name: fail2ban
        state: present

    # TODO Reload fail2ban if this changes

    - name: Configure Fail2Ban for sshd
      ansible.builtin.copy:
        dest: /etc/fail2ban/jail.d/sshd.local
        content: |
          [sshd]
          enabled = true
          mode = aggressive
          bantime = 1w
          findtime = 12h
        mode: "0600"

    - name: Configure Fail2Ban for gitea
      block:
        - name: Create gitea filter
          ansible.builtin.copy:
            dest: /etc/fail2ban/filter.d/gitea.local
            content: |
              [Definition]
              failregex = .*(Disconnected from invalid user).* <HOST> port
              ignoreregex =
            mode: "0600"

        - name: Create gitea jail
          ansible.builtin.copy:
            dest: /etc/fail2ban/jail.d/gitea.local
            content: |
              [gitea]
              enabled = true
              filter = gitea
              logpath = /var/log/gitea.log
              maxretry = 3
              bantime = 1w
              findtime = 12h
              action = iptables-allports[chain="FORWARD"]
            mode: "0600"

    - name: Start Fail2Ban
      ansible.builtin.service:
        name: fail2ban
        state: started

# vim: ft=yaml.ansible