Compare commits
No commits in common. "master" and "0e954238773bc6fdd2540d1369f122174ffcdca0" have entirely different histories.
master
...
0e95423877
|
@ -23,10 +23,6 @@ EOF
|
||||||
cat > ansible.cfg << EOF
|
cat > ansible.cfg << EOF
|
||||||
[defaults]
|
[defaults]
|
||||||
inventory = $(pwd)/hosts
|
inventory = $(pwd)/hosts
|
||||||
|
|
||||||
[ssh_connection]
|
|
||||||
ssh_args = "-o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey"
|
|
||||||
pipelining = true
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
ansible "$CATEGORY" -m ping
|
ansible "$CATEGORY" -m ping
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#
|
|
||||||
# Day 2 - Exit Code PS1 prompt
|
|
||||||
# "Pimp my prompt" with the return value of the last command.
|
|
||||||
# source this from ~/.bashrc or similar to modify PS1 to show the return value of previous command.
|
|
||||||
# Use the "demojify" command to restore your previous prompt after sourcing.
|
|
||||||
|
|
||||||
PS1OLD=$PS1
|
|
||||||
|
|
||||||
exitprompt ()
|
|
||||||
{
|
|
||||||
ERROR="$?"
|
|
||||||
if [ "$ERROR" -eq 0 ]
|
|
||||||
then
|
|
||||||
COLORCODE=32 # foreground green
|
|
||||||
EMOJI="🙂"
|
|
||||||
else
|
|
||||||
COLORCODE=31 # foreground red
|
|
||||||
EMOJI="🙁"
|
|
||||||
fi
|
|
||||||
echo -e "\e[${COLORCODE}m${ERROR} ${EMOJI} \e[0m"
|
|
||||||
}
|
|
||||||
|
|
||||||
demojify ()
|
|
||||||
{
|
|
||||||
PS1=$PS1OLD
|
|
||||||
}
|
|
||||||
|
|
||||||
PS1="\$(exitprompt)\n$PS1"
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
#
|
|
||||||
# Day 3 - Generate Inventory (Phase 1: tachyon user)
|
|
||||||
# Requires linode-cli to be installed (`pip3 install linode-cli`)
|
|
||||||
# The hosts file generated requires ansible (`pip3 install ansible`)
|
|
||||||
# This will crush any ansible.cfg and hosts files in the current directory.
|
|
||||||
|
|
||||||
# Default ansible group and linode label
|
|
||||||
if [ -z "$CATEGORY" ]
|
|
||||||
then
|
|
||||||
CATEGORY="UpskillChallengeNode"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$ADMINUSER" ]
|
|
||||||
then
|
|
||||||
ADMINUSER="tachyon"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# fetch IP address from Linode. Assumes one device (TODO: handle a swarm of them).
|
|
||||||
NODEIP=$(linode-cli linodes list --format 'ipv4' --label "$CATEGORY" --text | tail -n 1)
|
|
||||||
|
|
||||||
# create or clobber hosts file
|
|
||||||
cat > hosts << EOF
|
|
||||||
[$CATEGORY]
|
|
||||||
$NODEIP ansible_user=$ADMINUSER
|
|
||||||
|
|
||||||
[$CATEGORY:vars]
|
|
||||||
ansible_ssh_user=$ADMINUSER
|
|
||||||
ansible_become=yes
|
|
||||||
ansible_become_user=root
|
|
||||||
ansible_become_method=sudo
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# create or clobber hosts file
|
|
||||||
cat > ansible.cfg << EOF
|
|
||||||
[defaults]
|
|
||||||
inventory = $(pwd)/hosts
|
|
||||||
|
|
||||||
[ssh_connection]
|
|
||||||
ssh_args = "-o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey"
|
|
||||||
pipelining = true
|
|
||||||
EOF
|
|
||||||
|
|
||||||
ansible "$CATEGORY" -m ping
|
|
|
@ -1,48 +0,0 @@
|
||||||
#
|
|
||||||
# Day 3 - Generate Inventory (Phase 2: tachyon user on obscure port)
|
|
||||||
# Requires linode-cli to be installed (`pip3 install linode-cli`)
|
|
||||||
# The hosts file generated requires ansible (`pip3 install ansible`)
|
|
||||||
# This will crush any ansible.cfg and hosts files in the current directory.
|
|
||||||
|
|
||||||
# Default ansible group and linode label
|
|
||||||
if [ -z "$CATEGORY" ]
|
|
||||||
then
|
|
||||||
CATEGORY="UpskillChallengeNode"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$ADMINUSER" ]
|
|
||||||
then
|
|
||||||
ADMINUSER="tachyon"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$NODESSHPORT" ]
|
|
||||||
then
|
|
||||||
NODESSHPORT=22022
|
|
||||||
fi
|
|
||||||
|
|
||||||
# fetch IP address from Linode. Assumes one device (TODO: handle a swarm of them).
|
|
||||||
NODEIP=$(linode-cli linodes list --format 'ipv4' --label "$CATEGORY" --text | tail -n 1)
|
|
||||||
|
|
||||||
# create or clobber hosts file
|
|
||||||
cat > hosts << EOF
|
|
||||||
[$CATEGORY]
|
|
||||||
$NODEIP:$NODESSHPORT ansible_user=$ADMINUSER
|
|
||||||
|
|
||||||
[$CATEGORY:vars]
|
|
||||||
ansible_ssh_user=$ADMINUSER
|
|
||||||
ansible_become=yes
|
|
||||||
ansible_become_user=root
|
|
||||||
ansible_become_method=sudo
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# create or clobber hosts file
|
|
||||||
cat > ansible.cfg << EOF
|
|
||||||
[defaults]
|
|
||||||
inventory = $(pwd)/hosts
|
|
||||||
|
|
||||||
[ssh_connection]
|
|
||||||
ssh_args = "-o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey"
|
|
||||||
pipelining = true
|
|
||||||
EOF
|
|
||||||
|
|
||||||
ansible "$CATEGORY" -m ping
|
|
|
@ -1,11 +0,0 @@
|
||||||
[Unit]
|
|
||||||
Description=Jupyterhub
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
ExecStart=jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
|
|
||||||
Restart=on-failure
|
|
||||||
PIDFile=/var/run/jupyterhub.pid
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
1385
jupyterhub_config.py
1385
jupyterhub_config.py
File diff suppressed because it is too large
Load Diff
|
@ -1,78 +0,0 @@
|
||||||
---
|
|
||||||
- name: Install Jupyterhub
|
|
||||||
hosts: UpskillChallengeNode
|
|
||||||
gather_facts: no
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Create NodeJS directory
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: /opt/nodesource
|
|
||||||
state: directory
|
|
||||||
mode: 0755
|
|
||||||
|
|
||||||
- name: Create Jupyterhub config directory
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: /etc/jupyterhub
|
|
||||||
state: directory
|
|
||||||
mode: 0755
|
|
||||||
|
|
||||||
- name: Download NodeJS apt configuration
|
|
||||||
ansible.builtin.get_url:
|
|
||||||
url: "https://deb.nodesource.com/setup_14.x"
|
|
||||||
dest: /opt/nodesource
|
|
||||||
checksum: "sha512:a0451fa9a2d679fb43a1e703eb1ae0e0ad62da3eac73ff5a25abc71cbe908eb463ee478c1f2f7687532b56106956634afb72129572db347334bd1b7fbf99dcdc"
|
|
||||||
mode: 0755
|
|
||||||
|
|
||||||
- name: run NodeJS configuration script
|
|
||||||
ansible.builtin.shell: /opt/nodesource/setup_14.x
|
|
||||||
args:
|
|
||||||
chdir: /opt/nodesource
|
|
||||||
creates: /etc/apt/sources.list.d/nodesource.list
|
|
||||||
|
|
||||||
- name: update and upgrade packages
|
|
||||||
ansible.builtin.apt:
|
|
||||||
update_cache: yes
|
|
||||||
|
|
||||||
- name: install prerequisites [apt]
|
|
||||||
ansible.builtin.apt:
|
|
||||||
package:
|
|
||||||
- sudo
|
|
||||||
- python3
|
|
||||||
- python3-pip
|
|
||||||
- gcc
|
|
||||||
- g++
|
|
||||||
- make
|
|
||||||
- build-essential
|
|
||||||
- nodejs
|
|
||||||
- nginx
|
|
||||||
- certbot
|
|
||||||
- python3-certbot-nginx
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: install prerequisites [pip]
|
|
||||||
ansible.builtin.pip:
|
|
||||||
name:
|
|
||||||
- jupyterhub
|
|
||||||
- notebook
|
|
||||||
- virtualenv
|
|
||||||
|
|
||||||
- name: install prerequisites [npm]
|
|
||||||
community.general.npm:
|
|
||||||
global: yes
|
|
||||||
name: configurable-http-proxy
|
|
||||||
|
|
||||||
- name: copy Jupyterhub service file
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: jupyterhub.service
|
|
||||||
dest: /etc/systemd/system/
|
|
||||||
|
|
||||||
- name: copy Jupyterhub config file
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: jupyterhub_config.py
|
|
||||||
dest: /etc/jupyterhub
|
|
||||||
|
|
||||||
- name: daemon-reload
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
name: jupyterhub
|
|
||||||
state: restarted
|
|
||||||
daemon_reload: yes
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
d ()
|
|
||||||
{
|
|
||||||
date '+%F %T'
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $(d): Starting server
|
|
||||||
ROOT_PASS="Swordfish4321!" ./day0_create.sh
|
|
||||||
./wait_ready.sh
|
|
||||||
./day1_geninventory.sh
|
|
||||||
echo $(d): Creating user account
|
|
||||||
ansible-playbook phase1user.yml > .phase1.log
|
|
||||||
./day3_geninventory_phase1.sh
|
|
||||||
echo $(d): Securing SSH access
|
|
||||||
ansible-playbook phase2user.yml > .phase2.log
|
|
||||||
./day3_geninventory_phase2.sh
|
|
||||||
echo $(d): configuring jupyterhub
|
|
||||||
ansible-playbook jupyterhubsrv.yml > .jupyterhub.log
|
|
||||||
echo $(d): ready
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create admin user
|
|
||||||
hosts: UpskillChallengeNode
|
|
||||||
gather_facts: no
|
|
||||||
|
|
||||||
vars:
|
|
||||||
newusername: "tachyon"
|
|
||||||
|
|
||||||
vars_prompt:
|
|
||||||
- name: "passhash"
|
|
||||||
prompt: "Password for the user account"
|
|
||||||
private: yes
|
|
||||||
encrypt: "sha512_crypt"
|
|
||||||
confirm: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: install sudo
|
|
||||||
ansible.builtin.apt:
|
|
||||||
package: sudo
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: create user
|
|
||||||
ansible.builtin.user:
|
|
||||||
name: "{{ newusername }}"
|
|
||||||
password: "{{ passhash }}"
|
|
||||||
groups:
|
|
||||||
- sudo
|
|
||||||
state: present
|
|
||||||
shell: /bin/bash
|
|
||||||
createhome: yes
|
|
||||||
|
|
||||||
- name: set public key authentication
|
|
||||||
ansible.posix.authorized_key:
|
|
||||||
user: "{{ newusername }}"
|
|
||||||
key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDjO4ZEQxOZk0IZ1JgRP0AsO6/mIxSB8lojjq+dX2oIH8VTS2UxnwsrKx0DMn+qomUWk4HuYwRwPpWjP68+C+t3hqehhXpdM83YE+favA/VEtbTJnLVf0dq3RPzxuvtYsfpaiYF8/ctEaLAiXIgcpIAf0jOv7FTNADUBLhsV1KbpWneJqKquqroE1e6lCPoU968yWeZkzxCx8VpQ7uBDktJTosLNsm7wEtiKmlSdVE0cYUrNS+/VIoNE2Fr5xjqOlZHFhM5BBlUqqiVxWSpGizr+CGq+xhuOByGtqLgnmvju8oG2KkYhN/5LTMCRtpTwgRmjdU6oA7a8psFyu16iMpupmhPTc0aT3F7X5fiCWOiYDF0VvYNLVYRXzqm9UOy5OI3fCFnvERaheiNEm484OgWm/kUqHQWqlN30Tk9POY022QsDAVKPMCG3kSsAeM1LFsZE1fsleG31g5yicLqgQbw/v2fqGvklT0z5D2uXXuUEqM0aBNSysLWYvChGTfUZtk= john@arecibo
|
|
||||||
|
|
||||||
|
|
||||||
- name: grant {{ newusername }} passwordless sudo access
|
|
||||||
ansible.builtin.lineinfile:
|
|
||||||
path: /etc/sudoers
|
|
||||||
regexp: '^%sudo'
|
|
||||||
line: "%sudo ALL=(ALL:ALL) NOPASSWD: ALL"
|
|
||||||
validate: 'visudo -cf %s'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
---
|
|
||||||
- name: Lock down root & SSH on the server
|
|
||||||
hosts: UpskillChallengeNode
|
|
||||||
gather_facts: no
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Disable root login over ssh
|
|
||||||
ansible.builtin.lineinfile:
|
|
||||||
path: /etc/ssh/sshd_config
|
|
||||||
regexp: '^PermitRootLogin'
|
|
||||||
line: 'PermitRootLogin no'
|
|
||||||
|
|
||||||
- name: Disable all users' password login
|
|
||||||
ansible.builtin.lineinfile:
|
|
||||||
path: /etc/ssh/sshd_config
|
|
||||||
regexp: '^PasswordAuthentication'
|
|
||||||
line: 'PasswordAuthentication no'
|
|
||||||
|
|
||||||
- name: Change SSH port
|
|
||||||
ansible.builtin.lineinfile:
|
|
||||||
path: /etc/ssh/sshd_config
|
|
||||||
regexp: '^#?Port '
|
|
||||||
line: 'Port 22022'
|
|
||||||
|
|
||||||
- name: update and upgrade packages
|
|
||||||
ansible.builtin.apt:
|
|
||||||
update_cache: yes
|
|
||||||
upgrade: yes
|
|
||||||
|
|
||||||
- name: install fail2ban
|
|
||||||
ansible.builtin.apt:
|
|
||||||
package: fail2ban
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: restart ssh
|
|
||||||
service:
|
|
||||||
name: ssh
|
|
||||||
state: restarted
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Returns a non-zero exit code on purpose to test the day 2 error prompt.
|
|
||||||
|
|
||||||
exit 42
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ -z ""]
|
|
||||||
then
|
|
||||||
LABEL="UpskillChallengeNode"
|
|
||||||
fi
|
|
||||||
|
|
||||||
NODESTATE="indeterminate"
|
|
||||||
while [ "$NODESTATE" != "running" ]
|
|
||||||
do
|
|
||||||
OLDSTATE=$NODESTATE
|
|
||||||
NODESTATE=$(linode-cli linodes list --format 'status' --label "$LABEL" --text | tail -n 1)
|
|
||||||
if [ "$NODESTATE" = "status" ]
|
|
||||||
then
|
|
||||||
echo "No node detected."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$NODESTATE" != "$OLDSTATE" ]
|
|
||||||
then
|
|
||||||
echo "$(date '+%F %T'): $NODESTATE"
|
|
||||||
fi
|
|
||||||
done
|
|
Reference in New Issue