wip: simple server to trigger routine stuff + ufw role #51

Draft
ben wants to merge 2 commits from poked into main
7 changed files with 232 additions and 0 deletions

View File

@ -0,0 +1,4 @@
---
ufw_ssh_world: false
ufw_open_ports: []

View File

@ -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

View File

@ -0,0 +1,3 @@
---
- import_tasks: common-ufw.yml
tags: common-ufw

75
roles/common/files/rub.py Executable file
View File

@ -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()

View File

@ -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

View File

@ -0,0 +1,8 @@
FROM python:3.9
MAINTAINER Benedikt Kristinsson <ben@lokun.is>
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`

View File

@ -0,0 +1,75 @@
#!/bin/env python3
# mainframe ~/infra/roles/mainframe/files <main*> $ 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()