--- # Gitea SSH Passthrough Configuration - Rick-Infra # Configures system SSH to handle Gitea Git authentication # This is the default mode: more secure, standard Git URLs - name: Ensure OpenSSH server is installed pacman: name: openssh state: present - name: Create Gitea AuthorizedKeysCommand script template: src: gitea-keys.sh.j2 dest: /usr/local/bin/gitea-keys mode: '0755' owner: root group: root register: gitea_keys_script - name: Configure SSH for Gitea passthrough blockinfile: path: /etc/ssh/sshd_config marker: "# {mark} ANSIBLE MANAGED BLOCK - Gitea SSH Passthrough" block: | # Gitea SSH Passthrough - Rick-Infra # System SSH delegates git user authentication to Gitea # This allows standard Git URLs: git@{{ gitea_ssh_domain }}:user/repo.git Match User {{ gitea_user }} AuthorizedKeysCommandUser {{ gitea_user }} AuthorizedKeysCommand /usr/local/bin/gitea-keys %u %t %k AllowTcpForwarding no AllowAgentForwarding no X11Forwarding no PermitTTY no backup: yes validate: '/usr/bin/sshd -t -f %s' register: sshd_config_changed notify: restart sshd - name: Verify SSH configuration syntax command: sshd -t changed_when: false register: sshd_test - name: Display SSH validation result debug: msg: | {% if sshd_test.rc == 0 %} ✅ SSH configuration is valid {% else %} ⚠️ SSH configuration test failed: {{ sshd_test.stderr }} {% endif %} - name: Fail if SSH configuration is invalid fail: msg: "SSH configuration test failed. Rolling back changes." when: sshd_test.rc != 0 - name: Remove Gitea firewall rule (passthrough uses port 22) file: path: /etc/nftables.d/50-gitea.nft state: absent notify: reload nftables register: firewall_cleaned - name: Reload nftables if firewall rule was removed systemd: name: nftables state: reloaded when: firewall_cleaned.changed - name: Configure fail2ban for passthrough mode import_tasks: fail2ban.yml tags: ['fail2ban', 'security'] - name: Flush handlers to ensure sshd restarts if needed meta: flush_handlers - name: Wait for SSH service to be available after restart wait_for: port: 22 host: "{{ ansible_host | default('127.0.0.1') }}" timeout: 30 delegate_to: localhost become: false when: sshd_config_changed.changed - name: Test SSH connection after configuration ping: when: sshd_config_changed.changed - name: Verify passthrough is working command: sudo -u {{ gitea_user }} /usr/local/bin/gitea-keys ssh-rsa test register: gitea_keys_test changed_when: false failed_when: false - name: Display passthrough mode configuration debug: msg: | 🔧 Gitea SSH Mode: PASSTHROUGH (Default) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 📍 SSH Server: System SSH (port 22) 🔗 Clone URL: git@{{ gitea_ssh_domain }}:user/repo.git 🔥 Firewall: Port 2222 closed (not needed) 🛡️ fail2ban: System 'sshd' jail protects all SSH traffic 🔑 AuthorizedKeysCommand: /usr/local/bin/gitea-keys How it works: 1. User connects: ssh git@{{ gitea_ssh_domain }} 2. System SSH checks: /usr/local/bin/gitea-keys 3. Script queries Gitea database for SSH key 4. If authorized, Gitea handles Git operation Test connection: ssh -T git@{{ gitea_ssh_domain }} Clone repository: git clone git@{{ gitea_ssh_domain }}:username/repo.git Benefits: ✅ Standard Git URLs (no :2222 port number) ✅ Single SSH daemon (smaller attack surface) ✅ System fail2ban protects everything ✅ One port to manage and monitor # Rick-Infra: Self-contained SSH passthrough mode with enhanced security