Skip to content

Instantly share code, notes, and snippets.

Last active December 29, 2021 15:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save sageworksstudio/3f4b9aa97ff57eabd5011cc0148b718b to your computer and use it in GitHub Desktop.
Save sageworksstudio/3f4b9aa97ff57eabd5011cc0148b718b to your computer and use it in GitHub Desktop.
Ubuntu 20.04 LAMP setup

Ubuntu 20.04 LAMP setup

Note: Because this is my personal cheat sheet, I'm installing a few PHP modules that you may not need if you're not running SilverStripe 4.x.x. Otherwise this is a pretty standard and secure LAMP installation.

SECURITY FIRST: Add a sudo user, require public key authentication and disable root login

Log into the remote machine as root: ssh root@

First, add the admin user.

$ adduser <username>

Add user to sudo'ers:

$ gpasswd -a <username> sudo

Add your .pub key to authorized_keys and set permissions

$ mkdir /home/username/.ssh

$ nano /home/username/.ssh/authorized_keys

Paste your key into the authorized_keys file and save.

$ chown -R newuser:newuser /home/username/.ssh

$ chmod 700 /home/username/.ssh

$ chmod 600 /home/username/.ssh/authorized_keys

Edit the SSH configuration file to enable public key authentication only and disable password login:

$ nano /etc/ssh/sshd_config

Set this parameter to 'yes':


Set these parameters to 'no':

PermitRootLogin, ChallengeResponseAuthentication, PasswordAuthentication, UsePAM

Set AuthorizedKeysFile to:


Save, close and reload the SSH config file:

$ service ssh reload

Exit the remote machine:

$ exit

Try to reconnect as the new user. You should not be prompted for a password:

$ ssh username@

Trying to SSH into the server from another machine you should receive this error: Permission denied (publickey)

Disable root login

As the admin user:

$ sudo passwd -l root

You will be prompted to enter the sudo user's password.

SECURITY SECOND: Add a firewall.

$ sudo apt install ufw

Optionally enable IPv6

$ sudo nano /etc/default/ufw


Save and close and set up rules.

Allow connections:

$ sudo ufw allow <port>/<optional: protocol>


$ sudo ufw allow 80/tcp or sudo ufw allow 80 or sudo ufw allow www

Deny Connections:

$ sudo ufw deny <port>/<optional: protocol>


$ sudo ufw deny 3306 (Deny default mysql port)

Start by denying all incoming and enabling all outgoing:

$ sudo ufw default deny incoming

$ sudo ufw default allow outgoing

Then allow incoming for services you need:

$ sudo ufw allow ssh

$ sudo ufw allow http

$ sudo ufw allow https

Finally, enable the firewall

$ sudo ufw enable

Common inbound ports to leave open

  • 80 http
  • 443 https
  • 22 ssh

Common inbound ports to close

  • everything else

LAMP installation and setup (mod_php)

Install Apache

$ sudo apt update

$ sudo apt install apache2 -y

Set root directory permissions

$ sudo chown -R username:username /var/www/html

$ sudo chmod -R 754 /var/www/html

Install MariaDB

$ sudo apt install software-properties-common

$ sudo apt install mariadb-server mariadb-client -y

You might be prompted to give root a password. Just leave it blank

Run the MySQL secure installation

$ sudo mysql_secure_installation

Remember to set a root password. By default connections to MariaDB are done through unix_socket. In the next steps you will create a non-root user. For that user you can use password authentication if necessary.

  1. Database creation

Log into MariaDB

sudo mysql -u root

Create a new database

  1. User creation

Add your user (probably the sudo user you created earlier) to MariaDB to use unix_socket

CREATE USER username@localhost IDENTIFIED VIA unix_socket;

or if using password auth:

CREATE USER username@localhost IDENTIFIED VIA mysql_native_password;

UPDATE user SET password=PASSWORD('password') WHERE User='username' AND Host = 'localhost';
  1. Grant all privileges to the user on a specific database. Only allow access from localhost (this is the most secure and common configuration you will use for a web application). This will probably be the new sudo user you have set up previously.
GRANT ALL privileges ON mydb.* TO myuser@localhost IDENTIFIED VIA 'unix_socket';
  1. Apply changes made
flush privileges;


Install PHP

sudo apt install libapache2-mod-php php-mysql php-zip php-curl php-gd php-common php-intl php-mbstring php-tokenizer php-xml -y

Set date.timezone in php.ini

date.timezone = America/Los_Angeles

upload_max_filesize = 20M

post_max_size = 20M

For development:

display_errors = On

Enable Apache mods

$ sudo a2enmod rewrite headers deflate expires

Run Apache as your user

sudo nano /etc/apache2/envvars

export APACHE_RUN_USER=username
export APACHE_RUN_GROUP=username

Additionally you will need

sudo chown username.username -R /var/log/apache2

Optionally install mailutils

$ sudo apt-get install mailutils

Postfix is now set up with a default configuration. If you need to make changes, edit /etc/postfix/

After modifying, be sure to run '/etc/ reload'


After installing composer, install unzip or else composer will shit it's pants about permissions and such.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment