Resetting ESXi Evaluation License

#!/bin/sh
## remove license
echo 'Removing License'
rm -r /etc/vmware/license.cfg
## get a new trial license
echo 'Copying new license'
cp /etc/vmware/.#license.cfg /etc/vmware/license.cfg
## restart services
echo 'Restarting VPXA'
/etc/init.d/vpxa restart

Edit /etc/rc.local.d/local.sh and add:

/bin/kill $(cat /var/run/crond.pid)
/bin/echo "**59** /vmfs/volumes/ZFS0/reset-eval.sh" >> /var/spool/cron/crontabs/root
crond

This will reset the license via cron job every 59 days (eval license expires 60 days).

This was confirmed working in ESXI v7.0 U1.

Install Organizr on Ubuntu 20.04

I couldn’t find a good and concise setup guide for Organizr on Ubuntu – everything wanted me to use Docker which, admittedly, I haven’t started learning well enough to setup my lab management console on.

One thing I learned from this process – running your webserver on NGINX instead of, say, Apache is known as a LEMP stack. I’d only ever heard of LAMP or WAMP previously. Now you know, too.

So first things first, setup a LEMP stack.

Linux is taken care of by Ubuntu 20.04, duh. Make sure it’s fully updated and freshly rebooted for good measure. Also make sure OpenSSH is installed if that’s not part of your typical Ubuntu install regimen.

Installing NGINX

sudo apt install -y nginx
sudo ufw status
sudo ufw enable (if not already enabled)
sudo ufw app list (to find out what options exist for ufw profiles)
sudo ufw allow OpenSSH (if not already allowed)
sudo ufw allow 'Nginx Full' (this will allow both HTTP and HTTPS) 

Now, navigating to http://your_IP.com should produce the screen below. If you're not seeing this screen, check your firewall NAT rules and be sure 80 is allowed inbound. 

Installing MySQL

sudo apt install mysql-server
sudo mysql_secure_installation
Now this is going to trigger an SAT-like questionnaire that you need to go through to make sure your MySQL setup is as secure as possible. It's all pretty self-explanatory. Just read the daggum prompts and you'll be fine. Hint: It's pretty much "Y" all the way through. 

Installing PHP

Just like that, we’re at the end of setting up our LEMP stack.

sudo apt install php-fpm php-mysql php-curl php-zip php-simplexml php-sqlite3

The last 4 of those were "gotchas" from the actual Organizr install. They're pre-requisites that aren't picked up during any other install. You can add them here and now or you can wait until you get the error and install them later. Biggest takeaway is - whatever the error is you see, add php- to the beginning for the install and you'll be fine. 

The rest of the setup and testing is all documented well enough by Digital Ocean here.

Securing the site with Let’s Encrypt

Using Let’s Encrypt makes having that spiffy HTTPS lock icon a breeze. The steps are all beautifully documented by Digital Ocean, once again, here.

Organizr Install

Now it’s time for the actual install of Organizr! And trust me, the hard work is already done!

cd /var/www/html/thisnerdyguy where thisnerdyguy is the name of your Organizr site. 
git clone https://github.com/causefx/Organizr /var/www/html/thisnerdyguy
chown -R www-data:www-data /var/www/html/

Lastly, edit your sites-available config for your Organizr site and be sure it resembles the following:

server{
    root /var/www/html/thisnerdyguy;
    index index.php index.html index.htm index.nginx-debian.html;
    server_name thisnerdyguy.com www.thisnerdyguy.com;
    location / { try_files $uri $uri/ =404; }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    }
    location /api/v2 {
	    try_files $uri /api/v2/index.php$is_args$args;
    }
}

FIN

You should be all set! Navigating to http://www.YOUR_WEBSITE.com should, depending on how you configured Let’s Encrypt, redirect to https://www.YOUR_WEBSITE.com and, equally important, should load Organizr asking you to begin the very simple configuration process.

GREAT SUCCESS!

LTE WAN Failover with Sophos XG

Living in the land of moose and trees, power outages are a way of life. Either you’re fortunate enough to have an automatic standby generator, like a Generac, or you have a portable generator with the beloved “widowmaker” cobbled extension cord.

The problem with power outages here as opposed to somewhere like Texas is the outages up here are often due to trees coming down on the lines – which also takes down cable internet.

Of course we can tether our mobile phones to our laptops but that doesn’t do anything for the RokuTV, aka “The Babysitter”. And anyone who has let a 3 year old use their laptop understands why using my Macbook Pro 2013 nor my wife’s i7 Asus Zenbook are not options. We could also just let her use her Amazon Fire tablet, aka “The Other Babysitter”, but that’s just too easy, ok!?

On our Generac I am running a DIY-project that monitors and controls the outage and exercise cycles. While the exercise cycles are of little importance, I do want to know if the power goes out while I’m away from the house. The notification is controlled by a small box that is roughly 50 feet away from the house so no amount of tethering will work there.

Running a Sophos XG135w gives me a few options. If this were the XG135, and not the -w version with integrated wireless, I could get an LTE add-on card that just needs a SIM card and some minor setup. Alas, because I have built-in wireless, an all-one-box is not an option. Truthfully, even if it were an option, those add-on cards are very expensive.

Apparently prices have gone up…I blame COVID…they used to be around $80 but now around $100, the Netgear LB1120 is an LTE modem that outputs via ethernet as opposed to many of the other modem options that are basically fancy hotspots.

So you put your activated SIM card into the LB1120. I’ve used this model with Google Fi which runs on US Cellular, T-Mobile, and Sprint. We don’t have Sprint up here in the North Pole but USC and TMo are decent enough. I’m now running it with a VZW SIM and holy cow! The signal strength is so much better. I was getting about 2 bars with any carrier on Google Fi and I now get 4 bars on VZW.

Once the activated SIM card is inserted, plug in the power and plug in the ethernet cable to your computer. Power on the device. Navigate to http://192.168.5.1 (default) and login using the password printed on the bottom of the modem (varies by device).

The only required change is to set the LB1120 as Bridge as Router is default. If you’re running Google Fi, you’ll need to set the APN to h2g2. Next time I’m doing maintenance, I’ll take screenshots since I need to either remove the modem from the network or let a failover occur.

Once your changes are made, shutdown the LB1120. Plug in an ethernet cable from the LB1120 to a port on the XG135w. I used Port 8 for no real reason. Port 1 is screen-printed LAN, Port 2 WAN and Port 3 DMZ. Since these are only screen-prints and we can configure these ports however we want, it’s really only my OCD that keeps me from using Port 3. So yes, Port 8. Could I have used Port 4? Sure. But it’s Port 8.

