Skip to content →

Amir Eslampanah Posts

How To Install the Latest Ruby with Rails & LSAPI & OpenLiteSpeed

Ruby is a popular web programming language that is used for a variety of things while Ruby on Rails is a popular web programming framework that is used to create websites.

In this tutorial we will be installing both and demonstrating how to link them to OpenLiteSpeed. This tutorial assumes you followed the Installation and Configuration of OpenLiteSpeed with PHP, MariaDB, LetsEncrypt SSL, PHPMyAdmin, and NinjaFirewall on Debian 10 Buster.

We use GBEnv here as the current version of Ruby on Debian 10 (2.5.5) is below the minimum required version for some applications

sudo apt install dh-autoreconf autoconf bison build-essential libssl-dev libyaml-dev libreadline-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev curl git
git clone /var/lib/rbenv
git clone /var/lib/rbenv/plugins/ruby-build

Lets add that path to the profile path and the sudoers path

nano /etc/profile

Add the following line before export PATH




add the following to the end of secure_path (inside the double-quotes):


Now lets add it to the bashrc files, append the following lines to the TOP of the bashrc file

sudo nano /etc/bash.bashrc
export RBENV_ROOT=/var/lib/rbenv
eval "$(rbenv init -)"\

Make rbenv

cd /var/lib/rbenv/ && src/configure && make -C src

and reboot the system to ensure it applies to every user

sudo reboot

We need to initialize rbenv and check that it has been installed properly

rbenv init
curl -fsSL | bash

Finally we can install the latest ruby

rbenv install $(rbenv install -l | grep -v - | tail -1)
rbenv global $(rbenv install -l | grep -v - | tail -1)

Now we have to install git and some ruby gems

sudo gem install rubygems-update
sudo gem install rack
sudo gem install ruby-lsapi
sudo gem install bundler
sudo gem install rails

Time to test it out, Navigate to VHost Configuration in the OpenLiteSpeed Web Console

First we’ll need to enable SuExec in order to run ruby apps with rack later on, navigate to Basic->Security and match the settings below

Under Context, create a new Context and fill in the following details, and save

Now to make the directory (remember to replace VHOSTDIRECTORY with your VHOST’s directory) and the sample application

mkdir /var/www/VHOSTDIRECTORY/html2
nano /var/www/VHOSTDIRECTORY/html2/

Paste the following in for your sample application

app = proc do |env|
message = "It works!\n"
version = "Ruby %s\n" % RUBY_VERSION
response = [message, version].join("\n")
[200, {"Content-Type" => "text/plain"}, [response]]
run app

Then set the permissions

chown -R lsadm:lsadm /var/www/VHOSTDIRECTORY/html2

Now refresh your OpenLiteSpeed server configuration, and head over to your configured VHOST Domain

If you see something like this; congratulations you’re finished

Leave a Comment

Using LFTP to Easily Mirror/Transfer your Website on another VPS (Debian 10)

The traditional way of transferring files from one server to another is slow and requires a bunch of setup whether its done via archiving, imaging or direct file copy.

Instead you can use LFTP to easily mirror a remote directory on a new VPS.

Step 0:

We need to install lftp

sudo apt-get install lftp

Step 1:

Now we need to connect via ssh to our old server whilst on the new server’s terminal (this is to add its host key otherwise you may get an error in the next step)

ssh -p 22

Step 2:

Use the following series of commands to mirror the directory

open -u user,password s
mirror /path/remoteDir /path/localDir

That’s it!

Leave a Comment

How to Fix Bios Corruption on ASUS GL703GS Laptop (and others) using a CH341A Programmer

So a little while back, I was playing around with my machine’s BIOS, and without going into specifics. I messed it up big time.

So much so that eventually I couldn’t get a display to show and no display-out. Hence, I’ve decided to make this tutorial to help those in the same or a similar situation.

The techniques in this article should still apply to any other kind of laptop or computer system where there is a EEPROM that has enough space around it to attach an test clip to.

Note that this should be a LAST-DITCH effort to fix your machine. Try everything else, if it doesn’t work then proceed(Accept that I’m not responsible for anything that goes wrong on your machine).


  • To do this SPECIFIC repair you will require a 25 series EEPROM programmer. The series will vary depending on the model number of the BIOS chip on your machine.
  • You’ll need a programming software, in this tutorial we will use the open source AsProgrammer (Don’t worry the program has an English translation as well).
  • After extracting it you’ll find the CHA341A drivers in the package, install the parallel drivers.


Step 1:

Open up the laptop (Be sure it is powered off)

Step 2:

Find your BIOS chip.

