first part of config

gitea-rework
Jef Roosens 2021-12-11 16:28:17 +01:00
commit 8ee7c76f64
Signed by: Jef Roosens
GPG Key ID: B580B976584B5F30
30 changed files with 729 additions and 0 deletions

1
.gitignore vendored 100644
View File

@ -0,0 +1 @@
.vagrant/

3
README.md 100644
View File

@ -0,0 +1,3 @@
# Ansible Debian
This repository contains all the Ansible playbooks & roles I use to manage my various Debian-based servers & Docker swarms.

31
Vagrantfile vendored 100644
View File

@ -0,0 +1,31 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "generic/debian11"
# Use the standard insecure SSH key
config.ssh.insert_key = false
# Don't mount the current directory in the VM
config.vm.synced_folder ".", "/vagrant", disabled: true
# config.vm.define "manager" do |m|
# m.vm.network "private_network", ip: "192.168.50.4"
# m.vm.hostname = "manager"
# end
config.vm.define "alpha" do |n|
n.vm.hostname = "alpha.test"
n.vm.network :private_network, ip: "192.168.56.5"
end
config.vm.define "beta" do |n|
n.vm.hostname = "beta.test"
n.vm.network :private_network, ip: "192.168.56.6"
end
config.vm.define "gamma" do |a|
a.vm.hostname = "gamma.test"
a.vm.network :private_network, ip: "192.168.56.7"
end
end

12
bootstrap.yml 100644
View File

@ -0,0 +1,12 @@
---
- name: Configure non-root user.
hosts: all
become: yes
roles:
- create-debian-user
- name: Secure SSH.
hosts: all
become: yes
roles:
- configure-ssh

15
hosts.template.ini 100644
View File

@ -0,0 +1,15 @@
# This file should only contain static IPs. Dynamic IPs should be defined in
# originals.ini.
# The admin is the main host that initializes the swarm
admin ansible_host=
[managers]
[workers]
[all:vars]
ansible_ssh_user=debian

30
main.yml 100644
View File

@ -0,0 +1,30 @@
---
- name: Initialize base server.
hosts: all
become: yes
roles:
- install-base-packages
- docker
- net-security
- name: Initialize Docker swarm.
hosts: admin
become: yes
roles:
- docker-swarm-init
tags: swarm
- name: Add managers to swarm.
hosts: managers
become: yes
roles:
- docker-swarm-add-manager
tags: swarm
- name: Add workers to swarm.
hosts: workers
become: yes
roles:
- docker-swarm-add-worker
tags: swarm

View File

@ -0,0 +1,121 @@
# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
Port 2222
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
PermitRootLogin no
#StrictModes yes
MaxAuthTries 3
#MaxSessions 10
PubkeyAuthentication yes
# Expect .ssh/authorized_keys2 to be disregarded by default in future.
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
#PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
# override default of no subsystems
Subsystem sftp /usr/lib/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server

View File

@ -0,0 +1,6 @@
---
- name: restart sshd
service:
name: sshd
state: restarted
enabled: yes

View File

@ -0,0 +1,9 @@
---
- name: Copy over sshd config file.
copy:
src: sshd_config
dest: /etc/ssh/sshd_config
owner: root
group: root
mode: '600'
notify: restart sshd

View File

