commit 1d8356088642f7d2ed4943c77bbaf0713e497b47 Author: Kuba Orlik Date: Wed Mar 17 17:54:36 2021 +0100 Initial commit diff --git a/HOW_TO_RUN.md b/HOW_TO_RUN.md new file mode 100644 index 0000000..eeea1f8 --- /dev/null +++ b/HOW_TO_RUN.md @@ -0,0 +1,3 @@ +pass init your-gpg-id + +ansible-playbook -i '157.90.240.248,rpi' backup.yml diff --git a/backup.yml b/backup.yml new file mode 100644 index 0000000..05b05f5 --- /dev/null +++ b/backup.yml @@ -0,0 +1,178 @@ +--- +- hosts: remote_server:rpi + tasks: + - set_fact: RPI_NAME=kuba-rpi + - set_fact: SERVER_NAME=my-server + - set_fact: SERVER_FQDN=my.example.com + - set_fact: OVPN_IP_PREFIX=10.8.10 + - set_fact: RPI_BACKUP_DIR=/mnt/hdd/Backups + +- hosts: remote_server + become: yes + become_user: root + # become_method: su + + vars: + TO_INSTALL: + - openvpn + - restic + - ufw + + tasks: + # - include_vars: secrets.yml + + - name: install required packages + apt: state=present pkg={{ TO_INSTALL }} + + - name: create ovpn key + ansible.builtin.command: "openvpn --genkey --secret {{RPI_NAME}}.key" + args: + chdir: /etc/openvpn/server + creates: /etc/openvpn/server/{{RPI_NAME}}.key + + - name: Copy /etc/openvpn/server/{{RPI_NAME}}.key to /tmp/{{RPI_NAME}}.key + ansible.builtin.fetch: + src: /etc/openvpn/server/{{RPI_NAME}}.key + dest: /tmp/{{RPI_NAME}}.key + flat: yes + + - name: Create ovpn config + ansible.builtin.template: + src: "ovpn-server.conf.j2" + dest: /etc/openvpn/server/{{RPI_NAME}}.conf + + - name: open ovpn port (tcp) + ufw: rule=allow port=1194 proto=tcp + + - name: open ovpn port (udp) + ufw: rule=allow port=1194 proto=udp + + - name: start ovpn server + ansible.builtin.service: + name: openvpn-server@{{RPI_NAME}} + state: restarted + enabled: yes + + - name: rpi in /etc/hosts + ansible.builtin.lineinfile: + path: /etc/hosts + regexp: "rpi$" + line: "{{OVPN_IP_PREFIX}}.2 {{RPI_NAME}}" + owner: root + group: root + mode: "0644" + + - name: generate ssh key + ansible.builtin.command: 'ssh-keygen -t ed25519 -b 4096 -C "{{RPI_NAME}}-backup" -f /root/.ssh/{{RPI_NAME}}-backup -N ""' + args: + creates: "/root/.ssh/{{RPI_NAME}}-backup" + + - name: Create ssh config for rpi + blockinfile: + path: /root/.ssh/config + backup: yes + create: yes + block: | + Host {{RPI_NAME}} + User {{SERVER_NAME}}-backup + IdentityFile /root/.ssh/{{RPI_NAME}}-backup + + - name: download the public key of the server + ansible.builtin.fetch: + src: /root/.ssh/{{RPI_NAME}}-backup.pub + dest: /tmp/{{RPI_NAME}}-backup.pub + flat: yes + - name: create backup password + ansible.builtin.command: dd if=/dev/urandom of=/backup-pwd bs=1 count=52 + args: + creates: /backup-pwd + + - shell: base64 < /backup-pwd + register: shell_result + + - debug: msg="{{shell_result.stdout_lines}}" + + - name: Remind to backup the key + pause: + prompt: ZAPISZ TEN KLUCZ W MANADŻERZE HASEŁ ☝ i wciśnij ENTER + + # - name: initiate restic reposiotory + # command: restic init --password-file=/backup-pwd -r sftp:{{SERVER_NAME}}-backup@{{RPI_NAME}}:data + # run_once: true + - name: Create the backup script + ansible.builtin.template: + src: "backup.sh.j2" + dest: /root/backup.sh + mode: u+rwx + backup: yes + + - name: setup CRON + ansible.builtin.cron: + name: "nightly backup for {{SERVER_NAME}}_{{RPI_NAME}}" + minute: 15 + hour: 4 + job: "/root/backup.sh" + +- hosts: rpi + become: yes + become_user: root + + tasks: + - name: Upload /tmp/{{RPI_NAME}}.key to rpi:/etc/openvpn/client/{{SERVER_NAME}}.key + ansible.builtin.copy: + src: /tmp/{{RPI_NAME}}.key + dest: /etc/openvpn/client/{{SERVER_NAME}}.key + - name: Create ovpn config + ansible.builtin.template: + src: "ovpn-client.conf.j2" + dest: /etc/openvpn/client/{{SERVER_NAME}}.conf + - name: start ovpn client + ansible.builtin.service: + name: openvpn-client@{{SERVER_NAME}} + state: restarted + enabled: yes + - name: Add the backup user + ansible.builtin.user: + name: "{{SERVER_NAME}}-backup" + + - name: set permissions on backup dir + file: + path: "{{RPI_BACKUP_DIR}}/{{SERVER_NAME}}-backup" + owner: root + group: root + mode: 0755 + state: directory + - name: set permissions on backup data dir + file: + path: "{{RPI_BACKUP_DIR}}/{{SERVER_NAME}}-backup/data" + owner: "{{SERVER_NAME}}-backup" + group: "{{SERVER_NAME}}-backup" + mode: 0755 + state: directory + - name: auth the backup user with the public key + ansible.builtin.lineinfile: + path: /home/{{SERVER_NAME}}-backup/.ssh/authorized_keys + line: "{{lookup('file', '/tmp/{{RPI_NAME}}-backup.pub')}}" + owner: "{{SERVER_NAME}}-backup" + group: "{{SERVER_NAME}}-backup" + mode: "0600" + create: yes + - name: Create ssh config for the backup user + blockinfile: + path: /etc/ssh/sshd_config + backup: yes + create: yes + block: | + Match User {{SERVER_NAME}}-backup + ForceCommand internal-sftp + PasswordAuthentication yes + ChrootDirectory {{RPI_BACKUP_DIR}}/{{SERVER_NAME}}-backup + PermitTunnel no + AllowAgentForwarding no + AllowTcpForwarding no + X11Forwarding no + - name: restart sshd + ansible.builtin.service: + name: ssh + state: restarted + enabled: yes diff --git a/templates/backup.sh.j2 b/templates/backup.sh.j2 new file mode 100644 index 0000000..ab9f389 --- /dev/null +++ b/templates/backup.sh.j2 @@ -0,0 +1,30 @@ +#!/bin/bash + +REPO=sftp:{{SERVER_NAME}}-backup@{{RPI_NAME}}:data +PWD_FILE=/backup-pwd +RESTIC=/usr/bin/restic + +echo "Removing current backups..." +rm -fr /backup/* + +mkdir -p /backup + +####### Prepare data + +# tutaj wpychamy dane do zbackupowania do /backup. +# nie musimy ich tu wpychać, jeżeli po prostu są na dysku - wystarczy podać je jako argument do pierwszej komendy w sekcji "Send Backups". +# do /backup najlepiej wgrać artefakty, które nie są aktualnie w backupowalnej postaci na dysku, np. dumpy mysql + +# przykłady skryptów backupujących dodałem na końcu, w sekcji "bonusy" + +###### Send backups + +echo "Sending the backup to the destination..." + +# podaj tutaj listę katalogów do zbackupowania. Warto backupować katalog `/etc`. +$RESTIC -r "$REPO" --password-file=$PWD_FILE backup /backup /etc /var/phabricator-files /etc/nginx/sites # ... + inne pliki / katalogi + +echo "Pruning the backup on the destination..." +# poniższa konfiguracja będzie trzymała backupy z każdego z pięciu ostatnich dni, po jednym backupie dla każdego z ostatnich 10 tygodni, po jednym dla ostatnich 12 miesięcy i po jednym dla ostatnich 100 lat. + +$RESTIC -r "$REPO" --password-file=$PWD_FILE forget --prune --keep-daily 5 --keep-weekly 10 --keep-monthly 12 --keep-yearly 100 diff --git a/templates/ovpn-client.conf.j2 b/templates/ovpn-client.conf.j2 new file mode 100644 index 0000000..479ed02 --- /dev/null +++ b/templates/ovpn-client.conf.j2 @@ -0,0 +1,9 @@ +remote {{SERVER_FQDN}} +dev tun +ifconfig {{OVPN_IP_PREFIX}}.2 {{OVPN_IP_PREFIX}}.1 +secret {{SERVER_NAME}}.key +keepalive 10 60 +ping-timer-rem +persist-tun +persist-key +log-append /var/log/openvpn-{{SERVER_NAME}}.log diff --git a/templates/ovpn-server.conf.j2 b/templates/ovpn-server.conf.j2 new file mode 100644 index 0000000..55bc9f1 --- /dev/null +++ b/templates/ovpn-server.conf.j2 @@ -0,0 +1,8 @@ +dev tun +ifconfig {{OVPN_IP_PREFIX}}.1 {{OVPN_IP_PREFIX}}.2 +secret {{RPI_NAME}}.key +keepalive 10 60 +ping-timer-rem +persist-tun +persist-key +log-append /var/log/openvpn-{{RPI_NAME}}.log diff --git a/templates/server-ssh-config.j2 b/templates/server-ssh-config.j2 new file mode 100644 index 0000000..f046de3 --- /dev/null +++ b/templates/server-ssh-config.j2 @@ -0,0 +1,3 @@ +Host {{RPI_NAME}} + User {{SERVER_NAME}}-backup + IdentityFile /root/.ssh/{{RPI_NAME}}-backup