Port 1 – LAN
Port 2 – WAN
Port 3 – DMZ
Port 8 – LTE

Ok, so once you have the physical connections made, login to the XG. https://172.16.16.16:4444, default.

Network> Interfaces> Select the port that is connected to the LB1120. In my case, Port 8.

XG_Interfaces

I changed the name to LTE, again, OCD. Name the interface whatever you want.
Network Zone: WAN
IP assignment: DHCP
Gateway Name: DHCP_LTE_GW Name this whatever you want. I chose to keep with the default naming convention for the gateway.
Save.

Network> WAN Link Manager> Because we selected WAN as the Network Zone previously, we will notice the new Gateway shown.

Click on the new IPv4 Gateway. Mine is named DHCP_LTE_GW.

Set the Interface Type. This will be a Backup connection so I will unsurprisingly select “Backup”

Set the Interface Details according to your needs. The verbiage is nice and simple so you can tune this to your usage.
Activate this Gateway: If DHCP_Port2_GW fails.
Action on Activation: Inherit the weight of failed active gateway.
Action on Fallback: Serve all connections through restored gateway.
Save.

I left the Failover Rules at default.

That should do it. I tested my setup by unplugging my cable modem and it did, indeed, fail over appropriately. It happened fast enough that Netflix didn’t buffer and my beloved, possessed offspring didn’t even notice! The speedtest showed 14Mbps which isn’t amazing by cable standards but when you consider this is Verizon going through trees, to my cellular booster on my metal roof, to and out my indoor dome cellular booster antenna, and into my LTE modem in my basement.

How to update ESXi 7.0 to 7.0 U1b

Why would anyone want to update to a minor revision from a perfectly working version? All versions prior to this minor revision required some every boot “hacking” of the ethernet driver if you also want to run a USB NIC, which is very handy when you’re using a NIC and want a second interface.

Enable SSH.

Enter Maintenance Mode.

esxcli software profile update -p ESXi-7.0U1b-17168206-standard -d https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml

Reboot.

How to remove derelict or broken VMs from ESXi via CLI

I recently ran into an issue with one of my SSDs failing in my ESXi v6.7 NUC. All of my client VMs were house on this, now dead, datastore so all VMs were showing in vSphere Web as “Invalid.” One of the unfortunate side-effects of this error is the complete inability to really do anything to the VM – you can’t edit settings, you can’t unregister, and you definitely can’t delete.

Luckily, it is possible to delete these abominations. Unluckily, it requires some command-line magic.

The first step is to enable SSH on the ESXi host. No reboot is needed to enable SSH.

Once SSH is enabled, access the ESXi host and login.

vim-cmd /vmsvc/getallvms

Will list all VMs either currently or previously registered to this particular ESXi instance. I don’t remember the exact verbiage but it reported something to the effect of:

Skipping invalid VM 1

This error repeated for each VM that had been taken along with the now defunct SSD. Once the list of failed VMs is shown, run the following command for each VM:

vim-cmd /vmsvc/unregister <id>

And that’s it. All ghosts of the former VMs should be removed and your ESXi WebUI should be clear of errored clients.

Caldera Setup

Clone the Repository

git clone https://github.com/mitre/caldera.git --recursive --branch 2.8.1

Change directories into the “CALDERA” directory

cd caldera

Install PIP and the PIP requirements:

sudo apt install -y python3-pip
pip3 install -r requirements.txt

Install Go

Installing Go is technically optional but it makes it so that agent executables are dynamically compiled and they avoid AV detection much better.

Download Go from https://golang.org/doc/install

Extract the downloaded file (your filename may vary)

sudo tar -C /usr/local -xzf go1.15.2.linux-amd64.tar.gz

Update your PATH

Add the following line to your $HOME/.bashrc file:

export PATH=$PATH:/usr/local/go/bin

Close the terminal and reopen to have the PATH changes take effect, or use the “source ~/.bashrc” command.

Confirm that GO is properly installed by checking its version.

go --version

Start the server

Create a copy of the CALDERA config file called local.yml and then edit it to set your own users and secure passwords.

cp ~/caldera/conf/default.yml ~/caldera/conf/local.yml

Edit the local.yml file to change the usernames and passwords shown below to something more secure.

Start the CALDERA server.

python3 server.py

( Not functional below)

Setup SSL Communications for the CALDERA Web Interface

If your CALDERA web interface is reachable over an untrusted network, you should enable encrypted communications as instructed below.

The encrypted communications are handled by the HAProxy tool. Install HAProxy as follows.

sudo apt update
sudo apt install haproxy

After logging in to the CALDERA web interface on localhost:8888, go to the Advanced–>Configuration menu.

From the configuration menu enable the SSL plugin. You can now reach the CALDERA web interface at https://<your ip>:8443.

You also need to update your app.contact.http setting from the CALDERA web interface (advanced–>configuration) to include https as shown below. (update with the IP or domain name of your server)

Note: Make sure you do not include a trailing slash (/) on the URL.

Don’t forget to click the green “update” button and restart the server after making the configuration changes.

Now that we have configured the app.contact.http setting, we will see updated commands for deploying an agent using the http contact method (54ndc47 for example)

By default, a self signed certificate is used for the SSL encryption. Replace the self-signed certificate at ~/caldera/plugins/ssl/conf/insecure_certificate.pem with your own if desired.

Need to create your own signed/trusted certificate? Try using Let’s Encrypt. You will need to own a domain name and configure a DNS authoritative record to point to your CALDERA server’s IP address.

To use your own trusted cert create a combined pem file using the commands to below.

cd /etc/letsencrypt/live/<your domain>
cat cert.pem privkey.pem > ~/caldera/plugins/ssl/conf/insecure_certificate.pem

Restart the CALDERA server after making these changes.

If you use the self-signed cert, any PowerShell commands you run to get a remote agent are going to complain about not being able to establish a trust relationship. You will need to bypass the trust check by running the PowerShell commands below before you execute the agent command. (this only applies if you are using the default self-signed cert)

class TrustAllCertsPolicy : System.Net.ICertificatePolicy {
        [bool] CheckValidationResult([System.Net.ServicePoint] $a,
            [System.Security.Cryptography.X509Certificates.X509Certificate] $b,
            [System.Net.WebRequest] $c,
            [int] $d) {
            return $true
        }
    }
    [System.Net.ServicePointManager]::CertificatePolicy = [TrustAllCertsPolicy]::new()

