Start some simple python admin scripts.
This commit is contained in:
parent
48587fe6e3
commit
d1b91a0a89
11 changed files with 198 additions and 7 deletions
4
Containerfile
Normal file
4
Containerfile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
FROM debian
|
||||||
|
|
||||||
|
COPY machine_admin /
|
||||||
|
COPY machine_setup.py /
|
14
README.md
14
README.md
|
@ -1,2 +1,14 @@
|
||||||
This repo is a collection of ad-hoc scripts and snippets for setting up and administering a small cloud server.
|
This repo is a collection of ad-hoc scripts and snippets for setting up and administering a small cloud server. They are just a stepping stone toward for formal automation.
|
||||||
|
|
||||||
|
# Machine setup
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./setup_machine.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
# Set up basic nginx server
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./setup_basic_nginx.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
|
0
machine_admin/__init__.py
Normal file
0
machine_admin/__init__.py
Normal file
28
machine_admin/firewall.py
Normal file
28
machine_admin/firewall.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import logging
|
||||||
|
from util import run_op
|
||||||
|
|
||||||
|
class UfwInterface:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
op = "ufw enable"
|
||||||
|
logging.info(f"Enabling ufw: {op}")
|
||||||
|
run_op(op)
|
||||||
|
|
||||||
|
def allow_app(self, app_name: str):
|
||||||
|
op = f"ufw allow {app_name}"
|
||||||
|
logging.info(f"Allowing ufw app: {op}")
|
||||||
|
run_op(op)
|
||||||
|
|
||||||
|
class Firewall:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.ufw = UfwInterface()
|
||||||
|
|
||||||
|
def allow_app(self, app_name: str):
|
||||||
|
self.ufw.allow_app(app_name)
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
self.ufw.enable()
|
29
machine_admin/machine.py
Normal file
29
machine_admin/machine.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
from firewall import Firewall
|
||||||
|
from user import User, UserManager
|
||||||
|
from ssh_config import SshConfig
|
||||||
|
from package_manager import PackageManager
|
||||||
|
|
||||||
|
class Machine:
|
||||||
|
|
||||||
|
def __init__(self, default_user: User):
|
||||||
|
self.user = default_user
|
||||||
|
self.user_manager = UserManager()
|
||||||
|
self.firewall = Firewall()
|
||||||
|
self.ssh_config = SshConfig()
|
||||||
|
self.package_manager = PackageManager()
|
||||||
|
|
||||||
|
def enable_firewall(self):
|
||||||
|
self.firewall.allow_app("OpenSSH")
|
||||||
|
self.firewall.enable()
|
||||||
|
|
||||||
|
def secure_ssh_config(self):
|
||||||
|
self.ssh_config.sync_target_values()
|
||||||
|
self.ssh_config.restart_service()
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
self.package_manager.update()
|
||||||
|
self.user_manager.setup_user(self.user)
|
||||||
|
self.enable_firewall()
|
||||||
|
self.secure_ssh_config()
|
||||||
|
self.package_manager.install_packages(["rsync", "fail2ban"])
|
||||||
|
self.ssh_config.copy_ssh_dir_to_user(self.user.name)
|
39
machine_admin/package_manager.py
Normal file
39
machine_admin/package_manager.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import logging
|
||||||
|
from util import run_op
|
||||||
|
|
||||||
|
class AptInterface:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
op = "apt-get update"
|
||||||
|
logging.info(f"Updating apt: {op}")
|
||||||
|
run_op(op)
|
||||||
|
|
||||||
|
def upgrade(self):
|
||||||
|
op = "apt-get -y upgrade"
|
||||||
|
logging.info(f"Upgrading via apt: {op}")
|
||||||
|
run_op(op)
|
||||||
|
|
||||||
|
def install_packages(self, packages: list):
|
||||||
|
packages_str = "".join(packages)
|
||||||
|
op = f"apt-get install -y {packages_str}"
|
||||||
|
logging.info(f"Installing packages: {op}")
|
||||||
|
run_op(op)
|
||||||
|
|
||||||
|
|
||||||
|
class PackageManager:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.apt = AptInterface()
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.apt.update()
|
||||||
|
|
||||||
|
def upgrade(self):
|
||||||
|
self.update()
|
||||||
|
self.apt.upgrade()
|
||||||
|
|
||||||
|
def install_packages(self, packages: list):
|
||||||
|
self.apt.install_packages(packages)
|
25
machine_admin/ssh_config.py
Normal file
25
machine_admin/ssh_config.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
from pathlib import Path
|
||||||
|
import logging
|
||||||
|
from util import run_op
|
||||||
|
|
||||||
|
class SshConfig:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.config_path = Path("/etc/ssh/ssh_config")
|
||||||
|
self.target_values = {"PermitRootLogin": "No",
|
||||||
|
"PasswordAuthentication": "No",
|
||||||
|
"ChallengeResponseAuthentication": "No",
|
||||||
|
"UsePAM": "No"}
|
||||||
|
|
||||||
|
def sync_target_values(self):
|
||||||
|
logging.info(f"Updating ssh config in: {self.config_path}")
|
||||||
|
pass
|
||||||
|
|
||||||
|
def restart_service(self):
|
||||||
|
op = "systemctl restart ssh"
|
||||||
|
logging.info(f"Restarting ssh service: {op}")
|
||||||
|
run_op(op)
|
||||||
|
|
||||||
|
def copy_ssh_dir_to_user(self, username:str):
|
||||||
|
op = f"rsync --archive --chown={username}:{username} ~/.ssh /home/{username}"
|
||||||
|
|
27
machine_admin/user.py
Normal file
27
machine_admin/user.py
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import logging
|
||||||
|
from util import run_op
|
||||||
|
|
||||||
|
class User:
|
||||||
|
def __init__(self, name, has_sudo=False):
|
||||||
|
self.name = name
|
||||||
|
self.has_sudo = has_sudo
|
||||||
|
|
||||||
|
class UserManager:
|
||||||
|
|
||||||
|
def __init__():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def setup_user(self, user: User):
|
||||||
|
add_user(user)
|
||||||
|
if user.has_sudo:
|
||||||
|
add_user_to_sudo(user)
|
||||||
|
|
||||||
|
def add_user(self, user: User):
|
||||||
|
op = f"adduser {user.name}"
|
||||||
|
logging.info(f"Adding user: {op}")
|
||||||
|
run_op(op)
|
||||||
|
|
||||||
|
def add_user_to_sudo(self, user: User):
|
||||||
|
op = f"usermod -aG sudo {user.name}"
|
||||||
|
logging.info(f"Adding user to sudo: {op}")
|
||||||
|
run_op(op)
|
4
machine_admin/util.py
Normal file
4
machine_admin/util.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def run_op(op: str):
|
||||||
|
return subprocess.run(op, shell=True)
|
21
machine_setup.py
Normal file
21
machine_setup.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from machine_admin.user import User
|
||||||
|
from machine_admin.machine import Machine
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog='MachineSetup',
|
||||||
|
description='Scripts for machine provisioning')
|
||||||
|
|
||||||
|
parser.add_argument('--username',
|
||||||
|
help="Name of the default non-root user")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
user = User(args.username, has_sudo=True)
|
||||||
|
machine = Machine(user)
|
||||||
|
machine.setup()
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
|
export MY_DOMAIN="my_domain"
|
||||||
|
|
||||||
apt install nginx
|
apt install nginx
|
||||||
|
|
||||||
ufw allow 'Nginx HTTP'
|
ufw allow 'Nginx HTTP'
|
||||||
|
|
||||||
mkdir -p /var/www/your_domain/html
|
mkdir -p /var/www/$MY_DOMAIN/html
|
||||||
chown -R $USER:$USER /var/www/your_domain/html
|
chown -R $USER:$USER /var/www/$MY_DOMAIN/html
|
||||||
chmod -R 755 /var/www/your_domain
|
chmod -R 755 /var/www/$MY_DOMAIN
|
||||||
|
|
||||||
echo "Hello world" | /var/www/your_domain/html/index.html
|
echo "Hello world" | /var/www/$MY_DOMAIN/html/index.html
|
||||||
|
|
||||||
cp basic_serverblock.txt /etc/nginx/sites-available/your_domain
|
cp basic_serverblock.txt /etc/nginx/sites-available/$MY_DOMAIN
|
||||||
|
|
||||||
ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
|
ln -s /etc/nginx/sites-available/$MY_DOMAIN /etc/nginx/sites-enabled/
|
||||||
|
|
||||||
# sudo nano /etc/nginx/nginx.conf
|
# sudo nano /etc/nginx/nginx.conf
|
||||||
server_names_hash_bucket_size 64;
|
server_names_hash_bucket_size 64;
|
Loading…
Reference in a new issue