init: clean history with no PII
Toto repo ma novou cistou historii (1 commit). Predchozi historie byla smazana, protoze obsahovala osobni udaje (IP, emaily, hesla, klice, tokeny, Volume cesty). Soubory v aktualnim commit uz tyto udaje neobsahuji (nahradeno placeholdery <server-ip>, CHANGE_ME, admin@example.com atd.). Pokud chces zpet kompletni seznam starych commitu, mas je ve svem lokalnim working tree - git log --all ukaze prazdno (protoze jsme smazali .git/ a zacali znovu).
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
|||||||
|
# Secrets - nikdy v gitu
|
||||||
|
.env
|
||||||
|
*.env
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Zálohy a dočasné soubory
|
||||||
|
*.bak
|
||||||
|
*.tmp
|
||||||
|
*.orig
|
||||||
|
|
||||||
|
# Editor
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# Build artefakty
|
||||||
|
*.log
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 mates
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# mates-ansible
|
||||||
|
|
||||||
|
Ansible playbooky pro nasazení a správu home infrastruktury.
|
||||||
|
Vychází z tvých existujících setupů v `/home/mates/docker/`.
|
||||||
|
|
||||||
|
## Struktura
|
||||||
|
|
||||||
|
```
|
||||||
|
playbooks/
|
||||||
|
├── bootstrap-server.yml # Úvodní setup serveru (deploy user, SSH, UFW, fail2ban)
|
||||||
|
├── deploy-services.yml # Nasaď Docker služby
|
||||||
|
├── update-services.yml # Update všech služeb
|
||||||
|
└── security-hardening.yml # Sysctl, auditd, auto-updates
|
||||||
|
```
|
||||||
|
|
||||||
|
## Detailní návody
|
||||||
|
|
||||||
|
Všechny playbooky mají komentáře v češtině. Detailní postupy najdeš v Jotty knowledge base.
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
|
||||||
|
MIT – viz [LICENSE](LICENSE)
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = inventory.yml
|
||||||
|
roles_path = roles
|
||||||
|
host_key_checking = False
|
||||||
|
retry_files_enabled = False
|
||||||
|
stdout_callback = yaml
|
||||||
|
forks = 10
|
||||||
|
gathering = smart
|
||||||
|
fact_caching = jsonfile
|
||||||
|
fact_caching_connection = local
|
||||||
|
fact_caching_timeout = 86400
|
||||||
|
|
||||||
|
[privilege_escalation]
|
||||||
|
become = True
|
||||||
|
become_method = sudo
|
||||||
|
become_ask_pass = False
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
pipelining = True
|
||||||
|
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o ServerAliveInterval=30
|
||||||
|
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
# Spolecne promenne pro vsechny playbooky
|
||||||
|
# Zkopiruj na group_vars/all.yml a dopln
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
docker_user: deploy
|
||||||
|
docker_uid: 1000
|
||||||
|
docker_gid: 1000
|
||||||
|
docker_install_compose_plugin: true
|
||||||
|
|
||||||
|
# Sluzby k nasazeni (seznam nazvu adresaru v docker-services/)
|
||||||
|
services_to_deploy:
|
||||||
|
- portainer
|
||||||
|
- nginx-proxy-manager
|
||||||
|
- vaultwarden
|
||||||
|
- gitea
|
||||||
|
- jotty
|
||||||
|
- nextcloud-aio
|
||||||
|
- rustdesk
|
||||||
|
- audiobookshelf
|
||||||
|
- calibre-web
|
||||||
|
- plex
|
||||||
|
- erugo
|
||||||
|
- jswiki
|
||||||
|
- speedtest
|
||||||
|
- watchtower
|
||||||
|
|
||||||
|
# NPM admin (po prvnim loginu zmenit)
|
||||||
|
npm_default_email: admin@example.com
|
||||||
|
npm_default_password: changeme
|
||||||
|
|
||||||
|
# Gitea admin (po instalaci)
|
||||||
|
gitea_admin_user: admin
|
||||||
|
gitea_admin_password: changeme
|
||||||
|
gitea_admin_email: admin@example.com
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
# Ukazkovy inventory – zkopiruj na inventory.yml a uprav
|
||||||
|
all:
|
||||||
|
vars:
|
||||||
|
# SSH uzivatel (deploy user, UID 1000)
|
||||||
|
ansible_user: deploy
|
||||||
|
# Python na cilovem systemu
|
||||||
|
ansible_python_interpreter: /usr/bin/python3
|
||||||
|
# Timezone
|
||||||
|
timezone: Europe/Prague
|
||||||
|
|
||||||
|
children:
|
||||||
|
# Skupina pro vsechny home servery
|
||||||
|
homeservers:
|
||||||
|
hosts:
|
||||||
|
homeserver-01:
|
||||||
|
ansible_host: <server-ip>
|
||||||
|
# homeserver-02:
|
||||||
|
# ansible_host: <server-ip-2>
|
||||||
|
|
||||||
|
# Skupina pro produkcni servery
|
||||||
|
production:
|
||||||
|
hosts:
|
||||||
|
homeserver-01:
|
||||||
|
ansible_host: <server-ip>
|
||||||
|
|
||||||
|
# Skupina pro test
|
||||||
|
staging: []
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
---
|
||||||
|
# Bootstrap noveho Ubuntu serveru
|
||||||
|
# - aktualizace systemu
|
||||||
|
# - deploy user (UID 1000)
|
||||||
|
# - SSH hardening
|
||||||
|
# - UFW firewall
|
||||||
|
# - fail2ban
|
||||||
|
# - Docker
|
||||||
|
#
|
||||||
|
# Pouziti:
|
||||||
|
# ansible-playbook -i inventory.yml playbooks/bootstrap-server.yml
|
||||||
|
#
|
||||||
|
- name: Bootstrap home server
|
||||||
|
hosts: homeservers
|
||||||
|
become: true
|
||||||
|
gather_facts: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
deploy_user: deploy
|
||||||
|
deploy_uid: 1000
|
||||||
|
ssh_port: 22
|
||||||
|
# Verejny klic pro deploy uzivatele (nastav pred spustenim)
|
||||||
|
# deploy_ssh_key: "ssh-ed25519 AAAAC3Nz... hermes@mac"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Update apt cache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
cache_valid_time: 3600
|
||||||
|
|
||||||
|
- name: Upgrade vsech baliku
|
||||||
|
ansible.builtin.apt:
|
||||||
|
upgrade: dist
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Instalace zakladnich baliku
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- curl
|
||||||
|
- wget
|
||||||
|
- git
|
||||||
|
- vim
|
||||||
|
- htop
|
||||||
|
- ca-certificates
|
||||||
|
- gnupg
|
||||||
|
- ufw
|
||||||
|
- fail2ban
|
||||||
|
- bash-completion
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Nastav timezone
|
||||||
|
community.general.timezone:
|
||||||
|
name: "{{ timezone }}"
|
||||||
|
|
||||||
|
- name: Vytvor deploy uzivatele
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ deploy_user }}"
|
||||||
|
uid: "{{ deploy_uid }}"
|
||||||
|
shell: /bin/bash
|
||||||
|
create_home: true
|
||||||
|
password: ""
|
||||||
|
|
||||||
|
- name: Nastav SSH klic pro deploy uzivatele
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ deploy_user }}"
|
||||||
|
state: present
|
||||||
|
key: "{{ deploy_ssh_key }}"
|
||||||
|
when: deploy_ssh_key is defined
|
||||||
|
|
||||||
|
- name: Povol deploy uzivateli sudo bez hesla
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: "/etc/sudoers.d/{{ deploy_user }}"
|
||||||
|
content: "{{ deploy_user }} ALL=(ALL) NOPASSWD:ALL\n"
|
||||||
|
mode: "0440"
|
||||||
|
|
||||||
|
- name: SSH hardening
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: "^#?{{ item.key }}"
|
||||||
|
line: "{{ item.key }} {{ item.value }}"
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
- { key: "Port", value: "{{ ssh_port }}" }
|
||||||
|
- { key: "PermitRootLogin", value: "no" }
|
||||||
|
- { key: "PasswordAuthentication", value: "no" }
|
||||||
|
- { key: "X11Forwarding", value: "no" }
|
||||||
|
- { key: "ClientAliveInterval", value: "300" }
|
||||||
|
- { key: "ClientAliveCountMax", value: "2" }
|
||||||
|
notify: Restart ssh
|
||||||
|
|
||||||
|
- name: UFW vychozi pravidla
|
||||||
|
community.general.ufw:
|
||||||
|
direction: incoming
|
||||||
|
policy: deny
|
||||||
|
notify: Reload ufw
|
||||||
|
|
||||||
|
- name: Povol SSH pres UFW
|
||||||
|
community.general.ufw:
|
||||||
|
rule: allow
|
||||||
|
port: "{{ ssh_port }}"
|
||||||
|
proto: tcp
|
||||||
|
|
||||||
|
- name: Povol HTTP a HTTPS
|
||||||
|
community.general.ufw:
|
||||||
|
rule: allow
|
||||||
|
port: "{{ item }}"
|
||||||
|
proto: tcp
|
||||||
|
loop:
|
||||||
|
- "80"
|
||||||
|
- "443"
|
||||||
|
|
||||||
|
- name: Aktivuj UFW
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
|
||||||
|
- name: Konfigurace fail2ban
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: /etc/fail2ban/jail.local
|
||||||
|
content: |
|
||||||
|
[DEFAULT]
|
||||||
|
bantime = 1h
|
||||||
|
findtime = 10m
|
||||||
|
maxretry = 5
|
||||||
|
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = {{ ssh_port }}
|
||||||
|
filter = sshd
|
||||||
|
logpath = /var/log/auth.log
|
||||||
|
maxretry = 3
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart fail2ban
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: Restart ssh
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: sshd
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: Reload ufw
|
||||||
|
community.general.ufw:
|
||||||
|
state: reloaded
|
||||||
|
|
||||||
|
- name: Restart fail2ban
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: fail2ban
|
||||||
|
state: restarted
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
# Nasad Docker sluzby z docker-services/ adresare
|
||||||
|
#
|
||||||
|
# Pouziti:
|
||||||
|
# ansible-playbook -i inventory.yml playbooks/deploy-services.yml
|
||||||
|
# ansible-playbook -i inventory.yml playbooks/deploy-services.yml --extra-vars "services=[portainer,vaultwarden]"
|
||||||
|
#
|
||||||
|
- name: Nasad Docker sluzby
|
||||||
|
hosts: homeservers
|
||||||
|
become: true
|
||||||
|
gather_facts: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
services_repo: https://github.com/mates/mates-docker-services.git
|
||||||
|
services_path: "/home/{{ docker_user }}/docker-services"
|
||||||
|
services: "{{ services_to_deploy | default(['portainer', 'vaultwarden', 'gitea']) }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Klonuj services repo
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: "{{ services_repo }}"
|
||||||
|
dest: "{{ services_path }}"
|
||||||
|
force: false
|
||||||
|
update: true
|
||||||
|
become_user: "{{ docker_user }}"
|
||||||
|
|
||||||
|
- name: Vytvor .env z prikladu (pokud neexistuje)
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ services_path }}/{{ item }}/.env.example"
|
||||||
|
dest: "{{ services_path }}/{{ item }}/.env"
|
||||||
|
remote_src: true
|
||||||
|
force: false
|
||||||
|
loop: "{{ services }}"
|
||||||
|
become_user: "{{ docker_user }}"
|
||||||
|
|
||||||
|
- name: Nasad sluzby
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ services_path }}/{{ item }}"
|
||||||
|
state: present
|
||||||
|
pull: missing
|
||||||
|
loop: "{{ services }}"
|
||||||
|
become_user: "{{ docker_user }}"
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
# Security hardening – sysctl, AppArmor, auditd, auto-updates
|
||||||
|
#
|
||||||
|
# Pouziti:
|
||||||
|
# ansible-playbook -i inventory.yml playbooks/security-hardening.yml
|
||||||
|
#
|
||||||
|
- name: Security hardening
|
||||||
|
hosts: homeservers
|
||||||
|
become: true
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Kernel hardening pres sysctl
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: "{{ item.key }}"
|
||||||
|
value: "{{ item.value }}"
|
||||||
|
state: present
|
||||||
|
reload: true
|
||||||
|
loop:
|
||||||
|
- { key: "net.ipv4.conf.all.rp_filter", value: "1" }
|
||||||
|
- { key: "net.ipv4.conf.default.rp_filter", value: "1" }
|
||||||
|
- { key: "net.ipv4.icmp_echo_ignore_broadcasts", value: "1" }
|
||||||
|
- { key: "net.ipv4.conf.all.accept_redirects", value: "0" }
|
||||||
|
- { key: "net.ipv4.conf.default.accept_redirects", value: "0" }
|
||||||
|
- { key: "net.ipv6.conf.all.accept_redirects", value: "0" }
|
||||||
|
- { key: "net.ipv4.conf.all.send_redirects", value: "0" }
|
||||||
|
- { key: "net.ipv4.conf.all.accept_source_route", value: "0" }
|
||||||
|
- { key: "net.ipv4.conf.default.accept_source_route", value: "0" }
|
||||||
|
- { key: "net.ipv4.tcp_syncookies", value: "1" }
|
||||||
|
- { key: "net.ipv4.conf.all.log_martians", value: "1" }
|
||||||
|
|
||||||
|
- name: Instalace unattended-upgrades
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- unattended-upgrades
|
||||||
|
- apt-listchanges
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Povol automaticke security updaty
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: /etc/apt/apt.conf.d/20auto-upgrades
|
||||||
|
content: |
|
||||||
|
APT::Periodic::Update-Package-Lists "1";
|
||||||
|
APT::Periodic::Unattended-Upgrade "1";
|
||||||
|
APT::Periodic::AutocleanInterval "7";
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Instalace auditd
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- auditd
|
||||||
|
- audispd-plugins
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Aktivuj auditd
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: auditd
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
# Update vsech Docker sluzeb (docker compose pull plus up -d)
|
||||||
|
#
|
||||||
|
# Pouziti:
|
||||||
|
# ansible-playbook -i inventory.yml playbooks/update-services.yml
|
||||||
|
#
|
||||||
|
- name: Update Docker sluzby
|
||||||
|
hosts: homeservers
|
||||||
|
become: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
services_path: "/home/{{ docker_user }}/docker-services"
|
||||||
|
services: "{{ services_to_deploy | default([]) }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Pull a restart sluzeb
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ services_path }}/{{ item }}"
|
||||||
|
state: present
|
||||||
|
pull: always
|
||||||
|
loop: "{{ services }}"
|
||||||
|
become_user: "{{ docker_user }}"
|
||||||
Reference in New Issue
Block a user