Hoe installeer ik een veilige website op Debian 12 met Apache 2.4, PHP 8, SSH 9, SSL 3, UFW, HTTPS, HTTP2, en securityheaders?



Installeer de nieuwste versie van Debian 12 met Cinnamon Desktop, webserver en SSH server.


Open terminal en kijk of het hekje er staat.

Zo ja dan ben je root.

root@vps#

apt update

apt upgrade



Maak een user aan, geef 2 x een password, geef sudo rechten en switch user.


root@vps#

adduser bas

# give password twice

# add users to sudo

sudo usermod -aG sudo bas

# switch user account

su - bas

# give password for user bas

# nu staat er een $ in je console zoals hieronder

bas@vps$



Installeer en activeer de UFW firewall voor een veilige verbinding met SSH en voor je website:

sudo apt install ufw

sudo ufw status

# sta SSH op poort 22 toe voor een bepaalt ip adres:

sudo ufw allow from hier.je.ip.adres to any port 22

# of sta SSH toe op alle ip adressen:

sudo ufw allow SSH

# open poort 80 en 443 voor je website:

sudo ufw allow 'WWW Full'

sudo ufw enable

sudo ufw reload

sudo ufw app list

# regel verwijderen doe je zo:

sudo ufw status numbered

sudo ufw delete 3

sudo ufw reload



Als je root wil toestaan voor SSH kun je de sshd config file aanpassen.

nano /etc/ssh/sshd_config

Ergens in de file staat PerminRootLogin haal het hekje weg en maak daarvan:
PermitRootLogin yes


Reboot of reload SSH



Nu kan je inloggen op je webserver met ssh en dus niet vanaf andere ip adressen, anders moet je die handmatig toevoegen.


Handig voor SFTP Drive en RDP door een SSH tunnel


Meer info op https://www.computerbas.nl/ssh


SFTP programma's voor Windows:


Filezilla

SFTP Net Drive



SSH Tunnel met Putty:


In Putty:


Maak een SSH tunnel met port 1234 en destination localhost:3389


Open tunnel en log in.



RDP via SSH tunnel:


Op server:


sudo apt install cinnamon-desktop-environment

sudo apt install xrdp

sudo reboot



Op werkstation:


In RDP log je in met 127.0.0.1:1234 en servernaam\user


Nodig voor bovenstaande:


Putty voor Windows


En snel door naar het echte werk!


Apache webserver:

sudo apt install apache2

sudo systemctl status apache2

sudo apache2ctl configtest

sudo apachectl -V

sudo systemctl reload apache2

sudo systemctl restart apache2


All good?


Maak een folder en een index.html voor je website en geef rechten

sudo mkdir -p /var/www/computerbas

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

sudo chmod -R 755 /var/www/computerbas

nano /var/www/computerbas/index.html


Hier de index.html:

<html>

<head>

<title>Welkom op mijn website.nl!</title>

</head>

<body>

<h1>Gelukt! Virtual host werkt!</h1>

</body>

</html>


hostname -I

sudo apt install curl

curl -4 icanhazip.com

# dit is je server ipv4

curl -6 icanhazip.com

# dit is je server ipv6


kijk of het gelukt is: http://hier.je.server.ipv4


kijk of het gelukt is: http://[hier.je.server.ipv6]


Nu de VirtuaHost voor je website:
sudo systemctl restart apache2

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


En dan copy/paste en pas aan naar je website:

<VirtualHost *:80>

ServerAdmin bas@computerbas.nl

ServerName computerbas.nl

ServerAlias www.computerbas.nl

DocumentRoot /var/www/computerbas

ErrorLog ${APACHE_LOG_DIR}/error.log

CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>


Maak je configuratie actief:

sudo a2ensite computerbas.conf

sudo a2dissite 000-default.conf

sudo apache2ctl configtest



Do not copy/paste the #Comments

En snel door naar een echte website met PHP ondersteuning.

# Install manual for PHP 8.4 with HTTP2
# Install wget and get the PHP GNU privacy guard file

sudo apt install apt-transport-https lsb-release ca-certificates wget -y
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
sudo apt update


En kijk of het is gelukt:

# Check installed versions

sudo dpkg -l | grep php | tee packages.txt

# If PHP is not installed you will see nothing as result.
# Install PHP 8.4
# Note: you can expand the curly braces { } with all extensions necessary.

sudo apt install php8.4 php8.4-cli php8.4-mysql php8.4-{gd,zip,bz2,curl,mbstring,intl}
sudo apt install php8.4-fpm
sudo a2enconf php8.4-fpm

# When upgrading from older PHP versions:

sudo a2disconf php7.4-fpm

## Remove old packages

sudo apt purge php7.4*
sudo apt update
sudo apt upgrade

