Self-hosting a static website in Slackware 15

- Introduction -
- Installing Slackware -
- Updating OS certs and setting up SSH -
- Buying domains -
- Setting up a website server (darkhttpd) -
- Getting an SSL certificate -
- Self-signed -
- Uploading files -

Introduction

Did it again recently, and I thought I'll put the instructions up here just in case someone wants to try it too. The process is not that easy to figure out the first time, so I might as well save someone the trouble. Why even do it? Because having your own website is worth it, and a much better outlet than big tech social media, over which you have little control and can be kicked out from at any time. Why not Landchad? They cover stuff I don't need, or don't cover stuff I do need, or do it differently than I like. Don't get me wrong, it's a good project but I just like doing things my own way. And besides, some of their stuff is not applicable to Slackware. Why Slackware? Because it's all I know, and should be helpful to those familiar with it and not other distros / OSes. Anyway let's go:

Installing Slackware

First of all, you need a host that accepts custom ISOs; I will assume BuyVM in this guide. Login through Stallion, pick the CD-ROM menu option, and click Upload ISO:

Showing the Upload ISO option

After that, click the Upload ISO that appeared further down:

Showing the Upload ISO option

Then, input the Slackware 15 link (currently at https://mirrors.slackware.com/slackware/slackware-iso/slackware64-15.0-iso/slackware64-15.0-install-dvd.iso) into the second field, click Upload, and wait:

Showing the ISO address entry field

After it uploads, click Mount ISO:

Showing the Mount ISO option

This should appear after:

Showing the message that appears after an ISO has been mounted

Login through Stallion's web-based console. You should see a message prompting you to choose a keyboard layout - just press Enter. Then type root and finally setup to start the Slackware installer. Pick Target on the screen that pops up:

Picking the Target option on the Slackware install screen

Pick /dev/vda1, the only option:

Picking /dev/vda1 on the partition choice screen

Format as ext4 (the other should work too, but I have no experience with them and they might differ in important ways)

Agreeing to format the partition Choosing ext4 as the filesystem

Install from CD:

Picking the CD option on the Slackware installation media choice screen

In the package series selection screen, you can freely disable E, K, KDE, T, TCL, X, XAP, XFCE and Y series. Theoretically, you can also skip the D series, but then you'll need to download the perl package (the only one you'll need from that series) later:

First half of the package selection screen Second half of the package selection screen

After you're done, pick terse and wait.

Choosing 'terse' on the package installation style screen

Skip making the USB boot stick on the next screen.

Skipping the creation of an USB stick

Since we only have one OS and partition, lilo can be setup automatically.

Choosing automatic lilo setup

Next three screens can be OK-ed through. After that, choose to start gpm at boot time:

Choosing to start gpm at boot time

On the remaining screens, don't configure your network. Startup services can be left as they are, as well.

Slackware has now been installed. Go back to Stallion and switch to hard drive boot again (otherwise, it will go back to the install screen after reboot).

Setting BuyVM to boot from HDD in the control panel

Now boot inside the web VNC console at the top right of Stallion. There you'll be able to type commands before ssh is installed.

Updating OS certs and setting up SSH

The first thing we're going to do once Slackware is installed is upgrade the ca-certificates package - as without that, some hosts will fail to verify their SSL connections. Go to https://slackware.nl/slakfinder/ and find the newest version. Since we don't have SSH yet, we're going to have to use the direct VNC (or the web console) connection for this. Type wget [package_address], then installpkg [package_name]. Currently, the link to the newest version is http://ftp.osuosl.org/pub/slackware/slackware64-current/slackware64/n/ca-certificates-20250131-noarch-1.txz, so the commands would be wget http://ftp.osuosl.org/pub/slackware/slackware64-current/slackware64/n/ca-certificates-20250131-noarch-1.txz and upgradepkg ca-certificates-20250131-noarch-1.txz. This might change at any time though, so do not rely on this direct link.

By default, trusted SSL certificates are stored in the folders /etc/ssl/certs and /usr/share/ca-certificates/mozilla. But for some reason, only certs from the folder /usr/local/share/ca-certificates get detected. Yet, it doesn't exist by default, so create it (mkdir /usr/local/share/ca-certificates). Then copy the certs from folder #1 to #2; cd /usr/share/ca-certificates/mozilla/; cp * /usr/local/share/ca-certificates/.

