Benoît S. 8 months ago
parent
commit
3847f18792
  1. 7
      README.md
  2. 89
      files/haproxy.cfg
  3. 29
      files/lxd.yml
  4. 53
      files/nginx.default
  5. 14
      files/ondemand.service
  6. 38
      files/set-cpufreq-performance
  7. 0
      group_data/all.py
  8. 1
      inventory.py
  9. 127
      setup-base.py
  10. 88
      setup-haproxy.py
  11. 91
      setup-zfs-and-lxd.py

7
README.md

@ -1,3 +1,8 @@
# lxdXX.benpro.fr
Pyinfra that deploy my LXD server.
Pyinfra that deploy my LXD server.
```
pyinfra inventory.py setup-base.py
pyinfra inventory.py setup-zfs-and-lxd.py
```

89
files/haproxy.cfg

@ -0,0 +1,89 @@
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/haproxy/dhparam
ssl-dh-param-file /etc/haproxy/dhparam
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend gitea-ssh
mode tcp
bind :22
bind :::22 v6only
default_backend gitea-ssh
backend gitea-ssh
mode tcp
server gitea 127.0.0.1:2222 check send-proxy
frontend default
bind :80
bind :::80 v6only
bind :443 ssl crt /etc/ssl/haproxy/ strict-sni alpn h2,http/1.1
bind :::443 v6only ssl crt /etc/ssl/haproxy/ strict-sni alpn h2,http/1.1
# HSTS (15768000 seconds = 6 months)
http-response set-header Strict-Transport-Security max-age=15768000
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
# Let's Encrypt
acl letsencrypt path_dir -i /.well-known/acme-challenge
use_backend localhost if letsencrypt
# mo-f.fr
acl mof hdr_end(host) -i mo-f.fr
use_backend mof if mof
# play.benpro.fr
acl play hdr(host) -i play.benpro.fr
use_backend play if play
#default_backend localhost
backend localhost
option forwardfor
server localhost 127.0.0.1:8080 check send-proxy
backend mof
# Benhind CloudFlare, X-Forwarded-For always setted, do not override
option forwardfor if-none
redirect scheme https if !{ ssl_fc }
server mof 127.0.0.1:8081 check
backend play
option forwardfor
redirect scheme https if !{ ssl_fc }
server play 127.0.0.1:8096 check

29
files/lxd.yml

@ -0,0 +1,29 @@
config: {}
networks:
- config:
ipv4.address: auto
ipv6.address: auto
description: ""
name: lxdbr0
type: ""
project: default
storage_pools:
- config:
source: local
description: ""
name: default
driver: zfs
profiles:
- config: {}
description: ""
devices:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: /
pool: default
type: disk
name: default
cluster: null

53
files/nginx.default

@ -0,0 +1,53 @@
server {
listen 127.0.0.1:8080 default_server proxy_protocol;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

14
files/ondemand.service

@ -0,0 +1,14 @@
[Unit]
Description=Set the CPU Frequency Scaling governor
ConditionVirtualization=no
ConditionPathExists=/sys/devices/system/cpu/online
# Don't run if we're going to start an Android LXC container on Ubuntu Touch
ConditionPathExists=!/etc/init/lxc-android-config.conf
[Service]
Type=idle
ExecStart=/lib/systemd/set-cpufreq-performance
[Install]
WantedBy=multi-user.target

38
files/set-cpufreq-performance

@ -0,0 +1,38 @@
#! /bin/sh
# Set the CPU Frequency Scaling governor to "performance"/"powersave" where available
set -eu
FIRSTCPU=`cut -f1 -d- /sys/devices/system/cpu/online`
AVAILABLE="/sys/devices/system/cpu/cpu$FIRSTCPU/cpufreq/scaling_available_governors"
DOWN_FACTOR="/sys/devices/system/cpu/cpufreq/performance/sampling_down_factor"
[ -f $AVAILABLE ] || exit 0
read governors < $AVAILABLE
case $governors in
*performance*)
GOVERNOR="performance"
case $(uname -m) in
ppc64*)
SAMPLING=100
;;
esac
break
;;
*)
exit 0
;;
esac
[ -n "${GOVERNOR:-}" ] || exit 0
echo "Setting $GOVERNOR scheduler for all CPUs"
for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
do
[ -f $CPUFREQ ] || continue
echo -n $GOVERNOR > $CPUFREQ
done
if [ -n "${SAMPLING:-}" ] && [ -f $DOWN_FACTOR ]; then
echo -n $SAMPLING > $DOWN_FACTOR
fi

0
group_data/all.py

1
inventory.py

@ -0,0 +1 @@
my_hosts = ['lxd10.benpro.fr']

127
setup-base.py

