diff --git a/roles/common-ufw/defaults/main.yml b/roles/common-ufw/defaults/main.yml new file mode 100644 index 0000000..a27d6e9 --- /dev/null +++ b/roles/common-ufw/defaults/main.yml @@ -0,0 +1,4 @@ +--- + +ufw_ssh_world: false +ufw_open_ports: [] diff --git a/roles/common-ufw/tasks/common-ufw.yml b/roles/common-ufw/tasks/common-ufw.yml new file mode 100644 index 0000000..80f6a9a --- /dev/null +++ b/roles/common-ufw/tasks/common-ufw.yml @@ -0,0 +1,54 @@ +--- + +- name: sanity check + fail: + msg: "failig so we dont lock ourselves out" + when: 'inventory_hostname != ansible_control_host' + +- name: allow ssh (restircted) + ufw: + rule: allow + to_port: "22" + direction: in + state: enabled + src: + - "{{ my_public_ips['ansible_control_host'] }}" + - "{{ my_public_ips['backup_pull_host'] }}" + when: not ufw_ssh_world + +- name: allow ssh (restircted) + ufw: + rule: allow + to_port: "22" + direction: in + state: enabled + when: ufw_ssh_world + +- name: allow loopback + ufw: + rule: allow + interface: lo + direction: in + state: enabled + + # and/or use my cidrs +- name: allow wg if defined + ufw: + rule: allow + interface: wg0 + direction: in + state: enabled + when: ansible_wg0 is defined + +- name: open ports + ufw: + rule: allow + to_port: "{{ item }}" + direction: in + state: enabled + with_items: "{{ ufw_open_ports }}" + +- name: default policy + ufw: + policy: deny + state: enabled diff --git a/roles/common-ufw/tasks/main.yml b/roles/common-ufw/tasks/main.yml new file mode 100644 index 0000000..e188f57 --- /dev/null +++ b/roles/common-ufw/tasks/main.yml @@ -0,0 +1,3 @@ +--- + - import_tasks: common-ufw.yml + tags: common-ufw diff --git a/roles/common/files/rub.py b/roles/common/files/rub.py new file mode 100755 index 0000000..2a65cc5 --- /dev/null +++ b/roles/common/files/rub.py @@ -0,0 +1,75 @@ +#!/usr/bin/python3 -u + +# unbuffered + +import sys +import os +import subprocess +import getpass +import json + +""" +command="/usr/local/bin/rub.py" +""" + + +# idea: read stdin, pokies.py writes to its stdout +# read from rub.py's stdin. lineinput or something? + +def subps_run(cmd): + try: + p = subprocess.run( + cmd.split(' '), + capture_output=True, + check=False + ) + if p.stdout: + print(p.stdout) + if p.stderr: + print(p.stderr) + + p.check_returncode() + return p + + except (FileNotFoundError, subprocess.CalledProcessError) as e: + print(f"error: {e}") + sys.exit(1) + + +def nginx(): + cmds = [ + "nginx -t", + "systemctl reload nginx" + ] + for cmd in cmds: + subps_run(cmd) + + +def wg0(): + p = subps_run("sudo systemctl reload wg-quick@wg0") + print("reloaded: wg-quick@wg0") + + +def main(): + ssh_original_cmd = os.environ.get('SSH_ORIGINAL_COMMAND', None) + print(f"SSH_ORIGINAL_COMMAND={ssh_original_cmd}") + + j = json.loads(ssh_original_cmd) + rub = j['rub'] + + print(f"getting rubbed: '{rub}'") + + if rub == "ruok": + print('iamok') + elif rub == "nginx": + nginx() + elif rub == "wg0": + wg0() + else: + print(f"unkonwn: '{rub}'") + sys.exit(1) + + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/roles/common/tasks/common.yml b/roles/common/tasks/common.yml index 5a1cf6e..6f98036 100644 --- a/roles/common/tasks/common.yml +++ b/roles/common/tasks/common.yml @@ -590,3 +590,16 @@ tags: - packages - apt.sudo.is + +- name: copy scripts + copy: + src: "{{ item }}" + dest: /usr/local/bin/{{ item }} + owner: root + group: sudo + mode: 0750 + with_items: + - rub.py + tags: + - scripts + - pokies diff --git a/roles/mainframe/files/pokies/Dockerfile b/roles/mainframe/files/pokies/Dockerfile new file mode 100644 index 0000000..e20a563 --- /dev/null +++ b/roles/mainframe/files/pokies/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3.9 +MAINTAINER Benedikt Kristinsson + +ENV TZ=UTC +ENV DEBIAN_FRONTEND=noninteractive +ENV TERM=xterm-256color +# ENV PIP_ROOT_USER_ACTION=ignore +# can also use `pip install --root-user-action=ignore` diff --git a/roles/mainframe/files/pokies/pokies.py b/roles/mainframe/files/pokies/pokies.py new file mode 100755 index 0000000..51f43f3 --- /dev/null +++ b/roles/mainframe/files/pokies/pokies.py @@ -0,0 +1,75 @@ +#!/bin/env python3 + +# mainframe ~/infra/roles/mainframe/files $ sudo -u ansible python3 -m pip install --user paramiko + +import json +from base64 import b64decode +from argparse import ArgumentParser + +import paramiko.client +from loguru import logger + + +class SSHClient(paramiko.client.SSHClient): + def iter_cmd(self, cmd, timeout=None): + if isinstance(cmd, list): + command = " ".join(cmd) + else: + command = cmd + + stdin, stdout, stderr = self.exec_command(command, timeout=timeout) + return stdout.readlines() + + def cmd(self, command): + lines = self.iter_cmd(command) + return "\n".join(lines) + + + +def get_file_b64: + with open(file_path, 'r') as f: + return b64encode(f.read()) + + +def print_cmd(self, iter_output): + for line in iter_output: + print(line) + +def parse_args(): + parser = ArgumentParser() + parser.add_argument("destination", help="which pokies to rub") + parser.add_argument("-u", "--user", help="ssh user") + parser.add_argument("-i", "--identity-file", help="ssh key") + parser.add_argument("--rub", help="what to rub on the other end", + required=True) + parser.add_argument("--path", help="for --rub upload") + return parser.parse_args() + +def main(): + args = parse_args() + + logger.info(f"pokies: {args.destination}") + logger.info(f"rubbing: {args.rub}") + + ssh = SSHClient() + ssh.load_system_host_keys() + ssh.connect( + args.destination, + username=args.user, + key_filename=args.identity_file, + look_for_keys=False, + allow_agent=False + ) + + if args.rub == "upload": + pass + if args.rub == "touch": + j = json.dumps({'rub': args.rub, "path": args.path}) + rub_out = ssh.cmd(j) + else: + rub_out = ssh.cmd(args.rub) + + print(rub_out) + +if __name__ == "__main__": + main()