Serve a Website with Lighttpd
Lighttpd is a web server designed and optimized for high performance. It has a small memory footprint compared to most servers, effective management of cpu-load, and an advanced feature set (SSL, URL-Rewrite-Redirect, FastCGI, EVHost (subdomain-ing), Auth, Output-Compression, and many more). Lighttpd is a great do-it-yourself solution for setting up your own light-weight web server.
Web Serving Overview
When you purchase a web domain name from a domain business per year, you will often get inundated with offers to also purchase domain space and other domain hosting services. This is where they make money. If you have little time available it can be simplest to pay the dollars per month and have the domain business do that for you.
Just so you know though, you could just do it yourself.
Building a Server
Keeping in line with the previous article listed on the left, “building a static website with Jekyll”, this Howto provides a method for the “build a website yourself” guy to also be a “host a website yourself” guy.
What’s Needed
-
A PC connected to the internet
For preference sake it’ll be assumed you have an old/extra laptop kicking around ready to be put to good use. A laptop can be a pretty good choice for hosting your own website. It can sit on the corner of your desk or up on a shelf serving your site, use very little power and even stay running during a power outage because of its battery. -
An IP Address from your ISP that doesn’t change much
For the most part the IP address your ISP gives your modem shouldn’t change very often. Usually there will be a reason like they do changes on the network system in your area or you have to reset your modem. (If for some reason you find your IP changing too often you may need to inquire into the cost of a somewhat fixed IP or change ISP’s.) -
A router
These days almost all modems used by ISP’s are a modem-router combination providing multiple network jack connections as well as wireless so it’s unlikely you need a separate one. If for some reason you are from the way way back era and have only a modem you need to pick up a router to provide the extra network port for your laptop server as well as the extra firewalling/security a router naturally provides. -
A domain name
Using a domain name allows navigation via a name instead of a numeric IP address. When you purchase a domain name from a domain business they will provide a DNS interface where you can asociate your purchased name with your ISP assigned IP address.Installation
The instructions below are compatible with Ubuntu Linux distributions. If you don’t have a preference or it’s the first time using a Ubuntu OS give Linux Mint a try. It’s quite a refined stable version of Linux.
-
Install Linux on the laptop if you haven’t already done so.
- Install Lighttpd.
Open a terminal (command prompt) and paste the following:sudo apt-get install lighttpd gamin
Test the Installation
- The Lighttpd installation comes with a very basic configuration, enough to present a placeholder page.
Start the lighttpd service.sudo service lighttpd start
-
On the laptop point the web browser to http://127.0.0.1 to see if lighttpd is running and serving the placeholder page. 127.0.0.1 is the systems local loopback. It is the path to itself. The default configuration should be serving on the HTTP default port 80. Typing http://localhost:80 would achieve the same thing.
- It’s always nice to see some progress. Before going further its probably best to stop the service.
sudo service lighttpd stop
Folder and File Setup
- Linux systems are quite stable by nature and have been serving websites for the internet for many many years. The tradition is for the system to serve web data out of the /var/www folder. A default placeholder page is set in a folder within named html.
In your terminal you could type:sudo ls /var/www sudo ls /var/www/html cat /var/www/html/index.html
You should see the html folder, index file and it’s contents in html code.
- Create your web documents root folder and change ownership. Create any subdomain folder(s) as well if you want. Best not to use any spaces in the name.
sudo mkdir /var/www/nameyourwebsitefolder/ sudo mkdir /var/www/nameyoursubdomainfolder/ sudo chown www-data:www-data /var/www/nameyour*
- Place your Jekyll site in the folder you just created (i.e. copy the contents of your Jekyll _site folder, after building, to DocumentRoot)
Example command: (change the path to your Jekyll project accordingly)sudo cp -R /home/owner/Git/myJekyllSite/_site/* /var/www/nameyourwebsitefolder/ sudo chown www-data:www-data /var/www/nameyour*
Another option, instead, is to simply create a temporary placeholder for testing purposes.
sudo nano /var/www/nameyourwebsitefolder/index.html
Paste something like the following: (modify YOURSITE.NET accordingly)
<!doctype html> <html lang="en" class="no-js"> <head> <meta charset="utf-8"> <title>Welcome page</title> <style type="text/css" media="screen"> body { background: #b0b0b0; font-family: Verdana, sans-serif; font-size: 11pt; } #page { background: #ffffff; margin: 50px; border: 2px solid #707070; padding: 10px; } #header { background: #321e66; border: 2px solid #7590ae; text-align: center; padding: 10px; color: #ffffff; } #header h1 { color: #ffffff; } #body { padding: 10px; } </style> </head> <body> <div id="page"> <div id="header"> <h1> YOURSITE.NET </h1> What is this site all about? Good question! </div> <div id="body"> <h2>Content</h2> Yes this is still an empty page. <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <h2>About</h2> <p> There is nothing about this page that is fascinating, no. </p> <p> </p> <p> </p> </div> </div> </body> </html>
Do the same for your subdomain(s), if any. (modify SUB.YOURSITE.NET accordingly)
sudo nano /var/www/nameyoursubdomainfolder/index.html
Change ownership
sudo chown www-data:www-data /var/www/nameyour*
Basic Configuration
NOTE: If at any time you need extra info or further explanation on configuration visit the Lighttpd Wiki.
- Modify the Lighttpd configuration file so that it uses your DocumentRoot.
sudo nano /etc/lighttpd/lighttpd.conf
Change the following variable to point to your folder.
server.document-root = "/var/www/nameyourwebsitefolder"
- Start the lighttpd service again. Your site should be visible at http://127.0.0.1
sudo service lighttpd start
- Add Lighttpd to your boot startup.
sudo systemctl enable lighttpd
- Give your laptop server a static IP address on your local network. A static IP address is an address that doesn’t change. You will need to log into your router/modem with whatever the username and password are. You should have documentation for your device either on paper or online. The log-in address is usually something like 129.168.0.1. Somewhere in and around the DHCP settings there should be a screen to associate a constant IP address with your laptop’s network interface card via it’s unique mac number. If it’s not obvious under your DHCP status which mac belongs to the laptop you can issue the following command on your laptop. (look for HWaddr)
ifconfig
- Open HTTP port 80. Once the laptop server has a static address find the router’s firewall configuration settings section and open port 80 for the laptop IP address. Something like:
- - IP ADDRESS- - - -PORT- - - PROTOCOL- - NOTES- - - 192.168.0.2 - - - 80 - - - - TCP - - - http -
-
Check if the server is accessible from the internet via your ISP provided modem IP address. From within the routers DHCP status section you should be able to find your external IP address. Type the address in your web browser and see if it can connect. Something like: http://23.45.65.43
- Associate your domain name with your IP. Once you know it is accessible via your external IP address log in to your account profile of the domain business where you purchased your domain name from. Under something like “Domain Management” or “Manage My Domain” find the DNS settings section and type in your external IP address. Something like:
- - - - - - - - DNS IP ADDRESS RECORD - - - - - - - - - - - *.yoursiteaddress.net - - POINTS TO - - 23.45.65.43
- Check if the website is accessible by the domain name. It may take some time for the DNS record to propogate out through the internet. Once it does you should be able to visit the site using HTTP to connect to it. Example: http://yoursiteaddress.net
Disable Directory Listings
- To keep internet users from being able to get a directory listing of the contents of your site folders you can set the dir-listing variable to disable. Add the variable assignment if the line doesn’t already exist.
server.port = 80 server.dir-listing = "disable"
Drop the www. with Redirect
-
Back when the internet was a new project idea it was placed in it’s own space on a campus network somewhere. That space was assigned www as its subdomain location (the World Wide Web). As the internet project grew in size and began to stand on its own outside the early network structure they kept the www. tradition to keep from breaking the hard-coded addresses in much of the early equipment, etc. In this day and age there is very little reason, besides user habit, to keep www. (i.e. Of course its on the world wide web!).
Make sure the redirect module is listed in the server modules section of the Lighttpd config.
sudo nano /etc/lighttpd/lighttpd.conf
The default config likely has it enabled already and looks like this with rewrite commented out below it.
server.modules = ( "mod_access", "mod_alias", "mod_compress", "mod_redirect", # "mod_rewrite", )
Further down somewhere close to the bottom add a redirect for your domain. This takes the typed in www request and changes it to a request without it. Change the name accordingly.
# redirect www subdomain requests to the root domain $HTTP["host"] =~ "^www\.yoursiteaddress\.net$" { url.redirect = ( "^/(.*)" => "http://yoursiteaddress.net/$1" ) } # default listening port for IPv6 falls back to the IPv4 port
Restart Lighttpd and test it out. Now when someone types in http://www.yoursiteaddress.net the location bar will change to http://yoursiteaddress.net.
sudo service lighttpd restart
Add a Subdomain with EVHost
- It can be beneficial to organize parts of your site into a separate subdomain and/or provide a different service, etc. under the umbrella of your domain. Often you’ll see something like docs.whateversite.com.
Add evhost to the server modules section of the Lighttpd config.server.modules = ( "mod_access", "mod_alias", "mod_compress", "mod_redirect", "mod_evhost", # "mod_rewrite", )
Further down somewhere close to the bottom just below your redirect add an evhost entry for the name of your subdomain pointing to your sub folder. Change the names accordingly.
$HTTP["host"] =~ "docs.yoursiteaddress.net" { evhost.path-pattern = "/var/www/nameyoursubdomainfolder/" } # default listening port for IPv6 falls back to the IPv4 port
Restart Lighttpd and test it out. Typing the subdomain into your browser should now direct you to the placeholder page or whatever you placed in your sub folder.
Enable SSL (HTTPS with Lighttpd)
As technology has evolved, security has become more important. It is now possible to encrypt and decrypt on the fly. If you’re thinking there’s nothing you’re serving that’s super critical to encrypt, another motivating factor to bring your site up to the higher standard is search engines.
Most search engines these days prefer to display a list of newer, secure (https) sites over original, “unsecure” (http) ones simply due to the possibility there could be input forms in the site pages. When input form data is transmitted over the internet it is much less risky having it encrypted if, by chance, it were to get intercepted and copied along the way. The search engine companies would rather not provide a search result to a site that could put the user at risk.The following instructions are largely based on a pretty good tutorial by Vivek, over at nixCraft that uses Neil Pang’s acme.sh script to provide Free SSL Certification from Let’s Encrypt.
- Install some dependencies for downloading, installing and utilizing the acme.sh script.
sudo apt-get install git bc wget curl
- Clone the acme.sh repo.
cd /tmp git clone https://github.com/Neilpang/acme.sh.git sudo -i cd /tmp/acme.sh/ ./acme.sh --install
- Create the acme-challenge directory in your DocumentRoot site folder. Alter the root folder name accordingly.
mkdir -vp /var/www/nameyourwebsitefolder/.well-known/acme-challenge/ chown -R www-data:www-data /var/www/nameyourwebsitefolder/.well-known/acme-challenge/ chmod 0555 /var/www/nameyourwebsitefolder/.well-known/acme-challenge/
- Create a site directory to store the SSL certificate. Alter domain name accordingly.
mkdir -p /etc/lighttpd/ssl/yoursiteaddress.net/
- Generate your dhparam.pem file.
cd /etc/lighttpd/ssl/yoursiteaddress.net/ openssl dhparam -out dhparam.pem -dsaparam 4096
It may take a while and look something like the following.
Generating DSA parameters, 4096 bit long prime .....+..............+......+.+..........+.+++++++++++++++++++++++++++++++++++++++++++++++++++* +....................................+............+..........................+.+.....+.+.....+...........+..........+........+...+..+...+..+............+......+.....+....+......+......................................+..+.....+.+............+....+.+.+..+........+...+.............+..+........+++++++++++++++++++++++++++++++++++++++++++++++++++*
- Issue a certificate for your domain. Include the www. subdomain because even though you redirect it to your root domain (i.e. you drop the www. with redirect - step 18) the header actually still needs to be decrypted before it can read the redirect. Include your subdomain(s) as well. Alter the folder and site names accordingly.
acme.sh --issue -w /var/www/nameyourwebsitefolder -d yoursiteaddress.net -d www.yoursiteaddress.net -d docs.yoursiteaddress.net -k 4096
- Edit your Lighttpd config to include support for SSL on port 443 and make it aware of your certificates.
nano /etc/lighttpd/lighttpd.conf
Add the following just above your redirect entry (added in step 18).
Alter the site folder name accordingly.$SERVER["socket"] == ":443" { ssl.engine = "enable" ssl.disable-client-renegotiation = "enable" ssl.pemfile = "/etc/lighttpd/ssl/yoursiteaddress.net/ssl.pem" ssl.ca-file = "/etc/lighttpd/ssl/yoursiteaddress.net/ca.cer" ssl.dh-file = "/etc/lighttpd/ssl/yoursiteaddress.net/dhparam.pem" # ECDH/ECDHE ciphers curve strength ssl.ec-curve = "secp384r1" ssl.use-compression = "disable" # Environment flag for HTTPS enabled setenv.add-environment = ( "HTTPS" => "on" ) ssl.use-sslv2 = "disable" ssl.use-sslv3 = "disable" ssl.cipher-list = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA" ssl.honor-cipher-order = "enable" # HSTS(15768000 seconds = 6 months) setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=15768000;" ) } # redirect www subdomain requests to the root domain
- Update the redirect you added in step 18 to use https:// instead of http:// and add a redirect for all http requests.
Make it look like this. Alter site name accordingly.# redirect www subdomain requests to the root domain using https only # yet still allow acme.sh update mechanism access to its challenge folder via http $HTTP["host"] =~ "^www\.yoursiteaddress\.net$" { $HTTP["url"] !~ "^/.well-known/acme-challenge/.*$" { url.redirect = ( "^/(.*)" => "https://yoursiteaddress.net/$1" ) } } # redirect all http traffic to https # yet still allow acme.sh update mechanism access to its challenge folder via http $HTTP["scheme"] == "http" { $HTTP["host"] =~ ".*" { $HTTP["url"] !~ "^/.well-known/acme-challenge/.*$" { url.redirect = ( ".*" => "https://%0$0" ) } } }
- Create a hook script that can perform the install of the issued SSL certificate and restart the Lighttpd web server. Alter the folder path accordingly.
nano /root/.acme.sh/yoursiteaddress.net/hook.sh
Paste the following:
#!/bin/bash dom="yoursiteaddress.net" #your domain name dest="/etc/lighttpd/ssl/yoursiteaddress.net" #lighttpd ssl path root croot="/root/.acme.sh/${dom}" #acme.sh root path for your domain ### NO edit below ### sslfile="${dest}/ssl.pem" #lighttpd .pem file path certfile="${croot}/${dom}.cer" #lighttpd certficate file path keyfile="${croot}/${dom}.key" #lighttpd key file path echo "Running lighttpd cmd..." /bin/cat "${certfile}" "${keyfile}" > "${sslfile}" /bin/systemctl restart lighttpd
Make the script executable
chmod +x /root/.acme.sh/yoursiteaddress.net/hook.sh
- Paste the following command to install the certificate and restart the lighttpd web server:
acme.sh --installcert -d yoursiteaddress.net \ --capath /etc/lighttpd/ssl/yoursiteaddress.net/ca.cer \ --reloadcmd '/root/.acme.sh/yoursiteaddress.net/hook.sh'
- Verify Lighttpd is running and listening on port 443
netstat -tulpn | grep ':443'
Output should look something like:
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 379/lighttpd
- Make sure the port 443 is open in your ufw firewall. Type the following:
ufw allow 443/tcp
- Log in to your router and open port 443 for your server. It should look something like the following.
- - IP ADDRESS- - - -PORT- - - PROTOCOL- - NOTES- - - 192.168.0.2 - - - 80 - - - - TCP - - - http - - - 192.168.0.2 - - - 443- - - - TCP - - - https-
If all went well your site should be available via https with your web browser. (i.e. https://yoursiteaddress.net)
NOTE: The SSL certificate is valid for 90 days. The installation of acme.sh created a cron job that will try to do a scheduled renewal of the certificate for you. The cron job looks like this:
33 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null