bring guides from self hosted repo
This commit is contained in:
parent
8f7c589d03
commit
adef3f4ccc
16 changed files with 898 additions and 1 deletions
23
self-hosting/README.md
Normal file
23
self-hosting/README.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# self-hosted
|
||||
|
||||
## Description
|
||||
Aims to be a comprehensible guide to a self-hosted, FOSS digital presence.
|
||||
|
||||
## Roadmap
|
||||
- Fininsh scripting the Bypass CGNAT part.
|
||||
- Script the deployment of common apps for reproducibility.
|
||||
|
||||
## Authors and acknowledgment
|
||||
|
||||
I used these sources as a guide, documented steps and added useful configurations.
|
||||
|
||||
[mochman@github](https://github.com/mochman) - [Bypass CGNAT](https://github.com/mochman/Bypass_CGNAT)
|
||||
|
||||
[nerdonthestreet@github](https://github.com/nerdonthestreet) - [Install ONLYOFFICE on a Nextcloud Server](https://www.youtube.com/watch?v=Gc1zUmrxtKE)
|
||||
|
||||
[DenshiVideo](https://wiki.denshi.org/hypha/server/ejabberd) - [How to setup an XMPP server (ejabberd)](https://www.youtube.com/watch?v=rY0kRSj2rmU)
|
||||
|
||||
[Matthew Evan](https://github.com/MattMadness) - [landchad.net/nextcloud](https://landchad.net/nextcloud/)
|
||||
|
||||
## Project status
|
||||
Very early stages, doesn't work, use as a guide for manual implementation.
|
3
self-hosting/bypass-cgnat/README.md
Normal file
3
self-hosting/bypass-cgnat/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Bypass CGNAT
|
||||
Setup a wireguard VPN to route traffic from a VPS to your local machine.
|
||||
Based from [this](https://github.com/mochman/Bypass_CGNAT) guide.
|
|
@ -0,0 +1,7 @@
|
|||
Address = 10.0.0.2
|
||||
|
||||
[Peer]
|
||||
PublicKey = PUBLICKEY
|
||||
AllowedIPs = 10.0.0.1/32
|
||||
Endpoint = VPSIP:55107
|
||||
PersistentKeepalive = 25
|
|
@ -0,0 +1,6 @@
|
|||
ListenPort = 55107
|
||||
Address = 10.0.0.1/24
|
||||
|
||||
[Peer]
|
||||
PublicKey = PUBLICKEY
|
||||
AllowedIPs = 10.0.0.2/32
|
22
self-hosting/bypass-cgnat/iptables/iptables-down.sh
Normal file
22
self-hosting/bypass-cgnat/iptables/iptables-down.sh
Normal file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh
|
||||
|
||||
VPSINT="enp1s0"
|
||||
|
||||
TCP=$(cat /opt/wireguard/ports-tcp.txt)
|
||||
: "${tcpports:=$TCP}"
|
||||
for port in $tcpports; do
|
||||
iptables -D FORWARD -i "$VPSINT" -o wg0 -p tcp --syn --dport "$port" -m conntrack --ctstate NEW -j ACCEPT
|
||||
iptables -t nat -D PREROUTING -i "$VPSINT" -p tcp --dport "$port" -j DNAT --to-destination 10.0.0.2
|
||||
iptables -t nat -D POSTROUTING -o wg0 -p tcp --dport "$port" -d 10.0.0.2 -j SNAT --to-source 10.0.0.1
|
||||
ufw deny "$port"/tcp
|
||||
done
|
||||
|
||||
UDP=$(cat /opt/wireguard/ports-udp.txt)
|
||||
: "${udpports:=$UDP}"
|
||||
for port in $udpports; do
|
||||
iptables -D FORWARD -i "$VPSINT" -o wg0 -p udp --dport "$port" -m conntrack --ctstate NEW -j ACCEPT
|
||||
iptables -t nat -D PREROUTING -i "$VPSINT" -p udp --dport "$port" -j DNAT --to-destination 10.0.0.2
|
||||
iptables -t nat -D POSTROUTING -o wg0 -p udp --dport "$port" -d 10.0.0.2 -j SNAT --to-source 10.0.0.1
|
||||
ufw deny "$port"/udp
|
||||
done
|
||||
|
22
self-hosting/bypass-cgnat/iptables/iptables-up.sh
Normal file
22
self-hosting/bypass-cgnat/iptables/iptables-up.sh
Normal file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh
|
||||
|
||||
VPSINT="INTERFACE"
|
||||
|
||||
TCP=$(cat /opt/wireguard/ports-tcp.txt)
|
||||
: "${tcpports:=$TCP}"
|
||||
for port in $tcpports; do
|
||||
iptables -A FORWARD -i "$VPSINT" -o wg0 -p tcp --syn --dport "$port" -m conntrack --ctstate NEW -j ACCEPT
|
||||
iptables -t nat -A PREROUTING -i "$VPSINT" -p tcp --dport "$port" -j DNAT --to-destination 10.0.0.2
|
||||
iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport "$port" -d 10.0.0.2 -j SNAT --to-source 10.0.0.1
|
||||
ufw allow "$port"/tcp
|
||||
done
|
||||
|
||||
UDP=$(cat /opt/wireguard/ports-udp.txt)
|
||||
: "${udpports:=$UDP}"
|
||||
for port in $udpports; do
|
||||
iptables -A FORWARD -i "$VPSINT" -o wg0 -p udp --dport "$port" -m conntrack --ctstate NEW -j ACCEPT
|
||||
iptables -t nat -A PREROUTING -i "$VPSINT" -p udp --dport "$port" -j DNAT --to-destination 10.0.0.2
|
||||
iptables -t nat -A POSTROUTING -o wg0 -p udp --dport "$port" -d 10.0.0.2 -j SNAT --to-source 10.0.0.1
|
||||
ufw allow "$port"/udp
|
||||
done
|
||||
|
43
self-hosting/bypass-cgnat/local.sh
Normal file
43
self-hosting/bypass-cgnat/local.sh
Normal file
|
@ -0,0 +1,43 @@
|
|||
#!/bin/sh
|
||||
# Local utility for forwarding traffic through wireguard VPN
|
||||
#
|
||||
# Some code was borrowed from:
|
||||
# https://github.com/mochman/Bypass_CGNAT
|
||||
# and
|
||||
# https://www.youtube.com/watch?v=9tDeh9mutmI
|
||||
perms=$(umask)
|
||||
|
||||
print() {
|
||||
printf '\033[1m %b\033[0m%s\n\n' "$1"
|
||||
}
|
||||
|
||||
# Install wireguard
|
||||
printf "\nContinue ONLY is wireguard is installed [y/N] " && read -r check
|
||||
[ "$check" != "y" ] && exit
|
||||
|
||||
# Generate wireguard keys
|
||||
print "Generating wireguard configs..."
|
||||
sudo mkdir -p /etc/wireguard/
|
||||
umask 077 # perms for /etc/wireguard/* files
|
||||
printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null
|
||||
printf "\nCopy this key to server's setup (Press ENTER when done):\n> "
|
||||
sudo wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
|
||||
read -r NULL
|
||||
|
||||
# Make wireguard configuration with keys and write to /etc/wireguard/wg0.conf
|
||||
printf "\nEnter the generated Publickey from server:\n> " && read -r PUBKEY
|
||||
printf "\nEnter the VPS's public IP:\n> " && read -r VPSIP
|
||||
printf "Address = 10.0.0.2
|
||||
|
||||
[Peer]
|
||||
PublicKey = $PUBKEY
|
||||
AllowedIPs = 10.0.0.1/32
|
||||
Endpoint = $VPSIP:55107
|
||||
PersistentKeepalive = 25
|
||||
" | sudo tee -a /etc/wireguard/wg0.conf
|
||||
umask $perms # restore perms
|
||||
|
||||
# Start service
|
||||
#sudo systemctl start wg-quick@wg0
|
||||
printf "\nRun 'systemctl enable wg-quick@wg0' so the service starts automatically on boot.\n"
|
||||
printf "\nDone!\n"
|
64
self-hosting/bypass-cgnat/server.sh
Normal file
64
self-hosting/bypass-cgnat/server.sh
Normal file
|
@ -0,0 +1,64 @@
|
|||
#!/bin/sh
|
||||
# Server utility for forwarding traffic through wireguard VPN
|
||||
#
|
||||
# Some code was borrowed from:
|
||||
# https://github.com/mochman/Bypass_CGNAT
|
||||
# and
|
||||
# https://www.youtube.com/watch?v=9tDeh9mutmI
|
||||
perms=$(umask)
|
||||
|
||||
print() {
|
||||
printf '\033[1m %b\033[0m%s\n\n' "$1"
|
||||
}
|
||||
|
||||
# Enable forwarding FIX
|
||||
print "Enabling ip_forward..."
|
||||
cat /etc/sysctl.conf | sed "s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g" | sudo tee /etc/sysctl.conf
|
||||
sudo sysctl -p
|
||||
sudo sysctl --system
|
||||
|
||||
# Install wireguard
|
||||
print "Installing wireguard..."
|
||||
sudo apt-get install wireguard -y # Install wireguard
|
||||
ip a
|
||||
|
||||
# Prompt for required fields
|
||||
printf "\nEnter the VPS's public IP interface (see with 'ip a'):\n> " && read -r VPSINT
|
||||
|
||||
# Generate keys and write configuration to /etc/wireguard/wg0.conf
|
||||
print "Generating wireguard configs..."
|
||||
sudo mkdir -p /etc/wireguard/
|
||||
umask 077 # perms for /etc/wireguard/* files
|
||||
printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null
|
||||
sudo wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
|
||||
printf "\nEnter the generated /etc/wireguard/publickey from local machine:\n> " && read -r PUBKEY
|
||||
printf "ListenPort = 55107
|
||||
Address = 10.0.0.1/24
|
||||
|
||||
PostUp = /opt/wireguard/iptables-up.sh
|
||||
PostDown = /opt/wireguard/iptables-down.sh
|
||||
|
||||
[Peer]
|
||||
PublicKey = $PUBKEY
|
||||
AllowedIPs = 10.0.0.2/32
|
||||
" | sudo tee -a /etc/wireguard/wg0.conf
|
||||
printf "\nCopy this key to local machine's setup:\n> "
|
||||
sudo cat /etc/wireguard/publickey
|
||||
read -r NULL
|
||||
umask $perms # restore perms
|
||||
|
||||
# Start service
|
||||
print "Starting wg-quick@wg0..."
|
||||
sudo ufw allow 55107
|
||||
sudo systemctl start wg-quick@wg0
|
||||
|
||||
# iptables configuration
|
||||
print "Configuring iptables & ufw..."
|
||||
sudo iptables -P FORWARD DROP
|
||||
sudo iptables -A FORWARD -i "$VPSINT" -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
sudo iptables -A FORWARD -i wg0 -o "$VPSINT" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
sudo ufw status | grep -q "active" && sudo ufw reload
|
||||
|
||||
print "\nDone!\n"
|
||||
printf "Run 'systemctl enable wg-quick@wg0' so the service starts automatically on boot.\n\n"
|
149
self-hosting/services/ejabberd/README.md
Normal file
149
self-hosting/services/ejabberd/README.md
Normal file
|
@ -0,0 +1,149 @@
|
|||
# Enable ports
|
||||
|
||||
These are the ports needed for ejabberd to work.
|
||||
Ports 80 and 443 are needed for deploying and SSL certificate with certbot.
|
||||
|
||||
```shell
|
||||
declare -a ports=("80" "443" "5222:5443/udp" "5222:5443/tcp" "3478" "49152:65535/udp" "49152:65535/tcp")
|
||||
|
||||
for port in "${ports[@]}"; do ufw allow "$port" ; done
|
||||
ufw reload
|
||||
```
|
||||
|
||||
# Download ejabberd
|
||||
|
||||
Debian conveniently offers the packages in the official repositories!
|
||||
|
||||
```shell
|
||||
apt update
|
||||
apt install ejabberd python3-certbot-nginx
|
||||
systemctl enable --now ejabberd
|
||||
```
|
||||
|
||||
# Generate certs
|
||||
|
||||
This is from [Nerd on the Street](https://github.com/nerdonthestreet).
|
||||
Change the DOMAIN variable to your preference.
|
||||
|
||||
```shell
|
||||
DOMAIN="example.org"
|
||||
|
||||
# Set the domain names you want here, stun & turn are required for calls
|
||||
declare -a subdomains=("" "conference." "proxy." "pubsub." "upload." "stun." "turn.")
|
||||
|
||||
for i in "${subdomains[@]}"; do
|
||||
certbot --nginx -d $i$DOMAIN certonly
|
||||
mkdir -p /etc/ejabberd/certs/$i$DOMAIN
|
||||
cp /etc/letsencrypt/live/$i$DOMAIN/fullchain.pem /etc/ejabberd/certs/$i$DOMAIN
|
||||
cp /etc/letsencrypt/live/$i$DOMAIN/privkey.pem /etc/ejabberd/certs/$i$DOMAIN
|
||||
done
|
||||
```
|
||||
|
||||
# Directories and permissions
|
||||
|
||||
```shell
|
||||
chown -R ejabberd:ejabberd /etc/ejabberd/certs
|
||||
mkdir -p /var/www/upload
|
||||
chown -R ejabberd:ejabberd /var/www/upload
|
||||
```
|
||||
|
||||
# Base configuration
|
||||
|
||||
Fill with your domain.
|
||||
|
||||
```yaml
|
||||
hosts:
|
||||
- example.org
|
||||
```
|
||||
|
||||
Enable the path for previously generated certs.
|
||||
|
||||
```yaml
|
||||
certfiles:
|
||||
- "/etc/ejabberd/certs/*/*.pem"
|
||||
```
|
||||
|
||||
Note: Remember to `systemctl restart ejabberd` each time you modify `/etc/ejabberd.yml`.
|
||||
|
||||
# Example for some configs (optional)
|
||||
|
||||
## Admin user
|
||||
|
||||
Register admin user.
|
||||
|
||||
```shell
|
||||
su -c "ejabberdctl register admin example.org ADMIN_PASSWORD" ejabberd
|
||||
systemctl restart ejabberd
|
||||
```
|
||||
|
||||
Enable admin user.
|
||||
|
||||
```yaml
|
||||
acl:
|
||||
admin:
|
||||
user: admin
|
||||
```
|
||||
|
||||
## Message archive and http upload
|
||||
|
||||
Uncomment for compliance with XMPP standards.
|
||||
|
||||
```yaml
|
||||
mod_http_upload:
|
||||
put_url: https://@HOST@:5443/upload
|
||||
docroot: /var/www/upload
|
||||
custom_headers:
|
||||
"Access-Control-Allow-Origin": "https://@HOST@"
|
||||
"Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
|
||||
"Access-Control-Allow-Headers": "Content-Type"
|
||||
```
|
||||
|
||||
Enable message archive.
|
||||
|
||||
```yaml
|
||||
mod_mam:
|
||||
assume_mam_usage: true
|
||||
default: always
|
||||
```
|
||||
|
||||
## Postgresql database
|
||||
|
||||
Set postgresql as database.
|
||||
|
||||
```shell
|
||||
sudo -i -u postgres psql -c "CREATE USER ejabberd WITH PASSWORD 'DB_PASSWORD';"
|
||||
sudo -i -u postgres psql -c "CREATE DATABASE ejabberd OWNER ejabberd;"
|
||||
```
|
||||
|
||||
```yaml
|
||||
sql_type: pgsql
|
||||
sql_server: "localhost"
|
||||
sql_database: "ejabberd"
|
||||
sql_username: "ejabberd"
|
||||
sql_password: "DB_PASSWORD"
|
||||
default_db: sql
|
||||
```
|
||||
|
||||
## Call/Videocall support
|
||||
|
||||
Enable this module
|
||||
|
||||
```yaml
|
||||
ejabberd_stun:
|
||||
```
|
||||
|
||||
## Registration
|
||||
|
||||
Enable registration in your server
|
||||
|
||||
```yaml
|
||||
mod_register:
|
||||
```
|
||||
|
||||
Otherwise registered via:
|
||||
|
||||
```shell
|
||||
su -c "ejabberdctl register USERNAME example.org USER_PASSWORD" ejabberd
|
||||
```
|
||||
|
||||
Note: Remember to `systemctl restart ejabberd` each time you modify `/etc/ejabberd.yml`.
|
12
self-hosting/services/examplereverseproxy.conf
Normal file
12
self-hosting/services/examplereverseproxy.conf
Normal file
|
@ -0,0 +1,12 @@
|
|||
server {
|
||||
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name example.domain.xyz;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8080/;
|
||||
}
|
||||
|
||||
}
|
22
self-hosting/services/examplewebsite.conf
Normal file
22
self-hosting/services/examplewebsite.conf
Normal file
|
@ -0,0 +1,22 @@
|
|||
server {
|
||||
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name example.domain.xyz;
|
||||
|
||||
root /var/www/examplesite;
|
||||
|
||||
# Add index.php to the list if you are using PHP
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
#location ~ \.php$ {
|
||||
# include snippets/fastcgi-php.conf;
|
||||
# fastcgi_pass unix:/run/php/php7.4-fpm.sock;
|
||||
#}
|
||||
|
||||
}
|
235
self-hosting/services/nextcloud/README.md
Normal file
235
self-hosting/services/nextcloud/README.md
Normal file
|
@ -0,0 +1,235 @@
|
|||
# Ask for domain & database credentials
|
||||
printf "Domain name (e.g. cloud.example.com):\n * DNS records must already be set up!\n> " && read -r domain
|
||||
printf "nextcloud database admin username:\n> " && read -r nextcloud_db_admin
|
||||
printf "nextcloud database admin password:\n> " && read -r nextcloud_db_admin_pass
|
||||
|
||||
# Install dependencies
|
||||
|
||||
```shell
|
||||
apt install -y curl nginx python3-certbot-nginx postgresql php php-{fpm,bcmath,bz2,intl,gd,mbstring,pgsql,zip,xml,curl,imagick,gmp}
|
||||
```
|
||||
|
||||
For some reason that installs apache2, remove it as we don't need it.
|
||||
|
||||
```shell
|
||||
apt purge apache2
|
||||
apt autoremove
|
||||
```
|
||||
|
||||
### Check PHP version...
|
||||
|
||||
As of 2023-07-10, it's 8.2.
|
||||
You can also check with `ls /etc/php` by checking the version's folder name.
|
||||
|
||||
```shell
|
||||
php -v | grep -o '[0-9].*(cli)' | cut -d '.' -f 1,2
|
||||
```
|
||||
|
||||
# Set up postgresql database
|
||||
|
||||
```shell
|
||||
systemctl enable --now postgresql
|
||||
sudo -i -u postgres psql -c "CREATE USER nextcloud WITH PASSWORD 'DB_PASSWORD';"
|
||||
sudo -i -u postgres psql -c "CREATE DATABASE nextcloud TEMPLATE template0 ENCODING 'UTF8';"
|
||||
sudo -i -u postgres psql -c "ALTER DATABASE nextcloud OWNER TO nextcloud;"
|
||||
sudo -i -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE nextcloud TO nextcloud;"
|
||||
sudo -i -u postgres psql -c "GRANT ALL PRIVILEGES ON SCHEMA public TO nextcloud;"
|
||||
```
|
||||
|
||||
# Nginx configuration & cert
|
||||
I modified this config to be easily set up with SSL via certbot,
|
||||
but you can visit the following url for the official example:
|
||||
[Nextcloud's nginx example configuration](https://docs.nextcloud.com/server/19/admin_manual/installation/nginx.html).
|
||||
```shell
|
||||
curl -L nextcloud-nginx.tavo.one | sed "s/cloud.example.com/YOURDOMAIN/g" | tee /etc/nginx/sites-available/nextcloud.conf
|
||||
ln -s /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/
|
||||
systemctl restart nginx
|
||||
certbot -d YOURDOMAIN --nginx --register-unsafely-without-email --agree-tos
|
||||
```
|
||||
|
||||
# Download & extract latest nextcloud
|
||||
```shell
|
||||
wget -O /opt/nextcloud-$(date -I).tar.bz2 https://download.nextcloud.com/server/releases/latest.tar.bz2
|
||||
tar -xjf /opt/nextcloud-$(date -I).tar.bz2 -C /var/www
|
||||
```
|
||||
|
||||
# Permissions for www-data user & restart services
|
||||
```shell
|
||||
chown -R www-data:www-data /var/www/nextcloud
|
||||
chmod -R 755 /var/www/nextcloud
|
||||
systemctl enable --now php8.2-fpm
|
||||
systemctl enable --now nginx
|
||||
```
|
||||
|
||||
# Recommended modifications:
|
||||
|
||||
RECOMMENDED MODIFICATIONS TO ENHANCE
|
||||
SECURITY & PERFORMANCE:
|
||||
|
||||
I find it better to configure them
|
||||
one by one and troubleshoot each one
|
||||
separately that way!
|
||||
|
||||
## Tune php-fpm
|
||||
|
||||
Recommended settings for `/etc/php/8.2/fpm/pool.d/www.conf`
|
||||
This should get rid of the _'getenv("PATH") only returns an empty response'_
|
||||
overview panel notification, plus enhance performance.
|
||||
|
||||
```php
|
||||
pm = dynamic
|
||||
pm.max_children = 120
|
||||
pm.start_servers = 12
|
||||
pm.min_spare_servers = 6
|
||||
pm.max_spare_servers = 18
|
||||
|
||||
env[HOSTNAME] = $HOSTNAME
|
||||
env[PATH] = /usr/local/bin:/usr/bin:/bin
|
||||
env[TMP] = /tmp
|
||||
env[TMPDIR] = /tmp
|
||||
env[TEMP] = /tmp
|
||||
```
|
||||
|
||||
Recommended settings for `/etc/php/$php_ver/fpm/php.ini`
|
||||
Sometimes when installing apps, an error might occur
|
||||
and it's not always verbose as to why it can't proceed.
|
||||
This could fix some of those problems.
|
||||
|
||||
```php
|
||||
opcache.interned_strings_buffer=32
|
||||
|
||||
memory_limit = 512M
|
||||
```
|
||||
|
||||
## Tune memcache
|
||||
|
||||
### APCu local memcache
|
||||
For performance, documentation suggests enabling a
|
||||
memcache, for 'local memcache', APCu is recommended.
|
||||
|
||||
Install dependencies
|
||||
|
||||
```shell
|
||||
apt install php-apcu
|
||||
```
|
||||
|
||||
Add the following lines to `/var/www/nextcloud/config/config.php` under `$CONFIG=array`...
|
||||
|
||||
```php
|
||||
'memcache.local' => '\OC\Memcache\APCu',
|
||||
```
|
||||
|
||||
In order to avoid problems with cron jobs,
|
||||
Nextcloud's docs suggest to add these
|
||||
somewhere in `php.ini`, but I found it
|
||||
worked best when I added them in
|
||||
`/etc/php/$php_ver/mods-available/apcu.ini`
|
||||
(extension=apcu.so should already be there):
|
||||
|
||||
```php
|
||||
extension=apcu.so
|
||||
apc.enabled=1
|
||||
apc.enable_cli=1
|
||||
```
|
||||
|
||||
Restart php$php_ver-fpm
|
||||
```shell
|
||||
systemctl restart php8.2-fpm
|
||||
```
|
||||
|
||||
### Redis server (Transactional file locking)
|
||||
This is enabled by default in nextcloud to prevent
|
||||
dataloss with failed uploads or disconnects, however,
|
||||
it loads your database greatly for this purpose.
|
||||
To delegate this processing to redis, docs recommend:
|
||||
|
||||
NOTE:
|
||||
If you run into trouble just remove the
|
||||
`memcache.locking' => '\OC\Memcache\Redis'`,
|
||||
line mentioned below.
|
||||
|
||||
Insall required pacakges
|
||||
|
||||
```shell
|
||||
apt install redis-server php-redis
|
||||
```
|
||||
|
||||
Uncomment & modify `/etc/redis/redis.conf`
|
||||
|
||||
```
|
||||
port 0
|
||||
unixsocket /run/redis/redis.sock
|
||||
unixsocketperm 770
|
||||
```
|
||||
|
||||
Permissions, enable & run redis
|
||||
|
||||
```shell
|
||||
sudo usermod -a -G redis www-data
|
||||
systemctl enable --now redis-server
|
||||
```
|
||||
|
||||
Add the following lines to `/var/www/nextcloud/config/config.php` under `$CONFIG=array`...
|
||||
|
||||
```php
|
||||
'filelocking.enabled' => true,
|
||||
'memcache.locking' => '\OC\Memcache\Redis',
|
||||
'redis' => array(
|
||||
'host' => '/var/run/redis/redis.sock',
|
||||
'port' => 0,
|
||||
'timeout' => 0.0,
|
||||
),
|
||||
```
|
||||
|
||||
|
||||
(Optional) For distributed cache, also add:
|
||||
`memcache.distributed' => '\OC\Memcache\Redis'`,
|
||||
|
||||
Similarly with APCu, it is recommended
|
||||
to add these settings in php.ini, I just
|
||||
find it cleaner in the respective module's
|
||||
config in `/etc/php/$php_ver/mods-available/redis.ini`
|
||||
(extension=redis.so should already be there):
|
||||
|
||||
```php
|
||||
extension=redis.so
|
||||
redis.session.locking_enabled=1
|
||||
redis.session.lock_retries=-1
|
||||
redis.session.lock_wait_time=10000
|
||||
```
|
||||
|
||||
```shell
|
||||
Restart services
|
||||
systemctl restart redis-server
|
||||
systemctl restart php$php_ver-fpm
|
||||
systemctl restart nginx
|
||||
```
|
||||
|
||||
## Cron for background jobs
|
||||
|
||||
Run the following command:
|
||||
|
||||
```shell
|
||||
crontab -u www-data -e
|
||||
```
|
||||
|
||||
Append the following line AS IS
|
||||
to the end of the document
|
||||
(as recommended in nextcloud docs):
|
||||
|
||||
```
|
||||
*/5 * * * * php -f /var/www/nextcloud/cron.php
|
||||
```
|
||||
|
||||
```shell
|
||||
systemctl restart php8.2-fpm
|
||||
```
|
||||
|
||||
## Apply
|
||||
If applied, restart to apply changes with:
|
||||
|
||||
```shell
|
||||
systemctl restart redis-server
|
||||
systemctl restart php$php_ver-fpm
|
||||
systemctl restart nginx
|
||||
```
|
166
self-hosting/services/nextcloud/nextcloud.conf
Normal file
166
self-hosting/services/nextcloud/nextcloud.conf
Normal file
|
@ -0,0 +1,166 @@
|
|||
upstream php-handler {
|
||||
#server 127.0.0.1:9000;
|
||||
server unix:/run/php/php8.2-fpm.sock;
|
||||
}
|
||||
|
||||
# Set the `immutable` cache control options only for assets with a cache busting `v` argument
|
||||
map $arg_v $asset_immutable {
|
||||
"" "";
|
||||
default "immutable";
|
||||
}
|
||||
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name cloud.example.com;
|
||||
|
||||
# Prevent nginx HTTP Server Detection
|
||||
server_tokens off;
|
||||
|
||||
# Path to the root of your installation
|
||||
root /var/www/nextcloud;
|
||||
|
||||
# set max upload size and increase upload timeout:
|
||||
client_max_body_size 512M;
|
||||
client_body_timeout 300s;
|
||||
fastcgi_buffers 64 4K;
|
||||
|
||||
# Enable gzip but do not remove ETag headers
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_comp_level 4;
|
||||
gzip_min_length 256;
|
||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
||||
gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
||||
|
||||
# The settings allows you to optimize the HTTP2 bandwitdth.
|
||||
# See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
|
||||
# for tunning hints
|
||||
client_body_buffer_size 512k;
|
||||
|
||||
# HTTP response headers borrowed from Nextcloud `.htaccess`
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Download-Options "noopen" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
|
||||
# Remove X-Powered-By, which is an information leak
|
||||
fastcgi_hide_header X-Powered-By;
|
||||
|
||||
# Add .mjs as a file extension for javascript
|
||||
# Either include it in the default mime.types list
|
||||
# or include you can include that list explicitly and add the file extension
|
||||
# only for Nextcloud like below:
|
||||
include mime.types;
|
||||
types {
|
||||
text/javascript js mjs;
|
||||
}
|
||||
|
||||
# Specify how to handle directories -- specifying `/index.php$request_uri`
|
||||
# here as the fallback means that Nginx always exhibits the desired behaviour
|
||||
# when a client requests a path that corresponds to a directory that exists
|
||||
# on the server. In particular, if that directory contains an index.php file,
|
||||
# that file is correctly served; if it doesn't, then the request is passed to
|
||||
# the front-end controller. This consistent behaviour means that we don't need
|
||||
# to specify custom rules for certain paths (e.g. images and other assets,
|
||||
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
|
||||
# `try_files $uri $uri/ /index.php$request_uri`
|
||||
# always provides the desired behaviour.
|
||||
index index.php index.html /index.php$request_uri;
|
||||
|
||||
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
|
||||
location = / {
|
||||
if ( $http_user_agent ~ ^DavClnt ) {
|
||||
return 302 /remote.php/webdav/$is_args$args;
|
||||
}
|
||||
}
|
||||
|
||||
location = /robots.txt {
|
||||
allow all;
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Make a regex exception for `/.well-known` so that clients can still
|
||||
# access it despite the existence of the regex rule
|
||||
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
|
||||
# for `/.well-known`.
|
||||
location ^~ /.well-known {
|
||||
# The rules in this block are an adaptation of the rules
|
||||
# in `.htaccess` that concern `/.well-known`.
|
||||
|
||||
location = /.well-known/carddav { return 301 /remote.php/dav/; }
|
||||
location = /.well-known/caldav { return 301 /remote.php/dav/; }
|
||||
|
||||
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
|
||||
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
|
||||
|
||||
# Let Nextcloud's API for `/.well-known` URIs handle all other
|
||||
# requests by passing them to the front-end controller.
|
||||
return 301 /index.php$request_uri;
|
||||
}
|
||||
|
||||
# Rules borrowed from `.htaccess` to hide certain paths from clients
|
||||
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
|
||||
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
|
||||
|
||||
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
|
||||
# which handle static assets (as seen below). If this block is not declared first,
|
||||
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
|
||||
# to the URI, resulting in a HTTP 500 error response.
|
||||
location ~ \.php(?:$|/) {
|
||||
# Required for legacy support
|
||||
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
|
||||
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
set $path_info $fastcgi_path_info;
|
||||
|
||||
try_files $fastcgi_script_name =404;
|
||||
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $path_info;
|
||||
fastcgi_param HTTPS on;
|
||||
|
||||
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
|
||||
fastcgi_param front_controller_active true; # Enable pretty urls
|
||||
fastcgi_pass php-handler;
|
||||
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_request_buffering off;
|
||||
|
||||
fastcgi_max_temp_file_size 0;
|
||||
}
|
||||
|
||||
# Serve static files
|
||||
location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
|
||||
try_files $uri /index.php$request_uri;
|
||||
add_header Cache-Control "public, max-age=15778463, $asset_immutable";
|
||||
access_log off; # Optional: Don't log access to assets
|
||||
|
||||
location ~ \.wasm$ {
|
||||
default_type application/wasm;
|
||||
}
|
||||
}
|
||||
|
||||
location ~ \.woff2?$ {
|
||||
try_files $uri /index.php$request_uri;
|
||||
expires 7d; # Cache-Control policy borrowed from `.htaccess`
|
||||
access_log off; # Optional: Don't log access to assets
|
||||
}
|
||||
|
||||
# Rule borrowed from `.htaccess`
|
||||
location /remote {
|
||||
return 301 /remote.php$request_uri;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$request_uri;
|
||||
}
|
||||
|
||||
}
|
||||
|
43
self-hosting/services/onlyoffice/README.md
Normal file
43
self-hosting/services/onlyoffice/README.md
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Add non-free and contrib
|
||||
|
||||
Edit `/etc/apt/sources.list` and make sure to have enabled **non-free** and **contrib**.
|
||||
|
||||
```
|
||||
deb http://deb.debian.org/debian/ bookworm main non-free-firmware non-free contrib
|
||||
```
|
||||
|
||||
# Install dependencies
|
||||
```shell
|
||||
apt install -y nginx nginx-extras postgresql rabbitmq-server redis gnupg libcurl4 libxml2 fonts-dejavu fonts-liberation ttf-mscorefonts-installer fonts-crosextra-carlito fonts-takao-gothic fonts-opensymbol
|
||||
```
|
||||
|
||||
# OnlyOffice configuration
|
||||
```shell
|
||||
echo onlyoffice-documentserver onlyoffice/ds-port select 81 | sudo debconf-set-selections
|
||||
sudo -i -u postgres psql -c "CREATE USER onlyoffice WITH PASSWORD 'DB_PASSWORD';"
|
||||
sudo -i -u postgres psql -c "CREATE DATABASE onlyoffice OWNER onlyoffice;"
|
||||
```
|
||||
|
||||
# OnlyOffice Docs repository
|
||||
```shell
|
||||
mkdir -p -m 700 ~/.gnupg
|
||||
curl -fsSL https://download.onlyoffice.com/GPG-KEY-ONLYOFFICE | gpg --no-default-keyring --keyring gnupg-ring:/tmp/onlyoffice.gpg --import
|
||||
chmod 644 /tmp/onlyoffice.gpg
|
||||
chown root:root /tmp/onlyoffice.gpg
|
||||
mv /tmp/onlyoffice.gpg /usr/share/keyrings/onlyoffice.gpg
|
||||
|
||||
echo "deb [signed-by=/usr/share/keyrings/onlyoffice.gpg] https://download.onlyoffice.com/repo/debian squeeze main" | sudo tee /etc/apt/sources.list.d/onlyoffice.list
|
||||
apt-get update
|
||||
|
||||
apt install onlyoffice-documentserver # Will ask for DB_PASSWORD
|
||||
```
|
||||
|
||||
# Nginx reverse proxy & HTTPS
|
||||
|
||||
```shell
|
||||
curl -L reverse-proxy.tavo.one | sed "s/example.domain.xyz/YOURDOMAIN/g" | tee /etc/nginx/sites-available/onlyoffice.conf
|
||||
ln -s /etc/nginx/sites-available/onlyoffice.conf /etc/nginx/sites-enabled/
|
||||
|
||||
systemctl restart nginx
|
||||
certbot -d YOURDOMAIN --nginx --register-unsafely-without-email --agree-tos
|
||||
```
|
80
system_administration/secure-ssh/README.md
Normal file
80
system_administration/secure-ssh/README.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
# First login
|
||||
|
||||
```shell
|
||||
# Login into the VPS
|
||||
ssh root@codespec.xyz
|
||||
|
||||
# Update packages
|
||||
apt update && apt upgrade
|
||||
|
||||
# Enable automatic updates
|
||||
apt install unattended-upgrades
|
||||
dpkg-reconfigure unattended-upgrades
|
||||
```
|
||||
|
||||
# Add a new user
|
||||
|
||||
This is done so that you can disable
|
||||
loging in as root user.
|
||||
|
||||
```shell
|
||||
# '-m' creates a home directory,
|
||||
# '-s' assigns a shell (/bin/bash in this case),
|
||||
# 'user' is the name you want to give it
|
||||
useradd -m -s /bin/bash user
|
||||
passwd user # Set a password for 'user'
|
||||
```
|
||||
|
||||
Add 'user' to sudo group. This will allow to execute
|
||||
commands as root, such as `sudo apt update`.
|
||||
Some distros user 'wheel' group instead of 'sudo'
|
||||
Run command `visudo` to check root enabled groups.
|
||||
Debian, Ubuntu and derivatives usually use 'sudo'.
|
||||
|
||||
```shell
|
||||
usermod -aG sudo user # Give 'user' sudo privileges
|
||||
su - user # Login into 'user'
|
||||
sudo apt update # Test that you have access to sudo
|
||||
|
||||
# Exit your server, you may need to run 'exit' twice.
|
||||
exit
|
||||
```
|
||||
|
||||
# Configure SSH keypair
|
||||
|
||||
## In your local machine:
|
||||
```shell
|
||||
ssh-keygen # Generate keypair
|
||||
ssh-copy-id -i ~/.ssh/id_rsa.pub user@codespec.xyz # Copy to server
|
||||
ssh user@codespec.xyz # Check it works
|
||||
```
|
||||
|
||||
## ONCE IN THE VPS:
|
||||
`sudo nano /etc/ssh/sshd_config`
|
||||
Make sure to configure as follows
|
||||
(We only need to allow 'user', but
|
||||
you can add multiple users as well):
|
||||
|
||||
```ssh
|
||||
PermitRootLogin no
|
||||
AllowUsers user otheruser yetanotheruser
|
||||
PasswordAuthentication no
|
||||
UsePam no
|
||||
```
|
||||
|
||||
Then, restart SSH daemon
|
||||
|
||||
```shell
|
||||
systemctl restart sshd
|
||||
```
|
||||
|
||||
# Enable UFW
|
||||
|
||||
```shell
|
||||
# Allow SSH before enabling,
|
||||
# Will drop shell otherwise.
|
||||
ufw allow 22
|
||||
|
||||
# Enable firewall
|
||||
ufw enable
|
||||
```
|
|
@ -118,7 +118,7 @@ Which then can be appended to the `/etc/wpa_supplicant/wpa_supplicant.conf` file
|
|||
**Note**: The `#psk=` line can be omitted for the hashed password.
|
||||
However, this will not prevent others with access to this hash
|
||||
to connect to the network, but at least it will not reveal the
|
||||
plain text password.
|
||||
plain text password if the system is compromised.
|
||||
|
||||
**Note**: Make sure this file is not readable by running:
|
||||
|
Loading…
Reference in a new issue