In the case of this laptop it is the MXIC MX25L12873F, notice the 25L part, that refers to the series. It is important to get a programmer that is compatible with YOUR chip as they may have different spacing. Note the little dot on the left hand corner, that is the Pin 1 position, REMEMBER it, it is important later.

Step 3:

Disconnect the Laptop Battery (push the metal cover forward, then pull cable up)

Disconnect the CMOS Battery (pull out)

Step 4:

Use the assembled test clip to attach to the bios chip, MAKING SURE, that pin 1 position(the dot indicates pin 1) is connected to the wire that is coloured red/purple. You may need to adjust it several times till you can get a good connection, note that the 2nd red light on the programmer may not turn on until you attempt to write to the chip.

Step 5:

Open AsProgrammer and select IC->Search and put the model number of YOUR bios chip, double click it when you find it.

Step 6:

Now we need to make sure that the connection is good, unfortunately I haven’t found a really easy way of doing this.

Option 1: If you haven’t flashed before using a hardware programmer you can try to read the chip and make sure that you don’t get all 00 or FF in the hex view.

Option 2: You can try to Protect and UnProtect the chip, as this process will hang unless you have a good connection.

Option 3: You can try to program the IC with some random file or data and then read to see if the same hex data was read that was written.

Either way, once you’ve verified that the connection is good you can proceed.

Step 7:

Now its time to erase the IC and program it with the BIOS file you downloaded earlier.

First Erase the Bios, and wait for the complete message to appear below

Now open up the BIOS file

Now click Program IC

Then let it finish

Now its time to verify it was written correctly, so click Read IC

And ensure that the contents of the hex view are the same as before (just check the starting bits and the ending non-zero bytes to make sure they are the same)



Step 8:

Now its time to re-assemble the laptop, first re-connect the CMOS Battery, then the Laptop Battery, reassemble the laptop case, then plug in the charger, and give it a try. Hopefully at this point your machine should boot.

That’s it 😉

Hope this tutorial helps you out of a bind, it took me a while to figure this stuff out.

Helpful tip: If you are modding and have used the official updater program and are wondering why your BIOS keeps updating/bricking itself upon reboot, you need to remove the firmware BIOS update driver, in device manager (as that is where it installs)

Leave a Comment

How to Fix Winload.EFI and Other Windows 10 Boot Partition / Startup Issues

Recently, I ran into a problem when I tried to install another copy of windows on a different drive.

You see I had no idea that Windows 10 only keeps one copy of its boot-loader no matter many operating systems are installed.

I also had no idea that it merges any existing boot-loaders into the new one upon installation. In other words, when I installed windows on the new drive my old boot-loader was deleted and its contents were put into the new boot-loader ON THE NEW DRIVE.

This wouldn’t of been a problem if I hadn’t intended on using that drive for a completely different machine. Which is exactly what I did.

That meant that I couldn’t boot up my original machine anymore (without the new drive) because the boot-loader no longer existed on it.

After much trial and error, I ended up with a solution to this, and many other boot-loader issues.

The following steps should recover from almost any kind of boot-loader corruption/problem.

Step 1:

Boot into the Windows Recovery Environment using a USB or using the existing recovery partition on your system.

Open up command prompt and locate your windows drive. (Sometimes the drive letter will change in the recovery environment so be sure to find the correct letter).

Step 2:

Run the following commands in order, keeping in mind the drive letter you found earlier (be sure to replace the bracketed content and remove the brackets):

