This commit is contained in:
Matthew Tran 2025-05-04 17:57:34 -07:00
parent 007243c99e
commit 36df5d64d3
10 changed files with 117 additions and 77 deletions

9
.gitignore vendored
View File

@ -19,13 +19,6 @@ minecraft_bedrock/server.properties
# terraria
terraria/*.txt
# nas
nas/*.json
nas/Dockerfile
nas/smb.conf
nas/users.sh

View File

@ -26,8 +26,6 @@ final dev => reprovision + wipe home so images rebuilds
logs => sudo -u game podman logs container
TODO fix setup_router DUID suff => may need to reset after each provision...
1. Install [Ubuntu Desktop 24.04.1 LTS](https://ubuntu.com/download/desktop) with TPM-backed FDE. Server currently has a [bug](https://bugs.launchpad.net/ubuntu/+source/cryptsetup/+bug/1980018) that makes TPM-backed FDE hard.
- You may need to manually enable IPv6 on the network connection. Use `Automatic` not `Automatic, DHCP only`.
- Add an SSH key if you need remote access, setup will disable password authentication.

View File

@ -19,7 +19,7 @@ PORTS = {
"web": [
"80:80", # website
"443:443",
"2222:2222", # gitea
"2222:22", # gitea
],
"monero": [
"18080:18080", # monerod
@ -34,6 +34,9 @@ PORTS = {
"19133:19133/udp",
"7777:7777", # terraria
],
"nas": [
"445:445", # nas
],
}
def check_keys():
@ -145,6 +148,7 @@ def add_packages():
"[Service]",
"Type=oneshot",
"RemainAfterExit=yes",
f"ExecStart=/usr/bin/usermod -a -G {",".join(UIDS.keys())} core",
"ExecStart=/usr/bin/rpm-ostree install -y --allow-inactive " + " ".join([
"avahi",
"htop",
@ -201,25 +205,27 @@ def copy_source():
"user": { "name": "core" },
"group": { "name": "core" },
})
for i in (f for s in IMAGES.values() for f in s):
for user in IMAGES:
for img in IMAGES[user]:
but["storage"]["directories"].append({
"path": str(Path(SOURCE_DIR) / i),
"user": { "name": "core" },
"group": { "name": "core" },
"path": str(Path(SOURCE_DIR) / img),
"mode": 0o770,
"user": { "name": user },
"group": { "name": user },
})
for f in Path(i).glob("**/*"):
for f in Path(img).glob("**/*"):
if f.is_dir():
but["storage"]["directories"].append({
"path": str(Path(SOURCE_DIR) / f),
"user": { "name": "core" },
"group": { "name": "core" },
"user": { "name": user },
"group": { "name": user },
})
else:
but["storage"]["files"].append({
"path": str(Path(SOURCE_DIR) / f),
"contents": { "inline": open(f, "rb").read() },
"user": { "name": "core" },
"group": { "name": "core" },
"user": { "name": user },
"group": { "name": user },
})
def build_images():
@ -240,7 +246,10 @@ def create_pods():
for user in IMAGES:
but["storage"]["files"].append({
"path": f"/etc/containers/systemd/users/{UIDS[user]}/{user}.pod",
"contents": { "inline": "[Pod]\n" + "\n".join([f"PublishPort={p}" for p in PORTS[user]])}
"contents": { "inline": "\n".join([
"[Pod]",
*[f"PublishPort={p}" for p in PORTS[user]],
])},
})
def create_folders():
@ -250,16 +259,45 @@ def create_folders():
"group": { "name": "core" },
})
for user in IMAGES:
for img in IMAGES[user]:
but["storage"]["directories"].append({
"path": str(Path(cfg["core"]["data_dir"]) / img),
"path": str(Path(cfg["core"]["data_dir"]) / user),
"mode": 0o770,
"user": { "name": user },
"group": { "name": user },
})
for img in IMAGES[user]:
but["storage"]["directories"].append({
"path": str(Path(cfg["core"]["data_dir"]) / user / img),
"user": { "name": user },
"group": { "name": user },
})
for mnt in cfg["nas"]["mounts"]:
but["storage"]["directories"].append({
"path": str(Path(cfg["nas"]["mounts"][mnt]) / "share"),
"mode": 0o770,
"user": { "name": "nas" },
"group": { "name": "nas" },
})
def run_containers():
for user in IMAGES:
for img in IMAGES[user]:
env = []
if img == "gitea":
env.extend([
"Environment=GITEA__server__SSH_PORT=2222",
"Environment=GITEA__service__DISABLE_REGISTRATION=true",
"Environment=GITEA__openid__ENABLE_OPENID_SIGNIN=false",
"Environment=GITEA__openid__ENABLE_OPENID_SIGNUP=false",
])
vols = [f"Volume={str(Path(cfg["core"]["data_dir"]) / user / img)}:/data:z"]
if user == "nas":
vols.extend([
f"Volume={str(Path(cfg["nas"]["mounts"][mnt]) / "share")}:/mnt/{mnt}:z"
for mnt in cfg["nas"]["mounts"]
])
but["storage"]["files"].append({
"path": f"/etc/containers/systemd/users/{UIDS[user]}/{img}.container",
"contents": { "inline": "\n".join([
@ -267,7 +305,8 @@ def run_containers():
f"ContainerName={img}",
f"Image={img}.build",
f"Pod={user}.pod",
f"Volume={str(Path(cfg["core"]["data_dir"]) / img)}:/data:z",
*env,
*vols,
"[Install]",
"WantedBy=default.target",
])}
@ -299,13 +338,16 @@ if __name__ == "__main__":
run_containers()
# TODO add nas
# TODO restrict access to source code...
# add core to all groups => owned by users only access by them too
# TODO script to backup => restore backup if desired
# 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
# TODO generate ISO, else nginx if --insecure
# TODO full wipe test (wipefs all) => check folder permissions secure
with open("config/server.bu", "w") as f:
f.write(yaml.dump(but, sort_keys=False))
subprocess.check_output(["butane", "-p", "-s", "-o", "config/server.ign", "config/server.bu"])

View File

@ -32,5 +32,13 @@
"size": 3,
"difficulty": 2
}
},
"nas": {
"users": {
"matt": "password"
},
"mounts": {
"stuff": "/var/mnt/stuff"
}
}
}

