330 lines
10 KiB
Bash
330 lines
10 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# Copyright (c) 2021-2026 community-scripts ORG
|
|
# Author: ProxmoxVED Community
|
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
# Source: https://aliasvault.net
|
|
|
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
|
color
|
|
verb_ip6
|
|
catch_errors
|
|
setting_up_container
|
|
network_check
|
|
update_os
|
|
|
|
msg_info "Installing Dependencies"
|
|
$STD apt install -y \
|
|
nginx \
|
|
python3 \
|
|
build-essential \
|
|
gettext-base \
|
|
inotify-tools \
|
|
libkrb5-3 \
|
|
libgssapi-krb5-2 \
|
|
openssl
|
|
# Ensure cc linker is available — update-alternatives may not run in minimal LXC
|
|
[[ ! -e /usr/bin/cc ]] && ln -sf /usr/bin/gcc /usr/local/bin/cc
|
|
msg_ok "Installed Dependencies"
|
|
|
|
setup_rust
|
|
fetch_and_deploy_gh_release "wasm-pack" "rustwasm/wasm-pack" "prebuild" "latest" "/usr/local/bin" "wasm-pack-v*-x86_64-unknown-linux-musl.tar.gz"
|
|
|
|
NODE_VERSION="20" setup_nodejs
|
|
|
|
msg_info "Installing .NET SDK 10.0"
|
|
setup_deb822_repo "microsoft-prod" \
|
|
"https://packages.microsoft.com/keys/microsoft.asc" \
|
|
"https://packages.microsoft.com/debian/12/prod" \
|
|
"bookworm" \
|
|
"main" \
|
|
"amd64"
|
|
$STD apt install -y dotnet-sdk-10.0
|
|
msg_ok "Installed .NET SDK 10.0"
|
|
|
|
PG_VERSION="16" setup_postgresql
|
|
PG_DB_NAME="aliasvault" PG_DB_USER="aliasvault" setup_postgresql_db
|
|
|
|
fetch_and_deploy_gh_release "aliasvault" "aliasvault/aliasvault" "tarball"
|
|
|
|
msg_info "Building Core Libraries (Patience)"
|
|
source "$HOME/.cargo/env"
|
|
$STD rustup target add wasm32-unknown-unknown
|
|
cd /opt/aliasvault/core
|
|
$STD bash build-and-distribute.sh --browser
|
|
msg_ok "Built Core Libraries"
|
|
|
|
msg_info "Copying Core Artifacts"
|
|
mkdir -p /opt/aliasvault/apps/server/AliasVault.Client/wwwroot/wasm
|
|
cp /opt/aliasvault/core/rust/dist/wasm/aliasvault_core_bg.wasm \
|
|
/opt/aliasvault/apps/server/AliasVault.Client/wwwroot/wasm/
|
|
cp /opt/aliasvault/core/rust/dist/wasm/aliasvault_core.js \
|
|
/opt/aliasvault/apps/server/AliasVault.Client/wwwroot/wasm/
|
|
mkdir -p /opt/aliasvault/apps/server/AliasVault.Client/wwwroot/js/dist/core/{identity-generator,password-generator,vault}
|
|
cp -r /opt/aliasvault/core/typescript/identity-generator/dist/. \
|
|
/opt/aliasvault/apps/server/AliasVault.Client/wwwroot/js/dist/core/identity-generator/
|
|
cp -r /opt/aliasvault/core/typescript/password-generator/dist/. \
|
|
/opt/aliasvault/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/
|
|
cp -r /opt/aliasvault/core/vault/dist/. \
|
|
/opt/aliasvault/apps/server/AliasVault.Client/wwwroot/js/dist/core/vault/
|
|
msg_ok "Copied Core Artifacts"
|
|
|
|
msg_info "Building AliasVault Applications (Patience)"
|
|
cd /opt/aliasvault/apps/server
|
|
$STD dotnet workload install wasm-tools
|
|
$STD dotnet restore aliasvault.sln
|
|
$STD dotnet publish AliasVault.Api/AliasVault.Api.csproj \
|
|
-c Release -o /opt/aliasvault/api --no-restore
|
|
$STD dotnet build AliasVault.Client/AliasVault.Client.csproj \
|
|
-c Release --no-restore
|
|
$STD dotnet publish AliasVault.Client/AliasVault.Client.csproj \
|
|
-c Release -o /opt/aliasvault/client --no-restore
|
|
# Clear the hardcoded localhost:5092 API URL so the client uses its own origin + /api/
|
|
# Also remove pre-compressed copies so nginx (gzip_static on) serves the patched file
|
|
python3 -c "
|
|
import json, pathlib
|
|
p = pathlib.Path('/opt/aliasvault/client/wwwroot/appsettings.json')
|
|
c = json.loads(p.read_text()); c['ApiUrl'] = ''; p.write_text(json.dumps(c, indent=2))
|
|
for ext in ['.gz', '.br']:
|
|
q = pathlib.Path(str(p) + ext)
|
|
if q.exists(): q.unlink()
|
|
"
|
|
$STD dotnet publish AliasVault.Admin/AliasVault.Admin.csproj \
|
|
-c Release -o /opt/aliasvault/admin --no-restore
|
|
$STD dotnet publish Services/AliasVault.SmtpService/AliasVault.SmtpService.csproj \
|
|
-c Release -o /opt/aliasvault/smtp --no-restore
|
|
$STD dotnet publish Services/AliasVault.TaskRunner/AliasVault.TaskRunner.csproj \
|
|
-c Release -o /opt/aliasvault/taskrunner --no-restore
|
|
$STD dotnet publish Utilities/AliasVault.InstallCli/AliasVault.InstallCli.csproj \
|
|
-c Release -o /opt/aliasvault/installcli --no-restore
|
|
msg_ok "Built AliasVault Applications"
|
|
|
|
msg_info "Generating Secrets and Configuration"
|
|
ADMIN_PASS=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c 16)
|
|
ADMIN_HASH=$(dotnet /opt/aliasvault/installcli/AliasVault.InstallCli.dll hash-password "$ADMIN_PASS")
|
|
ADMIN_GENERATED=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
JWT_KEY=$(openssl rand -base64 32)
|
|
DATA_PROTECTION_CERT_PASS=$(openssl rand -base64 32)
|
|
DB_CONN="Host=localhost;Port=5432;Database=aliasvault;Username=aliasvault;Password=${PG_DB_PASS};Maximum Pool Size=80;Minimum Pool Size=5"
|
|
cat <<EOF >/opt/aliasvault/.env
|
|
ConnectionStrings__AliasServerDbContext=${DB_CONN}
|
|
JWT_KEY=${JWT_KEY}
|
|
DATA_PROTECTION_CERT_PASS=${DATA_PROTECTION_CERT_PASS}
|
|
ADMIN_PASSWORD_HASH=${ADMIN_HASH}
|
|
ADMIN_PASSWORD_GENERATED=${ADMIN_GENERATED}
|
|
PUBLIC_REGISTRATION_ENABLED=true
|
|
IP_LOGGING_ENABLED=true
|
|
PRIVATE_EMAIL_DOMAINS=
|
|
HIDDEN_PRIVATE_EMAIL_DOMAINS=
|
|
MAX_UPLOAD_SIZE_MB=100
|
|
SMTP_TLS_ENABLED=false
|
|
Logging__LogLevel__Default=Error
|
|
Logging__LogLevel__Microsoft__Hosting__Lifetime=Error
|
|
Logging__LogLevel__Microsoft=Error
|
|
EOF
|
|
chmod 600 /opt/aliasvault/.env
|
|
msg_ok "Generated Secrets and Configuration"
|
|
|
|
msg_info "Generating SSL Certificate"
|
|
mkdir -p /opt/aliasvault/certificates/ssl
|
|
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
|
-keyout /opt/aliasvault/certificates/ssl/key.pem \
|
|
-out /opt/aliasvault/certificates/ssl/cert.pem \
|
|
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=${LOCAL_IP}" \
|
|
-addext "subjectAltName=IP:${LOCAL_IP},DNS:localhost,IP:127.0.0.1" \
|
|
2>/dev/null
|
|
chmod 600 /opt/aliasvault/certificates/ssl/key.pem
|
|
chmod 644 /opt/aliasvault/certificates/ssl/cert.pem
|
|
msg_ok "Generated SSL Certificate"
|
|
|
|
msg_info "Configuring Nginx"
|
|
rm -f /etc/nginx/sites-enabled/default
|
|
cat <<'NGINXEOF' >/etc/nginx/sites-available/aliasvault
|
|
map $http_upgrade $connection_upgrade {
|
|
default upgrade;
|
|
'' close;
|
|
}
|
|
|
|
upstream aliasvault_api { server 127.0.0.1:3001 max_fails=1 fail_timeout=5s; }
|
|
upstream aliasvault_admin { server 127.0.0.1:3002 max_fails=1 fail_timeout=5s; }
|
|
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name _;
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl;
|
|
listen [::]:443 ssl;
|
|
server_name _;
|
|
|
|
ssl_certificate /opt/aliasvault/certificates/ssl/cert.pem;
|
|
ssl_certificate_key /opt/aliasvault/certificates/ssl/key.pem;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
client_max_body_size 100M;
|
|
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
|
|
include /etc/nginx/mime.types;
|
|
default_type application/octet-stream;
|
|
|
|
# .mjs files must be served as text/javascript for dynamic import() to work
|
|
types {
|
|
application/javascript mjs;
|
|
}
|
|
|
|
gzip on;
|
|
gzip_vary on;
|
|
gzip_proxied any;
|
|
gzip_comp_level 6;
|
|
gzip_types text/plain text/css application/json application/javascript
|
|
text/xml application/xml application/wasm;
|
|
|
|
# API
|
|
location /api {
|
|
proxy_pass http://aliasvault_api;
|
|
proxy_set_header Host $http_host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_intercept_errors on;
|
|
error_page 502 503 504 =503 @unavailable;
|
|
}
|
|
|
|
# Admin (Blazor Server — needs WebSocket)
|
|
location /admin {
|
|
proxy_pass http://aliasvault_admin;
|
|
proxy_set_header Host $http_host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Prefix /admin/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection $connection_upgrade;
|
|
proxy_read_timeout 86400;
|
|
proxy_intercept_errors on;
|
|
error_page 502 503 504 =503 @unavailable;
|
|
}
|
|
|
|
# Blazor WASM client (static files)
|
|
root /opt/aliasvault/client/wwwroot;
|
|
location / {
|
|
gzip_static on;
|
|
try_files $uri $uri/ /index.html =404;
|
|
}
|
|
|
|
location @unavailable {
|
|
return 503 "Service temporarily unavailable";
|
|
}
|
|
}
|
|
NGINXEOF
|
|
ln -sf /etc/nginx/sites-available/aliasvault /etc/nginx/sites-enabled/aliasvault
|
|
$STD nginx -t
|
|
systemctl enable -q --now nginx
|
|
$STD nginx -s reload
|
|
msg_ok "Configured Nginx"
|
|
|
|
mkdir -p /opt/certificates/app
|
|
|
|
msg_info "Creating Services"
|
|
cat <<EOF >/etc/systemd/system/aliasvault-api.service
|
|
[Unit]
|
|
Description=AliasVault API
|
|
After=network.target postgresql.service
|
|
Requires=postgresql.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
WorkingDirectory=/opt/aliasvault/api
|
|
EnvironmentFile=/opt/aliasvault/.env
|
|
Environment=ASPNETCORE_URLS=http://127.0.0.1:3001
|
|
Environment=ASPNETCORE_PATHBASE=/api
|
|
ExecStart=/usr/bin/dotnet AliasVault.Api.dll
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
cat <<EOF >/etc/systemd/system/aliasvault-admin.service
|
|
[Unit]
|
|
Description=AliasVault Admin
|
|
After=network.target aliasvault-api.service
|
|
Wants=aliasvault-api.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
WorkingDirectory=/opt/aliasvault/admin
|
|
EnvironmentFile=/opt/aliasvault/.env
|
|
Environment=ASPNETCORE_URLS=http://127.0.0.1:3002
|
|
Environment=ASPNETCORE_PATHBASE=/admin
|
|
ExecStart=/usr/bin/dotnet AliasVault.Admin.dll
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
StartLimitIntervalSec=0
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
cat <<EOF >/etc/systemd/system/aliasvault-smtp.service
|
|
[Unit]
|
|
Description=AliasVault SMTP Service
|
|
After=network.target aliasvault-api.service
|
|
Requires=aliasvault-api.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
WorkingDirectory=/opt/aliasvault/smtp
|
|
EnvironmentFile=/opt/aliasvault/.env
|
|
ExecStart=/usr/bin/dotnet AliasVault.SmtpService.dll
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
cat <<EOF >/etc/systemd/system/aliasvault-taskrunner.service
|
|
[Unit]
|
|
Description=AliasVault Task Runner
|
|
After=network.target aliasvault-api.service
|
|
Requires=aliasvault-api.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
WorkingDirectory=/opt/aliasvault/taskrunner
|
|
EnvironmentFile=/opt/aliasvault/.env
|
|
ExecStart=/usr/bin/dotnet AliasVault.TaskRunner.dll
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
systemctl enable -q --now aliasvault-api aliasvault-admin aliasvault-smtp aliasvault-taskrunner
|
|
msg_ok "Created Services"
|
|
|
|
{
|
|
echo ""
|
|
echo "AliasVault Admin Credentials:"
|
|
echo " Username: admin"
|
|
echo " Password: ${ADMIN_PASS}"
|
|
} >>~/aliasvault.creds
|
|
|
|
motd_ssh
|
|
customize
|
|
cleanup_lxc
|