From: Adam A.G. Shamblin Date: Sun, 7 Apr 2019 15:06:20 +0000 (-0600) Subject: First commit, on the way to configured. X-Git-Url: https://git.vexinglabs.com/?a=commitdiff_plain;h=e95a1aba4fabba5e93ef6c5404611a941cc3f7e1;p=letters.git First commit, on the way to configured. --- e95a1aba4fabba5e93ef6c5404611a941cc3f7e1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7da037c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +output diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a2c6c18 --- /dev/null +++ b/Makefile @@ -0,0 +1,86 @@ +PY?=python3 +PELICAN?=pelican +PELICANOPTS= + +BASEDIR=$(CURDIR) +INPUTDIR=$(BASEDIR)/content +OUTPUTDIR=$(BASEDIR)/output +CONFFILE=$(BASEDIR)/pelicanconf.py +PUBLISHCONF=$(BASEDIR)/publishconf.py + +SSH_HOST=localhost +SSH_PORT=22 +SSH_USER=signal9 +SSH_TARGET_DIR=/var/www + + +DEBUG ?= 0 +ifeq ($(DEBUG), 1) + PELICANOPTS += -D +endif + +RELATIVE ?= 0 +ifeq ($(RELATIVE), 1) + PELICANOPTS += --relative-urls +endif + +help: + @echo 'Makefile for a pelican Web site ' + @echo ' ' + @echo 'Usage: ' + @echo ' make html (re)generate the web site ' + @echo ' make clean remove the generated files ' + @echo ' make regenerate regenerate files upon modification ' + @echo ' make publish generate using production settings ' + @echo ' make serve [PORT=8000] serve site at http://localhost:8000' + @echo ' make serve-global [SERVER=0.0.0.0] serve (as root) to $(SERVER):80 ' + @echo ' make devserver [PORT=8000] serve and regenerate together ' + @echo ' make ssh_upload upload the web site via SSH ' + @echo ' make rsync_upload upload the web site via rsync+ssh ' + @echo ' ' + @echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html ' + @echo 'Set the RELATIVE variable to 1 to enable relative urls ' + @echo ' ' + +html: + $(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) + +clean: + [ ! -d $(OUTPUTDIR) ] || rm -rf $(OUTPUTDIR) + +regenerate: + $(PELICAN) -r $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) + +serve: +ifdef PORT + $(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT) +else + $(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) +endif + +serve-global: +ifdef SERVER + $(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT) -b $(SERVER) +else + $(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT) -b 0.0.0.0 +endif + + +devserver: +ifdef PORT + $(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT) +else + $(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) +endif + +publish: + $(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(PUBLISHCONF) $(PELICANOPTS) + +ssh_upload: publish + scp -P $(SSH_PORT) -r $(OUTPUTDIR)/* $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) + +rsync_upload: publish + rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --cvs-exclude --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) + + +.PHONY: html help clean regenerate serve serve-global devserver stopserver publish ssh_upload rsync_upload \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ab40ef3 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Letters + +https://letters.vexingworkshop.com + +## Goals + +### No Frameworks! + +* Using, as much as possible, only native browser frameworks +* Use WebComponents where practical for more involved features +* Use ES6 as much as is practical + +#### How? + +For now, I really only care about Firefox. This is my toy, and I feel perfectly +fine going retro-90's and saying that my site is best viewed with Firefox. That +being said, these should also be *standard* features, so they should work on +Firefox and webkit-derived browsers. + +### Offline! + +* Don't go blank or freak out when a device is offline +* Queue up network interactions where they can be + +#### How? + +_Offline First_ isn't quite the right term, as web pages have to be delivered to +an online client first, but it is my intention to build this site such that it +will keep working when offline, or fail gracefully where it may not. + +### Multilingual, EN/EO + +* Multilingual website, hosted in both English and Esperanto +* Navigation, etc. in both languages +* Content in both, if practical +* Easy to switch languages + +#### How? + +Proxy the `navigator.language` object and switch on change. diff --git a/app.js b/app.js new file mode 100644 index 0000000..fab5851 --- /dev/null +++ b/app.js @@ -0,0 +1,20 @@ +class NavigatorProxyHandler { + + constructor () { + this._language = navigator.language; + } + + set (obj, prop, val) { + if (prop === 'language') { + this._language = val; + } + } + + get (obj, prop) { + if (prop === 'language') { + return this._language; + } + } +}; + +let navigatorProxy = new Proxy(navigator, new NavigatorProxyHandler()); diff --git a/content/another-test.en.rst b/content/another-test.en.rst new file mode 100644 index 0000000..8b46d7d --- /dev/null +++ b/content/another-test.en.rst @@ -0,0 +1,8 @@ +Do Another Test +############### + +:date: 2019-04-07 +:tags: tech +:category: tech + +Another test of the system, categories, etc. diff --git a/content/hardening_notes.md b/content/hardening_notes.md new file mode 100644 index 0000000..55fea12 --- /dev/null +++ b/content/hardening_notes.md @@ -0,0 +1,283 @@ +Title: Science Friday - Basic Setup and Hardening of a Linux Server +Date: 2017-06-24 +Category: Security + +## Prerequisites + +- Install [VirtualBox](https://www.virtualbox.org/) for your platform +- Download a Debian netinst ISO from [Debian](https://www.debian.org/CD/netinst/) + +## Setting up our machine + +### Create a host-only network + +In order for us to be able to access our virtual machine over the network, we +will need to create a host-only network. The finer points of what exactly this +means are beyond the scope of this document. + +1. Open VirtualBox preferences +2. Select __Network__ +3. Open the __Host-only Networks__ tab +4. Click on the __+__ button + +This will add a new host-only network adapter, likely named vboxnet0. + +### Create a new virtual machine + +Click __New__. In the open dialog, give your machine a name, type and version. +In our case, we will be creating a Linux machine, version Debian (64-bit). +The next few pages, we will go with the defaults for memory and disk size. + +Click on the newly created record and then click __Settings__. Under __Storage__, +select the installed device under Controller IDE labeled Empty. Next to the +Optical drive, click the disk icon and navigate to the Debian installation ISO +you downloaded earlier. + +Under __Network__, click on the Adapter 2 tab and check Enable Network Adapter. +In the Attached to dropdown, select Host-only Adapter. vboxnet0 should appear +under name. + +At this point we should be able to start the virtual machine and the Debian +installation media will boot. + +## Intalling Debian + +Debian has a number of installation options, including a graphical install. We +will be using the default install method. When the Debian installation screen +appears, press Enter. The first few screens ask information regarding +localization and keyboard maps. Do what you will. + +You will encounter a screen labeled __Configure the Network__ where you should +see two available network interfaces. The default is to use eth0 as the primary +interface. This is fine. + +Choose your hostname and domain. These can be changed later, and since we're +running on local VMs, it doesn't overly matter for what we're doing. + +Choose a root password. You will also be asked to create a new user. Enter and +verify that user's password. We will be working with this user more later. + +Choose a timezone. When it is time to partition disks, choosing __Guided - use +entire disk__ and all files in one partition is fine for our purposes. Agree to +the partition table and continue. + +It is ok to use the defaults when configuring the package manager. After +choosing a location and a mirror (and configure a proxy if necessary) Debian +will download and install the base system. + +On the software selection screen, we will deselect __Debian desktop environment__ +and __print server__, but we will enable __SSH server__. A desktop environment +may be added later if you want, but since this is intended as a server, we want +a pretty bare-bones system. Navigate thru the screen using your arrow keys. +Press the space bar to select or deselect an option. Tab to Continue and press +Enter. Debian will install the remaining packages. + +You will be asked to install the GRUB boot loader, to which you will agree and +select `/dev/sda` as the installation target. + +With this complete, you will be prompted to reboot. Don't worry about removing +the installation media, the system will do that for you. + +In a few seconds, you will see the boot loader screen. Hit enter, or wait for +it to autoboot. You will then see a login prompt. You are now ready to log in. +The next few steps will require elevated privileges, so go ahead and log in as +root. + +## Configure networking + +In order to allow us to access our virtual machine over ssh, we need to enable +and configure the host-only network adapter we added to our virtual machine. +While this is not a step we would often perform when setting up a typical cloud +VPS, it is good to be at least aware of network interface configuration. + +During installation, Debian only configures the primary interface, `eth0`. +We're going to leave this be and enable `eth1` for our remote access. While this +step is not typical when configuring a cloud server, the networking principles +are basic to Linux and worth at least being aware of. + +### Verify network interfaces + +Having logged into the virtual machine as root, check and verify that both +network interfaces are present: + +```shell +ifconfig -a +``` + +You should see two configured interfaces: `eth0` and `eth1`. `eth0` will have +an IP4 address configured, and perhaps an IP6 address as well. `eth1` should not +have any addresses assigned + +### Enable secondary interface + +Using your editor of choice, open `/etc/network/interfaces` + +To the end of the file you will want to add: + + # Secondary network interface, vbox host-only + allow-hotplug eth1 + iface eth1 inet dhcp + +Save and close the file. + +The first line tells the server to automatically bring up the interface. The +second configures it for DHCP. A static address may be configured, but we'll +stick with this for now. + +Now, reboot the machine: + +```shell +shutdown -r now +``` + +When the machine comes back up, log in again as root and once again check our +interfaces by typing `ifconfig -a`. + +We should now see the second interface, `eth1`, has an IP4 address assigned. +Make a note of this address as we'll need it later. We should also now be able +to access the virtual machine from our host machine over `ssh`: + +```shell +ssh *youruser*@*yourip* +``` + +## Empower your user + +It is best to do most if not all of your work as a less privileged user than +`root`. The Debian installation creates a user for this purpose. We will want to +allow this user to perform some tasks with escalated privileges. + +First we will need to install `sudo` and give our user access. + +```shell +apt-get install sudo +adduser *youruser* sudo +``` + +Now, log out of the root account and log back in with your less-privileged user. +We will test that we have access to `sudo`: + +```shell +sudo ls +``` + +You should have been warned about the implications of using sudo and prompted +for your password. + +## Improve SSH Access + +### Generate a keypair + +Our goal is to allow our user to authenticate to the virtual server using public +key encryption rather than passwords. To do this, we will have to generate a +keypair and install the public key on the virtual machine. + +First, we need a safe place to keep our keys and configs. On your local machine: + +```shell +mkdir ~/.ssh +chmod 700 ~/.ssh +``` + +Now, also on our local machine, we will generate our key. If a key name is not +specified, the default is to create a pair of files called id\_rsa and id\_rsa.pub. +Today we will create a keypair called `debian_server` + +```shell +ssh-keygen -b 4096 -f ~/.ssh/debian_server +``` + +### Push your keypair + +During keypair creation, you will be prompted for an optional passphrase. It is +up to you whether you use one, but an empty passphrase is also acceptable. + +We will need to copy our public key to the virtual server to use it for remote +access. To do this, we'll use `ssh-copy-id`. On your local machine: + +```shell +ssh-copy-id -i ~/.ssh/debian_server *youruser*@*yourip* +``` + +You will be prompted for your remote password, then the file will copy securely +to the remote machine. To verify the key is present on the virtual server, from +that machine type: + +```shell +cat ~/.ssh/authorized_keys +``` + +You should see your key as the last item listed. + +### Configure SSH locally + +At this point you should be able to access the virtual server using your keypair +for authentication: + +```shell +ssh -i ~/.ssh/debian_server *youruser*@*yourip* +``` + +However, why do so much typing? `ssh` allows us to configure our local client +for name-based access. + +On your local machine, create or edit the file `~/.ssh/config` and add the +following: + + Host debian-server + HostName *yourip* + User *youruser* + IdentityFile ~/.ssh/debian_server + +With this in place, you may connect to the remote server simply by the name +configured: + +```shell +ssh debian-server +``` + +## Lock down SSH access + +### Disable root remote login + +We have options to significantly restrict SSH access and to minimize the ability +for attackers to brute-force a remote login. First, we will require that all SSH +users are non-root users. We will edit `/etc/ssh/sshd_config`. Find the setting +`PermitRootLogin` and set it to `no`. + +### Disable passwords + +Still in `/etc/ssh/sshd_config`, look for the setting `PasswordAuthentication` +and set it to `no`. This will disable the use of passwords when logging in over +SSH, thus requiring that your keys have been installed. + +Now you may restart the SSH server for the new settings to take effect. + +```shell +sudo systemctl restart sshd +``` + +You should now see access denied when trying to log in as root, or as any user +not configured in `~/.ssh/config` + +## Removing unwanted services + +There are likely at least a couple of services running on a default installation +that we do not want. To list the running services, type: + +```shell +sudo netstat -tulpn +``` + +On my system, I expect to see `sshd` and `dhclient`, but I also so see `rpcbind` +`rpc.statd` and `exim`, which I currently do not intend to use. I see that +removing `rpcbind` will also remove `rpc.statd`, so I only have to uninstall +one. + +```shell +sudo apt-get purge rpcbind exim4 +sudo systemctl stop exim4 +``` + +Running `sudo netstat -tulpn` again will show that now we are only running +`sshd` and `dhclient`. diff --git a/content/pages/about.en.rst b/content/pages/about.en.rst new file mode 100644 index 0000000..478a5a6 --- /dev/null +++ b/content/pages/about.en.rst @@ -0,0 +1,4 @@ +About +##### + + diff --git a/content/pages/keys.en.rst b/content/pages/keys.en.rst new file mode 100644 index 0000000..7070910 --- /dev/null +++ b/content/pages/keys.en.rst @@ -0,0 +1,2 @@ +Keys +#### diff --git a/content/test.en.rst b/content/test.en.rst new file mode 100644 index 0000000..80e3158 --- /dev/null +++ b/content/test.en.rst @@ -0,0 +1,9 @@ +Dig my crazy article +#################### + +:date: 2019-04-06 21:48 +:category: Test +:slug: testing-translations-in-pelican +:lang: en + +This is a test diff --git a/content/test.eo.rst b/content/test.eo.rst new file mode 100644 index 0000000..8eb2d67 --- /dev/null +++ b/content/test.eo.rst @@ -0,0 +1,9 @@ +Kompreni mi freneza artikolon +############################# + +:date: 2019-04-06 21:48 +:category: Test +:slug: testing-translations-in-pelican +:lang: eo + +Ĉi tiu estas testo. diff --git a/index.html b/index.html new file mode 100644 index 0000000..d29f3ca --- /dev/null +++ b/index.html @@ -0,0 +1,10 @@ + + + + Letters/Leteroj + + + + + + diff --git a/pelicanconf.py b/pelicanconf.py new file mode 100644 index 0000000..449dc50 --- /dev/null +++ b/pelicanconf.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- # +from __future__ import unicode_literals + +AUTHOR = 'signal9' +SITENAME = 'Leteroj' +SITEURL = '' + +PATH = 'content' + +TIMEZONE = 'America/Denver' + +DEFAULT_LANG = 'en' + +# Feed generation is usually not desired when developing +FEED_ALL_ATOM = None +CATEGORY_FEED_ATOM = None +TRANSLATION_FEED_ATOM = None +AUTHOR_FEED_ATOM = None +AUTHOR_FEED_RSS = None + +# Blogroll +LINKS = (('Pelican', 'http://getpelican.com/'), + ('Python.org', 'http://python.org/'), + ('Jinja2', 'http://jinja.pocoo.org/'), + ('You can modify those links in your config file', '#'),) + +# Social widget +SOCIAL = (('Twitter', 'https://twitter.com/AdamAGShamblin'), + ('GitHub', 'https://github.com/coyote240'),) + +DEFAULT_PAGINATION = 10 + +# Uncomment following line if you want document-relative URLs when developing +# RELATIVE_URLS = True diff --git a/publishconf.py b/publishconf.py new file mode 100644 index 0000000..59905aa --- /dev/null +++ b/publishconf.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- # +from __future__ import unicode_literals + +# This file is only used if you use `make publish` or +# explicitly specify it as your config file. + +import os +import sys +sys.path.append(os.curdir) +from pelicanconf import * + +# If your site is available via HTTPS, make sure SITEURL begins with https:// +SITEURL = 'https://letters.vexingworkshop.com' +RELATIVE_URLS = False + +FEED_ALL_ATOM = 'feeds/all.atom.xml' +CATEGORY_FEED_ATOM = 'feeds/{slug}.atom.xml' + +DELETE_OUTPUT_DIRECTORY = True + +# Following items are often useful when publishing + +# DISQUS_SITENAME = "" +# GOOGLE_ANALYTICS = "" diff --git a/tasks.py b/tasks.py new file mode 100644 index 0000000..995be0b --- /dev/null +++ b/tasks.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- + +import os +import shutil +import sys +import datetime + +from invoke import task +from invoke.util import cd +from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer + +CONFIG = { + # Local path configuration (can be absolute or relative to tasks.py) + 'deploy_path': 'output', + # Remote server configuration + 'production': 'signal9@localhost:22', + 'dest_path': '/var/www', + # Port for `serve` + 'port': 8000, +} + +@task +def clean(c): + """Remove generated files""" + if os.path.isdir(CONFIG['deploy_path']): + shutil.rmtree(CONFIG['deploy_path']) + os.makedirs(CONFIG['deploy_path']) + +@task +def build(c): + """Build local version of site""" + c.run('pelican -s pelicanconf.py') + +@task +def rebuild(c): + """`build` with the delete switch""" + c.run('pelican -d -s pelicanconf.py') + +@task +def regenerate(c): + """Automatically regenerate site upon file modification""" + c.run('pelican -r -s pelicanconf.py') + +@task +def serve(c): + """Serve site at http://localhost:8000/""" + + class AddressReuseTCPServer(RootedHTTPServer): + allow_reuse_address = True + + server = AddressReuseTCPServer( + CONFIG['deploy_path'], + ('', CONFIG['port']), + ComplexHTTPRequestHandler) + + sys.stderr.write('Serving on port {port} ...\n'.format(**CONFIG)) + server.serve_forever() + +@task +def reserve(c): + """`build`, then `serve`""" + build(c) + serve(c) + +@task +def preview(c): + """Build production version of site""" + c.run('pelican -s publishconf.py') + + +@task +def publish(c): + """Publish to production via rsync""" + c.run('pelican -s publishconf.py') + c.run( + 'rsync --delete --exclude ".DS_Store" -pthrvz -c ' + '{} {production}:{dest_path}'.format( + CONFIG['deploy_path'].rstrip('/') + '/', + **CONFIG)) +