[2020] Add Incoming Call Notification via Telegram API to FreePBX/RasPBX/IncrediblePBX

For our PBX system, we are looking for a solution where we get notified for incoming calls via Telegram App. Following guide will enable a simple Incoming Call Notification via Telegram using API. This method is tested on FreePBX, RasPBX and IncrediblePBX.

Why Telegram?

Telegram is an open-source cloud-based instant messaging and voice over IP service with support for Android, iOS, Windows Phone, Windows, macOS and Linux. Users can send messages and exchange photos, videos, stickers, audio and files of any type.

STEP 1 : Creating BOT in Telegram

The very first thing we need to do is BOT CREATION. For that, we need to search for a username @BotFather

Once located, we need to use the following commands to create our bot.


  • /newbot – executing command for creating new bot;
  • Google Cloud Platform – choosing a name for our bot;
  • gcponlinebot – choosing username for our bot;
  • /setuserpic – this is optional, but you can apply some kind of a ‘profile picture’ for your bot;

In above screenshot, you can see highlighted API token, (1273621638:AAG1EmfaptRrot2LCJrxobYfryrlIC9o-ow), which we will use later on. Remember this API Key.

Open a new chat with your bot and execute the /start command – it`s required for bot activation. Without this, BOT will not work.

Now, add your bot to the group chat. You can do it the same way as you are inviting new participants to the group chat – just search for your bot`s username in search and add to the group. Now in your group chat execute the following command:

/join @gcponlinebot

In your case, it will be username of your bot after @ symbol. Then you need to open following URL in web-browser:

XXXXXXXXXXXXXXXXXXXXXX – your token. In our case it looks like this:


Let’s get Group Chat ID.  In our case, it’s -452784357. You can also take out Group Chat ID from Replace ‘g‘ with ‘‘ for Telegram Group Chat in AGI Script below. If you want to forward notifications to normal user, just remove ‘-‘ sign.

Let’s start Asterisk script creation.

STEP 2 : Creating PHP-AGI Script for Asterisk

Script is written on PHP and it will be called from Asterisk dialplan through AGI. Script content is below:

nano /var/lib/asterisk/agi-bin/telegram.php

