Old

Hardware

BHS

SYS-BF-3

CPU

Intel Xeon E3-1245v2 4c/8t @ 3.4 GHz

RAM

32 GB DDR3 ECC @ 1333 MHz

SSD

2 × 480 GB

HDD

2 × 2 TB

MAC

70:54:d2:8f:9c:a6

WAN

250 Mbps

Network

IP4

address

192.99.160.67 /24

gateway

192.99.160.254

IP6

address

2607:5300:60:5843:: /64

gateway

2607:5300:60:58ff:ff:ff:ff:ff

192.99.160.67

tilde.link

158.69.5.50

rwx.work

149.56.249.159

marc-beninca.fr

144.217.189.17

54.39.193.87

51.161.101.247

51.161.101.99

51.161.56.101

Rescue

ssh-keygen -R tilde.link
ssh-keygen -R 192.99.160.67
ssh-copy-id root@tilde.link
scp /etc/bash.bashrc root@tilde.link:/etc/

Partitions

parted

select /dev/sda
mktable gpt
mkpart boot 1 2
mkpart raid 2 480104
set 1 bios_grub on

select /dev/sdb
mktable gpt
mkpart boot 1 2
mkpart raid 2 480104
set 1 bios_grub on

select /dev/sdc
mktable gpt
mkpart raid 1 2000399

select /dev/sdd
mktable gpt
mkpart raid 1 2000399

q
mdadm --create /dev/md0 \
--level 0 --raid-devices 2 /dev/sd[ab]2

mdadm --create /dev/md1 \
--level 0 --raid-devices 2 /dev/sd[cd]1
parted

select /dev/md0
mktable gpt
mkpart ssd 1 959934

select /dev/md1
mktable gpt
mkpart hdd 1 3966972
mkpart swap 3966972 4000527

q
mkfs.ext4 -L ssd \
-U 006234a0-eb29-a3a8-471d-bd5ec4bada55 \
/dev/md0p1

mkfs.ext4 -L hdd \
-U 06234a0e-b29a-3a84-71db-d5ec4bada557 \
/dev/md1p1

mkswap --label swap \
-U 6234a0eb-29a3-a847-1dbd-5ec4bada5579 \
/dev/md1p2

Boot

Warning

no ESP boot available!

Prepare a grub.cfg

insmod biosdisk
insmod part_gpt
insmod mdraid1x
insmod ext2
insmod search
insmod squash4
insmod loopback
insmod linux

search \
--set root \
--fs-uuid 006234a0-eb29-a3a8-471d-bd5ec4bada55
lmp=/fs/up
sfs=filesystem.squashfs

loopback sfs ${lmp}/${sfs}

linux ${lmp}/vmlinuz \
boot=live \
elevator=deadline \
ip=frommedia \
live-media-path=${lmp} \
toram=${sfs}

initrd ${lmp}/initrd.img

boot
grub-mkstandalone \
--verbose \
--compress xz \
--format i386-pc \
--output core.img \
--themes "" \
boot/grub/grub.cfg=grub.cfg \
--fonts "" \
--locales "" \
--install-modules "\
biosdisk \
part_gpt \
mdraid1x \
ext2 \
search \
squash4 \
loopback \
linux \
"

Todo

move to public grub