bootrec /ScanOs
bootrec /FixMbr
bootsect /nt60 SYS
bootrec /FixBoot
list disk
sel disk [Windows Disk # Here]
list part
sel part [System Partition # Here]
assign letter=V:
bootrec /RebuildBcd

Step 3:

Reboot to Windows

Note you may have multiple windows entries, try each one till you find the one that works

Now you can delete the extra entries using msconfig utility, and then check the box that says make boot changes permanent and hit apply.

You’re done 😉

Leave a Comment

Setting Recommended Security HTTP Headers in OpenLiteSpeed

Sometimes we spend so much time protecting our websites that we forget about protecting our users. It is more efficient to be proactive than reactive.

For this reason its a good idea to set some security HTTP headers so that if your users do get targeted by a hacker that they won’t be able to as easily fool them into handing over their credentials.

Step 1:

First lets open up the LiteSpeed WebAdmin console by heading over to

Now click on the magnifying glass icon to edit the virtual host and navigate to context

Navigate to the context tab and hit add

Make the type “Static” and hit the skip icon to the upper-right to go next

Now fill out the following, in the URI section put “/” or any subdomain you want, set accessible radio button to yes and add the following in the Header Operations box

NOTE: It is a good idea to understand exactly what Content-Security-Policy does before adding it, as if you use this without checking first if your scripts are loading anything outside your domain name it will stop those scripts from loading in browsers.

Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src https:
X-Content-Type-Options "nosniff" always
X-Frame-Options: SAMEORIGIN
Referrer-Policy: no-referrer-when-downgrade
Permissions-Policy: geolocation=(self ""),

Now you can hit the save button in the upper right and reload OpenLiteSpeed

Step 2:

To check that your headers have been set correctly, you can visit

And hopefully you’ll have a nice A+ result!


If you would like to learn more about these headers I suggest researching them individually.

Especially if you would like to have a more fine-tuned setup.

Please note that some of these settings can break your website if it isn’t built to use HTTPS or if it has errors/bad-practices in its make-up, please research/test each individual header prior to going to production with them.

One Comment

Installing and running Firefox via Flatpak

Flatpak is a neat little cross-distro package manager

Here’s a quickstart guide

Step 1:

Install flatpak

sudo apt install flatpak

If you use gnome you can also install this add-on so that you can browse flatpak applications in your desktop environment

sudo apt install gnome-software-plugin-flatpak

Next we’ll add the official flatpak repository

flatpak remote-add --if-not-exists flathub

Now we can install firefox

flatpak install flathub org.mozilla.firefox

Step 2:

Now as to how to run firefox, if you are using gnome you can just use the plugin mentioned previously and browse to it, however if you are trying to run it from console flatpak has a way to do that

flatpak run org.mozilla.firefox

That’s it!

Leave a Comment

How to Use rclone to Create or Mount a Copy of Your ©Microsoft OneDrive

Recently I’ve been getting these emails from Microsoft saying that my OneDrive account is about to be frozen ( Apparently they decided to chop everyone’s storage down after the fact to 5GB and then charge people for the excess storage they’ve already used up thinking it was free /facepalm ).

Thing is that I’ve been so busy with Life especially with the Covid-19 pandemic going on that I really don’t care about sorting out my OneDrive right now.

That being said my home connection sucks, I mean it’s really bad.

On a good day I get about 5-6mbit/s down and at that rate it would take about 37 Hours to download my entire OneDrive storage to my local system, not to mention it would piss off everyone else who wants to use the internet in the house.

Then I thought why don’t I just transfer these files to my VPS since I have the excess storage anyways and my VPS’s connection is a much more palatable 100mbit/s+ down.

In comes obstacle one, OneDrive doesn’t officially support Linux, so we’ll be using rclone to connect and download our files instead.

Step 1:

First we need to install rclone

curl | sudo bash

Easy enough am I right?

Step 2:

We need to configure rclone to connect to our onedrive account so it can fetch and mount the files for us.

Thing is this process actually requires a web-browser for the authentication part, so you cannot do it easily via console. In my case I ended up installing VNC (for which you can check my tutorial below) and Firefox (via flatpak which I will post soon).

Run the configuration prompt and type new to create a new remote server configuration

root@oneserver:~# rclone config

2020/06/16 14:31:56 NOTICE: Config file "/root/.config/rclone/rclone.conf" not found - using defaults
No remotes found - make a new one
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n

Next you’ll be asked what type of storage you wish to configure, in my case OneDrive was 23rd down the list but this may change in the future so be sure to check

Type of storage to configure.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
 1 / 1Fichier
   \ "fichier"
 2 / Alias for an existing remote
   \ "alias"
 3 / Amazon Drive
   \ "amazon cloud drive"
 4 / Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)
   \ "s3"
 5 / Backblaze B2
   \ "b2"
 6 / Box
   \ "box"
 7 / Cache a remote
   \ "cache"
 8 / Citrix Sharefile
   \ "sharefile"
 9 / Dropbox
   \ "dropbox"
10 / Encrypt/Decrypt a remote
   \ "crypt"
11 / FTP Connection
   \ "ftp"
12 / Google Cloud Storage (this is not Google Drive)
   \ "google cloud storage"
13 / Google Drive
   \ "drive"
14 / Google Photos
   \ "google photos"
15 / Hubic
   \ "hubic"
16 / In memory object storage system.
   \ "memory"
17 / Jottacloud
   \ "jottacloud"
18 / Koofr
   \ "koofr"
19 / Local Disk
   \ "local"
20 / Cloud
   \ "mailru"
21 / Mega
   \ "mega"
22 / Microsoft Azure Blob Storage
   \ "azureblob"
23 / Microsoft OneDrive
   \ "onedrive"
24 / OpenDrive
   \ "opendrive"
25 / OpenStack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
   \ "swift"
26 / Pcloud
   \ "pcloud"
27 /
   \ "putio"
28 / QingCloud Object Storage
   \ "qingstor"
29 / SSH/SFTP Connection
   \ "sftp"
30 / Sugarsync
   \ "sugarsync"
31 / Tardigrade Decentralized Cloud Storage
   \ "tardigrade"
32 / Transparently chunk/split large files
   \ "chunker"
33 / Union merges the contents of several upstream fs
   \ "union"
34 / Webdav
   \ "webdav"
35 / Yandex Disk
   \ "yandex"
36 / http Connection
   \ "http"
37 /
   \ "premiumizeme"
38 / seafile
   \ "seafile"
Storage> 23

Next you’ll be asked to enter Microsoft App Client Id and Secret, which we’ll ignore for now since we will be using the web authentication (just hit enter)

** See help for onedrive backend at: **

Microsoft App Client Id
Leave blank normally.
Enter a string value. Press Enter for the default ("").
Microsoft App Client Secret
Leave blank normally.
Enter a string value. Press Enter for the default ("").

Next it will ask you if you wish to enter advanced configuration, hit no unless you have something special planned

Edit advanced config? (y/n)
y) Yes
n) No (default)
y/n> n