Now your CALDERA SERVER is fully set up and ready to be put to use. Check out the “Attack Emulation: Atomic Red Team, CALDERA, and More” class to learn more about using Mitre CALDERA, including over 25 hands-on labs. https://wildwesthackinfest.com/online-training/attack-emulation-atomic-red-team-caldera-and-more/

Managing Sophos XG – Create VLANs

Pre-setup disclaimers:
– Some steps will vary depending on exact deployment. For this particular lab, a single trunk port is used between the XG Port 2 and the Switch (SW) Port 1. To maximize network throughput, this setup could split trunk ports between multiple 1Gbe ports on the XG to multiple 1Gbe ports on the SW. But that’s a project for another day.
– The switch used is a now-deprecated Linksys switch, SGE-2000P. It’s a faithful old steed and provides good PoE to the devices still tolerant of -at standards in an -af world.

Create the Interfaces

The first step is to create the interfaces needed for each VLAN. You’ll need to know which port(s) you’re trunking from the XG.

XG> Configure> Network> Interfaces> Add New Interface> Add VLAN>
– Give it an appropriate name.
– Select the appropriate trunk port.
– Select the desired zone. For the scope of this walkthrough, all VLANs will be “LAN”.
– Set the desired VLAN ID. It’s personal preference but I set the VLAN ID to the IP range of
that VLAN. It helps keeps my mind straight.
– Set your static IP range applicable to the VLAN. IE: 10.10.160.1/24 for the VLAN 160.
– Save the changes.

Setup DHCP

Each VLAN will need it’s own DHCP range to work properly.

XG> Configure> Network> DHCP> Server> Add>
– Give it a descriptive name. I tend to keep everything named with a convention similar to the VLAN itself.
– Select the interface for the VLAN.
– Set the dynamic IP lease range. I will typically set this smaller than the total to leave me some room for static assignments. IE: 10.10.160.100 – 10.10.160.200
– Set your static IP maps, if applicable. This is easy enough to do later, too.
– Leave “Use Interface IP as Gateway” checked.
– Leave all else default and Save changes.

XG Setup Complete!

That really is it – in the simplest sense. The default firewall rule will allow all traffic out so, unless otherwise specified, every VLAN should provide an IP via the DHCP server specified for that VLAN, provide DNS via the gateway IP for that VLAN, and allow all outbound.

Of course, this is useless without a properly configured switch. This is where things get tricky because unless you’re on the Cisco train, everything is done just a bit differently across all vendors. The next set of steps will apply to my switch as more of a “so I don’t forget” set of instructions to my future, post-annual-lab-nuke self but the overall concepts and lingo will hopefully help others conceptualize what they need to do in their labs.

Bring on the Switching

We first need to tell the switch what VLANs to expect from the XG.
VLAN Management> Properties> Add:
– Set the VLAN ID to a value set within the XG VLAN Interface.
– Give it a descriptive name.
– Do this for each VLAN set in the XG.

We then need to set the SW ports to the appropriate VLAN Mode.
VLAN Management> Interface Settings:
– Set Port 1 to Trunk (Access to XG)

Almost lastly, we need to tell the SW which VLANs to expect over the trunk Port 1.
VLAN Management> VLAN to Port> g1> Join VLAN:
– There will be one untagged VLAN and the rest tagged.
– The untagged VLAN will be the default VLAN assigned to non-VLAN-aware devices. This can be the admin VLAN (not recommended) or a guest VLAN or anything you choose.
– The tagged VLANs will be the remaining VLANs available to be assigned elsewhere in the switch. So we can tag VLAN 100 to Port 8 or VLAN 200 to Port 16.

I still need to go over the difference between “General” and “Access” ports as they relate to my schema but that’ll be an update for another night. As will screenshots.

How To Install WordPress with LAMP on Ubuntu 18.04

Introduction

WordPress is the most popular CMS (content management system) on the internet. It allows you to easily set up flexible blogs and websites on top of a MySQL backend with PHP processing. WordPress has seen incredible adoption and is a great choice for getting a website up and running quickly. After setup, almost all administration can be done through the web frontend.

In this guide, we’ll focus on getting a WordPress instance set up on a LAMP stack (Linux, Apache, MySQL, and PHP) on an Ubuntu 18.04 server.

Prerequisites

In order to complete this tutorial, you will need access to an Ubuntu 18.04 server.

You will need to perform the following tasks before you can start this guide:

  • Create a sudo user on your server: We will be completing the steps in this guide using a non-root user with sudo privileges. You can create a user with sudo privileges by following our Ubuntu 18.04 initial server setup guide.
  • Install a LAMP stack: WordPress will need a web server, a database, and PHP in order to correctly function. Setting up a LAMP stack (Linux, Apache, MySQL, and PHP) fulfills all of these requirements. Follow this guide to install and configure this software.
  • Secure your site with SSL: WordPress serves dynamic content and handles user authentication and authorization. TLS/SSL is the technology that allows you to encrypt the traffic from your site so that your connection is secure. The way you set up SSL will depend on whether you have a domain name for your site.
    • If you have a domain name… the easiest way to secure your site is with Let’s Encrypt, which provides free, trusted certificates. Follow our Let’s Encrypt guide for Apache to set this up.
    • If you do not have a domain… and you are just using this configuration for testing or personal use, you can use a self-signed certificate instead. This provides the same type of encryption, but without the domain validation. Follow our self-signed SSL guide for Apache to get set up.

When you are finished with the setup steps, log into your server as your sudo user and continue below.

Step 1 – Creating a MySQL Database and User for WordPress

The first step that we will take is a preparatory one. WordPress uses MySQL to manage and store site and user information. We have MySQL installed already, but we need to make a database and a user for WordPress to use.

To get started, log into the MySQL root (administrative) account by issuing this command:

mysql -u root -p

You will be prompted for the password you set for the MySQL root account when you installed the software.

First, we can create a separate database that WordPress will control. You can call this whatever you would like, but we will be using wordpress in this guide to keep it simple. Create the database for WordPress by typing:

CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Note: Every MySQL statement must end in a semi-colon (;). Check to make sure this is present if you are running into any issues.

Next, we are going to create a separate MySQL user account that we will use exclusively to operate on our new database. Creating one-function databases and accounts is a good idea from a management and security standpoint. We will use the name wordpressuser in this guide. Feel free to change this if you’d like.

We are going to create this account, set a password, and grant access to the database we created. We can do this by typing the following command. Remember to choose a strong password here for your database user:

GRANT ALL ON wordpress.* TO 'wordpressuser'@'localhost' IDENTIFIED BY 'password';

