4 Commits

7 changed files with 1509 additions and 1018 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ target
*peachdeploy.sh *peachdeploy.sh
*vpsdeploy.sh *vpsdeploy.sh
*bindeploy.sh *bindeploy.sh
tinstall.sh

2281
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[workspace] [workspace]
members = [ members = [
"peach-oled", # "peach-oled",
"peach-lib", "peach-lib",
"peach-config", "peach-config",
"peach-network", "peach-network",

219
install.sh Normal file
View File

@ -0,0 +1,219 @@
#!/bin/bash
set -e
#=============================
# BASIC CONFIGURATION
#=============================
# change the following with your configs
PASSWORD="changeme" # You should override this
DOMAIN=zpub.commoninternet.net
PORT=8000
PORT_SSB=8008
# these configs are probably fine as they are
APP="peach"
INSTALL_DIR="/opt/$APP"
TILDE_DIR="$INSTALL_DIR/.ssb-tilde"
PEACH_WEB_SERVICE="${APP}-peach-web"
TILDE_SBOT_SERVICE="${APP}-tilde-sbot"
GITHUB_BASE_URL="https://raw.githubusercontent.com/YunoHost-Apps/peachpub_ynh/refs/heads/master/conf/"
# Create app user if not exists
if ! id "$APP" &>/dev/null; then
useradd --system --create-home --shell /bin/bash "$APP"
fi
#=============================
# MAKE DIRECTORIES
#=============================
mkdir -p $INSTALL_DIR "$INSTALL_DIR/config" "$TILDE_DIR"
#=============================
# DOWNLOAD AND VERIFY SOURCE
#=============================
echo "Detecting architecture..."
ARCH=$(dpkg --print-architecture)
case "$ARCH" in
amd64)
ARCH_URL="https://files.commoninternet.net/assets/releases/peachpub-0.7.0~ynh1-amd64.tar.gz"
ARCH_SHA256="178750af87ba2ec2fc2778ad9031870224b85e6aaf85716aab0375c1077af80a"
;;
arm64)
ARCH_URL="https://files.commoninternet.net/assets/releases/peachpub-0.7.0~ynh1-arm64.tar.gz"
ARCH_SHA256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac
TMP_TAR="/tmp/${APP}.tar.gz"
echo "Downloading from $ARCH_URL..."
curl -fsSL "$ARCH_URL" -o "$TMP_TAR"
echo "Verifying checksum..."
DOWNLOADED_HASH=$(sha256sum "$TMP_TAR" | awk '{print $1}')
if [ "$DOWNLOADED_HASH" != "$ARCH_SHA256" ]; then
echo "Checksum mismatch!"
echo "Expected: $ARCH_SHA256"
echo "Got: $DOWNLOADED_HASH"
exit 1
fi
echo "Checksum verified. Extracting to $INSTALL_DIR..."
mkdir -p "$INSTALL_DIR"
tar -xzf "$TMP_TAR" -C "$INSTALL_DIR"
rm "$TMP_TAR"
#=============================
# DOWNLOAD CONF FILES
#=============================
download_and_template() {
local template_name="$1"
local destination="$2"
echo "Downloading and templating $template_name -> $destination"
curl -fsSL "$GITHUB_BASE_URL/$template_name" -o "$destination"
sed -i "s|__APP__|$APP|g" "$destination"
sed -i "s|__DOMAIN__|$DOMAIN|g" "$destination"
sed -i "s|__PORT__|$PORT|g" "$destination"
sed -i "s|__SSB_PORT__|$SSB_PORT|g" "$destination"
sed -i "s|__INSTALL_DIR__|$INSTALL_DIR|g" "$destination"
sed -i "s|__PEACH_WEB_SERVICE__|$PEACH_WEB_SERVICE|g" "$destination"
sed -i "s|__TILDE_SBOT_SERVICE__|$TILDE_SBOT_SERVICE|g" "$destination"
sed -i "s|__TILDE_DIR__|$TILDE_DIR|g" "$destination"
sed -i "s|__PASSWORD__|$PASSWORD|g" "$destination"
}
# download config files
download_and_template "tilde-sbot.toml" "$TILDE_DIR/tilde-sbot.toml"
download_and_template "peach.yml" "$INSTALL_DIR/config/config.yml"
# permissions
chmod -R u+rwX,g+rwX $INSTALL_DIR
chown -R "$APP:$APP" $INSTALL_DIR
# download sudoers file that allows peach-web to stop and restart tilde-sbot
mkdir -p /etc/sudoers.d/
download_and_template "sudoers" "/etc/sudoers.d/$APP"
chmod 440 "/etc/sudoers.d/$APP"
chown root:root "/etc/sudoers.d/$APP"
# #=============================
# # LOGGING
# #=============================
mkdir -p "/var/log/$APP"
touch "/var/log/$APP/$PEACH_WEB_SERVICE.log"
touch "/var/log/$APP/$TILDE_SBOT_SERVICE.log"
chown -R "$APP:$APP" "/var/log/$APP"
#=============================
# SYSTEMD SETUP
#=============================
download_and_template "peach-web.service" "/etc/systemd/system/$PEACH_WEB_SERVICE.service"
download_and_template "tilde-sbot.service" "/etc/systemd/system/$TILDE_SBOT_SERVICE.service"
systemctl daemon-reexec
systemctl daemon-reload
systemctl enable --now "$TILDE_SBOT_SERVICE"
systemctl enable --now "$PEACH_WEB_SERVICE"
#=============================
# PASSWORD SETUP
#=============================
chmod 770 "$INSTALL_DIR/peach-web"
PEACH_CONFIGDIR="$INSTALL_DIR/config" PEACH_CONFIG_PATH="$INSTALL_DIR/config/config.yml" \
"$INSTALL_DIR/peach-web" change-password "$PASSWORD"
chown -R "$APP:$APP" "$INSTALL_DIR"
chmod -R u+rwX,g+rwX "$INSTALL_DIR"
#=============================
# INSTALL AND CONFIGURE NGINX
#=============================
apt-get update
apt-get install -y nginx
NGINX_CONF="/etc/nginx/sites-available/${APP}"
mkdir -p /var/www/html
#-------------------------------
# Write HTTP-only config
#-------------------------------
cat > "$NGINX_CONF" <<EOF
server {
listen 80;
server_name $DOMAIN;
access_log /var/log/nginx/${APP}_access.log;
error_log /var/log/nginx/${APP}_error.log;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
proxy_set_header Accept-Encoding "";
try_files \$uri @proxy;
}
location @proxy {
proxy_pass http://localhost:$PORT;
proxy_set_header Host \$host;
proxy_set_header X-Forwarded-Host \$host;
proxy_set_header X-Forwarded-For \$remote_addr:\$remote_port;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_http_version 1.1;
}
}
EOF
ln -sf "$NGINX_CONF" "/etc/nginx/sites-enabled/${APP}"
echo "Testing and reloading HTTP nginx config..."
nginx -t && systemctl reload nginx
#-------------------------------
# RUN CERTBOT, WHICH WILL AUTOMATICALLY ADD HTTPS TO NGINX CONF IF IT SUCCEEDS
#-------------------------------
echo "installing certbot"
apt-get install -y certbot python3-certbot-nginx
# NOTE: if your domain was not properly configured before running install script,
# then you will need to re-run this certbot command after configuring your domain
echo "Attempting to request TLS certificate for $DOMAIN..."
if certbot --nginx --non-interactive --agree-tos --email "admin@$DOMAIN" -d "$DOMAIN"; then
echo "✔️ Certbot succeeded. linking HTTPS config..."
nginx -t && systemctl reload nginx
else
echo "⚠warning: Certbot failed. Skipping HTTPS. App will be available on HTTP only."
fi
#-------------------------------
# Auto-renew Cron
#-------------------------------
echo "Setting up certbot auto-renewal..."
echo "0 0 * * * root /usr/bin/certbot renew --quiet && /bin/systemctl reload nginx" > /etc/cron.d/certbot-renew
chmod 644 /etc/cron.d/certbot-renew
#=============================
# FINALIZE
#=============================
# NOTE ABOUT FAIL2BAN:
# logrotate and fail2ban not configured in this script
# example fail2ban regex is here if you want to configure manually
# https://github.com/YunoHost-Apps/peachpub_ynh/blob/a628312dc99425b158875fc1a5fe7ffc6da1be1a/scripts/install#L83
echo "☀ installation of $APP completed successfully ☀"

