21 Commits

Author SHA1 Message Date
06548bf135 removed giteaUninstall var 2023-02-02 16:04:44 -06:00
feaea47028 gitea: can now backup the database remotely 2023-02-01 23:30:14 -06:00
bf198f9d63 minor typos 2023-02-01 18:01:52 -06:00
af53eb4637 roles/gitea: support giteaUninstall variable 2023-01-21 18:25:02 -06:00
e8fe024b77 roles/git: ssh known_hosts is now idempotent
- roles/git now uses blockinfile to ensure the github ssh keypairs are trusted, and to allow subsequent ssh keypairs to be trusted and not overwritten by future runs.
- this commit marks idempotency for all roles. after a successful run of this playbook, subsequent runs will result in a change=0 !!!!!
2023-01-19 20:50:30 -06:00
3d75ac18e7 roles/gitea: better gitea installation condition 2023-01-19 18:03:49 -06:00
c6ea8eaf38 roles: minor idempotency changes 2023-01-19 18:02:55 -06:00
e3d3ec37fd roles/gitea: installing gitea is now idempotent 2023-01-19 15:11:22 -06:00
2d3fbfe484 removed stale github workflow 2023-01-18 20:36:30 -06:00
5cdc63e35a roles/deadswitch: role is now idempotent 2023-01-18 01:10:40 -06:00
1747125b67 roles/blog: fix updateBlog 2023-01-17 17:52:47 -06:00
41ef83bb4e roles/blog: run updateBlog; now idempotent! 2023-01-17 17:41:25 -06:00
4359544b6a blog: updateBlog now checks for changes before building 2023-01-17 17:32:47 -06:00
ca6fdaeff3 blog: maintain two separate builds of the site; one for tor, one for https 2023-01-16 17:17:07 -06:00
1028023b8b roles/nginx: made idempotent 2023-01-15 21:54:03 -06:00
5e2c4850e1 minor README changes 2023-01-14 17:36:51 -06:00
a971e7d065 github: disabled deploy workflow 2023-01-14 17:31:46 -06:00
abaa4c9639 switched to roles
- all tasks/* have been moved to their own roles in roles/*
- each file && template is now oragnized per-role
- annotated each task which still isn't idempotent !TODO!
2023-01-14 17:26:17 -06:00
d435ab80ac fix: wrong paths in imdead.sh (oops) 2022-10-04 13:13:46 -05:00
bf5763a42f updated to latest secrets 2022-10-04 13:09:36 -05:00
6325e393b3 updated readme 2022-10-04 12:51:54 -05:00
39 changed files with 276 additions and 190 deletions

View File

@@ -1,27 +0,0 @@
name: Run Playbook
on:
push:
tags:
- "v*.*.*"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Set up Git repository
uses: actions/checkout@v3
with:
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
submodules: recursive
- name: Run Ansible-Playbook
uses: dawidd6/action-ansible-playbook@v2
with:
playbook: run.yml
key: ${{ secrets.SSH_PRIVATE_KEY }}
inventory: |
[hosts]
openpunk-vps ansible_host=96.30.199.68 ansible_user=root ansible_connection=ssh
vault_password: ${{ secrets.VAULT_PASSWORD }}
options: |
--extra-vars domain=openpunk.com

1
.gitignore vendored
View File

@@ -1 +1,2 @@
hosts hosts
backups

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"yaml.schemas": {
"https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible.json#/$defs/tasks": "file:///home/cpunch/projects/openpunk-ansible/roles/nginx/tasks/main.yml"
}
}

View File

@@ -1,17 +1,28 @@
# OpenPunk's Ansible playbook # OpenPunk's Ansible playbook
This is my failsafe (and also my helpful migration tool) for restoring the OpenPunk server. This handles setting everything back up, including: This is my failsafe (and also my helpful migration tool) for restoring the OpenPunk server. This handles setting everything back up, including:
- gitea - gitea
- sadly, no db migration is supported right now. maybe a future todo?
- blog - blog
- cron job for grabbing the `HEAD` of https://github.com/CPunch/openpunk && building the hugo site
- tor mirror - tor mirror
- nginx (for the above mentioned) - nginx (for the above mentioned)
- certbot's Let's Encrypt
- my shell theme (zsh + powerlevel10k) - my shell theme (zsh + powerlevel10k)
- deadswitch (& the ssh + git config to allow pushes) - deadswitch (& the ssh + git config to allow pushes)
This playbook assumes the target VPS is running the latest debian stable release. This playbook assumes the target VPS is running the latest debian stable release.
## Notes to my future self ## Notes to my future self
The deadswitch has the deadtrigger setup every run, so you have a 14-day timer to add a one-liner to your crontab to keep that deadtrigger set. Add this to your local machine's crontab:
```sh
ssh openpunk 'touch /root/.deadtrigger'
```
Some DNS records also need to be set:
- an A record with a `git.*` subdomain
## Usage ## Usage
```sh ```sh

View File

@@ -1,2 +1,4 @@
--- ---
domain: openpunk.com
contact_email: openpunk@proton.me contact_email: openpunk@proton.me
onionDomain: http://opnpnk6eutjiqy4ndpyvwxd5pncj2g2cmz6fkocr5uh3omnn4utvspad.onion

View File

@@ -4,17 +4,18 @@
repo: "https://github.com/CPunch/openpunk.git" repo: "https://github.com/CPunch/openpunk.git"
dest: "/var/www/{{ domain }}" dest: "/var/www/{{ domain }}"
- name: Build blog
command:
cmd: hugo
chdir: "/var/www/{{ domain }}"
- name: Install updateBlog script - name: Install updateBlog script
template: template:
src: templates/blog/updateBlog src: templates/updateBlog
dest: /usr/local/bin/updateBlog dest: /usr/local/bin/updateBlog
mode: u+rx mode: u+rx
- name: Build blog
command:
cmd: updateBlog
register: blog_out
changed_when: blog_out.stdout != "up to date"
# Rebuild blog every hour # Rebuild blog every hour
- name: Setup blog cron job - name: Setup blog cron job
cron: cron:

View File

@@ -0,0 +1,32 @@
#!/bin/bash
cd /var/www/{{ domain }}
PUBLIC_DIR=public
TOR_DIR=tor
buildBlog () {
hugo --cleanDestinationDir --minify -d $PUBLIC_DIR -b https://{{ domain }}
hugo --cleanDestinationDir --minify -d $TOR_DIR -b {{ onionDomain }}
}
git fetch origin
UPSTREAM=${1:-'@{u}'}
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse "$UPSTREAM")
BASE=$(git merge-base @ "$UPSTREAM")
if [ $LOCAL = $REMOTE ]; then
# this string is hardcoded && checked by the 'Build blog' task
# to check for changes (changed_when)
echo "up to date"
elif [ $LOCAL = $BASE ]; then
# there are changes to reset to so we need to rebuild
echo "missing changes !!"
git reset --hard origin/main
buildBlog
fi
if [ ! -d "$PUBLIC_DIR" ] || [ ! -d "$TOR_DIR" ]; then
# probably first time setup
echo "missing directories !!"
buildBlog
fi

View File

@@ -22,5 +22,5 @@ echo $dTime
if [ $dTime -gt $triggerTime ] if [ $dTime -gt $triggerTime ]
then then
touch $fileLock touch $fileLock
bash $scriptToRun source $scriptToRun
fi fi

View File

@@ -1,8 +1,7 @@
#!/bin/bash #!/bin/bash
cd $HOME/deadman cd $HOME/deadman
postPatch='../dead.patch' postPatch='dead.patch'
pageName='content/pages/dead.md' pageName='content/pages/dead.md'
currDate=$(date '+%Y-%m-%d') currDate=$(date '+%Y-%m-%d')
@@ -10,9 +9,11 @@ git clone git@github.com:CPunch/openpunk.git
# commit & push the post # commit & push the post
cd openpunk cd openpunk
git am postPatch git am $postPatch
# replace our --DATE-- with the current date # replace our --DATE-- with the current date
sed -i 's/--DATE--/'$currDate'/g' $pageName sed -i 's/--DATE--/'$currDate'/g' $pageName
git add . git add .
git commit -m "DeadSwitch: No response from CPunch in 14 days, posting dead.md" git commit -m "DeadSwitch: No response from CPunch in 14 days, posting dead.md"
git push --force git push --force
updateBlog

View File

@@ -6,13 +6,13 @@
- name: Install deadswitch script - name: Install deadswitch script
copy: copy:
src: static/blog/deadswitch src: deadswitch
dest: /usr/local/bin/deadswitch dest: /usr/local/bin/deadswitch
mode: u+rx mode: u+rx
- name: Install imdead.sh - name: Install imdead.sh
copy: copy:
src: static/blog/imdead.sh src: imdead.sh
dest: /root/deadman/imdead.sh dest: /root/deadman/imdead.sh
mode: u+rx mode: u+rx
@@ -22,10 +22,17 @@
dest: /root/deadman/dead.patch dest: /root/deadman/dead.patch
mode: u+rw mode: u+rw
# TODO: deadtrigger path should be a variable, no?
- name: Check deadtrigger
stat:
path: /root/.deadtrigger
register: deadstat
- name: Install deadtrigger - name: Install deadtrigger
file: file:
name: /root/.deadtrigger path: /root/.deadtrigger
state: touch state: touch
when: deadstat.stat.exists == false
# Run deadswitch daily at 1am # Run deadswitch daily at 1am
- name: Install deadlock cronjob - name: Install deadlock cronjob

View File

@@ -0,0 +1,36 @@
---
- name: Upgrade Packages
apt:
update_cache: yes
upgrade: full
- name: Install required software
package:
name:
- hugo
- git
- nginx
- tor
- ufw
- fail2ban
- goaccess
- htop
- zsh # :D
- python3-certbot-nginx
- name: Setup zsh
user:
name: "{{ ansible_user }}"
shell: /usr/bin/zsh
- name: Clone Powerlevel10k theme
git:
repo: "https://github.com/romkatv/powerlevel10k.git"
dest: "/root/powerlevel10k"
depth: 1
- name: Install .zshrc
copy:
src: .zshrc
dest: /root/.zshrc
force: no

View File

@@ -23,7 +23,7 @@
- name: Copy fail2ban jail config - name: Copy fail2ban jail config
copy: copy:
src: static/fail2ban/jails.local src: jails.local
dest: /etc/fail2ban/jail.d/jails.local dest: /etc/fail2ban/jail.d/jails.local
- name: Enable fail2ban service - name: Enable fail2ban service

View File

@@ -1,7 +1,7 @@
--- ---
- name: Setup git config - name: Setup git config
copy: copy:
src: static/.gitconfig src: .gitconfig
dest: /root/.gitconfig dest: /root/.gitconfig
owner: root owner: root
mode: u=rw,g=,o= mode: u=rw,g=,o=
@@ -12,17 +12,19 @@
- name: Scan for SSH host keys - name: Scan for SSH host keys
command: ssh-keyscan github.com 2>/dev/null command: ssh-keyscan github.com 2>/dev/null
register: ssh_scan register: ssh_scan
changed_when: false
- name: Update known_hosts - name: Update .ssh/known_hosts
copy: blockinfile:
content: "{{ ssh_scan.stdout_lines|join('\n') }}" path: /root/.ssh/known_hosts
dest: /root/.ssh/known_hosts block: "{{ ssh_scan.stdout_lines|join('\n') }}"
insertbefore: BOF
create: yes
owner: root owner: root
mode: u=rw,g=,o= mode: u=rw,g=,o=
force: no # if we already have a known_hosts file, ignore!
# this keypair is trusted under my github account, so it allows my vps to make pushes # this keypair is trusted under my github account, so it allows my vps to make pushes
# to the main branch of my openpunk repository. (for my deadswitch: see static/blog/imdead.sh) # to the main branch of my openpunk repository. (see roles/deadswitch/files/imdead.sh)
- name: Install ssh priv key - name: Install ssh priv key
copy: copy:

View File

@@ -0,0 +1,2 @@
---
giteaPort: 3000

View File

@@ -0,0 +1,26 @@
---
- name: Stop Gitea
systemd:
name: gitea
enabled: yes
state: stopped
- name: Dump Gitea
shell:
cmd: gitea dump -c /etc/gitea/app.ini --work-path=/etc/gitea --file=gitea-dump.zip
chdir: /etc/gitea
become: true
become_method: su
become_user: gitea
- name: Start Gitea
systemd:
name: gitea
enabled: yes
state: started
- name: Fetch backup
fetch:
src: /etc/gitea/gitea-dump.zip
dest: backups/gitea-dump.zip
flat: true

View File

@@ -0,0 +1,45 @@
---
- name: Check for Gitea gpg key
stat:
path: /etc/apt/trusted.gpg.d/morph027-gitea.gpg
register: gitea_key
- name: Grab package facts
package_facts:
manager: auto
- name: Install Gitea
block:
- name: Add Gitea key, repository && install
block:
- name: Import Gitea key
shell: curl -s https://packaging.gitlab.io/gitea/gpg.key | sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/morph027-gitea.gpg --import && sudo chmod 644 /etc/apt/trusted.gpg.d/morph027-gitea.gpg
when: gitea_key.stat.exists == false or gitea_key.stat.mode != "0644"
- name: Add Gitea repository
apt_repository:
filename: morph027-gitea
repo: deb https://packaging.gitlab.io/gitea gitea main
- name: Add Gitea package
package:
name: gitea
when: "'gitea' not in ansible_facts.packages"
- name: Configure Gitea
template:
src: templates/app.ini
dest: /etc/gitea/app.ini
owner: gitea
force: no # we don't want to kill our existing config D:
- name: Reload Gitea
systemd:
name: gitea
enabled: yes
state: started
- name: Backup db
include_tasks: backup.yml
tags: ['never', 'backup']
tags: ['gitea', 'backup']

View File

View File

@@ -18,7 +18,7 @@ ROOT = /var/lib/gitea/gitea-repositories
[server] [server]
SSH_DOMAIN = git.{{ domain }} SSH_DOMAIN = git.{{ domain }}
DOMAIN = git.{{ domain }} DOMAIN = git.{{ domain }}
HTTP_PORT = 3000 HTTP_PORT = {{ giteaPort }}
ROOT_URL = https://git.{{ domain }}/ ROOT_URL = https://git.{{ domain }}/
DISABLE_SSH = false DISABLE_SSH = false
SSH_PORT = 22 SSH_PORT = 22

View File

@@ -1,5 +1,5 @@
--- ---
- name: Copy goaccess config - name: Copy goaccess config
copy: copy:
src: static/goaccess/goaccess.conf src: goaccess.conf
dest: /etc/goaccess/goaccess.conf dest: /etc/goaccess/goaccess.conf

View File

@@ -0,0 +1,2 @@
---
giteaPort: 3000

View File

@@ -0,0 +1,4 @@
---
- name: setup-nginx
include_tasks: setup.yml
listen: "setup nginx"

View File

@@ -0,0 +1,41 @@
---
- name: Install system nginx config
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: setup nginx
# setup our configs for each host (we don't want to
# overwrite certbot's changes, so if it already exists,
# don't copy!)
- name: Install nginx config for {{ domain }}
template:
src: templates/site.conf
dest: /etc/nginx/conf.d/{{ domain }}.conf
force: no
notify: setup nginx
- name: Install nginx config for git.{{ domain }}
template:
src: templates/gitea.conf
dest: /etc/nginx/conf.d/git.{{ domain }}.conf
force: no
notify: setup nginx
- name: Uninstall nginx config for git.{{ domain }}
file:
path: /etc/nginx/conf.d/git.{{ domain }}.conf
state: absent
notify: setup nginx
- name: Install nginx config for our Hidden Service
template:
src: templates/tor.conf
dest: /etc/nginx/conf.d/tor-{{ domain }}.conf
- name: Enable Nginx
systemd:
name: nginx
enabled: yes
state: started

View File

@@ -0,0 +1,12 @@
---
- name: Setup certbot for {{ domain }}
shell: "certbot --nginx --non-interactive --agree-tos -m {{ contact_email }} -d {{ domain }}"
- name: Setup certbot for git.{{ domain }}
shell: "certbot --nginx --non-interactive --agree-tos -m {{ contact_email }} -d git.{{ domain }}"
- name: Reload Nginx
systemd:
name: nginx
enabled: yes
state: restarted

View File

@@ -4,7 +4,7 @@ server {
location / { location / {
add_header Permissions-Policy interest-cohort=(); add_header Permissions-Policy interest-cohort=();
proxy_pass http://localhost:3000; proxy_pass http://localhost:{{ giteaPort }};
} }
client_max_body_size 100M; client_max_body_size 100M;

View File

@@ -1,5 +1,5 @@
server { server {
root /var/www/{{ domain }}/public; root /var/www/{{ domain }}/tor;
index index.html index.htm; index index.html index.htm;
location / { location / {

View File

@@ -1,7 +1,7 @@
--- ---
- name: Install torrc - name: Install torrc
template: template:
src: templates/tor/torrc src: templates/torrc
dest: /etc/tor/torrc dest: /etc/tor/torrc
owner: root owner: root
group: root group: root
@@ -23,7 +23,7 @@
group: debian-tor group: debian-tor
mode: u=rw,g=,o= mode: u=rw,g=,o=
- name: Reload Tor - name: Enable Tor Service
systemd: systemd:
name: tor name: tor
enabled: yes enabled: yes

29
run.yml
View File

@@ -1,21 +1,20 @@
--- ---
- hosts: all - hosts: all
become: yes become: yes
vars:
- giteaPort: 3000
vars_files: vars_files:
- group_vars/all.yml - group_vars/all.yml
vars_prompt: roles:
- name: domain - role: essential
prompt: domain pointing to the vps - role: firewall
private: no - role: git
- role: deadswitch
tasks: - role: blog
- import_tasks: tasks/essential.yml - role: gitea
- import_tasks: tasks/firewall.yml tags: [backup]
- import_tasks: tasks/blog.yml - role: nginx
- import_tasks: tasks/gitea.yml - role: goaccess
- import_tasks: tasks/tor.yml - role: tor
- import_tasks: tasks/nginx.yml
- import_tasks: tasks/git.yml
- import_tasks: tasks/goaccess.yml
- import_tasks: tasks/deadswitch.yml

Submodule secrets updated: d71665b85e...e643deb62e

View File

@@ -1,46 +0,0 @@
---
- name: Add Gitea repo key
shell: curl -s https://packaging.gitlab.io/gitea/gpg.key | sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/morph027-gitea.gpg --import
- name: Set key perms
shell: sudo chmod 644 /etc/apt/trusted.gpg.d/morph027-gitea.gpg
- name: Add Gitea repo
apt_repository:
filename: morph027-gitea
repo: deb https://packaging.gitlab.io/gitea gitea main
- name: Upgrade Packages
apt:
update_cache: yes
upgrade: full
- name: Install required software
package:
name:
- hugo
- gitea
- git
- nginx
- tor
- ufw
- fail2ban
- goaccess
- htop
- zsh # :D
- python3-certbot-nginx
- name: Setup default shell (zsh)
shell: chsh -s /usr/bin/zsh
- name: Clone Powerlevel10k theme
git:
repo: "https://github.com/romkatv/powerlevel10k.git"
dest: "/root/powerlevel10k"
depth: 1
- name: Install .zshrc
copy:
src: static/.zshrc
dest: /root/.zshrc
force: no

View File

@@ -1,13 +0,0 @@
---
- name: Configure Gitea
template:
src: templates/gitea/app.ini
dest: /etc/gitea/app.ini
owner: gitea
force: no # we don't want to kill our existing config D:
- name: Reload Gitea
systemd:
name: gitea
enabled: yes
state: started

View File

@@ -1,52 +0,0 @@
---
- name: Remove default nginx config
file:
name: /etc/nginx/sites-enabled
state: absent
- name: Restore sites-enabled
file:
name: /etc/nginx/sites-enabled
state: directory
- name: Install system nginx config
copy:
src: static/nginx/nginx.conf
dest: /etc/nginx/nginx.conf
# setup our configs for each host (we don't want to
# overwrite certbot's changes, so if it already exists,
# don't copy!)
- name: Install nginx config for {{ domain }}
template:
src: templates/nginx/site.conf
dest: /etc/nginx/conf.d/{{ domain }}.conf
force: no
- name: Install nginx config for git.{{ domain }}
template:
src: templates/nginx/gitea.conf
dest: /etc/nginx/conf.d/git.{{ domain }}.conf
force: no
- name: Install nginx config for our Hidden Service
template:
src: templates/nginx/tor.conf
dest: /etc/nginx/conf.d/tor-{{ domain }}.conf
force: no
- name: Reload Nginx to install LetsEncrypt
service:
name: nginx
state: restarted
# certbot is a life saver. thank you certbot devs!
- name: Setup certbot
shell: "certbot --nginx --non-interactive --agree-tos -m {{ contact_email }} -d {{ domain }} -d git.{{ domain }}"
- name: Reload Nginx with LetsEncrypt installed
systemd:
name: nginx
enabled: yes
state: restarted

View File

@@ -1,5 +0,0 @@
#!/bin/bash
cd /var/www/{{ domain }}
/usr/bin/git fetch origin
/usr/bin/git reset --hard origin/main
/usr/bin/hugo