grub-mkstandalone \
--verbose \
--compress xz \
--format x86_64-efi \
--output bootx64.efi \
--themes "" \
boot/grub/grub.cfg=grub.cfg
scp core.img root@rwx.work:
cp /usr/lib/grub/i386-pc/boot.img .
/usr/lib/grub/i386-pc/grub-bios-setup \
--directory . /dev/sda
/usr/lib/grub/i386-pc/grub-bios-setup \
--directory . /dev/sdb
  • debootstrap

  • apt

  • user account and home directory

  • fstab /d

  • systemd

  • linux-image

  • tops

  • hardware

  • completion

  • network

  • interfaces

  • iputils-ping

  • basics

  • openssh-server fixes (sshd user, /run/sshd)

  • live-boot

  • root

  • inception

  • bridge

  • grub-pc-bin

  • apparmor

  • unbound

  • tree

  • net.ipv4.ip_forward=1

  • net.ipv6.conf.all.forwarding=1

  • nftables

  • nginx-extras

  • root/user authorized_keys

  • curl

  • swap,swappiness

  • enable nftables.service

  • enable lxc.service

  • sources.list file:/

  • syslog-ng

  • ssh on port 80

  • domain certificate private key

  • domain certificate bundle

  • /etc/ssl/openssl.cnf tls 1.3 suites

  • nginx configuration

  • nginx in container

  • nginx host sites

  • python3-sphinx-rtd-theme

  • uwsgi

  • uwsgi-plugin-python3

  • sudo

  • file

  • fcgiwrap

  • gitweb

  • /etc/bash.bashrc

  • /etc/fstab (/d)

  • /etc/locale.gen

  • locale-gen

  • /etc/resolv.conf

  • /etc/apt/apt.conf

  • /etc/apt/sources.list

  • apt update

  • apt upgrade

  • live-boot

  • update-initramfs ← update-initramfs.orig

  • openssh-server

  • parted

  • squashfs-tools

  • tree

  • apt clean

  • /etc/ssh/sshd_config

  • mkdir /root/.ssh

  • echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICZAs76kQJ0/Et2NGzhxurK2wE0VhYsG9wl85iCmR9xH" > /root/.ssh/authorized_keys

  • lxc

  • /etc/network/interfaces.d/setup

  • gotty

Warning

inet6 dhcp hangs!

auto  lo

iface lo inet6 loopback

iface lo inet loopback


auto  br0

iface br0 inet static
      bridge_fd 0
      bridge_maxwait 0
      bridge_ports eno1
      bridge_stp off
      address 10.0.0.254/24

iface br0 inet6 static
      address 2607:5300:60:5843:192:99:160:67/64
      gateway 2607:5300:60:58ff:ff:ff:ff:ff

iface br0 inet static
      address 192.99.160.67/24
      gateway 192.99.160.254

iface br0 inet6 static
      address 2607:5300:60:5843:158:69:5:50/64
      gateway 2607:5300:60:58ff:ff:ff:ff:ff

iface br0 inet static
      address 158.69.5.50/32
      gateway 192.99.160.254

iface br0 inet6 static
      address 2607:5300:60:5843:149:56:249:159/64
      gateway 2607:5300:60:58ff:ff:ff:ff:ff

iface br0 inet static
      address 149.56.249.159/32
      gateway 192.99.160.254

iface br0 inet6 static
      address 2607:5300:60:5843:144:217:189:17/64
      gateway 2607:5300:60:58ff:ff:ff:ff:ff

iface br0 inet static
      address 144.217.189.17/32
      gateway 192.99.160.254

iface br0 inet6 static
      address 2607:5300:60:5843:54:39:193:87/64
      gateway 2607:5300:60:58ff:ff:ff:ff:ff

iface br0 inet static
      address 54.39.193.87/32
      gateway 192.99.160.254

iface br0 inet6 static
      address 2607:5300:60:5843:51:161:101:247/64
      gateway 2607:5300:60:58ff:ff:ff:ff:ff

iface br0 inet static
      address 51.161.101.247/32
      gateway 192.99.160.254

iface br0 inet6 static
      address 2607:5300:60:5843:51:161:101:99/64
      gateway 2607:5300:60:58ff:ff:ff:ff:ff

iface br0 inet static
      address 51.161.101.99/32
      gateway 192.99.160.254

iface br0 inet6 static
      address 2607:5300:60:5843:51:161:56:101/64
      gateway 2607:5300:60:58ff:ff:ff:ff:ff

iface br0 inet static
      address 51.161.56.101/32
      gateway 192.99.160.254

Warning

reboot from container doesn't reload config file

/var/lib/lxc/config

lxc.include = /usr/share/lxc/config/common.conf
lxc.mount.entry = /ssd/mirrors/apt-mirror/debian deb none bind,create=dir,ro 0 0
lxc.start.auto = 1
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = br0

/var/lib/lxc/name/config

lxc.include = /var/lib/lxc/config
lxc.mount.entry = /ssd/d/buster d none bind,create=dir,rw 0 0
lxc.rootfs.path = dir:/var/lib/lxc/buster
lxc.net.0.veth.pair = buster
lxc.net.0.ipv4.address = 10.0.0.1/24
lxc.net.0.ipv4.gateway = 10.0.0.254

/etc/nftables.conf

#! /usr/sbin/nft --file

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy accept;
        iifname "lo" accept
        ip protocol icmp accept
        ip6 nexthdr icmp accept
        tcp dport ssh accept
        tcp dport domain accept
        tcp dport http accept
        tcp dport https accept
    }
    chain forward {
        type filter hook forward priority 0; policy accept;
    }
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

table ip nat {
    chain prerouting {
        type nat hook prerouting priority 0; policy accept;
        tcp dport 65001 dnat to 10.0.0.1:ssh
    }
    chain postrouting {
        type nat hook postrouting priority 0; policy accept;
        masquerade
    }
}

Security

  • /etc/sudoers

Todo

all directives

user ALL=NOPASSWD: /bin/systemctl restart uwsgi

Web

Configuration

  • /etc/nginx/nginx.conf

load_module modules/ngx_http_fancyindex_module.so;
load_module modules/ngx_http_headers_more_filter_module.so;

pid /run/nginx.pid;
user user;
worker_processes auto;

events {
multi_accept off;
worker_connections 512;
}

http {

# General

keepalive_timeout 60;
sendfile on;
server_tokens off;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;

# Names

server_name_in_redirect off;
server_names_hash_bucket_size 128;

# File types

charset "UTF-8";
default_type application/octet-stream;
include mime.types;

# Security

ssl_buffer_size 8k;
ssl_ciphers "ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384";
ssl_ecdh_curve "X448:X25519:P-521";
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_session_cache shared:ssl_session_cache:16m;
ssl_session_tickets off;
ssl_session_timeout 15m;

# Log

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

# Compression

gzip off;

# Misc

client_max_body_size 16m;
index index.html;

# Proxy

proxy_pass_request_body on;
proxy_pass_request_headers on;
proxy_redirect off;

# Headers

more_clear_headers Server;

# Includes

include sites-enabled/*;

}

Warning

almost 1 minute to start the service

ssl_stapling on;
ssl_stapling_verify on;

Security

  • /etc/nginx/https.conf

listen 443 ssl http2;
listen [::]:443 ssl http2;

error_page 496 =496 @error; # Certificate Required
error_page 497 =497 @error; # HTTP Request Sent to HTTPS Port
error_page
403 # Forbidden
404 # Not Found
500 # Internal Server Error
502 # Bad Gateway
@error;

add_header Expect-CT "enforce,max-age=0" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Strict-Transport-Security "max-age=31557600;includeSubDomains;preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "sameorigin" always;
set $fp "";
set $fp "${fp}accelerometer 'none';";
set $fp "${fp}ambient-light-sensor 'none';";
set $fp "${fp}animations 'self';";
set $fp "${fp}autoplay 'none';";
set $fp "${fp}camera 'none';";
set $fp "${fp}document-domain 'none';";
set $fp "${fp}document-write 'none';";
set $fp "${fp}encrypted-media 'none';";
set $fp "${fp}fullscreen *;";
set $fp "${fp}geolocation 'none';";
set $fp "${fp}gyroscope 'none';";
set $fp "${fp}legacy-image-formats 'none';";
set $fp "${fp}magnetometer 'none';";
set $fp "${fp}microphone 'none';";
set $fp "${fp}midi 'none';";
set $fp "${fp}payment 'self';";
set $fp "${fp}picture-in-picture 'none';";
set $fp "${fp}speaker 'self';";
set $fp "${fp}sync-xhr 'none';";
set $fp "${fp}unsized-media 'none';";
set $fp "${fp}usb 'none';";
set $fp "${fp}vertical-scroll 'self';";
set $fp "${fp}vr 'none';";
add_header Feature-Policy "${fp}" always;

Todo

find policy not blocking sphinx search

add_header Content-Security-Policy "default-src 'self'" always;
  • /etc/nginx/fcgi.conf

fastcgi_param SERVER_PORT    ${server_port};

fastcgi_param QUERY_STRING   ${query_string};

fastcgi_param REQUEST_METHOD ${request_method};
fastcgi_param CONTENT_TYPE   ${content_type};
fastcgi_param CONTENT_LENGTH ${content_length};
  • /etc/nginx/uwsgi.conf

uwsgi_param client_address   ${remote_addr};
uwsgi_param client_port      ${remote_port};
uwsgi_param client_ciphers   ${ssl_ciphers};
uwsgi_param client_curves    ${ssl_curves};

uwsgi_param session_reused   ${ssl_session_reused};
uwsgi_param session_id       ${ssl_session_id};
uwsgi_param session_cipher   ${ssl_cipher};
uwsgi_param session_protocol ${ssl_protocol};

uwsgi_param server_protocol  ${server_protocol};
uwsgi_param server_address   ${server_addr};
uwsgi_param server_port      ${server_port};

uwsgi_param request_scheme   ${scheme};
uwsgi_param request_host     ${host};
uwsgi_param request_document ${document_uri};
uwsgi_param request_query    ${query_string};
uwsgi_param request_method   ${request_method};

uwsgi_param content_type     ${content_type};
uwsgi_param content_length   ${content_length};

uwsgi_param client_verify    ${ssl_client_verify};
uwsgi_param client_issuer    ${ssl_client_i_dn};
uwsgi_param client_subject   ${ssl_client_s_dn};
uwsgi_param client_start     ${ssl_client_v_start};
uwsgi_param client_remain    ${ssl_client_v_remain};
uwsgi_param client_end       ${ssl_client_v_end};

Apps

  • /lib/systemd/system/fcgiwrap.socket

[Unit]
Description=fcgiwrap socket

[Socket]
SocketMode=0600
SocketUser=user
SocketGroup=user
ListenStream=/run/fcgiwrap.socket

[Install]
WantedBy=sockets.target
  • /etc/gitweb.conf

$projectroot = "/ssd/projects/public";
$git_temp = "/tmp";
  • /etc/uwsgi/apps-enabled/root.ini

[uwsgi]
chown-socket = user
uid = user
gid = user
chdir = /ssd/projects/public/root
plugins = python3
module = __init__
callable = app
threads = 2

Sites

  • "/etc/nginx/sites-enabled/0 http"

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://${host}${request_uri};
}
  • "/etc/nginx/sites-enabled/1 rwx.work"

server {
include rwx.work.conf;
include uwsgi.conf;
server_name .rwx.work;
location / {
uwsgi_pass unix:/run/uwsgi/app/root/socket;
}
}

server {
include rwx.work.conf;
server_name live.rwx.work;
location / {
proxy_pass http://localhost:8080/;
proxy_set_header Connection "upgrade";
proxy_set_header Origin "";
proxy_set_header Upgrade ${http_upgrade};
}
}

server {
include rwx.work.conf;
server_name git.rwx.work;
location ~ ^.*/(info/refs|git-upload-pack)$ {
include fcgi.conf;
fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
fastcgi_param PATH_INFO ${uri};
fastcgi_param GIT_PROJECT_ROOT /ssd/projects/rwx.work;
fastcgi_param GIT_HTTP_EXPORT_ALL "";
fastcgi_pass unix:/run/fcgiwrap.socket;
}
location /static/ {
root /usr/share/gitweb;
}
location / {
include fcgi.conf;
fastcgi_param SCRIPT_FILENAME /usr/share/gitweb/gitweb.cgi;
fastcgi_pass unix:/run/fcgiwrap.socket;
}
}