You now have a database and user account, each made specifically for WordPress. We need to flush the privileges so that the current instance of MySQL knows about the recent changes we’ve made:

FLUSH PRIVILEGES;

Exit out of MySQL by typing:

EXIT;

Step 2 – Installing Additional PHP Extensions

When setting up our LAMP stack, we only required a very minimal set of extensions in order to get PHP to communicate with MySQL. WordPress and many of its plugins leverage additional PHP extensions.

We can download and install some of the most popular PHP extensions for use with WordPress by typing:

sudo apt update
sudo apt install php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip

Note: Each WordPress plugin has its own set of requirements. Some may require additional PHP packages to be installed. Check your plugin documentation to discover its PHP requirements. If they are available, they can be installed with apt as demonstrated above.

We will restart Apache to load these new extensions in the next section. If you are returning here to install additional plugins, you can restart Apache now by typing:

sudo systemctl restart apache2

Step 3 – Adjusting Apache’s Configuration to Allow for .htaccess Overrides and Rewrites

Next, we will be making a few minor adjustments to our Apache configuration. Based on the prerequisite tutorials, you should have a configuration file for your site in the /etc/apache2/sites-available/ directory. We’ll use /etc/apache2/sites-available/wordpress.conf as an example here, but you should substitute the path to your configuration file where appropriate.

Additionally, we will use /var/www/wordpress as the root directory of our WordPress install. You should use the web root specified in your own configuration.

Note: It’s possible you are using the 000-default.conf default configuration (with /var/www/html as your web root). This is fine to use if you’re only going to host one website on this server. If not, it’s best to split the necessary configuration into logical chunks, one file per site.

Enabling .htaccess Overrides

Currently, the use of .htaccess files is disabled. WordPress and many WordPress plugins use these files extensively for in-directory tweaks to the web server’s behavior.

Open the Apache configuration file for your website:

sudo nano /etc/apache2/sites-available/wordpress.conf

To allow .htaccess files, we need to set the AllowOverride directive within a Directory block pointing to our document root. Add the following block of text inside the VirtualHost block in your configuration file, being sure to use the correct web root directory: /etc/apache2/sites-available/wordpress.conf

<Directory /var/www/wordpress/>
    AllowOverride All
</Directory>

When you are finished, save and close the file.

Enabling the Rewrite Module

Next, we can enable mod_rewrite so that we can utilize the WordPress permalink feature:

sudo a2enmod rewrite

Enabling the Changes

Before we implement the changes we’ve made, check to make sure we haven’t made any syntax errors:

sudo apache2ctl configtest

The output might have a message that looks like this:

OutputAH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK

If you wish to suppress the top line, just add a ServerName directive to your main (global) Apache configuration file at /etc/apache2/apache2.conf. The ServerName can be your server’s domain or IP address. This is just a message however and doesn’t affect the functionality of our site. As long as the output contains Syntax OK, you are ready to continue.

Restart Apache to implement the changes:

sudo systemctl restart apache2

Next, we will download and set up WordPress itself.

Step 4 – Downloading WordPress

Now that our server software is configured, we can download and set up WordPress. For security reasons in particular, it is always recommended to get the latest version of WordPress from their site.

Change into a writable directory and then download the compressed release by typing:

cd /tmp
curl -O https://wordpress.org/latest.tar.gz

Extract the compressed file to create the WordPress directory structure:

tar xzvf latest.tar.gz

We will be moving these files into our document root momentarily. Before we do, we can add a dummy .htaccess file so that this will be available for WordPress to use later.

Create the file by typing:

touch /tmp/wordpress/.htaccess

We’ll also copy over the sample configuration file to the filename that WordPress actually reads:

cp /tmp/wordpress/wp-config-sample.php /tmp/wordpress/wp-config.php

We can also create the upgrade directory, so that WordPress won’t run into permissions issues when trying to do this on its own following an update to its software:

mkdir /tmp/wordpress/wp-content/upgrade

Now, we can copy the entire contents of the directory into our document root. We are using a dot at the end of our source directory to indicate that everything within the directory should be copied, including hidden files (like the .htaccess file we created):

sudo cp -a /tmp/wordpress/. /var/www/wordpress

Step 5 – Configuring the WordPress Directory

Before we do the web-based WordPress setup, we need to adjust some items in our WordPress directory.

Adjusting the Ownership and Permissions

One of the big things we need to accomplish is setting up reasonable file permissions and ownership.

We’ll start by giving ownership of all the files to the www-data user and group. This is the user that the Apache webserver runs as, and Apache will need to be able to read and write WordPress files in order to serve the website and perform automatic updates.

Update the ownership with chown:

sudo chown -R www-data:www-data /var/www/wordpress

Next we will run two find commands to set the correct permissions on the WordPress directories and files:

sudo find /var/www/wordpress/ -type d -exec chmod 750 {} \;
sudo find /var/www/wordpress/ -type f -exec chmod 640 {} \;

These should be a reasonable permissions set to start with. Some plugins and procedures might require additional tweaks.

Setting up the WordPress Configuration File

Now, we need to make some changes to the main WordPress configuration file.

When we open the file, our first order of business will be to adjust some secret keys to provide some security for our installation. WordPress provides a secure generator for these values so that you do not have to try to come up with good values on your own. These are only used internally, so it won’t hurt usability to have complex, secure values here.

To grab secure values from the WordPress secret key generator, type:

curl -s https://api.wordpress.org/secret-key/1.1/salt/

You will get back unique values that look something like this:

Warning! It is important that you request unique values each time. Do NOT copy the values shown below!

Outputdefine('AUTH_KEY',         '1jl/vqfs<XhdXoAPz9 DO NOT COPY THESE VALUES c_j{iwqD^<+c9.k<J@4H');
define('SECURE_AUTH_KEY',  'E2N-h2]Dcvp+aS/p7X DO NOT COPY THESE VALUES {Ka(f;rv?Pxf})CgLi-3');
define('LOGGED_IN_KEY',    'W(50,{W^,OPB%PB<JF DO NOT COPY THESE VALUES 2;y&,2m%3]R6DUth[;88');
define('NONCE_KEY',        'll,4UC)7ua+8<!4VM+ DO NOT COPY THESE VALUES #`DXF+[$atzM7 o^-C7g');
define('AUTH_SALT',        'koMrurzOA+|L_lG}kf DO NOT COPY THESE VALUES  07VC*Lj*lD&?3w!BT#-');
define('SECURE_AUTH_SALT', 'p32*p,]z%LZ+pAu:VY DO NOT COPY THESE VALUES C-?y+K0DK_+F|0h{!_xY');
define('LOGGED_IN_SALT',   'i^/G2W7!-1H2OQ+t$3 DO NOT COPY THESE VALUES t6**bRVFSD[Hi])-qS`|');
define('NONCE_SALT',       'Q6]U:K?j4L%Z]}h^q7 DO NOT COPY THESE VALUES 1% ^qUswWgn+6&xqHN&%');