Now is when you’ll be asked if you would like to auto-configure, and for this step we type yes

Use auto config?
 * Say Y if not sure
 * Say N if you are working on a remote or headless machine
y) Yes (default)
n) No
y/n> y

Now is when either your browser will open up for you or you’ll have to manually go to the link (note that I wasn’t able to connect to this port remotely, so it may be that you have to open it locally), once you go there you’ll be asked to login to your Microsoft account and allow rclone a bunch of privileges it needs to do its thing

If your browser doesn't open automatically go to the following link:
Log in and authorize rclone for access
Waiting for code...

Got code

Next we’ll be asked to describe exactly what type of account this is, which is a little redundant to be honest.. but well.. select 1 for OneDrive

Choose a number from below, or type in an existing value
 1 / OneDrive Personal or Business
   \ "onedrive"
 2 / Root Sharepoint site
   \ "sharepoint"
 3 / Type in driveID
   \ "driveid"
 4 / Type in SiteID
   \ "siteid"
 5 / Search a Sharepoint site
   \ "search"
Your choice> Your choice> 1

Next it will search for “drives” on the remote server, if you happen to have multiple drives you can pick which one. In my case I only have one so I select 0

Found 1 drives, please select the one you want to use:
0:  (personal) id=uniqueid834avsaf
Chose drive to use:> 0

Now it will ask you to confirm the root of the drive, just type yes

Found drive 'root' of type 'personal', URL:
Is that okay?
y) Yes (default)
n) No
y/n> y

At this point it will ask you to confirm that the access token was set correctly, type yes again

type = onedrive
token = {"access_token":"AWHOLEBUNCHOFSESSIONTOKENTEXTTHATYOUSHOULDNTSHAREWITHANYONE","expiry":"2020-06-16T15:40:51.775771327Z"}
drive_id = uniqueid834avsaf
drive_type = personal
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y

Now that were done with the configuration we can type quit

Current remotes:

Name                 Type
====                 ====
onedrive             onedrive

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> q

Step 3:

Now lets create the folder we will mount this OneDrive to

mkdir ~/OneDrive

We need to decide what type of mounting we want, in this case we wish to have full read/write access to our files even if they disappear from the server so we use –vfs-cache-mode full

