Previous Page

nihilist - 07 / 12 / 2022

perlite Setup

Perlite is an awesome project by sec77 to display your obsidian notes on the web, essentially an alternative to the paid Obsidian publish.

Initial Setup

You'll need nginx and php8.2 and some dependencies:


[ 10.8.0.2/24 ] [ home ] [/srv]
→ apt install nginx php8.2-fpm php-mbstring php-yaml -y

[ 10.8.0.2/24 ] [ home ] [/srv]
→ vim /etc/nginx/sites-available/perlite.nowhere.moe.conf

Then we can git clone the project wherever, i put it in /srv/:


[ 10.8.0.2/24 ] [ home ] [/srv/perlite]
→ git clone https://github.com/secure-77/Perlite

[ 10.8.0.2/24 ] [ home ] [/srv/]
→ chown -R www-data: /srv/Perlite

[ 10.8.0.2/24 ] [ home ] [/srv/]
→ cd Perlite

Now from here you will need the following nginx config:


[ 10.8.0.2/24 ] [ home ] [/srv/Perlite]
→ cat /etc/nginx/sites-available/perlite.nowhere.moe.conf
server {

		#apt install apache2-utils -y
        #htpasswd -c /etc/nginx/auth/default.htpasswd nothing

        auth_basic "Password protection";
        auth_basic_user_file /etc/nginx/auth/default.htpasswd;

        server_name perlite.nowhere.moe;

        root /srv/Perlite/perlite/;
        index index.php index.html index.htm;


        location ~ \.php$ {
               include snippets/fastcgi-php.conf;
               fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        }

        location ~ /\.ht {
                deny all;
        }

        location ~* ^/(.*)/.obsidian/appearance.json$ {
                allow all;
        }

        location ~* ^/(.*)/.obsidian/(.*)/theme.css$ {
                allow all;
        }

                #added for this specific setup, thanks sec77!
                location ~* ^/.obsidian/(.*)/theme.css$ {
                allow all;
        }

        location ~ \.(git|github|obsidian|trash) {
                deny all;
        }

        location ~ \.(md|json)$ {
                deny all;
        }
}
	

For now it's just on port 80, and with a basicauth because i want it to be in maintenance mode for now, then we go into the perlite folder:


[ 10.8.0.2/24 ] [ home ] [/srv]
→ cd Perlite

[ 10.8.0.2/24 ] [ home ] [/srv/Perlite]
→ ls -lash
total 72K
4.0K drwxr-xr-x 7 root root 4.0K Dec  7 22:20 .
4.0K drwxr-xr-x 7 root root 4.0K Dec  7 22:20 ..
4.0K drwxr-xr-x 8 root root 4.0K Dec  7 22:20 .git
4.0K -rw-r--r-- 1 root root   66 Dec  7 22:20 .gitattributes
4.0K drwxr-xr-x 3 root root 4.0K Dec  7 22:20 .github
4.0K -rw-r--r-- 1 root root  118 Dec  7 22:20 .gitignore
8.0K -rw-r--r-- 1 root root 4.4K Dec  7 22:20 Changelog.md
4.0K drwxr-xr-x 7 root root 4.0K Dec  7 22:20 Demo
4.0K -rw-r--r-- 1 root root 2.0K Dec  7 22:20 Docker.md
4.0K -rw-r--r-- 1 root root 1.1K Dec  7 22:20 LICENSE
8.0K -rw-r--r-- 1 root root 6.7K Dec  7 22:20 README.md
4.0K -rw-r--r-- 1 root root  182 Dec  7 22:20 SECURITY.md
4.0K -rw-r--r-- 1 root root  565 Dec  7 22:20 docker-compose-dev.yml
4.0K -rw-r--r-- 1 root root  522 Dec  7 22:20 docker-compose.yml
4.0K drwxr-xr-x 5 root root 4.0K Dec  7 22:21 perlite
4.0K drwxr-xr-x 3 root root 4.0K Dec  7 22:20 web

[ 10.8.0.2/24 ] [ home ] [/srv/Perlite]
→ cd perlite

[ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite]
→ ls -lash
total 216K
4.0K drwxr-xr-x 5 root root 4.0K Dec  7 22:21 .
4.0K drwxr-xr-x 7 root root 4.0K Dec  7 22:20 ..
4.0K drwxr-xr-x 2 root root 4.0K Dec  7 22:20 .js
4.0K drwxr-xr-x 4 root root 4.0K Dec  7 22:20 .styles
4.0K -rw-r--r-- 1 root root  508 Dec  7 22:20 Dockerfile
4.0K -rw-r--r-- 1 root root  151 Dec  7 22:20 Dockerfile.dev
4.0K drwxr-xr-x 6 root root 4.0K Dec  7 22:21 Obsidian
 44K -rw-r--r-- 1 root root  42K Dec  7 22:20 Parsedown.php
 12K -rw-r--r-- 1 root root  11K Dec  7 22:20 PerliteParsedown.php
8.0K -rw-r--r-- 1 root root 4.3K Dec  7 22:20 content.php
 16K -rw-r--r-- 1 root root  16K Dec  7 22:20 favicon.ico
 12K -rw-r--r-- 1 root root  12K Dec  7 22:21 helper.php
 56K -rw-r--r-- 1 root root  54K Dec  7 22:20 index.php
 20K -rw-r--r-- 1 root root  17K Dec  7 22:20 logo.svg
 20K -rw-r--r-- 1 root root  17K Dec  7 22:20 perlite.svg
	

This is where the root of the website will be. In here you can put your vault as a sub-folder, here i put mine as the "Obsidian" folder as you can see above. Before you put it there, you will need to do a few things. First of all you need the Obsidian plugin "Metadata Extractor" to get the generated metadata.json file, along with the enabled "write JSON files automatically when Obsidian Launches" option:


[ 10.8.0.2/24 ] [ home ] [Perlite/perlite/Obsidian]
→ ls -lash
total 260K
4.0K drwxr-xr-x  6 root root 4.0K Dec  7 22:21 .
4.0K drwxr-xr-x  5 root root 4.0K Dec  7 22:21 ..
4.0K drwxr-xr-x  8 root root 4.0K Dec  7 22:21 .git
4.0K drwxr-xr-x  4 root root 4.0K Dec  7 22:21 .obsidian
4.0K drwxr-xr-x 15 root root 4.0K Dec  7 22:21 HTB
   0 -rw-r--r--  1 root root    0 Dec  7 22:21 README.md
4.0K drwxr-xr-x  3 root root 4.0K Dec  7 22:21 Sysadmin
228K -rw-r--r--  1 root root 225K Dec  7 22:21 metadata.json
4.0K -rwxr-xr-x  1 root root   85 Dec  7 22:21 pull.sh
4.0K -rwxr-xr-x  1 root root  207 Dec  7 22:21 push.sh
	

Then you need to have the New link format option set to relative path to file (it's in the Files & Links menu in obsidian settings:

For further tweaking, please look at sec77's documentation here

From here you should already see your website as follows:


[ 10.8.0.2/24 ] [ home ] [Perlite/perlite/Obsidian]
→ systemctl restart php8.2-fpm nginx	

(big thanks to sec77 for showing me the fix here), If your theme doesn't load or if the vault doesnt show up, you can manually set the root directory of the vault in the helper.php file:


 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite]
→ cat helper.php| grep rootDir
//$rootDir = getenv('NOTES_PATH');
$rootDir = 'Obsidian';
$vaultName = $rootDir;

[...]

Here you see i setup mine to the relative path 'Obsidian' which points to the subdirectory in /srv/Perlite/perlite/Obsidian/. And there you go!

TLS Setup



If you want it setup with TLS just use acme.sh:


[ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite]
→ acme.sh --issue --standalone -d perlite.nowhere.moe -k 4096
[Wed Dec  7 22:59:59 CET 2022] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Wed Dec  7 22:59:59 CET 2022] Standalone mode.
[Wed Dec  7 22:59:59 CET 2022] Creating domain key
[Wed Dec  7 23:00:00 CET 2022] The domain key is here: /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.key
[Wed Dec  7 23:00:00 CET 2022] Single domain='perlite.nowhere.moe'
[Wed Dec  7 23:00:00 CET 2022] Getting domain auth token for each domain
[Wed Dec  7 23:00:03 CET 2022] Getting webroot for domain='perlite.nowhere.moe'
[Wed Dec  7 23:00:04 CET 2022] Verifying: perlite.nowhere.moe
[Wed Dec  7 23:00:04 CET 2022] Standalone mode server
[Wed Dec  7 23:00:06 CET 2022] Pending, The CA is processing your order, please just wait. (1/30)
[Wed Dec  7 23:00:09 CET 2022] Success

[...]

[Wed Dec  7 23:00:12 CET 2022] Your cert is in: /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.cer
[Wed Dec  7 23:00:12 CET 2022] Your cert key is in: /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.key
[Wed Dec  7 23:00:12 CET 2022] The intermediate CA cert is in: /root/.acme.sh/perlite.nowhere.moe/ca.cer
[Wed Dec  7 23:00:12 CET 2022] And the full chain certs is there: /root/.acme.sh/perlite.nowhere.moe/fullchain.cer
	

and then for the nginx config with TLS I use the following:


[ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite]
→ cat /etc/nginx/sites-available/perlite.nowhere.moe.conf
server {
        listen 80;
        listen [::]:80;
        server_name perlite.nowhere.moe;
        return 301 https://$server_name$request_uri;
}

server {
                ######## TOR CHANGES ########
        listen 4443;
        listen [::]:4443;
        server_name perlite.nihilisxacas2ntt3kb2nzfjp4nu5enratyehvahllblxgq2tqpsrnid.onion;
        add_header Onion-Location "http://perlite.nihilisxacas2ntt3kb2nzfjp4nu5enratyehvahllblxgq2tqpsrnid.onion$request_uri" always;
        ######## TOR CHANGES ########

        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name perlite.nowhere.moe;

        ssl_certificate /root/.acme.sh/perlite.nowhere.moe/fullchain.cer;
        ssl_trusted_certificate /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.cer;
        ssl_certificate_key /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.key;

        ssl_protocols TLSv1.3 TLSv1.2;
        ssl_ciphers 'TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;
        ssl_ecdh_curve auto;
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 80.67.188.188 80.67.169.40 valid=300s;
        resolver_timeout 10s;

        add_header X-XSS-Protection "1; mode=block"; #Cross-site scripting
        add_header X-Frame-Options "SAMEORIGIN" always; #clickjacking
        add_header X-Content-Type-Options nosniff; #MIME-type sniffing
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";


        root /srv/Perlite/perlite/;
        index index.php index.html index.htm;


        location ~ \.php$ {
               include snippets/fastcgi-php.conf;
               fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        }

        location ~ /\.ht {
                deny all;
        }

        location ~* ^/(.*)/.obsidian/appearance.json$ {
                allow all;
        }

        location ~* ^/(.*)/.obsidian/(.*)/theme.css$ {
                allow all;
        }

                #added for this specific setup, thanks sec77!
                location ~* ^/.obsidian/(.*)/theme.css$ {
                allow all;
        }

        location ~ \.(git|github|obsidian|trash) {
                deny all;
        }

        location ~ \.(md|json)$ {
                deny all;
        }
}


[ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite]
→ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite]
→ systemctl restart nginx

And there you go! We have been able to publish our obsidian notes on the web from our a VPS.

Nihilism

Until there is Nothing left.



Creative Commons Zero: No Rights Reserved

About nihilist

Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8


Contact: nihilist@contact.nowhere.moe (PGP)