These are configuration lines that we can paste directly in our configuration file to set secure keys. Copy the output you received now.

Now, open the WordPress configuration file:

sudo nano /var/www/wordpress/wp-config.php

Find the section that contains the dummy values for those settings. It will look something like this: /var/www/wordpress/wp-config.php

. . .

define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

. . .

Delete those lines and paste in the values you copied from the command line: /var/www/wordpress/wp-config.php

. . .

define('AUTH_KEY',         'VALUES COPIED FROM THE COMMAND LINE');
define('SECURE_AUTH_KEY',  'VALUES COPIED FROM THE COMMAND LINE');
define('LOGGED_IN_KEY',    'VALUES COPIED FROM THE COMMAND LINE');
define('NONCE_KEY',        'VALUES COPIED FROM THE COMMAND LINE');
define('AUTH_SALT',        'VALUES COPIED FROM THE COMMAND LINE');
define('SECURE_AUTH_SALT', 'VALUES COPIED FROM THE COMMAND LINE');
define('LOGGED_IN_SALT',   'VALUES COPIED FROM THE COMMAND LINE');
define('NONCE_SALT',       'VALUES COPIED FROM THE COMMAND LINE');

. . .

Next, we need to modify some of the database connection settings at the beginning of the file. You need to adjust the database name, the database user, and the associated password that we configured within MySQL.

The other change we need to make is to set the method that WordPress should use to write to the filesystem. Since we’ve given the web server permission to write where it needs to, we can explicitly set the filesystem method to “direct”. Failure to set this with our current settings would result in WordPress prompting for FTP credentials when we perform some actions.

This setting can be added below the database connection settings, or anywhere else in the file: /var/www/wordpress/wp-config.php

. . .

define('DB_NAME', 'wordpress');

/** MySQL database username */
define('DB_USER', 'wordpressuser');

/** MySQL database password */
define('DB_PASSWORD', 'password');

. . .

define('FS_METHOD', 'direct');

Save and close the file when you are finished.

Step 6 – Completing the Installation Through the Web Interface

Now that the server configuration is complete, we can complete the installation through the web interface.

In your web browser, navigate to your server’s domain name or public IP address:

https://server_domain_or_IP

Select the language you would like to use.

Next, you will come to the main setup page.

Select a name for your WordPress site and choose a username (it is recommended not to choose something like “admin” for security purposes). A strong password is generated automatically. Save this password or select an alternative strong password.

Enter your email address and select whether you want to discourage search engines from indexing your site:

When you click ahead, you will be taken to a page that prompts you to log in:

Once you log in, you will be taken to the WordPress administration dashboard:

Conclusion

WordPress should be installed and ready to use! Some common next steps are to choose the permalinks setting for your posts (can be found in Settings > Permalinks) or to select a new theme (in Appearance > Themes). If this is your first time using WordPress, explore the interface a bit to get acquainted with your new CMS.

https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-lamp-on-ubuntu-18-04

How To Secure Apache with Let’s Encrypt on Ubuntu 18.04

(Verified fully functional 11/2020)

Introduction

Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free TLS/SSL certificates, thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps. Currently, the entire process of obtaining and installing a certificate is fully automated on both Apache and Nginx.

In this tutorial, you will use Certbot to obtain a free SSL certificate for Apache on Ubuntu 18.04 and set up your certificate to renew automatically.

This tutorial will use a separate Apache virtual host file instead of the default configuration file. We recommend creating new Apache virtual host files for each domain because it helps to avoid common mistakes and maintains the default files as a fallback configuration.

Prerequisites

To follow this tutorial, you will need:

  • One Ubuntu 18.04 server set up by following this initial server setup for Ubuntu 18.04 tutorial, including a sudo non-root user and a firewall.
  • A fully registered domain name. This tutorial will use your_domain as an example throughout. You can purchase a domain name on Namecheap.
  • Both of the following DNS records set up for your server.
    • An A record with your_domain pointing to your server’s public IP address.
    • An A record with www.your_domain pointing to your server’s public IP address.
  • Apache installed by following How To Install Apache on Ubuntu 18.04. Be sure that you have a virtual host file for your domain. This tutorial will use /etc/apache2/sites-available/your_domain.conf as an example.

Step 1 — Installing Certbot

The first step to using Let’s Encrypt to obtain an SSL certificate is to install the Certbot software on your server.

Certbot is in very active development, so the Certbot packages provided by Ubuntu tend to be outdated. However, the Certbot developers maintain a Ubuntu software repository with up-to-date versions, so we’ll use that repository instead.

First, add the repository:

sudo add-apt-repository ppa:certbot/certbot

You’ll need to press ENTER to accept.

Install Certbot’s Apache package with apt:

sudo apt install python-certbot-apache

Certbot is now ready to use, but in order for it to configure SSL for Apache, we need to verify some of Apache’s configuration.

Step 2 — Set Up the SSL Certificate

Certbot needs to be able to find the correct virtual host in your Apache configuration for it to automatically configure SSL. Specifically, it does this by looking for a ServerName directive that matches the domain you request a certificate for.

If you followed the virtual host set up step in the Apache installation tutorial, you should have a VirtualHost block for your domain at /etc/apache2/sites-available/your_domain.com.conf with the ServerName directive already set appropriately.

To check, open the virtual host file for your domain using nano or your favorite text editor:

sudo nano /etc/apache2/sites-available/your_domain.conf

Find the existing ServerName line. It should look like this: /etc/apache2/sites-available/your_domain.conf

...
ServerName your_domain;
...

If it does, exit your editor and move on to the next step.

If it doesn’t, update it to match. Then save the file, quit your editor, and verify the syntax of your configuration edits:

sudo apache2ctl configtest

If you get an error, reopen the virtual host file and check for any typos or missing characters. Once your configuration file’s syntax is correct, reload Apache to load the new configuration:

sudo systemctl reload apache2

Certbot can now find the correct VirtualHost block and update it.

Next, let’s update the firewall to allow HTTPS traffic.

Step 3 — Allowing HTTPS Through the Firewall

If you have the ufw firewall enabled, as recommended by the prerequisite guides, you’ll need to adjust the settings to allow for HTTPS traffic. Luckily, Apache registers a few profiles with ufw upon installation.

You can see the current setting by typing:

sudo ufw status

It will probably look like this, meaning that only HTTP traffic is allowed to the web server:

OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Apache                     ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Apache (v6)                ALLOW       Anywhere (v6)

To additionally let in HTTPS traffic, allow the Apache Full profile and delete the redundant Apache profile allowance:

sudo ufw allow 'Apache Full'
sudo ufw delete allow 'Apache'

Your status should now look like this:

sudo ufw status
OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Apache Full                ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Apache Full (v6)           ALLOW       Anywhere (v6)        

Next, let’s run Certbot and fetch our certificates.

Step 4 — Obtaining an SSL Certificate

Certbot provides a variety of ways to obtain SSL certificates through plugins. The Apache plugin will take care of reconfiguring Apache and reloading the config whenever necessary. To use this plugin, type the following:

sudo certbot --apache -d your_domain -d www.your_domain

This runs certbot with the --apache plugin, using -d to specify the names you’d like the certificate to be valid for.

If this is your first time running certbot, you will be prompted to enter an email address and agree to the terms of service. After doing so, certbot will communicate with the Let’s Encrypt server, then run a challenge to verify that you control the domain you’re requesting a certificate for.

If that’s successful, certbot will ask how you’d like to configure your HTTPS settings:

OutputPlease choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Select your choice then hit ENTER. The configuration will be updated, and Apache will reload to pick up the new settings. certbot will wrap up with a message telling you the process was successful and where your certificates are stored:

OutputIMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/your_domain/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/your_domain/privkey.pem
   Your cert will expire on 2018-07-23. 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"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Your certificates are downloaded, installed, and loaded. Try reloading your website using https:// and notice your browser’s security indicator. It should indicate that the site is properly secured, usually with a green lock icon. If you test your server using the SSL Labs Server Test, it will get an A grade.

Let’s finish by testing the renewal process.

Step 5 — Verifying Certbot Auto-Renewal

The certbot package we installed takes care of renewals by including a renew script to /etc/cron.d, which is managed by a systemctl service called certbot.timer. This script runs twice a day and will automatically renew any certificate that’s within thirty days of expiration.

To check the status of this service and make sure it’s active and running, you can use:

sudo systemctl status certbot.timer

You’ll get output similar to this:

Output● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-04-28 17:57:48 UTC; 17h ago
    Trigger: Wed 2020-04-29 23:50:31 UTC; 12h left
   Triggers: ● certbot.service

Apr 28 17:57:48 fine-turtle systemd[1]: Started Run certbot twice daily.

To test the renewal process, you can do a dry run with certbot:

sudo certbot renew --dry-run

If you see no errors, you’re all set. When necessary, Certbot will renew your certificates and reload Apache to pick up the changes. If the automated renewal process ever fails, Let’s Encrypt will send a message to the email you specified, warning you when your certificate is about to expire.

Conclusion

In this tutorial, you installed the Let’s Encrypt client certbot, downloaded SSL certificates for your domain, configured Apache to use these certificates, and set up automatic certificate renewal. If you have further questions about using Certbot, their documentation is a good place to start.

https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-18-04

How to install a LAMP stack on Ubuntu 18.04

(Verified fully functional 11/2020)

Introduction

A “LAMP” stack is a group of open-source software that is typically installed together to enable a server to host dynamic websites and web apps. This term is actually an acronym which represents the Linux operating system, with the Apache web server. The site data is stored in a MySQL database, and dynamic content is processed by PHP.

In this guide, we will install a LAMP stack on an Ubuntu 18.04 server.

Prerequisites

In order to complete this tutorial, you will need to have an Ubuntu 18.04 server with a non-root sudo-enabled user account and a basic firewall.

Step 1 — Installing Apache and Updating the Firewall

The Apache web server is among the most popular web servers in the world. It’s well-documented and has been in wide use for much of the history of the web, which makes it a great default choice for hosting a website.

Install Apache using Ubuntu’s package manager, apt:

sudo apt update
sudo apt install apache2

Since this is a sudo command, these operations are executed with root privileges. It will ask you for your regular user’s password to verify your intentions.

Once you’ve entered your password, apt will tell you which packages it plans to install and how much extra disk space they’ll take up. Press Y and hit ENTER to continue, and the installation will proceed.

Adjust the Firewall to Allow Web Traffic

Next, assuming that you have followed the initial server setup instructions and enabled the UFW firewall, make sure that your firewall allows HTTP and HTTPS traffic. You can check that UFW has an application profile for Apache like so:

sudo ufw app list
OutputAvailable applications:
  Apache
  Apache Full
  Apache Secure
  OpenSSH

If you look at the Apache Full profile, it should show that it enables traffic to ports 80 and 443:

sudo ufw app info "Apache Full"
OutputProfile: Apache Full
Title: Web Server (HTTP,HTTPS)
Description: Apache v2 is the next generation of the omnipresent Apache web
server.

Ports:
  80,443/tcp

Allow incoming HTTP and HTTPS traffic for this profile:

sudo ufw allow in "Apache Full"

You can do a spot check right away to verify that everything went as planned by visiting your server’s public IP address in your web browser (see the note under the next heading to find out what your public IP address is if you do not have this information already):

http://your_server_ip

You will see the default Ubuntu 18.04 Apache web page, which is there for informational and testing purposes. It should look something like this:

If you see this page, then your web server is now correctly installed and accessible through your firewall.

How To Find your Server’s Public IP Address

If you do not know what your server’s public IP address is, there are a number of ways you can find it. Usually, this is the address you use to connect to your server through SSH.

There are a few different ways to do this from the command line. First, you could use the iproute2 tools to get your IP address by typing this:

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

This will give you two or three lines back. They are all correct addresses, but your computer may only be able to use one of them, so feel free to try each one.

An alternative method is to use the curl utility to contact an outside party to tell you how it sees your server. This is done by asking a specific server what your IP address is:

sudo apt install curl
curl http://icanhazip.com

Regardless of the method you use to get your IP address, type it into your web browser’s address bar to view the default Apache page.

Step 2 — Installing MySQL

Now that you have your web server up and running, it is time to install MySQL. MySQL is a database management system. Basically, it will organize and provide access to databases where your site can store information.

Again, use apt to acquire and install this software:

sudo apt install mysql-server

Note: In this case, you do not have to run sudo apt update prior to the command. This is because you recently ran it in the commands above to install Apache. The package index on your computer should already be up-to-date.