@ -0,0 +1,127 @@
from pyinfra import host
from pyinfra.operations import apt, server, files, systemd
SUDO = True
server.user(
name='Add user benpro',
user='benpro',
groups=['sudo'],
public_keys='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFs7yO0auvwFL8HTLMUq6lET6DMYLhqhd32rqFfZUsjL openpgp:0xA32E99AD',
shell='/bin/bash',
present=True,
)
server.hostname(
name='Set the hostname',
hostname='lxd10.benpro.fr',
)
apt.update(
name='Update apt repositories',
)
apt.upgrade(
name='Upgrade apt packages',
)
apt.packages(
name='Install ufw',
packages=['ufw'],
update=False,
)
server.shell(
name='Add ufw rules',
commands=['ufw limit 22', 'ufw limit 28', 'ufw allow 80', 'ufw allow 443'],
)
server.shell(
name='Enable ufw',
commands=['yes | ufw enable'],
)
files.line(
name='Set port 28 for SSH',
path='/etc/ssh/sshd_config',
line=r'Port .*',
replace='Port 28',
)
systemd.service(
name='Reload sshd',
service='ssh.service',
reloaded=True,
)
apt.packages(
name='Install packages',
packages=['zfsutils-linux', 'manpages', 'man', 'snapd', 'vim', 'file', 'parted', 'htop', 'ncdu', 'byobu', 'tcpdump', 'lm-sensors'],
update=False,
)
if not host.fact.directory('/var/snap/lxd'):
server.shell(
name='Install lxd',
commands=['snap install lxd'],
)
if not host.fact.command('file -s /dev/sdc1 | grep swap || true'):
server.shell(
name='Create swap',
commands=['wipefs -a /dev/sdc1', 'mkswap /dev/sdc1'],
)
files.line(
name='Add swap to /etc/fstab',
path='/etc/fstab',
line='/dev/sdc1 none swap defaults 0 0',
)
server.shell(
name='Enable swap',
commands=['swapon -a'],
)
files.line(
name='Disable intel_pstate',
path='/etc/default/grub',
line='GRUB_CMDLINE_LINUX="intel_pstate=disable"',
)
server.shell(
name='Reload grub',
commands=['update-grub'],
)
files.put(
name='Install set-cpufreq-performance',
src='files/set-cpufreq-performance',
dest='/lib/systemd/set-cpufreq-performance',
user='root',
group='root',
mode='755',
)
files.put(
name='Override systemd ondemand.service',
src='files/ondemand.service',
dest='/etc/systemd/system/ondemand.service',
user='root',
group='root',
mode='644',
)
systemd.daemon_reload(
name='Reload systemd',
user_mode=False,
)
systemd.service(
name='Restart and enable ondemand service',
service='ondemand.service',
running=True,
restarted=True,
enabled=True,
)

88
setup-haproxy.py

@ -0,0 +1,88 @@
from pyinfra import host
from pyinfra.operations import server, files, systemd, apt
SUDO = True
apt.packages(
name='Install packages',
packages=['certbot', 'haproxy', 'nginx'],
update=False,
)
files.put(
name='Upload Nginx default vhost',
src='files/nginx.default',
dest='/etc/nginx/sites-available/default',
user='root',
group='root',
mode='644',
)
systemd.service(
name='Restart and enable nginx service',
service='nginx.service',
running=True,
restarted=True,
enabled=True,
)
files.put(
name='Upload HAProxy config',
src='files/haproxy.cfg',
dest='/etc/haproxy/haproxy.cfg',
user='root',
group='root',
mode='644',
)
files.directory(
name='Ensure /etc/ssl/haproxy exists',
path='/etc/ssl/haproxy',
user='root',
group='root',
mode=700
)
if not host.fact.file('/etc/haproxy/dhparam'):
server.shell(
name='Generate dhparam',
commands=['openssl dhparam 2048 > /etc/haproxy/dhparam']
)
systemd.service(
name='Restart and enable HAProxy service',
service='haproxy.service',
running=True,
restarted=True,
enabled=True,
)
if not host.fact.directory('/etc/letsencrypt/live/mo-f.fr'):
server.shell(
name='Add certificate mo-f.fr',
commands=['certbot certonly --non-interactive --email certbot@benpro.fr --agree-tos --webroot --webroot-path /var/www/html/ -d mo-f.fr -d download.mo-f.fr -d ipv4.mo-f.fr -d oppai.mo-f.fr -d static-uploads.mo-f.fr -d www.mo-f.fr'],
)
if not host.fact.directory('/etc/letsencrypt/live/play.benpro.fr'):
server.shell(
name='Add certificate play.benpro.fr',
commands=['certbot certonly --non-interactive --email certbot@benpro.fr --agree-tos --webroot --webroot-path /var/www/html/ -d play.benpro.fr'],
)
if not host.fact.directory('/etc/letsencrypt/live/mo-f.fr'):
server.shell(
name='Add certificate mo-f.fr to HAProxy',
commands=['cat /etc/letsencrypt/live/mo-f.fr/fullchain.pem /etc/letsencrypt/live/mo-f.fr/privkey.pem > /etc/ssl/haproxy/mo-f.fr.pem']
)
if not host.fact.directory('/etc/letsencrypt/live/play.benpro.fr'):
server.shell(
name='Add certificate play.benpro.fr to HAProxy',
commands=['cat /etc/letsencrypt/live/play.benpro.fr/fullchain.pem /etc/letsencrypt/live/play.benpro.fr/privkey.pem > /etc/ssl/haproxy/play.benpro.fr.pem']
)
systemd.service(
name='Reload HAProxy service',
service='haproxy.service',
reloaded=True,
)

91
setup-zfs-and-lxd.py

@ -0,0 +1,91 @@
from pyinfra import host
from pyinfra.operations import server, files
SUDO = True
# This suppose you have:
# sda 8:0 0 2.7T 0 disk
# ├─sda1 8:1 0 512M 0 part
# │ └─md0 9:0 0 511M 0 raid1 /boot
# ├─sda2 8:2 0 40G 0 part
# │ └─md1 9:1 0 40G 0 raid1 /
# └─sda3 8:3 0 1M 0 part
# sdb 8:16 0 2.7T 0 disk
# ├─sdb1 8:17 0 512M 0 part
# │ └─md0 9:0 0 511M 0 raid1 /boot
# ├─sdb2 8:18 0 40G 0 part
# │ └─md1 9:1 0 40G 0 raid1 /
# └─sdb3 8:19 0 1M 0 part
# sdc 8:32 0 223.6G 0 disk
# └─sdc1 8:33 0 24G 0 part
if not host.fact.command('lsblk | grep sda4 || true'):
server.shell(
name='Create sda4 for zpool',
commands=['sgdisk -n4:0:0 -t4:BF00 /dev/sda', 'partprobe']
)
if not host.fact.command('lsblk | grep sdb4 || true'):
server.shell(
name='Create sdb4 for zpool',
commands=['sgdisk -n4:0:0 -t4:BF00 /dev/sdb', 'partprobe']
)
if not host.fact.command('lsblk | grep sdc2 || true'):
server.shell(
name='Create sdc2 for ZFS cache L2ARC',
commands=['sgdisk -n2:0:0 -t2:FD00 /dev/sdc', 'partprobe']
)
# zfs.key is not stored on GIT, but on KeePassXC
# When using new server be sure to set right disk ID
if not host.fact.command('zpool list local | grep local || true'):
server.shell(
name='Create ZFS pool',
commands=['zpool create -o ashift=12 -o autotrim=on -O encryption=aes-256-gcm -O keylocation=file:///etc/zfs.key -O keyformat=passphrase -O acltype=posixacl -O canmount=off -O dedup=on -O compression=lz4 -O dnodesize=auto -O normalization=formD -O relatime=on -O xattr=sa local mirror /dev/disk/by-id/ata-ST33000650NS_Z290FDG2-part4 /dev/disk/by-id/ata-ST33000650NS_Z290FEJQ-part4 cache /dev/disk/by-id/ata-INTEL_SSDSC2CW240A3_CVCV306301L3240CGN-part2']
)
files.put(
name='Upload LXD config',
src='files/lxd.yml',
dest='/tmp/lxd.yml',
mode='644',
)
if not host.fact.command('lxc storage list | grep local || true'):
server.shell(
name='Init LXD',
commands=['cat /tmp/lxd.yml | lxd init --preseed']
)
if not host.fact.command('lxc storage volume list default | grep backups || true'):
server.shell(
name='Set LXD backups volumes',
commands=['lxc storage volume create default backups', 'lxc config set storage.backups_volume default/backups']
)
if not host.fact.command('lxc storage volume list default | grep images || true'):
server.shell(
name='Set LXD images volumes',
commands=['lxc storage volume create default images', 'lxc config set storage.images_volume default/images']
)
files.directory(
name='Ensure /var/backups/lxd exists',
path='/var/backups/lxd',
user='root',
group='root',
mode=700
)
if not host.fact.command('zfs list | grep exports || true'):
server.shell(
name='Create ZFS volume exports',
commands=['zfs create local/exports -o mountpoint=/var/backups/lxd']
)
files.line(
name='Add info to motd',
path='/etc/motd',
line='`zfs load-key -a && systemctl start snap.lxd.daemon.service',
)
Loading…
Cancel
Save