Login into your server as the root user ssh root@xx.xx.xxx.xx
Update everything first
apt update && apt upgrade
Set timezone to UTC
dpkg-reconfigure tzdata and select UTC
Set hostname
hostnamectl set-hostname caddy-prod
Setup user
Add a new user for ourselves, we won’t be using root user after this initial setup for security purposes.
adduser ashfame
usermod -aG sudo ashfame
Setup SSH key based login for ourselves
mkdir ~/.ssh; nano ~/.ssh/authorized_keys
Paste your public key and save the file. Set permissions.
sudo chmod -R 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
Now update SSH config
In /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
AddressFamily inet #to allow ipv4 only for ssh connection
Restart SSH service to bring the changs into effect
sudo systemctl restart sshd
Ensure you can login with your new user without a password and just by your key before killing your root user session.
Setup Firewall
ufw app list
ufw allow OpenSSH
ufw allow http
ufw allow https
ufw enable
ufw status
Install packages
Install Caddy
For installing Caddy, lets first install go lang so that we can compile from source, right here on the server (if needed)
Install Go lang
Download the latest archive file
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.linux-amd64.tar.gz
Add PATH=$PATH:/usr/local/go/bin
in $HOME/.profile
Clone Caddy from Github for compilation and installation
git clone https://github.com/caddyserver/caddy.git
cd caddy/cmd/caddy/
go build
sudo mv caddy /usr/bin/
caddy version
sudo chown root:root /usr/bin/caddy
sudo chmod 755 /usr/bin/caddy
Create Caddy user and group
sudo groupadd --system caddy
sudo useradd --system \
--gid caddy \
--create-home \
--home-dir /var/lib/caddy \
--shell /usr/sbin/nologin \
--comment 'Caddy web server' \
caddy
Set Caddy to run via systemd
Take systemd service file – https://github.com/caddyserver/dist/blob/master/init/caddy.service
and put that at /etc/systemd/system/caddy.service
Define Caddyfile at /etc/caddy/Caddyfile
:80
response "Hello world"
Now, test by loading your IP address of your server and you should see some “hello world” output defined in your Caddyfile
Install PHP8
sudo apt install php8.1-fpm php8.1-cli php8.1-common php8.1-mysql php8.1-zip php8.1-gd php8.1-mbstring php8.1-curl php8.1-xml php8.1-bcmath php8.1-opcache php8.1-readline
Install MariaDB for database in place of MySQL
sudo apt install mariadb-server
sudo mysql_secure_installation
sudo mariadb
Run the following SQL commands:
GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit
sudo systemctl status mariadb
sudo mysqladmin version
Create more databases and a user for each of them (`sudo mariadb`):
create database food_ashfame_com
CREATE USER 'food_ashfame_com'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON food_ashfame_com.* TO 'food_ashfame_com'@'localhost' WITH GRANT OPTION;
Create php-fpm user
sudo useradd --system \
--gid caddy \
--shell /usr/sbin/nologin \
--comment 'PHP-FPM user' \
php-fpm
In /etc/php/8.1/fpm/pool.d/www.conf
, change:
user = php-fpm
group = caddy
# For socket
listen.owner = caddy
listen.group = caddy
listen.mode = 0660
Configure log file in /etc/php/8.1/fpm/php.ini
using error_log
error_log = /var/log/php_errors.log
All configured/resultant config can be viewed in phpinfo()
‘s output
File permissions
Since we have configured php to run as php-fpm
user and its in caddy
group,
owners of all our files could be ashfame
and group as caddy
Permission as follows:
sudo find . -type f -exec chmod 640 {} +
sudo find . -type d -exec chmod 751 {} +
sudo chmod 640 wp-config.php
sudo chmod 660 wp-content/debug.log
This is tight enough to not allow WP upgrades, plugin installs etc to not work. Media uploads can be made to work with the following permission:
There are more things to do, like configure Caddyfile to run your WordPress sites and other services, which I might follow up on later in separate posts.
Leave a Reply