#!/usr/bin/php -q
$agi = new AGI(); 
$cid = $agi->request['agi_callerid'];
$dnid = $agi->request['agi_rdnis'];
# $phoneFieldset1 = "Incoming Call : "; [Old Setting]
# $phoneFieldset2 = "Calling at : "; [Old Setting]
$token = "1273621638:AAG1EmfaptRrot2LCJrxobYfryrlIC9o-ow";
$chat_id = "-452784357";
$arr = array(
# $phoneFieldset1 => $cid,
# $phoneFieldset2 => $dnid,
'Incoming Call:' => $cid,
'DID Number   :' => $dnid,
foreach($arr as $key => $value) {
$txt .= "".$key." ".$value."%0A";

 You need to add your own data in $token and $chat_id variables. Save the script with telegram.php name and put it into /var/lib/asterisk/agi-bin/ directory. Then, you need to give it proper execution rights and convert it into unix format:

chmod 755 /var/lib/asterisk/agi-bin/telegram.php
chown asterisk:asterisk /var/lib/asterisk/agi-bin/telegram.php
dos2unix /var/lib/asterisk/agi-bin/telegram.php

[If dos2unix is not installed, use apt-get install dos2unix or yum install dos2unix command.]

In advance, please save your PHP-file in UTF-8(without BOM)

STEP 3 : Loading PHP-AGI Script in Asterisk Dialplan

Now, we need to adapt the script in dialplan. We are gonna send notifications about calls on entry point – on SIP-trunk. So, you need to add following string to its context:

exten => _.,n,AGI(telegram.php)

Example: I’ve added it in an incoming call email notification context called [custom-send-email]:

nano /etc/asterisk/extensions_custom.conf

exten => s,1,NoOp(Entering user defined context  [send-email] in extensions_custom.conf)
exten => s,n,TrySystem(echo 'Incoming call from ${CALLERID(number)} [ ${CALLERID(name)} ] at ${FROM_DID} received ${STRFTIME(${EPOCH},,%l:%M:%S %p %Z on %A %B %e)}' | mail -s '${CALLERID(number)}#${CALLERID(name)} - Call Notification HomePBX' '')
exten => _.,n,AGI(telegram.php)
exten => s,n,hangup()

Create a Custom Extension with Dial String: local/s@custom-send-email

Create Ring Group and Add Custom Extension Number in it along with other Extensions.

Allow Inbound Calls to go to Ring Group

Now, Save & Restart Dialplan.

asterisk -rx 'dialplan reload'

Call and Enjoy Notifications on your Cellphone!


[2020] Free SSL HTTPS for FreePBX/IncrediblePBX/RasPBX Let’s Encrypt

Problem : In FreePBX, you are asked to whitelist follow 4 FQDN’s. However, this information is stale. Since 19th February 2020, Lets Encrypt now validate challenges from multiple network vantage points. There are no specific set of IP Addresses, therefore we have to come up with a different way to deal with this issue.

Whitelisting following FQDN’s is an Outdated method and will not work:

NEW METHOD: SSH into your VPS using Putty and follow Guide Below:

Step 1 : Add VirtualHost at Port 80

nano etc/httpd/conf.d/certbot.conf

 Add following lines as Virtual Host at Port 80:

    DocumentRoot /var/www/html 

Save certbot.conf and exit.

Reload httpd Service

systemctl reload httpd

Step 2 : Install Certbot and Enable SSL/HTTPS using Lets Encrypt

We will basically allow certbot to use pre-hook and post-hook function to toggle iptables and allow Lets Encrypt to handshake using Port 80.

yum install python-certbot-apache

certbot --apache -m -d --pre-hook "systemctl stop iptables" --post-hook "systemctl start iptables"

If you want to Install Certificates Only and will Modify Apache on your own: 

certbot certonly --apache -m -d --pre-hook "systemctl stop iptables" --post-hook "systemctl start iptables" 


Press A to Agree Terms of Service
Press Y to share your email address

When it prompts to “Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access”, Pick option 2. This is IMPORTANT!

2: Redirect - Make all requests redirect to secure HTTPS access

After that, the SSL client should install the cert and configure your website to redirect all traffic over HTTPS

You should test your configuration at:

Step 3 : SSL Certificates Installed. Add Cronjob:

You will get the following message

 - Congratulations! Your certificate and chain have been saved at:
   Your key file has been saved at:
   Your cert will expire on 2020-08-16. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"

Now we should add cronjob to automatically renew certificates

crontab -e

Then add the line below and save.

0 1 * * * /usr/bin/certbot renew & > /dev/null

This will attempt to renew certificates 30 days before certificate expiring.

Note: If you want to change default editor from vi, use the following command:

export EDITOR=mcedit OR export EDITOR=nano

Now Refresh your FreePBX/IncrediblePBX/RasPBX Dashboard and look at Padlock sign next to URL to make sure website is secure.

NOTE: You can also achieve the same result by disabling ‘iptables’ and then go to:

Admin > Certificate Management > New Certificate > Generate Let's Encrypt Certificate > Generate Certificate.


[2020] – Easily Build/Host WordPress Website with Google Cloud Platform Free‎

Step by Step Guide

Welcome To GCP’s Tutorial – This Tutorial will guide you on how to set up your webhosting for less than a $1 for an entire year.

Why pay so much for third-party webhosting when you can pay for less than $1 for an entire year on webhosting … and not just that … you’ll be hosting in google’s own data centre. You’ll be cutting cost on extra hardware or anything else for that matter.



  1. Active Credit/Debit card to enable Google Cloud services to get $300 credit for 12 months.
  2. Google G Cloud SDK : I highly recommend Google G Cloud to be installed on your computer. Web-based SSH is an alternative solution, however it gets a little fussy and require expert knowledge. Therefore, I always recommend using G Cloud SDK. You can find download links of G Cloud SDK at . Choose installer according to your operating system.
  3. Domain : Have a domain name handy, because we would be needing it to set up our wordpress website.
  4. Since you need to direct your website’s traffic to your Google Cloud’s WebHost, your webhost need to set up a Static IP. This is basically what google cloud is going to charge for. And it’s going to be in cents, so not issues. Infact, even those webhosting companies you are paying right now have been using these same data centres and then charges you extra. Meaning, you’ll be paying 20 to 30 dollars per month and they’ll be paying cents while keeping the rest of your money in their pocket.

This video is going to be lengthy so do check time stances in description below.

Google Cloud Platform is extremely powerful, cost-effective and highly customizable. It had sounded too good to be true to me too, however you guys are going to love it once you get it going. So, lets get started.

We’ll be setting up an instance on Google Cloud Platform’s Free Tier (GCP Free Tier). Google Cloud Platform has some free products which are “Always Free” even after end of trial period. We’ll be utilizing this free tier in this guide. More :

Regions and Zones :

In this guide, we’ll be having our own wordpress system installed instead of running Bitnami deployment. I found Bitnami deployment to be slightly slower. You can experiment with both to choose which one you prefer.


(if you already have an active Google Cloud account, you can safely ignore this first step)

First of all, you need to create a Google Account. Good News is … if you already have a Youtube or Gmail account, then you already have a google account. So, you can straightaway go to link and enable your Google Cloud services. Here, you basically need to select your country and agree to “Terms of Service” by checking tickbox and then click on “AGREE AND CONTINUE”.

Next, you’ll see an option called “TRY FOR FREE”. This trial period will basically give you $300 credit for 12 months. To avoid spam, Google will ask you to verify your identity by selecting your country and provide your debit or credit card with correct address to verify you. It’s a 2-step process and once you have successfully completed this process, your Google Cloud Platform will become active immediately. There are no charges during trial period and you will not be automatically charged or switched into paid account. You will have to manually opt for paid account.

Now lets go to STEP 2.

STEP 2 : Google Cloud Console

Now that we have an active Google Cloud Platform, next thing is we go to Google Cloud Platform’s console by going to Here, you have to create “Projects” first and then run instances in it. So, the very first thing we do in this console is create “New Project” and select a name of our own choosing. Let’s just name it GoogleCloudPlatform and select create. Now, we have a Project and we can work inside our project however way we choose to.

STEP 3 : Create VM Instance.

Go to NAVIGATION MENU on top left corner (three horizontal lines) and look for “Compute Engine”. On screen, it says “CREATE”. This will create our VM instance where we’ll be hosting our wordpress site. Choose a name of your choice. Make sure it doesn’t have any space. For Region, we’ll select us-central1 (IOWA) because it falls under “Always Free” tier. You can choose any region according to your location nearest to you. Zones don’t matter much, therefore you can choose whichever one you want to. VM instances are located in zones or zonal persistent disks, Static external IP addresses are regional. Regional resources can be used by any resources in that region, regardless of zone, while zonal resources can only be used by other resources in the same zone. One region can have multiple zones located in several places.

In machine configuration, we’ll be choosing N-1 ‘first generation’ series and for machine type, we’ll opt for f1-micro instance.

For Boot Disk, you can choose whichever OS you are comfortable with. For this guide, I’ll be using LTS version of Ubuntu. LTS means “Long Term Support” which basically means you’ll always have the latest patches and security fixes open source world has to offer. 20 Gigs of would be enough for now. There’s not much of a difference in Standard Persistent Disk and SSD Persistent Disk in terms of pricing. So, you might as well choose SSD due to better speed and performance.

In firewall section, make sure both HTTP and HTTPS traffic options are enabled.

So, final check for this one:
Name : googlecloudplatform
Region : US-central1 (Iowa)
Zone : us-central1-a (doesn’t matter)
Machine Configuration – Series : N1
Machine Configuration – Machine Type : f1-micro (1 vCPU, 614 memory)
Boot Disk : Ubuntu 18.04 LTS (20GB SSD)
Firewall : HTTP, HTTPS enabled.

Now press CREATE! It’s going to take some time, like a minute or two, for VM instance to come online.

If you see a green tick logo next to your instance, it means you have successfully created your VM instance.

STEP 4 : Converting Ephemeral IP into Static IP.

As a web-hosting server, your VM should have a static IP address. Therefore, we’ll be doing some changes in Google Cloud Console and from there, we’ll go to NAVIGATION MENU > VPC Network > External IP Addresses.

Here, you’ll see your VM instance assigned an Ephemeral IP address. You need to change it to static. Click on “Ephemeral” and change its type to “Static” and it will open up “Reserve a new static IP Address”. Write any name and description for it and click on RESERVE button. It will reserve that same IP already assigned into static IP.

STEP 5 : Connect to VM Instance.

There are different ways to connect to VM instance. 
a) Google G Cloud SDK (g cloud command) – easiest
b) SSH button visible next to your VM instance at Google Cloud console.
c) Putty SSH – You’ll have to Generate a key using Putty Key Generator and add that key in Metadata’s SSH Keys tab manually.

