URI: 
       Cleaning up ansible scripts for new server. - infra - Terraform IoC for my remote (Hetzner) and local (Incus) servers.
   DIR Log
   DIR Files
   DIR Refs
   DIR README
       ---
   DIR commit 635e9945ef2e0d2def7301381daec2115377891e
   DIR parent 55d36aebb3497bf0333bcc8051ebd329cd607055
  HTML Author: Jay Scott <me@jay.scot>
       Date:   Sat, 10 Feb 2024 23:08:34 +0000
       
       Cleaning up ansible scripts for new server.
       
       Diffstat:
         M README                              |      21 +++++++++++----------
         A ansible/group_vars/all.yml          |       4 ++++
         A ansible/group_vars/git.yml          |       4 ++++
         A ansible/group_vars/gopher.yml       |      12 ++++++++++++
         A ansible/inventory.yml               |      10 ++++++++++
         A ansible/main.yml                    |      21 +++++++++++++++++++++
         A ansible/roles/common/files/sshd_co… |       6 ++++++
         A ansible/roles/common/handlers/main… |       4 ++++
         A ansible/roles/common/tasks/main.yml |      47 +++++++++++++++++++++++++++++++
         A ansible/roles/common/tasks/setup-D… |       5 +++++
         A ansible/roles/common/vars/Debian.y… |       5 +++++
         A ansible/roles/finger/files/list     |      16 ++++++++++++++++
         A ansible/roles/finger/files/log      |       1 +
         A ansible/roles/finger/files/logo.txt |       7 +++++++
         A ansible/roles/finger/files/luser    |      29 +++++++++++++++++++++++++++++
         A ansible/roles/finger/files/mcrae.t… |     222 ++++++++++++++++++++++++++++++
         A ansible/roles/finger/files/morris.… |     125 +++++++++++++++++++++++++++++++
         A ansible/roles/finger/files/nouser   |      19 +++++++++++++++++++
         A ansible/roles/finger/tasks/main.yml |      36 +++++++++++++++++++++++++++++++
         A ansible/roles/finger/vars/Debian.y… |       3 +++
         A ansible/roles/git/handlers/main.yml |       6 ++++++
         A ansible/roles/git/tasks/main.yml    |      31 +++++++++++++++++++++++++++++++
         A ansible/roles/git/templates/git-da… |      18 ++++++++++++++++++
         A ansible/roles/git/vars/Debian.yml   |       2 ++
         A ansible/roles/gopher/handlers/main… |      12 ++++++++++++
         A ansible/roles/gopher/tasks/main.yml |      58 ++++++++++++++++++++++++++++++
         A ansible/roles/gopher/templates/geo… |      16 ++++++++++++++++
         A ansible/roles/gopher/vars/Debian.y… |       4 ++++
         A ansible/roles/gopher/vars/main.yml  |       5 +++++
         A ansible/roles/stagit/handlers/main… |       5 +++++
         A ansible/roles/stagit/tasks/main.yml |      46 +++++++++++++++++++++++++++++++
         A ansible/roles/stagit/templates/sta… |      38 +++++++++++++++++++++++++++++++
         A ansible/roles/stagit/vars/Debian.y… |       4 ++++
         A ansible/roles/stagit/vars/main.yml  |       5 +++++
         D containers/docker-compose.yaml      |      25 -------------------------
         D containers/fingered/Dockerfile      |      22 ----------------------
         D containers/geomyidae/Dockerfile     |      22 ----------------------
         D containers/geomyidae/Makefile       |      52 -------------------------------
       
       38 files changed, 837 insertions(+), 131 deletions(-)
       ---
   DIR diff --git a/README b/README
       @@ -7,7 +7,7 @@ Bootstrap Hetzner Cloud servers.
                Provision X servers with desired configuration
                Create custom firewall rules
                Add reverse dns entry
       -        Userdata bootscript add a user and docker.
       +        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.
       @@ -17,25 +17,26 @@ the following depending on your requirements.
        
        
        The user_data script is a standard cloud-init yaml config that creates
       -an user for deploying docker containers.
       +an Ansible user for further configuration the instances.
        
        
                terraform plan
                terraform apply
        
        
       -|> Containers
       +|> Ansible
        
       -Docker containers for the following services I run:
       +Playbook to install the following:
        
          gopher
       -  fingered
       +  git and git daemon
       +  stagit-gopher
       +  efingerd
        
       +Apply all:
        
       -Create a remote context, one time thing:
       +        ansible-playbook -i inventory.yml main.yml
        
       -        docker context create remote --docker "host=ssh://jay@jay.scot"
       +Run tags
        
       -Build and run the containers:
       -
       -        docker-compose --context remote up --build -d
       +        ansible-playbook -i inventory.yml main.yml --tags <git/gopher/common>
   DIR diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
       @@ -0,0 +1,4 @@
       +default:
       +  username: jay
       +  comment: Jay Scott
       +  hostname: jay.scot
   DIR diff --git a/ansible/group_vars/git.yml b/ansible/group_vars/git.yml
       @@ -0,0 +1,4 @@
       +git:
       +  user: git
       +  group: users
       +  base_path: /srv/git
   DIR diff --git a/ansible/group_vars/gopher.yml b/ansible/group_vars/gopher.yml
       @@ -0,0 +1,12 @@
       +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
       @@ -0,0 +1,10 @@
       +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
       @@ -0,0 +1,21 @@
       +- 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
       @@ -0,0 +1,6 @@
       +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
       @@ -0,0 +1,4 @@
       +- 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
       @@ -0,0 +1,47 @@
       +---
       +
       +- 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
       @@ -0,0 +1,5 @@
       +- 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
       @@ -0,0 +1,5 @@
       +common_packages:
       +  - htop
       +  - vim
       +  - finger
       +  - lynx
   DIR diff --git a/ansible/roles/finger/files/list b/ansible/roles/finger/files/list
       @@ -0,0 +1,16 @@
       +#!/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
       @@ -0,0 +1 @@
       +# nope, no logs
   DIR diff --git a/ansible/roles/finger/files/logo.txt b/ansible/roles/finger/files/logo.txt
       @@ -0,0 +1,7 @@
       +     ___  _______  __   __        _______  _______  _______  _______
       +    |   ||   _   ||  | |  |      |       ||       ||       ||       |
       +    |   ||  |_|  ||  |_|  |      |  _____||       ||   _   ||_     _|
       +    |   ||       ||       |      | |_____ |       ||  | |  |  |   |
       + ___|   ||       ||_     _| ___  |_____  ||      _||  |_|  |  |   |
       +|       ||   _   |  |   |  |   |  _____| ||     |_ |       |  |   |
       +|_______||__| |__|  |___|  |___| |_______||_______||_______|  |___|
   DIR diff --git a/ansible/roles/finger/files/luser b/ansible/roles/finger/files/luser
       @@ -0,0 +1,29 @@
       +#!/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
       @@ -0,0 +1,222 @@
       +
       +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
       @@ -0,0 +1,125 @@
       +
       +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
       @@ -0,0 +1,19 @@
       +#!/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
       @@ -0,0 +1,36 @@
       +---
       +- 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
       @@ -0,0 +1,3 @@
       +common_packages:
       +  - openbsd-inetd
       +  - efingerd
   DIR diff --git a/ansible/roles/git/handlers/main.yml b/ansible/roles/git/handlers/main.yml
       @@ -0,0 +1,6 @@
       +---
       +- 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
       @@ -0,0 +1,31 @@
       +---
       +- 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
       @@ -0,0 +1,18 @@
       +[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
       @@ -0,0 +1,2 @@
       +common_packages:
       +  - git
   DIR diff --git a/ansible/roles/gopher/handlers/main.yml b/ansible/roles/gopher/handlers/main.yml
       @@ -0,0 +1,12 @@
       +---
       +- 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
       @@ -0,0 +1,58 @@
       +---
       +- 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
       @@ -0,0 +1,16 @@
       +[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
       @@ -0,0 +1,4 @@
       +common_packages:
       +  - git
       +  - build-essential
       +  - libssl-dev
   DIR diff --git a/ansible/roles/gopher/vars/main.yml b/ansible/roles/gopher/vars/main.yml
       @@ -0,0 +1,5 @@
       +---
       +
       +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
       @@ -0,0 +1,5 @@
       +---
       +- 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
       @@ -0,0 +1,46 @@
       +---
       +- 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
       @@ -0,0 +1,38 @@
       +#!/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
       @@ -0,0 +1,4 @@
       +common_packages:
       +  - git
       +  - build-essential
       +  - libgit2-dev
   DIR diff --git a/ansible/roles/stagit/vars/main.yml b/ansible/roles/stagit/vars/main.yml
       @@ -0,0 +1,5 @@
       +---
       +
       +build_path: /tmp/src/stagit-gopher
       +source_repo: git://git.codemadness.org/stagit-gopher
       +enable_old_libgit2: false
   DIR diff --git a/containers/docker-compose.yaml b/containers/docker-compose.yaml
       @@ -1,25 +0,0 @@
       -services:
       -  gopher:
       -    image: geomyidae
       -    build:
       -      context: geomyidae
       -      dockerfile: ../geomyidae/Dockerfile
       -      args:
       -        SERVER_ARGS: -p 70 -b /srv/gopher -h jay.scot -v 0
       -    ports:
       -      - 70:70
       -    restart: always
       -    volumes:
       -      - /srv/gopher:/srv/gopher
       -  fingered:
       -    image: fingered
       -    build:
       -      context: fingered
       -      dockerfile: ../fingered/Dockerfile
       -      args:
       -        SERVER_ARGS: -p 79 -d /srv/fingered
       -    ports:
       -      - 79:79
       -    restart: always
       -    volumes:
       -      - /srv/fingered:/srv/fingered
   DIR diff --git a/containers/fingered/Dockerfile b/containers/fingered/Dockerfile
       @@ -1,22 +0,0 @@
       -FROM alpine:latest AS builder
       -
       -WORKDIR /fingered
       -
       -RUN apk add go git make
       -RUN git clone https://git.sr.ht/~jayscott/fingered /fingered
       -RUN make install
       -
       -
       -FROM alpine:latest
       -
       -ARG SERVER_ARGS
       -ENV SERVER_ARGS=${SERVER_ARGS}
       -
       -EXPOSE 79/tcp
       -VOLUME /srv/fingered
       -
       -RUN mkdir -p /srv/fingered
       -
       -COPY --from=builder /usr/local/bin/fingered /usr/bin
       -
       -ENTRYPOINT /usr/bin/fingered $SERVER_ARGS
   DIR diff --git a/containers/geomyidae/Dockerfile b/containers/geomyidae/Dockerfile
       @@ -1,22 +0,0 @@
       -FROM alpine:latest AS builder
       -
       -WORKDIR /geomyidae
       -
       -RUN apk add build-base git
       -RUN git clone git://r-36.net/geomyidae /geomyidae
       -COPY Makefile .
       -RUN make
       -
       -FROM alpine:latest
       -
       -ARG SERVER_ARGS
       -ENV SERVER_ARGS=${SERVER_ARGS}
       -
       -EXPOSE 70/tcp
       -VOLUME /var/gopher
       -
       -RUN mkdir -p /var/gopher
       -
       -COPY --from=builder /geomyidae/geomyidae /usr/sbin
       -
       -ENTRYPOINT /usr/sbin/geomyidae -d $SERVER_ARGS
   DIR diff --git a/containers/geomyidae/Makefile b/containers/geomyidae/Makefile
       @@ -1,52 +0,0 @@
       -# geomyidae - a tiny, standalone gopherd written in C
       -# See LICENSE file for copyright and license details.
       -.POSIX:
       -
       -NAME = geomyidae
       -VERSION = 0.72
       -
       -PREFIX = /usr/local
       -BINDIR = ${PREFIX}/bin
       -MANDIR = ${PREFIX}/share/man/man8
       -
       -GEOM_CFLAGS = -D_DEFAULT_SOURCE -I. -I/usr/include ${TLS_CFLAGS} ${CFLAGS}
       -GEOM_LDFLAGS = -L/usr/lib -L. ${TLS_LDFLAGS} ${LDFLAGS}
       -
       -SRC = main.c ind.c handlr.c
       -OBJ = ${SRC:.c=.o}
       -
       -all: ${NAME}
       -
       -.c.o:
       -        ${CC} ${GEOM_CFLAGS} -c $<
       -
       -${OBJ}:
       -
       -${NAME}: ${OBJ}
       -        ${CC} -o $@ ${OBJ} ${GEOM_LDFLAGS}
       -
       -clean:
       -        rm -f ${NAME} ${OBJ} ${NAME}-${VERSION}.tar.gz
       -
       -install: all
       -        mkdir -p "${DESTDIR}${BINDIR}"
       -        cp -f ${NAME} "${DESTDIR}${BINDIR}"
       -        chmod 755 "${DESTDIR}${BINDIR}/${NAME}"
       -        mkdir -p "${DESTDIR}${MANDIR}"
       -        cp -f ${NAME}.8 "${DESTDIR}${MANDIR}"
       -        chmod 644 "${DESTDIR}${MANDIR}/${NAME}.8"
       -
       -uninstall:
       -        rm -f "${DESTDIR}${BINDIR}/${NAME}"
       -        rm -f "${DESTDIR}${MANDIR}/${NAME}.8"
       -
       -dist: clean
       -        mkdir -p ${NAME}-${VERSION}
       -        cp -R rc.d CGI README LICENSE index.gph Makefile ${NAME}.8 \
       -                       *.c *.h ${NAME}-${VERSION}
       -        tar -cf ${NAME}-${VERSION}.tar ${NAME}-${VERSION}
       -        gzip ${NAME}-${VERSION}.tar
       -        mv ${NAME}-${VERSION}.tar.gz ${NAME}-${VERSION}.tgz
       -        rm -rf "${NAME}-${VERSION}"
       -
       -.PHONY: all clean dist install uninstall