Web servers
Web servers serve web pages to users.
Apache
The configurations described here are unique to Ubuntu:
- Webservers display the webpage at the server IP addr by default
- config files are in
/etc/apache2
- main config at
/etc/apache2/apache2.conf
- main config at
- uses plugins to extend functionality
- serves content from document root,
/var/html/www
by default - always reload so site doesnt go down. only restart when enabling a plugin or there are issues
You can run multiple websites on single server with virtual hosts
- each virtual host has its own config file to make it unique
- to host multiple sites, create
.conf
file in/etc/apache2/sites-available
dir with unique<VirtualHost>
stanza for each host - To run one site, you can just replace the default
index.html
from/var/www/html
Virtual Host setup steps:
- Create website content
- Upload files to server in document root?, usually
/var/www
but can be custom location - Make sure
www-data
owns all files in Document Root - Create site config file and copy into
/etc/apache2/sites-available
. For example,mysite.com.conf
- Enable site with
a2ensite
(disable witha2dissite
) - Ubuntu-specific?a2ensite
creates a symlink to your site config file and stores in/etc/apache2/sites-enabled
a2dissite
deletes the symlink
- Reload Apache to refresh config
apt install apache2 # 1. Install
systemctl status apache2 # 2. Verify its running
# --- --- #
a2ensite mysite.com.conf # Enable site and reload (abs path not required)
systemctl reload apache2
a2dissite mysite.com.conf # Disable site and reload (abs path not required)
systemctl reload apache2
Config files
Important config file info:
/etc/apache2/apache2.conf
:IncludeOptional
is where Apache looks for site.conf
files
- VirtualHost
.conf
files are stored in/etc/apache2/sites-available
and symlinked in/etc/apache2/sites-enabled
- Each site needs its own document root
- Default log files are fine with one site, but create custom files when serving multiple sites
- Name-based Virtualhosts only get one IP addr, so you have to provide the
ServerName
in the config file- Config file example name:
000-virtual-hosts.conf
- Server filters incoming requests using
ServerName
, points reqs toDocumentRoot
- Add as many sites as you want, just make sure your server has enough resources to handle reqs
- Config file example name:
Research A names, domain names and how to set up Apache
# --- /etc/apache2/apache2.conf --- #
...
# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf
# --- 000-default.conf --- #
<VirtualHost *:80> # listen to everything (*) on port 80
...
ServerAdmin webmaster@localhost # email addr displayed in site error messages
DocumentRoot /var/www/html # serve content from this dir
...
# APACHE_LOG_DIR set in /etc/apache2/envvars - /var/log/ by default
ErrorLog ${APACHE_LOG_DIR}/error.log # Logs site errors
CustomLog ${APACHE_LOG_DIR}/access.log combined # Logs incoming HTTP requests
...
</VirtualHost>
# --- Sample VirtualHost .conf multiple interfaces --- #
<VirtualHost 10.20.30.40:80> # IP addr IDs the correct network interface
...
ServerAdmin webmaster@localhost
DocumentRoot /var/www/mysitename # Unique DocumentRoot for each site
...
ErrorLog ${APACHE_LOG_DIR}/mysitename.com-error.log # Unique log file name
CustomLog ${APACHE_LOG_DIR}/mysitename.com-access.log combined # Unique log file name
...
</VirtualHost>
# --- Sample name-based VirtualHost .conf single IP addr (VPS) --- #
<VirtualHost *:80> # All traffic on port 80
...
ServerName firstsite.com # Links incoming reqs to DocumentRoot
ServerAdmin webmaster@localhost
DocumentRoot /var/www/firstsite.com # Unique DocumentRoot for each site
...
ErrorLog ${APACHE_LOG_DIR}/firstsite.com-error.log # Unique log file name
CustomLog ${APACHE_LOG_DIR}/firstsite.com-access.log combined # Unique log file name
...
</VirtualHost>
<VirtualHost *:80> # All traffic on port 80
...
ServerName second.com # Links incoming reqs to DocumentRoot
ServerAdmin webmaster@localhost
DocumentRoot /var/www/second.com # Unique DocumentRoot for each site
...
ErrorLog ${APACHE_LOG_DIR}/second.com-error.log # Unique log file name
CustomLog ${APACHE_LOG_DIR}/second.com-access.log combined # Unique log file name
...
</VirtualHost>
Modules
Modules extend functionality. Install modules based on your needs:
- installed as modules from
apt
repo - Debian sometimes enables modules by default
a2enmod
: enable a modulea2dismod
: disable a module
apache2 -l # view built-in modules
a2enmod # all modules currently installed but not enabled
apt search libapache2-mod # view available mods
systemctl restart apache2 # activate a new configuration
# --- Enable module --- #
apt install libapache2-mod-php8.3 # 1. install php
a2enmod php8.3 # 2. enable php
systemctl restart apache2 # 3. restart service
TLS
TLS encrypts your web traffic and communicates over HTTPS:
- Install signed certs into your server to protect and encrypt traffic
- SSL precedes TLS. SSL might still be in use, but use TLS for enhanced security
- apache runs on port 80, not port 443 (HTTPS)
- config file is
/etc/apache2/sites-available/default-ssl.conf
a2ensite
command enables SSL config file
- Need to generate certs:
- self-signed: good for testing, but in prod most browsers won’t trust them by default and send users to an error page first
- certificate authority: trusted, signed by vendor. Good for prod
- Let’s Encrypt is a good option for setting up certs
sudo ss -tulpn | grep apache # view ports apache listens on
# --- Enable TLS --- #
a2enmod ssl # 1. enable ssl mod
systemctl restart apache2 # 2. restart service
a2ensite default-ssl.conf # 3. enable SSL conf file
# --- /etc/apache2/sites-available/default-ssl.conf --- #
<VirtualHost *:443> # listen on port 443
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on # enables SSL traffic
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
<FilesMatch "\.(?:cgi|shtml|phtml|php)$"> # apply these options to files that match regex ext
SSLOptions +StdEnvVars #
</FilesMatch>
<Directory /usr/lib/cgi-bin> # apply options to a dir
SSLOptions +StdEnvVars # applies these options - enable default env vars
</Directory> # for TLS
</VirtualHost>
Self-signed certs
For testing purposes:
- need directory to store certs
.crt
is certificate.key
is private key
mkdir /etc/apache2/certs # 1. create dir for certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ # 2. generate certs and answer questions
-keyout /etc/apache2/certs/mysite.key \
-out /etc/apache2/certs/mysite.crt
vim /etc/apache2/sites-avaiable/default-ssl.conf # 3. add cert locations to conf file
SSLCertificateFile /etc/apache2/certs/mysite.crt # Comment out original files, add your cert locations
SSLCertificateKeyFile /etc/apache2/certs/mysite.key
systemctl reload apache2 # 4. reload service
vim /etc/apache2/sites-avaiable/default-ssl.conf # 5. Tell apache to handle req for our site w TLS
<VirtualHost *:443>
ServerName mydomain.com:443
...
CA certs
Same process as self-signed certs, but you don’t generate the certs yourself, you have to request them and then copy them to your fs:
- Create a Certificate Signing Request (CSR)
- pay vendor’s fee
- complete necessary forms
- prove you own the website in question
- vendor sends you the files
- Add them to
/ect/apache2/certs/
dir and config in../default-ssl.conf
default-ssl.conf sample
If you have multiple websites, you can copy this file as a template:
- Copy
default-ssl.conf
and call it/etc/apache2/sites-avaialble/mysite.conf
<VirtualHost *:443>
ServerName mysite.com:443
ServerAdmin webmaster@localhost
DocumentRoot /var/www/mysite
...
ErrorLog ${APACHE_LOG_DIR}/mysite.com-error.log
CustomLog ${APACHE_LOG_DIR}/mysite.com-access.log combined
...
SSLEngine on
...
SSLCertificateFile /etc/apache2/certs/mysite.crt
SSLCertificateKeyFile /etc/apache2/certs/mysite.key
...
<FilesMatch "\.(?:cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>
nginx
Proxy server and web server:
- Should not run two web services on the same machine because there might be conflicts
- content in
/var/www/html
- config files in
/etc/nginx
- same
sites-available
andsites-enabled
as apache
- same
- No commands to enable sites, must create the symlink manually
- For one site, replace the
../sites-available/default
content - For more than one site, copy default config file and make changes, then create new dir in
/var/www/
apt install nginx # install package
# --- enable a site --- #
sudo ln -s /etc/nginx/sites-available/site.com /etc/nginx/sites-enabled/site.com
systemctl reload nginx
Multiple site config
nginx can have only one default site, so you have to create a new config file:
- There is a templat at the end of the
default
site config - easier configuration
cp sites-available/default sites-available/mysite.com # 1. duplicate default config file
vim /etc/nginx/sites-avaiable/mysite.com # 2. edit new config file
...
server {
listen 80; # rm default_site bc there can be only one
listen [::]:80; # rm default_site bc there can be only one
...
root /var/www/mysite.com; # dir storing site files
...
index index.html index.htm index.nginx-debian.html; # leave as default
server_name mysite.com www.mysite.com; # change to name of new site
location / {
...
try_files $uri $uri/ =404;
}
...
TLS
Store certs in a file and update the config files to use port 443 and the certs:
- requires a pem key
mkdir /etc/nginx/certs # 1. create dir for certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ # 2. generate certs and answer questions
-keyout /etc/nginx/certs/mysite.key \
-out /etc/nginx/certs/mysite.crt
vim /etc/nginx/sites-avaiable/tlssite.com # 3. edit config file
server {
listen 443 ssl;
listen [::]:443 ssl;
...
root /var/www/tlssite.com;
...
index index.html index.htm index.nginx-debian.html;
server_name tlssite.com www.tlssite.com;
ssl_certificate /etc/nginx/certs/cert.pem;
ssl_certificate_key /etc/nginx/certs/cert.key;
ssl_session_timeout 5m;
location / {
try_files $uri $uri/ =404;
}
...
vim /etc/nginx/sites-avaiable/default # 4. redirect users from default site
...
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://$host$request_uri;
...
Nextcloud
Requires web server to work:
- sync files between machines
- store and sync contacts
- keep track of tasks
- get email from a server
wget https://download.nextcloud.com/server/releases/latest.zip # 1. Download the latest zip
unzip latest.zip # 2. Unzip archive
mv nextcloud /var/www/html/nextcloud # 3. Move to Apache server dir
chown www-data:www-data -R /var/www/html/nextcloud # 4. Give Apache user account and group full access
vim /etc/apache2/sites-available/nextcloud.conf # 5. Create config file
a2ensite nextcloud.conf # 6. Enable site
apt install libapache2-mod-php8.3 # 7. Install Nextcloud req packages
php8.3-curl
php8.3-gd
php8.3-intl
php8.3-mbstring
php8.3-mysql
php8.3-xml
php8.3-zip
systemctl restart apache2 # 8. Restart Apache
mariadb -u root -p # 9. Log in to mariadb as root
CREATE DATABASE nextcloud; # 10. Create Nextcloud db
GRANT ALL ON nextcloud.* to 'nextcloud'@'localhost' # 11. Create user nextcloud and grant full access to db
IDENTIFIED BY 'super_secret_password';
# --- Nextcloud setup questions --- #
1. Go to <server-ip>/nextcloud
2. Complete the account setup:
New admin account: admin
New admin password: <password>
Database account: nextcloud (from step 11 above)
Database password: <password> (from step 11 above)
Database name: nextcloud (from step 11 above)
Database host: localhost (if you set up db on same machine as Nextcloud server. Otherwise, enter db server IP)
3. Select Install.
4. Create a regular user account. Use admin account to enable or disable apps.
# --- NextCloud config file --- #
<Directory /var/www/html/nextcloud/> # access at www.<domain-name>.com/nextcloud
Options +FollowSymlinks # if ServerName is not set, uses <server-ip>/nextcloud
AllowOverride All
<IfModule mod_dav.c>
Dav off # disable WebDAV - will not be file server
</IfModule>
SetEnv HOME /var/www/html/nextcloud # set env var HOME
SetEnv HTTP_HOME /var/www/html/nextcloud # set env var HTTP_HOME
</Directory>