@ -0,0 +1,3 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCkDjXuZn+blanbJAhte8KttrpeCPeT5CGcZ5mlAZv724wTa4qebpwCnf4SK4aFuDQEuCusnia3+X7YWAyCDReNURznAWCtq+b8LGxyIm2hTBbLA1m8sj0xidR/djlUtOwDp9VpSNamUWyiPWJ+WNsPd9xLJ6BK3qRsoFiMN87sO12L7DHHDaMze628Oc+IxFd+VZnH0dPVgitis31f+lXCr8w5qSiEepDJ8Nde8M+Ev1RrPQbR5Q5C+wYxlbY0oPNlGqSrs5i1jJl0BVMI4DlibxatTfuteU5IwcDMQObJr3xJGKNTPswSdzpfJFrLfUBZvsDs94BXEHR2CtxZ4aLQPeLfosWe4zuGvX22p7TzSPx1LkuqIF85Tw1PvK3f7u3l9sozHORAoEA8sFHG+DolqldgjuUgCGpfF/QOY1jkGpbEhq57kKFH+VlFI2XePGQ6299R9RN/Y4S88v14ChLwoLSNWgxK+CgYgB4lbquAIKTKsRla3gkEeziz+qoHPQkD5RcajrWOfSKU4alORpgQerSFZ9zMoz9N2rfTVEzCsVUj0Jiwtd5O7pCX9PWBhz1Nl1ItrRPuFiTSKB05dqsQ1CDZAZMDPJNqotd6QRS5+cKzFLgvU6k/gk08/qV00VM+BxlXkh8PwAhaxNPjMxjzqHx0+xC38FtacuhJiOV91Q== roosensjef@gmail.com
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCgHqW7mLuaW8XEFJrg031ES7v7y6Uk5QUp++axTd0wzvt5qfqTox9Hg1Xk5C9hdEfYzS5NCU+uoiInR0aHZ3Cl+yxqi3VqDfO20j6Irrt2SOBB86Gsyu9Brj62xtS0rY/e9rmyULJGUtJEz3UmFvn8fE5hUpGjDg7NByFs8f054pzifWw8F/wOvF5rKo9GqkWeXEUZ456FmowXCQLl5SypQliOsHJDs89NiTVvOxiKQXULBhj8o4c0MyCeFfPWqOutSSAetmbnegEjOTy7f/0IiqB+5713KOh1Bm1/u+3J2IVbRgeG1iTJdDVeIxBGmA1wMLvrBtBRIS0MaKa1Xabo3QTgYPHNGrf2w+GMnuoQ6/tdD6omPWGTHXqtHKEeIW1JrlDyhOo86oCl+l2aveMwhFFGW4nQmW7sfrowyLHdU3BpGl4m7pGa+5sTsHiOGEqEN/a7xikztXkuKacQ8E/y1C8gDXgaX8zFl6VOwR5EfMEMX390tz+R+ErDU81h47tSkwbY3KhunSKwPT8jSMldBttnCIexd+QuQgOlSwXkYVPPmXtPUkfp+4VzWSWeGKAa9k3HtVMIvKdVk9eXDVNnVdaAL+EkHyXOyFVVGa9gJ3ZOWhHMNi2/kHAwWMI9CwRxj7AVk30KGBhPN0wdS9Dt8/0Aa33hWuY2p9DxtNaiNw== roosensjef@gmail.com

View File

@ -0,0 +1,31 @@
---
- name: Install sudo.
apt:
name: sudo
state: present
- name: Create debian user.
user:
name: debian
groups: sudo
append: true
create_home: yes
shell: /bin/bash
password: "{{ debian_pass | password_hash('sha512') }}"
update_password: on_create
- name: Create SSH directory.
file:
path: /home/debian/.ssh/
state: directory
owner: debian
group: debian
mode: '700'
- name: Add authorized SSH keys.
copy:
src: authorized_keys
dest: /home/debian/.ssh/authorized_keys
owner: debian
group: debian
mode: '600'

View File

@ -0,0 +1,17 @@
---
- name: Check if swarm is already Initialized
shell: docker node ls
register: swarm_status
ignore_errors: true
- name: Check node state.
register: node_state
shell: "docker info --format '{{ '{{' }}.Swarm.LocalNodeState{{ '}}' }}'"
ignore_errors: true
- name: Add managers to the swarm
shell: >
docker swarm join
--token {{ hostvars.admin.manager_token }}
{{ hostvars.admin.ansible_host }}:2377
when: swarm_status.rc != 0 and node_state.stdout not in [ 'active', 'locked', 'error' ]