After this is done, actually run the script by typing update-ca-certificates. This where you'll need the Perl package if you've skipped the D series. If the command worked properly, you should get a message like 241 added, 0 removed, done.

By default, root is the only available Slackware user, but it's not good practice to allow him to ssh in, so let's create a regular user (all commands from now on will assume being run as root):

adduser luna

You can enter past everything other than the password field (remember to pick a strong one). After you're done, edit your ssh config file at /etc/ssh/sshd_config (by eg. nano) to allow server administration without VNC. You need this section somewhere in it:

Port 281
AddressFamily any
ListenAddress 0.0.0.0:281

The port can be any, but should probably be nonstandard to discourage hacking attempts. After that, add your user to the list of allowed users:

AllowUsers luna

Save. Restart sshd with sh /etc/rc.d/rc.sshd restart. Put dhcpcd in your /etc/rc.d/rc.local script. Reboot in Stallion. Now trash the VNC, as you will be able to login with this ssh command: ssh ssh://user@ipaddress:port, for example ssh ssh://luna@71.24.85.36:281. If anonymity is a concern (and it should be) you can put proxychains4 before the first ssh (proxychains is explained here).

Buying domains

Though you can technically have a website without it - if you are ever hoping to have actual viewership - then a domain is an absolute necessity. It is what allows people to type in your website address (eg digdeeper.love) instead of an unrememberable IP address. Basically the domain provider could be considered analogous to a translator of a really hard language (IP numbers) to an easy one (domain names), so that your viewers only need to know the easy one. Anyway, my favorite domain registrar is njalla, for these reasons:

There is a caveat that has to be mentioned in regards to the first point. Namely that the reason this is even possible is so that njalla substitutes their own data in place of yours, to the actual domain registrar, that they are only a middleman to. This means that you are not the legal owner of your domain - but if you're here, you're surely an outlaw for whom this does not matter. And if you one day decide to reveal yourself (or get doxed), njalla will allow you to claim the ownership of your domain with your real identity. This will mean - though - that governments will be suddenly able to grab you for the wrongthink in there. But hey, at least njalla offers this option. Anyway, click here to register:

The first registration screen for njalla, with email or XMPP options, with curson on the XMPP option

