Setup a LAMP (Debian 11) - Optimized method
Tags: hosts, programming, tutorial
Published: 2023-04-13 21:39:37

## ⚡ Update / Upgrade

### Update source:

@ */etc/apt/sources.list*

```
deb http://deb.debian.org/debian/ {dist} main
```

### Update libs:

```bash
apt-get update
apt-get upgrade
```

### Update system:

```bash
apt-get upgrade --without-new-pkgs
apt-get full-upgrade
reboot
```

### Fix APT :

```bash
rm -fr /var/lib/apt/lists/*
apt-get --purge autoremove
apt-get clean all
```

### Check:

```bash
uname -r
lsb_release -a
```

---

## ⚡ Setup Access (SSH/SFTP)

### Install:

```bash
apt-get install openssh-server
# apt-get install ssh (client/server)
```

### Change root password:

```bash
passwd root
```

### Add SSH user:

```bash
adduser {username}
```

### Apply SUDO on SSH user:

```bash
usermod -aG sudo {username}
```

@ */etc/sudoers*

```
{username} ALL=(ALL) ALL
# {username} ALL=(ALL) NOPASSWD:ALL
```

## Setup SSH/SFTP (CHROOT)

### Configuration:

@ */etc/ssh/sshd_config*

```
Port {port}
LoginGraceTime 60
PermitRootLogin no
StrictModes yes
MaxAuthTries 6
MaxSessions 3
```

```
#Subsystem sftp /usr/lib/openssh/sftp-server (comment)
Subsystem sftp internal-sftp
```

```
Match [User|Group] {username|groupname}
        ForceCommand internal-sftp -u 077
        PasswordAuthentication yes
        ChrootDirectory /var/www
        AllowTCPForwarding no
        X11Forwarding no
```

### Restart:

```bash
sshd -t
systemctl restart sshd
```

### Check:

```bash
tail -f /var/log/auth.log
```

---

## ⚡ Setup Apache Server

### Install:

```bash
apt-get install apache2
apt-get install libapache2-mod-php7.4
```

### Configuration:

```bash
a2enmod rewrite
a2dissite 000-default
a2dissite default-ssl
a2ensite {site}
a2dissite {site}
apache2ctl configtest
service apache2 restart
```

---

## ⚡ Setup MySQL Server

### Install:

```bash
apt-get install mariadb-server
mysql_secure_installation
```

### Add database:

```bash
mysql -u root
```

```
CREATE USER '{username}'@'localhost' IDENTIFIED BY '{password}';
GRANT ALL PRIVILEGES ON *.* TO '{username}'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
CREATE DATABASE IF NOT EXISTS {database};
exit;
```

```bash
service mysql restart
```

### Dump:

```bash
mysqldump -u {username} –p {password} {database} > {dump.sql}
```

---

## ⚡ Setup PHP

### Install:

```bash
apt-get install php7.4 (php7.4-common)
apt-get install php7.4-cli
apt-get install php7.4-curl
apt-get install php7.4-intl
apt-get install php7.4-imagick
apt-get install php7.4-{extension}
```

### Change php version:

```bash
a2dismod php7.0
a2enmod php7.4
service apache2 restart
```

---

## ⚡ Setup PhpMyAdmin

### Install:

```bash
apt-get install phpmyadmin
```

### Configuration:

@ */etc/apache2/apache2.conf*

```
Include /etc/phpmyadmin/apache.conf
```

```bash
echo 'Include /etc/phpmyadmin/apache.conf' >> /etc/apache2/apache2.conf
service apache2 restart
```

---

## ⚡ Setup FTP (Optional)

### Install:

```bash
apt-get install vsftpd
```

### Configuration:

@ */etc/vsftpd.conf*

**Edit**:

```
listen=YES
write_enable=YES
chown_uploads=YES
chown_username=www-data
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd
pam_service_name=vsftpd
local_umask=0022
anon_upload_enable=YES
anon_mkdir_write_enable=YES
```

**Add**:

```
allow_writeable_chroot=YES
chmod_enable=YES
ftp_username=www-data
force_dot_files=YES
max_clients=10
max_per_ip=3
hide_ids=YES
user_config_dir=/etc/vsftpd
file_open_mode=0777
user_sub_token=$USER
vsftpd_log_file=/var/log/vsftpd.log
```

```bash
mkdir /etc/vsftpd
nano /etc/vsftpd/{username}
```

```
local_root=/var/wwwsername}
```

```bash
service vsftpd restart
```

---

## ⚡ Setup DNS Server

### Install:

```bash
apt-get install bind9
service bind9 restart
```

---

## ⚡ Setup SMTP

### Install:

```bash
apt-get install postfix mailutils (postfix-mysql)
service postfix restart
service apache2 restart
```

---

## ⚡ Setup TLS/SSL

### Install:

```bash
apt-get install openssl
apt-get install certbot python3-certbot-apache
```

### Configuration:

```bash
certbot --apache
# certbot renew (/etc/letsencrypt/renewal)
# certbot certonly --cert-name domain.com -d domain.com
service apache2 restart
crontab -e
```

```
12 3 * * * letsencrypt renew >> /var/log/letsencrypt/renew.log
```

```bash
service cron restart
```

---

## ⚡ Setup Firewall

### Install:

```bash
apt-get install ufw
```

### Configuration:

```bash
ufw disable
ufw default deny incoming
ufw default allow outgoing
ufw allow 80
ufw allow 443
ufw allow ssh
ufw allow from {IPV4} to any port {port}
ufw allow from {IPV6} to any port {port}
ufw enable
# ufw reset
```

---

## ⚡ Setup Permissions

### Add WEB/SFTP user:

```bash
useradd {username}
```

### Add WEB/SFTP user to www-data Group:

```bash
# adduser {username} {group}
usermod -aG www-data {username}
usermod -d /var/www -m {username}
```

### Apply WEB/SFTP directory permissions:

```bash
chown -R {username}:www-data /var/www/
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;
```

### Change Access Control Lists (Optional):

```bash
apt-get install acl
setfacl -R -m g:www-data:rwx /var/www
setfacl -R -m u:{username}:rwx /var/www
```

### Change Apache user:

@ */etc/apache2/envvars*

```
export APACHE_RUN_USER={username}
```

```bash
echo 'export APACHE_RUN_USER={username}' >> /etc/apache2/envvars
```

---

## ⚡ Setup Redis

### Install:

```bash
apt-get install redis-server
apt-get install php7.4-redis
apt-get install php7.4-igbinary
```

### Configuration:

@ */etc/redis/redis.conf*

```
# bind 127.0.0.1 ::1 (comment)
maxmemory 1024mb
maxmemory-policy allkeys-lru
```

### Restart:

```bash
service redis-server restart
```

### Test:

```bash
redis-cli
redis-cli FLUSHALL
```

---

## ⚡ Setup WP-CLI

### Install:

```bash
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod u+x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp
```

---

## ⚡ Setup GIT

### Install:

```bash
apt-get install git
```

### Configuration:

```bash
git config --global user.name "{username}"
git config --global user.email "{email}"
```

---

## ⚡ Setup Security

### Install Fail2ban:

```bash
apt-get install fail2ban
```

### Secure Apache:

@ */etc/apache2/apache2.conf*

```
# Decrease Timeout value
Timeout 60
```

@ */etc/apache2/mods-available/ssl.conf*

```
# Use only TLS, Disable SSLv2, SSLv3
SSLProtocol -all +TLSv1

# Disable Weak Ciphers
SSLCipherSuite HIGH:!MEDIUM:!aNULL:!MD5:!RC4
```

@ */etc/apache2/mods-available/userdir.conf*

```
# Limit HTTP Request Methods
allow only GET, POST and HEAD
```

@ */etc/apache2/conf-available/security.conf*

```
ServerTokens Prod
TraceEnable off
ServerSignature Off
FileETag None
```

```
# Set rules for Directory /var/www/html
Options None
AllowOverride All
Order Allow,Deny
Allow from All
```

```bash
a2enmod headers
```

```
# Cookie with HttpOnly and Secure flag
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure

# Clickjacking Attack Protection
Header always append X-Frame-Options SAMEORIGIN

# XSS Protection
Header set X-XSS-Protection "1; mode=block"

# Enforce secure connections to the server (HSTS)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

# MIME sniffing Protection
Header set X-Content-Type-Options: "nosniff"

# Prevent Cross-site scripting and injections
Header set Content-Security-Policy "script-src 'self'; object-src 'self'"
```

```bash
service apache2 restart
```

### Disable FTP access:

```bash
iptables -A INPUT -p tcp --dport 21 -j DROP
```

---

## ⚡ Tools

### Install:

```bash
apt-get install net-tools
```

---

## ⚡ Service

### Reset:

```bash
systemctl stop {service}
systemctl disable {service}
systemctl unmask {service}
rm /etc/systemd/system/{service}
rm /usr/lib/systemd/system/{service} 
systemctl daemon-reload
systemctl reset-failed
```

---

## Authors:

* **Jihad Sinnaour** - [Jakiboy](https://github.com/Jakiboy) (*Initial work*)

## ⭐ Support:

Please give it a Star if you like the project.