diff --git a/src/debian/Containerfile b/src/debian/Containerfile index 2052a28..7023519 100644 --- a/src/debian/Containerfile +++ b/src/debian/Containerfile @@ -14,7 +14,7 @@ RUN rm /etc/localtime && \ # Install packages RUN apt update -y && \ apt upgrade -y && \ - apt install -y init sudo wget nano less man-db unzip && \ + apt install -y init sudo wget nano less man-db unzip rsync && \ apt autoremove -y --purge && \ apt clean -y diff --git a/src/debian/assets/bash.bashrc b/src/debian/assets/bash.bashrc index 4ca3e5d..e2f1090 100644 --- a/src/debian/assets/bash.bashrc +++ b/src/debian/assets/bash.bashrc @@ -83,4 +83,4 @@ fi alias ls='ls --color=auto' alias dir='ls -lFAh' -alias rsy='rsync -vaSH' +alias rsyn='rsync -vaSH' diff --git a/src/mailsrv/Containerfile b/src/mailsrv/Containerfile index 27f34e9..7a97424 100644 --- a/src/mailsrv/Containerfile +++ b/src/mailsrv/Containerfile @@ -26,7 +26,7 @@ ARG FILESUID=5000 ARG DEBIAN_FRONTEND=noninteractive # install packages we want -RUN apt update -y && apt install -y rsyslog postfix dovecot-imapd dovecot-lmtpd +RUN apt update -y && apt install -y rsyslog postfix dovecot-imapd dovecot-lmtpd dovecot-sieve # add virtual mail user RUN addgroup --gid ${FILESUID:?} vmail && \ diff --git a/src/mailsrv/assets/dovecot/conf.d/10-mail.conf b/src/mailsrv/assets/dovecot/conf.d/10-mail.conf index 337d8d5..98a397e 100644 --- a/src/mailsrv/assets/dovecot/conf.d/10-mail.conf +++ b/src/mailsrv/assets/dovecot/conf.d/10-mail.conf @@ -46,7 +46,7 @@ namespace inbox { # Hierarchy separator to use. You should use the same separator for all # namespaces or some clients get confused. '/' is usually a good one. # The default however depends on the underlying mail storage format. - #separator = + separator = / # Prefix required to access this namespace. This needs to be different for # all namespaces. For example "Public/". diff --git a/src/mailsrv/assets/dovecot/conf.d/15-mailboxes.conf b/src/mailsrv/assets/dovecot/conf.d/15-mailboxes.conf index bfc0a4d..d88460a 100644 --- a/src/mailsrv/assets/dovecot/conf.d/15-mailboxes.conf +++ b/src/mailsrv/assets/dovecot/conf.d/15-mailboxes.conf @@ -54,6 +54,9 @@ namespace inbox { mailbox Trash { special_use = \Trash } + mailbox Archive { + special_use = \Archive + } # For \Sent mailboxes there are two widely used names. We'll mark both of # them as \Sent. User typically deletes one of them if duplicates are created. diff --git a/src/mailsrv/assets/dovecot/conf.d/20-lmtp.conf b/src/mailsrv/assets/dovecot/conf.d/20-lmtp.conf index 7acbfed..d18433b 100644 --- a/src/mailsrv/assets/dovecot/conf.d/20-lmtp.conf +++ b/src/mailsrv/assets/dovecot/conf.d/20-lmtp.conf @@ -25,5 +25,5 @@ lda_mailbox_autosubscribe = yes protocol lmtp { # Space separated list of plugins to load (default is global mail_plugins). - #mail_plugins = $mail_plugins + mail_plugins = $mail_plugins sieve } diff --git a/src/minecraft_be/Containerfile b/src/minecraft_be/Containerfile new file mode 100644 index 0000000..59c9af7 --- /dev/null +++ b/src/minecraft_be/Containerfile @@ -0,0 +1,51 @@ +### +### Build Variables +### +FROM localhost/debian:latest + +# deploy options +# -p (port) and -v (volume) both go host:container +LABEL deployopts="\ +-p 19132:19132/udp \ +-p 19133:19133/udp \ +-v /srv/vol/minecraft_be/worlds:/vol/worlds" + +# Build variables +# uid that the files owner user should have +ARG FILESUID=5000 + +### +### General Setup +### + +# install packages we want +RUN apt update -y && apt install -y libcurl4 + +# create minecraft server user with file owner UID +RUN addgroup --gid $FILESUID mcadmin && \ + adduser mcadmin --ingroup mcadmin --uid $FILESUID --disabled-password --gecos "Minecraft Server Admin" --shell /usr/sbin/nologin && \ + rm /home/mcadmin/.bashrc + +# Copy custom scripts +COPY assets/bin/ /usr/local/bin/ + +### +### Minecraft +### +WORKDIR /home/mcadmin + +# download Minecraft Bedrock dedicated server +RUN url=$(wget -q https://www.minecraft.net/en-us/download/server/bedrock/ -O - | grep -Eo 'https://[^ ]+bin-linux/bedrock-server-[^ ]+\.zip' | head -n 1) && \ + wget $url && \ + unzip $(basename $url) && \ + rm $(basename $url) && \ + chown -R mcadmin:mcadmin ./ + +# copy minecraft config +COPY --chown=mcadmin:mcadmin assets/minecraft/ /home/mcadmin/ + +# copy units to systemd +COPY assets/systemd/ /etc/systemd/system/ + +# enable systemd units +RUN systemctl enable mcbe.service mcbe-backup.timer diff --git a/src/minecraft_be/assets/bin/mcbe-backup b/src/minecraft_be/assets/bin/mcbe-backup new file mode 100755 index 0000000..763da50 --- /dev/null +++ b/src/minecraft_be/assets/bin/mcbe-backup @@ -0,0 +1,40 @@ +#!/bin/bash + +do_backup() { + echo "Shutting down server for scheduled daily backup." + mcbe-shutdown 10 "Shutting down server for scheduled daily backup." + rsync -vaSH /home/mcadmin/worlds/ /vol/worlds/ + sleep 5 + echo "Restarting server after backup." + service mcbe start +} + +# Check if server is started +status=$(systemctl show mcbe -p ActiveState --value) +# Check if any players present +players=$(mcbe-exec list | cut -d ' ' -f 3 | cut -d '/' -f 1) +# check when mcbe-backup was last triggered +last=$(date -d "$(systemctl show mcbe-backup.timer -p LastTriggerUSec --value)" +%s) +# get current time +today=$(date +%s) + +# if service is not active, do backup immediately and exit +if [[ $status == inactive ]]; then + echo "Service is inactive: copying worlds immediately without restarting service." + rsync -vaSH /home/mcadmin/worlds/ /vol/worlds/ + +# if no players are present, do backup immediately and exit +elif [[ $players == 0 ]]; then + echo "No players detected: running backup immediately." + do_backup + +# if 12 or more hours have passed since backup was triggered, go ahead and force a shutdown anyways +elif [[ $(( $today - $last )) -ge 43200 ]]; then + echo "Backup was triggered more than 12 hours ago: forcing backup now." + do_backup + +# otherwise, schedule another attempt in an hour +else + echo "Players present in server: rescheduling backup to one hour from now." + systemd-run --on-active=1h $0 +fi diff --git a/src/minecraft_be/assets/bin/mcbe-exec b/src/minecraft_be/assets/bin/mcbe-exec new file mode 100755 index 0000000..38a9107 --- /dev/null +++ b/src/minecraft_be/assets/bin/mcbe-exec @@ -0,0 +1,5 @@ +#!/bin/bash +today=$(date "+%Y-%m-%d %H:%M:%S") +echo "$*" > /run/mcbe +sleep 0.1 +journalctl -u mcbe -S "$today" -o cat diff --git a/src/minecraft_be/assets/bin/mcbe-shutdown b/src/minecraft_be/assets/bin/mcbe-shutdown new file mode 100755 index 0000000..b22934f --- /dev/null +++ b/src/minecraft_be/assets/bin/mcbe-shutdown @@ -0,0 +1,36 @@ +#!/bin/bash + +if [[ -z $1 ]]; then + # default warning time is 10 seconds + time=10 +elif [[ $1 -ge 0 && $1 -le 60 ]]; then + time=$1 +else + echo "Invalid value for time-to-shutdown: only values between 0 and 60 seconds are accepted." + exit 2 +fi + +# if 2nd arg is given, say it before shutting down +if [[ -n $2 ]]; then + mcbe-exec say "$2" +fi + +echo "Shutting down server in $time seconds..." +count=$time + +while [[ $count -gt 0 ]]; do + # print warning every 10 seconds + if [[ $(( $count % 10 )) -eq 0 ]]; then + mcbe-exec say "Server shutting down in ${count} seconds!" + fi + + # print warning every second for last 5 seconds + if [[ $count -le 5 ]]; then + mcbe-exec say "Shutting down in ${count}s..." + fi + + count=$((count-1)) + sleep 1 +done + +systemctl stop mcbe diff --git a/src/minecraft_be/assets/minecraft/permissions.json b/src/minecraft_be/assets/minecraft/permissions.json new file mode 100644 index 0000000..d5a37be --- /dev/null +++ b/src/minecraft_be/assets/minecraft/permissions.json @@ -0,0 +1,6 @@ +[ + { + "permission" : "operator", + "xuid" : "2535473403284928" + } +] diff --git a/src/minecraft_be/assets/minecraft/server.properties b/src/minecraft_be/assets/minecraft/server.properties new file mode 100644 index 0000000..867be34 --- /dev/null +++ b/src/minecraft_be/assets/minecraft/server.properties @@ -0,0 +1,97 @@ +server-name=Living Lightning Server +# Used as the server name +# Allowed values: Any string + +gamemode=survival +# Sets the game mode for new players. +# Allowed values: "survival", "creative", or "adventure" + +difficulty=hard +# Sets the difficulty of the world. +# Allowed values: "peaceful", "easy", "normal", or "hard" + +allow-cheats=false +# If true then cheats like commands can be used. +# Allowed values: "true" or "false" + +max-players=10 +# The maximum number of players that can play on the server. +# Allowed values: Any positive integer + +online-mode=true +# If true then all connected players must be authenticated to Xbox Live. +# Clients connecting to remote (non-LAN) servers will always require Xbox Live authentication regardless of this setting. +# If the server accepts connections from the Internet, then it's highly recommended to enable online-mode. +# Allowed values: "true" or "false" + +white-list=true +# If true then all connected players must be listed in the separate whitelist.json file. +# Allowed values: "true" or "false" + +server-port=19132 +# Which IPv4 port the server should listen to. +# Allowed values: Integers in the range [1, 65535] + +server-portv6=19133 +# Which IPv6 port the server should listen to. +# Allowed values: Integers in the range [1, 65535] + +view-distance=80 +# The maximum allowed view distance in number of chunks. +# Allowed values: Any positive integer. + +tick-distance=8 +# The world will be ticked this many chunks away from any player. +# Allowed values: Integers in the range [4, 12] + +player-idle-timeout=30 +# After a player has idled for this many minutes they will be kicked. If set to 0 then players can idle indefinitely. +# Allowed values: Any non-negative integer. + +max-threads=8 +# Maximum number of threads the server will try to use. If set to 0 or removed then it will use as many as possible. +# Allowed values: Any positive integer. + +level-name=Glunge Drip +# Allowed values: Any string + +level-seed= +# Use to randomize the world +# Allowed values: Any string + +default-player-permission-level=member +# Permission level for new players joining for the first time. +# Allowed values: "visitor", "member", "operator" + +texturepack-required=false +# Force clients to use texture packs in the current world +# Allowed values: "true" or "false" + +content-log-file-enabled=false +# Enables logging content errors to a file +# Allowed values: "true" or "false" + +compression-threshold=1 +# Determines the smallest size of raw network payload to compress +# Allowed values: 0-65535 + +server-authoritative-movement=true +# Enables server authoritative movement. If true, the server will replay local user input on +# the server and send down corrections when the client's position doesn't match the server's. +# Corrections will only happen if correct-player-movement is set to true. + +player-movement-score-threshold=20 +# The number of incongruent time intervals needed before abnormal behavior is reported. +# Disabled by server-authoritative-movement. + +player-movement-distance-threshold=0.3 +# The difference between server and client positions that needs to be exceeded before abnormal behavior is detected. +# Disabled by server-authoritative-movement. + +player-movement-duration-threshold-in-ms=500 +# The duration of time the server and client positions can be out of sync (as defined by player-movement-distance-threshold) +# before the abnormal movement score is incremented. This value is defined in milliseconds. +# Disabled by server-authoritative-movement. + +correct-player-movement=false +# If true, the client position will get corrected to the server position if the movement score exceeds the threshold. diff --git a/src/minecraft_be/assets/minecraft/whitelist.json b/src/minecraft_be/assets/minecraft/whitelist.json new file mode 100644 index 0000000..580734f --- /dev/null +++ b/src/minecraft_be/assets/minecraft/whitelist.json @@ -0,0 +1 @@ +[{ignoresPlayerLimit:false,name:MarVel0z,xuid:2535473403284928},{ignoresPlayerLimit:false,name:BISONMEATS},{ignoresPlayerLimit:false},{ignoresPlayerLimit:false,name:TrinityAri,xuid:2535422548094088},{ignoresPlayerLimit:false,name:Marcade645},{ignoresPlayerLimit:false,name:JogsIntoMordor}] diff --git a/src/minecraft_be/assets/systemd/mcbe-backup.service b/src/minecraft_be/assets/systemd/mcbe-backup.service new file mode 100644 index 0000000..b1b0535 --- /dev/null +++ b/src/minecraft_be/assets/systemd/mcbe-backup.service @@ -0,0 +1,11 @@ +[Unit] +After=mcbe.service +Description=Backup Minecraft Bedrock Edition Server +Requisite=mcbe.service + +[Service] +ExecStart=/usr/local/bin/mcbe-backup +StandardOutput=journal +StandardError=journal +KillMode=none +Type=oneshot \ No newline at end of file diff --git a/src/minecraft_be/assets/systemd/mcbe-backup.timer b/src/minecraft_be/assets/systemd/mcbe-backup.timer new file mode 100644 index 0000000..7ae447a --- /dev/null +++ b/src/minecraft_be/assets/systemd/mcbe-backup.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Backup Minecraft Bedrock Edition Server daily at 4:05 AM + +[Timer] +# Every 2 hours: OnCalendar=0/2:00:00 +OnCalendar=*-*-* 04:05 + +[Install] +WantedBy=timers.target diff --git a/src/minecraft_be/assets/systemd/mcbe.service b/src/minecraft_be/assets/systemd/mcbe.service new file mode 100644 index 0000000..e0c003c --- /dev/null +++ b/src/minecraft_be/assets/systemd/mcbe.service @@ -0,0 +1,27 @@ +[Unit] +# Implicit needs are explicitly needed to survive shutdown till stop finishes +After=network.target +BindsTo=mcbe.socket +Description=Minecraft Bedrock Edition server + +[Service] +ExecReload=/bin/bash -c "echo reload > /run/mcb" +ExecStop=/bin/bash -c "echo stop > /run/mcb" +ExecStart=/bin/bash -c "LD_LIBRARY_PATH=. ./bedrock_server" +User=mcadmin +WorkingDirectory=/home/mcadmin +Restart=on-failure +StandardInput=socket +StandardOutput=journal +StandardError=journal +Type=simple +# Thanks for the security agowa338 +PrivateUsers=true +ProtectHome=true +ProtectControlGroups=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectSystem=full + +[Install] +WantedBy=multi-user.target diff --git a/src/minecraft_be/assets/systemd/mcbe.socket b/src/minecraft_be/assets/systemd/mcbe.socket new file mode 100644 index 0000000..6a951df --- /dev/null +++ b/src/minecraft_be/assets/systemd/mcbe.socket @@ -0,0 +1,8 @@ +[Unit] +BindsTo=mcbe.service + +[Socket] +ListenFIFO=/run/mcbe +RemoveOnStop=true +SocketMode=600 +SocketUser=mcadmin diff --git a/src/minecraft_bedrock/docs/resources.md b/src/minecraft_be/docs/resources.md similarity index 100% rename from src/minecraft_bedrock/docs/resources.md rename to src/minecraft_be/docs/resources.md diff --git a/src/minecraft_bedrock/Containerfile b/src/minecraft_bedrock/Containerfile deleted file mode 100644 index fbed82f..0000000 --- a/src/minecraft_bedrock/Containerfile +++ /dev/null @@ -1,77 +0,0 @@ -### -### Build Variables -### -FROM localhost/debian:latest - -# deploy options -# -p (port) and -v (volume) both go host:container -LABEL deployopts="\ --p 19132:19132/udp \ --p 19133:19133/udp \ --v /srv/vol/minecraft_bedrock/backup:/vol/backup" - -# Build variables -# uid that the files owner user should have -ARG FILESUID=5000 - -### -### General Setup -### - -# install packages we want -RUN apt update -y && apt install -y libcurl4 - -# create minecraft server user with file owner UID -RUN addgroup --gid $FILESUID mcadmin && \ - adduser mcadmin --ingroup mcadmin --uid $FILESUID --disabled-password --gecos "Minecraft Server Admin" --shell /usr/sbin/nologin && \ - rm /home/mcadmin/.bashrc - -### -### Minecraft -### - -# download Minecraft Bedrock dedicated server -RUN url=$(wget -q https://www.minecraft.net/en-us/download/server/bedrock/ -O - | grep -Eo 'https://[^ ]+bin-linux/bedrock-server-[^ ]+\.zip' | head -n 1) && \ - wget $url && \ - unzip $(basename $url) && \ - rm $(basename $url) - -### -### Gitea -### - -# dowload gitea -RUN wget https://dl.gitea.io/gitea/${giteav}/gitea-${giteav}-linux-amd64 && \ - mv gitea /usr/local/bin/gitea && \ - chmod +x /usr/local/bin/gitea - -# make directories gitea needs -RUN mkdir -p /var/lib/gitea/ && \ - cd /var/lib/gitea/ && \ - mkdir custom data log && \ - chown -R gitea:gitea /var/lib/gitea/ && \ - chmod -R 750 /var/lib/gitea/ - -# copy gitea config template -COPY assets/app.ini.esh /etc/gitea/ -# template config file -RUN cd /etc/gitea/ && \ - esh app.ini.esh > app.ini && \ - rm app.ini.esh && \ - chmod -R +r /etc/gitea/ - -COPY assets/gitea.service /etc/systemd/system/ - -### -### Crontab -### -COPY assets/crontab /root/ -RUN crontab -u gitea /root/crontab - -### -### Bugfix -### - -# execute command to workaround bug in cron -COPY bugfix/cronfix /root/ -RUN chmod +x /root/cronfix && /root/cronfix