Now input your XMPP address and password (for the njalla account, not your XMPP one), and pick your encryption type (your client and server must support it, or else the confirmation message won't come!):

The second registration screen for njalla, with filled login and pass options, as well as choices of encryption type, with cursor over the OTR option

After this, a message from no-reply@njal.la should immediately appear inside your XMPP client, containing a confirmation link - click it. Now go to the login page, fill in the details, and click Sign in. Direct your eyes to the right part of the page:

Showing the wallet balance, with the curson over an 'Add funds' button

I have some funds already transfered, but for you the amount will be zero - so let's add some. Choose the amount you'd like to add (30 euros should be enough to buy the average-cost domain names for one year, and the cheap ones for two), then pick Monero.

Showing the add funds screen, with 30 euro picked in the dropdown menu, and Monero as the currency of choice Showing the final add funds screen, with an amount listed to pay, as well as target Monero address

Just send the listed amount from your Monero wallet to the address that appears, and wait until confirmation. In Pale Moon the entire address appears to not display; to grab it you can also visit the Click here to pay link, and copy what's between monero: and ? - which should look like 4EH7kExT2jnRwdors2tZT3M4SZ9jycDCaNh2Bt8WeuvxDUeRKdgNbw9HdWasjwcEaWbHm2T2eozXZehYhHvAx7xdF5ZWwKM1Hdf4Dt9Y2h (seems to be 106 characters every time), for example. If you have a monero wallet mapped inside your browser, then it should simply open. Might get a screenshot at some point, but not now. Also, actually getting the Monero is out of the scope of this guide. Once it confirms, go here and type the first part (the one before the TLD, or dot) of the domain that you want:

Showing the domain search field, with 'schooling' typed in it

I thought long and hard about what domain to use as an example, as I wanted to actually buy it for this guide's purposes, so it had to somehow be useful to me. Then I remembered that .exposed is an actual TLD (which is hilarious as fuck). I tried wikipedia.exposed but the psychopaths running it grabbed it already, same with mozilla. Capitalism works but is kinda boring; then I remembered that I have an article about the schooling system, so I thought to try that. Anyway, after the results display, click the Show available filter category, so that you're not bothered with the domains that are already taken - unless you just want to see what TLDs exist at all:

Showing the results of the domain search, with the cursor hovered over 'available' filter option

Scrolling down a little reveals schooling.exposed as available. Beautiful! Let's grab it:

Showing the results of the domain search, with a few 'schooling' domains available, including 'schooling.exposed' Showing how 'Select domain' changes to 'Selected' after clicking

Scroll as far up as you can and click Check out!:

Showing the cursor positioned over 'Checkout' button

I'm only going to buy it for one year (default), as I lack anymore funds. I'm just a starving artist, you see:

Showing the screen where you finalize buying the domain, with cursor hovered over 'Pay Now' button

After buying the domain, go to the domain list and click Manage for the relevant one:

Showing the domain list with cursor over 'manage' for 'schooling.exposed'

Now click this button:

Showing the domain list with cursor over 'manage' for 'schooling.exposed'

Add an A record for the domain, which basically means "redirect this address to this IP number" (you can find your VPS's IP inside Stallion or other web control panel):

Showing the domain list with cursor over 'manage' for 'schooling.exposed'

If you did it properly, in some time you should be able to connect to your website by typing http://schooling.exposed (or whatever domain you bought) into your browser's address bar. But it will do nothing without...

Setting up a website server (darkhttpd)

A webserver is what actually serves (shows) the website files to the viewer. We'll be using darkhttpd because it's small, easy to install and configure, and has everything required for a static site. Our current system doesn't even allow us to install packages at all, so let's fix that. You will need spkg (a dependency for slapt-get), and slapt-get itself. Download the former with wget https://download.salixos.org/x86_64/15.0/salix/a/spkg-1.7-x86_64-2gv.tgz and the latter with wget https://download.salixos.org/x86_64/15.0/salix/ap/slapt-get-0.11.6-x86_64-2gv.txz. Then install both with installpkg. Update the repositories with slapt-get --update and you're good to go. Now install darkhttpd with slapt-get --install darkhttpd. Then make an user and a group that will use it:

groupadd darkhttpd
useradd --no-user-group --system -s /sbin/nologin --gid darkhttpd darkhttpd

This theoretically improves security, in that darkhttpd will have access only to folders containing the website files. Though I suspect that the practical effect won't be that noticable, because user submissions are not accepted due to the static-only nature. Still a good practice in case malicious code ends up in the binary by repo compromise or whatever. Anyway, create a folder that will contain your website files:

mkdir /var/www/mysite

To be able to later upload files conveniently (and you'll be doing that a lot, so it better be convenient), it's recommended (by me :D) to use a graphical FTP program like gftp. Again, it's the most secure to create a separate user for it, so let's do it now:

useradd --no-user-group --gid darkhttpd -s /bin/bash -d /home/gftp gftp
passwd gftp

We're making darkhttpd his main group so that when a new file is added to the website folders, it will automatically have read permissions for the server applied. As usual, remember to pick a strong password. After you're done, change the permission of the website folder like this:

chown -R gftp:darkhttpd /var/www/mysite
chmod -R 750 /var/www/mysite

This accomplishes two very important things. The first is that you will be able to upload files through your ftp client. The second is that the website server gets only read access to the website folders (it doesn't need more because user submissions are - again - not possible due to its static nature). The program actually uses the ssh protocol to upload, so you need to add the gftp user to /etc/ssh/sshd_config. Just change AllowUsers luna to AllowUsers luna gftp and save. Finally, run the server with:

darkhttpd /var/www/mysite --addr 0.0.0.0 --uid darkhttpd --gid darkhttpd --daemon&

You can now visit your site at your server's IP address. If you have a domain pointed to it, you can also use that.

Getting an SSL certificate

But that's not very useful alone. Anyone in between your reader and your server potentially gets to view - or even modify - the connection traffic. Defending from this is possible by getting a HTTPS certificate. To do so, install acme.sh (slapt-get --install acme.sh). Then issue a cert with this command (you need a domain first, with an A record pointing to the server IP):

acme.sh --issue --domain schooling.exposed --accountkeylength 4096 --standalone

You will get a message similar to this when it finishes:

Your cert is in: /root/.acme.sh/schooling.exposed_ecc/schooling.exposed.cer
Your cert key is in: /root/.acme.sh/schooling.exposed_ecc/schooling.exposed.key
The intermediate CA cert is in: /root/.acme.sh/schooling.exposed_ecc/ca.cer
And the full-chain cert is in: /root/.acme.sh/schooling.exposed_ecc/fullchain.cer

It is also possible to generate a self-signed certificate instead of requesting it from a cert authority, but it's a lot more involved and will also bring up errors in the viewers' browsers (though the security level is the same), so we will skip it for now. Anyway - because darkhttpd doesn't support SSL certificates by default (hey, I said it's lean...) - we need an additional piece of software called stunnel; so install it by typing slapt-get --install stunnel. As is tradition, we will make it run as a separate user:

groupadd stunnel
useradd --no-user-group --gid stunnel stunnel -s /bin/bash -d /home/stunnel

Now move the previously created certificates to stunnel's folder so it can pick them up:

cp /root/.acme.sh/schooling.exposed_ecc/fullchain.cer /etc/stunnel
cp /root/.acme.sh/schooling.exposed_ecc/schooling.exposed.key /etc/stunnel

Stunnel needs a folder to put its pid file in, so create it:

mkdir /var/run/stunnel
chown -R stunnel /var/run/stunnel
chmod 755 -R /var/run/stunnel

By default, stunnel has a sample config file at /etc/stunnel/stunnel.conf-sample, but it's not being used as it's the "wrong" name, so change it to stunnel.conf (mv /etc/stunnel/stunnel.conf-sample /etc/stunnel/stunnel.conf). Then edit it with nano or anything else. First, change the ;pid = /var/run/stunnel.pid part to pid = /var/run/stunnel/stunnel.pid (it won't work with the original folder due to permissions issues, I think). After that, put these in somewhere:

setuid = stunnel
setgid = stunnel

[https]
client = no
accept = 443
connect = 0.0.0.0:80
cert = /etc/stunnel/fullchain.cer
key = /etc/stunnel/schooling.exposed.key

The first two lines tell stunnel to run as the user stunnel. All others give SSL capabilities to your webserver (assuming it runs on port 80, which is the default for root-started darkhttpd). If you run stunnel, you should be able to connect to your website through https now.

Authority-assigned certificates don't stay valid forever, so you'll need to renew them with these commands every so often:

cd /root/.acme.sh/
sh acme.sh --renew -d schooling.exposed

And copy them to stunnel's folder with previously mentioned commands, then restart:

pkill stunnel; pkill darkhttpd
stunnel&
darkhttpd /var/www/mysite --addr 0.0.0.0 --uid darkhttpd --gid darkhttpd --daemon&

You can put all that in a cronjob at /etc/cron.monthly/renewcert.sh for example. HTTP (or onion) connections will always work even with expired certs.

Self-signed

You do not need to rely on a certificate authority to support encrypted connections - you can generate the cert yourself. This has some advantages in that you don't have to rely on a third party that can go down at any time, or just be hacked and compromised by "cybercriminals". You can have stronger encryption than the maximum offered by acme / Let's Encrypt (8192 vs 4096). You can have your cert be valid for whatever length of time you want to, instead of the puny month or 3 months or whatever of LE; you will never be canceled, either. And finally you can fill the data with funny stuff like this:

Showing the 'View certificate' window in Pale Moon for my diggy.club self-signed cert, with 'Dig Deeper Team' listed as the issuing organization

Compare to a Let's Encrypt-assigned one:

Showing the 'View certificate' window in Pale Moon for my digdeeper.club Let's Encrypt cert. The lack of fun stuff in the data is very obvious.

So what's the catch? Because there has to be one, right? There indeed is, and a very serious one. Namely that all mainstream browsers display a big scary warning when they encounter a self-signed cert. Like this:

Self-signed cert warning in Chrome-based browsers, claiming the connection is 'not private' and offering a way to 'get back to safety' by leaving the offending page

You can click Advanced and proceed to my site anyway, but every normie will retreat to his "safe" Google-shaped cage instead. So if you want any actual viewership, you can't rely on this at least unless you have another host with an "official" cert. Which is the way I recommend it - one LE host for the normies, one self-signed for the tech nerds. Anyway, I've rambled enough; let's proceed to generating a self signed certificate:

cd /etc/stunnel (this is so that the certs will be put inside the required folders after being generated)
openssl genrsa -des3 -out selfsignedcert.key 8192
(now choose a strong password)
openssl req -key selfsignedcert.key -new -out selfsignedcert.csr
openssl x509 -signkey selfsignedcert.key -in selfsignedcert.csr -req -days 3650 -out selfsignedcert.crt
(3650 is the length of time in days the cert is going to be valid for)
(now comes the fun part: filling your cert with information that will be shown inside the "View certificate" screens in browsers. Be careful because you can't go back! But you can put whatever you want in there, really)

Finally, you'll need to edit /etc/stunnel/stunnel.conf to point to the newly created certs:

[https]
client = no
accept = 443
connect = 0.0.0.0:80
cert = /etc/stunnel/selfsignedcert.crt
key = /etc/stunnel/selfsignedcert.key

You can still leave the old certs in the folder, just in case you want to switch back. Restart stunnel to apply, of course.

Uploading files

Let's finally get something up on that server, shall we? My favorite way of doing so is gFTP - it's graphical, it's easy, and does everything needed. So install it on your local machine (not the server!) by typing:

slapt-get --install gftp

Then run it with:

proxychains4 gftp

Proxychains needs to be installed and configured to use TOR - I've shown how to do this here. This is essential because you really don't want to reveal your real IP to your VPS; even using a VPN doesn't seem like enough when a file you upload there could get you busted by feds. In my proxychains guide I also explain how to make programs always run through it, with a specifically setup graphical icon in the panel. Anyway - after turning it on - go to gFTP -> Preferences and set them like this:

gFTP Preferences menu

You can use whichever editing program you want, of course (it won't be relevant often if you do it like me anyway). The other options I think are just the most sane ones; you can hover your cursor over them if you want to know what they do exactly. Click OK and fill the upper form fields like this:

gFTP upper form with server IP, port, username, password, and SSH2 chosen as the protocol

Of course, they have to correspond to what you really have on the server. Anyway, click the "two computers" button and you should end up connected:

gFTP folder lists

Left side contains the folders on your computer, right side - the ones on your VPS. Double click the folder you want to enter, on both sides. Then single-click the file you want to upload to your VPS (this selects it), and finally begin the transfer by clicking the arrow button:

gFTP with cursor over the file transfer button

Notice how the paths in the path fields changed. Anyway - while the file is transfering - this will be displayed below the folder listings:

gFTP file transfer  progress

When it finishes, gFTP will automatically refresh and you will see the file on the other side:

gFTP showing the turtle.png on the VPS side

Meaning you can access it at https://digdeeper.club/exposed/turtle.png. To go back (on either side), double click the line with the black arrow (no need to aim at it directly):

gFTP with cursor over the black arrow, AKA the back button

What else can gFTP do? Basically anything you'd want to while managing a site. Deleting files by right mouse button+delete. Mass transfer by shift+left mouse button, or ctrl+LMB if you want to skip some files. Editing remotely though I recommend doing it locally, then uploading - much more convenient and organized because you know you always have the same version everywhere. Renaming with RMB+rename, transfering back to your local computer with the reverse arrow nearer to the bottom (so you can use your VPS as an easy secondary backup, though space is very limited). Creating new folders, modifying permissions (including en masse by shift+RMB, like with deletions or transfers). In general, gFTP is faster and much less annoying than fiddling with the command line, which it pretty much deprecates (in terms of site management only, and not the myriad of other things you might want to do on the server, of course).

TBD: tor, i2p access; uploading files by gftp; self signed certs; getting domains; who knows what else...

Back to the front page