diff --git a/config/provision.py b/config/provision.py
index a04c1c5..0b824f2 100755
--- a/config/provision.py
+++ b/config/provision.py
@@ -193,6 +193,7 @@ def add_users():
but["passwd"]["users"].append({
"name": user,
"uid": UIDS[user],
+ "ssh_authorized_keys": cfg["core"]["ssh_keys"],
})
but["storage"]["files"].append({
"path": f"/var/lib/systemd/linger/{user}",
@@ -312,6 +313,32 @@ def run_containers():
])}
})
+def advertise_services():
+ but["storage"]["directories"].extend([
+ { "path": "/etc/avahi" },
+ { "path": "/etc/avahi/services" },
+ ])
+ for mnt in cfg["nas"]["mounts"]:
+ but["storage"]["files"].append({
+ "path": f"/etc/avahi/services/nas-{mnt}.service",
+ "contents": { "inline": "\n".join([
+ "",
+ "",
+ "",
+ f" %h - {mnt}",
+ " ",
+ " _smb._tcp",
+ " 445",
+ " ",
+ " ",
+ " _adisk._tcp",
+ f" dk0=adVN={mnt},adVF=0x82",
+ " sys=waMa=0,adVF=0x100",
+ " ",
+ "",
+ ])}
+ })
+
if __name__ == "__main__":
cfg = json.load(open("config/server.json"))
but = {
@@ -336,11 +363,9 @@ if __name__ == "__main__":
create_pods()
create_folders()
run_containers()
+ advertise_services()
- # TODO fix update.py ownership
- # TODO gen apache services
-
# TODO update router scripts bc DUID => make fixed??
# TODO script to backup => restore backup if desired => fix permissions
# may need to chown 777 for gitea restore
diff --git a/config/update.py b/config/update.py
index e37a060..cf83a99 100755
--- a/config/update.py
+++ b/config/update.py
@@ -62,9 +62,9 @@ def generate(cfg):
f.write(f"[{mnt}]\n")
f.write(f"path = /mnt/{mnt}\n\n")
-def run(cmds):
+def run(cmds, user="core"):
try:
- subprocess.check_output(["ssh", f"core@{cfg["core"]["hostname"]}.local", ";".join(cmds)], stderr=subprocess.STDOUT)
+ subprocess.check_output(["ssh", f"{user}@{cfg["core"]["hostname"]}.local", ";".join(cmds)], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
print("\033[31m", end="")
print(e.output.decode())
@@ -78,9 +78,10 @@ if __name__ == "__main__":
generate(cfg)
# copy files
- for f in (f for l in IMAGES.values() for f in l):
- subprocess.run(["scp", "-r", f, f"core@{cfg["core"]["hostname"]}.local:{SOURCE_DIR}"], check=True)
- # TODO should probs chown and chmod correctly...
+ for user in IMAGES:
+ for img in IMAGES[user]:
+ subprocess.run(["scp", "-r", img, f"{user}@{cfg["core"]["hostname"]}.local:{SOURCE_DIR}"], check=True)
+ run([f"chmod 770 {SOURCE_DIR}/{img}"], user=user)
# run builds
for user in IMAGES:
diff --git a/scripts/setup_drive.py b/scripts/setup_drive.py
deleted file mode 100755
index 5eba7b9..0000000
--- a/scripts/setup_drive.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/sudo /usr/bin/python3
-
-import os
-import shutil
-import subprocess
-import sys
-from pathlib import Path
-
-KEY_DIR = Path("/opt/luks")
-
-def run(cmd):
- subprocess.run(cmd.split(), check=True)
-
-if __name__ == "__main__":
- drive = sys.argv[1]
- mount = Path(sys.argv[2])
- key = KEY_DIR / f"{drive}.key"
- assert(Path(f"/dev/{drive}").exists())
- assert(not key.exists())
-
- # create directories and key
- KEY_DIR.mkdir(exist_ok=True)
- mount.mkdir(exist_ok=True)
- run(f"dd if=/dev/random bs=32 count=1 of={key}")
- key.chmod(0o400)
-
- # format and mount drive
- run(f"cryptsetup luksFormat --key-file={key} /dev/{drive}")
- run(f"cryptsetup luksOpen --key-file={key} /dev/{drive} {drive}_luks")
- run(f"mkfs.btrfs /dev/mapper/{drive}_luks")
- run(f"mount /dev/mapper/{drive}_luks {mount}")
- shutil.chown(mount, os.getlogin(), "nas")
- mount.chmod(0o770)
-
- # TODO modify /etc/crypttab instead once Ubuntu fixed
- with open("/opt/luks.sh", "a") as f:
- f.write(f"systemd-cryptsetup attach {drive}_luks /dev/{drive} {key} luks\n")
- f.write(f"mount /dev/mapper/{drive}_luks {mount}\n")
diff --git a/scripts/setup_repo.py b/scripts/setup_repo.py
deleted file mode 100755
index 2e22b2d..0000000
--- a/scripts/setup_repo.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/sudo /usr/bin/python3
-
-import json
-import os
-import shutil
-import subprocess
-import yaml
-from pathlib import Path
-
-if __name__ == "__main__":
- override = {}
-
- # create folders so containers have access
- PATHS = {
- "web": [
- "website/certbot",
- "website/gitea/config",
- "website/gitea/data",
- ],
- "monero": [
- "monerod/.bitmonero",
- "p2pool/cache",
- ],
- "game": [
- "minecraft/worlds",
- "minecraft_bedrock/worlds",
- "terraria/worlds",
- "terraria/mods",
- ]
- }
- for group in PATHS:
- for p in PATHS[group]:
- Path(p).mkdir(parents=True, exist_ok=True)
- Path(p).chmod(0o775)
- shutil.chown(p, user=os.getlogin(), group=group)
-
- # add users to nas
- file = Path("nas/users.json")
- script = Path("nas/users.sh")
- with script.open("w") as f:
- if file.exists():
- users = json.load(file.open())
- for id, user in enumerate(users):
- id = 3000 + id
- f.writelines(s + "\n" for s in [
- f"groupadd -g {id} {user}",
- f"useradd -M -s /bin/false -u {id} -g {id} {user}",
- f"su - me -c 'echo \"{users[user]}\\n{users[user]}\\n\" | pdbedit -s smb.conf -a {user}'",
- ])
- shutil.chown(script, user=os.getlogin(), group=os.getlogin())
-
- # add volumes to nas
- file = Path("nas/mounts.json")
- serv = Path("/etc/avahi/services")
- conf = Path("nas/smb.conf")
- shutil.copyfile("nas/base.conf", conf)
- shutil.chown(conf, user=os.getlogin(), group=os.getlogin())
- for f in serv.glob("nas-*.service"):
- f.unlink()
- if file.exists():
- mounts = json.load(file.open())
- with open("nas/smb.conf", "a") as f:
- for m in mounts:
- f.write(f"[{m}]\n")
- f.write(f"path = /home/me/share/{m}\n")
- f.write("\n")
- override.setdefault("services", {})["nas"] = {"volumes": [f"{mounts[m]}:/home/me/share/{m}" for m in mounts]}
- for m in mounts:
- with (serv / f"nas-{m}.service").open("w") as f:
- f.writelines(s + "\n" for s in [
- "",
- "",
- "",
- f" %h - {m}",
- " ",
- " _smb._tcp",
- " 445",
- " ",
- " ",
- " _adisk._tcp",
- f" dk0=adVN={m},adVF=0x82",
- " sys=waMa=0,adVF=0x100",
- " ",
- "",
- ])
- subprocess.run(["systemctl", "restart", "avahi-daemon"], check=True)
-
- # generate compose override
- file = Path("compose.override.yml")
- if override:
- with file.open("w") as f:
- yaml.dump(override, f)
- shutil.chown(file, user=os.getlogin(), group=os.getlogin())
- else:
- file.unlink(True)
diff --git a/scripts/setup_server.py b/scripts/setup_server.py
deleted file mode 100755
index 45fc11d..0000000
--- a/scripts/setup_server.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/sudo /usr/bin/python3
-
-import json
-import os
-import subprocess
-from pathlib import Path
-
-def run(cmd, capture=False):
- if capture:
- return subprocess.check_output(cmd.split())
- else:
- subprocess.run(cmd.split(), check=True)
-
-if __name__ == "__main__":
- # install dependencies and configure
- run("apt update")
- run("apt upgrade -y")
- run("apt install -y avahi-daemon btrfs-progs openssh-server python-is-python3 python3-pip wireguard zip")
- with open("/etc/sysctl.conf", "a+") as f: # enable huge pages for local mining
- f.seek(0)
- if "vm.nr_hugepages=1280\n" not in f.readlines():
- f.write("vm.nr_hugepages=1280\n")
- file = Path("/etc/ssh/sshd_config.d/restrict.conf") # only allow public key login
- if not file.exists():
- with file.open("w") as f:
- f.write("PasswordAuthentication no\n")
-
- # install docker and configure
- run("snap install docker")
- run("addgroup --system docker")
- run(f"adduser {os.getlogin()} docker")
- with open("/var/snap/docker/current/config/daemon.json", "r+") as f:
- cfg = json.load(f)
- cfg["ipv6"] = True
- cfg["fixed-cidr-v6"] = "fd3a:138e:8fd0:0000::/64" # Docker ULA
- f.seek(0)
- json.dump(cfg, f, indent=4)
- run("systemctl restart snap.docker.dockerd.service")
-
- try:
- run("addgroup --gid 2000 web")
- run("addgroup --gid 2001 monero")
- run("addgroup --gid 2002 game")
- run("addgroup --gid 2003 nas")
- run(f"adduser {os.getlogin()} web")
- run(f"adduser {os.getlogin()} monero")
- run(f"adduser {os.getlogin()} game")
- run(f"adduser {os.getlogin()} nas")
- except:
- pass
-
- # restrict network access from containers
- file = Path("/etc/systemd/system/docker-restrict.service")
- if not file.exists():
- with file.open("w") as f:
- f.writelines(s + "\n" for s in [
- "[Unit]",
- "Description=Restrict Docker network access",
- "Before=network.target",
- "After=network-pre.target",
- "",
- "[Service]",
- "Type=oneshot",
- "ExecStart=/opt/docker-restrict.sh",
- "RemainAfterExit=yes",
- "",
- "[Install]",
- "WantedBy=multi-user.target",
- ])
- file = Path("/opt/docker-restrict.sh")
- if not file.exists():
- with file.open("w") as f:
- f.writelines(s + "\n" for s in [
- "#!/bin/sh",
- "iptables -N DOCKER-USER || true",
- "iptables -I DOCKER-USER -d 10.0.0.0/8 -j DROP", # xfinity gateway
- "iptables -I DOCKER-USER -p tcp --dport 22 -j DROP", # SSH
- "ip6tables -N DOCKER-USER || true",
- "ip6tables -I DOCKER-USER -p tcp --dport 22 -j DROP", # SSH
- ])
- file.chmod(0o755)
- run("systemctl enable docker-restrict.service")
-
- # TODO modify /etc/crypttab instead once Ubuntu fixed
- file = Path("/etc/systemd/system/luks.service")
- if not file.exists():
- with file.open("w") as f:
- f.writelines(s + "\n" for s in [
- "[Unit]",
- "Description=Mount more LUKS drives",
- "After=local-fs.target",
- "Requires=local-fs.target",
- "",
- "[Service]",
- "Type=oneshot",
- "ExecStart=/opt/luks.sh",
- "RemainAfterExit=yes",
- "",
- "[Install]",
- "WantedBy=multi-user.target",
- ])
- file = Path("/opt/luks.sh")
- if not file.exists():
- with file.open("w") as f:
- f.write("#!/bin/sh\n")
- file.chmod(0o755)
- run("systemctl enable luks.service")