#Check installed version again

sudo dpkg -l | grep php | tee packages.txt


Als het goed is heb je nu alleen PHP 8.4

All good? Door!

nano /var/www/computerbas/index.php


Hier de index.php:

<html>

<head>

<title>Welkom op mijn php website.nl!</title>

</head>

<body>

<h1>Gelukt! Virtual host met php werkt!</h1>

</body>

</html>

<?php phpinfo();?>


HTTP2 en securityheaders:

sudo a2enmod http2

sudo systemctl restart apache2

sudo a2enmod headers

sudo systemctl restart apache2


Security:

sudo apt install libapache2-mod-security2

sudo systemctl restart apache2

sudo nano /etc/apache2/conf-enabled/security.conf


En dan:

ServerTokens Full

ServerSignature On

SecServerSignature "ComputerBas"

TraceEnable Off


Expires header:

sudo a2enmod expires

sudo systemctl restart apache2



SSL:

sudo apt update


Voor Debian 11 en 12:


sudo apt install python3-certbot-apache

sudo certbot --apache --key-type rsa --rsa-key-size 4096 -d computerbas.nl -d www.computerbas.nl

sudo certbot renew --dry-run



Als je een subdomein hebt op een ander ip doe je dit op de server van het subdomein:

sudo certbot --key-type rsa --rsa-key-size 4096 -d sub.domeinnaam.nl

Zo zien mijn DNS records eruit:

Naam: @
TTL: 1 day
Type: A
Waarde: mijn.ip4.adres.hier

Naam: @
TTL: 1 day
Type: AAAA
Waarde: mijn.ipv6.adres.hier

Naam: @
TTL: 5 min
Type: CAA
Waarde: 0 issue "letsencrypt.org"

Naam: www
TTL: 1 day
Type: A
Waarde: mijn.ip4.adres.hier

Naam: www
TTL: 1 day
Type: AAAA
Waarde: mijn.ipv6.adres.hier

Zo ziet mijn VirtualHost file eruit in /etc/apache2/sites-enabled/computerbas.conf

De HTTP versie:

<VirtualHost computerbas.nl:80>
Redirect permanent "/" "https://computerbas.nl"
</VirtualHost>

<VirtualHost www.computerbas.nl:80>
Redirect permanent "/" "https://www.computerbas.nl"
</VirtualHost>

En de HTTPS versie in /etc/apache2/sites-enabled/computerbas-le-ssl.conf

<IfModule mod_ssl.c>
SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)

<VirtualHost computer.nl:443>

ServerName computerbas.nl
DocumentRoot /var/www/html

#Altijd WWW

Redirect permanent / https://www.computerbas.nl

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

Include /etc/letsencrypt/options-ssl-apache.conf
SSLUseStapling on
Protocols h2 http/1.1
SSLCertificateFile /etc/letsencrypt/live/computerbas.nl/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/computerbas.nl/privkey.pem
</VirtualHost>


<VirtualHost www.computer.nl:443>

ServerName www.computerbas.nl
ServerAlias computerbas.nl
DocumentRoot /var/www/html

#Omdat ik nog iets wijzig via de .htaccess file voeg ik deze regels toe:

<Directory /var/www/html>
DirectoryIndex index.php
AddType application/x-httpd-php .php
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>


ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

Include /etc/letsencrypt/options-ssl-apache.conf
SSLUseStapling on
Protocols h2 http/1.1
SSLCertificateFile /etc/letsencrypt/live/computerbas.nl/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/computerbas.nl/privkey.pem

</VirtualHost>

</IfModule>


sudo nano /var/www/computerbas/.htaccess


Zo ziet mijn .htaccess file eruit:


## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
</IfModule>
## EXPIRES CACHING ##

RewriteEngine On

# remove //
RewriteCond %{THE_REQUEST} //
RewriteRule ^(.*)$ /$1 [R=301,NC,L]

# remove /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,NC,L]

# remove .php extern
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [R=301,NC,L]

# map it back to .php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [R=301,NC,L]





En dan..



Securityheaders in ssl.conf:


Er zijn meer dan 100 HTTP response headers en je hebt ze zeker niet allemaal nodig. Alle mogelijk denkbare headers die je redelijkerwijs nodig zou kunnen hebben voor beveiliging staan hieronder.

Probeer ze zeker niet allemaal tegelijk aan te zetten want dan kom je er niet achter welke header een probleem geeft als je website het niet meer doet.

Als je meer wilt weten over een specifieke header check wikipedia: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields


Als je Let's Encrypt gebruikt voor je SSL certificaat staat het configuratie bestand hier:


/etc/letsencrypt/options-ssl-apache.conf


En in:


/etc/apache2/sites-enabled/000-default-le-ssl.conf


staat :


Include /etc/letsencrypt/options-ssl-apache.conf


Om een nieuw configuratie bestand te gebruiken doe je dit:


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


SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)

DocumentRoot /var/www/computerbas

ServerName www.computerbas.nl

ServerAlias computerbas.nl

Include /etc/letsencrypt/ssl.conf

SSLCertificateFile /etc/letsencrypt/live/computerbas.nl/fullchain.pem

SSLCertificateKeyFile /etc/letsencrypt/live/computerbas.nl/privkey.pem

DirectoryIndex index.php

AddType application/x-httpd-php .php

Options Indexes FollowSymLinks


En dan maak je vervolgens het bestand dat je include in de virtualhost. Deze dus: /etc/letsencrypt/ssl.conf


sudo nano /etc/letsencrypt/ssl.conf


Copy/Paste dit hier:

SSLEngine On

SSLHonorCipherOrder On

SSLCompression Off

SSLUseStapling On

SSLOptions +StrictRequire

SSLProtocol -all +TLSv1.2 +TLSv1.3

SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-SHA

Protocols h2

SSLOpenSSLConfCmd ECDHParameters secp384r1

SSLOpenSSLConfCmd Curves secp521r1:secp384r1

SSLSessionTickets Off

SSLStaplingResponderTimeout 5

SSLStaplingReturnResponderErrors off

#ExpiresActive On

SetEnv no-gzip


#Kijk uit met deze settings! Controleer of je website nog wel werkt na elke stap!

#Check het debugscherm van je browser en de logboeken van je webserver!


Header always set Strict-Transport-Security 'max-age=63072000; includeSubDomains; preload'

Header always set X-Frame-Options DENY

Header always set X-Content-Type-Options nosniff

Header always set Set-Cookie __Secure-sessionid=computerbas;Path=/;Secure;HttpOnly;SameSite=Strict

Header always set X-Xss-Protection '1; mode=block'

Header always set Referrer-Policy 'no-referrer'

Header always set X-Permitted-Cross-Domain-Policies 'master-only'

Header always set X-Download-Options 'noopen'

Header always set X-Powered-By ComputerBas

Header always set Expect-CT max-age=0

Header always set Expect-Staple 'max-age=31536000; includeSubDomains; preload'

Header always set Access-Control-Allow-Origin computerbas.nl

Header always set Accept-Ranges bytes

Header always set Allow "GET, POST"

Header always set X-DNS-Prefetch-Control on

Header always set X-Robots-Tag all

#Header always set X-Robots-Tag none

Header always set Trailer Max-Forwards

Header always set Tk ?

Header always set X-UA-Compatible IE=edge

Header always set X-AspNet-Version ComputerBas

Header always set Access-Control-Allow-Credentials true

Header always set Access-Control-Allow-Methods "POST, GET"

Header always set Access-Control-Allow-Headers "origin"

Header always set Access-Control-Request-Method "POST, GET"

Header always set Access-Control-Request-Headers "X-PINGOTHER, Content-Type"

Header always set Access-Control-Max-Age 3600

Header always set Access-Control-Expose-Headers: Content-Length

Header always set cross-origin-embedder-policy "unsafe-none"

Header always set cross-origin-opener-policy "unsafe-none"

Header always set cross-origin-resource-policy "cross-origin"


Header always set Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), midi=(),fullscreen=()"


#Kijk uit met de onderstaande CSP settings! Controleer of je website nog wel werkt in het debug scherm van de browser.


Header always set Content-Security-Policy "default-src 'none'; media-src 'self'; object-src 'none'; font-src 'self' https://fonts.gstatic.com; frame-src 'self' https://gadgets.buienradar.nl; frame-ancestors 'none'; form-action 'self'; manifest-src 'self'; img-src data: 'self'; base-uri 'none'; style-src https://computerbas.nl https://www.computerbas.nl; child-src https://computerbas.nl https://www.computerbas.nl; connect-src 'self'; script-src https://computerbas.nl https://www.computerbas.nl; upgrade-insecure-requests;"

en dan..


Web Application Firewall:


nano /etc/modsecurity/modsecurity.conf


#Kijk uit met de onderstaande setting! Controleer of je website nog wel werkt in het debug scherm van de browser en ohja een herstart van apache duurt ongeveer 10 seconden langer. Is niet erg maar dan weet je dat ook weer.

#SecRuleEngine DetectionOnly

SecRuleEngine On




Alles werkend? Cool! Maak een snapshot en een backup!



Lees deze handleiding (en andere) op mijn forumpagina hier:

https://forum.computerbas.nl/viewtopic.php?id=64



bezoekers: 1956    Laatst gewijzigd op 14/05/2025