Debian 12 bookworm
Implementation sur une VM ayant 2 interface bindés sur la meme interface host ( pas top mais pas le choix pour l'instant )
Mise en place de l'application pour installation de machine physique, cette implementation ne pourra correctement fonctionner qu"avec un baremetal ayant deux interfaces reseau permettant d'eviter la guerre de boadcast ( dhcp,bootp etc ..)
Fichier /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug ens32
#iface ens32 inet dhcp
iface ens32 inet static
address 192.168.1.111/24
netmask 255.255.255.0
gateway 182.168.1.254
dns-nameservers 192.168.1.254
allow-hotplug ens35
iface ens35 inet static
address 192.168.60.254/24
netmask 255.255.255.0
Le reseau "interne" ne vois que le serveur en tant que passerrelle
Afin que les machine du reseau d'installation puissent se connecter sur le net ( eg: download de package .. ) il faut hider ce traffic par le serveur d'installation
Activer ip_forward
Editer le fichier /etc/sysctl.conf
net.ipv4.ip_forward=1
Ajouter les regles netfiler suivante :
iptables -I FORWARD 1 -i ens35 -o ens32 -s 192.168.60.0/24 -j ACCEPT
iptables -t nat -I POSTROUTING 1 -o ens32 -j MASQUERADE
Lié a l'implementation non standard réseau
Dans le cadre d'une machine avec deux interface physique distrinctes ca ne devrai pas etre nécessaire
sudo apt update
sudo apt upgrade
sudo apt install -y isc-dhcp-server tftpd-hpa nfs-kernel-server syslinux pxelinux syslinux-common
Fichier /etc/default/isc-dhcp-server
Mettre le service en ecoute sur ens35
INTERFACESv4="ens35"
Fichier /etc/dhcp/dhcpd.conf
default-lease-time 7200;
max-lease-time 7200;
authoritative;
allow unknown-clients;
#authoritautive;
option subnet-mask 255.255.255.0;
###PXE###
option space PXE;
option PXE.mtftp-ip code 1 = ip-address;
option PXE.mtftp-cport code 2 = unsigned integer 16;
option PXE.mtftp-sport code 3 = unsigned integer 16;
option PXE.mtftp-tmout code 4 = unsigned integer 8;
option PXE.mtftp-delay code 5 = unsigned integer 8;
option arch code 93 = unsigned integer 16;
option space ipxe;
option ipxe-encap-opts code 175 = encapsulate ipxe;
option ipxe.priority code 1 = signed integer 8;
option ipxe.keep-san code 8 = unsigned integer 8;
option ipxe.skip-san-boot code 9 = unsigned integer 8;
option ipxe.syslogs code 85 = string;
option ipxe.cert code 91 = string;
option ipxe.privkey code 92 = string;
option ipxe.crosscert code 93 = string;
option ipxe.no-pxedhcp code 176 = unsigned integer 8;
option ipxe.bus-id code 177 = string;
option ipxe.san-filename code 188 = string;
option ipxe.bios-drive code 189 = unsigned integer 8;
option ipxe.username code 190 = string;
option ipxe.password code 191 = string;
option ipxe.reverse-username code 192 = string;
option ipxe.reverse-password code 193 = string;
option ipxe.version code 235 = string;
option iscsi-initiator-iqn code 203 = string;
# Feature indicators
option ipxe.pxeext code 16 = unsigned integer 8;
option ipxe.iscsi code 17 = unsigned integer 8;
option ipxe.aoe code 18 = unsigned integer 8;
option ipxe.http code 19 = unsigned integer 8;
option ipxe.https code 20 = unsigned integer 8;
option ipxe.tftp code 21 = unsigned integer 8;
option ipxe.ftp code 22 = unsigned integer 8;
option ipxe.dns code 23 = unsigned integer 8;
option ipxe.bzimage code 24 = unsigned integer 8;
option ipxe.multiboot code 25 = unsigned integer 8;
option ipxe.slam code 26 = unsigned integer 8;
option ipxe.srp code 27 = unsigned integer 8;
option ipxe.nbi code 32 = unsigned integer 8;
option ipxe.pxe code 33 = unsigned integer 8;
option ipxe.elf code 34 = unsigned integer 8;
option ipxe.comboot code 35 = unsigned integer 8;
option ipxe.efi code 36 = unsigned integer 8;
option ipxe.fcoe code 37 = unsigned integer 8;
option ipxe.vlan code 38 = unsigned integer 8;
option ipxe.menu code 39 = unsigned integer 8;
option ipxe.sdi code 40 = unsigned integer 8;
option ipxe.nfs code 41 = unsigned integer 8;
subnet 192.168.60.0 netmask 255.255.255.0 {
range 192.168.60.100 192.168.60.200; # ip range
option broadcast-address 192.168.60.255;
option routers 192.168.60.254; # gateway for clients
option domain-name-servers 192.168.60.254;
ping-check = 1;
next-server 192.168.60.254; # tftpd server's IP
filename "pxelinux.0";
if exists user-class and option user-class = "iPXE" {
filename "http://192.168.60.254:4000/api/host/ipxe?uuid=${uuid}&mac=${
mac}&installip=${net0/ip}";
} else {
filename "ipxe.efi";
}
}
Relancer le service
systemctl restart isc-dhcp-server.service
sudo mkdir -p /srv/tftp
Edition /etc/default/tftpd-hpa
Binder uniquement sur l'ip associé au lan dédié a l'installation
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.60.254:69"
TFTP_OPTIONS="--secure"
Recuperation sources
apt install -y git liblzma-dev build-essential
git clone https://github.com/ipxe/ipxe.git
build undi
cd ipxe/src
make bin/undionly.kpxe
...
[BIN] bin/undionly.kpxe.bin
[ZINFO] bin/undionly.kpxe.zinfo
[ZBIN] bin/undionly.kpxe.zbin
[FINISH] bin/undionly.kpxe
rm bin/undionly.kpxe.bin bin/undionly.kpxe.zinfo bin/version.undionly.kpxe.o bin/undionly.kpxe.zbin
root@autoinstall:~/ipxe/src# cp bin/undionly.
undionly.kpxe undionly.kpxe.tmp undionly.kpxe.tmp.map undionly.o
Build efi
make bin-x86_64-efi/ipxe.efi
cp bin-x86_64-efi/ipxe.efi /srv/tftp/
Build usb
make bin-x86_64-efi/ipxe.usb
Inserer une clef usb
Verifier le path
sudo lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 10G 0 disk
├─sda1 8:1 0 487M 0 part /boot
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 9,5G 0 part
├─debian--12--model--vg-root 254:1 0 8,5G 0 lvm /
└─debian--12--model--vg-swap_1 254:2 0 976M 0 lvm [SWAP]
sdb 8:16 0 40G 0 disk
└─vg_data-lv_srv 254:0 0 20G 0 lvm /srv
sdc 8:32 1 57,8G 0 disk
├─sdc1 8:33 1 2G 0 part
├─sdc2 8:34 1 4,9M 0 part
├─sdc3 8:35 1 300K 0 part
└─sdc4 8:36 1 55,8G 0 part
sr0 11:0 1 1024M 0 rom
Effacer la cle
Bien verifier le path !! sinon ces adieu a votre disque
sudo dd if=/dev/zero of=/dev/sdc bs=512 count=1
Repartionnement
sudo cfdisk /dev/sdc
sdc 8:32 1 57,8G 0 disk
└─sdc1 8:33 1 512M 0 part
apt install dosfstools
https://gist.github.com/AdrianKoshka/5b6f8b6803092d8b108cda2f8034539a
cp bin/undionly.kpxe /srv/tftp/
Faire un test de boot
Remarque: Je desactive le DHCP de ma box pour éviter les collisions ( meme switch )
Voir https://docs.docker.com/engine/install/debian/
mkdir -p /srv/dockers/bind9/{config,cache,records}
Créer le fichier /srv/dockers/bind9/docker-compose.yml suivant
vi /srv/dockers/bind9/docker-compose.yml
version: "3"
services:
bind9:
container_name: bind-dns
image: ubuntu/bind9:latest
environment:
- BIND9_USER=root
- TZ=Europe/Paris
ports:
- "53:53/tcp"
- "53:53/udp"
volumes:
- ./config:/etc/bind
- ./cache:/var/cache/bind
- ./records:/var/lib/bind
restart: unless-stopped
fichier /srv/dockers/bind9/config/named.conf
vi /srv/dockers/bind9/config/named.conf
//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
// See the BIND Administrators Reference Manual (ARM) for details about the
// configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html
acl internal {
192.168.1.0/24;
192.168.60.0/24;
localhost;
localnets;
};
options {
# listen-on port 53 { 127.0.0.1; 10.8.10.2; };
# listen-on-v6 port 53 { ::1; };
# directory "/var/named";
# dump-file "/var/named/data/cache_dump.db";
# statistics-file "/var/named/data/named_stats.txt";
# memstatistics-file "/var/named/data/named_mem_stats.txt";
# recursing-file "/var/named/data/named.recursing";
# secroots-file "/var/named/data/named.secroots";
# allow-query { AllowQuery; };
#
#/*
# - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
# - If you are building a RECURSIVE (caching) DNS server, you need to enable
# recursion.
# - If your recursive DNS server has a public IP address, you MUST enable access
# control to limit queries to your legitimate users. Failing to do so will
# cause your server to become part of large scale DNS amplification
# attacks. Implementing BCP38 within your network would greatly
# reduce such attack surface
# */
# recursion yes;
#
# dnssec-enable yes;
# dnssec-validation yes;
#
# Using Cloudflare
forwarders {
1.1.1.1;
1.0.0.1;
};
allow-query { internal; };
# /* Path to ISC DLV key */
# bindkeys-file "/etc/named.root.key";
# managed-keys-directory "/var/named/dynamic";
# pid-file "/run/named/named.pid";
# session-keyfile "/run/named/session.key";
};
#logging {
# channel default_debug {
# file "data/named.run";
# severity dynamic;
# };
#};
zone "install.lan" IN {
type master;
file "/etc/bind/install.lan.zone";
};
fichier /srv/dockers/bind9/config/install.lan.zone
vi /srv/dockers/bind9/config/install.lan.zone
$TTL 5m
$ORIGIN install.lan.
@ IN SOA ns1.install.lan admin.install.lan (
20240419 ; serial number
3600 ; refresh period
600 ; retry period
604800 ; expire time
1800 ; negative TTL
)
@ IN NS ns1.install.lan.
ns1 IN A 192.168.60.254
; Main VLAN network services
router IN A 192.168.60.254
zeninstall IN A 192.168.60.254
fileserver IN A 192.168.60.254
tftp IN A 192.168.60.254
Lancement
cd /srv/dockers/bind9
docker compose up -d
Vérification
nslookup zeninstall.install.lan 192.168.60.254
Server: 192.168.60.254
Address: 192.168.60.254#53
Name: zeninstall.install.lan
Address: 192.168.60.254
mkdir -p /srv/dockers/traefik/{conf,ssl}
Créer le fichier /srv/dockers/traefik/docker-compose.yml suivant
networks:
traefik:
external: true
services:
traefik:
image: "traefik:v2.11"
container_name: "traefik"
hostname: traefik
restart: unless-stopped
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --log.level=ERROR
- --api
- --providers.docker=true
- --providers.file.directory=/ssl
- --providers.docker.exposedByDefault=false
# Dashboard
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.msi.stef.lan`)"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.entrypoints=websecure"
# Enables the web UI and tells Traefik to listen to docker
networks:
- traefik
ports:
# The HTTP port
- "80:80"
- "443:443"
# The Web UI (enabled by --api.insecure=true)
# - "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
- ./ssl:/ssl
Créer le fichier /srv/dockers/traefik/conf/traefik.toml
[providers.file]
filename = "/ssl/ssl.toml"
Créer le réseau docker traefik
docker network create traefik
Lancement du container
cd srv/dockers/traefik/
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
traefik traefik:v2.11 "/entrypoint.sh --en…" traefik 43 seconds ago Up 42 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp
mkdir /srv/dockers/mongo
docker network create databases
docker volume create mongo_db
Fichier /srv/dockers/mongo/docker-compose.yml
version: '3.1'
networks:
databases:
external: true
traefik:
external: true
volumes:
mongo_db:
external: true
services:
mongo:
image: mongo:6.0
hostname: mongo
container_name: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: mongo
ports:
- 27017:27017
volumes:
- mongo_db:/data/db
networks:
- databases
mongo-express:
image: mongo-express:latest
container_name: mongo-express
hostname: mongo-express
pull_policy: always
restart: always
ports:
- 8082:8081
environment:
ME_CONFIG_MONGODB_URL: "mongodb://admin:mongo@mongo:27017"
ME_CONFIG_MONGODB_ENABLE_ADMIN: "true"
networks:
- databases
- traefik
labels:
- "deployment.type=ansible"
- "traefik.docker.network=traefik"
- "traefik.enable=true"
- "traefik.http.routers.mongoexpress.rule=Host(`mongo-express.install.lan`)"
- "traefik.http.routers.mongoexpress.entrypoints=websecure"
- "traefik.http.services.mongoexpress.loadbalancer.server.port=8081"
- "traefik.http.routers.mongoexpress.tls=true"
Si besoin de restauration d'une base
Si votre host source lancer :
docker exec -i mongo /usr/bin/mongodump --username <admin user> --password <admin password> --authenticationDatabase admin --db <nom db> --archive > <nom db>.dump
Transferer votre fichier de dump sur le nouveau serveur
Restauration sur la cible
Creer votre utilisateur associé a votre base
Exemple
docker exec -ti mongo bash
mongosh -u admin -p <adm pass>
admin> use railszen
admin> db.createUser({ user: "dbuser", pwd: "dbpass", roles:[{role: "readWrite", db:"railszen"}]})
Restauration du dump
docker exec -i mongo /usr/bin/mongorestore --username dbuser --password dbpass --authenticationDatabase admin --nsInclude="railszen.*" --archive < ./railszen.dump
mkdir -p /srv/dockers/nginx/conf.d
Fichier /srv/dockers/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
autoindex on;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Fichier /srv/dockers/nginx/conf.d/default.conf
networks:
traefik:
external: true
services:
nginx:
image: nginx
hostname: nginx
container_name: nginx
restart: always
environment:
- NGINX_HOST=fileserver.install.lan
- NGINX_PORT=80
ports:
- 8080:80
volumes:
- ./conf.d/:/etc/nginx/conf.d/
- /srv/tftp/:/usr/share/nginx/html
networks:
- traefik
labels:
- "traefik.docker.network=traefik"
- "traefik.enable=true"
- "traefik.http.routers.nginx.rule=Host(`fileserver.install.lan`)"
- "traefik.http.routers.nginx.entrypoints=websecure"
- "traefik.http.services.nginx.loadbalancer.server.port=8081"
- "traefik.http.routers.nginx.tls=true"
docker compose up -d
Script a lancer ( en sudo )
#!/bin/bash
if [ ! -d /mnt/temp ]; then
mkdir -p /mnt/temp
fi
get_ubuntu (){
VERSION=$1
URL=$2
echo "Get $VERSION from $URL"
if [ ! -d /srv/tftp/isos ]; then
mkdir -p /srv/tftp/isos
fi
if [ ! -f /srv/tftp/isos/$VERSION.iso ]; then
wget -P /srv/tftp/isos $URL
fi
if [ ! -d /srv/tftp/images/$VERSION ]; then
mount -o loop /srv/tftp/isos/$VERSION.iso /mnt/temp
mkdir -p /srv/tftp/isos/$VERSION
rsync -a /mnt/temp/ /srv/tftp/images/$VERSION
umount /mnt/temp
fi
}
get_debian () {
VERSION=$1
if [ ! -d /srv/tftp/images/$VERSION ]; then
mkdir -p /srv/tftp/images/$VERSION
URL=http://ftp.fr.debian.org/debian/dists/$VERSION/main/installer-amd64/current/images/netboot/debian-installer/amd64/
wget $URL/linux -P /srv/tftp/images/$VERSION
wget $URL/initrd.gz -P /srv/tftp/images/$VERSION
fi
}
get_ubuntu ubuntu-22.04.4-live-server-amd64 https://releases.ubuntu.com/jammy/ubuntu-22.04.4-live-server-amd64.iso
get_ubuntu ubuntu-22.04.4-desktop-amd64 https://releases.ubuntu.com/jammy/ubuntu-22.04.4-desktop-amd64.iso
get_debian bookworm
get_debian bullseye
get_debian buster
rmdir /mnt/temp
cd /srv/dockers/
git clone https://gitea.zen6.info/stef/zeninstall.git
Pour l'url applicatif , editer le fichier zeninstall/src/autogen/config/application.rb
modifier la ligne config.hosts
Exemple:
config.hosts << "zeninstall.install.lan"
Editer le fichier "src/autogen/config/mongoid.yml"
clients:
# Defines the default client. (required)
default:
# Mongoid can connect to a URI accepted by the driver:
uri: mongodb://<user>:<password>@mongo:27017/<database>
cd zeninstall
docker compose build
docker compose up -d
docker compose exec -ti zeninstall bash
cd autogen/
bundle install
rails s -b 0.0.0.0
sudo mkdir -p /srv/tftp/images
Editer /etc/exports
sudo vi /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/srv/tftp/images *(ro,no_root_squash,nohide,no_subtree_check)
Rechargement de la configuration
exportfs -rav
exporting *:/srv/tftp/images