## Background
*TL;DR get to *[the point](#thepoint)
I think it was roughly the end of high school when I first had the idea I
wanted to make *some* kind of website. This would be around 2010 and I did
what I thought would be a good idea and bought a book on the subject: "Web
Sites for Dummies." I was dummy after all...
I got up to hyper linking with the "a" tag until I hit a wall. I don't want to
link the exact page since I don't want to get sued, but it basically read:
```
Web design programs:
- Adobe Dreamweaver
- Adobe Contribute
- Microsoft Expression Web
```
Well, damn. I didn't have any of those. And as a stingy high school kid, I
didn't want to buy anything. So I shelved that book and forgot about for a
while since making a website seemed too expensive and needed too much flashy
software to make it. I knew nothing about free software at that age,
other than music software like Audacity which is what I was into at the
time.
A few years later I caught a bit of a poetry bug--and maybe a bit of a
snooty college kid bug--and tried to run a blog. At that point, I had
learned about WordPress, which lets you easily make a space for sharing
writing, media, content, whatever really. And it's free as in *freedom*
as I understand since it's licensed under the GPL (if you want to take
the time to deploy it yourself). But they also give out free .wordpress
domains and some storage space with a snazzy dashboard to manage it all.
I had fun with that one, I don't update it anymore, but it's still up at
postquantumpoetry.wordpress.com
. WordPress got closer to what I wanted, but it still wasn't
*really* my site; it was WordPress's site unless I wanted to pay the
hosting and domain fee. It's pretty modest, but I wasn't sold on
sticking with a .com or .space domain, or even sticking with WordPress.
I was getting tired of blogging anyway. I was getting more interested
in the stuff that made it work; it seemed a lot more fruitful than
writing to no one.
It's now 2021, five years later, when I write this (and this website
isn't even finished yet). So what led me down the rabbit hole again?
It probably started where the last one left off, when I decided I
wanted to switch to more practical IT things over the academic things
I had previously wanted to pursue. I signed up for a Cybersecurity
program, somehow got in, and eventually managed to land an entry-level
SOC role after graduating.
At this point, it was getting a little weird that I had no web presence
--especially after I decided to take down most of my social media
accounts a few years ago.
So I was back at "how do I make a website," again, but this time, I
at least had some understanding of what a server was and how networks
work. And more importantly, I had a better idea of what it meant for
a computer to be *mine*.
Even though--let's be real--it *still isn't.*
I can't get high-speed Internet easily which I need to host a server
long-term so I'm stuck using some else's computer, otherwise called a
Virtual Private Server (VPS). Even if I could host at home, I'm still
of at the mercy of my ISP.
Because of that, I think it's important to understand that
"running your own website" is not just a *technical* ordeal, but also an
*economic* one since you have to carefully think about what it means to
you to *own* your server, your software, and your hardware. That doesn't
mean it's hard to do, just that there's options.
## What is a web server and how do I run one?
*TL;DR a web server is just a program that lets other computers on a
network view files in a chosen folder. All you need to do is download a
web server: apache and nginx are popular ones, but you can easily
program your own with web frameworks like
[Flask](https://flask.palletsprojects.com/en/2.0.x/) or
[Facil](https://facil.io/)*
You can run a web server for free right now. If you're on windows go
download Apache for Windows
[here](https://httpd.apache.org/docs/current/platform/windows.html) and
follow the set up guide
[here](https://www.liquidweb.com/kb/how-to-install-apache-on-a-windows-server/).
If you're on Linux, you probably already have it installed.
Find the configuration file in `sites-available/default` (on
windows, this may be led by C:\Program Files\Apache Software
Foundation\Apache2.4\ ). You'll see something like the following:
```
ServerAdmin webmaster@localhost
DocumentRoot /var/www
Options FollowSymLinks
AllowOverride None
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
```
For now, you don't need to change anything, so don't worry about what it
means.
But do note the directory set on "DocumentRoot," which may differ for
you. This is where the web server looks for files and folders.
So let's put some stuff there! Put whatever, a picture, a text file.
Run the server, then go to your web browser and type: `http://localhost`.
You'll find a directory with your files in it! And you can access them
at `http://localhost/filename.extension`
The problem is, only you and others on your home network can visit your
site right now.
Your computer's most likely behind your router's firewall, which will
not allow any traffic in. You'll need to forward a port from your router
(port 80 is for HTTP) to point to the device hosting the server.
Router's differ when it comes to to exact configuration, but MOST
routers will have some kind of steps similar to this:
1) Click "Advanced" then click "Firewall"
2) Scroll to the add new rule form
3) Put in the following values
- source/original port: 80
- forward to address/device: your device's local ip
- forward to/destination port: 80
You can get your device's local ip by typing `ipconfig` (Windows) or `ip
a` (Linux). Typically it is listed first and will start with "192.168" or
"10.0" but it depends on the manufacturer. Here's my output at home for
example:
```
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp7s0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 4c:cc:6a:93:eb:0b brd ff:ff:ff:ff:ff:ff
inet 192.168.1.202/24 brd 192.168.1.255 scope global dynamic noprefixroute enp7s0
valid_lft 74501sec preferred_lft 74501sec
inet6 fe80::4ecc:6aff:fe93:eb0b/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: wlp5s0: mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 82:e2:e4:c2:0c:a1 brd ff:ff:ff:ff:ff:ff permaddr 98:de:d0:f3:d6:ea
```
The device "enp7s0" is my Ethernet adapter (starts with an 'e') and my
current local ip address for the device is shown. If you use wifi, it
will likely start with a "wl."
Now get your *public* ip address at this site https://who.is/ and share
it with your friends. Watch in horror as they access all the files in
the directory you launched the server!
## How can make this server available on the Internet *cheaply* and *independently*
*TL;DR Expense scales with independence. It's possible to become your own
service provider, get IP addresses from ICANN, your own hardware to host
it, to host your cat pics; but it's also a lot of time, work and money
to do all that
([this guy](https://hackaday.com/2018/09/20/one-mans-journey-to-become-his-own-isp/)
did it apparently, and so did [Null](https://en.wikipedia.org/wiki/Kiwi_Farms))
Most likely you'll want to rent someone else's server, usually a VPS.*
Once you understand the basic installation above, you can now populate
your site with content just by adding HTML files to your web directory.
You can use an HTML editor to write these, or you can download a full
content management system to help you. Here are some options I know
about:
- You can just write the damn HTML and use apache or nginx
This honestly is not that hard, it just takes long and takes away from
the joy of writing in my opinion. But if your content is short and
sweet, or you're mostly hosting files, writing a few basic HTML files in
vim or notepad and adding some CSS goes a long way.
- [Neocities](https://neocities.org/)
Neocities is based on the old Geocities from the mid 90s which allows
simple static hosting and features and amazing array of creative
projects. Everything is managed through the website, and you can pay to
set your own custom domain.
- Wordpress (but this time, you set it up)
Before wordpress was a social media blogging thingamajig, it was just a
content management system to spin up a pretty blog. You can download and
install Wordpress by following:
https://wordpress.org/support/article/how-to-install-wordpress/
The benefit of installing yourself is enormous,
since you have full control and can even edit the source if you have
the guts.
- [Github pages](https://guides.github.com/features/pages/)
In addition to hosting code repositories, you can host small sites on
github for mostly free. I've never used it, but I definitely would if I
needed something like a small wiki.
But once you have stuff to share, how do you keep this stuff online?
### Can I run a web server at home
Technically yes, but practically probably not. At least not at a lot of
extra cost to you. If you do want to host a small thing at home, like
some text or some cat pics, a
[tor hidden service](/site/tutorial/how-to-host-a-tor-hidden-service.html)
is a great option.
I spent a lot of time searching on this (you can find a full list of
references at the bottom), and I've even tested a little bit by hosting
game servers and web projects for code jams, but the problem is
twofold. First, if you are in the United States and not a business,
you probably have a standard plan with one of the major ISPs (Verizon,
Optimum, etc.). This limits you in a few ways.
- Your bandwidth is limited, which limits the amount of people you can serve
at one time *and* the rate you can transfer data to them. Think laggy
games and videos that take 10 years to download.
- Your ISP probably explicitly does not allow this (at least in the US).
I have *never* had my ISP complain about hosting small personal servers
at home, but I imagine if I hosted higher traffic things, I would have
some problems.
### So what should I do
Most people will find it cheapest to rent from a VPS provider--VPS
stands for "Virtual Private Server," which just means an
Internet-connected server stored somewhere in someone's private data
center. You pay them for the storage and to keep your server online and
accessible.
Once you've got enough content and a way to manage it, all you have to
do is just copy all that stuff over to your VPS. Usually that looks
like:
- Installing a web server and a CMS tweaked to your liking
- Copying over your stuff to the web directory
- Opening up your ports to the outside world.
And in a nutshell that's it. There's fancy stuff of course, like you'll
want a [domain name](#dns) probably and I'll talk about that too, but at
this point, your stuff is on the Internet! Just tell your friends to
paste in your public ip address (your VPS provider will tell you this)
and there's your stuff!
## What's a "Domain Name"
Expecting people to save your IP address is not really a good idea
though. It's better to have an easy name they can remember. Enter DNS,
the Domain Name System. If an IP address is a telephone number, DNS is
the telephone book. ICANN and IANA host the top level servers, which
point to local domain registries who buy names like "mjfer.net" on
behalf of their customers.
The actual business of domain names is complicated and not something I
understand all that well. But setting up a domain name to point to an IP
address is typically easy, once you've chosen a domain registrar (just
search that online and you'll find a ton) and name you like. Be aware
that shorter names are rarer and usually more expensive and different
TLDs (like ".net" and ".io") will be priced differently.
Once you have a domain name, you'll need to set up a DNS record. Again,
this varies a bit based on the provider, but all will have some kind of
text input of API where you can edit DNS records. You'll want to make
two records
- A Type A that will be your main record
- set the HOST to your domain name (like mjfer.net)
- set the ANSWER to your IP address (like 8.9.36.54)
- A CNAME record, that will help point to all your other records
- set the HOST to your domain name, with a wildcard subdomain (like \*.mjfer.net)
- set the ANSWER to your main record (like mjfer.net)
The reason for the second record is in case you want to set subdomains
on the same IP address like "git.mjfer.net".
Wait a few minutes for the DNS servers to update and you should now be
able access your server by name.
## Setup HTTPS and TLS, a false sense of security
A decade of half-though through security advice has convinced everyone
that HTTPS and *only* HTTPS is secure. This is simply not true. Using
HTTP alone doesn't inherently make you insecure and using HTTPS
doesn't automatically guarantee the app your communicating with is
secure.
What HTTPS means is that the *data you send to the server* is
encrypted. This only provides security in contexts where you're entering
information like a credit card number or a password. In those cases
*you need HTTPS*. But if you're just requesting a text document, or a
cat picture, and not sending any data, HTTP is perfectly acceptable for
retrieving that information.
Web browsers have largely responded to this fact by assuming that HTTP
is always insecure and printing a warning when you visit a site without
HTTPS enabled. Unfortunately, most users interpret this to mean the site
is somehow dangerous, even if it doesn't collect any information about
the user. Because of that, most you will want to go the extra mile to
make your visitors feel warm and fuzzy inside and implement HTTPS.
Fortunately, this is now much easier than is used to be thanks to
[LetsEncrypt](https://letsencrypt.org/). LetsEncrypt generously serves
as a free certificate authority, which allows you to generate signed
certificates that are recognized by every web browser in the world. The
tool they recommend, [certbot](https://certbot.eff.org/) is painless to
install. I've rarely had to do much more than `certbot certonly` and
follow the prompts to get a certificate. Once you've obtained one, add
it to
[apache](https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html)
or
[nginx](https://www.nginx.com/blog/nginx-ssl/#Examples),
switch the port to 443 instead of 80 and bam, you've got HTTPS!
## References
1. https://dataswamp.org/~solene/2021-07-23-why-selfhosting-is-important.html
2. https://selfhostedweb.org/yourserver/
3. https://www.howtogeek.com/362602/can-you-host-a-web-server-on-your-home-internet-connection/
4. https://googiehost.com/blog/create-your-own-server-at-home-for-web-hosting/
5. https://en.wikipedia.org/wiki/ICANN