For this guide, we’ll be using g cloud. You can get your g cloud apt-get command from here. Copy/Paste this command in your g-cloud SDK Shell and it will automatically connect you to your VM instance via SSH. For first time, since you don’t have any PPK SSH key, Public SSH key and Private SSH key, g cloud will generate it for you and update project’s SSH metadata.

Just copy this g cloud command, paste it in G Cloud SDK and You will then be connected to your VM instance via SSH… just like that!

STEP 6 : Setting up your domain.

If you don’t have a domain name, you can simply edit your host file and add your VM instance’s static IP in there along with whatever fake domain name you can think off and you want it to be routed to. This will take DNS out of the equation and your Google Cloud as well your host system will think this website is real and we can then configure our wordpress.

Since is your VM’s static IP, in VM instance, you need to edit your host file and add the following:

sudo nano /etc/hosts

And add the following line:

You will also need to edit host file in your local PC you are running at your home.


To get your VM’s IP address, we’ll run curl command like:


This will give you your VM’s IP address. Copy that and paste it the following in your Domain’s DNS A Record. Hence, any traffic going to your web domain will go to your VM instance via static IP address

For this tutorial, we’ll use a real web domain :

Now, there are two ways you can set up your domain.

a) Add VM’s static IP address as A Record in Domain’s DNS settings. (usually takes few minutes)

b) Change Nameserver to Google Cloud’s assigned Nameservers and let google cloud handle this domain’s DNS records. (can take 24 to 48 hours)

For this tutorial, we’ll be opting for b) and proceed as follow.

Create a new Zone, enter Zone Name (whatever you want it to be) and then write your domain url in DNS Name. Keep DNSSEC off and Description is optional. Now, press “Create” and this will create DNS record for your domain. Find “NS” sub-record in it and copy/paste these records in your domain registrar’s DNS settings. These changes may not be instant as DNS propagation takes time (usually 24 to 48 hours). You can keep checking your NS records at

Now, Google Cloud’s Cloud DNS will be handling DNS records of our domain :

You can also add “A Record” and point it to your VM instance’s static IP address.

STEP 7 : Installation – Upgrade and Update VM instance.

Now, the very thing we always do is run the following commands:

sudo apt update && sudo apt upgrade

Google Cloud guys are constantly updating their image files as these things get constantly being launched by Web developers, system admins, etc. Therefore, whenever you update it, it’s usually done with couples of packages getting installed in a minute or so and that’s it!

STEP 8 : Installation – Installing Swap File and Optimizing Performance.

If you enter command ‘htop’, you will see that you don’t have any swap file by default in your instance. Since, we are working with micro instance … 582 megs of ram, 1 shared CPU … which is not much, obviously we’ll be needing our swap file to optimize its performance. So, Lets get this set up first.

fallocate -l 1G /swapfile 
dd if=/dev/zero of=/swapfile bs=1024 count=1048576 
chmod 600 /swapfile 
mkswap /swapfile 
swapon /swapfile
nano /etc/fstab

Alright. Time to edit our FSTAB file and simply add the following line in it:

/swapfile swap swap defaults 0 0

After editing, do $ sudo mount -a to make sure no misspellings are there.

After SWAP file, Lets go to htop and verify SWAP file settings. There you go! Swap file is showing as 1Gig.

STEP 9 : Installation – Installing LAMP Server.

Now, moving on to install LAMP Server (Linux, Apache, MySQL, PHP/Perl/Python). PHP is basically the core of any website handled by system admins. Installing LAMP Server is the easiest way. It’s also very quick to install. So, lets get going right way:

apt install tasksel 
tasksel install lamp-server