View File

@ -53,3 +53,4 @@ jsonrpc_client = { version = "0.7", features = ["macros", "reqwest"] }
reqwest = "0.11.24" reqwest = "0.11.24"
urlencoding = "2.1.3" urlencoding = "2.1.3"
rpassword = "5.0" rpassword = "5.0"
openssl = { version = '0.10', features = ["vendored"] }

View File

@ -1,4 +1,4 @@
use log::debug; use log::{debug, info};
use maud::{html, PreEscaped}; use maud::{html, PreEscaped};
use peach_lib::password_utils; use peach_lib::password_utils;
use rouille::{post_input, try_or_400, Request, Response}; use rouille::{post_input, try_or_400, Request, Response};
@ -73,7 +73,11 @@ pub fn handle_form(request: &Request, session_data: &mut Option<SessionData>) ->
Response::redirect_303("/") Response::redirect_303("/")
} }
Err(err) => { Err(err) => {
debug!("Unsuccessful login attempt"); let x_forwarded_for = request.header("X-Forwarded-For");
let real_ip = x_forwarded_for
.and_then(|ips| ips.split(':').next().and_then(|ip| Some(ip.to_string())))
.unwrap_or_else(|| request.remote_addr().ip().to_string());
info!("Unsuccessful login attempt from {:?}", real_ip);
let err_msg = format!("Invalid password: {}", err); let err_msg = format!("Invalid password: {}", err);
let (flash_name, flash_msg) = ( let (flash_name, flash_msg) = (
"error".to_string(), "error".to_string(),

View File

@ -31,13 +31,14 @@ echo "ARGS: $ARGS"
[ -n "$NETWORK_KEY" ] && echo "NETWORK_KEY: $NETWORK_KEY" [ -n "$NETWORK_KEY" ] && echo "NETWORK_KEY: $NETWORK_KEY"
[ -n "$DATABASE_DIRECTORY" ] && echo "DATABASE_DIRECTORY: $DATABASE_DIRECTORY" [ -n "$DATABASE_DIRECTORY" ] && echo "DATABASE_DIRECTORY: $DATABASE_DIRECTORY"
CMD="\"$TILDEFRIENDS_PATH\" run" # build and exec the command
[ -n "$ARGS" ] && CMD="$CMD -a \"$ARGS\"" CMD=("$TILDEFRIENDS_PATH" run)
[ -n "$NETWORK_KEY" ] && CMD="$CMD -k \"$NETWORK_KEY\"" [ -n "$ARGS" ] && CMD+=(-a "$ARGS")
[ -n "$DATABASE_DIRECTORY" ] && CMD="$CMD -d \"$DATABASE_DIRECTORY/db.sqlite\"" [ -n "$NETWORK_KEY" ] && CMD+=(-k "$NETWORK_KEY")
[ -n "$DATABASE_DIRECTORY" ] && CMD+=(-d "$DATABASE_DIRECTORY/db.sqlite")
echo "Running command:" echo "Running command:"
echo "$CMD" printf "%q " "${CMD[@]}"
echo
# Execute the command exec "${CMD[@]}"
eval $CMD