But there are many modes so be sure to check the documentation in case you don’t need a full copy (

rclone --vfs-cache-mode full mount onedrive: ~/OneDrive

And we’re done!

Now we can try to copy the files over to a local directory using a second SSH shell

mkdir ~/OneDriveBackup
cd ~/OneDrive
rsync -avzh --ignore-errors * ~/OneDriveBackup/


WireGuard VPN Server (Debian 9) and WireGuard VPN Client (Windows 10) Setup and Configuration

Wireguard is a next-generation open-source VPN connection protocol that claims to be faster and more secure than Open-VPN.

In this tutorial we will cover how to setup and configure a WireGuard VPN Server on a Debian Linux Distribution as well as how to get a Windows machine to route all traffic through that VPN using WireGuard’s Windows Client.

Step 0 : Install Un-Attended Updates

First, lets ensure we setup automated updates as we will want security patches and its likely that we wont be touching this VPS for a while.

apt-get install sudo
sudo apt-get install aptitude
sudo apt-get update && sudo apt-get upgrade 
sudo aptitude update -y && sudo aptitude install unattended-upgrades apt-listchanges -y
sudo dpkg-reconfigure -plow unattended-upgrades

Step 1 : Install WireGuard and Generate Keys

First lets edit our sources

sudo nano /etc/apt/sources.list.d/unstable.list

add the following line

deb unstable main


sudo nano /etc/apt/preferences.d/limit-unstable

add the following lines

Package: *
Pin: release a=unstable
Pin-Priority: 150

Update your package lists and install WireGuard

sudo apt update
sudo apt install wireguard

Check that its loaded

lsmod | grep wireguard

Now lets ensure that IPv4 Forwarding is enabled

sudo nano  /etc/sysctl.conf 

Uncoment the following


Now to save we need to

sudo sysctl -p

Now its time to generate your VPN’s private key


wg genkey

It’s important to write this down somewhere safe and private it’ll look something like this


Now its time to generate the corresponding VPN’s public key using the private key we just generated

echo "uDXR7FnTzGarLNj+E3ePv4gOwsbjumZ7M9YjcKAQ8WI=" | wg pubkey

It’ll look something like this, write it down somewhere


Now its time to generate the User’s private and public key pair, note you will one for each user of the VPN (this essentially the same process as before)

wg genkey

Write down the User’s private key somewhere safe


Now lets generate the User’s public key

echo "0IoyeQyyWPYVGf4P4DosBGHHrl/T7k+2fqFc8JZRmGo=" | wg pubkey 

Write this down somewhere


Step 2 : Configuration of WireGuard Server

First we need to find our active interface

ip l

Will show something like

1: lo:  mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0:  mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether  53:55:00:91:36:5c brd ff:ff:ff:ff:ff:ff

Here eth0 is our interface, now lets check our public IP address

ip a show dev eth0
2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 53:55:00:91:36:5c brd ff:ff:ff:ff:ff:ff
    inet brd scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2103:90c0:186::20/48 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::5058:ff:fe89:c66d/64 scope link 
       valid_lft forever preferred_lft forever

So here we can see our public IPv4 address is

Now lets create our configuration file

sudo nano /etc/wireguard/wg0s.conf

add the following, note where the User’s public/ VPN’s private keys go as well as our public IPv4 address and client’s public IPv4 address

Address =
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADEACCEPT; iptables -t nat -D PO$
ListenPort = 8081
PrivateKey = uDXR7FnTzGarLNj+E3ePv4gOwsbjumZ7M9YjcKAQ8WI=

PublicKey = JoYcG0Bq5+dMrEAc8eSTG6QCFBjwUWxfXTy7LWmhC0k=
AllowedIPs = 
PersistentKeepalive = 25

Now lets start it up

sudo wg-quick up wg0s

Check that it is running

wg show

You can terminate it if needed using

sudo wg-quick down wg0s

Step 3 : Setup and Configure Windows 10 WireGuard Client

First lets download and install the WireGuard Windows Client

In this tutorial we will be using Windows 10 64 bit so hit the button for downloading that version

Run through the installer and then open up the WireGuard Interface

Click Add Tunnel -> Add Empty Tunnel

Now add the following in, being careful to swap the keys with yours (note here we are providing the User’s Private Key followed by the VPN’s Public Key, and that the first Address is our local address)

Address =
ListenPort = 50001
PrivateKey = 0IoyeQyyWPYVGf4P4DosBGHHrl/T7k+2fqFc8JZRmGo=
PublicKey = 9XIklpw4lGQ/I0S9L3gqTjwjJYsXJPluihomcCCrEzU=
AllowedIPs =, ::/0
Endpoint =
PersistentKeepalive = 25

Give it a name, Save and Activate

Now to check that it’s working head over to on your Windows 10 machine and you should now see your VPN’s IP Address as if it were your own

NOTE: I’ve yet to get this working myself over the internet, certain ISPs may block this protocol and there may be some bugs yet. This information was compiled from various sources over the internet, use at your own discretion.

One Comment

Installation and Configuration of OpenLiteSpeed with PHP, MariaDB, LetsEncrypt SSL, PHPMyAdmin, and NinjaFirewall on Debian 10 Buster

Step 0 : Unattended Upgrades

The preparation step is to install unattended upgrades as an un-patched web-server is a really bad thing

sudo apt-get update && sudo apt-get upgrade
sudo apt-get install unattended-upgrades apt-listchanges

Now edit the following file:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Un-comment the line:


And hit Ctrl+o and Ctrl+x to save and exit

Now to ensure /etc/apt/apt.conf.d/20auto-upgrades exists

dpkg-reconfigure -plow unattended-upgrades

Lets give it a test run to ensure things aren’t configured wrong

sudo unattended-upgrade -d

Step 1 : Install OpenLiteSpeed & MariaDB

First lets add the OpenLiteSpeed server to our a repository list in our Debian sources.list so we can get the latest version

wget -O - | bash

Now to install our packages (the nice thing is that OpenLiteSpeed now comes with PHP73 included)

sudo apt-get install openlitespeed mariadb-server
sudo apt-get install lsphp73-common lsphp73-curl lsphp73-imagick lsphp73-imap lsphp73-json lsphp73-memcached lsphp73-mysql lsphp73-opcache lsphp73-redis memcached

Lets ensure we can access the included WebAdmin GUI for OpenLiteSpeed by running the initial configuration script

sudo /usr/local/lsws/admin/misc/

You will be asked to set a username and password, set them to something secure and be sure to write them down somewhere so you don’t forget

Now you can load and access the GUI from a browser at any time wish:


Note: That you may encounter a certificate error on some chromium browsers, its okay to ignore this at this point, and proceed anyway if your browser allows it, otherwise use a different browser

Now lets do the initial configuration for MariaDB

sudo systemctl start mysql && sudo mysql_secure_installation

Important! You will be asked for the MySQL root password by default this is empty so just hit enter at this point

Now press “y” to set a secure MySQL root database password, then answer “y” to all the remaining questions (remember to write it down somewhere)

Step 2 : Configuring OpenLiteSpeed

Lets create the directory for a virtual domains and setup the directory structure in such a way that we can easily add more domains to our server in the future (remember to replace with whatever your domain name is)

mkdir -p /var/www/{conf,logs,html}
cd /var/www
chown -R lsadm:lsadm *

Now ideally we’d want our configuration files to all be in /var/www/

For some silly reason OpenLiteSpeed wont allow that so we have to do a bit of a Linux trick to get make it think we are actually under its directory of /usr/local/lsws/conf/vhosts

Lets first delete the existing directory located there (note if you have existing configuration files from a previous install, be sure to back them up; by default only an Example configuration is here)

rm -rf  /usr/local/lsws/conf/vhosts 

Now lets use a symlink to link our /var/www/ to /usr/local/lsws/conf/vhosts

ln -s /var/www /usr/local/lsws/conf/vhosts

Lets go login to WebAdmin (again located at SERVER_IP_ADDRESS:7080)

Now click on Virtual Hosts – > + Sign to add a Virtual Host

Fill in the following details:

Virtual Host Name:

Virtual Host Root: /var/www/$VH_NAME

Config File: $SERVER_ROOT/conf/vhosts/$VH_NAME/conf/vhconf.conf

Now hit save and you’ll get an input error, click the link to create the file

Ensure the following radio buttons are selected and hit save again

Now lets hit the green graceful restart button on the top right to get rid of this warning (note you will have to do this again every-time you update something in your configuration, i will only mention it this once but be sure you remember to do so)

Now hit the magnifying glass to view our configuration again and go to the General tab and edit the Document Root to $VH_ROOT/html and hit save again

Now hit Listeners on the left-hand navigation bar

Delete the default 8088 configuration as we wont be using it

Now create a new Listener in a similar fashion that we made the Virtual Host earlier

Well call this listener HTTP

Set it up to listen on port 80

HTTP isn’t a secure protocol, so we set Secure to No

Now save and create another Listener

Well call this listener HTTPS

Set it up to listen on port 443

HTTPS is a secure protocol, so we set Secure to Yes

Now we need to add Virtual Host Mapping to our listeners , first click add on Virtual Host Mappings

Next put the following values, and save

Virtual Host:


This needs to repeated for the HTTPS Listener as well

Step 2.1 : Updating DNS Records

Ensure that both the A record for @ and www are pointing to your SERVER_IP_ADDRESS

Step 2.2 : Continuation of Configuration

Now if we head over to in a browser we should get the following 404 error screen since we don’t have anything in our html folder yet

Congratulations if you’ve gotten to this point you’ve successfully configured your OpenLiteSpeed installation

Step 3 : SSL/HTTPS Configuration & Automation of LetsEncrypt

Important Note: This part of the guide is something you should do after creating all your Virtual Hosts for your domain names, as there is a verification step that will fail if your DNS isn’t properly configured

First install the certbot package, this will handle the certification generation for you.

sudo apt-get install certbot

Now use the following command to generate a certificate for each of your domain name(s) (remember to replace with your domain name)

certbot certonly --webroot -w /var/www/ -d -d

Now enter your email address, and agree to the terms as needed

If all goes well you’ll get a Congratulations!

Note the following two file paths as they are important

Your certificate and chain have been saved at: /etc/letsencrypt/live/
Your key file has been saved at:

Its time to configure our Virtual Host Configuration to utilize these, this time navigate to the SSL tab

Values to be set as follows:

TIP: You can use $VH_NAME in place of but this trick wont work for the Listener section that is about to come

Private Key File :


Certificate File:


Chain Certificate:


Now save and check all the Protocol Versions in the SSL Protocols section and save again

We do this to have broad compatibility with different browsers

Now we must repeat these steps for the HTTPS listener, as it will be the default mode (which then gets over-written by our specific Virtual Host Configuration)

Basically if no SSL certificate is found in the Virtual Host Configuration this one will be used

Currently it is mandatory to set this in OpenLiteSpeed

Note that here we cannot use $VH_NAME so we must use the domain name

Head over to and now you should see a re-assuring SSL Lock indicator on the left which means everything was configured correctly

Optionally: Use this same Certificate and KeyFile for your OpenLiteSpeed WebAdmin (gets rid of the certificate error when using instead of using SERVER_IP_ADDRESS:7080)

Now this certificate is only valid for next ~ 3 months, so to avoid an issue where users will get a certificate error in 4 months time, lets setup auto-renewal for our certificate(s)

First lets test that certbot is functioning correctly

sudo certbot renew --dry-run

Now assuming nothing went wrong lets create the cron-job to renew our certificates every month

sudo crontab -e

and add the lines

00 02 1 * * certbot renew >/dev/null 2>&1 
00 03 1 * * /usr/local/lsws/bin/lswsctrl restart

Step 4 : Installation of PHPMyAdmin

First head over to and find the latest version number (for me this was 5.0.1) then download using

cd /var/www

Now we unzip, rename, and then delete the now un-needed zip file

sudo apt-get install unzip
mv phpMyAdmin-5.0.1-all-languages phpmyadmin
chown -R lsadm:lsadm * 

Since we may want to access this same panel from various domains, lets create a symlink for our current domain instead of copying the folder over to the html folder

cd /var/www/
ln -s /var/www/phpmyadmin phpmyadmin

Now lets configure it to use our MySQL root user

sudo mysql -u root
use mysql;
update user set plugin='' where User='root';
flush privileges;

Some may tell you to create a separate user here for security reasons, but the fact is that phpmyadmin is most useful when run as root

We will address security concerns in the NinjaFirewall section

mv phpmyadmin/ phpmyadmin/
sudo nano phpmyadmin/

Now we need to generate a secret for the blowfish encryption, so just put any alphanumber character combination of length 32 here (May also grab one from


$cfg['blowfish_secret'] = 'csVH6hmV4_E5jNN7lVP8oWT_cY9avX_3'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

Now head over to and login with your MySQL root user

Important Note: Avoid using phpmyadmin over HTTP as it is vulnerable to a man-in-the-middle attack

Step 5 : Installation and Configuration of NinjaFirewall

Ninja Firewall is a Freemium Model General PHP Application Firewall that is most excellent in my experience at preventing exploitation of PHP Applications on your server

Lets head over to the free-download

The latest version at the time of writing is 4.0.3 so I’ll be using that

mkdir -p /var/www/fw
cd /var/www/fw
wget -O
chown -R lsadm:lsadm * 

Again for easy management we can create a symlink in our virtual host directory

cd /var/www/
ln -s /var/www/fw fw

We also need to set the correct permissions

cd /var/www/fw
chmod -R 0777 conf
chmod -R 0777 nfwlog

Now lets head over to to start the installation

You may have an error telling us our PHP configuration doesn’t have cURL support and to install it even though you already did

In this case simply do a complete server restart since there is some configuration nonsense for lsphp that doesn’t update when just the OpenLiteSpeed service is restarted

sudo reboot

Now they should all be green

Now hit the next until you get to the the setting an administrator username and password (pick a secure user-password and record it somewhere safe)

In the integration section, ensure the following is set

Protected Directory: /var/www

HTTP Server and PHP SAPI: Litespeed

Select the PHP Initialization file: php.ini

Now we need add our prepends accordingly

sudo nano  /var/www/.htaccess


# BEGIN NinjaFirewall
php_value auto_prepend_file /var/www/fw/firewall.php
# END NinjaFirewall


sudo nano /usr/local/lsws/lsphp73/etc/php/7.3/litespeed/php.ini

Edit the existing auto_prepend_file = to

; Automatically add files before PHP document.
 auto_prepend_file = /var/www/fw/firewall.php

Save and restart the OpenLiteSpeed server using

pkill lsphp
/etc/init.d/lsws restart

Then select next on the installer and hopefully you get no errors 🙂

Lastly we need to make our config file writable

chmod 0777 /var/www/fw/conf/options.php

You can now login and manage your Ninja Firewall at note should you have any issues installing/using applications later on, it is highly advised to check the firewall logs first!

Step 6 : Some Final Tweaks

It is a good idea to force HTTPS on your domains to ensure your login information isn’t snooped on

Lets go to the virtual host configuration again, this time on the Rewrite tab and do the following

Enable Rewrite : Yes

Auto Load from .htaccess : Yes (This setting will help with installation scripts later)

Rewrite Rules:

rewriteCond %{HTTPS} !on
rewriteCond %{HTTP:X-Forwarded-Proto} !https
rewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

Now we should probably setup OpenLiteSpeed itself to automatically update

However since the current update script messes with some package defaults, we need to make some explicit edits to the configuration

sudo nano /usr/local/lsws/conf/httpd_config.conf

Ensure the following 2 lines are set to lsadm and save

user                      lsadm
group                     lsadm

Now we need to add the update script to our cronab

sudo crontab -e

Add the following line, which will run the official update script daily

30 2 * * * /usr/local/lsws/admin/misc/

That’s it! My longest tutorial in quite a while. Hope this helps.

One Comment

Getting XIDU PhilBook Max to Play Nice with Linux

This notebook uses a misidentified SYNA3602 ; which in actuality is likely a Hantick Touchpad.

Problem One – Non-Working TouchPad

The first problem is that the i2c_hid portion of the Linux kernel expects this device to throw an interrupt after being reset, which it doesn’t do.

So for example in Clear Linux there may be failure to reset touchpad error messages.

Apparently this was patched later, pushed upstream and yet somehow is still breaking after reboots.

So in order to get a touchpad that is working between reboots you need to build/install the following package (note here I’m using Manjaro, but the code is simple enough you can build your own script for in other distros fairly easily):

This will usually get the touchpad to start working after a reboot (wait for the service to run before presuming it didn’t work).

To build and install under Manjoro:

pacman -S base-devel
makepkg -si

and be sure to Reboot

Important Note:

If your touchpad(or even the touchscreen) wasn’t working before, this may not fix it.

That’s because the touchpad, and even the touchscreen can lock-up completely if they are improperly initialized by Linux. Something to do with voltage spike maybe? I’m not sure.

In this scenario the only solution I’ve found is to install Windows 10 and then install the proper driver pack, reboot and then install Linux (a real pain to be sure). However to minimize this pain you can use Rufus to install Windows 10 onto a USB drive and then boot it as a Live-USB, which can help avoid the whole re-installing Linux part.

After booting Windows 10 (with the proper driver pack installed) the touchpad and the touchscreen should resume working in Linux. You can actually repeat this as necessary until you get a working installation in which case I highly recommend getting a full system image backup.

Note: It’s a good idea to disable driver updates in Administrative Templates in Windows if you plan on doing this, otherwise Windows may override your good drivers with bad ones from Windows Update.

Problem Two – The Touchscreen Rotation Issues

First lets install the sensor proxy :

sudo pacman -S iio-sensor-proxy

Next lets install the build requirements for GuLinux’s ScreenRotator (

sudo pacman -S base-devel qt5-declarative qtcreator qt5-sensors cmake git clang 

Next lets build it..

git clone
mkdir ScreenRotator/build
cd ScreenRotator/build

but wait there is a problem

The orientations used do not match the Goodix TouchScreen orientations matrix.

If we build and run as is we will have the screen oriented in the wrong direction as we turn it around. Specifically the following needs to be interchanged:

RightUp <==> TopUp 
LeftUp <==> TopDown

So lets be sure to update the /src/orientationsensor.cpp accordingly.

Specifically change this:

d->to_orientation = {
    { QOrientationReading::TopUp, TopUp },
    { QOrientationReading::TopDown, TopDown },
    { QOrientationReading::RightUp, RightUp },
    { QOrientationReading::LeftUp, LeftUp },

to this:

d->to_orientation = {
    { QOrientationReading::TopUp, RightUp },
    { QOrientationReading::TopDown, LeftUp },
    { QOrientationReading::RightUp, TopUp },
    { QOrientationReading::LeftUp, TopDown },
cmake ..
make all
sudo make install

Now you just need to run the Screen Rotator located at /usr/local/bin/screenrotator

Alternatively you can reboot as this should start up with Linux on the next boot.

And now both the touchpad and touchscreen should be usable, I hope this helped you as it took me almost 2 work days to get this to behave correctly.

Leave a Comment