(it’s gonna take around 30 seconds). (Now, lamp stack is installed, now lets do that extra bit of apt stuff we need to get our wordpress going. You can find these commands in description below. Just copy/paste it.

apt install php-curl php-gd php-mbstring php-xml php-xmlrpc

(this will install all the dependencies and once it’s done, we’ll get right down to configure our wordpress. Right now, all the prerequisites are min. met. It’s time to jump into the configurations.

STEP 10 : Installation – Adding Domain name in our Apache Configuration file.

It’s now time to add our domain name in our Apache configuration file. So, we’ll do:

cd /etc/apache2/sites-available/

Now that we have default site, we need to create a new one for our website by using sample configuration file

cp 000-default.conf

It’s a good practice to have configuration file the exact same name in case when you have multiple websites hosted on one sever. You can also edit default config file and it will work too.

Remember that if you are only hosting single website on your server, you can leave it as /var/www however if you are hosting multiple websites, you will need to change each website to its own directory as I’m about to show you here.

Lets now edit config file and edit accordingly:

Require all granted

ServerAdmin webmaster@localhost
DocumentRoot /var/www/

Now create a directory 
mkdir -p /var/www/

copy index.html from root www directory to
$ cp /var/www/html/index.html /var/www/

Disable default site
a2dissite 000-default.conf

Enable website

Reload Apache2
systemctl reload apache2

That’s it for setting up Apache2 server.

Now we open website and you’ll be able to see a webpage being displayed.

STEP 11 : Installation – Preparing Database

Lets install database the terminal way because this is much easier and simpler way for me.

Create database ( Use semicolon after every mysql command. )

mysql for user root 
mysql -u root 
GRANT ALL ON wordpress.* TO 'wordpressadmin' IDENTIFIED BY '!Asdf4321';

Select Y for Validate Password plugin
For this guide, I’m going to choose low password, but you should always make sure your password is strong, or at least medium.

We’re going to enter and reenter root’s password here :

Select Y for Remove Anonymous user
Select Y for Disallow Root login remotely
Select Y for Remove Test Database and Access to it
Select Y for Reload privilege table now

That’s it. Your database is all set and mysql is secured. Make sure you remember the passwords you’ve used in line

GRANT ALL ON wordpress.* TO ‘wordpressadmin’ IDENTIFIED BY ‘!Asdf4321’

STEP 12 : Setting up PHP

For making PHP modifications, go to PHP directory

cd /etc/php/7.2/apache2
nano php.ini

From here, we need to make the following 3 changes. Lets use F6 or CTRL+W command to search for these lines.
max_input_time = 30
upload_max_filesize = 20M //2meg is extremely low for file size, especially if you’re migrating wordpress. You can edit it according to your file size preference.
post_max_size = 21M

So, now we’re done with PHP’s setting as well. You can also make other security measures here by changing other values, however we’re not going to dive into that in this guide.

STEP 13 : Finally install WORDPRESS

Finally it’s time to install wordpress.

Lets go to 
cd /var/www/

We have our index file sitting there. Lets move that index.html file to a lower directory

mv index.html ..

Now, lets see this directory:


It’s all clean now So, it’s time to install latest wordpress via wget:


From here, we’ll just do a tar extract. This will extract all files in a new folder called wordpress. Since, we want it in website’s root directory, we’ll just move all files from wordpress directory like this:

tar -xzvf latest.tar.gz

cd wordpress/
mv * .. 
cd ..
ll / all our files will now be visible in our website’s root directory.
rm wordpress/ -r
ll /wordpress directory is removed now.
rm latest.tar.gz /this will remove that tar zipped file.

Now, we’re done with the installation part of wordpress. In next step, we’ll be making wordpress configuration.

STEP 14 : Configuring WORDPRESS

First thing we’ll do is we’ll make a copy of sample wordpress config file and then set it up using our credentials.

cd /var/www/
mv wp-config-sample.php wp-config.php

If you are running a live server here, I highly recommend you hurry up because your system is completely wide open.

Lets jump to configuring wp-config.php file

nano wp-config.php

and make sure your file have correct database credentials you made earlier in Step 9.
GRANT ALL ON wordpress.* TO 'wordpressadmin' IDENTIFIED BY '!Asdf4321'

Leave the rest pretty much as default. Last thing to edit in it is the SALTS. Go to and generate new keys. Copy/Paste it back into it here. Do not leave default values as it is.

That’s it! Done! We’re pretty much done with wordpress configuration here. Lets check our website …. And here it is!

Lets create wordpress site title, username, password (make sure you save it somewhere safe), enter our email and click “Install WordPress”. It’s installed fairly quickly and you can test your credentials by going to admin page.

Welcome to WordPress – from here, you can take it and go. You now have your very own wordpress from hosting solution which you’re paying literally cents.

This setup and guide is made for lower end users, for about a 1000 visitors a day on your website. You can rev it up according to your own requirements. Everything in wordpress display right now is in stock settings – out of the box. You install your themes and plugins and go on from there.

STEP 15 : Tuning up VM instance

There’s tuning up which needs to be done because micro instances are over-tuned by default – meaning they allow way more traffic than they should. You should be able to throttle it using what’s called MPM_PREFORK

For this system, we’ll do the following to run this script. You need to give at least a couple of days before this script can give you actual results:

nano /etc/apache2/mods-enabled/mpm_prefork.conf

Here: it’s tuned for full system, which micro-instance is not. So, lets change it to following:
StartServers : 1
MinSpareServers : 2
MaxSpareServers : 5
MaxRequestWorkers : 10
MaxConnectionsPerChild : 1000

Lets save here.

Now, lets install this awesome script by Richard Forth to root of our VM:

cd ~
chmod +x       //lets make it writeable 

It will go through your settings and will report back to you what will be your recommended settings. Like I said before, since this is a brand new instance with really low uptime, you have to give it at least couple of days before you re-run this script and see recommendations. If you’re going to use a lot of plugins, memory usage will go high and you need to increase your intance’s memory.

STEP 16 : Enable Free SSL / HTTPS using Let’s Encrypt and Certbot

Phase 1:

apt-get install python-certbot-apache
certbot --apache -m -d -d

Press A to Agree Terms of Service
Press Y to share your email address

When it prompts to “Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access”, Pick option 2. This is IMPORTANT!

2: Redirect - Make all requests redirect to secure HTTPS access

After that, the SSL client should install the cert and configure your website to redirect all traffic over HTTPS.

You should test your configuration at:

You will also notice a new SSL.conf file at /etc/apache2/sites-available/ . This is Apache2 SSL module configuration file and should contain the certificate definitions defined in it

Phase 2:

You can change your wordpress URL by editing /var/www/ and adding following lines:

 //Use HTTPS for WordPress 
 define('FORCE_SSL_ADMIN', true); 

Save and exit. Now you should be able to logon to WordPress admin dashboard via HTTPS…

Phase 3:

Install “Search and Replace” Plugin in wordpress and use it to replace all http references in database to https.

– Choose “Search and Replace” Tab
– Search for :
– Replace with :
– Select table : check “SELECT ALL TABLES

This should be it. Website should be HTTPS compliant.

Now we should add cronjob to automatically renew certificates

crontab -e

Then add the line below and save.

0 1 * * * /usr/bin/certbot renew & > /dev/null

This will attempt to renew certificates 30 days before certificate expiring.

STEP 17 : Troubleshooting – WordPress Permission errors

One important addition to setting up WordPress. Permission errors with the WordPress installation can be fixed with the following command.
chown -R www-data:www-data /var/www/*
This adds permissions for the Apache server user to use the files in the webpage directory.

STEP 18 : Enable MailGun

[NOTE : Mailgun may have changed their policy and moved this feature to Paid Version]

You can use “MailGun” wordpress plugin which is super easy.
You may have to use your Credit/Debit card to enable “custom domain” setting in Mailgun.


We’ll use subdomain as MX domain which will be used for sending emails via MailGun. Since our server is based in US, we’ll choose US. You can enable DKIM Authority to 1024 or 2048 according to your requirement. Lets choose 1024.

Once your domain is verified and set up, you can enable your MailGun plugin via API by going to SETTINGS > API KEYS and copy/paste “Private API key” in API dialog box.

STEP 19 : Troubleshooting – Setup .htaccess file

The .htaccess file is a configuration file that affects how a webserver responds to various requests. It is supported by several webservers, including the popular Apache software used by mosy commercial web hosting providers. .htaccess files operate at the level of a directory, allowing them to override global configuration settings of .htaccess directives higher in the directory tree.

If you don’t have .htaccess file, you can create a new one by entering following command:

nano /var/www/

And copy/paste the following in it

# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress

sudo chmod 644 /var/www/

This will set .htaccess file’s permission to 644.

If you want, you can also set file permission access rights as follow:
chown -R www-data:www-data /var/www/

You can also let WordPress Plugins handle .htaccess file, such as WP HTACCESS EDITOR

You can also enable mod_rewrite if it’s not enabled and restart apache2:
a2enmod rewrite
systemctl restart apache2

STEP 20 : Troubleshooting – Permalinks JSON Error Fix

Remember that our /etc/apache2/sites-available/ file may end up completely being overridden in Ubuntu’s default /etc/apache2/apache2.conf file and your wordpress might give you following JSON error:

Updating Failed. Error message: The response is not a valid JSON response.

when editing pages or changing permalink settings from plain to post name, etc.

To fix that, edit /etc/apache2/apache2.conf and Lookup following:

change from AllowOverride None to AllowOverride All. Save it and restart apache by 
systemctl restart apache2


Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start writing!