View File

@ -20,6 +20,9 @@ IMAGES = {
"minecraft_bedrock",
"terraria",
],
"nas": [
"nas",
],
}
def generate(cfg):
@ -46,6 +49,19 @@ def generate(cfg):
with open("terraria/password.txt", "w") as f:
f.write(cfg["terraria"]["password"])
# nas
shutil.copy("nas/Dockerfile.template", "nas/Dockerfile")
shutil.copy("nas/smb.conf.template", "nas/smb.conf")
with open("nas/Dockerfile", "a") as f:
for user in cfg["nas"]["users"]:
p = cfg["nas"]["users"][user]
f.write(f"RUN useradd -M -s /bin/false {user}\n")
f.write(f"RUN echo \"{p}\\n{p}\\n\" | pdbedit -s smb.conf -a {user}\n")
with open("nas/smb.conf", "a") as f:
for mnt in cfg["nas"]["mounts"]:
f.write(f"[{mnt}]\n")
f.write(f"path = /mnt/{mnt}\n\n")
def run(cmds):
try:
subprocess.check_output(["ssh", f"core@{cfg["core"]["hostname"]}.local", ";".join(cmds)], stderr=subprocess.STDOUT)
@ -64,6 +80,7 @@ if __name__ == "__main__":
# 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...
# run builds
for user in IMAGES:

View File

@ -1,7 +1 @@
FROM docker.io/gitea/gitea:1.23.7
# After boot, recommended to modify the following in gitea/conf/app.ini
# SSH_LISTEN_PORT=2222
# DISABLE_REGISTRATION=true
# ENABLE_OPENID_SIGNIN=false
# ENABLE_OPENID_SIGNUP=false

View File

@ -1,20 +0,0 @@
FROM ubuntu:24.04
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y samba
# create required files and user
RUN groupadd -g 2003 me && useradd -u 2003 -g 2003 -m me
USER me
WORKDIR /home/me
RUN mkdir share samba samba/log samba/lock samba/state samba/cache samba/pid samba/private samba/ncalrpc
COPY --chown=me:me smb.conf entry.sh ./
# create additional users
USER root
COPY users.sh ./
RUN /bin/sh users.sh && rm users.sh
USER me

15
nas/Dockerfile.template Normal file
View File

@ -0,0 +1,15 @@
FROM ubuntu:24.04
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y samba
WORKDIR /root
COPY smb.conf entry.sh ./
CMD ["/bin/bash", "/root/entry.sh"]
# create users

View File

@ -1,6 +1,6 @@
#!/bin/sh
smbd -s smb.conf -l=/home/me/samba/log
trap 'echo "stopping smbd..."' TERM
smbd -s smb.conf
trap 'echo "stopping smbd..."' SIGTERM SIGINT
tail -f /dev/null &
wait $!

View File

@ -1,6 +1,6 @@
[global]
workgroup = WORKGROUP
smb ports = 8445
smb ports = 445
load printers = no
disable spoolss = yes
@ -22,19 +22,12 @@ client smb3 signing algorithms = AES-128-GMAC AES-128-CMAC HMAC-SHA256
client signing = required
client ipc signing = required
lock directory = /home/me/samba/lock
state directory = /home/me/samba/state
cache directory = /home/me/samba/cache
pid directory = /home/me/samba/pid
private dir = /home/me/samba/private
ncalrpc dir = /home/me/samba/ncalrpc
browseable = yes
writable = yes
create mask = 0660
directory mask = 0770
force user = me
force group = me
force user = root
force group = root
vfs objects = fruit streams_xattr
fruit:metadata = stream