This command, too, will show you a list of the packages that will be installed, along with the amount of disk space they’ll take up. Enter Y to continue.

When the installation is complete, run a simple security script that comes pre-installed with MySQL which will remove some dangerous defaults and lock down access to your database system. Start the interactive script by running:

sudo mysql_secure_installation

This will ask if you want to configure the VALIDATE PASSWORD PLUGIN.

Note: Enabling this feature is something of a judgment call. If enabled, passwords which don’t match the specified criteria will be rejected by MySQL with an error. This will cause issues if you use a weak password in conjunction with software which automatically configures MySQL user credentials, such as the Ubuntu packages for phpMyAdmin. It is safe to leave validation disabled, but you should always use strong, unique passwords for database credentials.

Answer Y for yes, or anything else to continue without enabling.

VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No:

If you answer “yes”, you’ll be asked to select a level of password validation. Keep in mind that if you enter 2 for the strongest level, you will receive errors when attempting to set any password which does not contain numbers, upper and lowercase letters, and special characters, or which is based on common dictionary words.

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary                  file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1

Regardless of whether you chose to set up the VALIDATE PASSWORD PLUGIN, your server will next ask you to select and confirm a password for the MySQL root user. This is an administrative account in MySQL that has increased privileges. Think of it as being similar to the root account for the server itself (although the one you are configuring now is a MySQL-specific account). Make sure this is a strong, unique password, and do not leave it blank.

If you enabled password validation, you’ll be shown the password strength for the root password you just entered and your server will ask if you want to change that password. If you are happy with your current password, enter N for “no” at the prompt:

Using existing password for root.