View File

@ -0,0 +1,16 @@
---
- name: Check node state.
register: node_state
shell: "docker info --format '{{ '{{' }}.Swarm.LocalNodeState{{ '}}' }}'"
ignore_errors: true
- name: Add worker to swarm.
register: join_cmd
shell: >
docker swarm join
--token {{ hostvars.admin.worker_token }}
{{ hostvars.admin.ansible_host }}:2377
# 0 means it was successfully added, 1 means it's already in the swarm.
failed_when: join_cmd.rc != 0
changed_when: join_cmd.rc == 0
when: node_state.stdout not in [ 'active', 'locked', 'error' ]

View File

@ -0,0 +1,33 @@
# https://github.com/ruanbekker/ansible-docker-swarm/blob/master/roles/docker-swarm-init/tasks/main.yml
---
# Basically we put the exit code in the variable and use it later
- name: Check if swarm has already been initialized.
shell: docker node ls
register: swarm_status
ignore_errors: true
changed_when: false
- name: Initialize Docker Swarm.
shell: >
docker swarm init
--advertise-addr={{ hostvars[inventory_hostname]['ansible_host'] }}:2377
when: swarm_status.rc != 0
run_once: true
- name: Get manager join token.
shell: docker swarm join-token --quiet manager
register: manager_token
changed_when: false
- name: Store manager join token as fact.
set_fact:
manager_token: "{{ manager_token.stdout }}"
- name: Get worker join token.
shell: docker swarm join-token --quiet worker
register: worker_token
changed_when: false
- name: Store worker join token as fact.
set_fact:
worker_token: "{{ worker_token.stdout }}"

View File

@ -0,0 +1,60 @@
---
- name: Ensure older Docker versions aren't installed.
apt:
name:
- docker
- docker-engine
- docker.io
- containerd
- runc
state: absent
- name: Install Docker PPA dependencies.
apt:
name:
- apt-transport-https
- ca-certificates
- gnupg
- lsb-release
state: present
- name: Add Docker GPG key.
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
- name: Add Docker PPA.
apt_repository:
# https://gist.github.com/rbq/886587980894e98b23d0eee2a1d84933
repo: "deb [arch={{ ansible_architecture | replace('aarch64', 'arm64') | replace('x86_64', 'amd64') }}] https://download.docker.com/{{ ansible_system | lower }}/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"
state: present
- name: Install Docker, docker-compose & cron.
apt:
update_cache: yes
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose
- cron
state: present
- name: Ensure Docker is running & enabled.
service:
name: docker
state: started
enabled: true
- name: Add Docker prune cronjob.
cron:
name: Prune the Docker system.
hour: 4
minute: 0
job: docker system prune -af
- name: Add debian user to docker group.
user:
name: debian
groups: docker
append: true

View File

@ -0,0 +1,9 @@
---
- name: Install frequently used packages.
apt:
name:
- vim
- tmux
- curl
- htop
state: present

View File

@ -0,0 +1,14 @@
- name: Install fail2ban.
apt:
name: fail2ban
state: present
# TODO add proper fail2ban config
- name: Ensure fail2ban is started & enabled.
service:
name: fail2ban
state: started
enabled: true
# TODO install UFW

View File

@ -0,0 +1,7 @@
---
- name: deploy portainer
shell: >
docker stack deploy
--compose-file /srv/portainer-stack.yml
--prune
portainer

View File

@ -0,0 +1,13 @@
---
- name: Create public network.
shell:
docker network create -d overlay public
register: create_network
failed_when: create_network.rc not in [ 0, 1 ]
changed_when: create_network.rc == 0
- name: Copy over the Portainer stack file.
template:
src: portainer-stack.yml.j2
dest: /srv/portainer-stack.yml
notify: deploy portainer

View File