server {
include rwx.work.conf;
server_name blog.rwx.work;
root /ssd/projects/public/rwx.work/blog/output;
}

server {
include rwx.work.conf;
server_name deb.rwx.work;
root /ssd/mirrors/apt-mirror/deb;
fancyindex on;
}

server {
include rwx.work.conf;
server_name doc.rwx.work;
root /ssd/projects/public/rwx.work/doc/out/doc;
}

server {
include rwx.work.conf;
server_name docs.rwx.work;
root /ssd/projects/public/rwx.work/docs/out/docs;
}

server {
include rwx.work.conf;
server_name sites.rwx.work;
root /ssd/projects/public/rwx.work/sites/out/sites;
}

server {
include rwx.work.conf;
server_name todo.rwx.work;
root /ssd/projects/public/rwx.work/todo/out/todo;
}
  • "/etc/nginx/sites-enabled/2 marc-beninca.fr"

server {
include marc-beninca.fr.conf;
include uwsgi.conf;
server_name .marc-beninca.fr;
location / {
uwsgi_pass unix:/run/uwsgi/app/root/socket;
}
}

server {
include marc-beninca.fr.conf;
server_name cnam.marc-beninca.fr;
root /ssd/projects/public/marc-beninca.fr/cnam/out/cnam;
}

server {
include marc-beninca.fr.conf;
server_name doc.marc-beninca.fr;
root /ssd/projects/public/marc-beninca.fr/doc/out/doc;
}

server {
include marc-beninca.fr.conf;
server_name docs.marc-beninca.fr;
root /ssd/projects/public/marc-beninca.fr/docs/out/docs;
}

server {
include marc-beninca.fr.conf;
server_name places.marc-beninca.fr;
root /ssd/projects/public/marc-beninca.fr/places/out/places;
}

server {
include marc-beninca.fr.conf;
server_name sites.marc-beninca.fr;
root /ssd/projects/public/marc-beninca.fr/sites/out/sites;
}

server {
include marc-beninca.fr.conf;
server_name todo.marc-beninca.fr;
root /ssd/projects/marc-beninca.fr/todo/out/todo;
}
  • "/etc/nginx/sites-enabled/3 tilde.link"

server {
include tilde.link.conf;
include uwsgi.conf;
server_name .tilde.link;
location / {
uwsgi_pass unix:/run/uwsgi/app/root/socket;
}
}

server {
include tilde.link.conf;
server_name doc.tilde.link;
root /ssd/projects/public/tilde.link/doc/out/doc;
}

Certificate and errors

  • /etc/nginx/rwx.work.conf

include https.conf;
ssl_certificate rwx.work.crt;
ssl_certificate_key rwx.work.key;
location @error {
return https://rwx.work/error/${status};
}
  • /etc/nginx/marc-beninca.fr.conf

include https.conf;
ssl_certificate marc-beninca.fr.crt;
ssl_certificate_key marc-beninca.fr.key;
location @error {
return https://marc-beninca.fr/error/${status};
}
  • /etc/nginx/tilde.link.conf

include https.conf;
ssl_certificate tilde.link.crt;
ssl_certificate_key tilde.link.key;
location @error {
return https://tilde.link/error/${status};
}
  • /etc/nginx/rwx.work.key

  • /etc/nginx/rwx.work.crt

  • /etc/nginx/marc-beninca.fr.key

  • /etc/nginx/marc-beninca.fr.crt

  • /etc/nginx/tilde.link.key

  • /etc/nginx/tilde.link.crt