mirror of
https://github.com/dragonlock2/matthewtran.com.git
synced 2025-10-11 12:07:56 +00:00
wip8
This commit is contained in:
parent
36df5d64d3
commit
e774f3ebdc
@ -193,6 +193,7 @@ def add_users():
|
|||||||
but["passwd"]["users"].append({
|
but["passwd"]["users"].append({
|
||||||
"name": user,
|
"name": user,
|
||||||
"uid": UIDS[user],
|
"uid": UIDS[user],
|
||||||
|
"ssh_authorized_keys": cfg["core"]["ssh_keys"],
|
||||||
})
|
})
|
||||||
but["storage"]["files"].append({
|
but["storage"]["files"].append({
|
||||||
"path": f"/var/lib/systemd/linger/{user}",
|
"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([
|
||||||
|
"<?xml version=\"1.0\" standalone='no'?>",
|
||||||
|
"<!DOCTYPE service-group SYSTEM \"avahi-service.dtd\">",
|
||||||
|
"<service-group>",
|
||||||
|
f" <name replace-wildcards=\"yes\">%h - {mnt}</name>",
|
||||||
|
" <service>",
|
||||||
|
" <type>_smb._tcp</type>",
|
||||||
|
" <port>445</port>",
|
||||||
|
" </service>",
|
||||||
|
" <service>",
|
||||||
|
" <type>_adisk._tcp</type>",
|
||||||
|
f" <txt-record>dk0=adVN={mnt},adVF=0x82</txt-record>",
|
||||||
|
" <txt-record>sys=waMa=0,adVF=0x100</txt-record>",
|
||||||
|
" </service>",
|
||||||
|
"</service-group>",
|
||||||
|
])}
|
||||||
|
})
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cfg = json.load(open("config/server.json"))
|
cfg = json.load(open("config/server.json"))
|
||||||
but = {
|
but = {
|
||||||
@ -336,11 +363,9 @@ if __name__ == "__main__":
|
|||||||
create_pods()
|
create_pods()
|
||||||
create_folders()
|
create_folders()
|
||||||
run_containers()
|
run_containers()
|
||||||
|
advertise_services()
|
||||||
|
|
||||||
|
|
||||||
# TODO fix update.py ownership
|
|
||||||
# TODO gen apache services
|
|
||||||
|
|
||||||
# TODO update router scripts bc DUID => make fixed??
|
# TODO update router scripts bc DUID => make fixed??
|
||||||
# TODO script to backup => restore backup if desired => fix permissions
|
# TODO script to backup => restore backup if desired => fix permissions
|
||||||
# may need to chown 777 for gitea restore
|
# may need to chown 777 for gitea restore
|
||||||
|
@ -62,9 +62,9 @@ def generate(cfg):
|
|||||||
f.write(f"[{mnt}]\n")
|
f.write(f"[{mnt}]\n")
|
||||||
f.write(f"path = /mnt/{mnt}\n\n")
|
f.write(f"path = /mnt/{mnt}\n\n")
|
||||||
|
|
||||||
def run(cmds):
|
def run(cmds, user="core"):
|
||||||
try:
|
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:
|
except subprocess.CalledProcessError as e:
|
||||||
print("\033[31m", end="")
|
print("\033[31m", end="")
|
||||||
print(e.output.decode())
|
print(e.output.decode())
|
||||||
@ -78,9 +78,10 @@ if __name__ == "__main__":
|
|||||||
generate(cfg)
|
generate(cfg)
|
||||||
|
|
||||||
# copy files
|
# copy files
|
||||||
for f in (f for l in IMAGES.values() for f in l):
|
for user in IMAGES:
|
||||||
subprocess.run(["scp", "-r", f, f"core@{cfg["core"]["hostname"]}.local:{SOURCE_DIR}"], check=True)
|
for img in IMAGES[user]:
|
||||||
# TODO should probs chown and chmod correctly...
|
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
|
# run builds
|
||||||
for user in IMAGES:
|
for user in IMAGES:
|
||||||
|
@ -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")
|
|
@ -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 [
|
|
||||||
"<?xml version=\"1.0\" standalone='no'?>",
|
|
||||||
"<!DOCTYPE service-group SYSTEM \"avahi-service.dtd\">",
|
|
||||||
"<service-group>",
|
|
||||||
f" <name replace-wildcards=\"yes\">%h - {m}</name>",
|
|
||||||
" <service>",
|
|
||||||
" <type>_smb._tcp</type>",
|
|
||||||
" <port>445</port>",
|
|
||||||
" </service>",
|
|
||||||
" <service>",
|
|
||||||
" <type>_adisk._tcp</type>",
|
|
||||||
f" <txt-record>dk0=adVN={m},adVF=0x82</txt-record>",
|
|
||||||
" <txt-record>sys=waMa=0,adVF=0x100</txt-record>",
|
|
||||||
" </service>",
|
|
||||||
"</service-group>",
|
|
||||||
])
|
|
||||||
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)
|
|
@ -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")
|
|
Loading…
x
Reference in New Issue
Block a user