Removing old Anisble, updating hetzner Terraform. - infra - Terraform IoC for my remote (Hetzner) and local (Incus) servers.
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit d5730ddfc770cf4d3daaec8224f90d10eb986d4c
(DIR) parent 635e9945ef2e0d2def7301381daec2115377891e
(HTM) Author: Jay Scott <me@jay.scot>
Date: Wed, 17 Jul 2024 19:34:12 +0100
Removing old Anisble, updating hetzner Terraform.
Diffstat:
M README | 45 +++++++------------------------
D ansible/group_vars/all.yml | 4 ----
D ansible/group_vars/git.yml | 4 ----
D ansible/group_vars/gopher.yml | 12 ------------
D ansible/inventory.yml | 10 ----------
D ansible/main.yml | 21 ---------------------
D ansible/roles/common/files/sshd_co… | 6 ------
D ansible/roles/common/handlers/main… | 4 ----
D ansible/roles/common/tasks/main.yml | 47 -------------------------------
D ansible/roles/common/tasks/setup-D… | 5 -----
D ansible/roles/common/vars/Debian.y… | 5 -----
D ansible/roles/finger/files/list | 16 ----------------
D ansible/roles/finger/files/log | 1 -
D ansible/roles/finger/files/logo.txt | 7 -------
D ansible/roles/finger/files/luser | 29 -----------------------------
D ansible/roles/finger/files/mcrae.t… | 222 ------------------------------
D ansible/roles/finger/files/morris.… | 125 -------------------------------
D ansible/roles/finger/files/nouser | 19 -------------------
D ansible/roles/finger/tasks/main.yml | 36 -------------------------------
D ansible/roles/finger/vars/Debian.y… | 3 ---
D ansible/roles/git/handlers/main.yml | 6 ------
D ansible/roles/git/tasks/main.yml | 31 -------------------------------
D ansible/roles/git/templates/git-da… | 18 ------------------
D ansible/roles/git/vars/Debian.yml | 2 --
D ansible/roles/gopher/handlers/main… | 12 ------------
D ansible/roles/gopher/tasks/main.yml | 58 ------------------------------
D ansible/roles/gopher/templates/geo… | 16 ----------------
D ansible/roles/gopher/vars/Debian.y… | 4 ----
D ansible/roles/gopher/vars/main.yml | 5 -----
D ansible/roles/stagit/handlers/main… | 5 -----
D ansible/roles/stagit/tasks/main.yml | 46 -------------------------------
D ansible/roles/stagit/templates/sta… | 38 -------------------------------
D ansible/roles/stagit/vars/Debian.y… | 4 ----
D ansible/roles/stagit/vars/main.yml | 5 -----
A remote/.terraform.lock.hcl | 24 ++++++++++++++++++++++++
A remote/checks.tf | 8 ++++++++
A remote/cloudinit/main.yml | 47 +++++++++++++++++++++++++++++++
A remote/main.tf | 69 ++++++++++++++++++++++++++++++
A remote/outputs.tf | 3 +++
A remote/terraform.tfvars | 53 ++++++++++++++++++++++++++++++
A remote/variables.tf | 25 +++++++++++++++++++++++++
41 files changed, 239 insertions(+), 861 deletions(-)
---
(DIR) diff --git a/README b/README
@@ -1,42 +1,17 @@
-|> Terraform
+ ___ __
+| |\ | |__ |__) /\
+| | \| | | \ /~~\
-Bootstrap Hetzner Cloud servers.
- Add public ssh key to account
- Provision X servers with desired configuration
- Create custom firewall rules
- Add reverse dns entry
- Userdata bootscript adding an Ansible user account
-
-If you actually want to use this for yourself then you might need to do
-the following depending on your requirements.
+---
+The remote servers are hosted Hetzner Cloud servers and selfhosted are running
+on Incus. If you actually want to use this for yourself then you might need to
+do the following depending on your requirements.
export HCLOUD_TOKEN='thisismylongasstoken'
-
-The user_data script is a standard cloud-init yaml config that creates
-an Ansible user for further configuration the instances.
-
-
- terraform plan
- terraform apply
-
-
-|> Ansible
-
-Playbook to install the following:
-
- gopher
- git and git daemon
- stagit-gopher
- efingerd
-
-Apply all:
-
- ansible-playbook -i inventory.yml main.yml
-
-Run tags
-
- ansible-playbook -i inventory.yml main.yml --tags <git/gopher/common>
+ tofu init
+ tofu plan
+ tofu apply
(DIR) diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
@@ -1,4 +0,0 @@
-default:
- username: jay
- comment: Jay Scott
- hostname: jay.scot
(DIR) diff --git a/ansible/group_vars/git.yml b/ansible/group_vars/git.yml
@@ -1,4 +0,0 @@
-git:
- user: git
- group: users
- base_path: /srv/git
(DIR) diff --git a/ansible/group_vars/gopher.yml b/ansible/group_vars/gopher.yml
@@ -1,12 +0,0 @@
-geomyidae:
- user: jay
- group: users
- root_path: /srv/gopher
- git_branch: v0.69
-
-stagit_gopher:
- git_branch: 1.2
- cron_user: jay
- cron_group: users
- output_path: /srv/gopher
- repo_path: /srv/git
(DIR) diff --git a/ansible/inventory.yml b/ansible/inventory.yml
@@ -1,10 +0,0 @@
-all:
- vars:
- ansible_user: jay
- children:
- git:
- hosts:
- jay.scot
- gopher:
- hosts:
- jay.scot
(DIR) diff --git a/ansible/main.yml b/ansible/main.yml
@@ -1,21 +0,0 @@
-- hosts: all
- become: true
- roles:
- - role: common
- tags:
- - common
-
-- hosts: git
- become: true
- roles:
- - role: git
- - role: stagit
- tags:
- - git
-
-- hosts: gopher
- become: true
- roles:
- - role: gopher
- tags:
- - gopher
(DIR) diff --git a/ansible/roles/common/files/sshd_config b/ansible/roles/common/files/sshd_config
@@ -1,6 +0,0 @@
-PasswordAuthentication no
-ChallengeResponseAuthentication no
-UsePAM yes
-X11Forwarding no
-Subsystem sftp /usr/lib/openssh/sftp-server
-PermitRootLogin no
(DIR) diff --git a/ansible/roles/common/handlers/main.yml b/ansible/roles/common/handlers/main.yml
@@ -1,4 +0,0 @@
-- name: Restart sshd
- ansible.builtin.service:
- name: sshd
- state: restarted
(DIR) diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml
@@ -1,47 +0,0 @@
----
-
-- name: Include OS-specific variables
- ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
-
-- name: Include OS-specfic tasks
- ansible.builtin.include_tasks: "setup-{{ ansible_os_family }}.yml"
-
-- name: Install Common Packages
- ansible.builtin.package:
- name: "{{ common_packages }}"
- state: present
-
-- name: Add hardened SSH config
- ansible.builtin.copy:
- dest: /etc/ssh/sshd_config
- src: sshd_config
- owner: root
- group: root
- mode: 0600
- notify: Restart sshd
-
-- name: Add default user
- ansible.builtin.user:
- name: "{{ default.username }}"
- comment: "{{ default.comment }}"
- shell: /bin/bash
- group: users
-
-- name: Set authorized key
- ansible.posix.authorized_key:
- user: "{{ default.username }}"
- state: present
- key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
-
-- name: Add default user to sudo
- community.general.sudoers:
- name: "local-{{ default.username }}"
- user: "{{ default.username }}"
- state: present
- nopassword: true
- commands: ALL
-
-- name: Set the hostname
- ansible.builtin.hostname:
- name: "{{ default.hostname }}"
- use: systemd
(DIR) diff --git a/ansible/roles/common/tasks/setup-Debian.yml b/ansible/roles/common/tasks/setup-Debian.yml
@@ -1,5 +0,0 @@
-- name: Update apt cache.
- ansible.builtin.apt:
- update_cache: true
- upgrade: true
- cache_valid_time: 3600
(DIR) diff --git a/ansible/roles/common/vars/Debian.yml b/ansible/roles/common/vars/Debian.yml
@@ -1,5 +0,0 @@
-common_packages:
- - htop
- - vim
- - finger
- - lynx
(DIR) diff --git a/ansible/roles/finger/files/list b/ansible/roles/finger/files/list
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-cat "/etc/efingerd/logo.txt"
-
-printf "\n\n"
-printf "Welcome to jay.scot!\n"
-printf "Uptime : %s\n\n" "$(uptime)"
-
-printf "Available Fingers:\n\n"
-printf "\tusername ... get user info\n"
-
-printf "\n\n"
-printf "Current Users:\n\n"
-printf "\tJay Scott\t\t%s\n" "$(last jay -n1 -R --time-format full | head -n1)"
-printf "\tRobert Morris\t\tmorris\t pts/0\t Wed Nov 2 08:23:03 1988\t still logged in\n"
-printf "\tWilliam McRae\t\tmcrae \t pts/1\t Sun Apr 7 15:35:49 1985\t still logged in"
(DIR) diff --git a/ansible/roles/finger/files/log b/ansible/roles/finger/files/log
@@ -1 +0,0 @@
-# nope, no logs
(DIR) diff --git a/ansible/roles/finger/files/logo.txt b/ansible/roles/finger/files/logo.txt
@@ -1,7 +0,0 @@
- ___ _______ __ __ _______ _______ _______ _______
- | || _ || | | | | || || || |
- | || |_| || |_| | | _____|| || _ ||_ _|
- | || || | | |_____ | || | | | | |
- ___| || ||_ _| ___ |_____ || _|| |_| | | |
-| || _ | | | | | _____| || |_ | | | |
-|_______||__| |__| |___| |___| |_______||_______||_______| |___|
(DIR) diff --git a/ansible/roles/finger/files/luser b/ansible/roles/finger/files/luser
@@ -1,29 +0,0 @@
-#!/bin/sh
-
-if [ "$3" = "root" ]; then
- printf "Yeah, not going to happen."
-elif [ "$3" = "git" ]; then
- printf "I am not a git, you are!"
-else
- user_folder="/home/${3}"
-
- if [ -f "${user_folder}/.header" ]; then
- cat "${user_folder}/.header"
- printf "\n"
- fi
-
- if [ -f "${user_folder}/.plan" ]; then
- printf "Plan:\n"
- cat "${user_folder}/.plan"
- printf "\n"
- fi
-
- if [ -f "${user_folder}/.project" ]; then
- printf "Project:\n"
- cat "${user_folder}/.project"
- printf "\n"
- fi
-
-fi
-
-exit 0
(DIR) diff --git a/ansible/roles/finger/files/mcrae.txt b/ansible/roles/finger/files/mcrae.txt
@@ -1,222 +0,0 @@
-
-T H E M Y S T E R Y O F
-
- __ __ ___
-| | | | | | /\ |\/| |\/| / ` |__) /\ |__
-|/\| | |___ |___ | /~~\ | | | | \__, | \ /~~\ |___
-
-
-
-Willie McRae (18 May 1923 – 7 April 1985) was a Scottish lawyer, orator,
-naval officer, politician and anti-nuclear campaigner. In the Second
-World War he served in the British Army and then the Royal Indian Navy.
-He supported the Indian independence movement and for much of his life
-was active in the Scottish National Party (SNP).
-
-McRae is remembered for his mysterious death, in which his car crashed
-in a remote part of the Scottish Highlands and he was found shot in the
-head with a revolver. The official verdict was undetermined.
-
-
-|> Life
-
-
-McRae was born in Carron, Falkirk, where his father was an electrician.
-McRae edited a local newspaper in Grangemouth at the same time as
-reading history at the University of Glasgow, from which he gained
-a first-class degree. In the Second World War he was commissioned into
-the Seaforth Highlanders but transferred to the Royal Indian Navy, in
-which he became a lieutenant commander and aide-de-camp to Admiral Lord
-Mountbatten. He supported the Indian independence movement.
-
-After the war McRae returned to the University of Glasgow and graduated
-again, this time in law.[1] He authored the maritime law of Israel and
-was an emeritus professor of the University of Haifa.
-After his death a forest of 3,000 trees was planted in Israel in his
-memory.
-
-McRae became a solicitor and an SNP activist. In both of the 1974
-General Elections and in the 1979 General Election he stood for
-Parliament as the SNP candidate for Ross and Cromarty. In October 1974
-he only lost to the Conservative Hamish Gray by 633 votes, but in 1979
-Gray's majority increased to 4,735. In the latter year he also contested
-the SNP leadership, coming third in a three-way contest with 52 votes to
-Stephen Maxwell's 117 votes and winner Gordon Wilson's 530 votes.
-
-McRae was a vocal critic of the British nuclear lobby. Early in the
-1980s he was a key figure in a campaign against the United Kingdom
-Atomic Energy Authority plans to dispose of nuclear waste in the
-Mullwharchar area of the Galloway Hills. Representing the SNP in
-a public inquiry, McRae asked difficult questions of the UKAEA and
-famously declared at one meeting that "nuclear waste should be stored
-where Guy Fawkes put his gunpowder." The authority's plans were
-rejected, and McRae was credited with "single-handedly" preventing the
-area from becoming a nuclear waste dump.
-
-
-|> Death
-
-
-On 5 April 1985 McRae left his Glasgow flat at 18:30 to spend the
-weekend at his cottage at Ardelve near Dornie, Ross-shire. He was not
-seen again until the next morning around 10:00, when two Australian
-tourists saw his maroon Volvo saloon car on a moor a short distance from
-the junction of the A887 and A87 roads Bun Loyne, Glenmoriston,
-Inverness-shire. The car was straddling a burn about 90 feet (27 m) from
-the road. The tourists flagged down the next car to pass, whose driver
-turned out to be a doctor, Dorothy Messer, accompanied by her fiancé as
-well as David Coutts, an SNP Dundee councillor who knew McRae.
-
-It was discovered that McRae was in the car. His hands were "folded on
-his lap", his head was "slumped on his right shoulder", and there was
-a "considerable amount of blood on his temple". He was not wearing
-a seat belt.
-
-Another car was sent to call the emergency services. Dr Messer examined
-McRae and found that he was still alive and breathing. She noted that
-one of his pupils was dilated, indicating the possibility of brain
-damage, and estimated that he had been in that state for 10 hours.
-
-McRae was removed by ambulance to Raigmore Hospital, Inverness,
-accompanied by Dr Messer. After admission it was decided to transfer him
-to Aberdeen Royal Infirmary. At Aberdeen it was realised that the
-incident was more than a road accident; six hours after he had been
-found, a nurse washing his head discovered what appeared to be the entry
-wound of a gunshot. An X-ray confirmed that McRae had been shot above
-his right ear and a bullet was detected in his head. His brain was
-severely damaged and his vital functions very weak. The next day, Sunday
-7 April, after consultation with his next of kin, McRae's life-support
-machine was switched off.
-
-
-|>Investigation
-
-
-The investigation was headed by Chief Superintendent Andrew Lister of
-Northern Constabulary CID. Despite no weapon having yet been found,
-McRae's car was moved at 12:00 on 7 April. It later transpired that the
-police had kept no record of the precise location where the car had been
-found, and the position stated by them was later found to be 1 mile (1.6
-km) in error, and was corrected by a witness who had been present at the
-scene.
-
-A weapon was found the next day, in the burn over which the car had been
-discovered, 60 feet (18 m) from the vehicle. It was a Smith & Wesson .22
-calibre revolver containing two spent cartridges and five remaining
-rounds.
-
-
-|> Controversy
-
-
-Although it was ruled at the time by authorities that McRae's death was
-undetermined, aspects of the investigation remain disputed, some
-claiming that the distance from McRae's car at which the gun was found
-and the lack of fingerprints on it rendered a suicide not credible.
-
-At the time of his death, McRae had been working to counter plans to
-dump nuclear waste from the Dounreay Nuclear Power Development
-Establishment into the sea. Due to his house being burgled on repeated
-occasions prior to his death, he had taken to carrying a copy of the
-documents relating to his Dounreay work with him at all times. They were
-not found following his death, and the sole other copy which was kept in
-his office was stolen when it was burgled, no other items being
-taken.
-
-Neither McRae's medical reports nor the post-mortem data have been
-released to the public and there was no fatal accident inquiry.
-
-
-|> Aftermath
-
-
-Winnie Ewing – then President of the SNP and herself an accomplished
-lawyer – was directed by the SNP's National Executive Committee (NEC) to
-conduct an internal investigation for the party to come to a conclusion
-as to whether Ewing "was satisfied or dissatisfied with the official
-version that he committed suicide". Having been refused access to police
-records of the investigation and rebuffed by both the Lord Advocate and
-the Procurator Fiscal in her attempts to conduct private, confidential
-meetings with them, Ewing, as she later wrote, came "up against a brick
-wall".[10] Ewing reported to the SNP NEC that she was not satisfied with
-the official account of suicide: "I do not know what happened, but
-I think it is important that the truth emerges, despite the time that
-has passed. Why the State refuses to let the truth be known is
-a pertinent question."
-
-In 1991 Channel 4 broadcast a "Scottish Eye" documentary investigating
-the mysterious circumstances of McRae's death. It found evidence to
-suggest that McRae had been under surveillance by UK intelligence
-services and that his death had likely involved foul play.
-
-In 2005 Winnie Ewing's son Fergus, by then an MSP, requested a meeting
-with Elish Angiolini, Solicitor General for Scotland, to discuss
-allegations that have persisted that McRae was under surveillance at the
-time of his death. The request was rebuffed, with Angiolini claiming
-that he had not been under surveillance and that she was satisfied that
-a thorough investigation into the case had been carried out.
-
-In July 2006 a retired police officer, Iain Fraser, who was working as
-a private investigator at the time of McRae's death, claimed that he had
-been anonymously employed to keep McRae under surveillance only weeks
-before he died. In November 2006 an episode of the Scottish Television
-show Unsolved examined the circumstances of McRae's death.
-
-In November 2010 John Finnie, then SNP group leader on Highland Council
-and a former police officer, wrote to the Lord Advocate urging her to
-reinvestigate McRae's death and release any details so far withheld.
-Finnie's request was prompted by the release the previous month of
-further details concerning the death of David Kelly.[14] In January 2011
-the Crown Office requested the files on the case from Northern
-Constabulary.
-
-Also in November 2010 Donald Morrison, a former Strathclyde Police
-officer, alleged that McRae had been "under surveillance" by both
-Special Branch and MI5. Morrison had collaborated with former colleague
-Iain Fraser to discover more about McRae's death. Morrison called for an
-enquiry into McRae's death and promised that he would give it a sworn
-affidavit that MI5 was involved.
-
-In July 2014 two unconnected plays by George Gunn and Andy Paterson
-about McRae's life and death, both coincidentally titled 3,000 Trees,
-were staged at the Edinburgh Festival Fringe. One of the plays explored
-his anti-nuclear campaigning, links with nationalist radicals and
-allegations that Special Branch and MI5 were surveilling him.
-
-In November 2014 a Scottish Sunday Express front-page article alleged
-that McRae had uncovered evidence of the alleged paedophile ring in
-Westminster during the 1980s. The article suggests he may have been
-murdered and that the evidence he possessed was stolen at the time of
-his death.
-
-In April 2015 there was a campaign to have a Fatal Accident Inquiry
-(FAI) on McRae's death. It attracted 6,500 signatures in 5 days.
-
-The petition eventually collected over 13,000 signatures and was handed
-in, in June 2015. The Crown Office rejected the proposal to hold a Fatal
-Accident Inquiry.
-
-On the Easter weekend of April 2015, the 30th anniversary of McRae's
-death, Scotland on Sunday ran a story claiming that McRae's Volvo was
-moved back to the crash site by Northern Constabulary in an attempt to
-hide that the car had been moved before the bullet had been found
-– accounting for the discrepancies relating to the gun's distance from
-the car.
-
-On the same day, one of the journalists involved started crowdfunding
-for a book on the case titled '30 Years of Silence'.
-
-Following the rejection of the petition for a Fatal Accident Inquiry by
-the Crown Office, a "Justice For Willie" Campaign group was set up by
-Mark MacNicol. The campaign decided to launch their own investigation
-since no official inquiry was forthcoming. They hired two private
-investigators to re-interview original witnesses from the time of Willie
-McRae's death. The results were published in November 2016, and the
-campaign were unable to find any new evidence to undermine the official
-suicide verdict.
-
-In October 2018, fresh doubt on the official verdict was raised again by
-a nurse who claims to have treated Willie McRae at Foresterhill Hospital
-in Aberdeen. Katharine Mcgonigal disputed that the bullet wound was to
-the right temple, as the post-mortem claimed, and said it was instead to
-the back of the neck.
(DIR) diff --git a/ansible/roles/finger/files/morris.txt b/ansible/roles/finger/files/morris.txt
@@ -1,125 +0,0 @@
-
-T H E
- ___ ___ ___ ____ ____ ____ _____ __ __ ___ ____ ___ ___
- | | |/ \| \| \| / ___/ | |__| |/ \| \| | |
- | _ _ | | D ) D )| ( \_ | | | | | D ) _ _ |
- | \_/ | O | /| / | |\__ | | | | | O | /| \_/ |
- | | | | \| \ | |/ \ | | ` ' | | \| | |
- | | | | . \ . \| |\ | \ /| | . \ | |
- |___|___|\___/|__|\_|__|\_|____|\___| \_/\_/ \___/|__|\_|___|___|
-
-
-
-The Morris worm or Internet worm of November 2, 1988, is one of the oldest
-computer worms distributed via the Internet, and the first to gain significant
-mainstream media attention. It resulted in the first felony conviction in the
-US under the 1986 Computer Fraud and Abuse Act. It was written by a graduate
-student at Cornell University, Robert Tappan Morris, and launched on November
-2, 1988, from the Massachusetts Institute of Technology network.
-
-
-|> Architecture
-
-
-The worm was created by Morris simply to see if it could be done,
-and was released from the Massachusetts Institute of Technology (MIT) in the
-hope of suggesting that its creator studied there, instead of Cornell. Morris
-later became a tenured professor at MIT in 2006. The worm's creator Robert
-Tappan Morris is the son of cryptographer Robert Morris, who worked at the NSA
-at the time.
-
-The worm exploited several vulnerabilities of targeted systems, including:
-
- A hole in the debug mode of the Unix sendmail program
-
- A buffer overflow or overrun hole in the finger network service
-
- The transitive trust enabled by people setting up network logins with no
- password requirements via remote execution (rexec) with Remote Shell (rsh),
- termed rexec/rsh
-
- The worm exploited weak passwords. Morris's exploits became generally
- obsolete due to decommissioning rsh (normally disabled on untrusted networks),
- fixes to sendmail and finger, widespread network filtering, and improved
- awareness of weak passwords.
-
-Though Morris did not intend for the worm to be actively destructive, instead
-seeking to merely highlight the weaknesses present in many networks of the
-time, an unintentional consequence of Morris's coding resulted in the worm
-being more damaging and spreadable than originally planned. It was initially
-programmed to check each computer to determine if the infection was already
-present, but Morris believed that some system administrators might counter this
-by instructing the computer to report a false positive. Instead, he programmed
-the worm to copy itself 14% of the time, regardless of the status of infection
-on the computer. This resulted in a computer potentially being infected
-multiple times, with each additional infection slowing the machine down to
-unusability. This had the same effect as a fork bomb, and crashed the computer
-several times.
-
-The main body of the worm can only infect DEC VAX machines running 4BSD,
-alongside Sun-3 systems. A portable C "grappling hook" component of the worm
-was used to download the main body parts, and the grappling hook runs on other
-systems, loading them down and making them peripheral victims.
-
-
-|> Coding mistake
-
-
-Morris's coding mistake, in instructing the worm to replicate itself regardless
-of a computer's reported infection status, transformed the worm from a
-potentially harmless intellectual and computing exercise into a viral
-denial-of-service attack. Morris's inclusion of the rate of copy within the
-worm was inspired by Michael Rabin's mantra of randomization.
-
-The resulting level of replication proved excessive, with the worm spreading
-rapidly, infecting some computers several times. Rabin would eventually comment
-that Morris "should have tried it on a simulator first".
-
-
-|> Effects
-
-
-During the Morris appeal process, the US court of appeals estimated the cost of
-removing the virus from each installation was in the range of $200–53,000.
-Possibly based on these numbers, Clifford Stoll of Harvard estimated for the US
-Government Accountability Office that the total economic impact was between
-$100,000 and $10,000,000. Stoll, a systems administrator known for discovering
-and subsequently tracking the hacker Markus Hess three years earlier, helped
-fight the worm, writing in 1989 that "I surveyed the network, and found that
-two thousand computers were infected within fifteen hours. These machines were
-dead in the water—useless until disinfected. And removing the virus often took
-two days." Stoll commented that the worm showed the danger of monoculture,
-because "If all the systems on the ARPANET ran Berkeley Unix, the virus would
-have disabled all fifty thousand of them."
-
-It is usually reported that around 6,000 major UNIX machines were infected by
-the Morris worm. However, Morris's colleague Paul Graham claimed, "I was there
-when this statistic was cooked up, and this was the recipe: someone guessed
-that there were about 60,000 computers attached to the Internet, and that the
-worm might have infected ten percent of them." Stoll estimated that "only a
-couple thousand" computers were affected, writing that "Rumors have it that
-[Morris] worked with a friend or two at Harvard's computing department (Harvard
-student Paul Graham sent him mail asking for 'Any news on the brilliant
-project')."
-
-The Internet was partitioned for several days, as regional networks
-disconnected from the NSFNet backbone and from each other to prevent
-recontamination while cleaning their own networks.
-
-The Morris worm prompted DARPA to fund the establishment of the CERT/CC at
-Carnegie Mellon University, giving experts a central point for coordinating
-responses to network emergencies. Gene Spafford also created the Phage mailing
-list to coordinate a response to the emergency.
-
-Morris was tried and convicted of violating United States Code Title 18 (18
-U.S.C. § 1030), the Computer Fraud and Abuse Act, in United States v. Morris.
-After appeals, he was sentenced to three years' probation, 400 hours of
-community service, and a fine of US$10,050 (equivalent to $20,000 in 2021) plus
-the costs of his supervision. The total fine ran to $13,326, which included a
-$10,000 fine, $50 special assessment, and $3,276 cost of probation oversight.
-
-The Morris worm has sometimes been referred to as the "Great Worm", due to the
-devastating effect it had on the Internet at that time, both in overall system
-downtime and in psychological impact on the perception of security and
-reliability of the Internet. The name was derived from the "Great Worms" of
-Tolkien: Scatha and Glaurung.
(DIR) diff --git a/ansible/roles/finger/files/nouser b/ansible/roles/finger/files/nouser
@@ -1,19 +0,0 @@
-#!/bin/sh
-
-if [ "$3" = "morris" ]; then
- cat "/etc/efingerd/morris.txt"
-elif [ "$3" = "mcrae" ]; then
- cat "/etc/efingerd/mcrae.txt"
-else
-
- cat <<EOF
-
- You tried to finger non-existent user!!!
- Your attempt is logged and sent to Scotland Yard, MI5 and the DLVA..
-
- Expect a visit soon.
-
- Just joking, it went to /dev/null
-EOF
-
-fi
(DIR) diff --git a/ansible/roles/finger/tasks/main.yml b/ansible/roles/finger/tasks/main.yml
@@ -1,36 +0,0 @@
----
-- name: Include OS-specific variables
- ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
-
-- name: Install required packages
- ansible.builtin.package:
- name: "{{ common_packages }}"
- state: present
-
-- name: Create efingerd config directory
- ansible.builtin.file:
- path: /etc/efingerd
- state: directory
- mode: '0755'
-
-- name: Copy efingerd scripts
- ansible.builtin.copy:
- src: "{{ item }}"
- dest: "/etc/efingerd/{{ item }}"
- owner: root
- group: root
- mode: '0755'
- loop:
- - list
- - logo.txt
- - morris.txt
- - mcrae.txt
- - log
- - luser
- - nouser
-
-- name: Enable inetd
- ansible.builtin.systemd:
- name: inetd
- state: started
- daemon_reload: true
(DIR) diff --git a/ansible/roles/finger/vars/Debian.yml b/ansible/roles/finger/vars/Debian.yml
@@ -1,3 +0,0 @@
-common_packages:
- - openbsd-inetd
- - efingerd
(DIR) diff --git a/ansible/roles/git/handlers/main.yml b/ansible/roles/git/handlers/main.yml
@@ -1,6 +0,0 @@
----
-- name: Restart git-daemon
- ansible.builtin.systemd:
- name: git-daemon
- state: started
- daemon_reload: true
(DIR) diff --git a/ansible/roles/git/tasks/main.yml b/ansible/roles/git/tasks/main.yml
@@ -1,31 +0,0 @@
----
-- name: Include OS-specific variables
- ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
-
-- name: Install required packages
- ansible.builtin.package:
- name: "{{ common_packages }}"
- state: present
-
-- name: Added git service account
- ansible.builtin.user:
- name: "{{ git.user }}"
- comment: "Git Service Account"
- home: "{{ git.base_path }}"
- shell: /usr/bin/git-shell
- group: "{{ git.group }}"
-
-- name: Set initial authorized key
- ansible.posix.authorized_key:
- user: git
- state: present
- key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
-
-- name: Create systemd service file
- ansible.builtin.template:
- src: templates/git-daemon.service.j2
- dest: /lib/systemd/system/git-daemon.service
- owner: root
- group: root
- mode: "0644"
- notify: Restart git-daemon
(DIR) diff --git a/ansible/roles/git/templates/git-daemon.service.j2 b/ansible/roles/git/templates/git-daemon.service.j2
@@ -1,18 +0,0 @@
-[Unit]
-Description=Start Git Daemon
-
-[Service]
-ExecStart=/usr/bin/git daemon --reuseaddr --base-path={{ git.base_path }} {{ git.base_path }}
-
-Restart=always
-RestartSec=500ms
-
-StandardOutput=syslog
-StandardError=syslog
-SyslogIdentifier=git-daemon
-
-User={{ git.user }}
-Group={{ git.group }}
-
-[Install]
-WantedBy=multi-user.target
(DIR) diff --git a/ansible/roles/git/vars/Debian.yml b/ansible/roles/git/vars/Debian.yml
@@ -1,2 +0,0 @@
-common_packages:
- - git
(DIR) diff --git a/ansible/roles/gopher/handlers/main.yml b/ansible/roles/gopher/handlers/main.yml
@@ -1,12 +0,0 @@
----
-- name: Restart geomyidae
- ansible.builtin.systemd:
- name: geomyidae
- state: started
- enabled: true
- daemon_reload: true
-
-- name: Install geomyidae
- community.general.system.make:
- chdir: "{{ build_path }}"
- target: install
(DIR) diff --git a/ansible/roles/gopher/tasks/main.yml b/ansible/roles/gopher/tasks/main.yml
@@ -1,58 +0,0 @@
----
-- name: Include OS-specific variables.
- ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
-
-- name: Install required packages
- ansible.builtin.package:
- name: "{{ common_packages }}"
- state: present
-
-- name: Git checkout
- ansible.builtin.git:
- repo: "{{ source_repo }}"
- dest: "{{ build_path }}"
- force: false
- version: "{{ geomyidae.git_branch }}"
- register: repo_clone
- failed_when:
- - repo_clone.failed
- - not 'Local modifications exist in the destination' in repo_clone.msg
-
-- name: Disable TLS options
- ansible.builtin.replace:
- path: "{{ build_path }}/Makefile"
- regexp: '^TLS_CFLAGS = -DENABLE_TLS'
- replace: '#TLS_CFLAGS = -DENABLE_TLS'
- when: disable_tls
-
-- name: Disable TLS flags
- ansible.builtin.replace:
- path: "{{ build_path }}/Makefile"
- regexp: '^TLS_LDFLAGS = -ltls'
- replace: '#TLS_LDFLAGS = -ltls'
- when: disable_tls
-
-- name: Build geomyidae
- community.general.system.make:
- chdir: "{{ build_path }}"
- notify: Install geomyidae
-
-- name: Flush handlers
- ansible.builtin.meta: flush_handlers
-
-- name: Create root directory
- ansible.builtin.file:
- path: "{{ geomyidae.root_path }}"
- owner: "{{ geomyidae.user }}"
- group: "{{ geomyidae.group }}"
- mode: 0755
- state: directory
-
-- name: Create systemd service file
- ansible.builtin.template:
- src: templates/geomyidae.service.j2
- dest: /lib/systemd/system/geomyidae.service
- owner: root
- group: root
- mode: '0644'
- notify: Restart geomyidae
(DIR) diff --git a/ansible/roles/gopher/templates/geomyidae.service.j2 b/ansible/roles/gopher/templates/geomyidae.service.j2
@@ -1,16 +0,0 @@
-[Unit]
-Description=Geomyidae Gopher Server
-After=network.target
-Wants=network.target
-StartLimitBurst=5
-StartLimitIntervalSec=1
-
-[Service]
-Type=forking
-Restart=on-abnormal
-RestartSec=1
-User=root
-ExecStart=/usr/local/bin/geomyidae -v 0 -b {{ geomyidae.root_path }} -p 70 -n -u {{ geomyidae.user }} -g {{ geomyidae.group }}
-
-[Install]
-WantedBy=multi-user.target
(DIR) diff --git a/ansible/roles/gopher/vars/Debian.yml b/ansible/roles/gopher/vars/Debian.yml
@@ -1,4 +0,0 @@
-common_packages:
- - git
- - build-essential
- - libssl-dev
(DIR) diff --git a/ansible/roles/gopher/vars/main.yml b/ansible/roles/gopher/vars/main.yml
@@ -1,5 +0,0 @@
----
-
-build_path: /tmp/src/geomyidae
-source_repo: git://r-36.net/geomyidae
-disable_tls: true
(DIR) diff --git a/ansible/roles/stagit/handlers/main.yml b/ansible/roles/stagit/handlers/main.yml
@@ -1,5 +0,0 @@
----
-- name: Install stagit
- community.general.system.make:
- chdir: "{{ build_path }}"
- target: install
(DIR) diff --git a/ansible/roles/stagit/tasks/main.yml b/ansible/roles/stagit/tasks/main.yml
@@ -1,46 +0,0 @@
----
-- name: Include OS-specific variables.
- ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
-
-- name: Install required packages
- ansible.builtin.package:
- name: "{{ common_packages }}"
- state: present
-
-- name: Git checkout
- ansible.builtin.git:
- repo: "{{ source_repo }}"
- dest: "{{ build_path }}"
- force: false
- version: "{{ stagit_gopher.git_branch }}"
- register: repo_clone
- failed_when:
- - repo_clone.failed
- - not 'Local modifications exist in the destination' in repo_clone.msg
-
-- name: Enable old libgit2 workaround
- ansible.builtin.replace:
- path: "{{ build_path }}/Makefile"
- regexp: '^#STAGIT_CFLAGS'
- replace: 'STAGIT_CFLAGS'
- when: enable_old_libgit2
-
-- name: Build from source
- community.general.system.make:
- chdir: "{{ build_path }}"
- notify: Install stagit
-
-- name: Create stagit run script
- ansible.builtin.template:
- src: templates/stagit_create.sh.j2
- dest: "/home/{{ stagit_gopher.cron_user }}/stagit_create.sh"
- owner: "{{ stagit_gopher.cron_user }}"
- group: "{{ stagit_gopher.cron_group }}"
- mode: "755"
-
-- name: Adding script to cron
- ansible.builtin.cron:
- name: "run stagit script"
- user: "{{ stagit_gopher.cron_user }}"
- minute: "*/5"
- job: "/home/{{ stagit_gopher.cron_user }}/stagit_create.sh"
(DIR) diff --git a/ansible/roles/stagit/templates/stagit_create.sh.j2 b/ansible/roles/stagit/templates/stagit_create.sh.j2
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-reposdir="{{ stagit_gopher.repo_path }}"
-gopherdir="{{ stagit_gopher.output_path }}"
-stagitdir="/git"
-destdir="${gopherdir}/${stagitdir}"
-
-# remove /'s at the end.
-stagitdir=$(printf "%s" "${stagitdir}" | sed 's@[/]*$@@g')
-
-rm -rf "{{ stagit_gopher.output_path }}/git/*"
-
-/usr/local/bin/stagit-gopher-index -b "${stagitdir}" "${reposdir}/"*.git/ >"${destdir}/index.gph"
-
-# make files per repo.
-for dir in "${reposdir}/"*/; do
- # strip .git suffix.
- r=$(basename "${dir}")
- d=$(basename "${dir}" ".git")
- printf "%s... " "${d}"
-
- mkdir -p "${destdir}/${d}"
- cd "${destdir}/${d}" || continue
-
- if [ "$d" != "pass" ]; then
- /usr/local/bin/stagit-gopher -b "${stagitdir}/${d}" \
- -u "gopher://jay.scot/1/git/$d/" "${reposdir}/${r}"
-
- # symlinks
- ln -sf log.gph index.gph
-
- echo "done"
- else
- echo "skipping"
- fi
-done
-
-
(DIR) diff --git a/ansible/roles/stagit/vars/Debian.yml b/ansible/roles/stagit/vars/Debian.yml
@@ -1,4 +0,0 @@
-common_packages:
- - git
- - build-essential
- - libgit2-dev
(DIR) diff --git a/ansible/roles/stagit/vars/main.yml b/ansible/roles/stagit/vars/main.yml
@@ -1,5 +0,0 @@
----
-
-build_path: /tmp/src/stagit-gopher
-source_repo: git://git.codemadness.org/stagit-gopher
-enable_old_libgit2: false
(DIR) diff --git a/remote/.terraform.lock.hcl b/remote/.terraform.lock.hcl
@@ -0,0 +1,24 @@
+# This file is maintained automatically by "tofu init".
+# Manual edits may be lost in future updates.
+
+provider "registry.opentofu.org/hetznercloud/hcloud" {
+ version = "1.47.0"
+ constraints = "1.47.0"
+ hashes = [
+ "h1:aqEPcSpaWhKqbMs7c7Pf5ot6Tye7ntRitWsuNGPRPfk=",
+ "zh:0759f0c23d0e59baab3382320eef4eb314e0c5967b6ef67ff07135da07a97b34",
+ "zh:0e9ca84c4059d6d7e2c9f13d3c2b1cd91f7d9a47bedcb4b80c7c77d536eff887",
+ "zh:17a033ac4650a39ddacf3265a449edabaea528f81542c4e63e254272d5aac340",
+ "zh:2997c76a500e42b7519b24fa1f8646d9baab70c68277f80394560d3e1fd06e6d",
+ "zh:37f3fe7bb34cac63c69123e43e5426bab75816b3665dbe7125276a8d2ee6b2d8",
+ "zh:45d4b04dc470f24ad96c1c0b6636ea5422c659004f3e472c863bc50130fabf25",
+ "zh:46df99d972a78af6875565e53a73df66d870c474a20cd90e9e0a3092aa25197f",
+ "zh:4b5bb8d49366ad895c6c767efe16a1b8143802414abfe3fdb1184cbbecf424eb",
+ "zh:55c6199eb401c4b0a6c948ceac8b50f352e252e1c985903ed173bf26ad0f109e",
+ "zh:7b6efe897bffa37248064155a699e67953350b5b9a5476456c0160ce59254557",
+ "zh:7bc004bcb649ce1ec70e2cf848392e10a1edbcbf11b3292a4cc5c5d49bd769e4",
+ "zh:e1b17b7595f158fbb3021afa8869b541b5c10bdd2d8d2b2b3eaa82200b104ddd",
+ "zh:f741ca40e8e99a3e4114ad108ea2b5a5bccbedb008326c7f647f250580e69c0e",
+ "zh:fae9c7f8d08a447bb0972529f6db06999c35391046320206041a988aeca6b54c",
+ ]
+}
(DIR) diff --git a/remote/checks.tf b/remote/checks.tf
@@ -0,0 +1,8 @@
+check "server_status" {
+ assert {
+ condition = alltrue([
+ for k, v in var.nodes : hcloud_server.this[k].status == "running"
+ ])
+ error_message = "Server status check failed."
+ }
+}
(DIR) diff --git a/remote/cloudinit/main.yml b/remote/cloudinit/main.yml
@@ -0,0 +1,47 @@
+#cloud-config
+
+ssh_pwauth: false
+hostname: jay.scot
+timezone: Europe/London
+package_update: true
+
+packages:
+ - caddy
+ - git
+ - git-daemon-sysvinit
+ - unattended-upgrades
+
+users:
+ - name: jay
+ groups: users,wheel
+ sudo: ALL=(ALL) NOPASSWD:ALL
+ shell: /bin/bash
+ lock_passwd: true
+ ssh_authorized_keys:
+ - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDLmKYxwXTbyRWLG0S24RTpyfyBO6AL8Dcy0XvVZ97Do
+
+ - name: git
+ shell: /usr/bin/git-shell
+ homedir: /srv/git
+ ssh_authorized_keys:
+ - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDLmKYxwXTbyRWLG0S24RTpyfyBO6AL8Dcy0XvVZ97Do
+
+write_files:
+ - path: /etc/default/git-daemon
+ permissions: '0644'
+ content: |
+ GIT_DAEMON_ENABLE=true
+ GIT_DAEMON_USER=git
+ GIT_DAEMON_BASE_PATH=/srv/git
+ GIT_DAEMON_DIRECTORY=/srv/git
+ GIT_DAEMON_OPTIONS="--export-all"
+
+ - path: /etc/caddy/Caddyfile
+ permissions: '0644'
+ content: |
+ jay.scot {
+ tls me@jay.scot
+ root * /srv/www
+ encode gzip
+ file_server
+ }
(DIR) diff --git a/remote/main.tf b/remote/main.tf
@@ -0,0 +1,69 @@
+terraform {
+ required_version = ">=1.7.0"
+ required_providers {
+ hcloud = {
+ source = "hetznercloud/hcloud"
+ version = "1.47.0"
+ }
+ }
+}
+
+resource "hcloud_ssh_key" "this" {
+ for_each = var.public_ssh_keys
+
+ name = each.key
+ public_key = file(each.value)
+}
+
+
+resource "hcloud_firewall" "this" {
+ for_each = var.firewall_rules
+
+ name = each.key
+
+ dynamic "rule" {
+ for_each = each.value.rules
+
+ content {
+ description = rule.key
+ direction = rule.value.direction
+ protocol = rule.value.protocol
+ source_ips = rule.value.source_ips
+ port = rule.value.port
+ }
+ }
+}
+
+
+resource "hcloud_server" "this" {
+ for_each = var.nodes
+
+ name = each.key
+ image = each.value.image
+ server_type = each.value.server_type
+ location = each.value.location
+ labels = each.value.labels
+ ssh_keys = [hcloud_ssh_key.this[each.value.public_key].id]
+ user_data = file(each.value.user_data)
+ firewall_ids = [hcloud_firewall.this[each.key].id]
+
+ public_net {
+ ipv4_enabled = each.value.ipv4
+ ipv6_enabled = each.value.ipv6
+ }
+
+ lifecycle {
+ postcondition {
+ condition = self.status == "running"
+ error_message = "Instance must be running."
+ }
+ }
+}
+
+resource "hcloud_rdns" "this" {
+ for_each = hcloud_server.this
+
+ server_id = each.value.id
+ ip_address = each.value.ipv4_address
+ dns_ptr = var.nodes[each.key].reverse_dns
+}
(DIR) diff --git a/remote/outputs.tf b/remote/outputs.tf
@@ -0,0 +1,3 @@
+output "public_ip_address" {
+ value = { for name, server in hcloud_server.this : name => server.ipv4_address }
+}
(DIR) diff --git a/remote/terraform.tfvars b/remote/terraform.tfvars
@@ -0,0 +1,53 @@
+public_ssh_keys = {
+ main = "~/.ssh/id_ed25519.pub"
+}
+
+firewall_rules = {
+ "main" = {
+ rules = {
+ ssh = {
+ direction = "in"
+ protocol = "tcp"
+ source_ips = ["0.0.0.0/0", "::/0"]
+ port = "22"
+ }
+ git = {
+ direction = "in"
+ protocol = "tcp"
+ source_ips = ["0.0.0.0/0", "::/0"]
+ port = "9418"
+ }
+ http = {
+ direction = "in"
+ protocol = "tcp"
+ source_ips = ["0.0.0.0/0", "::/0"]
+ port = "80"
+ }
+ https = {
+ direction = "in"
+ protocol = "tcp"
+ source_ips = ["0.0.0.0/0", "::/0"]
+ port = "443"
+ }
+
+ }
+ }
+
+}
+
+nodes = {
+ "main" = {
+ image = "debian-12"
+ location = "hel1",
+ server_type = "cx22",
+ reverse_dns = "jay.scot"
+ user_data = "cloudinit/main.yml"
+ public_key = "main"
+ ipv4 = true
+ ipv6 = true
+ labels = {
+ git = "true"
+ gemini = "true"
+ }
+ }
+}
(DIR) diff --git a/remote/variables.tf b/remote/variables.tf
@@ -0,0 +1,25 @@
+
+variable "public_ssh_keys" {
+ description = "Public SSH key location to attach to instance."
+ type = map(any)
+}
+
+variable "firewall_rules" {
+ description = "Firewall configuration settings."
+ type = map(any)
+}
+
+variable "nodes" {
+ description = "Configuration settings for each required node."
+ type = map(object({
+ image = string
+ location = string
+ server_type = string
+ reverse_dns = string
+ user_data = string
+ public_key = string
+ labels = map(any)
+ ipv4 = bool
+ ipv6 = bool
+ }))
+}