@ -0,0 +1,49 @@
# vim: ft=yaml
version: '3'
services:
app:
image: 'portainer/portainer-ce:2.11.0-alpine'
command: '-H tcp://tasks.agent:9001 --tlsskipverify'
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.portainer.rule=Host(`{{ portainer_domain }}`)'
- 'traefik.http.routers.portainer.service=portainer'
- 'traefik.http.services.portainer.loadbalancer.server.port=9000'
- 'traefik.http.routers.portainer.tls=true'
- 'traefik.http.routers.portainer.tls.certresolver=letsEncrypt'
networks:
- default
- public
volumes:
- 'data:/data'
ports:
- '8000:8000'
agent:
image: 'portainer/agent:2.9.3-alpine'
deploy:
mode: global
placement:
constraints:
- node.platform.os == linux
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
- '/var/lib/docker/volumes:/var/lib/docker/volumes'
networks:
public:
external: true
volumes:
data:

View File

@ -0,0 +1,5 @@
---
- name: Set hostname
hostname:
name: "{{ hostname }}"
method: debian

View File

@ -0,0 +1,7 @@
---
- name: deploy traefik
shell: >
docker stack deploy
--compose-file /srv/traefik-stack.yml
--prune
traefik

View File

@ -0,0 +1,12 @@
---
- name: Copy over config file.
template:
src: traefik.yml.j2
dest: "srv/traefik.yml"
notify: deploy treafik
- name: Copy over stack file.
template:
src: traefik-stack.yml.j2
dest: /srv/traefik-stack.yml
notify: deploy traefik

View File

@ -0,0 +1,30 @@
# vim: ft=yaml
version: '3'
services:
app:
image: 'traefik:2.5'
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
networks:
- public
ports:
- '80:80'
- '443:443'
volumes:
- '/srv/traefik.yml:/etc/traefik/traefik.yml'
- 'acme:/etc/traefik/acme'
- '/var/run/docker.sock:/var/run/docker.sock'
networks:
public:
external: true
volumes:
acme:

View File

@ -0,0 +1,28 @@
# vim: ft=yaml
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
api:
insecure: true
providers:
docker:
swarmMode: true
exposedbydefault: false
network: public
certificatesResolvers:
letsEncrypt:
acme:
email: "{{ letsencrypt_email }}"
storage: "/etc/traefik/acme/acme.json"
httpChallenge:
entryPoint: web

View File

@ -0,0 +1,8 @@
deb http://deb.debian.org/debian bullseye main contrib non-free
deb-src http://deb.debian.org/debian bullseye main contrib non-free
deb http://deb.debian.org/debian-security/ bullseye-security main contrib non-free
deb-src http://deb.debian.org/debian-security/ bullseye-security main contrib non-free
deb http://deb.debian.org/debian bullseye-updates main contrib non-free
deb-src http://deb.debian.org/debian bullseye-updates main contrib non-free

View File

@ -0,0 +1,14 @@
---
- name: Copy over sources.list
copy:
src: sources.list
dest: /etc/apt/sources.list
owner: root
group: root
mode: '644'
- name: Update system
apt:
update_cache: yes
install_recommends: yes
upgrade: dist

121
sshd_config 100644
View File

@ -0,0 +1,121 @@
# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
PubkeyAuthentication yes
# Expect .ssh/authorized_keys2 to be disregarded by default in future.
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
# override default of no subsystems
Subsystem sftp /usr/lib/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server

6
update.yml 100644
View File

@ -0,0 +1,6 @@
---
- name: Update system.
hosts: all
become: yes
roles:
- update

18
vagrant.hosts.ini 100644
View File

@ -0,0 +1,18 @@
# This file should only contain static IPs. Dynamic IPs should be defined in
# originals.ini.
# The admin is the main host that initializes the swarm
admin ansible_host=192.168.56.5
[managers]
[workers]
192.168.56.6
192.168.56.7
[all:vars]
ansible_ssh_user=debian
ansible_ssh_port=2222
ansible_become_pass=pass
; ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
debian_pass=pass