Estimated strength of the password: 100
Change the password for root ? ((Press y|Y for Yes, any other key for No) : n

For the rest of the questions, press Y and hit the ENTER key at each prompt. This will remove some anonymous users and the test database, disable remote root logins, and load these new rules so that MySQL immediately respects the changes you have made.

Note that in Ubuntu systems running MySQL 5.7 (and later versions), the root MySQL user is set to authenticate using the auth_socket plugin by default rather than with a password. This allows for some greater security and usability in many cases, but it can also complicate things when you need to allow an external program (e.g., phpMyAdmin) to access the user.

If you prefer to use a password when connecting to MySQL as root, you will need to switch its authentication method from auth_socket to mysql_native_password. To do this, open up the MySQL prompt from your terminal:

sudo mysql

Next, check which authentication method each of your MySQL user accounts use with the following command:

SELECT user,authentication_string,plugin,host FROM mysql.user;
Output+------------------+-------------------------------------------+-----------------------+-----------+
| user             | authentication_string                     | plugin                | host      |
+------------------+-------------------------------------------+-----------------------+-----------+
| root             |                                           | auth_socket           | localhost |
| mysql.session    | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys        | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+------------------+-------------------------------------------+-----------------------+-----------+
4 rows in set (0.00 sec)

In this example, you can see that the root user does in fact authenticate using the auth_socket plugin. To configure the root account to authenticate with a password, run the following ALTER USER command. Be sure to change password to a strong password of your choosing:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Then, run FLUSH PRIVILEGES which tells the server to reload the grant tables and put your new changes into effect:

FLUSH PRIVILEGES;

Check the authentication methods employed by each of your users again to confirm that root no longer authenticates using the auth_socket plugin:

SELECT user,authentication_string,plugin,host FROM mysql.user;
Output+------------------+-------------------------------------------+-----------------------+-----------+
| user             | authentication_string                     | plugin                | host      |
+------------------+-------------------------------------------+-----------------------+-----------+
| root             | *3636DACC8616D997782ADD0839F92C1571D6D78F | mysql_native_password | localhost |
| mysql.session    | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys        | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+------------------+-------------------------------------------+-----------------------+-----------+
4 rows in set (0.00 sec)

You can see in this example output that the root MySQL user now authenticates using a password. Once you confirm this on your own server, you can exit the MySQL shell:

exit

At this point, your database system is now set up and you can move on to installing PHP, the final component of the LAMP stack.

Step 3 — Installing PHP

PHP is the component of your setup that will process code to display dynamic content. It can run scripts, connect to your MySQL databases to get information, and hand the processed content over to your web server to display.

Once again, leverage the apt system to install PHP. In addition, include some helper packages this time so that PHP code can run under the Apache server and talk to your MySQL database:

sudo apt install php libapache2-mod-php php-mysql

This should install PHP without any problems. We’ll test this in a moment.

In most cases, you will want to modify the way that Apache serves files when a directory is requested. Currently, if a user requests a directory from the server, Apache will first look for a file called index.html. We want to tell the web server to prefer PHP files over others, so make Apache look for an index.php file first.

To do this, type this command to open the dir.conf file in a text editor with root privileges:

sudo nano /etc/apache2/mods-enabled/dir.conf

It will look like this: /etc/apache2/mods-enabled/dir.conf

<IfModule mod_dir.c>
    DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
</IfModule>

Move the PHP index file (highlighted above) to the first position after the DirectoryIndex specification, like this: /etc/apache2/mods-enabled/dir.conf

<IfModule mod_dir.c>
    DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
</IfModule>

When you are finished, save and close the file by pressing CTRL+X. Confirm the save by typing Y and then hit ENTER to verify the file save location.

After this, restart the Apache web server in order for your changes to be recognized. Do this by typing this:

sudo systemctl restart apache2

You can also check on the status of the apache2 service using systemctl:

sudo systemctl status apache2
Sample Output● apache2.service - LSB: Apache2 web server
   Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: active (running) since Tue 2018-04-23 14:28:43 EDT; 45s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 13581 ExecStop=/etc/init.d/apache2 stop (code=exited, status=0/SUCCESS)
  Process: 13605 ExecStart=/etc/init.d/apache2 start (code=exited, status=0/SUCCESS)
    Tasks: 6 (limit: 512)
   CGroup: /system.slice/apache2.service
           ├─13623 /usr/sbin/apache2 -k start
           ├─13626 /usr/sbin/apache2 -k start
           ├─13627 /usr/sbin/apache2 -k start
           ├─13628 /usr/sbin/apache2 -k start
           ├─13629 /usr/sbin/apache2 -k start
           └─13630 /usr/sbin/apache2 -k start

Press Q to exit this status output.

To enhance the functionality of PHP, you have the option to install some additional modules. To see the available options for PHP modules and libraries, pipe the results of apt search into less, a pager which lets you scroll through the output of other commands:

apt search php- | less

Use the arrow keys to scroll up and down, and press Q to quit.

The results are all optional components that you can install. It will give you a short description for each:

bandwidthd-pgsql/bionic 2.0.1+cvs20090917-10ubuntu1 amd64
  Tracks usage of TCP/IP and builds html files with graphs

bluefish/bionic 2.2.10-1 amd64
  advanced Gtk+ text editor for web and software development

cacti/bionic 1.1.38+ds1-1 all
  web interface for graphing of monitoring systems

ganglia-webfrontend/bionic 3.6.1-3 all
  cluster monitoring toolkit - web front-end

golang-github-unknwon-cae-dev/bionic 0.0~git20160715.0.c6aac99-4 all
  PHP-like Compression and Archive Extensions in Go

haserl/bionic 0.9.35-2 amd64
  CGI scripting program for embedded environments

kdevelop-php-docs/bionic 5.2.1-1ubuntu2 all
  transitional package for kdevelop-php

kdevelop-php-docs-l10n/bionic 5.2.1-1ubuntu2 all
  transitional package for kdevelop-php-l10n
…
:

To learn more about what each module does, you could search the internet for more information about them. Alternatively, look at the long description of the package by typing:

apt show package_name

There will be a lot of output, with one field called Description which will have a longer explanation of the functionality that the module provides.

For example, to find out what the php-cli module does, you could type this:

apt show php-cli

Along with a large amount of other information, you’ll find something that looks like this:

Output…
Description: command-line interpreter for the PHP scripting language (default)
 This package provides the /usr/bin/php command interpreter, useful for
 testing PHP scripts from a shell or performing general shell scripting tasks.
 .
 PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used
 open source general-purpose scripting language that is especially suited
 for web development and can be embedded into HTML.
 .
 This package is a dependency package, which depends on Ubuntu's default
 PHP version (currently 7.2).
…

If, after researching, you decide you would like to install a package, you can do so by using the apt install command like you have been doing for the other software.

If you decided that php-cli is something that you need, you could type:

sudo apt install php-cli

If you want to install more than one module, you can do that by listing each one, separated by a space, following the apt install command, like this:

sudo apt install package1 package2 ...

At this point, your LAMP stack is installed and configured. Before you do anything else, we recommend that you set up an Apache virtual host where you can store your server’s configuration details.

When using the Apache web server, you can use virtual hosts (similar to server blocks in Nginx) to encapsulate configuration details and host more than one domain from a single server. We will set up a domain called your_domain, but you should replace this with your own domain name. To learn more about setting up a domain name with DigitalOcean, see our Introduction to DigitalOcean DNS.

Apache on Ubuntu 18.04 has one server block enabled by default that is configured to serve documents from the /var/www/html directory. While this works well for a single site, it can become unwieldy if you are hosting multiple sites. Instead of modifying /var/www/html, let’s create a directory structure within /var/www for our your_domain site, leaving /var/www/html in place as the default directory to be served if a client request doesn’t match any other sites.

Create the directory for your_domain as follows:

sudo mkdir /var/www/your_domain

Next, assign ownership of the directory with the $USER environment variable:

sudo chown -R $USER:$USER /var/www/your_domain

The permissions of your web roots should be correct if you haven’t modified your unmask value, but you can make sure by typing:

sudo chmod -R 755 /var/www/your_domain

Next, create a sample index.html page using nano or your favorite editor:

nano /var/www/your_domain/index.html

Inside, add the following sample HTML: /var/www/your_domain/index.html

<html>
    <head>
        <title>Welcome to Your_domain!</title>
    </head>
    <body>
        <h1>Success!  The your_domain server block is working!</h1>
    </body>
</html>

Save and close the file when you are finished.

In order for Apache to serve this content, it’s necessary to create a virtual host file with the correct directives. Instead of modifying the default configuration file located at /etc/apache2/sites-available/000-default.conf directly, let’s make a new one at /etc/apache2/sites-available/your_domain.conf:

sudo nano /etc/apache2/sites-available/your_domain.conf

Paste in the following configuration block, which is similar to the default, but updated for our new directory and domain name: /etc/apache2/sites-available/your_domain.conf

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName your_domain
    ServerAlias www.your_domain
    DocumentRoot /var/www/your_domain
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Notice that we’ve updated the DocumentRoot to our new directory and ServerAdmin to an email that the your_domain site administrator can access. We’ve also added two directives: ServerName, which establishes the base domain that should match for this virtual host definition, and ServerAlias, which defines further names that should match as if they were the base name.

Save and close the file when you are finished.

Let’s enable the file with the a2ensite tool:

sudo a2ensite your_domain.conf

Disable the default site defined in 000-default.conf:

sudo a2dissite 000-default.conf

Next, let’s test for configuration errors:

sudo apache2ctl configtest

You should see the following output:

OutputSyntax OK

Restart Apache to implement your changes:

sudo systemctl restart apache2

Apache should now be serving your domain name. You can test this by navigating to http://your_domain, where you should see something like this:

Apache virtual host example

With that, you virtual host is fully set up. Before making any more changes or deploying an application, though, it would be helpful to proactively test out your PHP configuration in case there are any issues that should be addressed.

Step 5 — Testing PHP Processing on your Web Server

In order to test that your system is configured properly for PHP, create a very basic PHP script called info.php. In order for Apache to find this file and serve it correctly, it must be saved to your web root directory.

Create the file at the web root you created in the previous step by running:

sudo nano /var/www/your_domain/info.php

This will open a blank file. Add the following text, which is valid PHP code, inside the file: info.php

<?php
phpinfo();
?>

When you are finished, save and close the file.

Now you can test whether your web server is able to correctly display content generated by this PHP script. To try this out, visit this page in your web browser. You’ll need your server’s public IP address again.

The address you will want to visit is:

http://your_domain/info.php

The page that you come to should look something like this:

This page provides some basic information about your server from the perspective of PHP. It is useful for debugging and to ensure that your settings are being applied correctly.

If you can see this page in your browser, then your PHP is working as expected.

You probably want to remove this file after this test because it could actually give information about your server to unauthorized users. To do this, run the following command:

sudo rm /var/www/your_domain/info.php

You can always recreate this page if you need to access the information again later.

Conclusion

Now that you have a LAMP stack installed, you have many choices for what to do next. Basically, you’ve installed a platform that will allow you to install most kinds of websites and web software on your server.

As an immediate next step, you should ensure that connections to your web server are secured, by serving them via HTTPS. The easiest option here is to use Let’s Encrypt to secure your site with a free TLS/SSL certificate.

https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-ubuntu-18-04