From 3d8707215996596ccf73ef1e2843c8c47e098fa7 Mon Sep 17 00:00:00 2001 From: "antoine.perederii" Date: Tue, 6 Dec 2022 19:55:00 +0100 Subject: [PATCH] ajout de systeme --- id_rsa.pub => cle_ssh/id_rsa.pub | 0 vdn/LICENCE | 17 + vdn/README | 5 + vdn/allocators/db-default/hosts | 54 + vdn/allocators/db-default/hosts.global | 14 + vdn/allocators/db-default/networks | 9 + vdn/allocators/db-default/users | 3174 +++++++++ vdn/allocators/default | 276 + vdn/allocators/resolv | 13 + vdn/authorized-root.txt | 1 + vdn/bin/bbfs | Bin 0 -> 64320 bytes vdn/bin/ext4fuse | Bin 0 -> 196296 bytes vdn/bin/functions-build.sh | 551 ++ vdn/bin/functions-scripts.sh | 635 ++ vdn/bin/functions.sh | 568 ++ vdn/bin/sae203-init | 89 + vdn/bin/vdn | 483 ++ vdn/bin/vdn-alive | 65 + vdn/bin/vdn-alives | 50 + vdn/bin/vdn-build | 92 + vdn/bin/vdn-build-db | 58 + vdn/bin/vdn-build-network | 116 + vdn/bin/vdn-busy.rb | 37 + vdn/bin/vdn-clean | 96 + vdn/bin/vdn-clean-network | 56 + vdn/bin/vdn-clone-network | 69 + vdn/bin/vdn-config | 120 + vdn/bin/vdn-create-slash | 306 + vdn/bin/vdn-delete | 56 + vdn/bin/vdn-delete-disks | 83 + vdn/bin/vdn-delete-network | 72 + vdn/bin/vdn-diff | 96 + vdn/bin/vdn-doc | 139 + vdn/bin/vdn-docker | 183 + vdn/bin/vdn-download-disks | 237 + vdn/bin/vdn-download-network | 86 + vdn/bin/vdn-exec-in-fakechroot | 27 + vdn/bin/vdn-fakechroot | 149 + vdn/bin/vdn-fakechroot-umount | 52 + vdn/bin/vdn-find-ident.old | 67 + vdn/bin/vdn-fuse-proot | 168 + vdn/bin/vdn-get-network | 50 + vdn/bin/vdn-graph | 252 + vdn/bin/vdn-gui.rb | 4127 +++++++++++ vdn/bin/vdn-halt | 91 + vdn/bin/vdn-halt-all | 50 + vdn/bin/vdn-infos | 107 + vdn/bin/vdn-kill | 83 + vdn/bin/vdn-kvm | 52 + vdn/bin/vdn-list | 47 + vdn/bin/vdn-list-networks | 55 + vdn/bin/vdn-manage-backups | 80 + vdn/bin/vdn-manage-files | 65 + vdn/bin/vdn-mount-chroot | 166 + vdn/bin/vdn-mount-chroot.bak | 190 + vdn/bin/vdn-new-network | 68 + vdn/bin/vdn-open-network | 82 + vdn/bin/vdn-prepare | 85 + vdn/bin/vdn-prepare1 | 86 + vdn/bin/vdn-publish-network | 98 + vdn/bin/vdn-push | 39 + vdn/bin/vdn-query | 102 + vdn/bin/vdn-restart | 58 + vdn/bin/vdn-restore-extra-eth | 99 + vdn/bin/vdn-save | 100 + vdn/bin/vdn-scp | 115 + vdn/bin/vdn-scripts | 227 + vdn/bin/vdn-scripts.old | 215 + vdn/bin/vdn-send-proxy | 48 + vdn/bin/vdn-set-network-dir | 84 + vdn/bin/vdn-set-var | 61 + vdn/bin/vdn-shell | 55 + vdn/bin/vdn-show | 214 + vdn/bin/vdn-singularity | 8 + vdn/bin/vdn-spice-viewer | 74 + vdn/bin/vdn-ssh | 124 + vdn/bin/vdn-ssh-copy-id | 106 + vdn/bin/vdn-ssh-loop | 54 + vdn/bin/vdn-sshfs | 118 + vdn/bin/vdn-start | 993 +++ vdn/bin/vdn-start-secure-1 | 79 + vdn/bin/vdn-start-wrapper | 47 + vdn/bin/vdn-terminal | 70 + vdn/bin/vdn-test | 3 + vdn/bin/vdn-test-all | 187 + vdn/bin/vdn-test-kvm | 88 + vdn/bin/vdn-upload-disks | 177 + vdn/bin/vdn-viewer | 65 + vdn/build-template | 6 + vdn/config.rc | 53 + vdn/config.rc.local | 53 + vdn/config.template | 228 + vdn/config.template.local | 231 + .../direct/debian/bullseye/prepare-sae.sh | 571 ++ .../guests/direct/debian/bullseye/prepare.sh | 568 ++ .../direct/debian/bullseye/rc.local.disable | 189 + .../guests/direct/debian/buster/prepare.sh | 558 ++ .../direct/debian/buster/rc.local.disable | 202 + .../guests/overlay/debian/bullseye/mount-root | 502 ++ .../guests/overlay/debian/bullseye/save | 41 + .../guests/overlay/debian/buster/mount-root | 502 ++ .../guests/overlay/debian/buster/save | 41 + .../guests/tgz/debian/bullseye/mount-root | 502 ++ vdn/distribs/guests/tgz/debian/bullseye/save | 41 + .../guests/tgz/debian/buster/mount-root | 502 ++ vdn/distribs/guests/tgz/debian/buster/save | 41 + .../hosts/debian/bullseye/download-extras.sh | 20 + vdn/distribs/hosts/debian/bullseye/prepare.sh | 62 + vdn/distribs/hosts/debian/bullseye/vte.so | Bin 0 -> 191224 bytes .../hosts/debian/buster/download-extras.sh | 20 + vdn/distribs/hosts/debian/buster/prepare.sh | 62 + vdn/distribs/hosts/debian/buster/vte.so | Bin 0 -> 115520 bytes vdn/distribs/hosts/ubuntu/bionic/vte.so | Bin 0 -> 111520 bytes vdn/distribs/hosts/ubuntu/focal/vte.so | Bin 0 -> 206200 bytes vdn/distribs/hosts/ubuntu/jammy/vte.so | Bin 0 -> 206200 bytes vdn/doc/README | 3 + vdn/doc/banner.svgz | Bin 0 -> 1837 bytes vdn/files | 1 + vdn/net-template.svgz | Bin 0 -> 33111 bytes vdn/networks.bak/bullseye-mini-cow/build | 17 + .../bullseye-mini-cow/network.vdn | 0 vdn/networks.bak/bullseye-mini-test-cow/build | 18 + .../bullseye-mini-test-cow/debian-1.conf | 231 + .../bullseye-mini-test-cow/graph.svgz | Bin 0 -> 525 bytes .../bullseye-mini-test-cow/network.vdn | 0 vdn/networks.bak/buster-mini-cow/build | 18 + vdn/networks.bak/buster-mini-cow/network.vdn | 0 vdn/networks.bak/demo-bookworm/bigboss.conf | 230 + vdn/networks.bak/demo-bookworm/build | 71 + vdn/networks.bak/demo-bookworm/graph.svgz | Bin 0 -> 1469 bytes vdn/networks.bak/demo-bookworm/lambda.conf | 230 + vdn/networks.bak/demo-bookworm/net.svgz | Bin 0 -> 33592 bytes vdn/networks.bak/demo-bookworm/network.vdn | 0 vdn/networks.bak/demo-bookworm/nomade.conf | 230 + vdn/networks.bak/demo-bookworm/scripts/atest | 6 + .../demo-bookworm/scripts/baseConfigAll | 29 + .../demo-bookworm/scripts/baseConfigBigboss | 57 + .../scripts/baseConfigBigbossTiny | 28 + .../demo-bookworm/scripts/baseConfigLambda | 73 + .../demo-bookworm/scripts/baseConfigNomade | 70 + .../demo-bookworm/scripts/baseConfigSociete | 79 + .../demo-bookworm/scripts/baseConfigTiny | 56 + .../demo-bookworm/scripts/baseConfigWeb | 63 + .../demo-bookworm/scripts/configIPv6 | 62 + vdn/networks.bak/demo-bookworm/scripts/errors | 5 + .../demo-bookworm/scripts/errors-src/Makefile | 4 + .../scripts/errors-src/errorsWrapper | Bin 0 -> 19848 bytes .../scripts/errors-src/errorsWrapper.c | 13 + .../scripts/errors-src/qH3UmebTg5 | 139 + .../demo-bookworm/scripts/repairAll-1A | 666 ++ .../demo-bookworm/scripts/repairApache2 | 304 + .../demo-bookworm/scripts/repairDhcp | 67 + .../demo-bookworm/scripts/repairFirewall | 109 + .../demo-bookworm/scripts/repairIPv6 | 86 + .../demo-bookworm/scripts/repairNfs | 40 + .../demo-bookworm/scripts/repairProftpd | 76 + .../demo-bookworm/scripts/repairUsersTotoTiti | 43 + .../demo-bookworm/scripts/testAll-1A | 160 + .../demo-bookworm/scripts/testApache2 | 140 + .../demo-bookworm/scripts/testBigbossTiny | 37 + .../demo-bookworm/scripts/testDHCPBigbossTiny | 125 + .../demo-bookworm/scripts/testDhcp | 36 + .../demo-bookworm/scripts/testFirewall | 20 + .../demo-bookworm/scripts/testIPv6 | 40 + .../scripts/testMyCompanyFirewall | 136 + .../demo-bookworm/scripts/testNfs | 28 + .../demo-bookworm/scripts/testProftpd | 40 + vdn/networks.bak/demo-bookworm/societe.conf | 230 + vdn/networks.bak/demo-bookworm/tiny.conf | 230 + vdn/networks.bak/demo-bookworm/web.conf | 230 + .../demo-bullseye.bak/bigboss.conf | 230 + vdn/networks.bak/demo-bullseye.bak/build | 62 + vdn/networks.bak/demo-bullseye.bak/graph.svgz | Bin 0 -> 1478 bytes .../demo-bullseye.bak/lambda.conf | 230 + vdn/networks.bak/demo-bullseye.bak/net.svgz | Bin 0 -> 33592 bytes .../demo-bullseye.bak/network.vdn | 0 .../demo-bullseye.bak/nomade.conf | 230 + .../demo-bullseye.bak/scripts/baseConfigAll | 29 + .../scripts/baseConfigBigboss | 57 + .../scripts/baseConfigLambda | 69 + .../scripts/baseConfigNomade | 70 + .../scripts/baseConfigSociete | 79 + .../demo-bullseye.bak/scripts/baseConfigTiny | 56 + .../demo-bullseye.bak/scripts/baseConfigWeb | 60 + .../demo-bullseye.bak/scripts/configFirewall | 107 + .../demo-bullseye.bak/scripts/configIPv6 | 62 + .../demo-bullseye.bak/scripts/diag1 | 51 + .../demo-bullseye.bak/scripts/diag2 | 19 + .../demo-bullseye.bak/scripts/diag3 | 19 + .../demo-bullseye.bak/scripts/repairFirewall | 109 + .../demo-bullseye.bak/scripts/repairIPv6 | 86 + .../demo-bullseye.bak/scripts/testFirewall | 20 + .../demo-bullseye.bak/scripts/testIPv6 | 40 + .../scripts/testMyCompanyFirewall | 136 + .../demo-bullseye.bak/societe.conf | 230 + vdn/networks.bak/demo-bullseye.bak/tiny.conf | 230 + vdn/networks.bak/demo-bullseye.bak/web.conf | 230 + vdn/networks.bak/demo-bullseye/bigboss.conf | 228 + vdn/networks.bak/demo-bullseye/build | 71 + vdn/networks.bak/demo-bullseye/graph.svgz | Bin 0 -> 1491 bytes vdn/networks.bak/demo-bullseye/lambda.conf | 228 + vdn/networks.bak/demo-bullseye/net.svgz | Bin 0 -> 33592 bytes vdn/networks.bak/demo-bullseye/network.vdn | 0 vdn/networks.bak/demo-bullseye/nomade.conf | 228 + .../scripts/.baseConfigSociete.swp | Bin 0 -> 12288 bytes vdn/networks.bak/demo-bullseye/scripts/atest | 6 + .../demo-bullseye/scripts/baseConfigAll | 29 + .../demo-bullseye/scripts/baseConfigBigboss | 57 + .../scripts/baseConfigBigbossTiny | 28 + .../demo-bullseye/scripts/baseConfigLambda | 73 + .../demo-bullseye/scripts/baseConfigNomade | 70 + .../demo-bullseye/scripts/baseConfigSociete | 79 + .../demo-bullseye/scripts/baseConfigTiny | 56 + .../demo-bullseye/scripts/baseConfigWeb | 63 + .../demo-bullseye/scripts/configIPv6 | 62 + vdn/networks.bak/demo-bullseye/scripts/errors | 5 + .../demo-bullseye/scripts/errors-src/Makefile | 4 + .../scripts/errors-src/errorsWrapper | Bin 0 -> 19848 bytes .../scripts/errors-src/errorsWrapper.c | 13 + .../scripts/errors-src/qH3UmebTg5 | 139 + .../demo-bullseye/scripts/repairAll-1A | 666 ++ .../demo-bullseye/scripts/repairApache2 | 304 + .../demo-bullseye/scripts/repairDhcp | 67 + .../demo-bullseye/scripts/repairFirewall | 109 + .../demo-bullseye/scripts/repairIPv6 | 86 + .../demo-bullseye/scripts/repairNfs | 40 + .../demo-bullseye/scripts/repairProftpd | 76 + .../demo-bullseye/scripts/repairUsersTotoTiti | 43 + .../demo-bullseye/scripts/testAll-1A | 160 + .../demo-bullseye/scripts/testApache2 | 140 + .../demo-bullseye/scripts/testBigbossTiny | 37 + .../demo-bullseye/scripts/testDHCPBigbossTiny | 125 + .../demo-bullseye/scripts/testDhcp | 36 + .../demo-bullseye/scripts/testFirewall | 20 + .../demo-bullseye/scripts/testIPv6 | 40 + .../scripts/testMyCompanyFirewall | 136 + .../demo-bullseye/scripts/testNfs | 28 + .../demo-bullseye/scripts/testProftpd | 40 + vdn/networks.bak/demo-bullseye/societe.conf | 228 + vdn/networks.bak/demo-bullseye/tiny.conf | 228 + vdn/networks.bak/demo-bullseye/web.conf | 228 + vdn/networks.bak/demo-buster/bigboss.conf | 228 + vdn/networks.bak/demo-buster/build | 71 + vdn/networks.bak/demo-buster/graph.svgz | Bin 0 -> 1488 bytes vdn/networks.bak/demo-buster/lambda.conf | 228 + vdn/networks.bak/demo-buster/net.svgz | Bin 0 -> 33592 bytes vdn/networks.bak/demo-buster/network.vdn | 0 vdn/networks.bak/demo-buster/nomade.conf | 228 + vdn/networks.bak/demo-buster/scripts/atest | 6 + .../demo-buster/scripts/baseConfigAll | 29 + .../demo-buster/scripts/baseConfigBigboss | 57 + .../demo-buster/scripts/baseConfigBigbossTiny | 28 + .../demo-buster/scripts/baseConfigLambda | 73 + .../demo-buster/scripts/baseConfigNomade | 70 + .../demo-buster/scripts/baseConfigSociete | 79 + .../demo-buster/scripts/baseConfigTiny | 56 + .../demo-buster/scripts/baseConfigWeb | 63 + .../demo-buster/scripts/configIPv6 | 62 + vdn/networks.bak/demo-buster/scripts/errors | 5 + .../demo-buster/scripts/errors-src/Makefile | 4 + .../scripts/errors-src/errorsWrapper | Bin 0 -> 19848 bytes .../scripts/errors-src/errorsWrapper.c | 13 + .../demo-buster/scripts/errors-src/qH3UmebTg5 | 139 + .../demo-buster/scripts/repairAll-1A | 666 ++ .../demo-buster/scripts/repairApache2 | 304 + .../demo-buster/scripts/repairDhcp | 67 + .../demo-buster/scripts/repairFirewall | 109 + .../demo-buster/scripts/repairIPv6 | 86 + .../demo-buster/scripts/repairNfs | 40 + .../demo-buster/scripts/repairProftpd | 76 + .../demo-buster/scripts/repairUsersTotoTiti | 43 + .../demo-buster/scripts/testAll-1A | 160 + .../demo-buster/scripts/testApache2 | 140 + .../demo-buster/scripts/testBigbossTiny | 37 + .../demo-buster/scripts/testDHCPBigbossTiny | 125 + vdn/networks.bak/demo-buster/scripts/testDhcp | 36 + .../demo-buster/scripts/testFirewall | 20 + vdn/networks.bak/demo-buster/scripts/testIPv6 | 40 + .../demo-buster/scripts/testMyCompanyFirewall | 136 + vdn/networks.bak/demo-buster/scripts/testNfs | 28 + .../demo-buster/scripts/testProftpd | 40 + vdn/networks.bak/demo-buster/societe.conf | 228 + vdn/networks.bak/demo-buster/tiny.conf | 228 + vdn/networks.bak/demo-buster/web.conf | 228 + vdn/networks.bak/demo/bigboss.conf | 228 + vdn/networks.bak/demo/build | 71 + vdn/networks.bak/demo/graph.svgz | Bin 0 -> 1491 bytes vdn/networks.bak/demo/lambda.conf | 228 + vdn/networks.bak/demo/net.svgz | Bin 0 -> 33592 bytes vdn/networks.bak/demo/network.vdn | 0 vdn/networks.bak/demo/nomade.conf | 228 + .../demo/scripts/.baseConfigSociete.swp | Bin 0 -> 12288 bytes vdn/networks.bak/demo/scripts/atest | 6 + vdn/networks.bak/demo/scripts/baseConfigAll | 29 + .../demo/scripts/baseConfigBigboss | 57 + .../demo/scripts/baseConfigBigbossTiny | 28 + .../demo/scripts/baseConfigLambda | 73 + .../demo/scripts/baseConfigNomade | 70 + .../demo/scripts/baseConfigSociete | 79 + vdn/networks.bak/demo/scripts/baseConfigTiny | 56 + vdn/networks.bak/demo/scripts/baseConfigWeb | 63 + vdn/networks.bak/demo/scripts/configIPv6 | 62 + vdn/networks.bak/demo/scripts/errors | 5 + .../demo/scripts/errors-src/Makefile | 4 + .../demo/scripts/errors-src/errorsWrapper | Bin 0 -> 19848 bytes .../demo/scripts/errors-src/errorsWrapper.c | 13 + .../demo/scripts/errors-src/qH3UmebTg5 | 139 + vdn/networks.bak/demo/scripts/repairAll-1A | 666 ++ vdn/networks.bak/demo/scripts/repairApache2 | 304 + vdn/networks.bak/demo/scripts/repairDhcp | 67 + vdn/networks.bak/demo/scripts/repairFirewall | 109 + vdn/networks.bak/demo/scripts/repairIPv6 | 86 + vdn/networks.bak/demo/scripts/repairNfs | 40 + vdn/networks.bak/demo/scripts/repairProftpd | 76 + .../demo/scripts/repairUsersTotoTiti | 43 + vdn/networks.bak/demo/scripts/testAll-1A | 160 + vdn/networks.bak/demo/scripts/testApache2 | 140 + vdn/networks.bak/demo/scripts/testBigbossTiny | 37 + .../demo/scripts/testDHCPBigbossTiny | 125 + vdn/networks.bak/demo/scripts/testDhcp | 36 + vdn/networks.bak/demo/scripts/testFirewall | 20 + vdn/networks.bak/demo/scripts/testIPv6 | 40 + .../demo/scripts/testMyCompanyFirewall | 136 + vdn/networks.bak/demo/scripts/testNfs | 28 + vdn/networks.bak/demo/scripts/testProftpd | 40 + vdn/networks.bak/demo/societe.conf | 228 + vdn/networks.bak/demo/tiny.conf | 228 + vdn/networks.bak/demo/web.conf | 228 + vdn/networks.bak/docker-buster/build | 27 + .../system/docker.service.d/http-proxy.conf | 5 + vdn/networks.bak/docker-buster/net.svgz | Bin 0 -> 8030 bytes vdn/networks.bak/docker-buster/network.vdn | 0 vdn/networks.bak/docker-buster/scripts/test | 13 + vdn/networks.bak/docker-tmp-buster/build | 30 + .../system/docker.service.d/http-proxy.conf | 5 + vdn/networks.bak/docker-tmp-buster/net.svgz | Bin 0 -> 8030 bytes .../docker-tmp-buster/network.vdn | 0 .../docker-tmp-buster/scripts/test | 13 + vdn/networks.bak/firewall-buster/build | 61 + vdn/networks.bak/firewall-buster/net.svgz | Bin 0 -> 33387 bytes vdn/networks.bak/firewall-buster/network.vdn | 0 .../firewall-buster/scripts/baseConfigBigboss | 57 + .../firewall-buster/scripts/baseConfigLambda | 70 + .../firewall-buster/scripts/baseConfigNomade | 71 + .../firewall-buster/scripts/baseConfigSociete | 158 + .../firewall-buster/scripts/baseConfigTiny | 54 + .../firewall-buster/scripts/baseConfigWeb | 61 + .../firewall-buster/scripts/configAll | 120 + .../firewall-buster/scripts/repairAll | 192 + .../firewall-buster/scripts/testAll | 136 + .../firewall-buster/scripts/testAll-fast | 136 + vdn/networks.bak/fixme-bookworm/appolo.conf | 230 + .../fixme-bookworm/brightside.conf | 230 + vdn/networks.bak/fixme-bookworm/build | 68 + .../fixme-bookworm/castafiore.conf | 230 + vdn/networks.bak/fixme-bookworm/client.conf | 230 + vdn/networks.bak/fixme-bookworm/comanche.conf | 230 + vdn/networks.bak/fixme-bookworm/darkside.conf | 230 + .../fixme-bookworm/distributeur.conf | 230 + vdn/networks.bak/fixme-bookworm/graph.svgz | Bin 0 -> 1738 bytes vdn/networks.bak/fixme-bookworm/net.svgz | Bin 0 -> 14685 bytes vdn/networks.bak/fixme-bookworm/network.vdn | 0 .../fixme-bookworm/passerelle.conf | 230 + .../fixme-bookworm/scripts/configAll | 15 + .../fixme-bookworm/scripts/configAppolo | 50 + .../fixme-bookworm/scripts/configBrightside | 71 + .../fixme-bookworm/scripts/configCastafiore | 90 + .../fixme-bookworm/scripts/configClient | 55 + .../fixme-bookworm/scripts/configComanche | 62 + .../fixme-bookworm/scripts/configDarkside | 74 + .../fixme-bookworm/scripts/configDistributeur | 141 + .../fixme-bookworm/scripts/configPasserelle | 114 + .../fixme-bookworm/scripts/repairAll | 110 + .../fixme-bookworm/scripts/testAll | 99 + .../fixme-bookworm/scripts/testAll-fast | 99 + vdn/networks.bak/fixme-bullseye/appolo.conf | 230 + .../fixme-bullseye/brightside.conf | 230 + vdn/networks.bak/fixme-bullseye/build | 68 + .../fixme-bullseye/castafiore.conf | 230 + vdn/networks.bak/fixme-bullseye/client.conf | 230 + vdn/networks.bak/fixme-bullseye/comanche.conf | 230 + vdn/networks.bak/fixme-bullseye/darkside.conf | 230 + .../fixme-bullseye/distributeur.conf | 230 + vdn/networks.bak/fixme-bullseye/graph.svgz | Bin 0 -> 1726 bytes vdn/networks.bak/fixme-bullseye/net.svgz | Bin 0 -> 14685 bytes vdn/networks.bak/fixme-bullseye/network.vdn | 0 .../fixme-bullseye/passerelle.conf | 230 + .../fixme-bullseye/scripts/configAll | 15 + .../fixme-bullseye/scripts/configAppolo | 50 + .../fixme-bullseye/scripts/configBrightside | 71 + .../fixme-bullseye/scripts/configCastafiore | 90 + .../fixme-bullseye/scripts/configClient | 55 + .../fixme-bullseye/scripts/configComanche | 62 + .../fixme-bullseye/scripts/configDarkside | 74 + .../fixme-bullseye/scripts/configDistributeur | 141 + .../fixme-bullseye/scripts/configPasserelle | 114 + .../fixme-bullseye/scripts/repairAll | 110 + .../fixme-bullseye/scripts/testAll | 99 + .../fixme-bullseye/scripts/testAll-fast | 99 + vdn/networks.bak/fixme-buster/appolo.conf | 230 + vdn/networks.bak/fixme-buster/brightside.conf | 230 + vdn/networks.bak/fixme-buster/build | 68 + vdn/networks.bak/fixme-buster/castafiore.conf | 230 + vdn/networks.bak/fixme-buster/client.conf | 230 + vdn/networks.bak/fixme-buster/comanche.conf | 230 + vdn/networks.bak/fixme-buster/darkside.conf | 230 + .../fixme-buster/distributeur.conf | 230 + vdn/networks.bak/fixme-buster/graph.svgz | Bin 0 -> 1722 bytes vdn/networks.bak/fixme-buster/net.svgz | Bin 0 -> 14685 bytes vdn/networks.bak/fixme-buster/network.vdn | 0 vdn/networks.bak/fixme-buster/passerelle.conf | 230 + .../fixme-buster/scripts/configAll | 15 + .../fixme-buster/scripts/configAppolo | 50 + .../fixme-buster/scripts/configBrightside | 71 + .../fixme-buster/scripts/configCastafiore | 90 + .../fixme-buster/scripts/configClient | 55 + .../fixme-buster/scripts/configComanche | 62 + .../fixme-buster/scripts/configDarkside | 74 + .../fixme-buster/scripts/configDistributeur | 141 + .../fixme-buster/scripts/configPasserelle | 114 + .../fixme-buster/scripts/repairAll | 110 + vdn/networks.bak/fixme-buster/scripts/testAll | 99 + .../fixme-buster/scripts/testAll-fast | 99 + vdn/networks.bak/fixme/build | 66 + vdn/networks.bak/fixme/fixme-scripts.tgz | Bin 0 -> 5140 bytes vdn/networks.bak/fixme/net.svgz | Bin 0 -> 14685 bytes vdn/networks.bak/fixme/network.vdn | 0 vdn/networks.bak/fixme/scripts/configAll | 15 + vdn/networks.bak/fixme/scripts/configAppolo | 50 + .../fixme/scripts/configBrightside | 71 + .../fixme/scripts/configCastafiore | 90 + vdn/networks.bak/fixme/scripts/configClient | 55 + vdn/networks.bak/fixme/scripts/configComanche | 62 + vdn/networks.bak/fixme/scripts/configDarkside | 74 + .../fixme/scripts/configDistributeur | 141 + .../fixme/scripts/configPasserelle | 114 + vdn/networks.bak/fixme/scripts/repairAll | 110 + vdn/networks.bak/fixme/scripts/testAll | 99 + vdn/networks.bak/fixme/scripts/testAll-fast | 99 + vdn/networks.bak/k8s-bullseye/build | 63 + vdn/networks.bak/k8s-bullseye/net.svgz | Bin 0 -> 18089 bytes vdn/networks.bak/k8s-bullseye/network.vdn | 0 .../k8s-bullseye/scripts/baseConfigAll | 29 + .../k8s-bullseye/scripts/baseConfigBigboss | 57 + .../k8s-bullseye/scripts/baseConfigLambda | 69 + .../k8s-bullseye/scripts/baseConfigNomade | 70 + .../k8s-bullseye/scripts/baseConfigSociete | 79 + .../k8s-bullseye/scripts/baseConfigTiny | 56 + .../k8s-bullseye/scripts/baseConfigWeb | 60 + .../k8s-bullseye/scripts/configFirewall | 107 + .../k8s-bullseye/scripts/configIPv6 | 62 + vdn/networks.bak/k8s-bullseye/scripts/diag1 | 51 + vdn/networks.bak/k8s-bullseye/scripts/diag2 | 19 + vdn/networks.bak/k8s-bullseye/scripts/diag3 | 19 + .../k8s-bullseye/scripts/repairFirewall | 109 + .../k8s-bullseye/scripts/repairIPv6 | 86 + .../k8s-bullseye/scripts/testFirewall | 20 + .../k8s-bullseye/scripts/testIPv6 | 40 + .../scripts/testMyCompanyFirewall | 136 + .../migration-buster-bullseye/build | 24 + .../migration-buster-bullseye/network.vdn | 0 vdn/networks.bak/random-buster/build | 80 + vdn/networks.bak/random-buster/hosts | 15 + vdn/networks.bak/random-buster/network.vdn | 0 .../random-buster/vm-1.interfaces | 1 + .../random-buster/vm-2.interfaces | 1 + .../random-buster/vm-3.interfaces | 1 + .../random-buster/vm-4.interfaces | 1 + .../random-buster/vm-5.interfaces | 1 + .../random-buster/vm-6.interfaces | 1 + .../random-buster/vm-7.interfaces | 1 + .../random-buster/vm-8.interfaces | 1 + vdn/networks.bak/routing-ospf-bookworm/build | 56 + .../routing-ospf-bookworm/graph.svgz | Bin 0 -> 2057 bytes .../routing-ospf-bookworm/net.svgz | Bin 0 -> 25312 bytes .../routing-ospf-bookworm/network.vdn | 0 .../routing-ospf-bookworm/r1.conf | 230 + .../routing-ospf-bookworm/r2.conf | 230 + .../routing-ospf-bookworm/r3.conf | 230 + .../routing-ospf-bookworm/r4.conf | 230 + .../routing-ospf-bookworm/r5.conf | 230 + .../routing-ospf-bookworm/s1.conf | 230 + .../routing-ospf-bookworm/s2.conf | 230 + .../routing-ospf-bookworm/scripts/common.sh | 140 + .../routing-ospf-bookworm/scripts/configAll | 21 + .../routing-ospf-bookworm/scripts/configR1 | 53 + .../routing-ospf-bookworm/scripts/configR2 | 51 + .../routing-ospf-bookworm/scripts/configR3 | 56 + .../routing-ospf-bookworm/scripts/configR4 | 48 + .../routing-ospf-bookworm/scripts/configR5 | 53 + .../routing-ospf-bookworm/scripts/configS1 | 40 + .../routing-ospf-bookworm/scripts/configS2 | 41 + .../routing-ospf-bookworm/scripts/ping-all | 29 + .../scripts/ping-all-without-r2 | 31 + .../routing-ospf-bookworm/scripts/repairAll | 20 + .../routing-ospf-bookworm/scripts/repairR2 | 16 + .../routing-ospf-bookworm/scripts/testWithR2 | 8 + .../scripts/testWithoutR2 | 8 + vdn/networks.bak/routing-ospf-bullseye/build | 56 + .../routing-ospf-bullseye/graph.svgz | Bin 0 -> 2068 bytes .../routing-ospf-bullseye/net.svgz | Bin 0 -> 25312 bytes .../routing-ospf-bullseye/network.vdn | 0 .../routing-ospf-bullseye/r1.conf | 230 + .../routing-ospf-bullseye/r2.conf | 230 + .../routing-ospf-bullseye/r3.conf | 230 + .../routing-ospf-bullseye/r4.conf | 230 + .../routing-ospf-bullseye/r5.conf | 230 + .../routing-ospf-bullseye/s1.conf | 230 + .../routing-ospf-bullseye/s2.conf | 230 + .../routing-ospf-bullseye/scripts/common.sh | 140 + .../routing-ospf-bullseye/scripts/configAll | 21 + .../routing-ospf-bullseye/scripts/configR1 | 53 + .../routing-ospf-bullseye/scripts/configR2 | 51 + .../routing-ospf-bullseye/scripts/configR3 | 56 + .../routing-ospf-bullseye/scripts/configR4 | 48 + .../routing-ospf-bullseye/scripts/configR5 | 53 + .../routing-ospf-bullseye/scripts/configS1 | 40 + .../routing-ospf-bullseye/scripts/configS2 | 41 + .../routing-ospf-bullseye/scripts/ping-all | 29 + .../scripts/ping-all-without-r2 | 31 + .../routing-ospf-bullseye/scripts/repairAll | 20 + .../routing-ospf-bullseye/scripts/repairR2 | 16 + .../routing-ospf-bullseye/scripts/testWithR2 | 8 + .../scripts/testWithoutR2 | 8 + vdn/networks.bak/routing-ospf-buster/build | 56 + .../routing-ospf-buster/graph.svgz | Bin 0 -> 2057 bytes vdn/networks.bak/routing-ospf-buster/net.svgz | Bin 0 -> 25312 bytes .../routing-ospf-buster/network.vdn | 3 + vdn/networks.bak/routing-ospf-buster/r1.conf | 228 + vdn/networks.bak/routing-ospf-buster/r2.conf | 228 + vdn/networks.bak/routing-ospf-buster/r3.conf | 228 + vdn/networks.bak/routing-ospf-buster/r4.conf | 228 + vdn/networks.bak/routing-ospf-buster/r5.conf | 228 + vdn/networks.bak/routing-ospf-buster/s1.conf | 228 + vdn/networks.bak/routing-ospf-buster/s2.conf | 228 + .../routing-ospf-buster/scripts/common.sh | 80 + .../routing-ospf-buster/scripts/configAll | 21 + .../routing-ospf-buster/scripts/configR1 | 53 + .../routing-ospf-buster/scripts/configR2 | 51 + .../routing-ospf-buster/scripts/configR3 | 56 + .../routing-ospf-buster/scripts/configR4 | 48 + .../routing-ospf-buster/scripts/configR5 | 53 + .../routing-ospf-buster/scripts/configS1 | 40 + .../routing-ospf-buster/scripts/configS2 | 41 + .../routing-ospf-buster/scripts/ping-all | 29 + .../scripts/ping-all-without-r2 | 31 + .../routing-ospf-buster/scripts/repairAll | 20 + .../routing-ospf-buster/scripts/repairR2 | 16 + .../routing-ospf-buster/scripts/testWithR2 | 8 + .../routing-ospf-buster/scripts/testWithoutR2 | 8 + vdn/networks.bak/routing-rip-buster/build | 60 + .../routing-rip-buster/graph.svgz | Bin 0 -> 2058 bytes vdn/networks.bak/routing-rip-buster/net.svgz | Bin 0 -> 25312 bytes .../routing-rip-buster/network.vdn | 0 vdn/networks.bak/routing-rip-buster/r1.conf | 230 + vdn/networks.bak/routing-rip-buster/r2.conf | 230 + vdn/networks.bak/routing-rip-buster/r3.conf | 230 + vdn/networks.bak/routing-rip-buster/r4.conf | 230 + vdn/networks.bak/routing-rip-buster/r5.conf | 230 + vdn/networks.bak/routing-rip-buster/s1.conf | 230 + vdn/networks.bak/routing-rip-buster/s2.conf | 230 + .../routing-rip-buster/scripts/common.sh | 87 + .../routing-rip-buster/scripts/configAll | 21 + .../routing-rip-buster/scripts/configR1 | 54 + .../routing-rip-buster/scripts/configR2 | 52 + .../routing-rip-buster/scripts/configR3 | 52 + .../routing-rip-buster/scripts/configR4 | 48 + .../routing-rip-buster/scripts/configR5 | 53 + .../routing-rip-buster/scripts/configS1 | 39 + .../routing-rip-buster/scripts/configS2 | 38 + .../routing-rip-buster/scripts/ping-all | 29 + .../scripts/ping-all-without-r2 | 31 + .../routing-rip-buster/scripts/repairAll | 18 + .../routing-rip-buster/scripts/repairR2 | 15 + .../routing-rip-buster/scripts/testWithR2 | 8 + .../routing-rip-buster/scripts/testWithoutR2 | 8 + vdn/networks.bak/routing-static-buster/build | 61 + .../routing-static-buster/graph.svgz | Bin 0 -> 2102 bytes .../routing-static-buster/net.svgz | Bin 0 -> 25312 bytes .../routing-static-buster/net2.svg | 6221 +++++++++++++++++ .../routing-static-buster/network.vdn | 3 + .../routing-static-buster/r1.conf | 228 + .../routing-static-buster/r2.conf | 228 + .../routing-static-buster/r3.conf | 228 + .../routing-static-buster/r4.conf | 228 + .../routing-static-buster/r5.conf | 228 + .../routing-static-buster/s1.conf | 228 + .../routing-static-buster/s2.conf | 228 + .../routing-static-buster/scripts/common.sh | 17 + .../routing-static-buster/scripts/configAll | 20 + .../routing-static-buster/scripts/configR1 | 53 + .../routing-static-buster/scripts/configR2 | 51 + .../routing-static-buster/scripts/configR3 | 55 + .../routing-static-buster/scripts/configR4 | 50 + .../routing-static-buster/scripts/configR5 | 55 + .../routing-static-buster/scripts/configS1 | 40 + .../routing-static-buster/scripts/configS2 | 39 + .../routing-static-buster/scripts/ping-all | 29 + .../scripts/ping-all-without-r2 | 31 + .../routing-static-buster/scripts/repairAll | 17 + .../routing-static-buster/scripts/repairR2 | 42 + vdn/networks.bak/sae203/build | 22 + vdn/networks.bak/sae203/net.svgz | Bin 0 -> 13753 bytes vdn/networks.bak/sae203/network.vdn | 0 vdn/networks.bak/sae203/scripts/baseConfig | 47 + vdn/networks.bak/secure-1-buster/build | 23 + vdn/networks.bak/secure-1-buster/net.svgz | Bin 0 -> 17294 bytes vdn/networks.bak/secure-1-buster/network.vdn | 0 .../secure-1-buster/scripts/baseConfig | 47 + vdn/networks.bak/secure-buster/build | 23 + vdn/networks.bak/secure-buster/net.svgz | Bin 0 -> 17287 bytes vdn/networks.bak/secure-buster/network.vdn | 0 .../secure-buster/scripts/baseConfigAll | 28 + .../secure-buster/scripts/baseConfigBigboss | 58 + .../secure-buster/scripts/baseConfigLambda | 69 + .../secure-buster/scripts/baseConfigNomade | 70 + .../secure-buster/scripts/baseConfigSociete | 79 + .../secure-buster/scripts/baseConfigTiny | 54 + .../secure-buster/scripts/baseConfigWeb | 60 + .../secure-buster/scripts/configFirewall | 107 + .../secure-buster/scripts/configIPv6 | 62 + vdn/networks.bak/secure-buster/scripts/diag1 | 51 + vdn/networks.bak/secure-buster/scripts/diag2 | 19 + vdn/networks.bak/secure-buster/scripts/diag3 | 19 + .../secure-buster/scripts/diagFirewall | 22 + .../secure-buster/scripts/diagIPv6 | 39 + .../secure-buster/scripts/testFirewall | 109 + .../secure-buster/scripts/testIPv6 | 86 + vdn/networks.bak/zoo/bookworm.conf | 230 + vdn/networks.bak/zoo/build | 75 + vdn/networks.bak/zoo/bullseye-sae.conf | 230 + vdn/networks.bak/zoo/bullseye-test.conf | 230 + vdn/networks.bak/zoo/bullseye.conf | 230 + vdn/networks.bak/zoo/buster-tgz2.conf | 230 + vdn/networks.bak/zoo/buster.conf | 230 + vdn/networks.bak/zoo/graph.svgz | Bin 0 -> 765 bytes vdn/networks.bak/zoo/network.vdn | 0 .../scripts/.prepareDebianBullseye-test.swp | Bin 0 -> 12288 bytes vdn/networks.bak/zoo/scripts/prepareDebian | 143 + .../zoo/scripts/prepareDebian.old | 31 + .../zoo/scripts/prepareDebian.old2 | 120 + .../zoo/scripts/prepareDebianBookworm | 9 + .../zoo/scripts/prepareDebianBullseye | 9 + .../zoo/scripts/prepareDebianBullseye-test | 30 + .../zoo/scripts/prepareDebianBuster | 9 + vdn/networks.bak/zoo/scripts/prepareKali | 34 + vdn/networks/demo-buster/bigboss.conf | 228 + vdn/networks/demo-buster/build | 71 + vdn/networks/demo-buster/graph.svgz | Bin 0 -> 1479 bytes vdn/networks/demo-buster/lambda.conf | 228 + vdn/networks/demo-buster/net.svgz | Bin 0 -> 33592 bytes vdn/networks/demo-buster/network.vdn | 0 vdn/networks/demo-buster/nomade.conf | 228 + vdn/networks/demo-buster/scripts/atest | 6 + .../demo-buster/scripts/baseConfigAll | 29 + .../demo-buster/scripts/baseConfigBigboss | 57 + .../demo-buster/scripts/baseConfigBigbossTiny | 28 + .../demo-buster/scripts/baseConfigLambda | 73 + .../demo-buster/scripts/baseConfigNomade | 70 + .../demo-buster/scripts/baseConfigSociete | 79 + .../demo-buster/scripts/baseConfigTiny | 56 + .../demo-buster/scripts/baseConfigWeb | 63 + vdn/networks/demo-buster/scripts/configIPv6 | 62 + vdn/networks/demo-buster/scripts/errors | 5 + .../demo-buster/scripts/errors-src/Makefile | 4 + .../scripts/errors-src/errorsWrapper | Bin 0 -> 19848 bytes .../scripts/errors-src/errorsWrapper.c | 13 + .../demo-buster/scripts/errors-src/qH3UmebTg5 | 139 + vdn/networks/demo-buster/scripts/repairAll-1A | 666 ++ .../demo-buster/scripts/repairApache2 | 304 + vdn/networks/demo-buster/scripts/repairDhcp | 67 + .../demo-buster/scripts/repairFirewall | 109 + vdn/networks/demo-buster/scripts/repairIPv6 | 86 + vdn/networks/demo-buster/scripts/repairNfs | 40 + .../demo-buster/scripts/repairProftpd | 76 + .../demo-buster/scripts/repairUsersTotoTiti | 43 + vdn/networks/demo-buster/scripts/testAll-1A | 160 + vdn/networks/demo-buster/scripts/testApache2 | 140 + .../demo-buster/scripts/testBigbossTiny | 37 + .../demo-buster/scripts/testDHCPBigbossTiny | 125 + vdn/networks/demo-buster/scripts/testDhcp | 36 + vdn/networks/demo-buster/scripts/testFirewall | 20 + vdn/networks/demo-buster/scripts/testIPv6 | 40 + .../demo-buster/scripts/testMyCompanyFirewall | 136 + vdn/networks/demo-buster/scripts/testNfs | 28 + vdn/networks/demo-buster/scripts/testProftpd | 40 + vdn/networks/demo-buster/societe.conf | 228 + vdn/networks/demo-buster/tiny.conf | 228 + vdn/networks/demo-buster/web.conf | 228 + vdn/networks/demo/bigboss.conf | 228 + vdn/networks/demo/build | 71 + vdn/networks/demo/graph.svgz | Bin 0 -> 1492 bytes vdn/networks/demo/lambda.conf | 228 + vdn/networks/demo/net.svgz | Bin 0 -> 33592 bytes vdn/networks/demo/network.vdn | 0 vdn/networks/demo/nomade.conf | 228 + vdn/networks/demo/scripts/atest | 6 + vdn/networks/demo/scripts/baseConfigAll | 29 + vdn/networks/demo/scripts/baseConfigBigboss | 57 + .../demo/scripts/baseConfigBigbossTiny | 28 + vdn/networks/demo/scripts/baseConfigLambda | 73 + vdn/networks/demo/scripts/baseConfigNomade | 70 + vdn/networks/demo/scripts/baseConfigSociete | 79 + vdn/networks/demo/scripts/baseConfigTiny | 56 + vdn/networks/demo/scripts/baseConfigWeb | 63 + vdn/networks/demo/scripts/configIPv6 | 62 + vdn/networks/demo/scripts/errors | 5 + vdn/networks/demo/scripts/errors-src/Makefile | 4 + .../demo/scripts/errors-src/errorsWrapper | Bin 0 -> 19848 bytes .../demo/scripts/errors-src/errorsWrapper.c | 13 + .../demo/scripts/errors-src/qH3UmebTg5 | 139 + vdn/networks/demo/scripts/repairAll-1A | 666 ++ vdn/networks/demo/scripts/repairApache2 | 304 + vdn/networks/demo/scripts/repairDhcp | 67 + vdn/networks/demo/scripts/repairFirewall | 109 + vdn/networks/demo/scripts/repairIPv6 | 86 + vdn/networks/demo/scripts/repairNfs | 40 + vdn/networks/demo/scripts/repairProftpd | 76 + vdn/networks/demo/scripts/repairUsersTotoTiti | 43 + vdn/networks/demo/scripts/testAll-1A | 160 + vdn/networks/demo/scripts/testApache2 | 140 + vdn/networks/demo/scripts/testBigbossTiny | 37 + vdn/networks/demo/scripts/testDHCPBigbossTiny | 125 + vdn/networks/demo/scripts/testDhcp | 36 + vdn/networks/demo/scripts/testFirewall | 20 + vdn/networks/demo/scripts/testIPv6 | 40 + .../demo/scripts/testMyCompanyFirewall | 136 + vdn/networks/demo/scripts/testNfs | 28 + vdn/networks/demo/scripts/testProftpd | 40 + vdn/networks/demo/societe.conf | 228 + vdn/networks/demo/tiny.conf | 228 + vdn/networks/demo/web.conf | 228 + vdn/networks/docker/build | 25 + .../system/docker.service.d/http-proxy.conf | 5 + vdn/networks/docker/docker.conf | 229 + vdn/networks/docker/graph.svgz | Bin 0 -> 683 bytes vdn/networks/docker/net.svgz | Bin 0 -> 8008 bytes vdn/networks/docker/network.vdn | 0 vdn/networks/docker/scripts/test | 13 + vdn/networks/firewall/bigboss.conf | 228 + vdn/networks/firewall/build | 63 + vdn/networks/firewall/graph.svgz | Bin 0 -> 1486 bytes vdn/networks/firewall/lambda.conf | 228 + vdn/networks/firewall/net.svgz | Bin 0 -> 33387 bytes vdn/networks/firewall/network.vdn | 2 + vdn/networks/firewall/nomade.conf | 228 + .../firewall/scripts/baseConfigBigboss | 57 + .../firewall/scripts/baseConfigLambda | 70 + .../firewall/scripts/baseConfigNomade | 71 + .../firewall/scripts/baseConfigSociete | 158 + vdn/networks/firewall/scripts/baseConfigTiny | 54 + vdn/networks/firewall/scripts/baseConfigWeb | 61 + vdn/networks/firewall/scripts/configAll | 120 + vdn/networks/firewall/scripts/repairAll | 192 + vdn/networks/firewall/scripts/testAll | 136 + vdn/networks/firewall/scripts/testAll-fast | 136 + vdn/networks/firewall/societe.conf | 228 + vdn/networks/firewall/tiny.conf | 228 + vdn/networks/firewall/web.conf | 228 + vdn/networks/fixme/appolo.conf | 228 + vdn/networks/fixme/brightside.conf | 228 + vdn/networks/fixme/build | 69 + vdn/networks/fixme/castafiore.conf | 228 + vdn/networks/fixme/client.conf | 228 + vdn/networks/fixme/comanche.conf | 228 + vdn/networks/fixme/darkside.conf | 228 + vdn/networks/fixme/distributeur.conf | 229 + vdn/networks/fixme/fixme-scripts.tgz | Bin 0 -> 5140 bytes vdn/networks/fixme/graph.svgz | Bin 0 -> 1743 bytes vdn/networks/fixme/net.svgz | Bin 0 -> 14685 bytes vdn/networks/fixme/network.vdn | 2 + vdn/networks/fixme/passerelle.conf | 228 + vdn/networks/fixme/scripts/configAll | 15 + vdn/networks/fixme/scripts/configAppolo | 50 + vdn/networks/fixme/scripts/configBrightside | 71 + vdn/networks/fixme/scripts/configCastafiore | 90 + vdn/networks/fixme/scripts/configClient | 55 + vdn/networks/fixme/scripts/configComanche | 62 + vdn/networks/fixme/scripts/configDarkside | 74 + vdn/networks/fixme/scripts/configDistributeur | 141 + vdn/networks/fixme/scripts/configPasserelle | 114 + vdn/networks/fixme/scripts/testAll | 99 + vdn/networks/fixme/scripts/testAll-fast | 99 + vdn/networks/routing-ospf/build | 56 + vdn/networks/routing-ospf/graph.svgz | Bin 0 -> 2057 bytes vdn/networks/routing-ospf/net.svgz | Bin 0 -> 25312 bytes vdn/networks/routing-ospf/network.vdn | 3 + vdn/networks/routing-ospf/r1.conf | 228 + vdn/networks/routing-ospf/r2.conf | 228 + vdn/networks/routing-ospf/r3.conf | 228 + vdn/networks/routing-ospf/r4.conf | 228 + vdn/networks/routing-ospf/r5.conf | 228 + vdn/networks/routing-ospf/s1.conf | 228 + vdn/networks/routing-ospf/s2.conf | 228 + vdn/networks/routing-ospf/scripts/common.sh | 80 + vdn/networks/routing-ospf/scripts/configAll | 21 + vdn/networks/routing-ospf/scripts/configR1 | 53 + vdn/networks/routing-ospf/scripts/configR2 | 51 + vdn/networks/routing-ospf/scripts/configR3 | 56 + vdn/networks/routing-ospf/scripts/configR4 | 48 + vdn/networks/routing-ospf/scripts/configR5 | 53 + vdn/networks/routing-ospf/scripts/configS1 | 40 + vdn/networks/routing-ospf/scripts/configS2 | 41 + vdn/networks/routing-ospf/scripts/ping-all | 29 + .../routing-ospf/scripts/ping-all-without-r2 | 31 + vdn/networks/routing-ospf/scripts/repairAll | 20 + vdn/networks/routing-ospf/scripts/repairR2 | 16 + vdn/networks/routing-ospf/scripts/testWithR2 | 8 + .../routing-ospf/scripts/testWithoutR2 | 8 + vdn/networks/routing-static/build | 61 + vdn/networks/routing-static/graph.svgz | Bin 0 -> 2102 bytes vdn/networks/routing-static/net.svgz | Bin 0 -> 25312 bytes vdn/networks/routing-static/net2.svg | 6221 +++++++++++++++++ vdn/networks/routing-static/network.vdn | 3 + vdn/networks/routing-static/r1.conf | 228 + vdn/networks/routing-static/r2.conf | 228 + vdn/networks/routing-static/r3.conf | 228 + vdn/networks/routing-static/r4.conf | 228 + vdn/networks/routing-static/r5.conf | 228 + vdn/networks/routing-static/s1.conf | 228 + vdn/networks/routing-static/s2.conf | 228 + vdn/networks/routing-static/scripts/common.sh | 17 + vdn/networks/routing-static/scripts/configAll | 20 + vdn/networks/routing-static/scripts/configR1 | 53 + vdn/networks/routing-static/scripts/configR2 | 51 + vdn/networks/routing-static/scripts/configR3 | 55 + vdn/networks/routing-static/scripts/configR4 | 50 + vdn/networks/routing-static/scripts/configR5 | 55 + vdn/networks/routing-static/scripts/configS1 | 40 + vdn/networks/routing-static/scripts/configS2 | 39 + vdn/networks/routing-static/scripts/ping-all | 29 + .../scripts/ping-all-without-r2 | 31 + vdn/networks/routing-static/scripts/repairAll | 17 + vdn/networks/routing-static/scripts/repairR2 | 42 + vdn/networks/sae103/build | 24 + .../system/docker.service.d/http-proxy.conf | 5 + vdn/networks/sae103/graph.svgz | Bin 0 -> 683 bytes vdn/networks/sae103/net.svgz | Bin 0 -> 8001 bytes vdn/networks/sae103/network.vdn | 0 vdn/networks/sae103/sae103.conf | 228 + vdn/networks/sae103/scripts/test | 13 + vdn/networks/zoo/bookworm.conf | 228 + vdn/networks/zoo/build | 149 + vdn/networks/zoo/bullseye-sae.conf | 228 + vdn/networks/zoo/bullseye-test-tgz2.conf | 228 + vdn/networks/zoo/bullseye-test.conf | 228 + vdn/networks/zoo/bullseye-tgz2.conf | 228 + vdn/networks/zoo/bullseye.conf | 228 + vdn/networks/zoo/buster-test-tgz2.conf | 228 + vdn/networks/zoo/buster-test.conf | 228 + vdn/networks/zoo/buster-tgz2.conf | 228 + vdn/networks/zoo/buster.conf | 228 + vdn/networks/zoo/docker.conf | 228 + vdn/networks/zoo/graph.svgz | Bin 0 -> 987 bytes vdn/networks/zoo/network.vdn | 0 vdn/networks/zoo/sae103.conf | 228 + vdn/networks/zoo/scripts/prepareDebian | 245 + vdn/networks/zoo/scripts/prepareDebian.old | 31 + vdn/networks/zoo/scripts/prepareDebian.old2 | 120 + .../zoo/scripts/prepareDebianBookworm | 9 + .../zoo/scripts/prepareDebianBullseye | 9 + .../zoo/scripts/prepareDebianBullseye-test | 30 + vdn/networks/zoo/scripts/prepareDebianBuster | 9 + .../zoo/scripts/prepareDebianBuster-test | 30 + vdn/networks/zoo/scripts/prepareDebianDocker | 9 + vdn/networks/zoo/scripts/prepareKali | 34 + vdn/networks/zoo/scripts/prepareSae103 | 30 + vdn/release | 1 + vdn/sae103/build | 24 + .../system/docker.service.d/http-proxy.conf | 5 + vdn/sae103/graph.svgz | Bin 0 -> 683 bytes vdn/sae103/net.svgz | Bin 0 -> 8001 bytes vdn/sae103/network.vdn | 0 vdn/sae103/sae103.conf | 228 + vdn/sae103/scripts/test | 13 + vdn/script-template | 8 + vdn/scripts/01-first-boot | 51 + vdn/scripts/02-swap | 15 + vdn/scripts/10-network | 55 + vdn/scripts/12-lighttpd | 6 + vdn/scripts/12-proxy | 16 + vdn/scripts/15-authorized_keys | 17 + vdn/scripts/30-services | 30 + vdn/scripts/90-post-boot | 12 + vdn/scripts/99-bird | 14 + vdn/scripts/mount-root-tgz2 | 509 ++ vdn/scripts/on-boot | 28 + vdn/scripts/on-initramfs | 14 + vdn/scripts/save | 42 + vdn/tools/.Makefile.swp | Bin 0 -> 12288 bytes vdn/tools/Makefile | 16 + vdn/tools/build-container.sh | 64 + vdn/tools/compile-vte.sh | 95 + vdn/tools/create-singularity-distrib.sh | 67 + vdn/tools/libnss_vdn.so | Bin 0 -> 16416 bytes vdn/tools/nss_vdn.c | 117 + vdn/tools/nss_vdn.o | Bin 0 -> 3440 bytes vdn/tools/podman-exec-cmds.sh | 23 + vdn/tools/vdn-bootstrap | 346 + vdn/vdn-restore-extra-eth | 99 + 900 files changed, 105504 insertions(+) rename id_rsa.pub => cle_ssh/id_rsa.pub (100%) create mode 100644 vdn/LICENCE create mode 100644 vdn/README create mode 100644 vdn/allocators/db-default/hosts create mode 100644 vdn/allocators/db-default/hosts.global create mode 100644 vdn/allocators/db-default/networks create mode 100644 vdn/allocators/db-default/users create mode 100644 vdn/allocators/default create mode 100755 vdn/allocators/resolv create mode 100644 vdn/authorized-root.txt create mode 100755 vdn/bin/bbfs create mode 100755 vdn/bin/ext4fuse create mode 100644 vdn/bin/functions-build.sh create mode 100644 vdn/bin/functions-scripts.sh create mode 100644 vdn/bin/functions.sh create mode 100755 vdn/bin/sae203-init create mode 100755 vdn/bin/vdn create mode 100755 vdn/bin/vdn-alive create mode 100755 vdn/bin/vdn-alives create mode 100755 vdn/bin/vdn-build create mode 100755 vdn/bin/vdn-build-db create mode 100755 vdn/bin/vdn-build-network create mode 100755 vdn/bin/vdn-busy.rb create mode 100755 vdn/bin/vdn-clean create mode 100755 vdn/bin/vdn-clean-network create mode 100755 vdn/bin/vdn-clone-network create mode 100755 vdn/bin/vdn-config create mode 100755 vdn/bin/vdn-create-slash create mode 100755 vdn/bin/vdn-delete create mode 100755 vdn/bin/vdn-delete-disks create mode 100755 vdn/bin/vdn-delete-network create mode 100755 vdn/bin/vdn-diff create mode 100755 vdn/bin/vdn-doc create mode 100755 vdn/bin/vdn-docker create mode 100755 vdn/bin/vdn-download-disks create mode 100755 vdn/bin/vdn-download-network create mode 100755 vdn/bin/vdn-exec-in-fakechroot create mode 100755 vdn/bin/vdn-fakechroot create mode 100755 vdn/bin/vdn-fakechroot-umount create mode 100755 vdn/bin/vdn-find-ident.old create mode 100755 vdn/bin/vdn-fuse-proot create mode 100755 vdn/bin/vdn-get-network create mode 100755 vdn/bin/vdn-graph create mode 100755 vdn/bin/vdn-gui.rb create mode 100755 vdn/bin/vdn-halt create mode 100755 vdn/bin/vdn-halt-all create mode 100755 vdn/bin/vdn-infos create mode 100755 vdn/bin/vdn-kill create mode 100755 vdn/bin/vdn-kvm create mode 100755 vdn/bin/vdn-list create mode 100755 vdn/bin/vdn-list-networks create mode 100755 vdn/bin/vdn-manage-backups create mode 100755 vdn/bin/vdn-manage-files create mode 100755 vdn/bin/vdn-mount-chroot create mode 100755 vdn/bin/vdn-mount-chroot.bak create mode 100755 vdn/bin/vdn-new-network create mode 100755 vdn/bin/vdn-open-network create mode 100755 vdn/bin/vdn-prepare create mode 100755 vdn/bin/vdn-prepare1 create mode 100755 vdn/bin/vdn-publish-network create mode 100755 vdn/bin/vdn-push create mode 100755 vdn/bin/vdn-query create mode 100755 vdn/bin/vdn-restart create mode 100755 vdn/bin/vdn-restore-extra-eth create mode 100755 vdn/bin/vdn-save create mode 100755 vdn/bin/vdn-scp create mode 100755 vdn/bin/vdn-scripts create mode 100755 vdn/bin/vdn-scripts.old create mode 100755 vdn/bin/vdn-send-proxy create mode 100755 vdn/bin/vdn-set-network-dir create mode 100755 vdn/bin/vdn-set-var create mode 100755 vdn/bin/vdn-shell create mode 100755 vdn/bin/vdn-show create mode 100755 vdn/bin/vdn-singularity create mode 100755 vdn/bin/vdn-spice-viewer create mode 100755 vdn/bin/vdn-ssh create mode 100755 vdn/bin/vdn-ssh-copy-id create mode 100755 vdn/bin/vdn-ssh-loop create mode 100755 vdn/bin/vdn-sshfs create mode 100755 vdn/bin/vdn-start create mode 100755 vdn/bin/vdn-start-secure-1 create mode 100755 vdn/bin/vdn-start-wrapper create mode 100755 vdn/bin/vdn-terminal create mode 100755 vdn/bin/vdn-test create mode 100755 vdn/bin/vdn-test-all create mode 100755 vdn/bin/vdn-test-kvm create mode 100755 vdn/bin/vdn-upload-disks create mode 100755 vdn/bin/vdn-viewer create mode 100644 vdn/build-template create mode 100644 vdn/config.rc create mode 100644 vdn/config.rc.local create mode 100644 vdn/config.template create mode 100644 vdn/config.template.local create mode 100755 vdn/distribs/guests/direct/debian/bullseye/prepare-sae.sh create mode 100755 vdn/distribs/guests/direct/debian/bullseye/prepare.sh create mode 100755 vdn/distribs/guests/direct/debian/bullseye/rc.local.disable create mode 100755 vdn/distribs/guests/direct/debian/buster/prepare.sh create mode 100755 vdn/distribs/guests/direct/debian/buster/rc.local.disable create mode 100644 vdn/distribs/guests/overlay/debian/bullseye/mount-root create mode 100755 vdn/distribs/guests/overlay/debian/bullseye/save create mode 100644 vdn/distribs/guests/overlay/debian/buster/mount-root create mode 100755 vdn/distribs/guests/overlay/debian/buster/save create mode 100644 vdn/distribs/guests/tgz/debian/bullseye/mount-root create mode 100755 vdn/distribs/guests/tgz/debian/bullseye/save create mode 100644 vdn/distribs/guests/tgz/debian/buster/mount-root create mode 100755 vdn/distribs/guests/tgz/debian/buster/save create mode 100644 vdn/distribs/hosts/debian/bullseye/download-extras.sh create mode 100644 vdn/distribs/hosts/debian/bullseye/prepare.sh create mode 100755 vdn/distribs/hosts/debian/bullseye/vte.so create mode 100644 vdn/distribs/hosts/debian/buster/download-extras.sh create mode 100644 vdn/distribs/hosts/debian/buster/prepare.sh create mode 100644 vdn/distribs/hosts/debian/buster/vte.so create mode 100755 vdn/distribs/hosts/ubuntu/bionic/vte.so create mode 100755 vdn/distribs/hosts/ubuntu/focal/vte.so create mode 100755 vdn/distribs/hosts/ubuntu/jammy/vte.so create mode 100644 vdn/doc/README create mode 100644 vdn/doc/banner.svgz create mode 120000 vdn/files create mode 100644 vdn/net-template.svgz create mode 100644 vdn/networks.bak/bullseye-mini-cow/build create mode 100644 vdn/networks.bak/bullseye-mini-cow/network.vdn create mode 100644 vdn/networks.bak/bullseye-mini-test-cow/build create mode 100644 vdn/networks.bak/bullseye-mini-test-cow/debian-1.conf create mode 100644 vdn/networks.bak/bullseye-mini-test-cow/graph.svgz create mode 100644 vdn/networks.bak/bullseye-mini-test-cow/network.vdn create mode 100644 vdn/networks.bak/buster-mini-cow/build create mode 100644 vdn/networks.bak/buster-mini-cow/network.vdn create mode 100644 vdn/networks.bak/demo-bookworm/bigboss.conf create mode 100755 vdn/networks.bak/demo-bookworm/build create mode 100644 vdn/networks.bak/demo-bookworm/graph.svgz create mode 100644 vdn/networks.bak/demo-bookworm/lambda.conf create mode 100644 vdn/networks.bak/demo-bookworm/net.svgz create mode 100644 vdn/networks.bak/demo-bookworm/network.vdn create mode 100644 vdn/networks.bak/demo-bookworm/nomade.conf create mode 100755 vdn/networks.bak/demo-bookworm/scripts/atest create mode 100644 vdn/networks.bak/demo-bookworm/scripts/baseConfigAll create mode 100755 vdn/networks.bak/demo-bookworm/scripts/baseConfigBigboss create mode 100755 vdn/networks.bak/demo-bookworm/scripts/baseConfigBigbossTiny create mode 100755 vdn/networks.bak/demo-bookworm/scripts/baseConfigLambda create mode 100755 vdn/networks.bak/demo-bookworm/scripts/baseConfigNomade create mode 100755 vdn/networks.bak/demo-bookworm/scripts/baseConfigSociete create mode 100755 vdn/networks.bak/demo-bookworm/scripts/baseConfigTiny create mode 100755 vdn/networks.bak/demo-bookworm/scripts/baseConfigWeb create mode 100644 vdn/networks.bak/demo-bookworm/scripts/configIPv6 create mode 100755 vdn/networks.bak/demo-bookworm/scripts/errors create mode 100644 vdn/networks.bak/demo-bookworm/scripts/errors-src/Makefile create mode 100755 vdn/networks.bak/demo-bookworm/scripts/errors-src/errorsWrapper create mode 100644 vdn/networks.bak/demo-bookworm/scripts/errors-src/errorsWrapper.c create mode 100755 vdn/networks.bak/demo-bookworm/scripts/errors-src/qH3UmebTg5 create mode 100644 vdn/networks.bak/demo-bookworm/scripts/repairAll-1A create mode 100644 vdn/networks.bak/demo-bookworm/scripts/repairApache2 create mode 100644 vdn/networks.bak/demo-bookworm/scripts/repairDhcp create mode 100644 vdn/networks.bak/demo-bookworm/scripts/repairFirewall create mode 100644 vdn/networks.bak/demo-bookworm/scripts/repairIPv6 create mode 100644 vdn/networks.bak/demo-bookworm/scripts/repairNfs create mode 100644 vdn/networks.bak/demo-bookworm/scripts/repairProftpd create mode 100644 vdn/networks.bak/demo-bookworm/scripts/repairUsersTotoTiti create mode 100755 vdn/networks.bak/demo-bookworm/scripts/testAll-1A create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testApache2 create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testBigbossTiny create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testDHCPBigbossTiny create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testDhcp create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testFirewall create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testIPv6 create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testMyCompanyFirewall create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testNfs create mode 100644 vdn/networks.bak/demo-bookworm/scripts/testProftpd create mode 100644 vdn/networks.bak/demo-bookworm/societe.conf create mode 100644 vdn/networks.bak/demo-bookworm/tiny.conf create mode 100644 vdn/networks.bak/demo-bookworm/web.conf create mode 100644 vdn/networks.bak/demo-bullseye.bak/bigboss.conf create mode 100755 vdn/networks.bak/demo-bullseye.bak/build create mode 100644 vdn/networks.bak/demo-bullseye.bak/graph.svgz create mode 100644 vdn/networks.bak/demo-bullseye.bak/lambda.conf create mode 100644 vdn/networks.bak/demo-bullseye.bak/net.svgz create mode 100644 vdn/networks.bak/demo-bullseye.bak/network.vdn create mode 100644 vdn/networks.bak/demo-bullseye.bak/nomade.conf create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigAll create mode 100755 vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigBigboss create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigLambda create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigNomade create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigSociete create mode 100755 vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigTiny create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigWeb create mode 100755 vdn/networks.bak/demo-bullseye.bak/scripts/configFirewall create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/configIPv6 create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/diag1 create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/diag2 create mode 100644 vdn/networks.bak/demo-bullseye.bak/scripts/diag3 create mode 100755 vdn/networks.bak/demo-bullseye.bak/scripts/repairFirewall create mode 100755 vdn/networks.bak/demo-bullseye.bak/scripts/repairIPv6 create mode 100755 vdn/networks.bak/demo-bullseye.bak/scripts/testFirewall create mode 100755 vdn/networks.bak/demo-bullseye.bak/scripts/testIPv6 create mode 100755 vdn/networks.bak/demo-bullseye.bak/scripts/testMyCompanyFirewall create mode 100644 vdn/networks.bak/demo-bullseye.bak/societe.conf create mode 100644 vdn/networks.bak/demo-bullseye.bak/tiny.conf create mode 100644 vdn/networks.bak/demo-bullseye.bak/web.conf create mode 100644 vdn/networks.bak/demo-bullseye/bigboss.conf create mode 100755 vdn/networks.bak/demo-bullseye/build create mode 100644 vdn/networks.bak/demo-bullseye/graph.svgz create mode 100644 vdn/networks.bak/demo-bullseye/lambda.conf create mode 100644 vdn/networks.bak/demo-bullseye/net.svgz create mode 100644 vdn/networks.bak/demo-bullseye/network.vdn create mode 100644 vdn/networks.bak/demo-bullseye/nomade.conf create mode 100644 vdn/networks.bak/demo-bullseye/scripts/.baseConfigSociete.swp create mode 100755 vdn/networks.bak/demo-bullseye/scripts/atest create mode 100644 vdn/networks.bak/demo-bullseye/scripts/baseConfigAll create mode 100755 vdn/networks.bak/demo-bullseye/scripts/baseConfigBigboss create mode 100755 vdn/networks.bak/demo-bullseye/scripts/baseConfigBigbossTiny create mode 100755 vdn/networks.bak/demo-bullseye/scripts/baseConfigLambda create mode 100755 vdn/networks.bak/demo-bullseye/scripts/baseConfigNomade create mode 100755 vdn/networks.bak/demo-bullseye/scripts/baseConfigSociete create mode 100755 vdn/networks.bak/demo-bullseye/scripts/baseConfigTiny create mode 100755 vdn/networks.bak/demo-bullseye/scripts/baseConfigWeb create mode 100644 vdn/networks.bak/demo-bullseye/scripts/configIPv6 create mode 100755 vdn/networks.bak/demo-bullseye/scripts/errors create mode 100644 vdn/networks.bak/demo-bullseye/scripts/errors-src/Makefile create mode 100755 vdn/networks.bak/demo-bullseye/scripts/errors-src/errorsWrapper create mode 100644 vdn/networks.bak/demo-bullseye/scripts/errors-src/errorsWrapper.c create mode 100755 vdn/networks.bak/demo-bullseye/scripts/errors-src/qH3UmebTg5 create mode 100644 vdn/networks.bak/demo-bullseye/scripts/repairAll-1A create mode 100644 vdn/networks.bak/demo-bullseye/scripts/repairApache2 create mode 100644 vdn/networks.bak/demo-bullseye/scripts/repairDhcp create mode 100644 vdn/networks.bak/demo-bullseye/scripts/repairFirewall create mode 100644 vdn/networks.bak/demo-bullseye/scripts/repairIPv6 create mode 100644 vdn/networks.bak/demo-bullseye/scripts/repairNfs create mode 100644 vdn/networks.bak/demo-bullseye/scripts/repairProftpd create mode 100644 vdn/networks.bak/demo-bullseye/scripts/repairUsersTotoTiti create mode 100755 vdn/networks.bak/demo-bullseye/scripts/testAll-1A create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testApache2 create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testBigbossTiny create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testDHCPBigbossTiny create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testDhcp create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testFirewall create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testIPv6 create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testMyCompanyFirewall create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testNfs create mode 100644 vdn/networks.bak/demo-bullseye/scripts/testProftpd create mode 100644 vdn/networks.bak/demo-bullseye/societe.conf create mode 100644 vdn/networks.bak/demo-bullseye/tiny.conf create mode 100644 vdn/networks.bak/demo-bullseye/web.conf create mode 100644 vdn/networks.bak/demo-buster/bigboss.conf create mode 100755 vdn/networks.bak/demo-buster/build create mode 100644 vdn/networks.bak/demo-buster/graph.svgz create mode 100644 vdn/networks.bak/demo-buster/lambda.conf create mode 100644 vdn/networks.bak/demo-buster/net.svgz create mode 100644 vdn/networks.bak/demo-buster/network.vdn create mode 100644 vdn/networks.bak/demo-buster/nomade.conf create mode 100755 vdn/networks.bak/demo-buster/scripts/atest create mode 100644 vdn/networks.bak/demo-buster/scripts/baseConfigAll create mode 100755 vdn/networks.bak/demo-buster/scripts/baseConfigBigboss create mode 100755 vdn/networks.bak/demo-buster/scripts/baseConfigBigbossTiny create mode 100755 vdn/networks.bak/demo-buster/scripts/baseConfigLambda create mode 100755 vdn/networks.bak/demo-buster/scripts/baseConfigNomade create mode 100755 vdn/networks.bak/demo-buster/scripts/baseConfigSociete create mode 100755 vdn/networks.bak/demo-buster/scripts/baseConfigTiny create mode 100755 vdn/networks.bak/demo-buster/scripts/baseConfigWeb create mode 100644 vdn/networks.bak/demo-buster/scripts/configIPv6 create mode 100755 vdn/networks.bak/demo-buster/scripts/errors create mode 100644 vdn/networks.bak/demo-buster/scripts/errors-src/Makefile create mode 100755 vdn/networks.bak/demo-buster/scripts/errors-src/errorsWrapper create mode 100644 vdn/networks.bak/demo-buster/scripts/errors-src/errorsWrapper.c create mode 100755 vdn/networks.bak/demo-buster/scripts/errors-src/qH3UmebTg5 create mode 100644 vdn/networks.bak/demo-buster/scripts/repairAll-1A create mode 100644 vdn/networks.bak/demo-buster/scripts/repairApache2 create mode 100644 vdn/networks.bak/demo-buster/scripts/repairDhcp create mode 100644 vdn/networks.bak/demo-buster/scripts/repairFirewall create mode 100644 vdn/networks.bak/demo-buster/scripts/repairIPv6 create mode 100644 vdn/networks.bak/demo-buster/scripts/repairNfs create mode 100644 vdn/networks.bak/demo-buster/scripts/repairProftpd create mode 100644 vdn/networks.bak/demo-buster/scripts/repairUsersTotoTiti create mode 100755 vdn/networks.bak/demo-buster/scripts/testAll-1A create mode 100644 vdn/networks.bak/demo-buster/scripts/testApache2 create mode 100644 vdn/networks.bak/demo-buster/scripts/testBigbossTiny create mode 100644 vdn/networks.bak/demo-buster/scripts/testDHCPBigbossTiny create mode 100644 vdn/networks.bak/demo-buster/scripts/testDhcp create mode 100644 vdn/networks.bak/demo-buster/scripts/testFirewall create mode 100644 vdn/networks.bak/demo-buster/scripts/testIPv6 create mode 100644 vdn/networks.bak/demo-buster/scripts/testMyCompanyFirewall create mode 100644 vdn/networks.bak/demo-buster/scripts/testNfs create mode 100644 vdn/networks.bak/demo-buster/scripts/testProftpd create mode 100644 vdn/networks.bak/demo-buster/societe.conf create mode 100644 vdn/networks.bak/demo-buster/tiny.conf create mode 100644 vdn/networks.bak/demo-buster/web.conf create mode 100644 vdn/networks.bak/demo/bigboss.conf create mode 100755 vdn/networks.bak/demo/build create mode 100644 vdn/networks.bak/demo/graph.svgz create mode 100644 vdn/networks.bak/demo/lambda.conf create mode 100644 vdn/networks.bak/demo/net.svgz create mode 100644 vdn/networks.bak/demo/network.vdn create mode 100644 vdn/networks.bak/demo/nomade.conf create mode 100644 vdn/networks.bak/demo/scripts/.baseConfigSociete.swp create mode 100755 vdn/networks.bak/demo/scripts/atest create mode 100644 vdn/networks.bak/demo/scripts/baseConfigAll create mode 100755 vdn/networks.bak/demo/scripts/baseConfigBigboss create mode 100755 vdn/networks.bak/demo/scripts/baseConfigBigbossTiny create mode 100755 vdn/networks.bak/demo/scripts/baseConfigLambda create mode 100755 vdn/networks.bak/demo/scripts/baseConfigNomade create mode 100755 vdn/networks.bak/demo/scripts/baseConfigSociete create mode 100755 vdn/networks.bak/demo/scripts/baseConfigTiny create mode 100755 vdn/networks.bak/demo/scripts/baseConfigWeb create mode 100644 vdn/networks.bak/demo/scripts/configIPv6 create mode 100755 vdn/networks.bak/demo/scripts/errors create mode 100644 vdn/networks.bak/demo/scripts/errors-src/Makefile create mode 100755 vdn/networks.bak/demo/scripts/errors-src/errorsWrapper create mode 100644 vdn/networks.bak/demo/scripts/errors-src/errorsWrapper.c create mode 100755 vdn/networks.bak/demo/scripts/errors-src/qH3UmebTg5 create mode 100644 vdn/networks.bak/demo/scripts/repairAll-1A create mode 100644 vdn/networks.bak/demo/scripts/repairApache2 create mode 100644 vdn/networks.bak/demo/scripts/repairDhcp create mode 100644 vdn/networks.bak/demo/scripts/repairFirewall create mode 100644 vdn/networks.bak/demo/scripts/repairIPv6 create mode 100644 vdn/networks.bak/demo/scripts/repairNfs create mode 100644 vdn/networks.bak/demo/scripts/repairProftpd create mode 100644 vdn/networks.bak/demo/scripts/repairUsersTotoTiti create mode 100755 vdn/networks.bak/demo/scripts/testAll-1A create mode 100644 vdn/networks.bak/demo/scripts/testApache2 create mode 100644 vdn/networks.bak/demo/scripts/testBigbossTiny create mode 100644 vdn/networks.bak/demo/scripts/testDHCPBigbossTiny create mode 100644 vdn/networks.bak/demo/scripts/testDhcp create mode 100644 vdn/networks.bak/demo/scripts/testFirewall create mode 100644 vdn/networks.bak/demo/scripts/testIPv6 create mode 100644 vdn/networks.bak/demo/scripts/testMyCompanyFirewall create mode 100644 vdn/networks.bak/demo/scripts/testNfs create mode 100644 vdn/networks.bak/demo/scripts/testProftpd create mode 100644 vdn/networks.bak/demo/societe.conf create mode 100644 vdn/networks.bak/demo/tiny.conf create mode 100644 vdn/networks.bak/demo/web.conf create mode 100755 vdn/networks.bak/docker-buster/build create mode 100644 vdn/networks.bak/docker-buster/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf create mode 100644 vdn/networks.bak/docker-buster/net.svgz create mode 100644 vdn/networks.bak/docker-buster/network.vdn create mode 100755 vdn/networks.bak/docker-buster/scripts/test create mode 100755 vdn/networks.bak/docker-tmp-buster/build create mode 100644 vdn/networks.bak/docker-tmp-buster/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf create mode 100644 vdn/networks.bak/docker-tmp-buster/net.svgz create mode 100644 vdn/networks.bak/docker-tmp-buster/network.vdn create mode 100755 vdn/networks.bak/docker-tmp-buster/scripts/test create mode 100755 vdn/networks.bak/firewall-buster/build create mode 100644 vdn/networks.bak/firewall-buster/net.svgz create mode 100644 vdn/networks.bak/firewall-buster/network.vdn create mode 100644 vdn/networks.bak/firewall-buster/scripts/baseConfigBigboss create mode 100644 vdn/networks.bak/firewall-buster/scripts/baseConfigLambda create mode 100644 vdn/networks.bak/firewall-buster/scripts/baseConfigNomade create mode 100644 vdn/networks.bak/firewall-buster/scripts/baseConfigSociete create mode 100644 vdn/networks.bak/firewall-buster/scripts/baseConfigTiny create mode 100644 vdn/networks.bak/firewall-buster/scripts/baseConfigWeb create mode 100755 vdn/networks.bak/firewall-buster/scripts/configAll create mode 100644 vdn/networks.bak/firewall-buster/scripts/repairAll create mode 100644 vdn/networks.bak/firewall-buster/scripts/testAll create mode 100644 vdn/networks.bak/firewall-buster/scripts/testAll-fast create mode 100644 vdn/networks.bak/fixme-bookworm/appolo.conf create mode 100644 vdn/networks.bak/fixme-bookworm/brightside.conf create mode 100755 vdn/networks.bak/fixme-bookworm/build create mode 100644 vdn/networks.bak/fixme-bookworm/castafiore.conf create mode 100644 vdn/networks.bak/fixme-bookworm/client.conf create mode 100644 vdn/networks.bak/fixme-bookworm/comanche.conf create mode 100644 vdn/networks.bak/fixme-bookworm/darkside.conf create mode 100644 vdn/networks.bak/fixme-bookworm/distributeur.conf create mode 100644 vdn/networks.bak/fixme-bookworm/graph.svgz create mode 100644 vdn/networks.bak/fixme-bookworm/net.svgz create mode 100644 vdn/networks.bak/fixme-bookworm/network.vdn create mode 100644 vdn/networks.bak/fixme-bookworm/passerelle.conf create mode 100755 vdn/networks.bak/fixme-bookworm/scripts/configAll create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/configAppolo create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/configBrightside create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/configCastafiore create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/configClient create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/configComanche create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/configDarkside create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/configDistributeur create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/configPasserelle create mode 100644 vdn/networks.bak/fixme-bookworm/scripts/repairAll create mode 100755 vdn/networks.bak/fixme-bookworm/scripts/testAll create mode 100755 vdn/networks.bak/fixme-bookworm/scripts/testAll-fast create mode 100644 vdn/networks.bak/fixme-bullseye/appolo.conf create mode 100644 vdn/networks.bak/fixme-bullseye/brightside.conf create mode 100755 vdn/networks.bak/fixme-bullseye/build create mode 100644 vdn/networks.bak/fixme-bullseye/castafiore.conf create mode 100644 vdn/networks.bak/fixme-bullseye/client.conf create mode 100644 vdn/networks.bak/fixme-bullseye/comanche.conf create mode 100644 vdn/networks.bak/fixme-bullseye/darkside.conf create mode 100644 vdn/networks.bak/fixme-bullseye/distributeur.conf create mode 100644 vdn/networks.bak/fixme-bullseye/graph.svgz create mode 100644 vdn/networks.bak/fixme-bullseye/net.svgz create mode 100644 vdn/networks.bak/fixme-bullseye/network.vdn create mode 100644 vdn/networks.bak/fixme-bullseye/passerelle.conf create mode 100755 vdn/networks.bak/fixme-bullseye/scripts/configAll create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/configAppolo create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/configBrightside create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/configCastafiore create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/configClient create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/configComanche create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/configDarkside create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/configDistributeur create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/configPasserelle create mode 100644 vdn/networks.bak/fixme-bullseye/scripts/repairAll create mode 100755 vdn/networks.bak/fixme-bullseye/scripts/testAll create mode 100755 vdn/networks.bak/fixme-bullseye/scripts/testAll-fast create mode 100644 vdn/networks.bak/fixme-buster/appolo.conf create mode 100644 vdn/networks.bak/fixme-buster/brightside.conf create mode 100755 vdn/networks.bak/fixme-buster/build create mode 100644 vdn/networks.bak/fixme-buster/castafiore.conf create mode 100644 vdn/networks.bak/fixme-buster/client.conf create mode 100644 vdn/networks.bak/fixme-buster/comanche.conf create mode 100644 vdn/networks.bak/fixme-buster/darkside.conf create mode 100644 vdn/networks.bak/fixme-buster/distributeur.conf create mode 100644 vdn/networks.bak/fixme-buster/graph.svgz create mode 100644 vdn/networks.bak/fixme-buster/net.svgz create mode 100644 vdn/networks.bak/fixme-buster/network.vdn create mode 100644 vdn/networks.bak/fixme-buster/passerelle.conf create mode 100755 vdn/networks.bak/fixme-buster/scripts/configAll create mode 100644 vdn/networks.bak/fixme-buster/scripts/configAppolo create mode 100644 vdn/networks.bak/fixme-buster/scripts/configBrightside create mode 100644 vdn/networks.bak/fixme-buster/scripts/configCastafiore create mode 100644 vdn/networks.bak/fixme-buster/scripts/configClient create mode 100644 vdn/networks.bak/fixme-buster/scripts/configComanche create mode 100644 vdn/networks.bak/fixme-buster/scripts/configDarkside create mode 100644 vdn/networks.bak/fixme-buster/scripts/configDistributeur create mode 100644 vdn/networks.bak/fixme-buster/scripts/configPasserelle create mode 100644 vdn/networks.bak/fixme-buster/scripts/repairAll create mode 100755 vdn/networks.bak/fixme-buster/scripts/testAll create mode 100755 vdn/networks.bak/fixme-buster/scripts/testAll-fast create mode 100755 vdn/networks.bak/fixme/build create mode 100644 vdn/networks.bak/fixme/fixme-scripts.tgz create mode 100644 vdn/networks.bak/fixme/net.svgz create mode 100644 vdn/networks.bak/fixme/network.vdn create mode 100755 vdn/networks.bak/fixme/scripts/configAll create mode 100644 vdn/networks.bak/fixme/scripts/configAppolo create mode 100644 vdn/networks.bak/fixme/scripts/configBrightside create mode 100644 vdn/networks.bak/fixme/scripts/configCastafiore create mode 100644 vdn/networks.bak/fixme/scripts/configClient create mode 100644 vdn/networks.bak/fixme/scripts/configComanche create mode 100644 vdn/networks.bak/fixme/scripts/configDarkside create mode 100644 vdn/networks.bak/fixme/scripts/configDistributeur create mode 100644 vdn/networks.bak/fixme/scripts/configPasserelle create mode 100644 vdn/networks.bak/fixme/scripts/repairAll create mode 100755 vdn/networks.bak/fixme/scripts/testAll create mode 100755 vdn/networks.bak/fixme/scripts/testAll-fast create mode 100755 vdn/networks.bak/k8s-bullseye/build create mode 100644 vdn/networks.bak/k8s-bullseye/net.svgz create mode 100644 vdn/networks.bak/k8s-bullseye/network.vdn create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/baseConfigAll create mode 100755 vdn/networks.bak/k8s-bullseye/scripts/baseConfigBigboss create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/baseConfigLambda create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/baseConfigNomade create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/baseConfigSociete create mode 100755 vdn/networks.bak/k8s-bullseye/scripts/baseConfigTiny create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/baseConfigWeb create mode 100755 vdn/networks.bak/k8s-bullseye/scripts/configFirewall create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/configIPv6 create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/diag1 create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/diag2 create mode 100644 vdn/networks.bak/k8s-bullseye/scripts/diag3 create mode 100755 vdn/networks.bak/k8s-bullseye/scripts/repairFirewall create mode 100755 vdn/networks.bak/k8s-bullseye/scripts/repairIPv6 create mode 100755 vdn/networks.bak/k8s-bullseye/scripts/testFirewall create mode 100755 vdn/networks.bak/k8s-bullseye/scripts/testIPv6 create mode 100755 vdn/networks.bak/k8s-bullseye/scripts/testMyCompanyFirewall create mode 100644 vdn/networks.bak/migration-buster-bullseye/build create mode 100644 vdn/networks.bak/migration-buster-bullseye/network.vdn create mode 100755 vdn/networks.bak/random-buster/build create mode 100644 vdn/networks.bak/random-buster/hosts create mode 100644 vdn/networks.bak/random-buster/network.vdn create mode 100644 vdn/networks.bak/random-buster/vm-1.interfaces create mode 100644 vdn/networks.bak/random-buster/vm-2.interfaces create mode 100644 vdn/networks.bak/random-buster/vm-3.interfaces create mode 100644 vdn/networks.bak/random-buster/vm-4.interfaces create mode 100644 vdn/networks.bak/random-buster/vm-5.interfaces create mode 100644 vdn/networks.bak/random-buster/vm-6.interfaces create mode 100644 vdn/networks.bak/random-buster/vm-7.interfaces create mode 100644 vdn/networks.bak/random-buster/vm-8.interfaces create mode 100644 vdn/networks.bak/routing-ospf-bookworm/build create mode 100644 vdn/networks.bak/routing-ospf-bookworm/graph.svgz create mode 100644 vdn/networks.bak/routing-ospf-bookworm/net.svgz create mode 100644 vdn/networks.bak/routing-ospf-bookworm/network.vdn create mode 100644 vdn/networks.bak/routing-ospf-bookworm/r1.conf create mode 100644 vdn/networks.bak/routing-ospf-bookworm/r2.conf create mode 100644 vdn/networks.bak/routing-ospf-bookworm/r3.conf create mode 100644 vdn/networks.bak/routing-ospf-bookworm/r4.conf create mode 100644 vdn/networks.bak/routing-ospf-bookworm/r5.conf create mode 100644 vdn/networks.bak/routing-ospf-bookworm/s1.conf create mode 100644 vdn/networks.bak/routing-ospf-bookworm/s2.conf create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/common.sh create mode 100755 vdn/networks.bak/routing-ospf-bookworm/scripts/configAll create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/configR1 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/configR2 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/configR3 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/configR4 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/configR5 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/configS1 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/configS2 create mode 100755 vdn/networks.bak/routing-ospf-bookworm/scripts/ping-all create mode 100755 vdn/networks.bak/routing-ospf-bookworm/scripts/ping-all-without-r2 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/repairAll create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/repairR2 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/testWithR2 create mode 100644 vdn/networks.bak/routing-ospf-bookworm/scripts/testWithoutR2 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/build create mode 100644 vdn/networks.bak/routing-ospf-bullseye/graph.svgz create mode 100644 vdn/networks.bak/routing-ospf-bullseye/net.svgz create mode 100644 vdn/networks.bak/routing-ospf-bullseye/network.vdn create mode 100644 vdn/networks.bak/routing-ospf-bullseye/r1.conf create mode 100644 vdn/networks.bak/routing-ospf-bullseye/r2.conf create mode 100644 vdn/networks.bak/routing-ospf-bullseye/r3.conf create mode 100644 vdn/networks.bak/routing-ospf-bullseye/r4.conf create mode 100644 vdn/networks.bak/routing-ospf-bullseye/r5.conf create mode 100644 vdn/networks.bak/routing-ospf-bullseye/s1.conf create mode 100644 vdn/networks.bak/routing-ospf-bullseye/s2.conf create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/common.sh create mode 100755 vdn/networks.bak/routing-ospf-bullseye/scripts/configAll create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/configR1 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/configR2 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/configR3 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/configR4 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/configR5 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/configS1 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/configS2 create mode 100755 vdn/networks.bak/routing-ospf-bullseye/scripts/ping-all create mode 100755 vdn/networks.bak/routing-ospf-bullseye/scripts/ping-all-without-r2 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/repairAll create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/repairR2 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/testWithR2 create mode 100644 vdn/networks.bak/routing-ospf-bullseye/scripts/testWithoutR2 create mode 100644 vdn/networks.bak/routing-ospf-buster/build create mode 100644 vdn/networks.bak/routing-ospf-buster/graph.svgz create mode 100644 vdn/networks.bak/routing-ospf-buster/net.svgz create mode 100644 vdn/networks.bak/routing-ospf-buster/network.vdn create mode 100644 vdn/networks.bak/routing-ospf-buster/r1.conf create mode 100644 vdn/networks.bak/routing-ospf-buster/r2.conf create mode 100644 vdn/networks.bak/routing-ospf-buster/r3.conf create mode 100644 vdn/networks.bak/routing-ospf-buster/r4.conf create mode 100644 vdn/networks.bak/routing-ospf-buster/r5.conf create mode 100644 vdn/networks.bak/routing-ospf-buster/s1.conf create mode 100644 vdn/networks.bak/routing-ospf-buster/s2.conf create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/common.sh create mode 100755 vdn/networks.bak/routing-ospf-buster/scripts/configAll create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/configR1 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/configR2 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/configR3 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/configR4 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/configR5 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/configS1 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/configS2 create mode 100755 vdn/networks.bak/routing-ospf-buster/scripts/ping-all create mode 100755 vdn/networks.bak/routing-ospf-buster/scripts/ping-all-without-r2 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/repairAll create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/repairR2 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/testWithR2 create mode 100644 vdn/networks.bak/routing-ospf-buster/scripts/testWithoutR2 create mode 100644 vdn/networks.bak/routing-rip-buster/build create mode 100644 vdn/networks.bak/routing-rip-buster/graph.svgz create mode 100644 vdn/networks.bak/routing-rip-buster/net.svgz create mode 100644 vdn/networks.bak/routing-rip-buster/network.vdn create mode 100644 vdn/networks.bak/routing-rip-buster/r1.conf create mode 100644 vdn/networks.bak/routing-rip-buster/r2.conf create mode 100644 vdn/networks.bak/routing-rip-buster/r3.conf create mode 100644 vdn/networks.bak/routing-rip-buster/r4.conf create mode 100644 vdn/networks.bak/routing-rip-buster/r5.conf create mode 100644 vdn/networks.bak/routing-rip-buster/s1.conf create mode 100644 vdn/networks.bak/routing-rip-buster/s2.conf create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/common.sh create mode 100755 vdn/networks.bak/routing-rip-buster/scripts/configAll create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/configR1 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/configR2 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/configR3 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/configR4 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/configR5 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/configS1 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/configS2 create mode 100755 vdn/networks.bak/routing-rip-buster/scripts/ping-all create mode 100755 vdn/networks.bak/routing-rip-buster/scripts/ping-all-without-r2 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/repairAll create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/repairR2 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/testWithR2 create mode 100644 vdn/networks.bak/routing-rip-buster/scripts/testWithoutR2 create mode 100644 vdn/networks.bak/routing-static-buster/build create mode 100644 vdn/networks.bak/routing-static-buster/graph.svgz create mode 100644 vdn/networks.bak/routing-static-buster/net.svgz create mode 100644 vdn/networks.bak/routing-static-buster/net2.svg create mode 100644 vdn/networks.bak/routing-static-buster/network.vdn create mode 100644 vdn/networks.bak/routing-static-buster/r1.conf create mode 100644 vdn/networks.bak/routing-static-buster/r2.conf create mode 100644 vdn/networks.bak/routing-static-buster/r3.conf create mode 100644 vdn/networks.bak/routing-static-buster/r4.conf create mode 100644 vdn/networks.bak/routing-static-buster/r5.conf create mode 100644 vdn/networks.bak/routing-static-buster/s1.conf create mode 100644 vdn/networks.bak/routing-static-buster/s2.conf create mode 100644 vdn/networks.bak/routing-static-buster/scripts/common.sh create mode 100755 vdn/networks.bak/routing-static-buster/scripts/configAll create mode 100644 vdn/networks.bak/routing-static-buster/scripts/configR1 create mode 100644 vdn/networks.bak/routing-static-buster/scripts/configR2 create mode 100644 vdn/networks.bak/routing-static-buster/scripts/configR3 create mode 100644 vdn/networks.bak/routing-static-buster/scripts/configR4 create mode 100644 vdn/networks.bak/routing-static-buster/scripts/configR5 create mode 100644 vdn/networks.bak/routing-static-buster/scripts/configS1 create mode 100644 vdn/networks.bak/routing-static-buster/scripts/configS2 create mode 100755 vdn/networks.bak/routing-static-buster/scripts/ping-all create mode 100755 vdn/networks.bak/routing-static-buster/scripts/ping-all-without-r2 create mode 100644 vdn/networks.bak/routing-static-buster/scripts/repairAll create mode 100644 vdn/networks.bak/routing-static-buster/scripts/repairR2 create mode 100755 vdn/networks.bak/sae203/build create mode 100644 vdn/networks.bak/sae203/net.svgz create mode 100644 vdn/networks.bak/sae203/network.vdn create mode 100755 vdn/networks.bak/sae203/scripts/baseConfig create mode 100755 vdn/networks.bak/secure-1-buster/build create mode 100644 vdn/networks.bak/secure-1-buster/net.svgz create mode 100644 vdn/networks.bak/secure-1-buster/network.vdn create mode 100755 vdn/networks.bak/secure-1-buster/scripts/baseConfig create mode 100755 vdn/networks.bak/secure-buster/build create mode 100644 vdn/networks.bak/secure-buster/net.svgz create mode 100644 vdn/networks.bak/secure-buster/network.vdn create mode 100644 vdn/networks.bak/secure-buster/scripts/baseConfigAll create mode 100755 vdn/networks.bak/secure-buster/scripts/baseConfigBigboss create mode 100644 vdn/networks.bak/secure-buster/scripts/baseConfigLambda create mode 100644 vdn/networks.bak/secure-buster/scripts/baseConfigNomade create mode 100644 vdn/networks.bak/secure-buster/scripts/baseConfigSociete create mode 100755 vdn/networks.bak/secure-buster/scripts/baseConfigTiny create mode 100644 vdn/networks.bak/secure-buster/scripts/baseConfigWeb create mode 100755 vdn/networks.bak/secure-buster/scripts/configFirewall create mode 100644 vdn/networks.bak/secure-buster/scripts/configIPv6 create mode 100644 vdn/networks.bak/secure-buster/scripts/diag1 create mode 100644 vdn/networks.bak/secure-buster/scripts/diag2 create mode 100644 vdn/networks.bak/secure-buster/scripts/diag3 create mode 100755 vdn/networks.bak/secure-buster/scripts/diagFirewall create mode 100755 vdn/networks.bak/secure-buster/scripts/diagIPv6 create mode 100755 vdn/networks.bak/secure-buster/scripts/testFirewall create mode 100755 vdn/networks.bak/secure-buster/scripts/testIPv6 create mode 100644 vdn/networks.bak/zoo/bookworm.conf create mode 100755 vdn/networks.bak/zoo/build create mode 100644 vdn/networks.bak/zoo/bullseye-sae.conf create mode 100644 vdn/networks.bak/zoo/bullseye-test.conf create mode 100644 vdn/networks.bak/zoo/bullseye.conf create mode 100644 vdn/networks.bak/zoo/buster-tgz2.conf create mode 100644 vdn/networks.bak/zoo/buster.conf create mode 100644 vdn/networks.bak/zoo/graph.svgz create mode 100644 vdn/networks.bak/zoo/network.vdn create mode 100644 vdn/networks.bak/zoo/scripts/.prepareDebianBullseye-test.swp create mode 100644 vdn/networks.bak/zoo/scripts/prepareDebian create mode 100755 vdn/networks.bak/zoo/scripts/prepareDebian.old create mode 100755 vdn/networks.bak/zoo/scripts/prepareDebian.old2 create mode 100755 vdn/networks.bak/zoo/scripts/prepareDebianBookworm create mode 100755 vdn/networks.bak/zoo/scripts/prepareDebianBullseye create mode 100755 vdn/networks.bak/zoo/scripts/prepareDebianBullseye-test create mode 100755 vdn/networks.bak/zoo/scripts/prepareDebianBuster create mode 100755 vdn/networks.bak/zoo/scripts/prepareKali create mode 100644 vdn/networks/demo-buster/bigboss.conf create mode 100755 vdn/networks/demo-buster/build create mode 100644 vdn/networks/demo-buster/graph.svgz create mode 100644 vdn/networks/demo-buster/lambda.conf create mode 100644 vdn/networks/demo-buster/net.svgz create mode 100644 vdn/networks/demo-buster/network.vdn create mode 100644 vdn/networks/demo-buster/nomade.conf create mode 100755 vdn/networks/demo-buster/scripts/atest create mode 100644 vdn/networks/demo-buster/scripts/baseConfigAll create mode 100755 vdn/networks/demo-buster/scripts/baseConfigBigboss create mode 100755 vdn/networks/demo-buster/scripts/baseConfigBigbossTiny create mode 100755 vdn/networks/demo-buster/scripts/baseConfigLambda create mode 100755 vdn/networks/demo-buster/scripts/baseConfigNomade create mode 100755 vdn/networks/demo-buster/scripts/baseConfigSociete create mode 100755 vdn/networks/demo-buster/scripts/baseConfigTiny create mode 100755 vdn/networks/demo-buster/scripts/baseConfigWeb create mode 100644 vdn/networks/demo-buster/scripts/configIPv6 create mode 100755 vdn/networks/demo-buster/scripts/errors create mode 100644 vdn/networks/demo-buster/scripts/errors-src/Makefile create mode 100755 vdn/networks/demo-buster/scripts/errors-src/errorsWrapper create mode 100644 vdn/networks/demo-buster/scripts/errors-src/errorsWrapper.c create mode 100755 vdn/networks/demo-buster/scripts/errors-src/qH3UmebTg5 create mode 100644 vdn/networks/demo-buster/scripts/repairAll-1A create mode 100644 vdn/networks/demo-buster/scripts/repairApache2 create mode 100644 vdn/networks/demo-buster/scripts/repairDhcp create mode 100644 vdn/networks/demo-buster/scripts/repairFirewall create mode 100644 vdn/networks/demo-buster/scripts/repairIPv6 create mode 100644 vdn/networks/demo-buster/scripts/repairNfs create mode 100644 vdn/networks/demo-buster/scripts/repairProftpd create mode 100644 vdn/networks/demo-buster/scripts/repairUsersTotoTiti create mode 100755 vdn/networks/demo-buster/scripts/testAll-1A create mode 100644 vdn/networks/demo-buster/scripts/testApache2 create mode 100644 vdn/networks/demo-buster/scripts/testBigbossTiny create mode 100644 vdn/networks/demo-buster/scripts/testDHCPBigbossTiny create mode 100644 vdn/networks/demo-buster/scripts/testDhcp create mode 100644 vdn/networks/demo-buster/scripts/testFirewall create mode 100644 vdn/networks/demo-buster/scripts/testIPv6 create mode 100644 vdn/networks/demo-buster/scripts/testMyCompanyFirewall create mode 100644 vdn/networks/demo-buster/scripts/testNfs create mode 100644 vdn/networks/demo-buster/scripts/testProftpd create mode 100644 vdn/networks/demo-buster/societe.conf create mode 100644 vdn/networks/demo-buster/tiny.conf create mode 100644 vdn/networks/demo-buster/web.conf create mode 100644 vdn/networks/demo/bigboss.conf create mode 100755 vdn/networks/demo/build create mode 100644 vdn/networks/demo/graph.svgz create mode 100644 vdn/networks/demo/lambda.conf create mode 100644 vdn/networks/demo/net.svgz create mode 100644 vdn/networks/demo/network.vdn create mode 100644 vdn/networks/demo/nomade.conf create mode 100755 vdn/networks/demo/scripts/atest create mode 100644 vdn/networks/demo/scripts/baseConfigAll create mode 100755 vdn/networks/demo/scripts/baseConfigBigboss create mode 100755 vdn/networks/demo/scripts/baseConfigBigbossTiny create mode 100755 vdn/networks/demo/scripts/baseConfigLambda create mode 100755 vdn/networks/demo/scripts/baseConfigNomade create mode 100755 vdn/networks/demo/scripts/baseConfigSociete create mode 100755 vdn/networks/demo/scripts/baseConfigTiny create mode 100755 vdn/networks/demo/scripts/baseConfigWeb create mode 100644 vdn/networks/demo/scripts/configIPv6 create mode 100755 vdn/networks/demo/scripts/errors create mode 100644 vdn/networks/demo/scripts/errors-src/Makefile create mode 100755 vdn/networks/demo/scripts/errors-src/errorsWrapper create mode 100644 vdn/networks/demo/scripts/errors-src/errorsWrapper.c create mode 100755 vdn/networks/demo/scripts/errors-src/qH3UmebTg5 create mode 100644 vdn/networks/demo/scripts/repairAll-1A create mode 100644 vdn/networks/demo/scripts/repairApache2 create mode 100644 vdn/networks/demo/scripts/repairDhcp create mode 100644 vdn/networks/demo/scripts/repairFirewall create mode 100644 vdn/networks/demo/scripts/repairIPv6 create mode 100644 vdn/networks/demo/scripts/repairNfs create mode 100644 vdn/networks/demo/scripts/repairProftpd create mode 100644 vdn/networks/demo/scripts/repairUsersTotoTiti create mode 100755 vdn/networks/demo/scripts/testAll-1A create mode 100644 vdn/networks/demo/scripts/testApache2 create mode 100644 vdn/networks/demo/scripts/testBigbossTiny create mode 100644 vdn/networks/demo/scripts/testDHCPBigbossTiny create mode 100644 vdn/networks/demo/scripts/testDhcp create mode 100644 vdn/networks/demo/scripts/testFirewall create mode 100644 vdn/networks/demo/scripts/testIPv6 create mode 100644 vdn/networks/demo/scripts/testMyCompanyFirewall create mode 100644 vdn/networks/demo/scripts/testNfs create mode 100644 vdn/networks/demo/scripts/testProftpd create mode 100644 vdn/networks/demo/societe.conf create mode 100644 vdn/networks/demo/tiny.conf create mode 100644 vdn/networks/demo/web.conf create mode 100755 vdn/networks/docker/build create mode 100644 vdn/networks/docker/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf create mode 100644 vdn/networks/docker/docker.conf create mode 100644 vdn/networks/docker/graph.svgz create mode 100644 vdn/networks/docker/net.svgz create mode 100644 vdn/networks/docker/network.vdn create mode 100755 vdn/networks/docker/scripts/test create mode 100644 vdn/networks/firewall/bigboss.conf create mode 100755 vdn/networks/firewall/build create mode 100644 vdn/networks/firewall/graph.svgz create mode 100644 vdn/networks/firewall/lambda.conf create mode 100644 vdn/networks/firewall/net.svgz create mode 100644 vdn/networks/firewall/network.vdn create mode 100644 vdn/networks/firewall/nomade.conf create mode 100644 vdn/networks/firewall/scripts/baseConfigBigboss create mode 100644 vdn/networks/firewall/scripts/baseConfigLambda create mode 100644 vdn/networks/firewall/scripts/baseConfigNomade create mode 100644 vdn/networks/firewall/scripts/baseConfigSociete create mode 100644 vdn/networks/firewall/scripts/baseConfigTiny create mode 100644 vdn/networks/firewall/scripts/baseConfigWeb create mode 100755 vdn/networks/firewall/scripts/configAll create mode 100644 vdn/networks/firewall/scripts/repairAll create mode 100755 vdn/networks/firewall/scripts/testAll create mode 100644 vdn/networks/firewall/scripts/testAll-fast create mode 100644 vdn/networks/firewall/societe.conf create mode 100644 vdn/networks/firewall/tiny.conf create mode 100644 vdn/networks/firewall/web.conf create mode 100644 vdn/networks/fixme/appolo.conf create mode 100644 vdn/networks/fixme/brightside.conf create mode 100755 vdn/networks/fixme/build create mode 100644 vdn/networks/fixme/castafiore.conf create mode 100644 vdn/networks/fixme/client.conf create mode 100644 vdn/networks/fixme/comanche.conf create mode 100644 vdn/networks/fixme/darkside.conf create mode 100644 vdn/networks/fixme/distributeur.conf create mode 100644 vdn/networks/fixme/fixme-scripts.tgz create mode 100644 vdn/networks/fixme/graph.svgz create mode 100644 vdn/networks/fixme/net.svgz create mode 100644 vdn/networks/fixme/network.vdn create mode 100644 vdn/networks/fixme/passerelle.conf create mode 100755 vdn/networks/fixme/scripts/configAll create mode 100644 vdn/networks/fixme/scripts/configAppolo create mode 100644 vdn/networks/fixme/scripts/configBrightside create mode 100644 vdn/networks/fixme/scripts/configCastafiore create mode 100644 vdn/networks/fixme/scripts/configClient create mode 100644 vdn/networks/fixme/scripts/configComanche create mode 100644 vdn/networks/fixme/scripts/configDarkside create mode 100644 vdn/networks/fixme/scripts/configDistributeur create mode 100644 vdn/networks/fixme/scripts/configPasserelle create mode 100755 vdn/networks/fixme/scripts/testAll create mode 100755 vdn/networks/fixme/scripts/testAll-fast create mode 100644 vdn/networks/routing-ospf/build create mode 100644 vdn/networks/routing-ospf/graph.svgz create mode 100644 vdn/networks/routing-ospf/net.svgz create mode 100644 vdn/networks/routing-ospf/network.vdn create mode 100644 vdn/networks/routing-ospf/r1.conf create mode 100644 vdn/networks/routing-ospf/r2.conf create mode 100644 vdn/networks/routing-ospf/r3.conf create mode 100644 vdn/networks/routing-ospf/r4.conf create mode 100644 vdn/networks/routing-ospf/r5.conf create mode 100644 vdn/networks/routing-ospf/s1.conf create mode 100644 vdn/networks/routing-ospf/s2.conf create mode 100644 vdn/networks/routing-ospf/scripts/common.sh create mode 100755 vdn/networks/routing-ospf/scripts/configAll create mode 100644 vdn/networks/routing-ospf/scripts/configR1 create mode 100644 vdn/networks/routing-ospf/scripts/configR2 create mode 100644 vdn/networks/routing-ospf/scripts/configR3 create mode 100644 vdn/networks/routing-ospf/scripts/configR4 create mode 100644 vdn/networks/routing-ospf/scripts/configR5 create mode 100644 vdn/networks/routing-ospf/scripts/configS1 create mode 100644 vdn/networks/routing-ospf/scripts/configS2 create mode 100755 vdn/networks/routing-ospf/scripts/ping-all create mode 100755 vdn/networks/routing-ospf/scripts/ping-all-without-r2 create mode 100644 vdn/networks/routing-ospf/scripts/repairAll create mode 100644 vdn/networks/routing-ospf/scripts/repairR2 create mode 100644 vdn/networks/routing-ospf/scripts/testWithR2 create mode 100644 vdn/networks/routing-ospf/scripts/testWithoutR2 create mode 100644 vdn/networks/routing-static/build create mode 100644 vdn/networks/routing-static/graph.svgz create mode 100644 vdn/networks/routing-static/net.svgz create mode 100644 vdn/networks/routing-static/net2.svg create mode 100644 vdn/networks/routing-static/network.vdn create mode 100644 vdn/networks/routing-static/r1.conf create mode 100644 vdn/networks/routing-static/r2.conf create mode 100644 vdn/networks/routing-static/r3.conf create mode 100644 vdn/networks/routing-static/r4.conf create mode 100644 vdn/networks/routing-static/r5.conf create mode 100644 vdn/networks/routing-static/s1.conf create mode 100644 vdn/networks/routing-static/s2.conf create mode 100644 vdn/networks/routing-static/scripts/common.sh create mode 100755 vdn/networks/routing-static/scripts/configAll create mode 100644 vdn/networks/routing-static/scripts/configR1 create mode 100644 vdn/networks/routing-static/scripts/configR2 create mode 100644 vdn/networks/routing-static/scripts/configR3 create mode 100644 vdn/networks/routing-static/scripts/configR4 create mode 100644 vdn/networks/routing-static/scripts/configR5 create mode 100644 vdn/networks/routing-static/scripts/configS1 create mode 100644 vdn/networks/routing-static/scripts/configS2 create mode 100755 vdn/networks/routing-static/scripts/ping-all create mode 100755 vdn/networks/routing-static/scripts/ping-all-without-r2 create mode 100644 vdn/networks/routing-static/scripts/repairAll create mode 100644 vdn/networks/routing-static/scripts/repairR2 create mode 100755 vdn/networks/sae103/build create mode 100644 vdn/networks/sae103/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf create mode 100644 vdn/networks/sae103/graph.svgz create mode 100644 vdn/networks/sae103/net.svgz create mode 100644 vdn/networks/sae103/network.vdn create mode 100644 vdn/networks/sae103/sae103.conf create mode 100755 vdn/networks/sae103/scripts/test create mode 100644 vdn/networks/zoo/bookworm.conf create mode 100755 vdn/networks/zoo/build create mode 100644 vdn/networks/zoo/bullseye-sae.conf create mode 100644 vdn/networks/zoo/bullseye-test-tgz2.conf create mode 100644 vdn/networks/zoo/bullseye-test.conf create mode 100644 vdn/networks/zoo/bullseye-tgz2.conf create mode 100644 vdn/networks/zoo/bullseye.conf create mode 100644 vdn/networks/zoo/buster-test-tgz2.conf create mode 100644 vdn/networks/zoo/buster-test.conf create mode 100644 vdn/networks/zoo/buster-tgz2.conf create mode 100644 vdn/networks/zoo/buster.conf create mode 100644 vdn/networks/zoo/docker.conf create mode 100644 vdn/networks/zoo/graph.svgz create mode 100644 vdn/networks/zoo/network.vdn create mode 100644 vdn/networks/zoo/sae103.conf create mode 100644 vdn/networks/zoo/scripts/prepareDebian create mode 100755 vdn/networks/zoo/scripts/prepareDebian.old create mode 100755 vdn/networks/zoo/scripts/prepareDebian.old2 create mode 100755 vdn/networks/zoo/scripts/prepareDebianBookworm create mode 100755 vdn/networks/zoo/scripts/prepareDebianBullseye create mode 100755 vdn/networks/zoo/scripts/prepareDebianBullseye-test create mode 100755 vdn/networks/zoo/scripts/prepareDebianBuster create mode 100755 vdn/networks/zoo/scripts/prepareDebianBuster-test create mode 100755 vdn/networks/zoo/scripts/prepareDebianDocker create mode 100755 vdn/networks/zoo/scripts/prepareKali create mode 100755 vdn/networks/zoo/scripts/prepareSae103 create mode 100644 vdn/release create mode 100755 vdn/sae103/build create mode 100644 vdn/sae103/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf create mode 100644 vdn/sae103/graph.svgz create mode 100644 vdn/sae103/net.svgz create mode 100644 vdn/sae103/network.vdn create mode 100644 vdn/sae103/sae103.conf create mode 100755 vdn/sae103/scripts/test create mode 100644 vdn/script-template create mode 100644 vdn/scripts/01-first-boot create mode 100644 vdn/scripts/02-swap create mode 100644 vdn/scripts/10-network create mode 100644 vdn/scripts/12-lighttpd create mode 100644 vdn/scripts/12-proxy create mode 100644 vdn/scripts/15-authorized_keys create mode 100644 vdn/scripts/30-services create mode 100644 vdn/scripts/90-post-boot create mode 100644 vdn/scripts/99-bird create mode 100644 vdn/scripts/mount-root-tgz2 create mode 100644 vdn/scripts/on-boot create mode 100644 vdn/scripts/on-initramfs create mode 100755 vdn/scripts/save create mode 100644 vdn/tools/.Makefile.swp create mode 100644 vdn/tools/Makefile create mode 100755 vdn/tools/build-container.sh create mode 100755 vdn/tools/compile-vte.sh create mode 100755 vdn/tools/create-singularity-distrib.sh create mode 100755 vdn/tools/libnss_vdn.so create mode 100644 vdn/tools/nss_vdn.c create mode 100644 vdn/tools/nss_vdn.o create mode 100644 vdn/tools/podman-exec-cmds.sh create mode 100755 vdn/tools/vdn-bootstrap create mode 100755 vdn/vdn-restore-extra-eth diff --git a/id_rsa.pub b/cle_ssh/id_rsa.pub similarity index 100% rename from id_rsa.pub rename to cle_ssh/id_rsa.pub diff --git a/vdn/LICENCE b/vdn/LICENCE new file mode 100644 index 0000000..b217347 --- /dev/null +++ b/vdn/LICENCE @@ -0,0 +1,17 @@ +Virtual Didactic Network (VDN). + +Copyright (C) 2006-2018 Guénal DAVALAN . + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + diff --git a/vdn/README b/vdn/README new file mode 100644 index 0000000..644573c --- /dev/null +++ b/vdn/README @@ -0,0 +1,5 @@ +=== Virtual Didactic Network === + +see : http://opale.u-clermont1.fr/vdn + + diff --git a/vdn/allocators/db-default/hosts b/vdn/allocators/db-default/hosts new file mode 100644 index 0000000..0046eaf --- /dev/null +++ b/vdn/allocators/db-default/hosts @@ -0,0 +1,54 @@ +fixme:distributeur +fixme:client +fixme:appolo +fixme:brightside +fixme:comanche +fixme:passerelle +fixme:darkside +fixme:castafiore +docker:docker +demo:web +demo:societe +demo:lambda +demo:tiny +demo:bigboss +demo:nomade +demo-buster:web +demo-buster:societe +demo-buster:lambda +demo-buster:tiny +demo-buster:bigboss +demo-buster:nomade +zoo:bullseye +zoo:buster-test +zoo:bullseye-test +zoo:buster-test-tgz2 +zoo:sae103 +zoo:docker +zoo:buster-tgz2 +zoo:bullseye-sae +zoo:bullseye-test-tgz2 +zoo:bookworm +zoo:buster +zoo:bullseye-tgz2 +firewall:web +firewall:societe +firewall:lambda +firewall:tiny +firewall:bigboss +firewall:nomade +routing-static:r2 +routing-static:s2 +routing-static:s1 +routing-static:r5 +routing-static:r1 +routing-static:r4 +routing-static:r3 +sae103:sae103 +routing-ospf:r2 +routing-ospf:s2 +routing-ospf:s1 +routing-ospf:r5 +routing-ospf:r1 +routing-ospf:r4 +routing-ospf:r3 diff --git a/vdn/allocators/db-default/hosts.global b/vdn/allocators/db-default/hosts.global new file mode 100644 index 0000000..74dddd1 --- /dev/null +++ b/vdn/allocators/db-default/hosts.global @@ -0,0 +1,14 @@ +fixme:brightside +fixme:passerelle +fixme:darkside +docker:docker +demo:societe +demo:lambda +demo:nomade +demo-buster:societe +demo-buster:lambda +demo-buster:nomade +firewall:societe +firewall:lambda +firewall:nomade +sae103:sae103 diff --git a/vdn/allocators/db-default/networks b/vdn/allocators/db-default/networks new file mode 100644 index 0000000..aa7f913 --- /dev/null +++ b/vdn/allocators/db-default/networks @@ -0,0 +1,9 @@ +fixme +docker +demo +demo-buster +zoo +firewall +routing-static +sae103 +routing-ospf diff --git a/vdn/allocators/db-default/users b/vdn/allocators/db-default/users new file mode 100644 index 0000000..fa4f0e3 --- /dev/null +++ b/vdn/allocators/db-default/users @@ -0,0 +1,3174 @@ +aahindedin +aballoui +abatallah +abbarrier +abdkhald +abhasban +ablazregue +abmazouz1 +abounoughi +acheloun +adahmedali +adambrosio +adbartoli1 +adbattisti +adbella +adbilliaer +adblanchet +adbonafos +adbordel +adboustani +adcaisso +adchabanie +adchargu +adchartrou +adcottais +adcoudour +addebritor +addenis +addenonfou +adduroyon +adelalaoui +adelgout +adfarret +adfemenias +adgaudard +adgouttefa +adguittard +adlezzoum +adlouisgui +admege1 +admourie +adnoel2 +adoziol +adpierre +adpinier +adrathier +adrbarto +adrenaudie +adsivign +adtempier +adthevenon +adwohrer +adzaia +agarnaud +agbarthele1 +agcarrasco +agdubois +aggelot +aggranger +aglabonne +agraquin +agrevel +agtrasso +ahaabed +ahghouat +aialet +aicareo +aielimache +akaijazi +alagostinh +alaidjadj +alamelbonn +alamhall +alanglade1 +alauzenat +albarthome +albeal +albeaumet +alblondel +alboeufs +albonniot1 +albonnot +albons +albontemps +alboutte +albouvard +albouvier +albouvot +albracke +albranco +albreuil1 +albrun11 +albrunaud +albrustel +albuffiere +alcarreau +alcauchy +alchambrio1 +alchampomm +alchan +alcharbo +alchastang3 +alchazot +alchomarat +alclaude +alcompto +alcondutie +aldacosta6 +aldamoisea +aldasilv +aldaveau +aldebruyne +aldegroo +aldequere +aldesboscs +aldias +aldrai +aldupichot +alduverger +alemasse +aleozwal +aleruiz +aletchebes +alfavier5 +alferon +alferreira11 +alferreira12 +alfiafialo +algallonet +algattoni +algessent +algineste +alglenat +algleyze1 +algralha +alguilhot +alinmart +aljeudilem +aljourda +aljurbert +alkeller +alkesler +allamande +allaurent13 +allauret1 +allepron +allesot +alloungar1 +almadamour +almaira1 +almamado +almaranjon +almarmeys +almartinai +almauchien +almaury3 +almayerwei +almegevand +almilani +almontorie +almoreira4 +almorvan +almuller2 +alnotin +alodin +alollier3 +alpicard4 +alplanti +alpoint +alpolat +alpouillot +alpourrat +alprost +alquintane +alrefougou +alrigaud1 +alroche8 +alrome +alrongier2 +alsaboury +alsage +alsaintbea +alsemjonov +alsigayr +alsouqui +altain +altatry1 +alteissedr +alterrasse +altessier +altrinquar +alvergne1 +alvitale +alwilhel +amadevau +amagniel +amaudoinri +ambananaha +ambarato +ambasandel +ambergam +ambesse7 +ambouzaidi +amcarrazbi +amchardes +amchloup +amciterne +amdampierr +amdarroux +amdelacour +amdelpeuch +amelaroy +amelmahdi +amferreira2 +amgabert +amgaigneux +amguiche +amlebaro +ammamaniss +amrandrian1 +amrossato +amsagna +amsagnet +amtillois +amtroncy +amvillatte +anaduran +analbouze +analvarez +anandriant +anaubouard +anautiere +anbaccon +anbairros +anballan1 +anballet +anbeaudeau +anbeaufort2 +anbeaufort3 +anbertrand5 +anboniere +anbonneton +anbouazza +anboudet2 +anboudoul +anbriam +anbroussy +anbussi +ancalmet +ancalvet2 +ancanamas +anchaleil +ancharles2 +ancharmes +ancochard +andarj +andasilva7 +andeamorin +andestarac +andetailla +andevidal +anduartes +andupois +andupont3 +andupuy4 +anduteyrat +anelia +anesteban +anfafourno1 +anfardet +anfaye4 +anfereyrol +anfernande +anferreira11 +anfigeac +anfranco2 +anfreita +angay3 +angbarge +angilbertc +angoisna +anhousseau +anhuguenot1 +animbert2 +aninacio +anjaffre +anjourdain2 +ankedi +ankhalfall +anlarpin +anlouraich +anmarcadie +anmazenc +anmendes5 +anmeyrueis +anmitard +anmorin3 +anndumas +annicolas6 +anobelli +anovize +anpays4 +anpelissie2 +anpelissie3 +anpellegri +anperederi +anpihen +anpinagot +anpontheni +anpulveric +anrabany +anrebord +anrenault +anrichard7 +anrochelet +anrodrigue16 +anroussel4 +ansage +anschall +anserange +ansophia +antassini +antauleign +antcornu +anterrier +antramba +antrzeci +anvenant +anverdil +anvichy +anviton +anwaleedma +aphugues +arallemand3 +arbossuyt +ardelafayo +ardenier +ardurand5 +arfaure4 +argabriely1 +argambiez +argiraud1 +arkoessl +arkowalski +arlasherme +arlecaille +arleyinda +armallet +armeeuwess +arndufou +arnmarti +arnsengiyu +arodin +arorgeval +arpalmieri +arpeyronon +arplanchon +arpouderou +arranglare +arsaintand1 +arservanti +arsigure +arsnasni +arsoares +arthevenou +arthievet +arvalero +arvalin +arvandamme +arzymberi +asabdoulga +asbenabdal +ascharre +asespinade +auaffognon +auandre3 +auantoine1 +aubastide2 +audaviet +audebastie +audouard +aufauger +aufleury +augiraudie +auguehi +aujault +aulaborie +aumargue +aupintrand +aupoucle +aurcaill +aurduboi +aurmaure +auroux7 +ausabatier4 +ausoulier4 +ausoussein +auvolle +awndao +axandanson +axandriant +axcarton +axchartier +axcotin +axdelafuen +axdossou +axgaillot +axgalimard +axguillier +axjulien +axmartindi +axmestayer +axmoreau1 +axraymond +axrigouste +axrodrigue +axsainrat +axsertilla +axvanbraba +ayayour +aybenioual +aybillot +aychazeaud +aydumur +ayelmhadde +aygagnaire +aylarbaoui +aymuller +aynezou +ayrahmouni +ayselimi +aytouresec +baalizert +baarnould +babaverel +babonneau +babrunet +bacadet +bacomby +bacornic +badebock +badebur +badescours +badesrut +badubrays +badudonne +baduquesno +baduret +baepisse +bafoucras +bagardette +baguillera +bahelfre +baimbert1 +bajacqueli +bakane +bakrouch +balefevre2 +bamajorel +bamalea +bamalvezin +bamarcel +bamartel +bamaufroy +bamenard +bamioche +baollier1 +bapeghaire +bapereira +bapoirierv +baroddier +baroucan +barougier1 +basalat +baschaefer1 +basurel +basuty +bathenot +bavandame +bayounci +beallard1 +bebachelar +bebarnini +bebenet1 +beberinger +bebertin +bebrunel +bechabrier +bechagno +bedeschamp +beducornai +beduman +befoure +begabriel +begourmil +begrave +begregory +bejacquet1 +bejarlan +belabonne +belevarl +beluquet +bemagnet2 +bemailho +benecoha +bepaczkows +besaouli +beteixeira +betixier2 +bevalleix +bibangoura +bibenboule +bichougui +biguillaum +bisalem +blbattut +blly +bltartiere1 +bomichalsk +bralbert +brbelin1 +brberganza +brbourgo +brchatai +brdacostac +brdespal +brduarte +brfilliat +brguillot1 +brgutier +brhorion +brjourde +brpetitet +brsteeland +caabrial +caarango +caarbaud +cabegonr +cabento +cabenzerro +cabrocke +cacasals +cachevar +cachevassu +cacollomb +cacruz +cadausse +cadomingos +cafaure14 +cafilipett +cafournier8 +cageliot +cagiffar +cagregoire5 +cajoudiou +camassotea +camipeti +camlemai +camonnier +camoua +canoury +caoudot +caperaut +caperrier3 +caperronda +capeynet2 +caronau +casimmon +casimon +casunyindi +catardif +catardy1 +cathanse +catheillie +cathominet +catiberghi +catranchet +catvatou +cazanins +ceallinc +ceauzeau +ceberthonn +cebonal1 +cebonnefoy1 +ceborel +cebouhou +cebourgn +ceccolli +ceceaux +cecharbonn5 +cedchapa +cedugand +cedvigie +ceengramer +cegafanhao +cegagnev +cegatignol +cegimber +ceglaizol +cegomis +cegonin1 +ceguichard +cejohnston1 +cekempf1 +celdegea +celespine +cellasribe +cemoreau3 +cepinard +cepissardm +cerey +cethiers +cetouba +cetrecou +chabreu +chadesch +chaolivi +chapinsa +chaucagne +chbarnay +chbeaurega +chblanc +chblavig +chbordes1 +chbreton +chchakhgue +chcharle +chcivard +chcombau +chdali +chdalverny +chdechamp +chdeplat +chelmimoun +cheyme +chfachin +chfagheon +chgassen +chgiraudon1 +chgondard +chguichon +chhospit +chjuban +chlabonne2 +chlepape +chlustie +chmagales +chmakoug +chmalo +chmarliat +chmartinez8 +chmassar +chmihala +chmillet3 +chmontau +chmourgand +chmourgu +chmuzelle +chnierding +chouerghi +chours +chpelade +chpeyretai +chporte1 +chrdupuy +chrichev +chridubo +chrimart +christma +chrives +chroudier +chrpierr +chrvalla +chrvelut +chsamir +chsnani +chterrier1 +chtourna +chtrabelsi3 +chvaurillo +chvernis +chviceriat +cladioud +clamaton +clambrosio +claubremai +claussert +clbarage +clbarnavon +clbecquie +clbonaz +clbornard +clboyer11 +clbranger +clbrosse1 +clcastres +clchambo +clchantela1 +clchevrel +clchieu +clcosta +clcrepin1 +clcrespola +clcrouzier +clculetto +cldelpy +cleduboi +clefau +cleiras +cleschenbr +clfarfait +clfargette +clfaure10 +clferrere +clfreville2 +clgalibert +clgauran +clgil3 +clgoineau +clgrange2 +clgranier2 +cljarreau +cllacote +cllaporte +cllarias +cllaronde +cllavergne4 +cllecour +cllesme1 +clletzelte +cllindner +clmallet8 +clmasson1 +clmesny +clmialon3 +clnezblanc +cloziol +clparis1 +clportalie +clprat1 +clquart +clranglare +clreynaud1 +clrogeaux +clsiguier +clsoignon +clszczep +cltetard +cltournant +cltourret +clvara +clvarga +clverdoire +clvialle1 +clvian +clzalio +clzborowsk +cobarbier +cobarnier +cobeaudonn +cobelvil +coborder +coboudon +cocavagnet +cocharbon +cocome +cocornuot +cocoudert +cocouvreux +cocros1 +codidelot +cododin +codoucheme +coferreira +cofrancois1 +cofrizot +cogalonnie +cogourmaud +cogstalter +coguichet +cojouve +coldamon +colebars +colemaire +comoutaud +coollier +coperrin2 +copetit +copimentel +copitt1 +copradeau +corichard1 +cosilvestr1 +cotanguy1 +cotissier +covennat +coverot +crbunch +cybracher +cycalmels1 +cyfayelle +cyguillon +cyjacquemo +cylaveyssi +cylonchamb +cymutin +cyperinet +cyrougier1 +cysodaig +dabaccaud +dabatteux +dabertrand2 +dablanc4 +dabonetto +dachrzan +dacoursi +dadalmeida1 +dadasilva4 +dadaval +dadelon +dadinee +daferrie +dafriess +dagladine +dakebe +damandala +damandor +damarschal +dambardy +dambaye +damgiron +damigonz +dangounoum +danguyen1 +danortier +dapicard1 +darage +daraymond3 +darichar +daroyono +daseddeki +dasilber +davacher +davaivrand +davcomte +davessie +davibonn +deardid +debonnet +debouche +dediene +degratio +degreffet +denjouff +deroux1 +diagripino +dichassa +diezgi +diilkay +dirouire +disaintg +diseran +djcisse +djmohamadi +doalonso +doauboueix +doauzel +doblanchet +dodelacr +dodhenai +dofalies +dohodin +dojouanne +dolafont +doleclercq +doloubrado +domalioche +domatha +domichoux +dopradeill +dosafidine +doseyrolle +dyancelin +dychauvet +dydakpa +dykabano +eaelsafa +eamoua +edbattiste +edborot +edbrunie +edcosterou +eddabrig +edgoma +edrougier1 +ehkouako +elallais +elandre4 +elbeaud +elbillar +elbiseuil +elbontemps1 +elbortoli +elbrun6 +elchevalie8 +elchevrier1 +elconte +elcoulon2 +eldarocha2 +eldelarosa +eldonnier +elferal +elfernande5 +elferreira4 +elfourni +elgallet +elgay +elguette +elhermet +eljelic +eljourda +ellacourt1 +elleguehen +elleriche +elmaille +elmarchepo +elmerlin1 +elmessina +elmetenier1 +elnoirau +elpautard +elpetit3 +elpierre +elpontvian +elpothier +elroux7 +elturle +elwest +embailly +emberthier +embeys +embianchin +emboudot1 +embourdon +emboussena +embrasse +embresson +embrindel1 +emburle +emcaldei +emcherea +emcia +emcrouzier +emcuzol +emdabert +emdasilva8 +emdelic +emdeshayes +emdupuissa +emfauque +emfesche +emgoasguen +emguilbaul +emkartal1 +emlorette +emmaltete +emmarechal +emmchabo +emmignard +emmorisset +emmounet +emnarce +empaliot +empery +emrambert +emrenou +emrottier +emroux10 +emsalgueir +emsaut +emseon +emsouchal +emsudre1 +emteissier +emtouche +emturmeau +emvallat +emvassias +emvazeil +emveronnet +enartaud +enaustruy1 +enbrun +encelle +enchastane +encouto +endefelice +endogru +enfavre +enfoucher +engonzalez +enjolys +enkaya +enlafont +enleoty +enmage +enmora +enranvier +ensoeiro +eranneavel +erboucha +erboudon +ermenager +erpeyret +erpoyet +erroyer +ersahin +ertheron +esandre2 +escalvet +esdeazeved +eshanne +esherail +esjulesfau +eslouvier +esmenut +esquiqua +esrousset +essimoens +estbigot +etbozec +etbruger +etcellier +etcharpin +etcoyac +etdelpuech +etgroueix +etmonat +etmoulin +etpagesdoa +etpegand +etterrier +eudubois +eupulveric +evabrial +evbernar +evbert +evcourt +evdelon +eveyraud +evfayos +evforissie +evgenevrie +evgirond +evlamy +evlesueur +evmaurer +evprothier +faamane1 +fabarlet +fabosquet +fabouchotc +fabrionne +fachantela +fachaput +fachasta +faclement +fadesurmon +fafesche +fagenin +fagoutorbe +fajouhanne +faleperon +famahammad +faozer +fapantel +faquaino +farocher +farossi +fasapet +fatailha +favaz +fbmazuel +fecourbon +felacoste +femallet +femielcare +fesahin +fimazza +flandre3 +flapacco +flbassot +flbecouze3 +flbenoit +flberlin +flbouhamda +flbourgoig +flboyer8 +flbrunel2 +flbuhot +flcapall +flcoulon2 +fldelche +fldevender +fldrut +fldubois10 +fldumas5 +flfaure8 +flfoucau +flgarcia3 +flgateau +flgaugirar +flgregoire +flhospit +flmareynat +flmarques1 +flmolteni +flmourette +floblois +flpayet +flrios +fltedeschi +fltoire +flville2 +flvivet +fradegou +franstep +fraulric +frchardo +frchauss +frcollan +frdelobe +fredfaur +fremorin +frfarget +frglazio +frgraffi +frjacque +frjammes +frkuss +frminet +frmotton +froliva +frrefouvel +frrevere +frsaccoman +fryousse +gaabrial +gaalves +gabarbosa1 +gabayout +gabeaudonn +gaberger2 +gabrunel1 +gaclamens +gademonet +gadomaison +gadosset +gaduyck +gaelegac +gaeps +gafaugere +gafoucher +gafougerou +gagerentes +gaghaddar +gagoddet +gagoncalve1 +galachenal +galandri +galembert +galeydier +galheritie +gamarechal +gamareyn +gamarsolla +gapachot +gapierre +gapillet +gaporee +gapriouret +gaprot +garodrigue5 +garoux2 +gasoubeyra +gatheuws +gaucanq +gavalentin +gdsidibe +gebarriere1 +gecampedel +gechalho +gedobbelae +geobayar +geofavit +getreignat +ghrollan +gisballe +grbazire +grblanch +grchandiou +gregguir +grleveau +grmarcet +grmbemba +grsaillard +guassailly +gubardakof +guboucha +gucothenet +gudavala +gudavid2 +gudiasda +gudurand2 +guespinass +guiimber +guilranc +gulevet +gumalvezin +gumonier +gupailhoux +gupantel +gupatouill +gupaulhe +guquinio +guramel +guregnault +gurey2 +gutoumazet +guvalentin2 +guvidal2 +guzanin +gweroche +gwmajewski +haabdelk +haahamada1 +habenalaya +habendaoud +hacisse +hadalgin +haelouar +halabour +halepere +hamathieu +hamendoud +hashaitit +hasow2 +hayalcin +hebertra +hebotcho +hecoumoul +hederoquet +hefosse +hehaltemal1 +helchat +hellevet +helmilie +hervaleg +hevidil +hifernande +higurlie +hjdoumbia +hualbisson +huandrejew +huauger +hubarrando +huberthonn +hubougerol +hubouletsa +hucanivet +huchamarat +huchambon1 +hucharbonn +huchignier2 +huchossonn +huclamens +hucoiffard +hucoitou +hucortial +hudenizot +hudevignes +huescuroux +huflorenti +hugdelos +hugely1 +hugoyet +hugpeyta +hugrimaldi +huhanusiak +hulafontai +hulagner +hulahouel +hulivet1 +humartin3 +humeravill +huminambre +humioche +huoculy +huody +huparan +hupawlowsk +huperonnet +hupeyron +hupradier1 +hureydepre +hurobert1 +hurochelle +huroger +husergere +hustassine +huthelyden +huthibon +huthys +hutournadr +hutuzet +huyavuz +ibcakir +ibdjabi +ilbellard +ilcabouni +ilhadjabde +ilkaddouri +ilnourine +imcherrat +imdehli +imreuche +inaissi +inboukhadr +inbousquet +incassi1 +inguyonnet +inkouidere +inmaani +inmorel +inoudjani +inschidlow +irmoutsi +isamouni +ischamoux +iscossou +isdiouf +isgoi +ishniminau +ismoreau2 +isndiaye2 +isseptem +istahajana +isvillalde +ivleteuff +ivwawrzy +jaabdelsad +jabengherb +jacouchot +jaduclos +jaexartier +jaguerre +jainfante +jakahlouch +jakanfou +jakerfa +japerol +japrulhier +jaquantin +jarejony +jasue +jathomas2 +jatoussain +javaure +jawhitton +jawoods +jbperez +jbrouvet +jcbailly +jcluans +jcratsara +jeanglade +jebesnard1 +jebesse +jebesson2 +jebonnic +jebourebi +jebrugiere1 +jebusser +jechanal +jecondutie +jecornetve +jecrozat +jedenizo +jedeporte +jedollet +jeduchesne1 +jeducourth +jedumuis +jedupont +jefayard1 +jefourment +jegarret +jegil +jegouber +jeguinet +jelimagne +jemailfe +jemarcilla +jemartins1 +jemassines +jemetal +jeminet1 +jepounit +jeschanc +jetourna +jetremblay +jevirole +jfbruger +jfdenieul +jfhurier +jfpont +jijridi +jjalopez +jldegirond +jlfremau +jlgilberta +jmafavre +jmallanic +jmlavest +jmracoll +joartzet +joblanc3 +jobonin +jobonvin +jobordeau +jobourdo +jocabrerac +jocinque +jocosterou +joduperret +jofdevau +joforestie +jogadet +jogerbe +jogodefroi +joguillet +johaoui +johedieu +johmille +joibrahim2 +jolachenal +jomanaranc +jomartydit +jometifiot +jominchin +jopascal1 +jopierron +joratton +joribeiro1 +joroux2 +josilly +joteissier +jotoussa +jovigier2 +jpjacque +juachard2 +juadvenier +juaguilhon +juandre1 +juangenieu +juaubry1 +jubaraduc +jubarbatdu +jubartasso1 +jubeaudoux +juberal +jubergouni +jubernalie +jubijoux1 +jubloux +jubonnand +jubourlon +jubrugerol +jubrun1 +jubruyere3 +jubujan +jucarvalhe +jucasals +jucasimiro +jucathaud +jucaylou +jucercy +juchalayer +juchevalie7 +judefour1 +judouarre1 +judupre +juduteyrat +juduverge +juescalier +juetaix1 +juetienn +jueyzat +jufazendap +juferrier2 +jufevre +jugachon1 +juganne2 +jugroueix +juhaga +juhebrard1 +juheinis +jujoachim1 +julaffez +julazema +juleonard2 +julesueur +julpages +jumahul +jumaiffred +jumarol +jumazen +jumeuret +jumeyer6 +jumignotte +jumonteil1 +jumonteilh +jupascal5 +jupatural +juperrin6 +jupetitbon +jupitelet +jupourtier3 +juprat2 +juprost +juravet +juraynal1 +juriboul +juribreau +juroche7 +jurossell +jusarmet +jusourylav +jutaylor +juteissand +juternat +jutheme +jutugar +juvidal10 +juvieira +jvamacq +kaabdelkad +kadidier +kagiraud1 +kagudanaux +karbogto +kasghairi +katecher +kavincent +keauterive +kebeaugr +keblondel +kebory +kebruyere +kecorreia +kedasilva4 +kedasilva5 +kedemir +kedessol +kedumas3 +kelecharde +kemonteiro2 +keperry +kevalente +khbruneau +khdasiyev +khfadhla +khloichet +kicherifi +kiexbrayat +kifaure1 +kiheritier +kimascheix +kimathieu +kimeunier +kipage +kirodert +kltachet +kmdevoles +koawitor +krlazou +krray +kychabanon +kydavid +kyjouvency +kysage +laaubry +laaugier +labarrat +labarthome1 +laberchoux +labondieu1 +labonnal +labougar +labrette +labreuil1 +labros +labusquets +lacanetti +lacarvalho1 +lacusson +ladagost +ladarmet +lademas +ladesros +ladiop +lafontaine +lafournet1 +lagaulen +lagauthier4 +lagemin +lagiraud +lagomez1 +lagonin +lagreck +lagregoire3 +laguienn +laguillarm +lalaforest +lalemoin +lamalate +lamarty2 +lamolenat1 +landias +laparret +laprovot +laraynau +lauducro +laufayet +laviel +leaugagneu +lebatouxas +lebeaulato +lebelin1 +leberson +lebesson5 +lebion1 +leblanchon2 +leblin +leboric +lebouamran +lebouteill +lecazalet +lechagnon +lechambare +lechevalie4 +lechouvel +lecoudertb +ledecombas +lederoide +ledetommas +ledrochon +ledumont +ledupont1 +leenault +leessique +lefernande7 +lefernande9 +leferreira3 +lefiguet +lefollot +lefritz +legalibern +legardelle +legicquel +legoutte2 +legravier +lehader1 +lehamla +lehervieu +lejacquet1 +lejaffuer1 +lejavelle +lejorland +lejuillard1 +lelacroix3 +lelapender +lelaroussi +lelasseur +leleboedec +lelhoste +lemansare +lemartin7 +lemartin8 +lemillot +lemoneger +lemunoz +leorober +lepalabost +lepatural +leperricot +lepetit1 +lepinto +lepramalio +leramos3 +leraphael +lerateau1 +leriocros +lerobert8 +lerogue +leruy +lestaimphi +lesurrel +lesvest +lethomas3 +letournadr1 +letroccaz +letuaillon +lezanini +liastruc1 +liauclair +liavard +libadieres +libellefin +libenite +libreton +libroquin +libruyere +lichampin +lidahi +lidaure +lidossanto5 +lifayet +lifoulet +ligaillat +ligiraud1 +liguenand +liguerrier +lihertel +lijames +lijolly +lilabate +limichel1 +limonchani +limurat +liojouve +lipetit2 +lipeyraud +liplazanet +liressouch +liroussy +liroux +lisalgado +lisauerbre +lisurrel +lithomas1 +lituy +livernet1 +livernette +lmleone +loantoine1 +lobaubet +lobeal +lobeauthea +lobeguet +lobellec +loberiard +lobonnabau1 +lobonnet5 +lobordji +loboucheix1 +lobouchet1 +loboulet +lobroda +locaporale +locarpenti1 +lochakaria +lochalmin +lochandat +lochapon2 +lochassagn +lochavagne +locherasse +lochevalot +locouderc2 +locusinpan +lodegentil +lodelannay +lodufour1 +loduran +lofella +lofinaz +lofrancois4 +logameir +logiacalon +logispert +logoubet +logoulmy +logranvaud +logrosbell +loguilhaum +loguiraude +lohamard1 +lohoriot +loideles +loidevau +lolaborie +lolabussie +lolasherme +lolavigne +lolhostis +lomartin12 +lomerand +lomian +lomonginou +lomonteyre +lonerfi +loobry +loparant +lopatton +lopaulet +lopays +loperret2 +loperret3 +lopezaire +loplantade +loquerlioz +loregnier1 +lorenault2 +lorobert3 +lorougier +lorougier1 +loroussel2 +lorusak +losaffre +losilve +losoaresda +lost+found +lotorres +loudauga +loudebar +lovalade +lovarago +lovedrine1 +loviallet +lrvuillerm +ltdannus +luageorges +luannicett +lubadiou +lubedouret +lubelard +lubelligon +lubesseraz +lublouin1 +lubonnel +luboudon3 +luboulade +lubourdiol +lubresson +lucastigli +luchabrill1 +luchalmeau +luchassang +luclaffe +ludaboussy +ludebussy +ludechanet +ludelanier +ludesforge2 +ludevillar +ludgodar +ludlegro +luduflot +ludupuy1 +ludurand +ludurand1 +luduru +luevard +lufernande8 +lufort +lufournier5 +lugaillard5 +lugaliano +lugirond +lugoigoux1 +luguittard1 +lujacon +lujanvier +lukeomany +lulavest +lulevet +lulucand +lumarco +lumaujean +lumege2 +lumercy +lumoulin4 +lumoulin5 +luocamicad +luperrat +lupouget2 +luquidel +lurobb +lurobert5 +luroche3 +lusanchez1 +lusoanen +lusouyris +lutastevin +luthevenet +lutorret +luvalade1 +luvarichon +luvassault +luvayssie +luvelut +luzborowsk +luzembrzus +lydealmeid +lygiroir +lyperrot +maadjif +maahmadouh +maalbiero +maandremas +maarcherng +maarnaud16 +maatouil +mabaguet +mabalzar +mabamdad +mabanny +mabarge4 +mabaroupir +mabarreau +mabassi1 +mabataillo +mabatista1 +mabay4 +mabel3 +mabenistan +maberger20 +mabernard41 +mabernardi5 +mabernus +maberriotc +mabertholl +mabertogli +mabesserve4 +mabizet +mablanc22 +mablangy +mablinet1 +maboizard +mabonetti2 +mabonnabau1 +mabony10 +maborel3 +mabouchet8 +maboudi +mabousquet8 +mabousteya +maboutonni +mabouvard2 +maboyer45 +mabozec +mabrando +mabringer2 +mabrivari +mabroquet1 +mabrossard2 +mabrun23 +mabrunet15 +mabrunpica +mabullich +macaillot +macalmels +macampourc +macappelle +macarrouee +macaudal +macenteno +machabid +machalopin +machambaud +machandeze +machanel1 +machanet4 +machanssea +macharat +macharpent2 +macharpin1 +macharrat1 +machartoir +machaumont2 +macheval +machiere +macholley1 +machristol +macognet4 +macointet +macollette +macombes4 +macondefer +maconstant5 +macorge +macottavoz +macoudoule +macromaria3 +madaim +madalmeida3 +madasilva23 +madebettig +madefretie2 +madelage3 +madepres +maderangeo +madesbouys +madesousa8 +madias1 +madosreis +madoucenet +madouellou1 +madubost11 +maduclos1 +madumas30 +madumay2 +maemasso +maepaud1 +maescarava1 +maespejo +mafahs +mafalcon4 +mafall10 +mafarey +mafargea +mafaure46 +mafernande34 +mafernande36 +maferreira15 +maferreira17 +mafevrilli +mafournie1 +maframit +mafratissi +mafredon +mafrezier +mafritsch +magalli1 +magaluba1 +magarrigou +magarroust2 +magilbert10 +maginhac +magirardet2 +magoaregue +magouttera +magrand9 +magranet2 +magregoris1 +magrenie +magroussea1 +maguiguet +maguillot13 +maguitard4 +mahamada +mahersan +mahitier +mahoerner +mahonorez +maivain +majacob4 +majallais1 +majandaud +majardin1 +majarry3 +majavanaud +majaverlia1 +majay6 +majean5 +majonget +majouannet +majourdan10 +majridi +majulienla +majunes +makarroum2 +makeskin +makienlen +malabopin +malabourot +malabuss +malambert9 +malamouche2 +malanone +malassalas1 +malefebvre8 +malemaire +malepetit +maleroux2 +malevyvale +maligneul +malioson +malivrozet +maloirette +malombar +maloriot1 +malugoboni +maluret +mamaiterfe +mamallaret1 +mamarchi1 +mamarquet3 +mamartin59 +mamasse4 +mamathieu12 +mamauger1 +mamaulus1 +mamazingue +mamazza1 +mamedynska +mamelein +mameridja +mameunier17 +mameutelet +mameynie +maminard2 +mamolle1 +mamondelin +mamonnet5 +mamontel2 +mamore +mamorel27 +mamoulin15 +mamounier1 +mamourgues +mamuguet1 +manawrot +mandione +manoel10 +manordest +manowakows +manrocco +manroux +maolivas +maorillon +mapailhoux +maparillau +maparrain +maparry2 +mapascal5 +mapasselai +mapatry1 +mapayetauz +mapeixoton +mapelletie4 +maperderiz +maperrier11 +mapetitcol +mapicard10 +mapimbert +mapinto4 +maplisson2 +mapoint2 +mapommie +mapons17 +maporas +mapoulain1 +mapourcel +mapouriau +mapouteix +mapozdnyak +mapuechber +maqueiros +maqueiros1 +maraby3 +marahali +maraviol +marayssac +marcornu +marenault3 +marepincay +marestit +marevollat +margboye +maribemont +marichard23 +marigollet +marmorez +marobert34 +marobillon +maroddier4 +maroddier5 +marogier +maroiron +marollet1 +marouault +marouches +maroudier1 +maroux18 +maroy14 +maroyer3 +marybarczy +marygaut +maryoth +masapountz +masauveu +mascalzo +maschwalm +masechirou +maseguin7 +masion +masoares4 +masouviraa +masuchet2 +mataieb +matailland9 +matbonne +mateyssier4 +matgaume +mathevenet8 +mathevenot3 +mathierry3 +mathierry4 +mathiery +matouraud +matressol1 +matuffery2 +matureck +maulutuipa +mavacheres +mavaladier1 +mavalentin7 +mavallet3 +mavandijk +mavanhaeze +mavassel +mavazeille2 +mavazeille3 +maverdier16 +maverniere +mavialatte5 +maviel4 +mavigier8 +mavimpere +mavincen +mavincent16 +mavoute4 +mawalocq +mawissocq +maxduval +maxgras +mayenny +mazayene +mclipson +mddaguis +mdlatip +mearafa +meaynard +mebeurrier +mecarasco +mecarvalho1 +mecourteix +mecouvert +medebatiss +medelmas1 +meeyraud1 +mefabre3 +megenet +megodiveau1 +mehanida +meizard +melanglois +melaurent6 +melcherv +meleberre +memachado1 +memathieu1 +memirgon +memoranges +meozcicek +mepitout +merigaud +merouvet +mesac +metuncer +meublet +meuner +meveysseyr +mevigneron +mevoldoire +mfhubert +mfservaj +mfvillat +mibidet +miboulan +micdidie +micnguye +miconry +microdri +midebray +midubois1 +miferreira1 +migrellet +mijacquot +mijuan +mivillem +miwezl +mldizier +mlmagassi +modesport +moelmakkao +moessouak +moettouil +mohassani1 +mohtrraf +mokhiat +mokoubar +molarpin +momadiouss +moprunier +mosavart +mosinopoli +mosuarez +motayara +mouaouni +mozeghou +mozouhri +mscasanova +mugul +mukahraman +mukhuvsgul +muustun +myantrib +mygarrid +mymoureau +mzamini +mzhassane +mzjeeawody +naaugheard +nabarbat +nabeaufils +naberbenni1 +nabernardi +nabertiaux +naboileau +nabonheur +naboudon1 +nabouret +nabousquet +nacasas +nacavard +nacouden +nadauga +nadhamma +nadompie +nadosjoub +naelfakiri +naestelle +nafonty +nafouchard +nagiraud +nagordon +najacquet +nalambaraa +nalenoir +namaurin1 +namichel1 +namillier +napaulin1 +naportal1 +napoulalio +naprotzenk +naqueyrut +naraheri +narahrah +narichard3 +nasauvan +natramad +naverdier +naverduijn +naverne +navirlogeu +nawollensa +neaubert +nedchatt +nerose +nhbelrhitr +nibarnic +niberdouz +niblondeau +nibridier +nicchadu +nicgueri +nicmaury +nicoyard +nidelpirou +nideltro +nidomerg +nidoupeux1 +nidurack +nifalcot +nifranco +nigreven +nigrignac +nijobert1 +nilacour +nimaye +nimonteilh +nimonteiro1 +nimorin +ninolin +nipillet +niploix +niraymon +niroigt +niroussetf +niroux3 +niselvy +nistriff +nitixier +nitournadr +nituffery1 +nivazeille2 +nivialle +niyardim +noabdell +noallezard +noamalric +noaugoyard +noborel1 +nobouygues +nocatherin +nochevassu +noconnin +nodealmeid +nodevouass +nodubien +nofauverni +nogarnier1 +nolapeyrie +nomarcoz +nomasson +nomianowsk +nomoullec +nomounie +nopallet +noporte +nopouget +norandon +nosillard +nosoilihi +nospeciel +novarjabed +nozolger +ocalizon +ocbertel +occlain +ocdelaunay +ocdressy +ocgaritte +ocmetton +odaubree +ogdolmaci +oghan +olbardot +olbenedic +olblanc1 +olgiroud +olguinal +olidemar +oligoute +olteraub +opgrenet +opsoleilha +opvilela +orlebroc +ospimpaud +otbenjello +ouhabach +oumoutik +ousouib +owargout +oxpoullot +ozsallabas +pabarral1 +pabelin +paberaud2 +paberot +pabonhomme1 +pabonnal +pabourna +pabourret +pabrigou +pabrugiere +pacharbo +pachecch +pacordesse1 +padescot +paflorat +pagarry +pagawron +pagay1 +pagiraud6 +pahaon +pajaniaud +pakernei +palafour +palarue +palauren +palebouar +palemetaye +palevrault +pamaloron +paminiau +panantou +panpapon +papequig +paperez1 +papieuchot +papinault +paravel1 +paregnat +pariveau +paseon +paseronde +pasquizzat +patirat +pebouvard +pecapell +pecouedel +pecourto +pegauvin +pelacure +pemezquita +perichy +pevert +phgailla +phibost +phjourde +phluccar +phmaille +phmaret +pholivier1 +phrenon +piantoinat +piballandr +pibarlot +pibelmon +pibezbor +pibourdiau +picantourn +picarlet +picaumon +picros2 +pidemay +pidemurard +pidupuis2 +piedauma +piedumon +piepic +pierarno +piferreira +pifoussard +pifully +pigarrel +piguinau +pileheu +pimourgues +pipeyret +pipitout +pipruniere +pisaugues +pisauvan +pitastavin +pithurin +plcharnier +plfabre +pllasseur +pmfernande +prfaure +prgaonac +prmasson +prpilaud +pymalegue +quaoustin +quaubert +qubeal1 +qubordiga +quchamaret +quchirac +qudupont1 +qugireaud +quglayat +qugrandjea +qujay +qukuntzler +qulecoz +qulheveder +qumoreau1 +quortega +qupoumeyro +quraynal +quserange +qusoule +quvieillem +rabaudiman +rabendoula +rabouter +rachartier +racoiffi +radarmon +rahacques +rahassine +rahassou +raheraba +rakhedair +ralacote +ramazoyer +ramicoli +randiaye1 +raphdela +rapiastr +ravromandt +reakossi +reamari +rearnal +reaydin +rebeuret +reblondet +rebrechet +recharmant +recovizzi +redauzet +redefaria +redethoor1 +reduplay +relandra +relasne +relaurent3 +relavergne +relecler +remalgou +remartin3 +remipoll +remoullec +repalisson +repetre +reregnault +revillet +ricbergo +righannam +rigozzi +risegura +roaguay +roalbino +roandre2 +robaylot +robergeal +robesse1 +roblanc4 +robonnetli +robossy +robotz +roboulange +rocaly +rocamiller +rocheyrou1 +rofayt +rofila +rofillot +rogarry +roguillon1 +rojousea +rolabesse +rolagarde +rolarrieu +rolefevre +rolegoy +rolemoan +rolemouzy +rolochenth +rolussan +romalzieu1 +romarcaud +romarquant +romarsau +romasson1 +romchiro +romiallet +romondiere +romonteil1 +romurat1 +roohanness +ropalau +ropelat +roperigaud +ropons2 +rorigaud +rorossetto +rosouchon1 +rotartie +rothevenot1 +rotournadr +rovaissair +rovergne2 +rovial +rovidal2 +rovilleg +rskhodri +rulefebvre +rumartinsd +rupiris +rycambon +saaouiche2 +saaurelle +saavarguez +sabaranger +sabehar +saberaud +saberion +sabouquier +sabraike +sachebbi +sadabert +sadeat +sademeule +sadepardie1 +sadieste +sadunis +saelakili +saennia +safeschet +safolleas +safontanet +sagervas +saghebrid +sagrange4 +sahavrez +sakebdani +salafont +saleonard1 +salepaysan +samabadi +samartin9 +samohamed6 +samoumit +samounta +samoury1 +sapicut +sapoyet2 +saraveyre +saroche3 +saronger +sarosette +sasaitz +sasirven +satorti +satounsadi +saveyriere +sebapasc +sebelfetta +sebherna +sebmarli +sebpoint +secollet +sedelmas1 +sedoridant +sedoumi +seelgarrai +seeski +sefargeix +sefougerou1 +sekaya1 +sekettan +selathene +selatier +senovais +seregaie +sesaintroc +sesalva +sesame +setachon +seteyssier1 +setutal +sevialle +sevincent +shcascarra +sialic +sibeaunee +sicalen +sidallet +sidesenclo +sidupirejo +sigervais +siguillot2 +siitier +siraviol +siromane +skbekhouch +smsault +sochartrou +sochatti +sodassaud1 +sodiouane +soduchez +sodupuy +sofryszm +sogoumrhar +sojoubert1 +soleveque1 +sopbesse +sopchaus +sopezot +sopirin +sorougeron +sosaadaoui1 +sovayssier +staujoulat +stbreuil1 +stepommi +sthermit +stjoseph1 +stmadar +stmathot +stmehoua +stmeyome +sudasilva1 +sulehner +svguilla +sycoiffe2 +sycopet +sygazagn +sygermai +syguilla +syjouven +sylepeti +sylrouss +sylvcoly +symalvieil +syquille +taaubijoux +takalayci +tasimonnet +tatissot +tebouche +tedefrance +tedepret +teweber +tfahmad +thalix +thallain +thartaud +thbachel +thbelier +thbellem +thblanc4 +thboirel +thbonnevil +thboyer7 +thbuchou +thcalchera +thcapus +thcelle +thchambade +thchazot1 +thcoli +thcoulan +thcramois +thcrombez +thcrouzet2 +thdasilvam +thdecaeste +thdelpirou3 +thdemeyere +thdesbois +thdestaill +thdevienne +thduboscla +thdufour1 +thdulud +thdupin2 +thfavodon +thfernande5 +thfourne +thganga +thgardes +thgarnier3 +thgenot +thginhac +thgoigoux1 +thgroisne +thgrosse1 +thherviou +thhugny +thidedie +thihonor +thivars +thjacquet3 +thlabarre +thlabory +thlacroix4 +thlatchi +thlaya +thlayat +thlebailpa +thleloup1 +thleuridan +thlichtena +thlutz2 +thmagalhae +thmaillarb +thmandon1 +thmansanet +thmasson3 +thmasson4 +thmaurin2 +thmerle2 +thmeyronne +thmischler +thmoriceau1 +thmorin2 +thmotescum +thmourgues +thmuzard +thnicolas5 +thnicolas7 +thpaulet2 +thpegheon +thpetitb +thphilip +thpicamelo +thpothier +thpoujat1 +thprades +thpradinat +thrabany +thraimbaul1 +thralet +thramousse +threnaud1 +threy2 +thrichard11 +throchefor +thromaniuk +throngere1 +throyon +thsaintleb +thsauvai +thschmiz +thsmith +thtalon1 +thtissier1 +thtraikovi +thtrevis +thurban +thvercasso +thvernet3 +thvernisse1 +thveysseyr1 +thvitry +thwilhem +tibarreira +tibertrand1 +tibettonpl +ticurado +tiduclos +tifabre +tiidris +tiivorra +tilestrade +tilevadoux +tilouvet +tipham +tiseguin +tisenty +titixeront +tivelle +toangely +toberne +tobertram +tobiard +toboutier +toboutillo +tobrouard +tocadoret +tocarpenti +tocouchard +tocoullomb +tocrouzet +todumourie +tofabre +tofages1 +togeniquet +togronfier +tolafanech +tolours +tomanciati +tomargot +tomontagno +tomounier +toncano +topourtier +torambeau +tosudre +toviars +tratger +trbarlet +trbauzil +trbesse +trbraz +trbrun +trchallet +trdieumega +trjaniszew +trmartinek +trmartinek1 +trperier +turoy +tylaloi +ugduteil +ugvignon +ugyigit +ulboutin +ulrome +unlartigau +vabouchot +vabrandon +vacabrin +vacentener +vaclergue +vacondodos +vacourmont +vacravinho +vadelpuech1 +vadoignies +vafavier +valavialle1 +valdumon +vamahaling +vamercier1 +vaparado +vapinon +vaprevot2 +varaffier +varagazzo +varassinie +varenaud +varouge +vatremeaud +vavazou +vdn +vemiraju +veronmor +viallirol +viarrault +viastolfi +vibaraud +vibauge +vibaz +vibuchon +vibuchou +vichabre +vicharmes +videlestre +videlmon +vidrouillo +vidufour1 +vifaure7 +viferreira +vigaborit +vigaillard2 +vigalloy +vigarsau +vijamon +vijamot +vijourdy1 +vikaczorow +vilimoges +viluc +vimarcas +vimaronnat +vimartin12 +vimeunier1 +vimoulin3 +vinraspa +vipicolet +virbonni +visalomon1 +visoudy +vithery +vitourlo +vividal2 +vpngounou +wadmatar +wamestiri +wapeschaud +werouel +wibussie +wifontaine +wigarrier +wiguyot +wimihindou +wipoursac +wujeremiej +xamollard +yaaddi +yaaudebert +yabah +yabargoi +yabattache +yaboudache +yabouzaidi +yaboyer +yabresson +yachampeau +yachampomm +yacharbaji +yachiffe +yacladie +yadahmaneb +yadarbak +yadarkaoui +yadimassi +yadoumirfe +yaessouak +yaferguen +yafeunte +yafevrier +yagerard +yagourbeix +yagranet +yakarabulu +yakraghel +yalouati +yamarchal +yamerlin +yamourguy +yapelopone +yaperrin1 +yariviere +yasellak +yasevret +yearchimba +yeberriah +yefaliez +yhboukhn +yoaissou +yoaraiso +yoattar +yobouazi +yobreuil +yobrugiere1 +yoburgun +yodecarval +yoessika +yofaurie +yogeoffre +yogourves +yohamri +yolamamy +yolemeur +yolouedec +yoraguenea +yoromagny +yosahraoui +yvcalatayu +yvcommun +zasaoula +zichatti +zobronet +zodavid +zodepedrin +zooblette +zoorsati +zooulli +zorosay +zyouazi diff --git a/vdn/allocators/default b/vdn/allocators/default new file mode 100644 index 0000000..b58554d --- /dev/null +++ b/vdn/allocators/default @@ -0,0 +1,276 @@ +#!/bin/bash + +set -u + +PUBLIC_PREFIX=20 # 20, 21, 22... + +MCAST_PREFIX_BASE="235" +MCAST_COMMON_ADDR="$MCAST_PREFIX_BASE.0.0.1" +MCAST_BASE_PORT=4000 + +set +u +[ -z "$USER" ] && export USER=$(id -un) +set -u + +error() { + echo ERROR : "allocator : $@ !" + exit 1 +} + +# Numéro de l'utilisteur sur la machine +# Utilisé par la redirection de port +computeLocalUser() { + + set +u + [ -z "$USER" ] && export USER=$(id -un) + set -u + + local u=$USER + #[ $# = 2 ] && u=$2 + + ps --no-headers --sort=start_time -eo user:14,lstart | gawk -v USER=$u -e ' + BEGIN { + n=0 + } + + /[^[:space:]]+ .*/ { + + user=$1 + #print $0 USER "===" user + + if(user == USER) { + print n%32 + exit 0 + } + + + if ( ! ( user in users ) ) { + #print "SET USER : user :" $0 + users[user]=n + n=n+1 + } + } + ' + +} + +# Calcule les paramètres d'un hôte +# $1 : hôte + +computeDb() { + local split host network user domain + + [ -d $VDN_PATH/allocators/db-$VDN_RESOURCES_ALLOCATOR ] && dir=$VDN_PATH/allocators/db-$VDN_RESOURCES_ALLOCATOR + [ -d /etc/vdn/allocators/db-$VDN_RESOURCES_ALLOCATOR ] && dir=/etc/vdn/allocators/db-$VDN_RESOURCES_ALLOCATOR + + ALLOCATOR_DIR=$dir + + [ -z "$dir" ] && error "Allocators dir not found!" + + split="${1//./ }" + + set - $split + + set +u + + host=$1 + network=$2 + user=$3 + domain=$4 + + + [ -z "$domain" ] && domain=vdn + [ $domain != vdn ] && error "computeDb : bad domain $domain" + + set +u + [ -z "$user" -a -n "$GUEST_OWNER" ] && user=$GUEST_OWNER + set -u + + [ -z "$user" ] && user=$USER + + + [ -z "$network" ] && { + [ -z "$NETWORK_DIR" ] && + error "computeDb : no network and NETWORK_DIR is empty !" + network=$(basename $NETWORK_DIR) + } + + [ -z "$host" ] && error "computeDb : host is empty !" + + #echo "computeDb : $VDN_NETWORKS_BASE_DIR/$network/$host.conf" >&2 + + ##[ ! -e $VDN_NETWORKS_BASE_DIR/$network/$host.conf ] && \ + ## error "computeDb : host $host not found in network $network!" + + grep -q $network:$host $dir/hosts || { + error "host $host not found in network $network" + } + + ### + + set +u + [ -z "$DB_CURRENT_USER" ] && DB_CURRENT_USER="" + set -u + + [ "$user" != "$DB_CURRENT_USER" ] && { + ! cat $dir/users | grep -q "^$user$" && + error "computeDb : user $user not found" + + export DB_CURRENT_USER_NUM=$(cat $dir/users | grep -n "^$user$" | cut -d ':' -f 1) + export DB_CURRENT_USER=$user + export DB_CURRENT_LOCAL_USER_NUM=$(computeLocalUser $user $host) + + } + + [ -z "$DB_CURRENT_LOCAL_USER_NUM" ] && $(computeLocalUser $user $host) + + set +u + [ -z "$DB_CURRENT_NETWORK" ] && DB_CURRENT_NETWORK="" + set -u + + + [ "$network" != "$DB_CURRENT_NETWORK" ] && { + #local netList=$(cd $VDN_NETWORKS_BASE_DIR; find . -maxdepth 1 -type d) + local netList=$(cat $dir/networks) + + export DB_CURRENT_NETWORKS_LIST="$netList" + + DB_CURRENT_NETWORK_NUM=$(echo "$DB_CURRENT_NETWORKS_LIST" | grep -n "^$network$" | cut -d ':' -f 1) + + [ -z "$DB_CURRENT_NETWORK_NUM" ] && + error "computeDb : DB_CURRENT_NETWORK_NUM empty (not in $VDN_NETWORKS_BASE_DIR ?)" + + #local hostsList=$(cd $VDN_NETWORKS_BASE_DIR/$network; find . -maxdepth 1 -type f -name '*.conf' ) + local hostsList=$(cat $dir/hosts | grep "^$network:" | cut -d ':' -f 2 ) + export DB_CURRENT_HOSTS_LIST="$hostsList" + DB_CURRENT_HOST_NUM=$(echo "$DB_CURRENT_HOSTS_LIST" | grep -n "^$host$" | cut -d ':' -f 1) + + [ -z "$DB_CURRENT_HOST_NUM" ] && { + error "computeDb : DB_CURRENT_HOST_NUM empty (not in $VDN_NETWORKS_BASE_DIR/$network/*.conf ?)" + } + DB_CURRENT_NETWORK=$network + DB_CURRENT_HOST=$host + } + + cat << EOF > /dev/null + echo " +host:$host +network:$network +user:$user + +hostNum:$DB_CURRENT_HOST_NUM +networkNum:$DB_CURRENT_NETWORK_NUM +userNum=$DB_CURRENT_USER_NUM +" +EOF +} + +# $1 : host +# $2 : proto (tcp/udp) +# $3 : port à redirigé +# en sortie : affichage d'un port libre +computeRedir() { + local base dst proto=$2 + + computeDb $1 + + base=$(( 5000+$DB_CURRENT_LOCAL_USER_NUM*1024 )) + dst=$(( $base + $DB_CURRENT_HOST_NUM*32+($3%16) )) + + dst=$(findUnusedPort $proto $dst) + echo $dst +} + +# Affiche l'IP PUBLIC de la machine +# L'hôte (ex : tiny.demo.user.vdn) + +computePublicIp() { + computeDb $1 + + grep -q "$DB_CURRENT_NETWORK:$DB_CURRENT_HOST" $ALLOCATOR_DIR/hosts.global || return + + #echo $NETWORKS | egrep -q 'NET_0|NET_G' || return + #echo "keys: $DB_CURRENT_USER $DB_CURRENT_NETWORK $DB_CURRENT_HOST" + #echo "keys: userNum networkNum hostNum : $DB_CURRENT_USER_NUM $DB_CURRENT_NETWORK_NUM $DB_CURRENT_HOST_NUM" + + # 20.X.Y.Z => 24 bits dispo + # Une adresse IP_PUBLIC par machine + # 13 bits de poids fort pour le numero de l'utilisateur (max 8192) + # 6 bits pour le numéro réseau (max 64 réseaux) + # 5 bits pour le numéro d'hôte (max 32 hôte par réseau) + # + # IP = -------- -------- --------- + # ^ ^^ ^^ ^ + # +------------++------++---+ + # user net host + + local ip=$(( $DB_CURRENT_USER_NUM * 2**11 + $DB_CURRENT_NETWORK_NUM * 2**5 + $DB_CURRENT_HOST_NUM)) + + + ip1=$(( $ip/2**24 )) + ip2=$(( ($ip-$ip1*2**24) / 2**16 )) + ip3=$(( ($ip- $ip1*2**24 - $ip2*2**16) / 2**8 )) + ip4=$(( $ip % 256 )) + + echo "$(($PUBLIC_PREFIX+$2)).$ip2.$ip3.$ip4" + +} + +# $1 : +# $2 : le numéro du lien souhaihé +computeMacAddr() { + + computeDb $1 + + # xx:xx:xx:xx:xx:xx + # 52 ----- -- -- -- + # ^ -interface (8 bits, max 256 interface par hôte) + # ^- host (8 bits, max 256 hôtes par réseau) + # ^network (8 bits, max 256 réseaux) + # ^user (16 bits, max 65536 utilisateurs) + + local uHigh=$(($DB_CURRENT_USER_NUM /256)) + local uLow=$(($DB_CURRENT_USER_NUM %256)) + + printf "52:%02X:%02X:%02X:%02X:%02X\n" $uHigh $uLow $DB_CURRENT_NETWORK_NUM $DB_CURRENT_HOST_NUM $2 +} + +# Affiche l'adresse IPv4 multicast du brin ethernet n°$1 +# $1 : l'hôte +# $2 : le numéro du lien souhaité + +computeEthLink() { + computeDb $1 + + echo "=== computeEthLink:$2" >&2 + echo "DB_CURRENT_USER_NUM:$DB_CURRENT_USER_NUM" >&2 + echo "DB_CURRENT_NETWORK_NUM:$DB_CURRENT_NETWORK_NUM" >&2 + #echo "DB_CURRENT_HOST_NUM:$DB_CURRENT_HOST_NUM" >&2 + + # idem que pour l'IP publique sauf : + # - préfixe de l'adresse mcast IPv4 + # - le numéro de brin remplace le numéro d'hôte. + # (5bits = 32 brins max par réseau) + # 230.X.Y.Z + + # 13 bits de poids fort pour le numero de l'utilisateur (max 8192) + # 6 bits pour le numéro réseau (max 64 réseaux) + # 5 bits pour le numéro de brins (max 32 hôte par réseau) + # + # IP = -------- -------- --------- + # ^ ^^ ^^ ^ + # +------------++----++---+ + # user net link + + + local ip=$(( $DB_CURRENT_USER_NUM * 2**11 + $DB_CURRENT_NETWORK_NUM * 2**5)) + + ip1=$(( $ip/2**24 )) + ip2=$(( ($ip-$ip1*2**24) / 2**16 )) + ip3=$(( ($ip- $ip1*2**24 - $ip2*2**16) / 2**8 )) + ip4=$(( $ip % 256 )) + echo "==> $MCAST_PREFIX_BASE.$ip2.$ip3.$ip4:$MCAST_BASE_PORT" >&2 + echo "$MCAST_PREFIX_BASE.$ip2.$ip3.$ip4:$MCAST_BASE_PORT" +} + + diff --git a/vdn/allocators/resolv b/vdn/allocators/resolv new file mode 100755 index 0000000..8cb0f62 --- /dev/null +++ b/vdn/allocators/resolv @@ -0,0 +1,13 @@ +#!/bin/bash + +[ -z "$2" ] && n=0 || n=$2 + +if [ -e /etc/vdn/config ]; then + . /etc/vdn/config + . /etc/vdn/allocators/$VDN_RESOURCES_ALLOCATOR + computePublicIp $1 $n +else + vdn-query PUBLIC_IP $n $1 +fi + + diff --git a/vdn/authorized-root.txt b/vdn/authorized-root.txt new file mode 100644 index 0000000..3f73c00 --- /dev/null +++ b/vdn/authorized-root.txt @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCYtj+/9jtKUkVrcYBwmanz3WpgPON5nl7+3uj8g7bV2Wz8xavHJSqLpC1tLdAdKjcou5tKL23vDPRaYjFcOAt1A2JJQnoMk56AboeEAnJabGKH/2rhWRYifePVe9LJqzj8h/haF5/JETwJsNRGvmAXYKPW+2srkpP6UyacjoAzwsYHuPtc1hrmJ0vfrc1HDcRrypNZmrzmtSqD08iKmnaSZiQ54P+5bEzJbV03rDF5YG5xYsKYBy0WavZjA05Ouy6OGMUCBKZ6LjMKhtFiYmrdS3TQn9V9rwtr9OLTQU3ZWwWd0VQ9ORnkChVo20mfznfTpTVbccVuGtEsXlUgjwql gudavala diff --git a/vdn/bin/bbfs b/vdn/bin/bbfs new file mode 100755 index 0000000000000000000000000000000000000000..6476ef317d6d7ea68c3486193607142a1b1c7b5b GIT binary patch literal 64320 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 W;V%eOhE4yh4-owcXbwi>G5`P|qXrBB literal 0 HcmV?d00001 diff --git a/vdn/bin/ext4fuse b/vdn/bin/ext4fuse new file mode 100755 index 0000000000000000000000000000000000000000..fd3ce20519b3084feae1ceb15deda8c516bf6d9a GIT binary patch literal 196296 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 VDe%5I0}qg>p+1huLLV(8->__WCfiDW{7i@a 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' -f 2- | cut -d ' ' -f 2 +} + +injectFileAndLink() { + local b=$(basename $1) + local d=$(dirname $1) + local l + + #echo "--> $1" + + [ ! -d $DST/$d ] && mkdir -p $DST/$d + [ ! -e $DST/$1 ] && { + #echo "cp $1 $DST/$1" + cp -a $1 $DST/$1 + } + + + if [ -L $1 ]; then + l=$(link $1) + + # Absolute link + if ! echo $l | grep -q '^/'; then + l=$d/$l + fi + + injectFileAndLink $l + fi +} + +injectDepends() { + + local b d l ld + + #echo "deps : $1" + + ! file $1 | grep -q 'dynamically linked' && return + + # Dynmamic linker + + l=$(ldd $1 | grep -v '=>' | grep ld-linux | sed -re 's/^[[:space:]]*//' | cut -d ' ' -f 1) + + #echo " $l" + + injectFileAndLink $l + + # Libraries + + for l in $(ldd $1 | grep '=>' | cut -d '>' -f 2 | cut -d ' ' -f 2); do + #echo " -> $l" + injectFileAndLink $l + done +} + +injectCommandWithDepends() { + local f=$1 + + if ! echo $1 | grep -q '/'; then + f=$(whereis -b -B $SEARCH_DIRS -f $1 | cut -d ' ' -f 2) + fi + + #echo "*** $f" + + [ -z "$f" ] && error "Command $f not found in $SEARCH_DIRS !" + + injectFileAndLink $f + injectDepends $f + + if [ -L $f ]; then + f=$(link $f) + injectCommandWithDepends $f + fi +} + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + + + +debootstrap() { + + #if [ -e $VDN_PATH/files/$HDA ]; then + # echo "Warning : $VDN_PATH/files/$HDA exist. Skip debootstrap !" + # return + #fi + + ID=$(echo $GUEST_SYS|cut -d '/' -f 1) + VERSION_CODENAME=$(echo $GUEST_SYS|cut -d '/' -f 2) + + TMP_DIR=/tmp/bootstrap-$VERSION_CODENAME-$USER + + KVERS=$(uname -r) + [ -n "$KVERS" ] || { error "KVERS is empty !?! "; } + + LOCAL_KERNEL=$(ls /boot/vmlinuz*$KVERS | head -n 1) + + [ -n "$LOCAL_KERNEL" ] || { error "No kernel found in /boot for $KVERS"; } + + LOCAL_INITRD=$(ls /boot/initrd*$KVERS | head -n 1) + + [ -n "$LOCAL_INITRD" ] || { error "No initrd found in /boot for $KVERS"; } + + FORMAT=$(file $LOCAL_INITRD) + case "$FORMAT" in + *gzip*) FORMAT=gzip;; + *cpio*) FORMAT=asciiCpio;; + *Zstandard*) FORMAT=zStandard;; + *) echo "Unknown initrd format ($FORMAT)" >&2 + exit 1 + esac + + if [ $FORMAT = zStandard ]; then + [ -z "$(which zstdcat)" ] && error "zstdcat not found ! Need zstd package !" + [ -z "$(which zstd)" ] && error "zstd not found ! Need zstd package !" + fi + + [ ! -d $TMP_DIR/initrd ] && mkdir -p $TMP_DIR/initrd + + export DST=$TMP_DIR/initrd + + ( + set -eu + + cd $TMP_DIR + + if [ ! -e $TMP_DIR/initrd/init ]; then + echo "Extract $LOCAL_INITRD..." + case $FORMAT in + asciiCpio|gzip) ( cd initrd && zcat $LOCAL_INITRD | cpio -idm > /dev/null);; + zStandard) ( cd initrd && zstdcat $LOCAL_INITRD | cpio -idm > /dev/null ) + esac + fi + + [ -e $TMP_DIR/initrd/init.bak ] || cp $TMP_DIR/initrd/init $TMP_DIR/initrd/init.bak + + + #rm -f $DST/bin/busybox $DST/usr/bin/busybox + + echo "Inject packages..." + + #apt-get download haveged + #dpkg -x haveged*.deb initrd + + #apt-get download libhavege2 + #dpkg -x libhavege2*.deb initrd + + apt-get download busybox + dpkg -x busybox_*.deb initrd + + apt-get download debootstrap + dpkg -x debootstrap*.deb initrd + + apt-get download file + dpkg -x file*.deb initrd + + apt-get download libmagic-mgc + dpkg -x libmagic-mgc*.deb initrd + + #apt-get download haveged + #dpkg -x haveged*.deb initrd + + + echo "Inject files and program with depends..." + + [ ! -d $DST/bin ] && mkdir $DST/bin + + injectCommandWithDepends /bin/bash + injectCommandWithDepends /sbin/modprobe + injectCommandWithDepends /sbin/fdisk + injectCommandWithDepends /sbin/mke2fs + injectCommandWithDepends /usr/bin/gpgv + injectCommandWithDepends /usr/bin/perl + + #injectCommandWithDepends /usr/bin/file + #injectCommandWithDepends /usr/bin/ldd + #injectCommandWithDepends /usr/bin/strace + #injectCommandWithDepends /usr/bin/script + + injectFileAndLink /lib/x86_64-linux-gnu/libresolv.so.2 + injectFileAndLink /lib/x86_64-linux-gnu/libnss_files.so.2 + injectFileAndLink /lib/x86_64-linux-gnu/libnss_dns.so.2 + #injectFileAndLink /usr/lib/x86_64-linux-gnu/libidn2.so + + cp /sbin/mke2fs $DST/bin/mke2fs + #injectCommandWithDepends /bin/grep + #mv $DST/usr/bin/grep $DST/bin/grep + + #injectCommandWithDepends /usr/bin/perl + #injectCommandWithDepends /usr/bin/wget + #cp /usr/bin/wget $DST/bin + + mkdir -p $DST/usr/share/keyrings + cp /usr/share/keyrings/debian-archive-keyring.gpg $DST/usr/share/keyrings + + cp /etc/resolv.conf $DST/etc/resolv.conf + ) + + echo "Inject scripts..." + + cp $VDN_PATH/scripts/on-boot $TMP_DIR/initrd + + set +u + + cat << EOF > $TMP_DIR/initrd/init +#!/bin/bash + +#set -a +#. /config +#set +a + +[ -d /dev ] || mkdir -m 0755 /dev +[ -d /proc ] || mkdir /proc +[ -d /sys ] || mkdir /sys + +mkdir -p /var/lock +mount -t sysfs -o nodev,noexec,nosuid sysfs /sys +mount -t proc -o nodev,noexec,nosuid proc /proc + +mkdir /dev/pts +mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts + +modprobe virtio_pci +modprobe virtio_blk +modprobe ext4 +modprobe crc32c + +modprobe virtio-net + +mdev -s + +rm -f /dev/null; mknod -m 666 /dev/null c 1 3 + +if ! fdisk -l /dev/vda | grep -q /dev/vda1; then + echo -e "n\np\n1\n\n\nw\n" | fdisk /dev/vda + mdev -s + /bin/mke2fs -j -t ext4 /dev/vda1 +fi + +rm -f /dev/null; mknod -m 666 /dev/null c 1 3 + +mkdir -p /tmp/d +mount /dev/vda1 /tmp/d || { + echo "Can't mount partition !" >&2 + echo "Repair + exit to continue or poweroff -f to halt !" + /bin/busybox ash +} + +ifconfig eth0 10.0.2.15 +route add default gw 10.0.2.2 + +ln -sf /bin/bash /bin/sh + +[ -n "$http_proxy" ] && export http_proxy="$http_proxy" +[ -n "$https_proxy" ] && export https_proxy="$https_proxy" + +#echo "Before debootstrap. exit to continue." +#/bin/sh -i + +if [ ! -d /tmp/d/bin ]; then + echo "Debootstrap $VERSION_CODENAME ..." + debootstrap --arch=amd64 $VERSION_CODENAME /tmp/d +fi + +mount -o bind /dev /tmp/d/dev +mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /tmp/d/dev/pts +mount -o bind /proc /tmp/d/proc +mount -o bind /sys /tmp/d/sys + +#cp /config /tmp/d/root/config +cp /base.sh /tmp/d/root/base.sh + +[ ! -d /tmp/d/etc/vdn ] && mkdir -p /tmp/d/etc/vdn +cp /on-boot /tmp/d/etc/vdn +chmod 755 /tmp/d/etc/vdn/on-boot + +#echo "Before chroot, exit to quit" +#/bin/busybox ash + +chroot /tmp/d /root/base.sh + +#echo "In chroot exit to quit" +#chroot /tmp/d /bin/bash + +#/bin/busybox ash + +poweroff -f + +EOF + + chmod 755 $TMP_DIR/initrd/init + + cat << EOF > $DST/base.sh + +#set -a +#. /root/config +#set +a + +export DEBIAN_FRONTEND=noninteractive + +[ -n "$http_proxy" ] && export http_proxy="$http_proxy" +[ -n "$https_proxy" ] && export https_proxy="$https_proxy" + +apt-get -y update +apt-get -y upgrade + +apt-get -y install linux-image-amd64 grub2 + +# Inject initramfs config scripts + +[ ! -d /etc/initramfs-tools ] && mkdir -p /etc/initramfs-tools + +echo "overlay" >> /etc/initramfs-tools/modules +sed -i -re 's/^MODULES=.*$/MODULES=dep/' /etc/initramfs-tools/initramfs.conf + +update-initramfs -u +update-grub + +rm -f /etc/initramfs-tools/scripts/init-premount/vdn +cat << END > /etc/initramfs-tools/scripts/local-bottom/vdn +#!/bin/sh + +PREREQ="lvm" +prereqs() +{ + echo "\\\$PREREQ" +} + +case \\\$1 in + prereqs) + prereqs + exit 0 + ;; +esac + +. /scripts/functions +# Begin real processing below this line + +echo "ECHO : Starting vdn pre-mount, exit to quit !" >&2 +log_begin_msg "Starting vdn pre-mount, exit to quit !" + +# Extract tgz + +lastDisk=\\\$(ls /dev/vd*| grep '/...$' | tail -n 1) + +if [ -n "\\\$lastDisk" ]; then + if tar -C / -xzf \\\$lastDisk; then + set -a + . /etc/vdn/config + set +a + else + echo >&2 + echo "WARNING : no vdn config partition found !" >&2 + sleep 3 + exit 1 + fi +else + echo 'Not a VDN VM (/dev/vd? !)' >&2 + sleep 3 + exit 1 +fi + +#echo "/etc/initramfs-tools/scripts/local-bottom/vdn : before . /etc/vdn/on-initramfs" >&2 +#/bin/busybox ash + +chown root:root / +chmod 755 / + +. /etc/vdn/on-initramfs + +log_end_msg + +END + +chmod 755 /etc/initramfs-tools/scripts/local-bottom/vdn + +#echo "base.sh : after install kernel" +#/bin/bash -i + +[ -n "$http_proxy" ] && export http_proxy="$http_proxy" +[ -n "$https_proxy" ] && export https_proxy="$https_proxy" + +apt-get -y update +apt-get -y upgrade + +apt-get -y install ssh locales mingetty file + +#grub-install /dev/vda +#update-grub + +echo "root:$(getRandomPasswd)" | chpasswd + +[ ! -e /home/test ] && adduser --disabled-password --gecos '' test +echo "test:$(getRandomPasswd)" | chpasswd + +apt-get -y install ssh # task-ssh-server +#apt-get -y install task-xfce-desktop + +cat << END > /etc/fstab +# +# Use 'blkid' to print the universally unique identifier for a +# device; this may be used with UUID= as a more robust way to name devices +# that works even if disks are added and removed. See fstab(5). +# +# +# / was on /dev/vda1 during installation +/dev/vda1 / ext4 errors=remount-ro 0 1 +END + +[ ! -d /etc/vdn ] && mkdir /etc/vdn + +if [ ! -e /etc/rc.local ]; then + cat << END > /etc/rc.local +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. + +END +fi + +if ! grep -q /etc/vdn/on-boot /etc/rc.local; then + cat << END >> /etc/rc.local +sh /etc/vdn/on-boot +END +fi + +chmod 755 /etc/rc.local + +echo "Allow root autologin on ttyS0" +sed -i -re 's,^ExecStart=.*$,ExecStart=-/sbin/mingetty --noclear --autologin root %I,' /lib/systemd/system/serial-getty@.service + +echo "Allow net.ifnames=0 in GRUB + console" +sed -i -re 's,^GRUB_CMDLINE_LINUX_DEFAULT=.*$,GRUB_CMDLINE_LINUX_DEFAULT=\"net.ifnames=0 console=ttyS0\,115200n8 noresume blacklist=floppy\",' /etc/default/grub +echo "Set 1s timout for Grub menu" +sed -i -re 's,^GRUB_TIMEOUT=.*$,GRUB_TIMEOUT=0,' /etc/default/grub +update-grub + +echo "Allow ssh root connection" +if grep -q '^#?PermitRootLogin ' /etc/ssh/sshd_config; then + sed -i -re 's/^#?PermitRootLogin/PermitRootLogin prohibit-password' /etc/ssh/sshd_config +else + echo 'PermitRootLogin prohibit-password' >> /etc/ssh/sshd_config +fi + +#apt-get install -y --reinstall linux-image-amd64 +update-initramfs -u +grub-install /dev/vda +#update-grub + +#echo "End of base.sh, exit to quit" +#/bin/bash -i + +EOF + + chmod 755 $DST/base.sh + + [ ! -e $VDN_PATH/files/$HDA ] && { + echo "Create sparse disk $VDN_PATH/files/$HDA ($HDA_SIZE M)..." + dd of=$VDN_PATH/files/$HDA count=0 bs=1M seek=$HDA_SIZE + } + + # Build $TMP_DIR/initrd.img + + #if [ ! -e $TMP_DIR/initrd.img ]; then + echo "Create $TMP_DIR/initrd.img..." + case $FORMAT in + asciiCpio|gzip) ( cd $TMP_DIR/initrd && find . | cpio -o -H newc -R root:root | gzip -9 > $TMP_DIR/initrd.img);; + zStandard) ( cd $TMP_DIR/initrd && find . | cpio -o -H newc -R root:root | zstd -9 > $TMP_DIR/initrd.img );; + esac + #fi + + #echo "Press return to continue !" + #read + + echo "Boot and debootstrap..." + + qemu-system-x86_64 -kernel $LOCAL_KERNEL -smp 8 -enable-kvm -cpu host -device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -rtc base=localtime -m 3072M -nographic -serial mon:stdio -monitor null -initrd $TMP_DIR/initrd.img -append "root=/dev/vda boot=live ro console=ttyS0,115200n8 net.ifnames=0 noresume" -boot order=c -drive file=$VDN_PATH/files/$HDA,if=virtio,format=raw -device virtio-net-pci,netdev=n0,mac=52:56:0A:E8:00:02 -netdev user,id=n0 + +} + +# $1 : system name started +cleanHistory() { + echo "Clear /var/log, history, ..." + vdn-ssh -t root@$1 ' + + #rm -Rf /etc/vdn + set -a + . /etc/vdn/config + set +a + + rm -f /etc/vdn-$MODE-initialized + + #for i in $(find /var/log -type f); do cat /dev/null > $i; done + find /var/log -name "*.gz" -delete + + echo "Clear .bash_history" + + rm -f /root/.bash_history + touch /root/.bash_history + chmod 600 /root/.bash_history + rm -f /home/test/.bash_history + touch /home/test/.bash_history + chmod 600 /home/test/.bash_history + + echo "Clear .cache .mozilla" + for d in /root /home/test; do + rm -Rf $d/.cache + rm -Rf $d/.mozilla + done + + echo "$$$ Clear apt-cache..." + apt autoremove -y + sleep 1 + apt-get clean + + + echo "Clear authorized_keys (only user test)" + + for d in /root /home/test; do + rm -f $d/.ssh/authorized_keys + rm -Rf $d/.mozilla + done + + echo end of cleaning ! + + echo "poweroff (in 3 s) !" + poweroff -f + +' +} + + diff --git a/vdn/bin/functions-scripts.sh b/vdn/bin/functions-scripts.sh new file mode 100644 index 0000000..159c00a --- /dev/null +++ b/vdn/bin/functions-scripts.sh @@ -0,0 +1,635 @@ +#!/usr/bin/env bash + +set +u +[ -z "$USER" ] && USER=$(id -un) +set -u + +GUEST_OWNER=$USER + + +# Ces fonctions peuvent êtres utilisées par les scripts de configuration et +# de test d'un réseau. + +error() { + echo -e "\033[0;31;1mError in $SCRIPT !\033[0m" >&2 + echo + if [ $READ -eq 1 ]; then + echo + echo "touche \"Entrée\" pour terminer." + read + fi + + exit 1 + +} + +diagOld() { + printf "%-70s" "$@" +} + +green() { + local n="" + [ "$1" = "-n" ] && { n="-n"; shift; } + echo $n -e "\033[0;32;1m$@\033[0m" +} + +red() { + local n="" + [ "$1" = "-n" ] && { n="-n"; shift; } + echo $n -e "\033[0;31;1m$@\033[0m" +} + +diagResult() { + [ "$1" = 0 ] && green " ok" || red " ko" + echo +} + +diagResultWithMessage() { + echo + echo -en "$1 ... " + [ "$2" = 0 ] && green " ok" || red " ko" + echo +} + + +diag() { + local r + local term="-t" + + #if [ "$1" = "-t" ]; then + # term="-t" + # shift + #fi + + if [ "$1" = "-n" ]; then + term="" + shift + fi + echo -e "$2" + echo -ne " Please wait...\r" + + set +e + vdn-ssh $term $1 "$3 &> /dev/null" + r=$? + set -e + echo -ne " \r" + #diagResult $r + return $r +} + + +vdnTest() { + local error=0 + local message="$1" + local cmd="$2" + + b=$(echo "$1" | base64 | tr '/' '-') + + echo -n "$1 ... " + eval $cmd &> /dev/null + error=$? + #echo -n "" + + [ $error = 0 ] && green ok || red ko + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + [ ! -d $VDN_TESTS_DIR ] && mkdir -p $VDN_TESTS_DIR + echo "$1" > $VDN_TESTS_DIR/$b + echo $error >> $VDN_TESTS_DIR/$b + + #errors=$(($errors+$error)) + + return $error +} + + +warning() { + echo -e "\033[1;33;1mWarning in $SCRIPT !\033[0m" >&2 +} + +request() { + echo + echo -e "$@" + echo + echo -n "Confirmez (O/n) : " + read + if [ -z "$REPLY" -o "$REPLY" = "o" -o "$REPLY" = "O" ]; then + return 0 + fi + return 1 +} + + +setDebugMode() { + [ $VDN_DEBUG = 1 ] && set -x || : +} + + +setErrorHandler() { + setDebugMode + set +u + [ -z "$SCRIPT" ] && SCRIPT=$(basename "$1") || : + set -u + trap "error" 0 +} + +echoStart() { + echo + echo "Start : $SCRIPT" + #START_DATE=$(date +%s) +} + +echoDone() { + #echo -e "\033[0;32;1m$SCRIPT : done.\033[0m" + echo + echo -ne "\033[0;34;1mdone\033[0m (time : " + gawk 'BEGIN {print strftime("%M:%S)",'$(date +%s)-$START_DATE')}' + +} + +echoDoneWithTestErrors() { + #echo -e "\033[0;32;1m$SCRIPT : done.\033[0m" + errors=${errors:-0} + echo + [ "$errors" = 0 ] && green -n ok || red -n ko + echo -en " (time : " + gawk 'BEGIN {print strftime("%M:%S)",'$(date +%s)-$START_DATE')}' +} + + +unsetErrorHandler() { + trap - 0 +} + +startGuests() { + local i + local n=0 + for i in $@; do + echo -n "Alive $i ? : " + if ! $VDN_PATH/bin/vdn-alive $i ; then + echo "No : Start $i..." + set +u + #set -x + if [ "$WITH_GUI" = 1 -o "$VDN_GUI" = 1 ]; then + vdn-start -g $i + elif [ $IN_BG = 1 ]; then + vdn-start -b $i + else + vdn-start $i + fi + #set +x + n=$((n+1)) + set -u + else + echo "Yes" + fi + done + return $n +} + +waitSsh() { + for i in $@; do + echo "Waiting ssh on $i..." + local n=0 + #set -x + until $VDN_PATH/bin/vdn-ssh root@$i : &> /dev/null; do + if [ $n = 1 ]; then + echo "Waiting ssh on $i..." >&2 + n=$(n+1) + fi + sleep 2 + done + done +} + +requireGuests() { + set +e + startGuests $@ + + #echo "All guests started !" + [ $? -ne 0 ] && sleep 1 + set -e + return 0 +} + +startAndWaitSsh() { + #echo "startAndWaitSsh :$DISABLE_SCAN" + DISABLE_SCAN=${DISABLE_SCAN:-0} + if [ "$DISABLE_SCAN" != 1 ]; then + requireGuests $@ + sleep 1 + waitSsh $@ + fi +} + +requireSshGuests() { # DEPRECATED + startAndWaitSsh $@ +} + +setHostname() { + echo "setHostname $1" + vdn-ssh root@$1 " + echo $1 > /etc/hostname + hostname -F /etc/hostname + " +} + + +setFile() { + #echo "setFile $1 $2 (functions-script.sh)" + #set -x + vdn-ssh root@$1 "cat > $2" + #set +x +} + +setHosts() { + echo "setHosts $1" + setFile $1 /etc/hosts +} + +setInterfaces() { + echo "setInterfaces $1" + setFile $1 /etc/network/interfaces + #vdn-ssh root@$1 "ip route | grep -q default && ip route del default || : ; service networking restart" + #cat /etc/network/interfaces + #ip addr + #ip route + vdn-ssh root@$1 "service networking restart" + #sleep 1 +} + +setForwarding() { + echo "setForwarding $1" + # cat /proc/sys/net/ipv4/ip_forward + vdn-ssh root@$1 " + sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf + sysctl -p | grep net.ipv4.ip_forward + " +} + +setIpv6WorkAround() { + vdn-ssh root@$1 " + echo setIpv6WorkAround $1 + if ! grep -q \"^net.ipv6.conf.all.accept_dad = 0\" /etc/sysctl.conf; then + cat << EOF >> /etc/sysctl.conf +#broken for uml/kvm/qemu, mcast hears itself +net.ipv6.conf.all.accept_dad = 0 +net.ipv6.conf.all.dad_transmits = 0 +net.ipv6.conf.default.accept_dad = 0 +net.ipv6.conf.default.dad_transmits = 0 +# and since the interfacs are there before sysctl is run, and the +# all target is an utter linux failure, we have to set it per interface +net.ipv6.conf.lo.accept_dad = 0 +net.ipv6.conf.eth0.accept_dad = 0 +net.ipv6.conf.eth1.accept_dad = 0 +net.ipv6.conf.eth2.accept_dad = 0 +net.ipv6.conf.lo.dad_transmits = 0 +net.ipv6.conf.eth0.dad_transmits = 0 +net.ipv6.conf.eth1.dad_transmits = 0 +net.ipv6.conf.eth2.dad_transmits = 0 +EOF + sysctl -p &> /dev/null + service networking restart + fi +" +} + +pauseRaw() { + echo + echo "*** touche \"Entrée\" pour terminer." + read +} + + +pause() { + set +u + VDN_GUI=${VDN_GUI:-0} + set +u + #echo "PAUSE:$PAUSE RUN_PARALLEL:$RUN_PARALLEL IN_PARALLEL=$IN_PARALLEL VDN_GUI=$VDN_GUI VDN_SCRIPTS_LEVEL=$VDN_SCRIPTS_LEVEL" + #echo "read..." + #read + #set -x + #echo "$PAUSE = 1 -a $IN_PARALLEL = 0 -a \( $VDN_GUI = 1 -a $VDN_SCRIPTS_LEVEL = 1" + if [ $PAUSE = 1 -a $IN_PARALLEL = 0 -a \( $VDN_GUI = 1 -a $VDN_SCRIPTS_LEVEL = 1 \) ]; then + if [ "$NO_INTERACTIVE" != 1 ]; then + echo + echo "*** touche \"Entrée\" pour terminer." + read + fi + else + #echo VDN_SCRIPTS_LEVEL:$VDN_SCRIPTS_LEVEL + if [ $READ = 1 -a $VDN_SCRIPTS_LEVEL -gt 2 ]; then + #echo "reading" + #echo "VDN_SCRIPTS_LEVEL:$VDN_SCRIPTS_LEVEL" + #echo "sleep infinit disable" + sleep infinity + #while :; do + # read + #done + fi + fi + + #set +x +} + +#parallelDisablePause() { + #[ $RUN_PARALLEL = 1 ] && PAUSE=0 || : +#} + +canRunParallel() { + local r + set +u + [ $RUN_PARALLEL = 1 -a "$DISABLE_PARALLEL" != 1 -a $(echo $@ | wc -w) -gt 1 ] && r=0 || r=1 + #[ $RUN_PARALLEL = 1 -a "$DISABLE_PARALLEL" != 1 ] && r=0 || r=1 + set -u + return $r +} + + + +runParallel() { + local tmp name + + #[ $RUN_PARALLEL = 1 ] && PAUSE=0 || : + + export RUN_PARALLEL + #export IN_PARALLEL=1 + + #export IN_PARALLEL=1 + #export PAUSE=0 + + [ ! -d $HOME/.tmuxinator ] && (umask 077 && mkdir $HOME/.tmuxinator ) + + tmp=$(mktemp -p $HOME/.tmuxinator vdn-tmuxinator-XXXXXX) + name=$(basename $tmp) + + #echo "runParallel: PAUSE:$PAUSE" + + #sleep 3 + + #if [ $VDN_DEBUG = 1 ]; then + #tmuxinator new $name + #else + # + #tmuxinator new $name &> /dev/null + #fi + + + #echo "NAME is $name" + #echo "WRITE to $tmp.yml" + +cat << EOF > $tmp.sh +#!/bin/bash + +quit() { + tmuxinator stop $name; +} + +trap quit 0 + +tput reset +echo -e '\n\n\n QUIT : Return / CTRL C' +read +EOF + + cat << EOF > $tmp.conf +set -g mouse on +set -g status-bg white +set -g status-fg blue +set -g status-left '#[fg=blue](#S) #(whoami)@#H#[default]' +set -g pane-active-border-fg blue +EOF + + + cat << EOF > $tmp.yml + +name: $name +root: $PWD +tmux_options: -f $tmp.conf + +windows: + - terminal: + layout: tiled + panes: + - clear; bash "$tmp.sh" +EOF + + chmod 700 $tmp.yml + + local i n payload + n=$(($#+1)) + #n=$(($#)) + payload=0 + if [ $(($n % 3)) != 0 ]; then + payload=$(( (($n/3)+1)*3 - $n )) + fi + + [ $n = 2 -o $n = 4 ] && payload=0 || : + [ $n = 3 ] && payload=1 || : + + #echo "#:$# @:$@" + #echo "N: $n" + #echo "PAYLOAD: $payload" + #sleep 10 + #set -x + for i in $@; do + echo " - cd; export NETWORK_DIR=$NETWORK_DIR; export VDN_GUI=1; export READ=$READ; export PAUSE=$PAUSE; export FORCE_SEQUENTIAL=$FORCE_SEQUENTIAL; clear; $VDN_PATH/bin/vdn-scripts $i" >> $tmp.yml + done + + for i in $(seq 1 $payload); do + echo " - cd; clear; echo -e \"\n\"' Not used !'; sleep infinity" >> $tmp.yml + done + #set +x + #sleep 10 + + #echo "Press Return" + #read + + if [ $VDN_DEBUG = 1 ]; then + tmuxinator start $name + else + tmuxinator start $name &> /dev/null + fi + + # dump + + local pane + + #for pane in $(tmux list-pane | sed -re 's/^.*(%[0-9]+).*$/\1/'); do + # echo "----------------------------" + # tmux capture-pane -S -100 -p -t $pane + #done + + rm $tmp $tmp.yml $tmp.sh $tmp.conf + + #[ $VDN_DEBUG = 0 ] && clear + #echo "leave: parallel" +} + +fn_exists() { + local r + #set -x + set | grep -q "$1 ()" + r=$? + #set +x + return $r +} + +prepareRun() { + + #echo "### prepareRun : " + + #setErrorHandler + #set | grep test + #echo "SCRIPT:$SCRIPT." + #echo "ARGS:$ARGS." + + + if [ -n "$ARGS" ]; then + fn_exists $ARGS + else + fn_exists $SCRIPT + fi + local fn=$? + + #echo "FN:$fn (0 is true)" + + + if [ $fn = 0 ]; then + if [ -n "$ARGS" ]; then + $ARGS + else + $SCRIPT $@ + fi + exit + fi + + #read + + # Not a function + + # is a script ? + if [ -r $SCRIPT ]; then + #echo "$SCRIPT is a script !" + #echo "ARGS:$ARGS" + if [ -n "$ARGS" ]; then + SCRIPT=$ARGS + $SCRIPT + exit + fi + + return 0 + + fi + + echo "$SCRIPT not a script !" + + #read + + #if [ -n "$ARGS" ]; then + # SCRIPT=$1 + # shift + # $SCRIPT $@ + # exit + #fi + + exit +} + +vdnExec() { + local L="" + + for i in $@; do + set | egrep -q "^$i \(\)" + + fn=$? + #echo "$i => $fn" + + [ $fn = 0 ] && i="$SCRIPT:$i" + L="$L $i" + done + + vdn-scripts $L +} + +vdnExecWithErrors() { + export SHOW_ERRORS=1 + vdnExec $@ + +} + + + +runSequential() { + local i + local r + local lerrors=0 + + #export IN_PARALLEL=0 + + #echo "runSeq: $@ PAUSE:$PAUSE" + + errors=${errors:-0} + + for i in $@; do + #echo + #echo -e "Run : $i [$(echo $i | tr ':' ' ')]" + #echo + SCRIPT=$i + #echo "SCRIPT1:$SCRIPT" + SCRIPT=$(echo $i | tr ':' ' ' | sed -re 's/^ *//' | cut -d ' ' -f 1) + ARGS=$(echo $i | tr ':' ' ' | sed -re 's/^ *//' | gawk ' { print $2 $3 $4 $5 $6 $7 }') + + #. $VDN_PATH/bin/functions-scripts.sh + + #echo "SCRIPT2:$SCRIPT" + + . $SCRIPT + + + START_DATE=$(date +%s) + + set -e + + PAUSE=1 + + + #echo "runSeq : $SCRIPT args : $ARGS" + if [ -z "$ARGS" ]; then + run + r=$? + else + $ARGS + r=$? + #echoDone + fi + + set +u + + #echo "R:$r" + if [ $r = 0 ]; then + success=$((success+1)) + else + errors=$((errors+1)) + lerrors=$((lerrors+1)) + + #echo "ERRORS ! : $errors" + #echo "LERRORS ! : $lerrors" + fi + set -u + + done + + if [ $VDN_SCRIPTS_LEVEL = 1 ]; then + if [ $errors != 0 ]; then + red "Error(s) detected !" + fi + fi + + return $errors +} + + +[ "$VDN_DEBUG" = 1 ] && set -x || : + + diff --git a/vdn/bin/functions.sh b/vdn/bin/functions.sh new file mode 100644 index 0000000..e1bfacc --- /dev/null +++ b/vdn/bin/functions.sh @@ -0,0 +1,568 @@ +#!/usr/bin/env bash + +# FOR DEBUG : tmux kill-session -t name + +# Options prédéfinies pour ssh lors d'un vdn-ssh. + +set +u +[ -z "$USER" ] && export USER=$(id -un) +set -u + +set -a +VDN_RESOURCES_ALLOCATOR=${VDN_RESOURCES_ALLOCATOR:-default} +DB_CURRENT_HOST=${DB_CURRENT_USER:-$USER} +DB_CURRENT_HOST=${DB_CURRENT_NETWORK:-} +DB_CURRENT_HOST=${DB_CURRENT_HOST:-} +set +a + +#SSH_OPTS="-o NoHostAuthenticationForLocalhost=yes -c aes128-ctr" +SSH_OPTS="-o NoHostAuthenticationForLocalhost=yes" + +# Options prédéfinies pour scp lors d'un vdn-scp. + +SCP_OPTS="-o NoHostAuthenticationForLocalhost=yes -c aes128-ctr" + +# Utilise le mode master de ssh pour la connexion avec les systèmes virtuels. + +SSH_GUEST_MASTER=1 + +#set +u +#[ -z "$PAUSE" ] && export PAUSE=1 || : +#set -u + + +warning() { + echo -e "\n`basename $0` : warning : $@ !" >&2 +} + +error() { + echo -e "`basename $0` : error : $@ !" >&2 + READ_ON_ERROR=${READ_ON_ERROR:-0} + + if [ "$READ_ON_ERROR" = "1" ]; then + echo "Appuyez sur Entrée pour quitter" + read + fi + exit 64 +} + +request() { + echo + echo -e "$@" + echo + echo -n "Confirmez (O/n) : " + read + if [ -z "$REPLY" -o "$REPLY" = "o" -o "$REPLY" = "O" ]; then + return 0 + fi + return 1 +} + +requestNo() { + echo + echo -e "$@" + echo + echo -n "Confirmez (o/N) : " + read + if [ "$REPLY" = "o" -o "$REPLY" = "O" ]; then + return 0 + fi + return 1 +} + +testInstallDebian() { + local notFound=0 + #local bin="lsb_release qemu-system-x86_64 neato bzip2 wget" + local bin="lsb_release bzip2 wget" + + for i in $bin; do + if ! whereis $i | grep -q bin; then + echo "Impossible de trouver l'exécutable : $i !" + notFound=1 + fi + done + + if [ $notFound = 1 ]; then + request "Programme(s) manquant(s) !\nL'administrateur doit préparer le système via la commande :\nvdn-prepare-debian\nAbandonner le démarrage de VDN ?" + if [ $? -eq 0 ]; then + exit 1 + fi + fi +} + +computeHostRelease() { + + set +u + [ -n "$HOST_RELEASE" ] && return || : + set -u + + if [ -e /usr/lib/os-release ]; then + ID=$(cat /usr/lib/os-release | grep '^ID=' | cut -d '=' -f 2) + if [ -z "$ID" ]; then + ID="empty" + fi + VERSION_CODENAME=$(cat /usr/lib/os-release | grep '^VERSION_CODENAME=' | cut -d '=' -f 2) + if [ -z "$VERSION_CODENAME" ]; then + VERSION_CODENAME="empty" + fi + + export HOST_RELEASE="$ID/$VERSION_CODENAME" + + else + export HOST_RELEASE="empty/empty" + fi +} + + +# Fixe GUEST_PATH, GUEST_CONF et GUEST_SAVE +# $1 : GUEST_NAME +setGuestVars() { + set -a + MODE=tgz + GUEST_OWNER=$USER + GUEST_NAME=$1 + GUEST_PATH="$NETWORK_DIR" + GUEST_CONF="$GUEST_PATH/$1.conf" + #if [ ! -e "$GUEST_CONF" ]; then + # error "WARNING : Le système $(basename $NETWORK_DIR)/$1 n'existe pas !" + #fi + ##NETWORK="$(basename $NETWORK_DIR)" + #IDENT="" + #IDENT=$(grep '^IDENT=[0-9]' $GUEST_CONF | \ + # sed -re 's/^.*IDENT=([0-9]+).*/\1/') + #[ -z "$IDENT" ] && error "IDENT n'est pas fixé dans $GUEST_CONF" || : + + SSH_IDENTITY="$HOME/.ssh/id_dsa.pub $HOME/.ssh/id_rsa.pub" + SWAP_FILE="$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-swap" + + # fichier utilisé pour la partition de l'union. + # si fixée à "" alors un tmpfs est utilisé + + AUFS_FILE="$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-part" + OUT_FILE="$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-out" + + ALIVE_FILE=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER.alive + + EXCLUDE_SERVICES="" + + KVM_NETWORKS_OPTS="" + KVM_DISKS_OPTS="" + KVM_OPTS="" + KVM_CMD="" + NET_MODEL=${NET_MODEL:-ne2k_pci} + + set +u + [ -n "$EXPR" -a "$EXPR" != '[]' ] && { + eval "$EXPR" + } + set -u + + set +a +} + +loadGuestVars() { + setGuestVars $1 + computeNetworks + . $VDN_PATH/config.template + [ -e $VDN_PATH/config.template.local ] && . $VDN_PATH/config.template.local || : + . $GUEST_CONF + set -a + set +u + [ -n "$EXPR" -a "$EXPR" != '[]' ] && { + eval "$EXPR" + } + set -u + set +a + + case "$MODE" in + tgz|tgz2) + SAVE_FILE="$SAVE_DIR/$GUEST_NAME.tgz" + ;; + overlay) + #SAVE_FILE="$SAVE_DIR/$GUEST_NAME.tgz" + SAVE_FILE="$SAVE_DIR/$GUEST_NAME.overlay" + ;; + *) + SAVE_FILE="$SAVE_DIR/$GUEST_NAME.cow" + ;; + esac + + [ ! -d "$(dirname $SAVE_FILE)" ] && mkdir -p "$(dirname $SAVE_FILE)" || : +} + +# retourne 0 (vrai) si le système existe + +isDefined() { + GUEST_PATH="$NETWORK_DIR" + GUEST_CONF="$GUEST_PATH/$1.conf" + test -e "$GUEST_CONF" + return $? +} + +resizeMultipleOf512() { + local s=$(stat -c %s $1) + local n=$(( (($s/512)+($s%512!=0)*1)*512 )) + #echo "s=$s, n=$n" + truncate -s $n $1 +} + +debugNet1() { + set +u + [ -z "$DEBUG_NET" ] && export DEBUG_NET="false" + set -u + echo "debugNet1 host:$KHOST K:$K K_HIGH:$K_HIGH K_LOW:$K_LOW U:$U U1:$U_LOW U2:$U_HIGH" >&2 +} + +computeNetworksOld() { + + local K U i + + set +u + ident=$1 + set -u + + [ -z "$ident" ] && ident=$IDENT || : + + # Configuration des réseaux (brins Ethernet, adresse IP et adresses MAC) + + # Ce fichier est lu avant la lecture du fichier de configuration d'un + # système et est utilisé pour définir les réseaux (virtuels). + # Lorsque ce fichier est lu, la variable IDENT contenant + # l'identificateur du système à démarrer est fixée. + + # ### + # 1. Calcule les adresses "multicast" des brins Ethernet virtuels. + # ### + + # Détermine la clé propre à chaque utilisateur. + # Remarque : conflit si même poids faible de l'UID. + + U=$(($(id -u)%512)) + + # !!! + #[ "$USER" = gudavala ] && U=511 + + U_LOW=$(($U%256)) + U_HIGH=$(($U/256)) + + + # Détermine la clé K propre à la machine hôte (poids faible de l'IP) + + #K=`/sbin/ifconfig eth0 | grep Bcast | head -n 1 | cut -d ':' -f 2 | \ + # cut -d ' ' -f 1 | cut -d '.' -f 4`A + + IP_LINE=$(ip addr | grep '192\.168' | head -n 1) + #IP_LINE=$(echo " inet 192.168.1.37/24 brd 192.168.1.255 scope global dynamic eth0" | grep '192\.168' | head -n 1) + + K=$(echo $IP_LINE | sed -re 's/.*192\.168\.([0-9]+)\.([0-9]+)\/.*$/\1 \2/') + + + #IP_LINE=$(echo " inet 192.168.1.37/24 brd 192.168.1.255 scope global dynamic eth0" | grep '192\.168' | head -n 1) + + K=$(echo $IP_LINE | sed -re 's/.*192\.168\.([0-9]+)\.([0-9]+)\/.*$/\1 \2/') + + [ -z "$K" ] && { + echo "Warning : can't find network host uniq number ! use "1" !" + K=1 + } + + #KK="" + #if [ -e $NETWORK_DIR/hosts.txt ]; then + # local h=$(hostname) + # h=$(echo $h | sed -re 's/iutclinf(.*)l/\1/') + # KK=$(cat $NETWORK_DIR/hosts.txt | grep -n $h | cut -d ':' -f 1) + # [ -n "$k2" ] && K=$K_LOW + #fi + #echo "KEY:$K K_LOW=$KK" + + + K_HIGH=$(echo $K | cut -d ' ' -f 1) + K_LOW=$(echo $K | cut -d ' ' -f 2) + + KHOST=$K_LOW + [ "$K_HIGH" = "128" ] && KHOST=$((512+$K_LOW)) + + [ $K_HIGH = 128 ] && K_HIGH=1 || K_HIGH=0 + + #K_HIGH=$(($K_HIGH%16)) + K_LOW=$(($K_LOW%256)) + + set +u + #[ "$USER" = "gudavala" ] && [ -z "$VDN_FIRST" ] && debugNet1 + set -u + + set -a + + # Brin Ethernet PARTAGÉ par TOUS les systèmes de TOUS les utilisateurs. + # [Internet virtuel] + + NET_G="239.2.0.0:1999" + + # Brins privés à une machine hôte + + for i in `seq 0 64`; do + eval NET_$i="234.$K_HIGH.$K_LOW.$U_LOW:$((2000+$U*16+$i))" + done + + # ### + # 2. Calcule l'adresse IP "réservée" sur le brin PARTAGÉ + # ### + + ###PUBLIC_IP="$((20+$K_HIGH+U_HIGH*2)).$K_LOW.$U_LOW.$ident" + + #set -x + PUBLIC_IP=$(vdn-query PUBLIC_IP 0 $GUEST_NAME.$NETWORK_NAME) + #set +x + + # ### + # 3. Calcule les adresses MAC des cartes Ethernet + # ### + + U_LOW=`printf "%02X" $U_LOW` + + V=$((54+$K_HIGH+$U_HIGH*2)) + V=$(printf "%02d" $V) + K_HIGH=`printf "%02X" $K_HIGH` + K_LOW=`printf "%02X" $K_LOW` + + + + F_IDENT=$(printf "%02d" $ident) + + MAC_0=52:$V:$K_LOW:$U_LOW:$F_IDENT:00 + MAC_1=52:$V:$K_LOW:$U_LOW:$F_IDENT:01 + MAC_2=52:$V:$K_LOW:$U_LOW:$F_IDENT:02 + MAC_3=52:$V:$K_LOW:$U_LOW:$F_IDENT:03 + MAC_4=52:$V:$K_LOW:$U_LOW:$F_IDENT:04 + MAC_5=52:$V:$K_LOW:$U_LOW:$F_IDENT:05 + MAC_6=52:$V:$K_LOW:$U_LOW:$F_IDENT:06 + MAC_7=52:$V:$K_LOW:$U_LOW:$F_IDENT:07 + + set +a +} + +computeNetworks() { + + set -a + # NET_G ? + # NET_ ? + + #PUBLIC_IP=$(vdn-query PUBLIC_IP 0 $GUEST_NAME.$NETWORK_NAME) + + # MAC_ ? +} + +# "Calcule" le port utilisé pour une redirection (interface pour la connexion +# avec l'hôte). +# En unique argument, le port de la machine virtuelle à rediriger vers un port +# local. En sortie, affichage du port "théorique" pour la redirection. +# En pratique le premier port libre égal ou supérieur au port "théorique" sera +# utilisé. + +vdn_redirOld() { + echo $((5000+100*$IDENT+$1)) +} + +getIpNotUsed() { + name=$1 + eth=$2 + + #vdn-infos $name >&2 + local nets=$(vdn-infos $name | grep '^NETWORKS=' | sed -re 's/^NETWORKS=//') + local ip=$(echo $nets | cut -d ' ' -f $((eth+1)) | cut -d '#' -f 2 | sed -re 's/^[^0-9]*([0-9.]+).*$/\1/') + + echo $ip +} + +# Vérifie l'unicité des identificateurs des systèmes du réseau courant. + +verifIdentOld() { + local i=0 + local configs="`find $NETWORK_DIR -follow -type f -name \"*.conf\" 2> /dev/null`" + [ -n "$configs" ] || return 0 + l=$(grep -E '^[[:space:]]*IDENT=[0-9]+' $configs | \ + sed -re 's,^.*/([^/]*)/config:[[:space:]]*IDENT=([0-9]+).*$,\1:\2,' | sort -n -t : -k 2) + + local t + + for i in $l; do + name=$(echo $i | cut -d ':' -f 1) + ident=$(echo $i | cut -d ':' -f 2) + set +u + t[$ident]="${t[$ident]},$name" + set -u + done + + local found=0 + for i in ${t[*]}; do + l=$(echo $i | sed -re 's/^,//') + if echo $l | grep -q ','; then + n=$(echo $l | cut -d ',' -f 1) + ident=$(vdn-config $n IDENT) + echo "Erreur : l'identificateur $ident est partagé par $l !" + found=1 + fi + done + + return $found + + +} + + +# Démarre un ssh pour un système virtuel en mode "master" +sshGuestControlMaster() { + Login=${LOGIN}localhost + + # wait lock + local n=0 + local lock=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-ssh-lock + while ! mkdir $lock 2> /dev/null; do + sleep 0.5 + # Securité + n=$(($n+1)) + if [ $n -gt 5 ]; then + rmdir $lock 2> /dev/null || : + fi + done + + sleep 0.1 + + #echo "Locked" + + #echo "Login:$Login" >&2 + #ps auwx > /tmp/p + #ps auwx | grep -v grep | grep $Login | grep -q -- "-N -M" > /tmp/o || : + local sign="$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest" + test="ps auwx | grep -v grep | grep $Login | grep $sign" + #[ $GUEST_OWNER = gudavala ] && echo "test:$test" + if ! ps auwx | grep -v grep | grep $Login | grep $sign | grep -q -- "-N -M"; then + rmdir $lock 2> /dev/null || : + #[ $GUEST_OWNER = gudavala ] && echo "Master... $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest" + ssh -g $Login $SSH_OPTS $@ -o ServerAliveInterval=5 -p $SSH_REDIR_PORT -X -f -n -N -M -S $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest-%r@%h:%p &> /dev/null + else + rmdir $lock 2> /dev/null || : + fi + +} + +findUnusedPort() { + # $1 : proto + # $2 : port + + local proto port dst hex proc + + proto=$1 + port=$2 + + + hex=`printf "%04X" $port` + proc="/proc/net/$proto" + + while cat $proc | cut -d : -f2- | cut -d ' ' -f2,3 | grep -q ":$hex"; do + #echo "$proto port $port (for $dst) is used ! find next !" >&2 + port=$(($port+1)) + hex=`printf "%04X" $port ` + done + + echo $port +} + + + +setEnv() { + + set +u + local save="$NETWORK_DIR" + set -u + set -a + + . $VDN_PATH/config.rc # ! set NETWORK_DIR + [ -e $VDN_PATH/config.rc.local ] && . $VDN_PATH/config.rc.local || : + + + # NETWORK_DIR priority + + if [ -n "$save" ]; then + NETWORK_DIR=$save + fi + + set +a + + set +u + [ -z "$EDITOR" ] && export EDITOR="vi" + set -u + + export HOST_RELEASE + + export VDN_WS_PROXY_SOCKET=$TMPDIR/vdn-$USER-ws-sock +} + +vdn_init() { + + export VDN_NETWORKS_BASE_DIR=${VDN_NETWORKS_BASE_DIR:-$VDN_PATH/networks} + set +u + CURRENT_NETWORK_DIR="$NETWORK_DIR" # var. d'env. prioritaire + + NETWORK_NAME="" + [ -n "$CURRENT_NETWORK_DIR" ] && NETWORK_NAME=$(basename $CURRENT_NETWORK_DIR) + + #[ -z "$NETWORK_NAME" ] && error "NETWORK_NAME empty !" + set -u + + PATH="$PATH:$VDN_PATH/bin" + setEnv + + set -a + [ ! -e "$TMPDIR" ] && (umask 077 && mkdir -p "$TMPDIR" ) + [ -n "$CURRENT_NETWORK_DIR" ] && NETWORK_DIR="$CURRENT_NETWORK_DIR" + + set +u + if [ -n "$NETWORK_DIR" ]; then + if [ ! -d "$NETWORK_DIR" ]; then + #echo "Le réseau $NETWORK_DIR n'existe pas !" >&2 || : + NETWORK_DIR="" + SAVE_DIR="" + #exit 1 + + fi + if [ "$NETWORK_DIR" != "" ]; then + . $NETWORK_DIR/network.vdn + SAVE_DIR="$SAVE_PATH/$(basename $NETWORK_DIR)" + fi + else + SAVE_DIR="" + fi + + set -u + set +a + + set +u + [ -z "$VDN_DEBUG" ] && export VDN_DEBUG=0 || : + set -u + + + +} + + +sendToGui() { + local pid=$(ps auwx | grep 'ruby' | grep 'vdn-gui' | tr -s " " | cut -d ' ' -f 2) + if [ -n "$pid" ]; then + #echo "SENDTOGUI ($TMPDIR/vdn-gui-$USER-fifo-ctrl) : $@" + echo "$@" > $TMPDIR/vdn-gui-$USER-fifo-ctrl + fi +} + +# main + +set +u +[ -z "$VDN_PATH" ] && export VDN_PATH=$(readlink -f $(dirname $0)/..) || : +! echo "$PATH" | grep -q $VDN_PATH && export PATH="$VDN_PATH/bin:$PATH" +set -u + +computeHostRelease + +setEnv + +vdn_init diff --git a/vdn/bin/sae203-init b/vdn/bin/sae203-init new file mode 100755 index 0000000..b213c77 --- /dev/null +++ b/vdn/bin/sae203-init @@ -0,0 +1,89 @@ +#!/bin/bash + +# Mot de passe par défaut + +export SSHPASS='iut*' +pass='' + +# Demande et affiche un mot de passe + +getPassword() { + local pass1 pass2 + local cont=1 + + while [ $cont = 1 ];do + + echo -n "Mot de passe : " >&2 + + # -s : lecture sans affichage + read -s pass1 + + echo >&2 + + echo -n "Retapez le mot de passe : " >&2 + + read -s pass2 + + echo >&2 + + if [ -n "$pass1" -a "$pass1" = "$pass2" ]; then + cont=0 + else + if [ "$pass1" != "$pass2" ]; then + echo "Les mots de passe ne correspondent pas." >&2 + else + echo "Un mot de passe vide n'est pas valide !" >&2 + fi + fi + done + + echo "$pass1" +} + + +# main + +if [ ! -r ~/.ssh/id_rsa.pub ]; then + echo "~/.ssh/id_rsa.pub manquant !" >&2 + exit 1 +fi + +if [ -z "$pass" ]; then + echo "Entrez un mot de passe pour les utilisateurs root et test" + echo "N'oubliez pas ce mot de passe sous peine de tout perdre !" + echo "ATTENTION : Les caractères ', \" et tabulation ne sont pas autorisés ! :" + pass=$(getPassword) +fi + +# Copie de la clé ssh publique dans ~root/.ssh/authorized_keys +# de la machine virtuelle +sshpass -e ~vdn/vdn/bin/vdn-ssh-copy-id -i ~/.ssh/id_rsa.pub root@debian-1 &> /dev/null + +# idem pour l'utilisateur test +sshpass -e ~vdn/vdn/bin/vdn-ssh-copy-id -i ~/.ssh/id_rsa.pub test@debian-1 &> /dev/null + +vdn-ssh root@debian-1 'echo "root:'$pass'" | chpasswd' +vdn-ssh root@debian-1 'echo "test:'$pass'" | chpasswd' + +# Vérification + +SSHPASS="$pass" +if ! sshpass -e vdn-ssh -n -o PubkeyAuthentication=no root@debian-1 ':'; then + echo "Echec !" >&2 +fi + + +exit 0 + +# Copie de la clé ssh publique dans ~test/.ssh/authorized_keys +# de la machine virtuelle + +vdn-ssh-copy -i ~/.ssh/id_rsa.pub test@debian-1 + +# Choix d'un nouveau mot de passe pour le compte root + +echo "Entrez un nouveau mot + + + + diff --git a/vdn/bin/vdn b/vdn/bin/vdn new file mode 100755 index 0000000..0ae0ad9 --- /dev/null +++ b/vdn/bin/vdn @@ -0,0 +1,483 @@ +#!/usr/bin/env bash + +#set -x + +MULTIPLE=1 + +RUN_SINGULARITY=0 + +export VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +FIRST_REQUEST=1 +ACCEPT_CHROOT=0 +USE_SUDO=0 +NO_HOST_KVM_TEST=0 +FORCE_CHROOT=0 # for test +TEST_ONLY=0 # test host and quit. +NETWORK="" + +set +u +[ -z "$RUN_IN_CHROOT" ] && RUN_IN_CHROOT=0 || : +set -u +export RUN_IN_CHROOT + +set -a +NO_MOZ=0 +set +a + +quit() { + echo "quit..." + + + #sendToGui "gui" + #sleep 1 + + pid=$(ps auwx | grep 'ruby' | grep 'vdn-gui' | tr -s " " | cut -d ' ' -f 2) + if [ -n "$pid" ]; then + echo "kill : $pid" >&2 + kill $pid + sleep 1 + fi + echo +} + +synopsis() { + cat << EOF +Usage : $(basename $0) [-h] [-v] +EOF +} + +help() { + cat << EOF + +$(basename $0) démarre l'interface graphique de Vdn. + +$(synopsis) + +-h : affiche cette aide. +-v : affiche la version. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "cdfhsmntv" opt; do + case $opt in + h) help; exit 0;; + v) cat $VDN_PATH/release; exit 0;; + c) ACCEPT_CHROOT=1;; + d) export VDN_DEBUG=1; vdn-set-var VDN_DEBUG 1; set -x;; + m) MULTIPLE=1;; + n) NO_HOST_KVM_TEST=1;; + s) USE_SUDO=1;; + f) FORCE_CHROOT=1;; + t) TEST_ONLY=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -eq 1 ] && NETWORK="$1" +} + + +request() { + + if [ $FIRST_REQUEST = 1 ]; then + FIRST_REQUEST=0 + request "Une ou plusieurs questions vont vous être posées. Sauf bonne raison, acceptez\nles choix par défaut en appuyant sur \"Entrée\"." + if [ $? -ne 0 ]; then + echo "Bye !" + exit 0 + fi + fi + echo + echo -e "$@" + echo + echo -n "Confirmez (O/n) : " + read + if [ -z "$REPLY" -o "$REPLY" = "o" -o "$REPLY" = "O" ]; then + return 0 + fi + return 1 +} + +testHost() { + + if [ "$(uname -m)" != "x86_64" ]; then + echo "Désolé, cette version de VDN ne fonctionne que sur architecture x86_64 !" >&2 + exit 1 + fi + + #if [ "$DISPLAY" = "" ]; then + # echo "Désolé, cette version de VDN nécessite un serveur graphique compatible X11 !" >&2 + # exit 1 + #fi + + if [ $NO_HOST_KVM_TEST = 0 ]; then + grep -Eq '(vmx|svm)' /proc/cpuinfo + virtproc=$? + [ -w /dev/kvm ] + kvmwrite=$? + lsmod | grep -q 'kvm_' + kvmproc=$? + lsmod | grep -q 'kvm[^_]' + + kvm=0 + + if [ $virtproc -ne 0 ]; then + echo "Votre processeur ne dispose pas d'instructions de virtualisation :-( !" + #else + # echo "Votre processeur dispose d'instructions de virtualisation ;-)" + fi + if [ $virtproc -eq 0 -a $kvmwrite -ne 0 ]; then + echo + echo "Votre processeur dispose d'instructions de virtualisation." + echo "Cependant vous ne pouvez pas les utiliser :-( !" + echo + + if [ -e /dev/kvm ]; then + msg=" Vous n'avez pas les droits de lecture/écriture sur /dev/kvm !\n L'administrateur (root) doit, au choix, effectuer les actions suivantes :\n 1. chmod 666 /dev/kvm.\n 2. Vous ajouter au groupe $(stat -c %G /dev/kvm) (commande \"addgroup $USER $(stat -c %G /dev/kvm)\" par exemple).\n\n Si la deuxième solution est choisie, vous devrez vous déconnecter de votre\n session graphique et vous reconnecter ou, plus simplement, ouvrir un nouveau\n shell de connexion via par exemple la commande \"su - $USER\"." + + elif lsmod | grep -q kvm; then + msg=" Les instructions de virtualisation de votre processeur ne sont pas activées dans votre BIOS/UEFI.\n + Redémarrez et configurez le BIOS/UEFI pour bénéficier de la virtualisation." + else + proc="intel" + if cat /proc/cpuinfo | grep -i -q amd; then + proc="amd" + fi + msg=" Le module noyau \"kvm-$proc\" n'est pas chargé !\n L'administrateur du système doit exécuter : modprobe kvm-$proc ." + fi + echo "Il semblerait que la raison soit :" + echo -e "$msg" + echo + + request "Continuer en mode \"sans instructions de virtualisation\" ?" + + [ $? -ne 0 ] && exit 1 + fi + fi +} + +runInChrootOld() { + #[ $RUN_IN_CHROOT = 1 ] && good=1 || : + if [ $ACCEPT_CHROOT = 0 ]; then + if [ $good = 0 -o \( $FORCE_CHROOT = 1 -a $RUN_IN_CHROOT = 0 \) ]; then + request "Le sytème hôte n'est pas une Debian 10 (buster).\nBasculer dans un environnement chroot ? (accès root nécessaire)" + + [ $? -ne 0 ] && exit 0 + fi + fi + + if [ $good = 0 -o \( $FORCE_CHROOT = 1 -a $RUN_IN_CHROOT = 0 \) ]; then + RUN_IN_CHROOT=1 + + export VDN_DISK_ENV="DebianBuster-amd64-env.disk" + export VDN_DISK_NAME="DebianBuster-amd64.disk" + + [ ! -e $VDN_PATH/files/$VDN_DISK_ENV ] && VDN_DISK_ENV=$VDN_DISK_NAME || : + + DISK=$VDN_PATH/files/$VDN_DISK_ENV + + + DISK_SIZE=0 + if [ -e $DISK ]; then + DISK_SIZE=$(ls -l $DISK | tr -s ' ' | cut -d ' ' -f 5) + fi + if [ $DISK_SIZE -lt $REMOTE_DISK_SIZE ]; then + + request "Télécharger du disque virtuel de VDN (6 Go) ?" + + [ $? -ne 0 ] && exit 0 + + local notFound=0 + local bin="bzip2 wget" + + for i in $bin; do + if ! whereis $i | grep -q bin; then + echo "Impossible de trouver l'exécutable : $i !" + notFound=1 + fi + done + + if [ $notFound = 1 ]; then + error "Programme(s) manquant(s) !\nL'administrateur doit installer ces programmes !" + fi + + vdn-download-disks -t DebianBuster-amd64.disk.gz + fi + + echo + echo "Running in chroot." + + if [ $USE_SUDO = 1 ]; then + vdn-mount-chroot -s + else + vdn-mount-chroot + fi + + exit $? + fi + +} + +runInChrootIfNecessary() { + + local good=0 + + # chroot ? + + if [ -e /etc/debian_version ]; then + if grep -q '^10\.' /etc/debian_version ; then + good=1 + fi + fi + + [ $RUN_IN_CHROOT = 1 ] && good=1 || : + + #runInChrootOld + + # Not in chroot + + +} + +runWithSingularityIfNecessary() { + + local good=0 + + # chroot ? + + if [ -e /etc/debian_version ]; then + if grep -q '^10\.' /etc/debian_version ; then + good=1 + fi + fi + + + if [ $good = 0 ]; then + RUN_SINGULARITY=1 + fi + +} + +updateVdnrc() { + if [ -e ~/.vdnrc ]; then + + request "Lors d'un changement de version de VDN, il est conseillé de mettre à jour\nle fichier ~/.vdnrc (la version courante sera enregistrée sous ~/.vdnrc.old).\nVoulez-vous mettre à jour ~/.vdnrc ?" + + if [ $? -eq 0 ]; then + mv ~/.vdnrc ~/.vdnrc.old + fi + fi +} + +pathWarning() { + echo + echo "*******************************************************************************" + echo "Le chemin de l'exécutable de VDN sera connu uniquement des NOUVEAUX shells !" + echo "*******************************************************************************" +} + +### main + +export VDN_DEBUG=0; vdn-set-var VDN_DEBUG 0 + +args "$@" + +if [ -n "$NETWORK" -a "$NETWORK" = "stop" ]; then + quit + exit 0 +fi + +if [ -n "$NETWORK" ]; then + if [ ! -d $NETWORK ]; then + if [ -d $NETWORK_DIR/../$NETWORK ]; then + NETWORK=$(readlink -f $NETWORK_DIR/../$NETWORK) + fi + fi + + if [ ! -d $NETWORK ]; then + error "Can' find network $NETWORK !" + fi + + # set and reload + vdn-set-var NETWORK_DIR "$NETWORK" + export NETWORK_DIR="$NETWORK" + . $VDN_PATH/bin/functions.sh +fi + +#for i in 1 2 3 4 5; do +# if ! ps auwx | grep -v grep | grep -q 'ruby.*vdn-gui' ; then +# break +# fi +# sleep 0.1 +#done + +if [ $MULTIPLE = 0 ]; then + if ps auwx | grep -v grep | grep -q 'ruby.*vdn-gui' ; then + error "Une instance de l'interface graphique de VDN est déjà active" + fi +else + #echo "Multiple..." + if ps auwx | grep -v grep | grep -q 'ruby.*vdn-gui' ; then + export NETWORK_DIR="" + vdn-set-var NETWORK_DIR "" + fi +fi + +#clear + +#if ! /sbin/route -n | grep -q '0.0.0.0' ; then +#/sbin/ip route + +if ! /sbin/ip route | grep -q default; then + cat << EOF >&2 + +Pas de route par défaut ! + +Si le système hôte ne dispose pas d'interface réseau, vous pouvez +autoriser la diffusion sur l'interface lo (loopback) via les commandes +(il faut être root) : + +Avec ifconfig : + +ifconfig lo multicast +route add default gw 127.0.0.1 + +avec ip : + +ip link set dev lo multicast on +ip route add default via 127.0.0.1 + +EOF + error "Pas de route par défaut ! Voir ci-dessus ou consultez la FAQ !" +fi + + + +testHost # chroot if necessary + +runInChrootIfNecessary + +# Not in chroot + +# download extras +#if [ -e $VDN_PATH/distribs/hosts/$HOST_RELEASE/download-extras.sh ]; then +# . $VDN_PATH/distribs/hosts/$HOST_RELEASE/download-extras.sh +# if ! testDownloadExtras; then +# downloadExtras +# fi +#fi + +testInstallDebian + +testVersionOld() { + +while :; do + version="$VDN_PATH" + current=$(cat ~/.bashrc |sed -nre 's/^[^#]*PATH.*:([^:]*vdn[^:]*)\/bin.*$/\1/p') + + [ "$current" = "$version" ] && break; + + # La version courante diffère de la version lancée + if [ -n "$current" ] && [ "$version" != "$current" ]; then + request "Votre fichier ~/.bashrc définit la version $current comme étant la version à utiliser. Cependant vous exécutez $version.\nVotre fichier ~/.bashrc doit être adapté !\nVoulez-vous que ce programme l'adapte pour vous ?" + + if [ $? -ne 0 ]; then + echo "Adaptez votre fichier ~/.bashrc puis relancez $0."; + exit 1; + + else + cp ~/.bashrc ~/.bashrc.vdn.old + + echo "Ancien fichier ~/.bashrc copié sous ~/.bashrc.vdn.old" + + cat ~/.bashrc |sed -re 's,[^:]*'$current','$VDN_PATH',g'> \ + ~/.bashrc-vdn + mv ~/.bashrc-vdn ~/.bashrc + + echo + + pathWarning + + updateVdnrc + + fi + + elif [ -z "$current" ]; then + line="PATH=\"\$PATH:$VDN_PATH/bin\"" + request "Votre fichier ~/.bashrc ne définit pas le chemin des exécutables de $version.\nLa ligne suivante doit être ajoutée :\n$line\nVoulez vous que ce programme adapte votre fichier ~/.bashrc pour vous ?" + if [ $? -eq 0 ]; then + echo "Adaptation de ~/.bashrc" + echo "PATH=\"\$PATH:$VDN_PATH/bin\"" >> ~/.bashrc + + pathWarning + + updateVdnrc + else + break + fi + + # echo "Ajoutez une ligne PATH=\"\$PATH:$VDN_PATH/bin\" à votre fichier ~/.bashrc puis relancez $0." + # exit 1; + + fi +done + + +if [ ! -e ~/.ssh/id_dsa.pub -a ! -e ~/.ssh/id_rsa.pub ]; then + request "Vous ne disposez pas d'un couple de clé SSH RSA nécessaire au fonctionnement de Vdn.\nVoulez vous que ce programme vous génère un couple de clé RSA ?" + + if [ $? -eq 0 ]; then + echo + echo "Create ssh keys..." + ssh-keygen -q -N '' -f ~/.ssh/id_rsa -t rsa + else + echo "Exécutez la commde ci-dessous pour générer un couple de +clé SSH RSA puis relancez $0 :" + echo "ssh-keygen -q -N '' -f ~/.ssh/id_rsa -t rsa" + exit 1 + fi + set +x +fi +} + + +export VDN_RELEASE="$(cat $VDN_PATH/release)" +export PATH="$VDN_PATH/bin:$PATH" + +[ $TEST_ONLY = 1 ] && exit 0 || : + +setEnv + +rm -f $HOME/.tmuxinator/vdn-tmuxinator* + +trap 'quit' SIGINT + +if [ ! -e /usr/bin/tmuxinator ]; then + $VDN_PATH/bin/vdn-set-var RUN_PARALLEL 0 + echo "/usr/bin/tmuxinator not found ! RUN_PARALLEL disable..." >&2 + sleep 1 +fi + +rm -f $TMPDIR/vdn-$USER-gui-log +mkfifo $TMPDIR/vdn-$USER-gui-log +chmod 600 $TMPDIR/vdn-$USER-gui-log + +export GUI=1 +export VDN_GUI=1 + +export LANG=fr_FR.UTF-8 + +$VDN_PATH/bin/vdn-gui.rb 2>&1 # | tee $TMPDIR/vdn-$USER-gui-log + +#$VDN_PATH/bin/vdn-gui.rb #2>&1 > $TMPDIR/vdn-$USER-gui-log & +#echo + diff --git a/vdn/bin/vdn-alive b/vdn/bin/vdn-alive new file mode 100755 index 0000000..31ad347 --- /dev/null +++ b/vdn/bin/vdn-alive @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` retourne 0 si le système est en fonctionnement, 1 sinon. + +`synopsis` + +-h : affiche cette aide. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi +} + +alive() { + local r + set +e + #ps u | grep -E $GUEST_NAME[-]$USER-pid + #ps auwx | grep qemu + #ps -w -w -u $USER -eo cmd | grep -Eq $GUEST_NAME[-]$USER-pid + ps -w -w -eo user:14,cmd | grep $USER | grep -Eq $GUEST_NAME[-]$USER-pid + r=$? + set -e + return $r +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +alive diff --git a/vdn/bin/vdn-alives b/vdn/bin/vdn-alives new file mode 100755 index 0000000..4e427b8 --- /dev/null +++ b/vdn/bin/vdn-alives @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` affiche la liste des systèmes en fonctionnement. + +`synopsis` + +-h : affiche cette aide. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +#ps u | grep 'bash.*[/]vdn-start ' | grep -v linux | sed -re 's/^.* ([^[:space:]]+)$/\1/' | sort | uniq +#ps -u root -eo cmd | grep 'bash.*[/]vdn-start ' | sed -re 's/^.* ([^[:space:]]+)$/\1/' | sort | uniq +ps -eo user:14,cmd | grep ^$USER | grep 'bash.*[/]vdn-start ' | sed -re 's/^.* ([^[:space:]]+)$/\1/' | sort | uniq + +#ps auwx | grep 'name[= ].*user[ =]'$USER' ' | grep -v sed | grep -v grep | sed -re 's/^.*[ -]name[= ]([^[:space:]]+).*$/\1/' | sort | uniq + + diff --git a/vdn/bin/vdn-build b/vdn/bin/vdn-build new file mode 100755 index 0000000..a30730c --- /dev/null +++ b/vdn/bin/vdn-build @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : $(basename $0) [-h] system +EOF +} + +help() { + cat << EOF + +$(basename $0) initialise le fichier de configuration d'un système. + +$(synopsis) + +Le fichier de configuration du système est créé à partir du +modèle (config.template) du répertoire du réseau ou, à défaut, +du modèle config.template du répertoire de Vdn. + +Pour modifier des variables du fichier de configuration consultez +la commande vdn-config. Le script build du répertoire d'un réseau +utilise $(basename $0). + +Voir aussi les fichier build des répertoire des réseaux pour des +exemples de configurations. + +-h : affiche cette aide + +EOF +} + + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + + if echo "$GUEST_NAME" | grep -q '[[:space:]]'; then + error "$GUEST_NAME est un nom de système invalide" + fi + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi + + +} + +setIdentOld() { + tmp=$(mktemp) + cat $GUEST_CONF | sed -re 's/^IDENT=.*$/IDENT='$1'/' \ + > $tmp + mv $tmp $GUEST_CONF 2> /dev/null +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +#isDefined $GUEST_NAME && error "$GUEST_PATH existe déjà" + +GUEST_PATH="$NETWORK_DIR" +GUEST_CONF="$GUEST_PATH/$1.conf" +#IDENT=256 +#computeNetworks + +config=$NETWORK_DIR/config.template +[ ! -e $config ] && config=$VDN_PATH/config.template + +echo "Build $GUEST_NAME..." >&2 + +cp $config $GUEST_CONF + +#ident=$(vdn-find-ident) +#setIdent $ident + diff --git a/vdn/bin/vdn-build-db b/vdn/bin/vdn-build-db new file mode 100755 index 0000000..17d9713 --- /dev/null +++ b/vdn/bin/vdn-build-db @@ -0,0 +1,58 @@ +#!/bin/bash + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` reconstruit la base de données de l'allocateur de ressources. + +`synopsis` + +A faire à chaque changement de la liste des utilisateurs, +ou chaque ajout/suppression d'un réseau ou d'un hôte dans un réseau. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hqs" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done +} + +# main + +args "$@" + +dir=$VDN_PATH/allocators/db-$VDN_RESOURCES_ALLOCATOR + +[ ! -d $dir ] && mkdir -p $dir + +ls $(dirname $HOME) > $dir/users + +( cd $VDN_NETWORKS_BASE_DIR; find . -maxdepth 1 -type d | grep -v '^\.$' | cut -d '/' -f 2 | grep -v '\/') > $dir/networks + +rm -f $dir/hosts.global +for i in $(cat $dir/networks) ; do + for j in $(cd $VDN_NETWORKS_BASE_DIR/$i; find . -maxdepth 1 -type f -name '*.conf' | sed -re 's/^..(.*).conf$/\1/' ); do + egrep -q '^NETWORKS=.*(NET_G|NET_0)' $VDN_NETWORKS_BASE_DIR/$i/$j.conf && echo $i:$j >> $dir/hosts.global + echo $i:$j + done +done > $dir/hosts + diff --git a/vdn/bin/vdn-build-network b/vdn/bin/vdn-build-network new file mode 100755 index 0000000..ea421cb --- /dev/null +++ b/vdn/bin/vdn-build-network @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +#set -x + +EDIT=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-e] [networkDir...] + +EOF +} + +help() { + cat << EOF + +`basename $0` construit le réseau. + +`synopsis` + +-h : affiche cette aide. +-e : propose l'édition du script avant la reconstruction + (la reconstruction n'est faite que si modifications il y a) + +Cette commande, après avoir fixé quelques variables, appelle +le script build du réseau. + +Si networkDir n'est pas précisé, le réseau défini par la +variable NETWORK_DIR est (re)créé. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "he" opt; do + case $opt in + h) help; exit 0;; + e) EDIT=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + NETS=$@ +} + +# main + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + + +if [ -z "$NETS" ]; then + NETS=$NETWORK_DIR +fi + +if [ -z "$NETS" ]; then + error "NETWORK_DIR not set !" +fi + +for i in $NETS; do + + if [ -d $i ]; then + NETWORK_DIR=$i + elif [ -d $VDN_NETWORKS_BASE_DIR/$i ]; then + NETWORK_DIR=$VDN_NETWORKS_BASE_DIR/$i + else + error "Network : $i not found !" + fi + + echo + echo "Build : $NETWORK_DIR" + + [ ! -r $NETWORK_DIR/build ] && error "$NETWORK_DIR/build script not found !" + + if [ $EDIT = 1 ]; then + if [ -w $NETWORK_DIR/build ]; then + cp $NETWORK_DIR/build $NETWORK_DIR/.build.save + $EDITOR $NETWORK_DIR/build + if diff -q $NETWORK_DIR/build $NETWORK_DIR/.build.save > /dev/null; then + rm $NETWORK_DIR/.build.save + echo "No modification !" + exit + fi + rm $NETWORK_DIR/.build.save + else + echo "En lecture seule !" + sleep 2 + $EDITOR $NETWORK_DIR/build + exit + fi + rm $NETWORK_DIR/.build.save + fi + + if [ -w $NETWORK_DIR ]; then + ( + cd $NETWORK_DIR + rm -f *.conf + . build + echo "Create \"$(basename $NETWORK_DIR)\" config files..." + echo + build && echo && vdn-graph + touch $(readlink -f $NETWORK_DIR)/network.vdn + ) + else + echo "$NETWORK_DIR not writable !" >&2 + + fi + +done diff --git a/vdn/bin/vdn-busy.rb b/vdn/bin/vdn-busy.rb new file mode 100755 index 0000000..2f0f722 --- /dev/null +++ b/vdn/bin/vdn-busy.rb @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby + +require 'gtk2' + +$cpt=0 + +window = Gtk::Window.new + +window.modal=true +window.set_default_size(640, 140) +#window.signal_connect("delete_event") { +# puts "delete event occurred" +# #true +# false +#} + +window.signal_connect("destroy") { + puts "destroy event occurred" + Gtk.main_quit +} + +window.add(Gtk::Label.new("Load network description... Be patient !")) + +window.show_all + +Gtk.timeout_add(200) { + $cpt=$cpt+1 + if $cpt > 2 + r=system("ps auwx | grep -v grep | grep -q 'ruby.*vdn-gui'") + if r==true + Gtk.main_quit + end + end + true +} + +Gtk.main diff --git a/vdn/bin/vdn-clean b/vdn/bin/vdn-clean new file mode 100755 index 0000000..4b751e4 --- /dev/null +++ b/vdn/bin/vdn-clean @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +set -eu + +FORCE=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-f] system +EOF +} + +help() { + cat << EOF + +`basename $0` supprime les modifications d'un système. + +`synopsis` + +-h : affiche cette aide +-f : pas de demande de confirmation + +Remarque : Les fichiers seront regénérés (vides) au prochain + demarrage de la machine. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hf" opt; do + case $opt in + h) help; exit 0;; + f) FORCE=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + GUEST_NAMES="$@" + [ -z "$GUEST_NAMES" ] && usage || : + +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +SAVE_FILES="" + +for i in $GUEST_NAMES; do + loadGuestVars $i + + [ -n "$SAVE_FILE" ] && { + [ -e $SAVE_FILE ] && \ + SAVE_FILES="$SAVE_FILES $SAVE_FILE" || : + } || : + + [ -n "$HDB" ] && { + set +u + [ -z "$SAVE_DIR_HDB" ] && SAVE_DIR_HDB=$SAVE_DIR + set -u + + [ -e $SAVE_DIR_HDB/$HDB ] && \ + SAVE_FILES="$SAVE_FILES $SAVE_DIR_HDB/$HDB" || : + } || : +done + +if [ -n "$SAVE_FILES" ]; then + + if [ $FORCE = 0 ]; then + echo -e "Supprimer ? :" + for i in $SAVE_FILES; do + du -h $i + done + msg="Supprimer tous les fichiers ?" + request "$msg" + [ $? != 0 ] && exit || : + fi + + echo + rm -f $SAVE_FILES + echo "rm -f $SAVE_FILES" + +else + echo "No files to clean !" >&2 + sleep 1 +fi + diff --git a/vdn/bin/vdn-clean-network b/vdn/bin/vdn-clean-network new file mode 100755 index 0000000..5d2971d --- /dev/null +++ b/vdn/bin/vdn-clean-network @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +networkDir="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [networkDir] +EOF +} + +help() { + cat << EOF + +`basename $0` supprime le répertoire des sauvegardes du réseau. + +ATTENTION : aucune demande ne confirmation. + +`synopsis` + +-h : affiche cette aide. + +Si networkDir n'est pas précisé, le répertoire des sauvegardes du réseau +défini par la variable NETWORK_DIR est supprimé. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -eq 1 ] && { networkDir=$1; shift; } + [ $# -ne 0 ] && usage; +} + +# main + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ -n "$networkDir" ] && NETWORK_DIR="$networkDir" + +netname=$(basename $NETWORK_DIR) + +rm -Rf $SAVE_PATH/$netname diff --git a/vdn/bin/vdn-clone-network b/vdn/bin/vdn-clone-network new file mode 100755 index 0000000..be74c2e --- /dev/null +++ b/vdn/bin/vdn-clone-network @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +#set -x + +NEW="" + +networkName="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-n existingNetworkName] [newNetworkName] + +EOF +} + +help() { + cat << EOF + +`basename $0` clone le réseau courant (ou celui précisé par l'option -n). + +`synopsis` + +-h : affiche cette aide. +-n : réseau à cloner. + +Si newNetwork n'est pas précisé, il sera demandé sur l'entrée standard. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hn:" opt; do + case $opt in + h) help; exit 0;; + n) networkName="$OPTARG";; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -eq 1 ] && { NEW=$1; shift; } + [ $# -ne 0 ] && usage; +} + +# main + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ -n "$networkName" ] && NETWORK_DIR="$VDN_NETWORKS_BASE_DIR/$networkName" + +export VDN_PATH + +while [ -z "$NEW" ]; do + echo -n "Nom destination : " + read NEW +done + +echo "clone : $NETWORK_DIR to $NEW" +new=$(dirname $NETWORK_DIR)/$NEW +[ -d $new ] && error "Le réseau $NEW existe déja !" || : +cp -a $NETWORK_DIR $new + diff --git a/vdn/bin/vdn-config b/vdn/bin/vdn-config new file mode 100755 index 0000000..47d2bd1 --- /dev/null +++ b/vdn/bin/vdn-config @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +set -eu + +ADD=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-a] system variable [value] +EOF +} + +help() { + cat << EOF + +`basename $0` affiche ou modifie une variable de configuration d'un système. + +`synopsis` + +Le fichier de configuration d'un système contient des définitions de variables. + +Si l'argument value n'est pas précisé, cette commande affiche la valeur +de la variable. + +Si l'argument value est précisé, cette commande fixe la valeur de la variable. + +-h : affiche cette aide +-a : ajoute un espace puis la valeur précisée à la valeur courante. + + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "ha" opt; do + case $opt in + h) help; exit 0;; + a) ADD=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + if [ $# -ne 2 ] && [ $# -ne 3 ]; then + usage + fi + + GUEST_NAME="$1" + VAR=$2 + GET=1 + [ $# = 3 ] && { GET=0; VALUE=$3; } + + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi +} + +getValue() { + local file="$1" var="$2" v + v="`cat "$1" | grep "^$var=" | sed -ne 's/^[^=]*="\([^"]*\)".*$/\1/p'`" + [ -z "$v" ] && \ + v="`cat "$1" | grep "^$var=" | sed -ne 's/^[^=]*=\([^ ]*\).*$/\1/p'`" + echo "$v" +} + + + +setValue() { + local file="$1" var="$2" value="$3" + + shift 2 + + cat $file | gawk -v value="$@" -e ' +BEGIN { + found=0 +} + +/^'$var'=/ { + found=1 + print "'$var'=\""value"\"" + next + } + + { print } + +END { if(found==0) print "'$var'=\""value"\"" } + ' > $file.tmp + + mv $file.tmp $file +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + + +GUEST_CONF=$NETWORK_DIR/$GUEST_NAME.conf + +if [ $GET = 1 ]; then + GUEST_OWNER=$USER + loadGuestVars $GUEST_NAME + getValue $GUEST_CONF $VAR +else + if [ $ADD = 1 ]; then + GUEST_OWNER=$USER + loadGuestVars $GUEST_NAME + v=$(getValue $GUEST_CONF $VAR ) + VALUE="$v $VALUE" + fi + setValue $GUEST_CONF $VAR "$VALUE" +fi + diff --git a/vdn/bin/vdn-create-slash b/vdn/bin/vdn-create-slash new file mode 100755 index 0000000..05a9796 --- /dev/null +++ b/vdn/bin/vdn-create-slash @@ -0,0 +1,306 @@ +#!/usr/bin/env bash + +set -eu + +VDN_PATH=$(readlink -f $(dirname $(whereis vdn| cut -d ' ' -f 2))/..) +REVERSE=0 +TRACE=0 +export SLASH=$VDN_PATH/slash + +help() { + cat << EOF + +`basename $0` create slash directoty. + +`synopsis` + +-h : affiche cette aide +-t : lance vdn en mode trace. La capture est placée dans /tmp/vdn.trace (*) +-r : replace par un shebang classique. + +(*) le fichier capture (/tmp/vdn.trace) est utilisé s'il existe par `basename $0`. + +EOF +} + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-r] + `basename $0` -t +EOF +} + +usage() { + synopsis + exit 2 +} + + + +args() { + local opt + while getopts "hrt" opt; do + case $opt in + h) help; exit 0;; + r) REVERSE=1;; + t) TRACE=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) +} + + + +getTrace() { + strace -f -e trace=file $@ 2>&1 | \ + egrep -v 'ENOENT|unfinished|resumed|attached|exited|SIG' | \ + sed -re 's/^.*"(.*)".*$/\1/' | \ + grep -v $VDN_PATH | \ + grep -v $HOME | \ + egrep '^/' | \ + egrep -v '^/proc|^/etc|^/var|^/tmp/|^/run/|^/sys/|^/dev|^.$' | \ + egrep -v '^/home|^/tmp' | \ + sort -u > /tmp/trace.vdn +} + +copy() { + + s=$SLASH + r='^#' + while read f; do + [ -z "$f" ] && continue + [[ $f =~ $r ]] && continue + #[ $f = "/bin/bash" ] && continue + [ -d $f ] && continue + [ -f $f -o -L $f ] || { + echo "copy : BAD : $f" + continue + } + + #echo ":$f" + + d=$(dirname $f) + [ ! -d $s/$d ] && mkdir -p $s/$d || : + cp -a $f $s/$d || : + + if [ -L $f ]; then + dst=$(readlink $f) + if [[ $dst =~ ^/ ]]; then + echo "ABS ($f) > $dst" + n=$(($(echo $f | sed -re 's/[^/]//g' | wc -c) -2)) + p=$(ruby -e "puts \"../\"*$n") + b=$(basename $f) + rm $s/$d/$b + #ln -sf $s/$dst $s/$d/$b + ln -sf $p/$dst $s/$d/$b + echo $dst | copy + elif [[ $dst =~ ^/ ]]; then + echo "REL ($f) > $dst" + echo $dst | copy + else + echo $d/$dst | copy + fi + fi + #echo "==> $f" + done +} + +findLibIte() { + local i e + + while :; do + + e=${ALL[$N]} + + [ -z "$e" ] && break + + for i in $(ldd $e | grep '=>' | sed -re 's/.*=> *([^ ]*) .*$/\1/g'); do + [[ ${ALL[@]} =~ (^| )$i( |$) ]] && continue + ALL+=("$i") # push + echo -ne "Found lib dependencies: ${#ALL[@]} ...\r" >&2 + done + N=$((N+1)) + done + + echo "${ALL[@]}" +} + +findShebang() { + local shebang + find $VDN_PATH -type f | while read f; do + shebang=$(dd if=$f bs=1 count=2 2> /dev/null | tr '\0' '\n' ) + reg='#!' + [[ "$shebang" =~ $reg ]] && echo $f + done +} + +setShebang() { + local shebang + while read f; do + #echo "---" + #echo $f + shebang=$(cat $f 2> /dev/null | gawk -e '{ print; exit 0 }' | tr '\0' '\n' 2> /dev/null) + #echo $shebang + new=$(echo "$shebang" | sed -re 's/#! */#!/' | gawk -v SHEBANG=$SHEBANG -e ' +/env/ { print SHEBANG" "$2" "$3; exit } +{ sub(/^.*\//, "", $1); printf SHEBANG" "$1" "$2" "$3 ; exit } + ') + #echo "new=$new" + sed -i -re "1s,.*,$new," $f + + #sed -i -re '1s,(.*) -u,\1\n\nset -eu,' $f + #head -n 3 $f + done + } + +findElf() { + local elf + find $VDN_PATH/slash -type f | while read f; do + elf=$(dd if=$f bs=1 count=10 2> /dev/null | tr '\0' '\n' ) + reg='ELF' + [[ "$elf" =~ $reg ]] && echo $f + done +} + +setElf() { + while read f; do + + if ! patchelf --print-interpreter $f &> /dev/null; then + continue + fi + + echo "patch $f" + + patchelf --set-interpreter "/tmp/vdn-slash/lib/x86_64-linux-gnu/ld-2.24.so" $f + done + + } + + + depends() { + rm -Rf $SLASH + mkdir $SLASH + + rm -f /tmp/vdn-list-cmd + + [ -e /tmp/vdn.trace ] && { + echo "Read trace" + cat /tmp/vdn.trace >> /tmp/vdn-list-cmd + } + + echo "Scan commands" + + vdn-find-commands >> /tmp/vdn-list-cmd + + echo "Add manual dependencies" + + cat << EOF >> /tmp/vdn-list-cmd +/bin/bash + +/bin/ls +/bin/sh +/bin/dash + +/usr/bin/less +/usr/bin/strace + +/usr/bin/vim.gtk +/usr/bin/ldd +/usr/bin/basename + +/usr/bin/xclock +/usr/bin/xauth + + +/lib/x86_64-linux-gnu/libreadline.so.7 + +/usr/bin/gdk-pixbuf-query-loaders + +/usr/share/gir-1.0/Gio-2.0.gir +/lib64/ld-linux-x86-64.so.2 +/usr/bin/python2.7 +/usr/bin/python2.7-config +/lib/x86_64-linux-gnu/libaudit.so.1 +/lib/x86_64-linux-gnu/libpcre.so.3 +/lib/x86_64-linux-gnu/libprocps.so.6 +/lib/x86_64-linux-gnu/libselinux.so.1 +/lib/x86_64-linux-gnu/libtinfo.so.5 +/lib/x86_64-linux-gnu/libtinfo.so.5.9 +/lib/x86_64-linux-gnu/libnss_dns.so.2 + +/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.so +EOF + + echo "Find dependencies..." + + #echo "/bin/bash" > /tmp/vdn-list-cmd + + #cat /tmp/vdn-list-cmd + + cat /tmp/vdn-list-cmd | sort -u | { + declare -a ALL + N=0 + + while read l; do + [[ "$l" =~ ^[[:space:]]*$ ]] && continue + [[ "$l" =~ ^[[:space:]]*# ]] && continue + ALL+=("$l") # push + done + + N=0 + + while :; do + + set +u + e=${ALL[$N]} + set -u + + [ -z "$e" ] && { break; } + + for i in $(ldd $e 2> /dev/null | grep '=>' | sed -re 's/.*=> *([^ ]*) .*$/\1/g'); do + [[ ${ALL[@]} =~ (^| )$i( |$) ]] && continue + ALL+=("$i") # push + #echo -e "Found lib dependencies ${#ALL[@]} : $i ...\r" >&2 + done + N=$((N+1)) + done + echo ${ALL[@]} | tr ' ' '\n' | sort -u > /tmp/vdn-list-files + } + + } + + + # main + + args "$@" + + [ $REVERSE = 1 ] && { + SHEBANG="#!/usr/bin/env" + echo "Reverse shebang : $SHEBANG" + SHEBANG="#!/usr/bin/env"; findShebang | setShebang $SHEBANG + exit + } + + [ $TRACE = 1 ] && { + + getTrace $@ + + exit + } + + + SHEBANG="#!/tmp/vdn-slash/usr/bin/env" + + depends + echo "Copy..."; cat /tmp/vdn-list-files | copy + echo "Patch shebang"; findShebang | setShebang $SHEBANG + echo "Patch elf"; findElf | setElf + + echo "Update pixbuf loader module file" + [ ! -d $VDN_PATH/slash/usr/lib/gdk-pixbuf-2.0/2.10.0/ ] && mkdir -p $VDN_PATH/slash/usr/lib/gdk-pixbuf-2.0/2.10.0/ + gdk-pixbuf-query-loaders $VDN_PATH/slash/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/* |\ + sed -re "s,$VDN_PATH/slash,/tmp/vdn-slash,"> $VDN_PATH/slash/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache + #gdk-pixbuf-query-loaders $VDN_PATH/slash/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/* > $VDN_PATH/slash/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders.cache + + diff --git a/vdn/bin/vdn-delete b/vdn/bin/vdn-delete new file mode 100755 index 0000000..232e1df --- /dev/null +++ b/vdn/bin/vdn-delete @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` supprime le fichier de configuration du système. + +`synopsis` + +-h : affiche cette aide + +ATTENTION : aucune demande de confirmation n'est demandée ! + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +isDefined $GUEST_NAME || exit 0 + +setGuestVars $GUEST_NAME + +rm $GUEST_CONF + diff --git a/vdn/bin/vdn-delete-disks b/vdn/bin/vdn-delete-disks new file mode 100755 index 0000000..db79fc7 --- /dev/null +++ b/vdn/bin/vdn-delete-disks @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +set -eu + +FORCE=0 +LIST="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-f] system... +EOF +} + +help() { + cat << EOF + +`basename $0` supprime les disques associés au(x) système(s). + +`synopsis` + +Les disques HDA, HDB et CDROM du système présents dans le répertoire "files" +sont supprimés. + +-h : affiche cette aide +-f : force : pas de demande de confirmation ! + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hf" opt; do + case $opt in + h) help; exit 0;; + f) FORCE=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -lt 1 ] && usage + + for i; do + GUEST_NAME="$i" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi + + HDA=""; HDB=""; CDROM="" + loadGuestVars $GUEST_NAME + LIST="$LIST $HDA $HDB $CDROM" + + done +} + +deleteDisks() { + + for b in $LIST; do + #b=$(basename $i) + if [ -e $VDN_PATH/files/$b ]; then + echo "Suppression de $VDN_PATH/files/$b" + if [ $FORCE = 1 ]; then + rm -f $VDN_PATH/files/$b + else + rm -i $VDN_PATH/files/$b + fi + fi + done +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +deleteDisks diff --git a/vdn/bin/vdn-delete-network b/vdn/bin/vdn-delete-network new file mode 100755 index 0000000..d17cb12 --- /dev/null +++ b/vdn/bin/vdn-delete-network @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +#set -x + +NEW="" +FORCE=0 + +networkDir="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-f] networkDir + +EOF +} + +help() { + cat << EOF + +`basename $0` supprime le réseau. + +`synopsis` + +-h : affiche cette aide. +-f : PAS de demande de confirmation ! + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hf" opt; do + case $opt in + h) help; exit 0;; + f) FORCE=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -eq 1 ] && { networkDir=$1; shift; } + [ $# -ne 0 ] && usage; +} + +# main + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ -n "$networkDir" ] && NETWORK_DIR="$networkDir" + +export VDN_PATH + + +echo "DETETE $NETWORK_DIR" +echo + +if [ $FORCE = 0 ]; then + msg=$(echo -e "Supprimer:\n$NETWORK_DIR" | tr -s ' ' '\n') + request "$msg" + [ $? != 0 ] && exit || : + fi + + + +[ -d $NETWORK_DIR ] && rm -Rf $NETWORK_DIR || : + diff --git a/vdn/bin/vdn-diff b/vdn/bin/vdn-diff new file mode 100755 index 0000000..93ebf14 --- /dev/null +++ b/vdn/bin/vdn-diff @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +set -eu + +TMP1="/tmp/vdn-dir1" +TMP2="/tmp/vdn-dir2" +TMP="/tmp/vdn-dir" +EXCLUDES="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] dir1 dir2 +EOF +} + +help() { + cat << EOF + +`basename $0` affiche les différences dans les archives des modifications. + +dir1 et dir2 doivent contenir les archives des modifications des systèmes. + +Exemple : `basename $0` ~/.vdn-0.7.bak/demo ~/.vdn-0.7/demo + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + + shift $(($OPTIND - 1)) + [ $# -ne 2 ] && usage + + DIR1=$1 + DIR2=$2 +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ ! -d "$DIR1" ] && usage +[ ! -d "$DIR2" ] && usage + + +l1=$(cd $DIR1; ls *.tgz) +l2=$(cd $DIR2; ls *.tgz) +l=$(echo "$l1 $l2" | tr " " '\n' | sort -u | tr '\n' ' ') + +for i in $l; do + echo + echo "#------------------------------------------------------------" + echo "### $i" + echo "#------------------------------------------------------------" + echo + + if [ ! -e $DIR1/$i ]; then + echo "error : $DIR1/$i absent" + continue + fi + if [ ! -e $DIR2/$i ]; then + echo "error : $DIR2/$i absent" + continue + fi + + rm -Rf $TMP1 $TMP2 + mkdir $TMP1 $TMP2 + tar -C $TMP1 -xzf $DIR1/$i 2> /dev/null + tar -C $TMP2 -xzf $DIR2/$i 2> /dev/null + + for f in $EXCLUDES; do + rm -Rf $TMP1/$f; rm -Rf $TMP2/$f + done + + diff -Bru $TMP1 $TMP2 2> /dev/null || true + +done + +echo "### END ###" diff --git a/vdn/bin/vdn-doc b/vdn/bin/vdn-doc new file mode 100755 index 0000000..2ff95f9 --- /dev/null +++ b/vdn/bin/vdn-doc @@ -0,0 +1,139 @@ +#!/usr/bin/env bash + +set -eu + + +VDN_PATH=$(readlink -f $(dirname $0)/..); + +synopsis() { + cat << EOF +Usage : $(basename $0) [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` extrait la documentation à partir de l'aide des commandes. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage || : + +} + + +scan() { + cd $VDN_PATH/bin + for i in *; do + + [[ $i =~ .rb$ ]] && continue + [[ $i =~ .sh$ ]] && continue + + [ ! -f $i ] && continue + + [ ! -x $i ] && continue + + echo "=== $i ===" + $i -h + echo + + done +} + + +args $@ + +#scan + +doc() { + echo "=== $1 ===" + echo -n "" + $1 -h + echo "" + echo +} + +cat << EOF > /tmp/doc.txt + +===== Liste des commandes VDN ==== + +==== Pour l'administrateur ==== + +$(doc vdn-prepare) + +==== Pour l'utilisateur ==== + +$(doc vdn-clean) +$(doc vdn-download-disks) +$(doc vdn-halt) +$(doc vdn-infos) +$(doc vdn-kill) +$(doc vdn-list) +$(doc vdn-start) + +==== Pour le développeur (de disques et de réseaux) ==== + +$(doc vdn-build-network) +$(doc vdn-clean-network) +$(doc vdn-delete-disks) +$(doc vdn-delete) +$(doc vdn-scp) +$(doc vdn-ssh) +$(doc vdn-ssh-copy-id) +$(doc vdn-ssh-loop) + + +==== Non classées ==== + +$(doc vdn-alive) +$(doc vdn-alives) +$(doc vdn-build) +$(doc vdn-config) +$(doc vdn-create-slash) +$(doc vdn-diff) +$(doc vdn-doc) +$(doc vdn-graph) +$(doc vdn-kvm) +$(doc vdn-mount-chroot) +$(doc vdn-open-network) +$(doc vdn-push) +$(doc vdn-restart) +$(doc vdn-save) +$(doc vdn-scripts) +$(doc vdn-set-network-dir) +$(doc vdn-set-var) +$(doc vdn-shell) +$(doc vdn-show) +$(doc vdn-ssh-loop) +$(doc vdn-start-wrapper) +$(doc vdn-terminal) +$(doc vdn-test) +$(doc vdn-test-kvm) +$(doc vdn-upload-disks) +$(doc vdn-vnc-viewer) + +EOF + +cat /tmp/doc.txt + + diff --git a/vdn/bin/vdn-docker b/vdn/bin/vdn-docker new file mode 100755 index 0000000..1336158 --- /dev/null +++ b/vdn/bin/vdn-docker @@ -0,0 +1,183 @@ +#!/bin/bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` démarre la machine virtuelle debian-1 du réseau virtualMachines. + +La commande ~vdn/vdn/bin/vdn est une alternative graphique à ce script. + +`synopsis` + +-h : affiche plus d'aide + +EOF +} + +helpStart() { + + cat << EOF + +Pour vous connecter en tant qu'utilisateur test sur debian-1 : + + vdn-ssh -X test@debian-1 # -X : pour recevoir les fenêtres graphiques de debian-1. + +Pour vous connectez root : + + vdn-ssh -X root@debian-1 # -X : pour recevoir les fenêtres graphiques de debian-1. + +Pour arrêter la machine virtuelle : + +vdn-halt debian-1 # ou la commande (root) "poweroff" dans votre machine virtuelle. + +Si la machine ne réponds pas : + +vdn-kill debian-1 # ARRÊT BRUTAL : équivalent à une coupure électrique ! + +Pour un écran graphique (VNC) de la debian-1 : + +vous devrez fixer un mot de passe à l'utilisateur (commande passwd). + +vdn-viewer debian-1 + +`basename $0` -h pour plus d'aide (vdn-scp, vdn-sshfs, ...). + +EOF +} + +helpWarning() { + +cat << EOF + +** AVERTISSEMENT ** + +Vous êtes l'administrateur unique de vos machines virtuelles ! + +En tant qu'administrateur vous avez la charge de leur intégrité ! + +Ce système est une Debian buster classique avec authentification ssh par clés. + +L'authentification ssh par clés, uniquement active par défaut pour +l'utilisateur propriétaire de la machine virtuelle, permet de ne pas avoir +à connaitre les mots de passes (générés initialement aléatoirement). + +Vous pouvez changer les mots de passe mais, votre machine virtuelle étant +connectée au réseau pédagogique et à Internet (via le proxy du réseau +pédagogique si ce dernier est ouvert), choisissez de bons mots de passe ! + +**************************************************************************** +N'utilisez pas et ne stockez pas de mots de passe (ou tout autre information +"sensible") provenant du monde "réel" dans vos machines virtuelles ! +**************************************************************************** + +EOF + +echo -n "Appuyez sur la touche Entrée pour la suite "; read resp + +} + +helpPlus() { + +cat << EOF + + +** Informations ** + +Les commandes vdn-* disposent toutes d'une documentation intégrée obtenue +avec l'option -h. + +Outre la commande vdn-ssh déjà présentée plus haut, les commandes suivantes +vont cous permettre de "joindre" votre machine virtuelle à partir de l'hôte : + +vdn-scp : effectue un scp à partir ou à destination d'un système virtuel. +vdn-sshfs : monte un répertoire du système virtuel dans un répertoire de l'hôte. +vdn-ssh-copy-id : copie une clé publique dans un système virtuel. + +Appliquez l'option -h à une de ces commandes pour un exemple. + +EOF + +cat << EOF + + +** Notes ** + +La documentation générale sur VDN, est accessible ici : +https://opale.u-clermont1.fr/info/wiki/doku.php?id=public:vdn:start + +S'il vous reste de la place sur le disque de votre machine virtuelle (df -h), +n'hésitez pas à installer, dans un cadre pédagoqique, les paquets/logiciels +de votre choix. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; helpStart; helpPlus; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ -n "$*" ] && usage || : + +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)); . $VDN_PATH/bin/functions.sh + +args "$@" + +n="debian-1" + +if vdn-alive $n; then + helpStart + error "Le système virtuel $n est déjà lancé !" +fi + +helpWarning + +vdn-set-network-dir $VDN_PATH/networks/virtualMachines + +vdn -t # test host + +echo +echo -n "vdn-start debian-1 " + +vdn-start -b -v "KVM_VIEWER_AUTOSTART=0" debian-1 + +cpt=0 +while ! vdn-ssh -n -o ConnectTimeout=1 root@debian-1 exit 0 2> /dev/null; do + echo -n "." + cpt=$(($cpt+1)) +done + +echo "( $cpt sec.)" + +echo "Démarrage du service docker..." + +vdn-scripts -n startDocker &> /dev/null +r=$? + +helpStart + +[ $r -ne 0 ] && warning "Echec du démarrage de docker". + +echo "debian-1 démarrée !" + diff --git a/vdn/bin/vdn-download-disks b/vdn/bin/vdn-download-disks new file mode 100755 index 0000000..b08fca4 --- /dev/null +++ b/vdn/bin/vdn-download-disks @@ -0,0 +1,237 @@ +#!/usr/bin/env bash + +set -eu + +set -x + +DRY=0 +SYSTEMS="" +FORCE=0 +DDISK=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-hdf] system... + `basename $0` -t disk +EOF +} + +help() { + cat << EOF + +`basename $0` télécharge les disques associés au(x) système(s). + +`synopsis` + +Les disques utilisés par les systèmes spécifiés sont téléchargés. + +Remarque : les fichiers "*.disk.gz" sont automatiquement decompressés. + +-h : affiche cette aide +-d : dry run +-f : pas de demande de confirmation + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hdft" opt; do + case $opt in + h) help; exit 0;; + d) DRY=1;; + f) FORCE=1;; + t) DDISK=1;; + ?) usage;; + esac + done + shift $(($OPTIND-1)) + SYSTEMS=$@ + if [ -z "$SYSTEMS" ]; then + SYSTEMS=$(vdn-list | grep -v '^#') + fi + #[ $# -lt 1 ] && usage +} + +download() { + + local i + + echo "start download func" + + + for i in $@; do + + echo "loop" + file=$(basename $i .gz) + echo "file:$file" + if [[ $i =~ \.gz ]]; then + if [ $DRY = 1 ]; then + echo "Dry run : download $i" + else + echo "Download to $VDN_PATH/files/$file..." + wget -c -O - $i | { gzip -d -c || error "Problème de téléchargement"; } | \ + dd of=$VDN_PATH/files/$file conv=sparse bs=512 || \ + error "Problème de téléchargement" + fi + if [ "$(stat -c %s $VDN_PATH/files/$file)" = "0" ]; then + error "Problème de téléchargement" + fi + + else + echo "no gz" + if [ $DRY = 1 ]; then + echo echo "Dry run : download $i" + else + wget -c -O $VDN_PATH/files/$file $i + fi + fi + done +} + +downloadDisks() { + + local error=0 absent=0 r + + LIST="" + LIST_DISKS="" + + # find all files (uniq) + + for i; do + GUEST_NAME="$i" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi + + DISKS_REPOSITOY=""; + CDROM_REPOSITORY=""; + HDA=""; HDB=""; CDROM=""; BOOT_CDROM="0"; + KERNEL=""; INITRAMFS="" + + loadGuestVars $GUEST_NAME + + [ "$MODE" = "tgz" ] && { + [ -n "$KERNEL" ] && LIST="$LIST $DISKS_REPOSITORY/$KERNEL" + [ -n "$INITRAMFS" ] && LIST="$LIST $DISKS_REPOSITORY/$INITRAMFS" + } + + #[ -n "$CDROM" -a "$BOOT_CDROM" = 1 ] && + [ -n "$CDROM" ] && \ + LIST="$LIST $CDROM_REPOSITORY/$CDROM" + + [ -n "$HDA" ] && LIST_DISKS="$LIST_DISKS $DISKS_REPOSITORY/$HDA.gz" + [ -n "$HDB" ] && LIST_DISKS="$LIST_DISKS $DISKS_REPOSITORY/$HDB.gz" + + done + + #set -x + LIST_DISKS=$(echo $LIST_DISKS | tr -s ' ' '\n' | sort -u | grep -v '^$') + LIST=$(echo $LIST | tr -s ' ' '\n' | sort -u | grep -v '^$' || :) + + LIST="$LIST $LIST_DISKS" + + #echo "LIST :" + #echo $LIST | tr -s ' ' '\n' + + # test dates + + LIST_DOWNLOAD="" + + for i in $LIST; do + file=$(basename $i .gz) + locDate=0 + [ -e $VDN_PATH/files/$file ] && \ + locDate=$(stat -c %Y $VDN_PATH/files/$file) + + set +e + reInfos="$(wget --spider -S $i 2>&1)" + r=$? + set -e + + if [ $r -ne 0 ]; then + warning "$(basename $i) not found on server !" + error=1 + [ ! -e $VDN_PATH/files/$file ] && absent=1 + continue + fi + + reDate=$(echo "$reInfos" | grep "Last-Modified:" | cut -d ':' -f 2-) + reDate=$(date -d "$reDate" +%s) + + #echo $locDate $reDate + + [ $locDate -lt $reDate ] && LIST_DOWNLOAD="$LIST_DOWNLOAD $i" + done + + if [ $error = 1 ]; then + if [ -n "$LIST_DOWNLOAD" ]; then + if [ $FORCE = 0 ]; then + request "Tous les fichiers ne peuvent être téléchargés !\nTélécharger quand même ceux qui peuvent l'être ?" + [ $? -ne 0 ] && exit 0 + fi + fi + fi + + + [ -n "$LIST_DOWNLOAD" ] && { + echo + echo "LIST_DOWNLOAD :" + echo + echo $LIST_DOWNLOAD | tr -s ' ' '\n' + echo + + NEW="" + + for i in $(echo $LIST_DOWNLOAD | tr -s ' ' '\n'); do + request "Télécharger le fichier : $i ?" + + [ $? -eq 0 ] && NEW="$NEW $i" || : + done + LIST_DOWNLOAD=$NEW + + } + + if [ -n "$LIST_DOWNLOAD" -a $FORCE = 0 ]; then + request "Télécharger les fichiers ?" + [ $? -ne 0 ] && exit 0 + fi + + + # download + + echo "LIST_DOWNLOAD:$LIST_DOWNLOAD" + download $LIST_DOWNLOAD + + echo "End of download" + + for i in $LIST; do + file=$(basename $i .gz) + if [ ! -e $VDN_PATH/files/$file ]; then + warning "$file absent" + absent=1 + fi + done + + [ $absent = 1 ] && error "Fichiers manquants" || : +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + + +args "$@" + +if [ $DDISK = 1 ]; then + download http://opale.u-clermont1.fr/vdn/files/$SYSTEMS +else + downloadDisks $SYSTEMS +fi diff --git a/vdn/bin/vdn-download-network b/vdn/bin/vdn-download-network new file mode 100755 index 0000000..e57b38b --- /dev/null +++ b/vdn/bin/vdn-download-network @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DRY=0 +SYSTEMS="" +FORCE=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-hdf] url +EOF +} + +help() { + cat << EOF + +`basename $0` télécharge le réseau. + +`synopsis` + +-h : affiche cette aide +-d : dry run +-f : pas de demande de confirmation + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hf" opt; do + case $opt in + h) help; exit 0;; + f) FORCE=1;; + ?) usage;; + esac + done + shift $(($OPTIND-1)) + [ $# -gt 1 ] && usage + [ $# -eq 1 ] && URL=$1 || URL="" +} + +download() { + + file=$(basename $URL .zip) + if [ $file.zip = $URL ]; then + URL="$DEFAULT_REPOSITORY/$file" + fi + + echo "file:$file" + + rm -f $TMPDIR/$file.zip + + wget -c -O $TMPDIR/$file.zip $URL + + if [ -e $VDN_NETWORKS_BASE_DIR/$file -a $FORCE = 0 ]; then + requestNo "Network exist ! Overwrite ?" + fi + + if [ $FORCE = 0 ]; then + request "Extract $file.zip ?" + fi + + ( cd $VDN_NETWORKS_BASE_DIR; rm -Rf $file; unzip -x $TMPDIR/$file.zip ) +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +if [ -z "$URL" ]; then + echo -n "URL (ex: http:truc.bidule/net.zip) : " + read URL +fi +download $URL diff --git a/vdn/bin/vdn-exec-in-fakechroot b/vdn/bin/vdn-exec-in-fakechroot new file mode 100755 index 0000000..630b16d --- /dev/null +++ b/vdn/bin/vdn-exec-in-fakechroot @@ -0,0 +1,27 @@ +#!/bin/bash + +FAKECHROOT_DIR=/tmp/vdn-fakechroot-$USER/part + +echo "FAKECHROOT_DIR:$FAKECHROOT_DIR" + +echo "Exec..." + +set -x + +export LD_LIBRARY_PATH=$FAKECHROOT_DIR/lib:$FAKECHROOT_DIR/usr/lib:$FAKECHROOT_DIR/usr/lib/x86_64-linux-gnu:/lib:/usr/lib:/usr/lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu:$FAKECHROOT_DIR/lib/x86_64-linux-gnu:$FAKECHROOT_DIR/usr/lib/x86_64-linux-gnu/pulseaudio:$FAKECHROOT_DIR/usr/lib/x86_64-linux-gnu:$FAKECHROOT_DIR/lib/x86_64-linux-gnu:$VDN_PATH/distribs/lib + +export LD_LIBRARY_PATH=$FAKECHROOT_DIR/lib:$FAKECHROOT_DIR/usr/lib:$FAKECHROOT_DIR/usr/lib/x86_64-linux-gnu:FAKECHROOT_DIR/lib/x86_64-linux-gnu:$FAKECHROOT_DIR/usr/lib/x86_64-linux-gnu/pulseaudio:$FAKECHROOT_DIR/usr/lib/x86_64-linux-gnu:$FAKECHROOT_DIR/lib/x86_64-linux-gnu:$VDN_PATH/distribs/lib + +export GIO_MODULE_DIR=$FAKECHROOT_DIR/usr/lib/x86_64-linux-gnu/gio + +#PATH="$FAKECHROOT_DIR/bin:$FAKECHROOT_DIR/usr/bin:$VDN_PATH/bin" + +#echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH +#echo PATH=$PATH + +echo "LD_LIBRARY_PATH:$LD_LIBRARY_PATH" + +echo "### before exec..." + +exec $* + diff --git a/vdn/bin/vdn-fakechroot b/vdn/bin/vdn-fakechroot new file mode 100755 index 0000000..07663d1 --- /dev/null +++ b/vdn/bin/vdn-fakechroot @@ -0,0 +1,149 @@ +#!/usr/bin/env bash + +set -eu + +UMOUNT=0; + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` monte (via fuse) le disque et configure fakechroot pour l'utiliser. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hu" opt; do + case $opt in + h) help; exit 0;; + u) UMOUNT=1;; + ?) usage;; + esac + done +} + +vdnUmount() { + + fusermount -u $FAKECHROOT_DIR/unionfs || : + fusermount -u $FAKECHROOT_DIR//unionfs-2/etc ||: + fusermount -u $FAKECHROOT_DIR//unionfs-2/home ||: + fusermount -u $FAKECHROOT_DIR//unionfs-2/tmp ||: + fusermount -u $FAKECHROOT_DIR/unionfs-1 || : + fusermount -u $FAKECHROOT_DIR/unionfs-2 || : + + fusermount -u $FAKECHROOT_DIR/part || : + fusermount -u $FAKECHROOT_DIR/offset || : +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +FAKECHROOT_DIR=/tmp/vdn-fakechroot-$USER + +if [ $UMOUNT = 1 ]; then + vdnUmount + exit $? +fi + +[ ! -d $FAKECHROOT_DIR/offset ] && mkdir -p $FAKECHROOT_DIR/offset || : +bbfs $VDN_PATH/files $FAKECHROOT_DIR/offset + +[ ! -d $FAKECHROOT_DIR/part ] && \ + mkdir $FAKECHROOT_DIR/part || : + +ext4fuse $FAKECHROOT_DIR/offset/DebianBuster-amd64.disk $FAKECHROOT_DIR/part -o allow_other + +[ ! -d $FAKECHROOT_DIR/unionfs-1 ] && mkdir -p $FAKECHROOT_DIR/unionfs-1 || : +unionfs -o max_files=64000 -o allow_other -o relaxed_permissions $FAKECHROOT_DIR/part=RW $FAKECHROOT_DIR/unionfs-1 +#rm -Rf $FAKECHROOT_DIR/unionfs-1/etc +# -o uid=1000 -o gid=1000 + +[ ! -d $FAKECHROOT_DIR/unionfs-2/etc ] && mkdir -p $FAKECHROOT_DIR/unionfs-2/etc || : +unionfs -o max_files=64000 -o allow_other,use_ino,suid,dev -o relaxed_permissions /etc=RW $FAKECHROOT_DIR/unionfs-2/etc + +[ ! -d $FAKECHROOT_DIR/unionfs-2/home ] && mkdir -p $FAKECHROOT_DIR/unionfs-2/home || : +unionfs -o max_files=64000 -o allow_other,use_ino,suid,dev -o relaxed_permissions /home=RW $FAKECHROOT_DIR/unionfs-2/home + +[ ! -d $FAKECHROOT_DIR/unionfs-2/tmp ] && mkdir -p $FAKECHROOT_DIR/unionfs-2/tmp || : +unionfs -o max_files=64000 -o allow_other,use_ino,suid,dev -o relaxed_permissions /tmp=RW $FAKECHROOT_DIR/unionfs-2/tmp + +[ ! -d $FAKECHROOT_DIR/unionfs ] && mkdir -p $FAKECHROOT_DIR/unionfs || : +##unionfs -o cow -o max_files=64000 -o allow_other,use_ino,suid,dev,nonempty /=RW:$FAKECHROOT_DIR/part=RO $FAKECHROOT_DIR/unionfs +set -x +unionfs -o cow -o max_files=64000 -o allow_other,use_ino,suid,dev -o relaxed_permissions \ + $FAKECHROOT_DIR/unionfs-2=RW:$FAKECHROOT_DIR/unionfs-1=RO $FAKECHROOT_DIR/unionfs + +#echo shell +#bash +#exit +echo fakechroot:$FAKECHROOT_DIR/unionfs + +fakechroot -s chroot $FAKECHROOT_DIR/unionfs /bin/bash -i + +echo Press Enter to umont +read + +vdnUmount + +#[ ! -d $FAKECHROOT_DIR/unionfs-home/home ] && mkdir -p $FAKECHROOT_DIR/unionfs-home/home || : +#unionfs -o cow -o max_files=64000 -o allow_other,use_ino,suid,dev,nonempty $FAKECHROOT_DIR/part=RO $FAKECHROOT_DIR/unionfs + + + +#ls $FAKECHROOT_DIR/part + +# config fakechroot + +#PATH="$PATH:/bin:/usr/bin" + +#export FAKECHROOT_DIR + +#DIR=$FAKECHROOT_DIR/part + +#export FAKECHROOT_EXCLUDE_PATH=/tmp:/proc:/dev:/sys:/var/run:/home:/etc/passwd + +#export LD=$DIR/lib:$DIR/usr/lib:$DIR/usr/lib/x86_64-linux-gnu:$DIR/lib/x86_64-linux-gnu:/lib:/usr/lib:/usr/lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu:$DIR/usr/lib/x86_64-linux-gnu/pulseaudio:$DIR/usr/lib/x86_64-linux-gnu:$DIR/lib/x86_64-linux-gnu:$VDN_PATH/distribs/lib + +#export GIO_MODULE_DIR=$DIR/usr/lib/x86_64-linux-gnu/gio + +#export LD_LIBRARY_PATH=$VDN_PATH/distribs/lib + +#echo "LD_LIBRARY_PATH:$LD_LIBRARY_PATH" + +#echo "### before fakechroot..." + +#echo "export LD_LIBRARY_PATH=$FAKECHROOT_DIR/part/lib/x86_64-linux-gnu" + + +#/usr/bin/fakechroot -s /usr/sbin/chroot $FAKECHROOT_DIR/part $VDN_PATH/bin/vdn-exec-in-fakechroot $@ +#/usr/bin/fakechroot -s /usr/sbin/chroot $FAKECHROOT_DIR/part /bin/bash -c "/bin/bash $VDN_PATH/bin/vdn" +#fakechroot /usr/sbin/chroot $FAKECHROOT_DIR/part /bin/bash + +#proot -r $FAKECHROOT_DIR/part /bin/bash + + + +#/usr/bin/fakechroot /usr/sbin/chroot $FAKECHROOT_DIR/part $VDN_PATH/bin/vdn-exec-in-fakechroot ls +#/usr/bin/fakechroot /usr/sbin/chroot $FAKECHROOT_DIR/part /bin/ls +#/usr/bin/fakechroot /bin/bash -c "/usr/sbin/chroot $FAKECHROOT_DIR/part $VDN_PATH/bin/vdn-exec-in-fakechroot $@" + + diff --git a/vdn/bin/vdn-fakechroot-umount b/vdn/bin/vdn-fakechroot-umount new file mode 100755 index 0000000..d38c949 --- /dev/null +++ b/vdn/bin/vdn-fakechroot-umount @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` démonte le disque. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +FAKECHROOT_DIR=/tmp/vdn-fakechroot-$USER + +fusermount -u $FAKECHROOT_DIR/part || : +fusermount -u $FAKECHROOT_DIR/offset || : + + + + + diff --git a/vdn/bin/vdn-find-ident.old b/vdn/bin/vdn-find-ident.old new file mode 100755 index 0000000..45eb4c1 --- /dev/null +++ b/vdn/bin/vdn-find-ident.old @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` affiche le premier identificateur libre pour un nouveau système. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage || : +} + +findIdent() { + local i=0 + local configs="`find $NETWORK_DIR -follow -type f -name \"*.conf\"`" + if [ -n "$configs" ]; then + for i in `seq 0 256`; do + if ! grep -Eq "^IDENT=$i([[:space:]]|$)" $configs; then + break + fi + done + if [ $i = 256 ]; then + error "Aucun identificateur disponible" + fi + fi + + echo $i +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +ident=`findIdent` + +echo $ident + + diff --git a/vdn/bin/vdn-fuse-proot b/vdn/bin/vdn-fuse-proot new file mode 100755 index 0000000..f7dbccf --- /dev/null +++ b/vdn/bin/vdn-fuse-proot @@ -0,0 +1,168 @@ +#!/usr/bin/env bash + +set -eu +#set -x + +DISK_NAME="DebianBuster-amd64.disk" +FOR_ROOT=0 +USE_SUDO=0 +UMOUNT=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-r] [-i user] [-s] [-u] +EOF +} + +help() { + cat << EOF + +`basename $0` exécute VDN dans un environnement proot en utilisant le disque : + +$DISK + +`synopsis` + +-h : affiche cette aide. +-u : démontages seulement. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hrsi:u" opt; do + case $opt in + h) help; exit 0;; + u) UMOUNT=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage || : +} + +vdnMountProotForRoot() { + + key="$(cat $TMPDIR/vdn-key-$USER)" + + disp=$(cat $TMPDIR/vdn-display-$USER) + + d=$TMPDIR/vdn-chroot-$USER; + + if [ $UMOUNT = 0 ]; then + + mount | grep -q $d || mount -o loop,offset=$((2048*512)) $DISK $d + + for i in /dev /dev/pts /sys /proc /tmp; do + mount | grep -q $d$i || { mount --bind $i $d$i; } + done + + mount --bind $VDN_PATH $d/home/test/vdn + + #mount | grep $d + + chroot $d su - -s /bin/bash -c "export DISPLAY=":"$disp; \ + unset XAUTHORITY; rm -rf /home/test/.config/xfce4-session; \ + rm -rf /home/test/.config/xfce4/terminal/; \ + xauth add \$DISPLAY . $key; \ + export NO_AT_BRIDGE=1; \ + xfce4-terminal --disable-server # 2> /dev/null;" test + + sleep 1 + fi + + for i in /tmp /proc /sys /dev/pts /dev; do + mount | grep -q $d$i && { umount $d$i || { echo "umount lazy : $d$i"; umount -l $d$i; } ; } || : + done + + mount | grep -q $d/home/test/vdn && { umount $d/home/test/vdn || umount -l $d/home/test/vdn; } || : + mount | grep -q $d && { umount $d || umount -l $d; } || : + + m="$(mount | grep $d)" + + echo $m +} + +vdnUmount() { + set +e + for i in $(mount | grep $TMPDIR/vdn-proot-$USER | cut -d ' ' -f 3 | tac); do + fusermount -u $i + done + set -e +} + +vdnMount() { + + [ ! -e $DISK ] && error "$DISK not found !" || : + + if [ ! -w $DISK ]; then + error "$DISK doit être accessible en écriture !" + fi + + + # get display + + if [ -z $DISPLAY ]; then + error "DISPLAY not set !" + fi + + (rm -f $TMPDIR/vdn-display-$USER; umask 077 ; touch $TMPDIR/vdn-display-$USER) + DISP=$(echo $DISPLAY | cut -d ':' -f 2 | cut -d '.' -f 1) + echo $DISPLAY | cut -d ':' -f 2 >> $TMPDIR/vdn-display-$USER + + # get xauth key + + key=$(xauth list| grep $(uname -n) | grep $DISP | tail -n 1 | tr -s ' ' | cut -d ' ' -f 3) + + [ -n "$key" ] || error "Xauth key is empty !" + echo $key | egrep -q '^[[:xdigit:]]+$' || error "Bad xauth key ($key) !" + + (rm -f $TMPDIR/vdn-key-$USER; umask 077 ; touch $TMPDIR/vdn-key-$USER) + + echo $key >> $TMPDIR/vdn-key-$USER + + # mount (fuse) + + # 1 : offset (2048*512) + d=$TMPDIR/vdn-proot-$USER; + [ ! -d $d/offset ] && mkdir -p $d/offset || : + $VDN_PATH/bin/bbfs $VDN_PATH/files $d/offset + + # 2 : mount part + [ ! -d $d/part ] && mkdir -p $d/part1 || : + $VDN_PATH/bin/ext4fuse $d/offset/$DISK_NAME $d/part1 + + # 3 : proot + # -b /etc/passwd -b /etc/group + proot -b /proc -b /dev -b /sys -b /dev/pts -b /home -b /tmp -b /etc \ + -r $d/part1 /bin/bash + + echo "Done" + + + +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +DISK=$VDN_PATH/files/$DISK_NAME + +args "$@" + +set -x + +if [ $UMOUNT = 0 ]; then + vdnUmount + trap vdnUmount 0 + vdnMount +else + vdnUmount +fi diff --git a/vdn/bin/vdn-get-network b/vdn/bin/vdn-get-network new file mode 100755 index 0000000..0795576 --- /dev/null +++ b/vdn/bin/vdn-get-network @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +set -eu + +CMD="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] command arg... +EOF +} + +help() { + cat << EOF + +`basename $0` retourne le nom du réseau courant. + +`synopsis` + +-h : affiche cette aide. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + [ $# -ne 0 ] && usage || : +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ ! -e $HOME/.vdnrc ] && touch $HOME/.vdnrc +. $HOME/.vdnrc +echo $NETWORK_DIR diff --git a/vdn/bin/vdn-graph b/vdn/bin/vdn-graph new file mode 100755 index 0000000..0f038ef --- /dev/null +++ b/vdn/bin/vdn-graph @@ -0,0 +1,252 @@ +#!/usr/bin/env bash + +ASCII=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-a] +EOF +} + +help() { + cat << EOF + +`basename $0` génère le graphe associé au réseau (graph.svgz). + +`synopsis` + +-h : affiche cette aide. +-a : ne génère pas le graphe dans le fichier mais sur stdout (en ASCII). + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "ha" opt; do + case $opt in + h) help; exit 0;; + a) ASCII=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage; +} + +toGnuplot() { + n=1 + echo "set term dumb" + while read; do + set - $REPLY + #echo $1 + case "$1" in + graph) scale=$2; width=$3; height=$4;; + node) name=$2; x=$3; y=$4 + echo "set label \"[$name]\" at $x, $y" + n=$(($n+1)) + ;; + + edge) n1=$2; n2=$3; n3=$4; x1=$5; y1=$6; + shift 10 + x2=$1; y2=$2 + echo "set arrow $n from $x1,$y1 to $x2,$y2 nohead " + name=$3; x=$5; y=$6 + echo "set label $name\" at $x, $y" + + n=$(($n+1)) + ;; + esac + done + + #echo "plot \"< echo '0 0'\"" + echo "set nokey" + echo "unset tics" + echo "unset border" + echo "set xrange [ 0 : $width ]" + echo "set yrange [ 0 : $height ]" + + echo "plot [0:$width] 0 with dot" + +} + +parse() { + + echo + echo -e "\t\"$1\" [ $guestProps ]" + ETH=0 + guest=$1 + [ "$networks" == '""' -o -z "$networks" ] && return 0 + set - $networks + for i; do + #set -x + net="$i" + + comment=$(echo $net | cut -d '#' -f 2) + net=$(echo $net | cut -d '#' -f 1) + [ "$net" = "$comment" ] && comment="" + + #net1=$(echo $net | sed -re 's/^.*NET_(.*)\(\$NET_.*\)$/\1/') + + #net1=$(echo $net | sed -re 's/\$NET_([0-9G]+).*/\1/') + #net2=$(echo $net | sed -nre 's/.*NET_.*NET_(.*)\)$/\1/p') + + net=$(echo $net | sed -re 's/.*NET_(.*)$/\1/') + + [ "$net" = "G" ] && net=0 + + #net=$(computeEthLink $GUEST_NAME $net2) + + #[ "$net1" = "G" ] && net1=0 + #[ "$net2" = "G" ] && net2=0 + #echo "$guest net:$net net1=$net1 net2=$net2" >&2 + #read + + #echo "net=$net." + #echo "comment=$comment" + #comment="" + + #net=$net1 + #[ -n "$net2" ] && net=$net2 + + case "$net" in + none) ;; + [0-9]*) + set +u + if [ -z "${switchs[$net]}" ]; then + switchs[$net]=1 + props=$switchProps + if [ "$net" = "0" ]; then + props=$(echo $switchProps | sed -re 's,switch,internet,g') + props="$props label=\"Internet\",width=\"0\",height=\"0\"" + else + props="$props width=\"0\",height=\"0\" label=\"$net\"" + fi + echo -e "\t$net [ $props ]" + fi + set -u + echo -e "\t\"$guest\" -> $net [ taillabel=\"eth$ETH $comment\" $edgeProps ]" + ;; + *) error "Eth error for $guest: $net" + esac + ETH=$(($ETH+1)) + + # ??? + #[ -n "$net2" ] && { + # connects["$net1 -> $net2"]=1 + #} + + + done + + + +} + +# main + +declare -A connects + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +export PATH="$VDN_PATH/bin:$PATH" + +. $VDN_PATH/allocators/$VDN_RESOURCES_ALLOCATOR + +args "$@" + +guestProps="shape=box style=solid color=lightgray" +#switchProps="shape=ellipse color=gray fontsize=8" +#switchProps="imagepath=\"$VDN_PATH/svg\", image=\"switch.svg\",width=\"100px\",height=\"100px\",imagepos=tc,fontsize=8,shape=none" +switchProps="fontsize=12 shape=none" + +edgeProps="labeldistance=4.0 len=1.8 fontsize=12 fontcolor=gray arrowhead=none" + +networkDir=$NETWORK_DIR + +echo "Build graph ($NETWORK_DIR/graph.svgz). " + +#IDENT=0; computeNetworks + +dot1=`mktemp` + +#set -x + +guests="`find $NETWORK_DIR -maxdepth 1 -follow -name "*.conf" | sort -R | \ + sed -re 's/^.*\/([^/]+).conf$/\1/'`" + +{ + echo "digraph {" + #echo "overlap=scale;" + #echo 'rankdir="LR"' + echo 'splines=true;' + echo 'nodesep=0.1;' + + + + #echo '1 -> 2 [style="invis"]' + for i in $guests; do + #loadGuestVars $i + unset networks + set -a + GUEST_NAME=$i + GUEST_OWNER=$USER + . $NETWORK_DIR/$i.conf + set +a + networks="$NETWORKS" + #networks=$(vdn-config $i NETWORKS) + + + parse $i + done + + for k in "${!connects[@]}"; do + echo "=> $k" >&2 + echo "$k [ arrowhead=none ]" + done + + + echo "}" +} > $dot1 + + +if [ $ASCII = 1 ]; then + + # obsolete + + #dot2=`mktemp` + #plain=`mktemp` + #gnuplot=`mktemp` + + #cat $dot1 | sed -re 's/taillabel/label/g' \ + # > $dot2 + + ##graph-easy --renderer neato --as ascii $dot2 + #graph-easy --as ascii $dot2 + + warning "ASCII = 1 is obsolete !" + + #neato -Tplain $dot2 > $plain + #cat $plain | toGnuplot > $gnuplot + + #gnuplot $gnuplot | sed -re 's/\.//g' | sed -re 's/[<>]/\./g' \ + # | sed -re 's/\[/'`echo -e "\033"`'\[1m/g' \ + # | sed -re 's/\]/'`echo -e "\033"`'\[22m/g' + + #rm -f $dot2 $plain $gnuplot + +else + neato -Tsvg $dot1 | iconv -t UTF-8 > $NETWORK_DIR/graph.svg + gzip $NETWORK_DIR/graph.svg + mv $NETWORK_DIR/graph.svg.gz $NETWORK_DIR/graph.svgz + echo "Done." + +fi + +#cp $dot1 /tmp/dot +rm -f $dot1 diff --git a/vdn/bin/vdn-gui.rb b/vdn/bin/vdn-gui.rb new file mode 100755 index 0000000..79fab55 --- /dev/null +++ b/vdn/bin/vdn-gui.rb @@ -0,0 +1,4127 @@ +#!/usr/bin/env ruby + +# encoding: UTF-8 +# coding: UTF-8 +# -*- coding: UTF-8 -*- + +#encoding: utf-8 + +require 'gtk2' +require 'rsvg2' +require 'socket' +require 'monitor' +require 'zlib' + +# pour debug + +$threads=[] +$currentNetName="" + +# Pour un usage des threads avec GTK +# http://ruby-gnome2.sourceforge.jp/hiki.cgi?cmd=view&p=tips_threads + +$home="https://opale.iut-clermont.uca.fr/info/wiki/doku.php?id=public:vdn:start" + +$lock=false + + +def setDefaultEditor + if ENV['NANO_EDITOR'] == "1"; then + $editor="nano" + else + #$editor=ENV['EDITOR'] + $editor="vi" #if $EDITOR == "" + end + ENV['EDITOR']=$editor +end + +setDefaultEditor + +#=begin +#p "[** MAIN prcess **] : #{Process.pid}" + +Thread.new { + while true + $main.setTitle if $main + sleep(3) + begin + #p "[**WAIT parent:#{Process.pid}**]}" + #Process.wait2(-1, Process::WUNTRACED) + Process.wait() + rescue => e + #p e + next + end + #p "[**RET parent:#{Process.pid}**] #{$?}" + end + +} +#=end + +=begin +trap("CLD") do + p "TRAP CLD begin" + begin + cpid = Process.wait + rescue StandardError => e + p e + end + + p "TRAP CLD end pid:#{cpid}" +end +=end + +def mySystem(cmd) + + #p "*** #{cmd[-1]}" + if cmd[-1] == "&" + cmd=cmd[0..-2] + end + #p "+++ #{cmd}" + + #Gtk.idle_add { + #system(cmd) + + #Thread.new { + # spawn(cmd) + #} + #return + + Thread.new { + + desc="mySystem" + $threads.push(desc) + + #p "[parent : #{Process.pid}] : fork : #{cmd}" + pid=spawn(cmd) + #pid=fork { + # p "[child : #{Process.pid} #{Process.ppid}] :exec : #{cmd}" + # exec(cmd) + #} + sleep(0.5) + Process.detach(pid) + $threads.delete_at($threads.index(desc)) + } + + # false + #} + #fork {system(cmd)} + #pid = fork { system(cmd) } + #Thread.new { + # puts "system:#{cmd}" + # pid = fork { system(cmd) } + # puts "system end" + #} +end + +module Gtk + GTK_PENDING_BLOCKS = [] + GTK_PENDING_BLOCKS_LOCK = Monitor.new + + def Gtk.queue &block + if Thread.current == Thread.main + block.call + else + GTK_PENDING_BLOCKS_LOCK.synchronize do + GTK_PENDING_BLOCKS << block + end + end + end + + def Gtk.main_with_queue timeout + + if $lock==false + Gtk.timeout_add timeout do + if $lock==false + begin + GTK_PENDING_BLOCKS_LOCK.synchronize do + for block in GTK_PENDING_BLOCKS + block.call + end + GTK_PENDING_BLOCKS.clear + end + rescue => e + p "$!" + puts e.backtrace + end + end + true + end + Gtk.main + end + end + +end + +# Gestion du graphique + +module Svg + + def svgInit + @white = Gdk::Color.parse("white") + @black = Gdk::Color.parse("black") + @grey = Gdk::Color.parse("grey") + @blue = Gdk::Color.parse("blue") + @red = Gdk::Color.parse("red") + @green = Gdk::Color.parse("green") + @yellow = Gdk::Color.parse("yellow") + @orange = Gdk::Color.parse("orange") + end + + def draw(area) + + return false if ! @gw + return false if ! @gh + + width=@gw + height=@gh + + a=area.allocation.to_a + aw=a[2]; ah=a[3] + + width=width+100+2*@bx; height=height+100+2*@by + + x=0; y=0 + + w0=(aw)-2*@bx; h0=(ah)-2*@by + + if width>w0 || height>h0 + width=w0; height=h0 + end + + w=width + h=height + + awin=area.window + @gc=Gdk::GC.new(awin) if !@gc && awin!=nil + + if @gc + gc=@gc + gc.fill = Gdk::GC::Fill::SOLID + gc.rgb_fg_color = @white + if awin!= nil + area.window.draw_rectangle(gc, true, 0, 0 , aw, ah) + end + end + + return if w-2*@bx<=0 || h-2*@by<=0 + + rw=w0*1.0/@gw; rh=h0*1.0/@gh + + if rw>rh + ratio=rh + else + ratio=rw + end + + ratio=1.2 if ratio > 1.2 + + begin + if ! @pixbuf + @pixbuf=nil + svg=RSVG::Handle.new_from_file(@graphfile) + surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, @gw*ratio, @gh*ratio) + context = Cairo::Context.new(surface) + context.scale(ratio, ratio); + context.render_rsvg_handle(svg) + file="#{ENV['TMPDIR']}/vdn-gui-#{ENV['USER']}-#{ENV['VDN_GUI_IDENT']}-graph" + context.target.write_to_png(file) + context.target.finish + @pixbuf=GdkPixbuf::Pixbuf.new(:file => file) + File.delete(file) + end + rescue + return + end + + return if ! @pixbuf + + pixbuf=@pixbuf + + w=pixbuf.width + h=pixbuf.height + + width=w; height=h + + dx=(w0-w)/2; dy=(h0-h)/2 + + area.window.draw_pixbuf(nil, pixbuf, 0, 0, x+@bx+dx, y+@by+dy, width, height, Gdk::RGB::DITHER_MAX, 0, 0) + + @x=x; @y=y; @w=w; @h=h; @w0=w0; @h0=h0; @dx=dx; @dy=dy; @w=w; @h=h + @width=width; @height=height + + @cx=@gw/w.to_f; @cy=@gh/h.to_f + @cx=1.0/@cx; @cy=1.0/@cy + + #drawBoxs + drawBoxs + updateSelect + #Gtk.idle_add { sleep 0.01; updateSelect; false; } + #drawSelRec + #updateSelRec + + true + end + +end + +class Preview + include Svg + + attr_reader :dx, :dy, :area, :gc + attr_reader :cx, :cy, :bx, :by + attr_reader :selColor + attr_reader :consoles, :combo + attr_accessor :hosts, :selection, :pixbuf + attr_accessor :lines, :graphfile + + + def initialize(main) + super() + @main=main + + @gc=nil + @drawed=false + @gw=@gh=nil + + svgInit + + @area = Gtk::DrawingArea.new + @area.set_size_request(640,480) + + @area.show + #@area.realize + + @area.signal_connect("expose-event") do |widget, event| + #p "expose...#{ENV['VDN_GUI_IDENT']} #{event} #{@area}" + load(@dir) if @dir + false + end + + @bx=20 + @by=20 + + end + + def draw(area) + #p "draw: #{area}" + end + + def load(dir) + #p "load:#{dir}" + + return if ! dir + @dir=dir if dir + + return if ! @dir + + if FileTest.exist?(@dir+"/net.svgz") && ENV['RAW_GRAPH']=="0" + @graphfile=@dir+"/net.svgz" + elsif FileTest.exist?(@dir+"/graph.svgz") + @graphfile=@dir+"/graph.svgz" + end + + begin + svg=RSVG::Handle.new_from_file(@graphfile) + svg.close + rescue + return + end + + @gw=svg.width + @gh=svg.height + #p "w: #{@gw} #{@gh}" + + return false if ! @gw + return false if ! @gh + + width=@gw + height=@gh + + area=@area + + a=area.allocation.to_a + aw=a[2]; ah=a[3] + + width=width+100+2*@bx; height=height+100+2*@by + + x=0; y=0 + + w0=(aw)-2*@bx; h0=(ah)-2*@by + + if width>w0 || height>h0 + width=w0; height=h0 + end + + w=width + h=height + + awin=area.window + @gc=Gdk::GC.new(awin) if !@gc && awin!=nil + + if @gc + gc=@gc + gc.fill = Gdk::GC::Fill::SOLID + gc.rgb_fg_color = @white + if awin!= nil + area.window.draw_rectangle(gc, true, 0, 0 , aw, ah) + end + end + + return if w-2*@bx<=0 || h-2*@by<=0 + + rw=w0*1.0/@gw; rh=h0*1.0/@gh + + if rw>rh + ratio=rh + else + ratio=rw + end + + ratio=1.2 if ratio > 1.2 + + #return + @pixbuf=nil + + begin + if ! @pixbuf + @pixbuf=nil + svg=RSVG::Handle.new_from_file(@graphfile) + surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, @gw*ratio, @gh*ratio) + context = Cairo::Context.new(surface) + context.scale(ratio, ratio); + context.render_rsvg_handle(svg) + file="#{ENV['TMPDIR']}/vdn-gui-#{ENV['USER']}-#{ENV['VDN_GUI_IDENT']}-graph" + context.target.write_to_png(file) + context.target.finish + @pixbuf=GdkPixbuf::Pixbuf.new(:file => file) + File.delete(file) + end + rescue + return + end + + return if ! @pixbuf + + #p "pixbuf:#{@pixbuf}" + + pixbuf=@pixbuf + + w=pixbuf.width + h=pixbuf.height + + width=w; height=h + + dx=(w0-w)/2; dy=(h0-h)/2 + + area.window.draw_pixbuf(nil, pixbuf, 0, 0, x+@bx+dx, y+@by+dy, width, height, Gdk::RGB::DITHER_MAX, 0, 0) + + @x=x; @y=y; @w=w; @h=h; @w0=w0; @h0=h0; @dx=dx; @dy=dy; @w=w; @h=h + @width=width; @height=height + + @cx=@gw/w.to_f; @cy=@gh/h.to_f + @cx=1.0/@cx; @cy=1.0/@cy + + #drawBoxs + #updateSelect + + true + + end + +end + +class Log < Gtk::ScrolledWindow + def initialize(main, fifo) + @main=main + @fifo=fifo + super() + set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) + + add(@textView=Gtk::TextView.new) + + @buffer=@textView.buffer + @errorTag=@buffer.create_tag('error', {'foreground' => 'red'}) + @normalTag=@buffer.create_tag('normal', {'foreground' => 'black'}) + @buffer.signal_connect("changed") { + @eob_mark = @textView.buffer.create_mark(nil,@textView.buffer.start_iter.forward_to_end,false) + @textView.scroll_mark_onscreen(@eob_mark) + } + + startLogListener + + end + + def startLogListener + Gtk.init_add do + Thread.new { + desc="startLogListener" + $threads.push(desc) + + l=[] + while line=@fifo.gets + l=line.dup + + #Gtk.queue do + eob_mark = @textView.buffer.create_mark(nil,@textView.buffer.start_iter.forward_to_end,false) + iter = @buffer.get_iter_at_mark(eob_mark) + if l.include? "rror" + tag=@errorTag + else + tag=@normalTag + end + @buffer.insert(iter, Time.now.to_s+ " "+l, tag) + #end + end + + $threads.delete_at($threads.index(desc)) + } + end + + end + +end + +class BasicTerminal < Gtk::ScrolledWindow + attr_reader :pid + + def initialize(command) + + super() + + set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_NEVER) + + add_with_viewport(@vbox=Gtk::VBox.new) + @vbox.pack_start(@hbox=Gtk::HBox.new) + + @vte=Vte::Terminal.new + @vte.signal_connect('child-exited') { |w| parent.destroy } + + @scrollbar=Gtk::VScrollbar.new(@vte.adjustment) + + @hbox.pack_start(@vte)#, false, false) + @hbox.pack_start(@scrollbar) #, false, false) if p + + @vte.set_size(80,24) + @vte.set_word_chars(".a-zA-Z_0-9//-") + @vte.set_colors(Gdk::Color.parse("black"), Gdk::Color.parse("white"),[]) + @vte.audible_bell=false + @vte.visible_bell=true + @vte.scrollback_lines=1000 + @vte.set_font("Monospace 12", Vte::TerminalAntiAlias::USE_DEFAULT) + @pid=@vte.fork_command(:argv => args("bash -c \"#{command}\"")) + show_all + end + + def args(s) + r=[] + s.gsub(/'([^']*)'|"([^"]*)"|([^[:space:]]+)/) { |m| + r.push("#{$1}#{$2}#{$3}") + } + return r + end +end + +class VdnTerminal < Gtk::Window + def initialize(name, cmd, read=true, background=true, center=true) + super() + + set_title(name) + + cmd="#{cmd}; echo; echo Press Enter to exit !; read" if read + + t=BasicTerminal.new(cmd) + add(t) + realize + + if(center) + x,y=$main.position + w,h=$main.size + x=x+w/2; y=y+h/2 + w,h=size + x=x-w/2; y=y-h/2 + move(x, y) + end + + show_all + + if !background + while `ps --no-headers -p #{t.pid} -o pid` != "" + Gtk.main_iteration while Gtk.events_pending? + sleep(0.05) + end + end + end +end + +class Vdn < Gtk::Window + +attr_reader :group, :accelGroup + def initialize + super() + $main=self + + @group = Gtk::AccelGroup.new + add_accel_group(@group) + + @consolesAccelGroup= Gtk::AccelGroup.new + + @accelGroupGui=Gtk::AccelGroup.new + @accelGroupConsole=Gtk::AccelGroup.new + + @accelGroup = @accelGroupGui + + + open + #mainDetector + end + + def add_main_accel_group + if @consolesAccelGroup + remove_accel_group(@consolesAccelGroup) + end + add_accel_group(@group) + end + + def add_consoles_accel_group + if @group + remove_accel_group(@group) + end + add_accel_group(@consolesAccelGroup) + + end + + + def open + + dir=ENV['NETWORK_DIR'] + #p "Vdn OPEN dir:#{dir}" + @frame=VdnFrame.new + add(@frame) + + show_all + + #setTitle("") + set_default_size(720,480) + maximize if ENV["MAXIMIZE"] == "1" + + signal_connect("delete-event") { r=whenQuit; Gtk::main_quit if r; true } + + #p "frame.net:#{@frame.net}" + @net=@frame.net + @notebook=@frame.notebook + end + + def setTitle + name=$currentNetName + release=ENV["VDN_RELEASE"] + if name=="" + set_title("[#{ENV['USER']}] vdn-gui (#{release}) - [ nThreads:#{$threads.length} ]") # + else + set_title("[#{ENV['USER']}] vdn-gui (#{release}) - #{name} - [ nThreads:#{$threads.length} ]") + end +end + + def clean + remove(@frame) + end + + + + def startListener + Gtk.init_add do + Thread.new { + desc="startListener" + $threads.push(desc) + fifo="#{ENV['TMPDIR']}/vdn-gui-#{ENV['USER']}-fifo-ctrl" + if ! File.exist?(fifo) + mySystem("umask 077; mkfifo #{fifo}") + sleep 0.5 + end + + session = File.open(fifo, "r+") + + rawLine=session.gets + while line=rawLine.chomp.split + + + cmd=line[0] + + + case cmd + + when "quit" + exit(0) + when "start" + name=line[1] + #if mySystem("#{$VDN_PATH}/bin/vdn-alive #{name}") + # $stderr.puts "Abort starting #{name}., is alive !" + #else + expr=line[2..100] + if @net && @net.consoles + #cmd=$VDN_PATH+"/bin/vdn-start-wrapper -et -v \"#{expr}\" #{name}" + #puts "cmd:#{cmd}" + #Gtk.queue do + @net.consoles.addTerm(name) + @notebook.set_page(2) + #end + #sleep 1 + else + cmd=$VDN_PATH+"/bin/vdn-start-wrapper -v \"#{expr}\" #{name}" + #$stderr.puts "cmd:#{cmd}" + mySystem(cmd) + end + #end + + when "vnc-viewer" + name=line[1] + @net.startVnc(name) + when "spice-viewer" + name=line[1] + @net.startSpice(name) + end + + + rawLine=session.gets + #p "raw line : #{rawLine}" + end + $threads.delete_at($threads.index(desc)) + } + + end + + end + +=begin + def mainDetector + Gtk.timeout_add(500) { + begin + while pid = Process.wait(-1, Process::WNOHANG) + end + rescue + end + } + + + + end +=end + + def method_missing(m, *args, &block) + @frame.send(m, *args, &block) + end +end + +class VdnFrame < Gtk::Frame + + attr_reader :scriptsMenu, :scriptsTestsMenu, :notebook + attr_accessor :bback, :bforward, :bhome, :actionsMenu, :actions, :files, :filesMenu + attr_reader :mod, :net, :preview + attr_reader :main + + def initialize() + super() + + + @main=$main + + @preview=Preview.new(self) + + + @folder=nil + + @testsToggle=false + + + @group = @main.group + + + + @menubar = Gtk::MenuBar.new + + @vbox=Gtk::VBox.new + add(@vbox) + + networksMenu = Gtk::Menu.new + @scriptsMenu = Gtk::Menu.new + optionsMenu = Gtk::Menu.new + @setupMenu = Gtk::Menu.new + + @setupMenu.append(Gtk::TearoffMenuItem.new) + + s=Gtk::MenuItem.new("Edit default rc config (local)..."); + @setupMenu.append(s) + s.signal_connect('activate') { |w| + startTerminal("#{$editor} config.rc.local", + "[ ! -e #{ENV['VDN_PATH']}/config.rc.local ] && \ + cp #{ENV['VDN_PATH']}/config.rc #{ENV['VDN_PATH']}/config.rc.local; \ + #{$editor} #{ENV['VDN_PATH']}/config.rc.local", false) + } + + @setupMenu.append(Gtk::MenuItem.new()) + + s=Gtk::MenuItem.new("Edit default guest config (local) ..."); + @setupMenu.append(s) + s.signal_connect('activate') { |w| + startTerminal("#{$editor} config.template.local", + "[ ! -e #{ENV['VDN_PATH']}/config.template.local ] && \ + cp #{ENV['VDN_PATH']}/config.template #{ENV['VDN_PATH']}/config.template.local; \ + #{$editor} #{ENV['VDN_PATH']}/config.template", false) + } + + @setupMenu.append(Gtk::MenuItem.new) + + s=Gtk::MenuItem.new("New network..."); + @setupMenu.append(s) + s.signal_connect('activate') { |w| + startTerminal("vdn-new-network", + "#{$VDN_PATH}/bin/vdn-new-network", true, false) + } + + @setupMenu.append(Gtk::MenuItem.new) + + s=Gtk::MenuItem.new("Download network..."); + @setupMenu.append(s) + s.signal_connect('activate') { |w| + startTerminal("vdn-download-network", + "#{$VDN_PATH}/bin/vdn-download-network", true, false) + } + + @setupMenu.append(Gtk::MenuItem.new) + + @setupMenu.append(s=Gtk::MenuItem.new("Terminal (in vdn directory...)")) + s.signal_connect('activate') { + startTerminal("", "cd #{$VDN_PATH}/files; bash", false) + } + #@setupMenu.show_all + + @actionsMenu = Gtk::Menu.new + @filesMenu = Gtk::Menu.new + + + @filesMenu.append(Gtk::TearoffMenuItem.new) + + + @filesMenu.append(s=Gtk::MenuItem.new("Terminal (in files directory...)")) + s.signal_connect('activate') { + startTerminal("", "vdn-manage-files; cd #{$VDN_PATH}/files; bash", false) + } + @filesMenu.show_all + + + @scriptsTestsMenu = Gtk::Menu.new + + networks = Gtk::MenuItem.new("Network") + options = Gtk::MenuItem.new("Preferences") + @scripts = Gtk::MenuItem.new("Scripts") + @setup = Gtk::MenuItem.new("Main setup") + @actions = Gtk::MenuItem.new("Network setup") + @scriptsTests = Gtk::MenuItem.new("All scripts") + @files = Gtk::MenuItem.new("Files (disks, ...)") + + #p"vdn: @actions:#{@actions}" + #p"vdn: @actionsMenu:#{@actionsMenu}" + + networks.submenu = networksMenu + options.submenu = optionsMenu + @scripts.submenu = @scriptsMenu + @actions.submenu = @actionsMenu + @setup.submenu = @setupMenu + @files.submenu = @filesMenu + + @scriptsTests.submenu = @scriptsTestsMenu + + @actions.signal_connect('activate') { |w,e| + @net.updateMoreMenu(@actionsMenu) if @net + @actionsMenu.show_all + false + } + + @setup.signal_connect('activate') { |w,e| + @setupMenu.show_all + false + } + + #@files.signal_connect('activate') { |w,e| + # @net.updateFilesMenu if @net + # false + #} + + #@scriptsTests.submenu = @scriptsTestsMenu + + + networksMenu.append(Gtk::TearoffMenuItem.new) + + # Create the Networks menu content. + + @bopen = Gtk::ImageMenuItem.new(Gtk::Stock::OPEN, @group) + networksMenu.append(@bopen) + @bopen.signal_connect("activate") { |w| whenOpen } + + @bclose = Gtk::ImageMenuItem.new(Gtk::Stock::CLOSE, @group) + networksMenu.append(@bclose) + @bclose.signal_connect("activate") { |w| + whenClose; + } + @bclose.sensitive=false + + networksMenu.append(Gtk::MenuItem.new) + + + + Gtk::Stock.add(Gtk::Stock::SELECT_ALL, "Select all", Gdk::Window::CONTROL_MASK, Gdk::Keyval::GDK_A) + + @bselect = Gtk::ImageMenuItem.new(Gtk::Stock::SELECT_ALL, @group) + networksMenu.append(@bselect) + @bselect.signal_connect("activate") { |w| whenSelectAll } + @bselect.sensitive=false + + Gtk::Stock.add(Gtk::Stock::YES, "Start selected", Gdk::Window::CONTROL_MASK, Gdk::Keyval::GDK_S) + @bstart = Gtk::ImageMenuItem.new(Gtk::Stock::YES, @group) + networksMenu.append(@bstart) + @bstart.signal_connect("activate") { |w| whenStartSelected } + @bstart.sensitive=false + + Gtk::Stock.add(Gtk::Stock::NO, "Halt all", Gdk::Window::CONTROL_MASK, Gdk::Keyval::GDK_H) + @bhalt = Gtk::ImageMenuItem.new(Gtk::Stock::NO, @group) + networksMenu.append(@bhalt) + @bhalt.signal_connect("activate") { |w| whenHaltAll } + @bhalt.sensitive=false + + Gtk::Stock.add(Gtk::Stock::REFRESH, "Restart selected", Gdk::Window::CONTROL_MASK, Gdk::Keyval::GDK_R) + @brestart = Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH, @group) + networksMenu.append(@brestart) + @brestart.signal_connect("activate") { |w| whenRestartAll } + @brestart.sensitive=false + + Gtk::Stock.add(Gtk::Stock::CLEAR, "Clean selected", Gdk::Window::CONTROL_MASK, Gdk::Keyval::GDK_C) + @bclean = Gtk::ImageMenuItem.new(Gtk::Stock::CLEAR, @group) + networksMenu.append(@bclean) + @bclean.signal_connect("activate") { |w| whenCleanAll } + @bclean.sensitive=false + + Gtk::Stock.add(Gtk::Stock::DISCONNECT, "Kill all", Gdk::Window::CONTROL_MASK, Gdk::Keyval::GDK_K) + @bkill = Gtk::ImageMenuItem.new(Gtk::Stock::DISCONNECT, @group) + networksMenu.append(@bkill) + @bkill.signal_connect("activate") { |w| whenKillAll } + @bkill.sensitive=false + + # Accel -> Tests mode + + #@group.connect(Gdk::Keyval::GDK_M, Gdk::Window::CONTROL_MASK, + # Gtk::ACCEL_VISIBLE) { + # toggleTests + #} + + networksMenu.append(Gtk::MenuItem.new) + + Gtk::Stock.add(Gtk::Stock::COPY, "View all backups", Gdk::Window::CONTROL_MASK, Gdk::Keyval::GDK_B) + @bfiles = Gtk::ImageMenuItem.new(Gtk::Stock::COPY, @group) + networksMenu.append(@bfiles) + @bfiles.signal_connect("activate") { |w| whenBackups } + + networksMenu.append(Gtk::MenuItem.new) + + s=Gtk::MenuItem.new("Edit user rc file..."); + networksMenu.append(s) + s.signal_connect('activate') { |w| + startTerminal("#{$editor} rc file", + "#{$editor} #{ENV['HOME']}/.vdnrc; \ + echo \\\"Pour que les modifications soient effectives vous devez redémarrer VDN\\\" ", true) + } + networksMenu.append(Gtk::MenuItem.new) + + quit = Gtk::ImageMenuItem.new(Gtk::Stock::QUIT, @group) + quit.signal_connect('activate') { + r=whenQuit + p "whenQuit r:#{r}" + Gtk::main_quit if r + } + networksMenu.append(quit) + + @menubar.append(networks) + + + # Create the Options menu content. + + item=Gtk::CheckMenuItem.new("Debug") + #puts("VDN_DEBUG=#{ENV["VDN_DEBUG"]}") + item.active=false + item.active=true if ENV["VDN_DEBUG"] == "1" + optionsMenu.append(item) + item.signal_connect("activate") { |w| whenDebug(w) } + + #item=Gtk::CheckMenuItem.new("External ssh") + #item.active=true if ENV["VDN_EXTERNAL_SSH"] == "1" + #optionsMenu.append(item) + #item.signal_connect("activate") { |w| whenExternalSsh(w) } + + item=Gtk::CheckMenuItem.new("Parallel") + item.active=true if ENV["RUN_PARALLEL"] == "1" + optionsMenu.append(item) + item.signal_connect("activate") { |w| whenParallel(w) } + + item=Gtk::CheckMenuItem.new("Maximize at startup") + item.active=true if ENV["MAXIMIZE"] == "1" + optionsMenu.append(item) + item.signal_connect("activate") { |w| whenPreferenceGeneric(w, "MAXIMIZE") } + + item=Gtk::CheckMenuItem.new("Use nano text editor") + item.active=true if ENV["NANO_EDITOR"] == "1" + optionsMenu.append(item) + item.signal_connect("activate") { |w| whenPreferenceNano(w, "NANO_EDITOR") } + + item=Gtk::CheckMenuItem.new("Raw graph") + item.active=true if ENV["RAW_GRAPH"] == "1" + optionsMenu.append(item) + item.signal_connect("activate") { |w| whenRawGraph(w) } + + item=Gtk::CheckMenuItem.new("Test mode") + + optionsMenu.append(item) + item.signal_connect("activate") { |w| whenTestMode(w) } + + @menubar.append(options) + + @menubar.append(@scripts) + + if ENV["TEST_MODE"] == "1" + item.active=true + @testsToggle=false + end + + @vbox.pack_start(@menubar, false, false) + + @vbox.pack_start(@notebook=Gtk::Notebook.new, true, true) + + @notebook.scrollable=true + @notebook.show_border=false + @notebook.focus_chain=[] + + # moz + + @mozbox=Gtk::VBox.new + + @mozbox.pack_start(@mozbar=Gtk::HBox.new, false, false) + + @html="#{$home}" + @banner="#{$VDN_PATH}/doc/banner.svgz" + + @moz=Gtk::Browser.new + @moz.banner = @banner + @moz.location = @html + + @mozbox.add(@moz) + @notebook.append_page(@mozbox, Gtk::Label.new("Documentation")) + + #@log=Log.new(@main, $LOG_FIFO) + #@notebook.append_page(@log, Gtk::Label.new("Log")) + + show_all + + if ENV["NETWORK_DIR"] != "" + @dir=ENV["NETWORK_DIR"] + if @dir == "" + @dir=$dir + ENV["NETWORK_DIR"]=$dir + end + openNet + else + closeNet + end + + + + signal_connect('event') { |w,e| + if e.class.to_s == "Gdk::EventKey" + n=Gdk::Keyval.to_name(e.keyval) + if e.event_type == Gdk::Event::Type::KEY_PRESS + if n =~ /Control/ + @mod="Control" + end + + if n =~ /Shift/ + @mod="Shift" + end + else + if n =~ /Control/ || n =~ /Shift/ + @mod=nil + end + + end + end + } + end + + + def startTerminal(name, cmd, read=true, background=true, big=false) + #VdnTerminal.new(name, cmd, read, background, center); + #return +#=begin + opts="" + + # bg only need for xfce4-terminal + bg="--disable-server" + bg="" if background + + longCmd="NETWORK_DIR=#{@dir} #{cmd}" + + # xfce4-terminal + #geom="" + #geom="--geometry 140x43 --font 10" if big + + # sajura terminal + #geom="" + #geom="-c 140 -r 43 --font 10" if big + + # xterm + # xterm -fa 'Monospace' -fs 12 -geometry 80x24 -j -rightbar + #p "big:#{big}" + opts="-j -rightbar -sb -vb" + geom="-fa 'Monospace' -fs 12" + geom="-fa 'Monospace' -fs 10 -geometry 140x43" if big + + #p "cmd:#{cmd} read:#{read} bg:#{bg}" + + #c="cd; export NO_INTERACTIVE=1; xfce4-terminal #{geom} --disable-server -T \"#{name}\" #{bg} -e \"bash -c \'#{longCmd}; echo; echo Press Enter to exit !; read\'\"" + #c="cd; export NO_INTERACTIVE=1; sakura #{geom} -t \"#{name}\" -e \"bash -c \'#{longCmd}; echo; echo Press Enter to exit !; read\'\" 2> /dev/null" + #c="cd; export NO_INTERACTIVE=1; xterm #{geom} -T \"#{name}\" -e \"bash -c \'#{longCmd}; echo; echo Press Enter to exit !; read\'\" 2> /dev/null" + + prefix="cd; export NO_INTERACTIVE=1; " + + extra="" + extra="; echo; echo Press Enter to exit !; read" if read + + #c="cd; export NO_INTERACTIVE=1; xfce4-terminal #{geom} --disable-server -T \"#{name}\" #{bg } -e \"bash -c \'#{longCmd} #{extra}\'\"" + #c="cd; export NO_INTERACTIVE=1; sakura #{geom} -t \"#{name}\" -e \"bash -c \'#{longCmd}\'\" 2> /dev/null" + #c="xterm ${opts} #{geom} -T \"#{name}\" -e \"bash -c \'#{prefix} #{longCmd} #{extra}\'\" &" + + c="bash -c \'#{prefix} #{longCmd} #{extra}\'" + + #puts "c:#{c} networkDir:#{ENV['NETWORK_DIR']}" + #c="#{c} &" # if background + + #mySystem(c) + #puts "=== vdn-terminal \"#{c}\"" + + if big == true + mySystem("vdn-terminal -b \"#{c}\" &") + else + mySystem("vdn-terminal \"#{c}\" &") + end + +#=end + end + + + def getPass + m=" Mot de passe VDN (mode edit) : " + + dialog = Gtk::Dialog.new("Message", self, + Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT, + [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT], + [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT]) + + dialog.vbox.add(Gtk::Label.new(m)) + dialog.vbox.add(e=Gtk::Entry.new) + e.visibility=false + + e.signal_connect("activate") { + dialog.children[0].children.last.children.first.clicked + true + } + + #e.max_length=10 + + dialog.show_all + r=dialog.run + if r==Gtk::Dialog::RESPONSE_ACCEPT + require 'bcrypt' + + # #hash a user's password + # require'bcrypt' + # BCrypt::Password.create("secret") + + hash="$2a$10$bxqjywHoKH5LI6MP6oX2SeJJX./rdZknVByguTj936bqgqZ.Lv/QW" + r2=(BCrypt::Password.new(hash)==e.text) + end + + dialog.destroy + + return (r==Gtk::Dialog::RESPONSE_ACCEPT) && r2 + end + + + + + + def toggleTests + if @testsToggle + @testsToggle=false + @menubar.remove(@setup) + @menubar.remove(@actions) + @menubar.remove(@scriptsTests) + @menubar.remove(@files) + else + #if (FileTest.writable?(ENV["NETWORK_DIR"]+"/scripts") || getPass ) + #if (getPass ) + @menubar.append(@setup) + @menubar.append(@actions) + @menubar.append(@scriptsTests) + @menubar.append(@files) + @scriptsTests.show + @setup.show + @actions.show + @files.show + + @testsToggle=true + #end + end + end + + def whenHaltAll + + if @net != nil + @net.whenHaltAll + @notebook.set_page(1) + end + + return true + end + + def whenRestartAll + if @net != nil + @net.whenRestart + @notebook.set_page(1) + end + + return true + end + + def whenCleanAll + if @net != nil + @net.whenClean + end + + return true + end + + def whenKillAll + r=`#{$VDN_PATH}/bin/vdn-alives` + if r != "" + m=" +Un ou plusieurs systèmes restent en fonctionnement ! +Si vous validez ils seront \"brutalement\" arrêtés (pas de sauvegarde !) +" + + dialog = Gtk::Dialog.new("Message", @main, + Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT, + [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT], + [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT]) + + dialog.vbox.add(Gtk::Label.new(m)) + dialog.show_all + r=dialog.run + dialog.destroy + #p "r:#{r}" + #p "Gtk::Dialog::RESPONSE_ACCEPT:#{Gtk::Dialog::RESPONSE_ACCEPT}" + return false if r != Gtk::Dialog::RESPONSE_ACCEPT + end + + if @net != nil + @net.whenKillAll + @notebook.set_page(1) + end + + return true + end + + def whenClose + + #p "whenClose" + + return false if ! whenKillAll + + if @net + + @net.close + @net=nil + closeNet + @dir="" + $currentNetName="" + + + end + + @bclose.sensitive=false + @bselect.sensitive=false + @bstart.sensitive=false + @bhalt.sensitive=false + @brestart.sensitive=false + @bclean.sensitive=false + @bkill.sensitive=false + @bopen.sensitive=true + @scripts.sensitive=false + @scriptsTests.sensitive=false + @setup.sensitive=true + @actions.sensitive=false + #@files.sensitive=false + return true + end + + + def whenOpen + + if @folder == nil + if ENV["NETWORK_DIR"] != "" + @folder=File.dirname(ENV["NETWORK_DIR"]) + else + @folder=ENV["VDN_NETWORKS_BASE_DIR"] + end + end + + dialog = Gtk::FileChooserDialog.new("Open network", $main, + Gtk::FileChooser::ACTION_OPEN, + nil, + [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL], + [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT]) + dialog.preview_widget=@main.preview.area + preview_widget_active=true + + dialog.signal_connect('update-preview') { |w| + #p "update-preview #{w.preview_filename}" + @main.preview.load(w.preview_filename) + } + + + #p "dialog.filename:#{dialog.filename}" + #@main.preview.load(dialog.filename) + + if @folder + dialog.current_folder=@folder + + dialog.signal_connect('current-folder-changed') { |w| + Gtk.timeout_add(200) { + begin + if File.exist?(w.current_folder+"/network.vdn") + w.filename=w.current_folder+"/network.vdn" + w.response(Gtk::Dialog::RESPONSE_ACCEPT) + end + rescue + end + false + } + false + } + + f = Gtk::FileFilter.new + f.name="Vdn network" + f.add_pattern("*.vdn") + + dialog.set_filter(f) + + n=nil + + if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT + f=dialog.filename + n=File.dirname(f) + end + dialog.preview_widget=nil + dialog.destroy + else + @folder=ENV["VDN_NETWORKS_BASE_DIR"] + end + + #p "n:#{n}" + + + + if n + + if @net != nil + r=whenClose + return false if !r + end + + @dir=n + #mySystem($VDN_PATH+"/bin/vdn-busy.rb &") + +=begin + message="\n\n\n Open #{@dir} network.\n\nPlease wait... \n\n\n" + dialog = Gtk::MessageDialog.new( + self, + Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT, + Gtk::MessageDialog::INFO, + Gtk::MessageDialog::BUTTONS_CLOSE, + message) + + # Ensure that the dialog box is destroyed when the user responds. + dialog.signal_connect('response') { dialog.destroy } + + # Add the message in a label, and show everything we've added to the dialog. + #dialog.vbox.add(Gtk::Label.new(message)) + dialog.show_all + + #Gtk.idle_add { +=end + mySystem($VDN_PATH+"/bin/vdn-set-var NETWORK_DIR \"#{@dir}\"") + ENV['NETWORK_DIR']=@dir + #@net.close if @net + #$main.destroy + + $main.whenQuit + #$main.destroy + + #mySystem($VDN_PATH+"/bin/vdn #{@dir} &") + #sleep(2) + #whenQuit + + startNet +=begin + #} +=end + end + end + + def whenSelectAll + @net.hosts.each_value { |i| + @net.selection.add(i) if ! i.isSel + } + end + + def whenStartSelected + @net.whenStart + end + + def whenRestartSelected + @net.whenRestart + end + + #def whenTermOld + # #mySystem("cd #{@dir}; cd scripts; xfce4-terminal --disable-server &") + # mySystem("cd #{@dir}; cd scripts; sakura &") + #end + + def whenBackups + startTerminal("", "vdn-manage-backups; bash", false) + #mySystem("xfce4-terminal --disable-server &") + end + + def whenFiles + startTerminal("", "vdn-manage-files; cd $VDN_PATH/files; bash", false) + #mySystem("xfce4-terminal --disable-server &") + end + + def whenQuit + mySystem($VDN_PATH+"/bin/vdn-set-var NETWORK_DIR \"#{@dir}\"") + if whenClose + begin + #Process.kill("SIGTERM", Process.ppid) + rescue + end + begin + File.delete("#{ENV['TMPDIR']}/vdn-#{ENV['USER']}-gui-log") + #File.delete("#{ENV['TMPDIR']}/vdn-gui-#{ENV['USER']}-fifo-ctrl") + + rescue + end + #puts "Bye !" + #Gtk::main_quit + return true + end + return false + end + + def openNet + + #p "openNet:" + + $dir=@dir if @dir && @dir != "" + + @net.close if @net + + + @net=nil + + @dir=$dir if @dir == "" + + mySystem("#{$VDN_PATH}/bin/vdn-set-network-dir #{@dir}") + + ENV["NETWORK_DIR"]=@dir + + @net=Net.new(self, @dir) + + @net.open + + + $currentNetName=File.basename(@dir) + $currentNetName="" if $currentNetName == nil + + $main.setTitle + + # Create the Scripts menu content. + + @scripts.signal_connect('activate') { |w,e| + @net.updateScriptsMenu + false + } + + @scriptsTests.signal_connect('activate') { |w,e| + @net.updateScriptsTestsMenu + false + } + + @setup.signal_connect('activate') { |w,e| + false + } + + @actions.signal_connect('activate') { |w,e| + @net.updateActionsMenu if @net + false + } + + #@files.signal_connect('activate') { |w,e| + # p "files.activate" + # @net.updateFilesMenu if @net + # false + #} + + show_all + + @bclose.sensitive=true + #@bterm.sensitive=true + @bselect.sensitive=true + @bstart.sensitive=true + @bhalt.sensitive=true + @brestart.sensitive=true + @bclean.sensitive=true + @bkill.sensitive=true + #@bopen.sensitive=false + @scripts.sensitive=true + @scriptsTests.sensitive=true + @setup.sensitive=true + @actions.sensitive=true + @files.sensitive=true + @moz.banner=@banner + @moz.location=@html + + @notebook.set_page(1) + + end + + def closeNet + + @lastDateGraphFile=nil + if @net + @net.close + @net=nil + end + + @dir=nil + ENV['NETWORK_DIR']="" + #mySystem($VDN_PATH+"/bin/vdn-set-var NETWORK_DIR \"\"") + + @html="#{$home}" + @moz.banner=@banner + @moz.location=@html + #release=ENV["VDN_RELEASE"] + $main.setTitle + + + @bclose.sensitive=false + #@bterm.sensitive=false + @bselect.sensitive=false + @bstart.sensitive=false + @bhalt.sensitive=false + @brestart.sensitive=false + @bclean.sensitive=false + @bkill.sensitive=false + @bopen.sensitive=true + @scripts.sensitive=false + @actions.sensitive=false + #@setup.sensitive=false + @scriptsTests.sensitive=false + + + + + end + + def whenDebug(w) + s="0" + s="1" if w.active? + ENV["VDN_DEBUG"]=s + mySystem($VDN_PATH+"/bin/vdn-set-var VDN_DEBUG #{s}") + end + + def whenExternalSsh(w) + + #p "whenExternalSsh: #{w} #{w.active?}" + s="0" + s="1" if w.active? + ENV["VDN_EXTERNAL_SSH"]=s + mySystem($VDN_PATH+"/bin/vdn-set-var VDN_EXTERNAL_SSH #{s}") + end + + def whenPreferenceGeneric(w, varName) + s="0" + s="1" if w.active? + ENV[varName]=s + mySystem($VDN_PATH+"/bin/vdn-set-var #{varName} #{s}") + end + + def whenPreferenceNano(w, varName) + s="0" + s="1" if w.active? + ENV[varName]=s + mySystem($VDN_PATH+"/bin/vdn-set-var #{varName} #{s}") + + setDefaultEditor + end + + def whenParallel(w) + s="0" + s="1" if w.active? + ENV["RUN_PARALLEL"]=s + mySystem($VDN_PATH+"/bin/vdn-set-var RUN_PARALLEL #{s}") + end + + def whenRawGraph(w) + s="0" + s="1" if w.active? + ENV["RAW_GRAPH"]=s + mySystem($VDN_PATH+"/bin/vdn-set-var RAW_GRAPH #{s}") + + return if ! @net + + @net.lines="" + @net.graphfile=nil + @net.parseGraph + end + + def whenTestMode(w) + s="0" + s="1" if w.active? + ENV["TEST_MODE"]=s + mySystem($VDN_PATH+"/bin/vdn-set-var TEST_MODE #{s}") + + if ! w.active? + @testsToggle=false + @menubar.remove(@setup) + @menubar.remove(@actions) + @menubar.remove(@scriptsTests) + @menubar.remove(@files) + else + #if (FileTest.writable?(ENV["NETWORK_DIR"]+"/scripts") || getPass ) + #if (getPass ) + @menubar.append(@setup) + @menubar.append(@actions) + @menubar.append(@scriptsTests) + @menubar.append(@files) + @scriptsTests.show + @setup.show + @actions.show + @files.show + @testsToggle=true + #end + end + + end + + + def whenTests(w) + s="0" + s="1" if w.active? + end + + + +end + +class Net < Gtk::VBox + + include Svg + + attr_reader :dx, :dy, :area, :gc + attr_reader :cx, :cy, :bx, :by + attr_reader :selColor + attr_reader :consoles, :combo + attr_accessor :hosts, :selection, :pixbuf + attr_accessor :lines, :graphfile, :lines + + + def initialize(main, dir) + + super() + + @main=main + @notebook=@main.notebook + @dir=dir + + @graphTimeout=nil + @netTimeout=nil + + + @lines=nil + @graphfile=nil + + @gc=nil + @drawed=false + @gw=@gh=nil + + @consoles=nil + @ssh=nil + + svgInit + + @selColor=Gdk::Color.parse("yellow") + + @bx=20 + @by=20 + + @selColor=Gdk::Color.parse("yellow") + + @white = Gdk::Color.parse("white") + @grey = Gdk::Color.parse("grey") + @blue = Gdk::Color.parse("blue") + @red = Gdk::Color.parse("red") + @green = Gdk::Color.parse("green") + + @dx=0 + @dy=0 + + @selection=Selection.new(self) + + @menu=Gtk::Menu.new + createMenu(@menu) + + @hosts=Hash.new + @states=Hash.new + + @mx=@my=nil + @selRec=nil + + @area = Gtk::DrawingArea.new + + @eventbox=Gtk::EventBox.new + @eventbox.events=Gdk::Event::ALL_EVENTS_MASK + + @eventbox.add(@area) + add(@eventbox); + + @eventbox.signal_connect('event') { |w,e| + parseEvent(w,e) + false + } + + @notebook.insert_page(1,self, Gtk::Label.new("Graph")) + + @area.signal_connect("expose-event") do |widget, event| + #p "expose...#{ENV['VDN_GUI_IDENT']} #{event} #{@area}" + draw(@area) + + # MARCHE PAS !@main.main.add_main_accel_group + # Il y a des fois ou dans l'onglet graphe les raccourcis claviers + # Ne fonctionne pas ! Ex Ctrl A pour sélectionner toutes les machines. + + false + end + + @area.signal_connect("configure-event") do |widget, event| + #p "resize...#{ENV['VDN_GUI_IDENT']} #{event} #{@area}" + @pixbuf=nil + false + end + + @area.signal_connect("event") do |widget, event| + #p "event...#{ENV['VDN_GUI_IDENT']} #{event} #{@area}" + false + end + + + + end + + + def parseGraph # net + + if FileTest.exist?(@dir+"/net.svgz") && ENV['RAW_GRAPH']=="0" + @graphfile=@dir+"/net.svgz" + elsif FileTest.exist?(@dir+"/graph.svgz") + @graphfile=@dir+"/graph.svgz" + end + + begin + f=File::open(@graphfile) + z=Zlib::GzipReader.open(f) + lines=z.readlines[1..20].join + z.close + f.close + rescue + return + end + if lines != @lines + @hosts={} + @selection.clear + @lines=lines + if lines.include?("nkscape") then + parseInkscape + elsif lines.include?("raphviz") then + parseGraphviz + else + $stderr.puts("Error : Svg parser not found !") + end + begin + draw(@area) + rescue + + end + whenNewGraph + end + end + + def netDetector + + #p "add netDetector" + @netTimeout=Gtk.timeout_add(2000) { + #p "netDetector... #{Time.now}" + detect + #p "netDetector end #{Time.now}" + true + } + + #Gtk.timeout_add(100) { + # begin + # @net.detect if @net + # rescue + # end + # false + #} + @graphTimeout=Gtk.timeout_add(200) { + + if @dir && @dir != "" + + if ! FileTest.exist?(@graphfile) + @graphfile=nil + end + + if ! @graphfile + if FileTest.exist?(@dir+"/net.svgz") && ENV['RAW_GRAPH']=="0" + @graphfile=@dir+"/net.svgz" + elsif FileTest.exist?(@dir+"/graph.svgz") + @graphfile=@dir+"/graph.svgz" + end + end + + if (@graphfile) + begin + @dateGraphFile=File.mtime(@graphfile) + rescue + end + #p @dateGraphFile + #p " " + if( ! @lastDateGraphFile || @dateGraphFile!=@lastDateGraphFile) + + dir=@dir.dup + + @lines="" + @pixbuf=nil + parseGraph + area.queue_draw + @lastDateGraphFile=@dateGraphFile + end + end + end + + true + } + + end + + def whenNewGraph + + #p "whenNewGraph..." + + l=`#{$VDN_PATH}/bin/vdn-list | grep -v '^#'` + l=l.split("\n") + l=l.sort { |a,b| + if a.size > b.size + 1 + else + a <=> b + end + } + + # consoles + + #@consolesNotebook.set_page(0) + + #while @consolesNotebook.n_pages > 0 + # @consolesNotebook.remove_page(0) + #end + + while @consolesNotebook.n_items > 0 + @consolesNotebook.remove(@consolesNotebook.nth_item(0)) + end + + l.each { |i| + #@consolesNotebook.append_page(Gtk::Frame.new, Gtk::Button.new(i)) + #@consolesNotebook.show_all + b=Gtk::ToolButton.new(nil, i) + #b.can_focus=false + @consolesNotebook.add(b) + b.signal_connect("clicked") { + #p "initBar : add console" + #@consoles.addTerm(i) + mySystem("vdn-viewer #{i} &") + } + } + + @consolesNotebook.show_all + #@consoles.initBar # initBar consoles + + # ssh + + #while @sshNotebook.n_pages > 0 + # @sshNotebook.remove_page(0) + #end + + while @sshNotebook.n_items > 0 + @sshNotebook.remove(@sshNotebook.nth_item(0)) + end + + l.each { |i| + + #b=Gtk::Button.new(i) + b=Gtk::ToolButton.new(nil, i) + #b.can_focus=false + #b.relief=Gtk::RELIEF_NONE + + #@sshNotebook.append_page(Gtk::Frame.new, b) + @sshNotebook.add(b) + b.signal_connect("clicked") { + #p "initBar : add ssh" + if ENV['VDN_EXTERNAL_SSH'] != "1" + #cmd=$VDN_PATH+"/bin/vdn-ssh-loop -X #{user}@#{i.name}" + #@ssh.addTerm(i.name, cmd) + @ssh.addTerm(i) + @notebook.set_page(3) + else + user=@main.net.combo.active_text + startTerminal("vdn-ssh-loop -X #{user}@#{i}", + "#{$VDN_PATH}/bin/vdn-ssh-loop -X #{user}@#{i}") + end + } + + } + + @sshNotebook.show_all + + #@ssh.initBar # ssh initBar + + + #@notebook.set_page(3) + + + + + end + + def open # class Net + + + return if ! @dir || @dir == "" + + + r=Dir.glob("#{@dir}/*.conf") + + if Dir.glob("#{@dir}/*.conf").size == 0 + Gtk.main_iteration while Gtk.events_pending? + + #p "@dir:#{@dir}" + #p "ENV['NETWORK_DIR']:#{ENV['NETWORK_DIR']}" + + startTerminal("vdn-build-network", + "#{$VDN_PATH}/bin/vdn-build-network", true, false) + end + + if FileTest.exist?(@dir+"/net.svgz") && ENV['RAW_GRAPH']=="0" + @graphfile=@dir+"/net.svgz" + elsif FileTest.exist?(@dir+"/graph.svgz") + @graphfile=@dir+"/graph.svgz" + else + $stderr.puts("No SVGZ file found !") + return + end + + Gtk.idle_add { + parseGraph + if (@graphfile) + @lastDateGraphFile=File.mtime(@graphfile) + end + + #GC.start + false + } + + #@consolesNotebook=Gtk::Notebook.new + #@consolesNotebook.scrollable=true + + # Create console + + @consoles=ConsolesPanel.new(@main, "vdn-start-wrapper -et ", "", \ + "\nN'utilisez les consoles qu'en cas de perte de réseau ! \ + Utilisez le panneau \"Ssh\".\n") + #@consolesNotebook.append_page(@consoles, + # Gtk::Label.new("ttyS0")) + + @consolesNotebook=Gtk::Toolbar.new + @consolesNotebook.toolbar_style=Gtk::Toolbar::Style::TEXT + @consolesNotebook.can_focus=false + + @consolesContainer=Gtk::VBox.new + @consolesContainerHBox=Gtk::HBox.new + @consolesContainerHBox.pack_start(Gtk::Label.new("Click to open display -> : "), false, false) + @consolesContainerHBox.pack_start(@consolesNotebook) + @consolesContainer.pack_start(@consolesContainerHBox, false, false) + @consolesContainer.pack_start(@consoles) + + + @notebook.insert_page(2,@consolesContainer, + Gtk::Label.new("Consoles")) + + @consoles.setProps("fgColor", "white") + @consoles.setProps("bgColor", "black") + @consoles.setProps("canClose", "false") + @consoles.setProps("audibleBell", "false") + @consoles.setProps("gridFont", ENV["GRID_FONT"]) + + + # Create ssh + + @ssh=SshPanel.new(@main, "vdn-ssh-loop -X ") + + #@sshNotebook=Gtk::Notebook.new + @sshNotebook=Gtk::Toolbar.new + #@sshNotebook.scrollable=true + @sshNotebook.toolbar_style=Gtk::Toolbar::Style::TEXT + @sshNotebook.can_focus=false + + @sshContainer=Gtk::VBox.new + @sshContainerHBox=Gtk::HBox.new(false, 5) + + @sshContainerHBox.pack_start(Gtk::Label.new("Ssh user : "), false, false) + + + combo = Gtk::ComboBoxEntry.new + combo.can_focus=false + combo.has_focus=false + combo.focus_on_click=false + %w( root test alice bob eve ).each do |val| + combo.append_text(val) + end + combo.set_size_request(120, -1) + combo.active = 0 + @combo=combo + + @sshContainerHBox.pack_start(@combo, false, false) + @sshContainerHBox.pack_start(Gtk::Label.new(" Click to open ssh -> : "), false, false) + @sshContainerHBox.pack_start(@sshNotebook) + @sshContainer.pack_start(@sshContainerHBox, false, false) + @sshContainer.pack_start(@ssh) + + + item=Gtk::CheckButton.new("New window") + item.active=true if ENV["VDN_EXTERNAL_SSH"] == "1" + item.signal_connect("clicked") { |w| @main.whenExternalSsh(w) } + + @sshContainerHBox.pack_start(item, false, false) + + + @sshContainerHBox.pack_start(b=Gtk::Button.new("Remove all"), false, false) + b.signal_connect('clicked') { + puts "clear ssh..." + @ssh.close + } + + + + @ssh.setProps("audibleBell", "false") + @ssh.setProps("gridFont", ENV["GRID_FONT"]) + + + createMoreMenu(@main.actionsMenu) + + + @notebook.insert_page(3, @sshContainer, Gtk::Label.new("Ssh")) + + whenNewGraph + + netDetector + end + + + def detect + return if ! @graphfile + begin + f=File::open(@graphfile) + rescue + return + end + + z=nil + begin + z=Zlib::GzipReader.open(f) if f != nil + rescue + z=nil + end + + begin + lines=z.readlines[1..10].join if z != nil + rescue + return + end + + begin + z.close if z != nil + f.close if f != nil + rescue + end + + #if lines != @lines + # @main.whenClose + # @main.openNet + #end + + #l=IO.popen("/bin/bash -c \""+$VDN_PATH+"/bin/vdn-alives"+"\"").read + io=IO.popen($VDN_PATH+"/bin/vdn-alives") + l=io.read + Thread.new { + desc="detect" + $threads.push(desc) + Process.wait(io.pid) + $threads.delete_at($threads.index(desc)) + } + #p "l1:#{l}" + + #cmd=$VDN_PATH+"/bin/vdn-alives" + #l=`#{cmd}` + #p "l2:#{l}" + + l=l.split + + #puts "detect : #{l}" + + @states.each_key { |i| + v=@hosts[i] + if v + if l.include?(i) + @states[i]=true + v.draw(self, @green) + else + @states[i]=false + v.draw(self, @red) + + if v.vncViewer + begin + v.vncViewer.destroy + rescue + end + v.vncViewer=nil + end + + if v.spiceViewer + begin + v.spiceViewer.destroy + rescue + end + v.spiceViewer=nil + end + + end + end + + } + true + end + + def runScript(name, script) + $stderr.puts "#{Time.now} Run: \"#{script}\"" + cmd="#{$VDN_PATH}/bin/vdn-scripts -n -r #{script}" + #VdnTerminal.new(name, cmd, false) + startTerminal(name, cmd, false, true, true) + end + + def editScript(name, script) + cmd="#{$VDN_PATH}/bin/vdn-scripts -e #{script}" + startTerminal(name, cmd, false) + #VdnTerminal.new(name, cmd, false, true, false) + end + + def hideScript(file) + mySystem("chmod 644 #{file}") + end + + def unhideScript(file) + mySystem("chmod 755 #{file}") + end + + def isScript(f) + return true if FileTest.symlink?(f) + return false if + ! FileTest.file?(f) || ! FileTest.executable?(f) # || ( f =~ /\/repair[^\/]*$/) + true + end + + def updateScriptsMenu + @main.scriptsMenu.each { |c| @main.scriptsMenu.remove(c) } + @main.scriptsMenu.append(Gtk::TearoffMenuItem.new) + dir=@dir+"/scripts" + l=Dir["#{dir}/*"] + l.sort.each { |i| + #next if ! FileTest.file?(i) + #if ! @testsToggle + # next if ! FileTest.executable?(i) + # next if ( i =~ /\/test.*/) + #end + + next if ! isScript(i) + f=File.basename(i) + s=Gtk::MenuItem.new(f) + s.signal_connect('activate') { + runScript("Script : #{f}", f) + } + @main.scriptsMenu.append(s) + } + @main.scriptsMenu.show_all + end + + def isTestScript(f) + return false if isScript(f) + return false if + ! FileTest.file?(f) || ! FileTest.executable?(f) + return true if ( f =~ /\/test.*/) + false + end + + def updateActionsMenu + #@main.actionsMenu.each { |c| @main.actionsMenu.remove(c) } + + #createMoreMenu(@main.actionsMenu) + + #@main.actionsMenu.show + #@main.actionsMenu.show_all + + #@main.actions.submenu=@main.actionsMenu + #@main.actions.show_all + #@main.actions.signal_connect('activate') { |w,e| + # updateActionsMenu + # false + #} + end + + def updateScriptsTestsMenu + @main.scriptsTestsMenu.each { |c| @main.scriptsTestsMenu.remove(c) } + dir=@dir+"/scripts" + l=Dir["#{dir}/*"] + @main.scriptsTestsMenu.append(@tearoff=Gtk::TearoffMenuItem.new) + l.sort.each { |i| + #next if ! FileTest.file?(i) + #if ! @testsToggle + # next if ! FileTest.executable?(i) + # next if ( i =~ /\/test.*/) + #end + #next if ! isTestScript(i) + next if ! FileTest.file?(i) + f=File.basename(i) + s=Gtk::MenuItem.new(f) + s.signal_connect('activate') { + #editScript("Script : #{f}", f) + runScript("Script : #{f}", f) + } + @main.scriptsTestsMenu.append(s) + } + + @main.scriptsTestsMenu.append(Gtk::MenuItem.new) + + # edit sub menu + editMenu = Gtk::Menu.new + editMenu.append(Gtk::TearoffMenuItem.new) + + l.sort.each { |i| + #next if ( ! isScript(i) && !isTestScript(i) ) + next if ! FileTest.file?(i) + f=File.basename(i) + e=Gtk::MenuItem.new(f) + e.signal_connect('activate') { + editScript("Script : #{f}", f) + } + editMenu.append(e) + } + + s=Gtk::MenuItem.new("Edit...") + s.submenu=editMenu + + #editMenu.append(s) + #editMenu.show + + @main.scriptsTestsMenu.append(s) + + # hide sub menu + hideMenu = Gtk::Menu.new + hideMenu.append(Gtk::TearoffMenuItem.new) + + l.sort.each { |i| + #next if ( ! isScript(i) && !isTestScript(i) ) + next if ! FileTest.file?(i) + f=File.basename(i) + e=Gtk::MenuItem.new(f) + e.signal_connect('activate') { + hideScript(i) + } + hideMenu.append(e) + } + + s=Gtk::MenuItem.new("Hide...") + s.submenu=hideMenu + @main.scriptsTestsMenu.append(s) + + # unhide sub menu + unhideMenu = Gtk::Menu.new + unhideMenu.append(Gtk::TearoffMenuItem.new) + + l.sort.each { |i| + #next if ( ! isScript(i) && !isTestScript(i) ) + next if ! FileTest.file?(i) + f=File.basename(i) + e=Gtk::MenuItem.new(f) + e.signal_connect('activate') { + unhideScript(i) + } + unhideMenu.append(e) + } + s=Gtk::MenuItem.new("Unhide...") + s.submenu=unhideMenu + @main.scriptsTestsMenu.append(s) + + + s=Gtk::MenuItem.new("New script...") + s.signal_connect('activate') { + #mySystem("echo -en \"New script name ? : \"; read new; echo #{dir}/$new") + cmd="echo -en \\\"(new) New script name ? : \\\"; \ + read new; + + cat << EOF > #{dir}/\\$new; +#!/usr/bin/env bash + +DESC=\\\"One line description.\\\" + +run() { + + # name=XXX + # + # requestSshGuest \\\$name + # ... + +} + +EOF +" + + startTerminal("New script", cmd, false) + } + @main.scriptsTestsMenu.append(s) + + + + # renameScript sub menu + renameScriptMenu = Gtk::Menu.new + renameScriptMenu.append(Gtk::TearoffMenuItem.new) + + l.sort.each { |i| + #next if ( ! isScript(i) && !isTestScript(i) ) + next if ! FileTest.file?(i) + f=File.basename(i) + e=Gtk::MenuItem.new(f) + e.signal_connect('activate') { + cmd="echo -en \\\"(rename) New script name ? : \\\"; read new; mv #{i} #{dir}/\\$new" + startTerminal("Rename #{i}", cmd, false) + } + renameScriptMenu.append(e) + } + s=Gtk::MenuItem.new("Rename...") + s.submenu=renameScriptMenu + @main.scriptsTestsMenu.append(s) + + + # copyScriptMenu sub menu + copyScriptMenu = Gtk::Menu.new + copyScriptMenu.append(Gtk::TearoffMenuItem.new) + + l.sort.each { |i| + #next if ( ! isScript(i) && !isTestScript(i) ) + next if ! FileTest.file?(i) + f=File.basename(i) + e=Gtk::MenuItem.new(f) + e.signal_connect('activate') { + cmd="echo -en \\\"(copy) New script name ? : \\\"; read new; cp #{i} #{dir}/\\$new" + startTerminal("Copy #{i}", cmd, false) + } + copyScriptMenu.append(e) + } + s=Gtk::MenuItem.new("Copy...") + s.submenu=copyScriptMenu + @main.scriptsTestsMenu.append(s) + + # deleteScript sub menu + deleteScriptMenu = Gtk::Menu.new + deleteScriptMenu.append(Gtk::TearoffMenuItem.new) + + l.sort.each { |i| + #next if ( ! isScript(i) && !isTestScript(i) ) + next if ! FileTest.file?(i) + f=File.basename(i) + e=Gtk::MenuItem.new(f) + e.signal_connect('activate') { + cmd="rm -i #{i}" + startTerminal("Delete #{i}", cmd, false) + } + deleteScriptMenu.append(e) + } + s=Gtk::MenuItem.new("Delete...") + s.submenu=deleteScriptMenu + @main.scriptsTestsMenu.append(s) + + @main.scriptsTestsMenu.append(Gtk::MenuItem.new) + + s=Gtk::MenuItem.new("Terminal (in scripts directory)...") + s.signal_connect('activate') { + startTerminal("", "cd #{@dir}/scripts; bash", false) + } + @main.scriptsTestsMenu.append(s) + + + @main.scriptsTestsMenu.show_all + end + + + def updateIsosMenu(menu) + menu.each { |c| menu.remove(c) } + dir=$VDN_PATH+"/files/g" + l=Dir["#{dir}/*.iso"] + l.sort.each { |i| + f=File.basename(i) + s=Gtk::MenuItem.new(f) + s.signal_connect('activate') { + whenStartOnSelectedIso(i) + } + menu.append(s) + } + menu.show_all + end + + def updateMenus + updateMainMenu + #updateMoreMenu + end + + def updateMoreMenu(menu) + state=true + state=false if @selection.empty + + l=[menu.downloadDisks,menu.uploadDisksAndIsos,menu.uploadDisks] + l.each { |i| i.sensitive=state } + end + + def updateOtherBuildMenu + l=`vdn-list-networks -b` + #p "l:#{l}" + l.split.sort.each { |i| + f=File.basename(i) + e=Gtk::MenuItem.new(f) + e.signal_connect('activate') { + startTerminal("Edit and build network...", + "#{ENV['VDN_PATH']}/bin/vdn-build-network -e #{File.dirname(@dir)}/#{f}", true) + #startTerminal("#{$editor} #{f}", + #"#{$editor} #{File.dirname(@dir)}/#{f}/build", false) + + } + @otherBuildMenu.append(e) + } + end + + def createMoreMenu(menu) + + #p "createMoreMenu:#{menu}" + menu.append(Gtk::TearoffMenuItem.new) + + #p "add meth to menu : #{menu}" + class << menu + attr_accessor :downloadDisks, :uploadDisksAndIsos, :uploadDisks + end + + menu.downloadDisks=Gtk::MenuItem.new("Download cdrom(s) and/or disk(s)...") + menu.append(menu.downloadDisks) + menu.downloadDisks.signal_connect('activate') { |w| + whenDownload + } + + menu.uploadDisksAndIsos=Gtk::MenuItem.new("Upload cdrom(s) and/or disk(s)...") + menu.append(menu.uploadDisksAndIsos) + menu.uploadDisksAndIsos.signal_connect('activate') { |w| + whenUploadDisksAndIsos + } + + menu.uploadDisks=Gtk::MenuItem.new("Upload only disk(s)...") + menu.append(menu.uploadDisks) + menu.uploadDisks.signal_connect('activate') { |w| + whenUploadDisks + } + + menu.append(Gtk::MenuItem.new()) +=begin + @editMainConfigTemplate=Gtk::MenuItem.new("Edit template config (local) ..."); + menu.append(@editMainConfigTemplate) + @editMainConfigTemplate.signal_connect('activate') { |w| + startTerminal("#{$editor} config.template.local", + "[ ! -e #{ENV['VDN_PATH']}/config.template.local ] && \ + cp #{ENV['VDN_PATH']}/config.template #{ENV['VDN_PATH']}/config.template.local; \ + #{$editor} #{ENV['VDN_PATH']}/config.template", false) + } +=end + @editNetworkScript=Gtk::MenuItem.new("Edit network script..."); + menu.append(@editNetworkScript) + @editNetworkScript.signal_connect('activate') { |w| + startTerminal("Build network...", "#{ENV['VDN_PATH']}/bin/vdn-build-network -e #{@dir}", false) + } + + @buildNetwork=Gtk::MenuItem.new("(Re)build network..."); + menu.append(@buildNetwork) + @buildNetwork.signal_connect('activate') { |w| + #p "@dir:#{@dir}" + #p "ENV['NETWORK_DIR']:#{ENV['NETWORK_DIR']}" + + startTerminal("vdn-build-network", + "#{$VDN_PATH}/bin/vdn-build-network") + } + + + + menu.append(Gtk::MenuItem.new()) + + + @otherBuildMenu = Gtk::Menu.new + @otherBuildMenu.append(Gtk::TearoffMenuItem.new) + updateOtherBuildMenu + s=Gtk::MenuItem.new("Other \"build\" scripts...") + s.submenu=@otherBuildMenu + + menu.append(s) + + menu.append(Gtk::MenuItem.new()) + + @cloneNetwork=Gtk::MenuItem.new("Clone network..."); + menu.append(@cloneNetwork) + @cloneNetwork.signal_connect('activate') { |w| + startTerminal("vdn-clone-network", + "#{$VDN_PATH}/bin/vdn-clone-network", true, false) + #mySystem("vdn-clone-network") + + } + + @cloneNetwork=Gtk::MenuItem.new("Delete network..."); + menu.append(@cloneNetwork) + @cloneNetwork.signal_connect('activate') { |w| + startTerminal("vdn-clone-network", + "#{$VDN_PATH}/bin/vdn-delete-network") + #mySystem("vdn-clone-network") + @main.closeNet + } + + menu.append(Gtk::MenuItem.new()) + + @editNetworkGraph=Gtk::MenuItem.new("Inkscape net.svgz..."); + menu.append(@editNetworkGraph) + @editNetworkGraph.signal_connect('activate') { |w| + mySystem("inkscape #{@dir}/net.svgz &") + } + + @editNetworkGraph=Gtk::MenuItem.new("Delete net.svgz..."); + menu.append(@editNetworkGraph) + @editNetworkGraph.signal_connect('activate') { |w| + startTerminal("Delete #{@dir}/net.svgz", "rm -i #{@dir}/net.svgz", false) + } + + menu.append(Gtk::MenuItem.new()) + + @s=Gtk::MenuItem.new("Publish network..."); + menu.append(@s) + @s.signal_connect('activate') { |w| + startTerminal("vdn-publish-network", + "vdn-publish-network") + } + + menu.append(Gtk::MenuItem.new) + + s=Gtk::MenuItem.new("Terminal (in network directory)...") + s.signal_connect('activate') { + startTerminal("", "cd #{@dir}; bash", false) + } + menu.append(s) + + end + + def createMenu(menu) + menu.append(Gtk::MenuItem.new("")) + @tearoff=Gtk::TearoffMenuItem.new + menu.append(@tearoff) + + + #menu.append(Gtk::MenuItem.new("")) + + @start=Gtk::MenuItem.new("Download disk(s)...") + menu.append(@start) + @start.signal_connect('activate') { |w| whenDownload } + + menu.append(Gtk::MenuItem.new()) + + @start=Gtk::MenuItem.new("Start") + menu.append(@start) + @start.signal_connect('activate') { |w| whenStart } + + @startOnCdrom=Gtk::MenuItem.new("Start on cdrom") + menu.append(@startOnCdrom) + @startOnCdrom.signal_connect('activate') { |w| whenStartOnCdrom } + + @startSelectCdromMenu = Gtk::Menu.new + @startSelectCdrom=Gtk::MenuItem.new("Start on selected cdrom") + @startSelectCdrom.submenu=@startSelectCdromMenu + + updateIsosMenu(@startSelectCdromMenu) + + menu.append(@startSelectCdrom) + + @halt=Gtk::MenuItem.new("Halt") + menu.append(@halt) + @halt.signal_connect('activate') { |w| whenHalt } + + #@reboot=Gtk::MenuItem.new("Reboot") + #menu.append(@reboot) + #@reboot.signal_connect('activate') { |w| whenReboot } + #@reboot.sensitive=false + + @save=Gtk::MenuItem.new("Save") + menu.append(@save) + @save.signal_connect('activate') { |w| whenSave } + + @restart=Gtk::MenuItem.new("Restart") + menu.append(@restart) + @restart.signal_connect('activate') { |w| whenRestart } + + @ssh=Gtk::MenuItem.new("Ssh") + menu.append(@ssh) + @ssh.signal_connect('activate') { |w| whenSsh } + + + @viewer=Gtk::MenuItem.new("Viewer") + menu.append(@viewer) + @viewer.signal_connect('activate') { |w| whenViewer } + + #Gtk::Stock.add(Gtk::Stock::EXECUTE, "Terminal", Gdk::Window::CONTROL_MASK, Gdk::Keyval::GDK_T) + #@bviewer = Gtk::ImageMenuItem.new(Gtk::Stock::EXECUTE, @group) + #networksMenu.append(@bviewer) + #@bviewer.signal_connect("activate") { |w| whenViewer } + + + @config=Gtk::MenuItem.new("Config...") + menu.append(@config) + @config.signal_connect('activate') { |w| whenConfig } + + @infos=Gtk::MenuItem.new("Infos") + menu.append(@infos) + @infos.signal_connect('activate') { |w| whenInfos } + + @clean=Gtk::MenuItem.new("Clean") + menu.append(@clean) + @clean.signal_connect('activate') { |w| whenClean } + + @kill=Gtk::MenuItem.new("Kill") + menu.append(@kill) + @kill.signal_connect('activate') { |w| whenKill } + + menu.append(Gtk::MenuItem.new("")) + +=begin + @moreMenu = Gtk::Menu.new + @more=Gtk::MenuItem.new("More...") + @more.submenu=@moreMenu + + createMoreMenu(@moreMenu) + menu.append(@more) + @more.signal_connect('activate') { |w,e| + updateMoreMenu(menu) + false + } + + sep1=Gtk::MenuItem.new() + menu.append(sep1) +=end + + menu.show_all + end + + def updateMainMenu + state=true + state=false if @selection.empty + + @menu.children.each { |i| i.sensitive=state } + #@more.sensitive=true + @tearoff.sensitive=true + + end + + def showMenu + updateMainMenu + @menu.popup(nil, nil, 3, 0) + end + + def startTerminal(name, cmd, read=true, background=true, big=false) + @main.startTerminal(name, cmd, read, background, big) + end + + def whenStart + @selection.to_a.sort_by{ |i| i.name }.each { |i| + if ! @states[i.name] + p "Start #{i.name}" + if @consoles + cmd=$VDN_PATH+"/bin/vdn-start-wrapper -et #{i.name}" + @consoles.addTerm(i.name, cmd) + @notebook.set_page(2) + else + cmd=$VDN_PATH+"/bin/vdn-start-wrapper #{i.name}" + mySystem(cmd) + end + end + } + + end + + def whenStartOnCdrom + @selection.to_a.each { |i| + if ! @states[i.name] + p "Start #{i.name}" + if @consoles + cmd=$VDN_PATH+"/bin/vdn-start-wrapper -et -v BOOT_CDROM=1 #{i.name}" + p "addTerm:" + @consoles.addTerm(i.name, cmd) + @notebook.set_page(2) + else + cmd=$VDN_PATH+"/bin/vdn-start-wrapper -v BOOT_CDROM=1 #{i.name}" + mySystem(cmd) + end + end + } + + end + + def whenStartOnSelectedIso(iso) + @selection.to_a.each { |i| + if ! @states[i.name] + p "Start #{i.name}" + if @consoles + cmd=$VDN_PATH+"/bin/vdn-start-wrapper -et -v \"BOOT_CDROM=1;CDROM=#{iso}\" #{i.name}" + @consoles.addTerm(i.name, cmd) + @notebook.set_page(2) + else + cmd=$VDN_PATH+"/bin/vdn-start-wrapper -v \"BOOT_CDROM=1;CDROM=#{iso}\" #{i.name}" + mySystem(cmd) + end + end + } + + end + + def whenDownload + l="" + @selection.to_a.each { |i| + l="#{l} #{i.name}" + } + + startTerminal("vdn-download-disks #{l}", "#{$VDN_PATH}/bin/vdn-download-disks #{l}") + end + + def whenUploadDisks + l="" + @selection.to_a.each { |i| + l="#{l} #{i.name}" + } + startTerminal("vdn-upload-disks #{l}", "#{$VDN_PATH}/bin/vdn-upload-disks #{l}") + end + + def whenUploadDisksAndIsos + l="" + @selection.to_a.each { |i| + l="#{l} #{i.name}" + } + startTerminal("vdn-upload-disks -o #{l}", "#{$VDN_PATH}/bin/vdn-upload-disks -o #{l}") + end + + def whenHalt + + @selection.to_a.each { |i| + if @states[i.name] + mySystem($VDN_PATH+"/bin/vdn-halt #{i.name} &") + end + } + + end + + + def whenReboot + @selection.to_a.each { |i| + if @states[i.name] + mySystem($VDN_PATH+"/bin/vdn-ssh root@#{i.name} reboot &") + end + } + + end + + def whenRestart + @selection.to_a.each { |i| + if @states[i.name] + p "Restart #{i.name}..." + mySystem($VDN_PATH+"/bin/vdn-restart -g #{i.name} &") + end + } + end + + def whenSave + @selection.to_a.each { |i| + if @states[i.name] + mySystem($VDN_PATH+"/bin/vdn-save #{i.name} &") + end + } + + end + + def whenSsh + @selection.to_a.each { |i| + user=@main.net.combo.active_text + if @ssh && ENV['VDN_EXTERNAL_SSH'] != "1" + cmd=$VDN_PATH+"/bin/vdn-ssh-loop -X #{user}@#{i.name}" + @ssh.addTerm(i.name, cmd) + @notebook.set_page(3) + else + startTerminal("vdn-ssh-loop -X #{user}@#{i.name}", + "#{$VDN_PATH}/bin/vdn-ssh-loop -X #{user}@#{i.name}") + end + } + + end + + def whenViewer + @selection.to_a.each { |i| + if @states[i.name] + mySystem($VDN_PATH+"/bin/vdn-spice-viewer #{i.name} &") + end + } + + end + + def whenConfig + @selection.to_a.each { |i| + startTerminal("#{$editor} #{i.name}.conf", + "#{$editor} #{@dir}/#{i.name}.conf", false) + } + + end + + + def whenInfos + @selection.to_a.each { |i| + startTerminal("vdn-infos #{i.name}", + "#{$VDN_PATH}/bin/vdn-infos #{i.name}") + } + + end + + def whenClean + l="" + @selection.to_a.each { |i| + l="#{l} #{i.name}" + } + + startTerminal("vdn-clean #{l}", "#{$VDN_PATH}/bin/vdn-clean #{l}", false) if l != "" + + end + + def whenHaltAll + @hosts.each_value { |i| + if @states[i.name] + mySystem($VDN_PATH+"/bin/vdn-halt #{i.name} &") + end + } + end + + def whenKillAll + @hosts.each_value { |i| + if @states[i.name] + mySystem($VDN_PATH+"/bin/vdn-kill -s #{i.name} &") + end + } + end + + + def whenKill + @selection.to_a.each { |i| + if @states[i.name] + mySystem($VDN_PATH+"/bin/vdn-kill -s #{i.name} &") + end + } + end + + def startVnc(name) + Gtk.queue do + @notebook.set_page(2) + end + cmdFifoPath="#{ENV['TMPDIR']}/vdn-vnc-#{ENV['USER']}-#{name}-fifo" + mySystem("mkfifo #{cmdFifoPath} 2> /dev/null") + mySystem("chmod 600 #{cmdFifoPath}") + vncSock="#{ENV['TMPDIR']}/vdn-vnc-#{ENV['USER']}-#{name}-socket" +=begin + Thread.new { + + Gtk.queue do + label=Gtk::Label.new(name) + vnc=VncViewer.new(self, label, name, $VDN_PATH, vncSock, cmdFifoPath) + @hosts[name].vncViewer=vnc + @consolesNotebook.append_page(vnc, label) + @consolesNotebook.show_all + vnc.plug + @consolesNotebook.set_page(@consolesNotebook.n_pages-1) + end + } +=end + end + + + + def startSpiceOld(name) + Gtk.queue do + @notebook.set_page(2) + end + #cmdFifoPath="#{ENV['TMPDIR']}/vdn-vnc-#{ENV['USER']}-#{name}-fifo" + #mySystem("mkfifo #{cmdFifoPath} 2> /dev/null") + #mySystem("chmod 600 #{cmdFifoPath}") + + Thread.new { + desc="startSPiceOld" + $threads.push(desc) + Gtk.queue do + label=Gtk::Label.new(name) + #spice=Gtk::EventBox.new + spice=SpiceViewer.new(name) + sleep 2 + #spice=Gtk::EventBox.new + #@hosts[name].spiceViewer=spice + #@consolesNotebook.append_page(spice, label) + + #@consolesNotebook.show_all + + #spice.plug + + #@consolesNotebook.set_page(@consolesNotebook.n_pages-1) + + end + $threads.delete_at($threads.index(desc)) + } + end + + def hostsSorted + systems=[] + @hosts.each_value { |i| systems.push(i) } + systems.sort! { |a,b| + r=0 + if a.y < b.y+50 && a.y < b.y-50 + r=-1 + elsif a.y > b.y+50 && a.y > b.y-50 + r=1 + elsif a.x < b.x + r=-1 + elsif a.x > b.x + r=1 + end + r + } + return systems + end + + + def select(m, b) + + if ! m && b!=3 + @selection.clear + return + end + + case @main.mod + when "Shift" + found=false + last=@selection.array[0] + return if !last + sorted=hostsSorted + il=sorted.index(last) + im=sorted.index(m) + + sorted=sorted.reverse if im>il + sorted.each { |i| + if i==m + found=true + end + if found + if i.isSel + break; + else + @selection.add(i) + end + + end + } + when "Control" + if m && ! m.isSel + @selection.add(m) + else + @selection.del(m) if b!=3 + end + + else + if m && ! m.isSel + @selection.clear + @selection.add(m) + end + end + + if b==3 + showMenu + end + + end + + + def parseEvent(w, e) + case e.class.to_s + when "Gdk::EventButton" + if e.event_type == Gdk::Event::Type::BUTTON2_PRESS + rs=Gdk::Rectangle.new(e.x, e.y, 1, 1) + + m=nil + @hosts.each_value { |i| + x=i.rx; y=i.ry; w=i.rw; h=i.rh + r=Gdk::Rectangle.new( + x*@cx+@dx+@bx, + y*@cy+@dy+@by, + w*@cx+1, h*@cy+1) + + m=i if r.intersect(rs) + break if m + } + + elsif e.event_type == Gdk::Event::Type::BUTTON_PRESS + + rs=Gdk::Rectangle.new(e.x, e.y, 1, 1) + + m=nil + @hosts.each_value { |i| + x=i.rx; y=i.ry; w=i.rw; h=i.rh + r=Gdk::Rectangle.new( + x*@cx+@dx+@bx, + y*@cy+@dy+@by, + w*@cx+1, h*@cy+1) + + m=i if r.intersect(rs) + break if m + } + + if m==nil + @mx=e.x + @my=e.y + else + @mx=@my=nil + end + + if e.button == 3 + showMenu + @mx=@my=nil + select(m, e.button) if @selection.empty + + else + select(m, e.button) + end + else + if @selRec + undrawSelRec + end + @mx=@my=nil + end + when "Gdk::EventMotion" + if @mx + drawSelRec(@mx, @my, e.x, e.y) + updateSelRec + end + end + + end + + def updateSelect + @selection.array.each { |i| + i.sel(self) + } + end + + + + def updateSelRec + @hosts.each_value { |i| + state=false + x=i.x; y=i.y; w=i.rw; h=i.rh + _x=x*@cx+@dx+@bx + _y=y*@cy+@dy+@by + _w=w*@cx+1 + _h=h*@cy+1 + r=Gdk::Rectangle.new(_x, _y, _w, _h) + s=@selRec + if r.intersect(@selRec).to_a==r.to_a + state=true + end + + if state + @selection.add(i) if ! i.isSel + else + @selection.del(i) if i.isSel + end + + } + end + + + + def drawSelRec(x1, y1, x2, y2) + return if @gc==nil + if @selRec + undrawSelRec + end + + if x1>x2 + t=x2; x2=x1; x1=t + end + + if y1>y2 + t=y2; y2=y1; y1=t + end + + @selRec=Gdk::Rectangle.new(x1, y1, x2-x1, y2-y1) + + @gc.function = Gdk::GC::XOR + @gc.fill = Gdk::GC::Fill::SOLID + @gc.rgb_fg_color = @grey + @gc.set_line_attributes(1, Gdk::GC::LineStyle::ON_OFF_DASH, Gdk::GC::CapStyle::ROUND, Gdk::GC::JoinStyle::ROUND) + + return if @area.window==nil + + @area.window.draw_rectangle(@gc, false, x1, y1, x2-x1, y2-y1) + @gc.function = Gdk::GC::COPY + + + end + + + def undrawSelRec + return if @gc==nil + if @selRec + @gc.function = Gdk::GC::XOR + @gc.fill = Gdk::GC::Fill::SOLID + @gc.rgb_fg_color = @grey + @gc.set_line_attributes(1, Gdk::GC::LineStyle::ON_OFF_DASH, Gdk::GC::CapStyle::ROUND, Gdk::GC::JoinStyle::ROUND) + + return if @area.window==nil + + @area.window.draw_rectangle(@gc, false, @selRec.x, @selRec.y, @selRec.width, @selRec.height) + @gc.function = Gdk::GC::COPY + + @selRec=nil + end + end + + + def drawBoxs + @hosts.each { |k,v| + if @states[k] + v.draw(self, @green) + else + v.draw(self, @red) + end + } + end + + + def parseInkscape + + @gw=@gh=nil + Zlib::GzipReader.open( @graphfile) do |aFile| + r=false + x=y=width=height=label=nil + tx=ty=nil + + aFile.each_line do |line| + + case line + + when /transform="translate/ + + if !tx + tx=line.chomp.sub(/^.*translate.([-0-9.]+).*$/, '\1').to_i + ty=line.chomp.sub(/^.*translate.*,([-0-9.]+).*$/, '\1').to_i + end + + when /width=/ + if ! @gw + @gw=line.chomp.sub(/^.*"([-0-9.]+)".*$/, '\1').to_i + + else + width=line.gsub(/[^0-9.]/, "").to_i + end + + when /height/ + if ! @gh + @gh=line.chomp.sub(/^.*"([-0-9.]+)".*$/, '\1').to_i + else + height=line.gsub(/[^0-9.]/, "").to_i + end + + when // + + + case line + when /label=/ + label=line.chomp.sub(/^.*"#([^"].*)".*$/, '\1') + when /x=/ + x=line.gsub(/[^0-9.]/, "").to_i + when /y=/ + y=line.gsub(/[^0-9.]/, "").to_i + end + + if ( !x || !y || !width || !height ) && label!=nil + $stderr.puts "rec : #{label} incomplet !" + else + if label + @hosts[label]=Host.new( + label, x+tx, y+ty, width, height) + @states[label]=false + end + end + end + end + end + + end + + + def parseGraphviz + @gw=@gh=tx=ty=gw=gh=nil + + rw=1.0; rh=1.0 + + svg=RSVG::Handle.new_from_file(@graphfile) + svg.close + @gw=svg.width + @gh=svg.height + + Zlib::GzipReader.open( @graphfile) do |aFile| + r=false + x=y=width=height=label=nil + + aFile.each_line do |line| + case line + when /transform.*translate/ + if !tx + tx=line.chomp.sub(/^.*translate.([-0-9.]+).*$/, '\1').to_i + ty=line.chomp.sub(/^.*translate.* ([-0-9.]+).*$/, '\1').to_i + end + #when /class=.*node.*title/ + # label=line.chomp.sub(/^.*title>(.*)<.*$/, '\1') + when /^[^%]*$/ + label=line.chomp.sub(/^.*title>(.*)<.*$/, '\1') + when /polygon/ + points=line.chomp.sub(/^.*points="(.*)".*$/, '\1') + points=points.split(" ") + x1=points[0].sub(/^([-0-9.]+).*$/, '\1').to_i + y1=points[0].sub(/^[-0-9.]+,([-0-9.]+)$/, '\1').to_i + x2=points[2].sub(/^([-0-9.]+).*$/, '\1').to_i + y2=points[2].sub(/^[-0-9.]+,([-0-9.]+)$/, '\1').to_i + if x1<x2 + x=x1; width=x2-x1 + else + x=x2; width=x1-x2 + end + + if y1<y2 + y=y1; height=y2-y1 + else + y=y2; height=y1-y2 + end + + if label + label.gsub!("-", "-") + @hosts[label]=Host.new( + label, (x+tx)*rw, (y+ty)*rh, width*rw, height*rh) + @states[label]=false + else + gw=width; gh=height + rw=@gw*1.0/gw; rh=@gh*1.0/gh + end + + end + + + end + end + end + + def close + + + if @graphTimeout + Gtk.timeout_remove(@graphTimeout) + @graphTimeout=nil + end + + if @netTimeout + #p "remove netDetector" + Gtk.timeout_remove(@netTimeout) + @netTimeout=nil + end + + @notebook.remove_page(1) + + if @consolesNotebook + if @consoles + #@consolesNotebook.remove_page(@consolesNotebook.page_num(@consoles)) + @consoles.close + @consoles.destroy + @consoles=nil + end + + if @ssh + + #@notebook.remove_page(@notebook.page_num(@ssh)) + @ssh.close + @ssh.destroy + @ssh=nil + end + + end + @consolesNotebook=nil + @notebook.remove_page(1) + @notebook.remove_page(1) + @notebook.set_page(0) + + @hosts={} + @states={} + @graphfile=nil + + end + +end + +class Host + attr_reader :rectangle, :rectangleSmall, :name, :isSel + attr_reader :x, :y, :w, :h + attr_reader :rx, :ry, :rw, :rh + attr_accessor :vncViewer, :spiceViewer + + def initialize(name, x, y, w, h) + @isSel=false + @name=name; @x=x; @y=y; @w=w; @h=h + @rx=@x; @ry=@y; @rw=@w; @rh=@h + @black = Gdk::Color.parse("black") + @vncViewer=nil + @spiceViewer=nil + end + + def draw(panel, color) + + @area=panel.area + @gc=panel.gc + + return if !@gc || !panel.cx + + @gc.function = Gdk::GC::COPY + @gc.fill = Gdk::GC::Fill::SOLID + @gc.rgb_fg_color = color + @gc.set_line_attributes(1, Gdk::GC::LineStyle::SOLID, Gdk::GC::CapStyle::ROUND, Gdk::GC::JoinStyle::ROUND) + + cx=panel.cx; cy=panel.cy + dx=panel.dx; dy=panel.dy + bx=panel.bx; by=panel.by + + return if @area.window==nil + + begin + @area.window.draw_rectangle(@gc, false, @x*cx+dx+bx, @y*cy+dy+by, @w*cx+1, @h*cy+1) + rescue + p "Error in draw..." + p $! + end + + @gc.rgb_fg_color = @black + end + + def sel(panel) + color=panel.selColor + cx=panel.cx; cy=panel.cy + dx=panel.dx; dy=panel.dy + bx=panel.bx; by=panel.by + + @isSel=true + + @gc.function = Gdk::GC::XOR + @gc.fill = Gdk::GC::Fill::SOLID + @gc.rgb_fg_color = color + @gc.set_line_attributes(1, Gdk::GC::LineStyle::SOLID, Gdk::GC::CapStyle::ROUND, Gdk::GC::JoinStyle::ROUND) + + + return if @area.window==nil + + #p "### update draw in sel method" + + @area.window.draw_rectangle(@gc, true, @x*cx+dx+bx+2, @y*cy+dy+by+2, @w*cx+1-3, @h*cy+1-3) + @gc.function = Gdk::GC::COPY + + end + + def unsel(panel) + + return if @gc==nil + color=panel.selColor + cx=panel.cx; cy=panel.cy + dx=panel.dx; dy=panel.dy + bx=panel.bx; by=panel.by + @isSel=false + @gc.function = Gdk::GC::XOR + @gc.fill = Gdk::GC::Fill::SOLID + @gc.rgb_fg_color = color + @gc.set_line_attributes(1, Gdk::GC::LineStyle::SOLID, Gdk::GC::CapStyle::ROUND, Gdk::GC::JoinStyle::ROUND) + + return if @area.window==nil + + @area.window.draw_rectangle(@gc, true, @x*cx+dx+bx+2, @y*cy+dy+by+2, @w*cx+1-3, @h*cy+1-3) + @gc.function = Gdk::GC::COPY + end + +end + + +class Selection + def initialize(panel) + @sel=[] + @panel=panel + + end + + def add(m) + @sel.push(m) if ! @sel.include?(m) + m.sel(@panel) + @panel.updateMenus + end + + def del(m) + @sel.delete(m) + m.unsel(@panel) + @panel.updateMenus + end + + def clear + @sel.each { |i| i.unsel(@panel) } + @sel=[] + @panel.updateMenus + end + + def array + return @sel + end + + def empty + return @sel.size==0 + end + + def to_a + return @sel + end +end + + class Gtk::Browser < Gtk::VBox + attr_accessor :banner + def initialize + super + pack_start(@text=Gtk::TextView.new, true, true) + @text.justification = Gtk::JUSTIFY_CENTER + @text.cursor_visible=false + + end + def location=(url) + @url=url + @text.editable=true + @text.buffer.text="\n" + + w=Gtk::Image.new(@banner) + w.show_all + bold = @text.buffer.create_tag(nil, + { + 'weight' => + Pango::Weight::BOLD + }) + + iter=@text.buffer.end_iter + anchor = @text.buffer.create_child_anchor(iter) + @text.add_child_at_anchor(w, anchor) + @text.buffer.insert(iter, "\n\nBienvenue !\n\n", bold) + @text.buffer.insert_at_cursor("\n\n Cliquez sur le bouton ci-dessous pour accéder à la documentation dans votre navigateur : \n\n") + iter=@text.buffer.end_iter + anchor = @text.buffer.create_child_anchor(iter) + b1=Gtk::Button.new("#{@url}") + b1.show + b1.signal_connect("clicked") { mySystem("xdg-open #{@url} &") } + @text.add_child_at_anchor(b1, anchor) + @text.buffer.insert_at_cursor("\n\n") + @text.editable=false + end + end + + +### begin: pterms + +#!/usr/bin/env ruby + +require 'gtk2' + +if FileTest.exist?(ENV["VDN_PATH"]+"/distribs/hosts/"+ENV["HOST_RELEASE"]+"/vte.so") + #puts "load "+ENV["VDN_PATH"]+"/files/"+ENV["HOST_RELEASE"]+"/vte.so" + require ENV["VDN_PATH"]+"/distribs/hosts/"+ENV["HOST_RELEASE"]+"/vte.so" +else + require 'vte' +end + +class String + def to_b; self.downcase=="true" || self=="1" ; end +end + + +class Console < Gtk::EventBox + attr_reader :eventbox, :name, :term, :vte, :isGrouped + attr_accessor :icoButton, :area, :barea + attr_accessor :x, :y + + def initialize(term, stock) + @term=term + @panel=@term.panel + @stock=stock + super() + + add(@frame=Gtk::Frame.new) + @frame.add(@vbox=Gtk::VBox.new) + @vbox.border_width=2 + @vbox.pack_start(@eventbox=Gtk::EventBox.new,false,false) + @eventbox.height_request=18 + @eventbox.add(@hbox=Gtk::HBox.new) + + @hbox.pack_start(@label=Gtk::Label.new(), false, false) + @hbox.pack_start(f=Gtk::Frame.new, true, true) + f.shadow_type=Gtk::SHADOW_NONE + + @bclose=addButton(@hbox, @panel.iclose, + "Close", "closeConsoleAccel", :whenCloseButton) + + signal_connect('destroy') { |w| whenDestroy } + + @vbox.pack_start(@hbox2=Gtk::HBox.new, true, true) + + @vte=Vte::Terminal.new + + @vte.signal_connect('child-exited') { |w| whenExited } + + @vte.signal_connect('contents-changed') { |w| + Gtk.timeout_add(300) { @update=true; false; } + } + + @scrollbar=Gtk::VScrollbar.new(@vte.adjustment) + + p=props('rightBar').to_b + @hbox2.pack_start(@scrollbar, false, false) if !p + @hbox2.pack_start(@vte, true, true) + @hbox2.pack_start(@scrollbar, false, false) if p + + signal_connect('enter_notify_event') { |w,e| + if @panel.props("focusFollowMouse").to_b + focus + end + + } + + signal_connect('leave-notify-event') { |w,e| + name="GDK_NOTIFY_ANCESTOR" + if e.detail.name == name + deselect(self) + end + } + + + signal_connect('button-press-event') { |w,e| focus } + + # Button event (focus + paste clipboard) + + @vte.signal_connect('button-press-event') { |w,e| + case e.button + when 1; focus + when 2; broadcastEvent(e) + end + false + } + + # Button event (paste clipboard) + + @vte.signal_connect('button-release-event') { |w,e| + broadcastEvent(e) if e.button == 2 + } + + # Key event + @leftAccel=Gtk::Accelerator.parse( + @panel.props("switchTermRightAccel")) + + + init(term) + end + + def init(term) + @term=term + @pid=nil + @label.text=@term.name + + @vte.set_size(80,24) + @vte.set_word_chars(".a-zA-Z_0-9//-") + @vte.set_colors(Gdk::Color.parse(props('fgColor')), + Gdk::Color.parse(props('bgColor')),[]) + @vte.audible_bell=props('audibleBell').to_b + @vte.visible_bell=props('visibleBell').to_b + @vte.scrollback_lines=props('scrollbackLines').to_i + + a=args(term.cmd) + + #if ENV['GUI_INTERNAL'] == "1" + # @pid=@vte.fork_command(a[0], a) + #else + + #$stderr.puts "a:#{a}" + + @pid=@vte.fork_command(:argv => a) + #end + + show_all + + @bclose.hide if ! props("canClose").to_b + setFontArea + setHeader + + end + + def setHeader + if ! props("header").to_b || + ! @term.panel.props("globalHeaders").to_b + @eventbox.height_request=4 + @hbox.hide + else + @eventbox.height_request=18 + @hbox.show + end + end + + def props(name) + @term.props(name) + end + + def args(s) + r=[] + s.gsub(/'([^']*)'|"([^"]*)"|([^[:space:]]+)/) { |m| + r.push("#{$1}#{$2}#{$3}") + } + return r + end + + def addButton(w,p,t,a,handler) + i=Gtk::Image.new(p) + w.pack_start(b=Gtk::ToolButton.new(i), false, false) + + accel=props(a) + + b.signal_connect('clicked') { |w,e| send(handler) } + return b + end + + def broadcastEvent(e) + pterms=@term.panel + panelView=@term.panel + if @isGrouped && pterms.view.currentPanelView==panelView && + self==panelView.selected + pterms.view.sendEvent(panelView, self, e) + end + false + end + + def myClampPanel(wlen, adj, min, len) + value=adj.value + if min+len > value+wlen + delta=min+len-(value+wlen) + adj.value=value+delta + else + if min<value + adj.value=min + end + end + end + + + def clampPanel + a=allocation; x=a.x; y=a.y + p=parent.parent + myClampPanel(p.allocation.height, p.vadjustment, a.y, a.height) + myClampPanel(p.allocation.width, p.hadjustment, a.x, a.width) + end + + def deselect(c) + return if @term.panel.selected!=c + color=@term.panel.cnormal + w=c.eventbox + w.modify_bg(Gtk::STATE_NORMAL,color) if ! w.destroyed? + @term.panel.selected=nil + term.panel.main.main.add_main_accel_group + end + + def focus + @vte.has_focus=true + @vte.grab_focus + + selected=@term.panel.selected + return if selected==self + + deselect(selected) if selected + + @term.panel.selected=self + + color=@term.panel.cselect + @eventbox.modify_bg(Gtk::STATE_NORMAL,color) + + + term.panel.main.main.add_consoles_accel_group + + clampPanel + end + + def setFontArea + setFont(props("gridFont")) + end + + def setFont(font) + @vte.set_font(font, Vte::TerminalAntiAlias::USE_DEFAULT) + end + + def whenCloseButton + whenClose + end + + def whenDestroy + whenClose + end + + def whenExited + whenClose + end + + def whenClose + if @term + @term.close + @term.panel.update + end + end + + def close + return if ! parent # already closed (and stocked) + + begin + Process.kill('TERM',@pid) if @pid && (@pid != -1) + rescue + end + + deselect(self) + + s=@term.panel.selected + @term.panel.selectTerm(self, "right") if !s||s==self + deselect(self) if @term.panel.selected==self + + parent.remove(self) + + @vte.reset(true, true) + @stock.push(self) + @term.panel.update + end +end + +class ConsolesView < Gtk::Frame + attr_reader :main + attr_reader :iclose + attr_reader :cnormal, :cflash, :cselect + attr_reader :props, :stock, :accelsKeys + attr_accessor :selected + def initialize(main, list) + @main=main + super() + @selected=nil + @terms=[] + @stock=PtermsStock.new + @propsStack=[] + @x=@y=0 + + @props={ + + # Application property + + "globalHeaders" => "true", + "focusFollowMouse" => "true", + + # Main window properties + "tooltips" => "true", + + # Panel properties + + "gridNbCols" => "2", + + # Terminal properties + + "inGrid" => "true", + "gridFont" => "Monospace 8", + "zoomFont" => "Monospace 10", + + "header" => "true", + "canClose" => "true", + + "minWidth" => "100", + "minHeight" => "50", + + "fgColor" => "black", + "bgColor" => "white", + + "audibleBell" => "true", + "visibleBell" => "true", + "scrollbackLines" => "1000", + "rightBar" => "false", + + # Accelerators + + # Main window accels + "quitAccel" => "<Ctrl>x", + "toggleHeadersAccel" => "<Alt>h", + "toggleButtonsTextsAccel" => "<Alt>t", + "toggleFocusFollowMouseAccel" => "<Alt>f", + + "switchTermLeftAccel" => "<Shift><Alt>Left", + "switchTermRightAccel" => "<Shift><Alt>Right", + "switchTermUpAccel" => "<Shift><Alt>Up", + "switchTermDownAccel" => "<Shift><Alt>Down", + + "increaseZoomAccel" => "<Shift><Alt>KP_Add", + "decreaseZoomAccel" => "<Shift><Alt>KP_Subtract", + + # Terminal accels + "groupToggleAccel" => "<Ctrl>g", + "moveAccel" => "<Ctrl>m", + "closeConsoleAccel" => "<Ctrl>q", + + } + @accelsKeys=[] + @props.keys.each { |p| + next if (p=~/Accel/) == nil + @accelsKeys.push(Gtk::Accelerator.parse(props(p))) + } + # build small pixbufs (used by consoles) + + w=9; h=9 + @iclose=createPixbuf(Gtk::Stock::CLOSE, w, h) + + @cnormal=Gdk::Color.parse("#E8E8E8") + @cselect=Gdk::Color.parse("#84D7E5") + @cflash=Gdk::Color.parse("#ff4242") + add(@grid=Gtk::ScrolledWindow.new) + @grid.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) + @grid.add_with_viewport(@grid=Gtk::Table.new(1,1)) + @grid.homogeneous=false + end + def props(name) + raise "Invalid property : #{name}" if ! @props[name] + @props[name] + end + def setProps(name, value) + raise "Invalid property : #{name}" if ! @props[name] + @props[name]=value + end + def createPixbuf(t,w,h) + return render_icon(t,s=Gtk::IconSize::MENU).scale(w, h) + end + def getPropsDup + return @props.dup + end + def addToGrid(widget, x, y) + @grid.attach(widget, x, x+1, y, y+1, + Gtk::EXPAND|Gtk::FILL, + Gtk::EXPAND|Gtk::FILL, 1, 1) if ! widget.parent + end + def selectTerm(c, direction) + end + def update + @terms.each { |t| redraw(t.view.vte) if t.view } + end + + def redraw(widget) + Gtk.timeout_add(200) { + begin + widget.queue_draw_area(0, 0, 10000, 10000) + rescue + end + false + } + end + def addTerm(name, cmd) + + #p "addTerm : #{name} #{cmd}" + + @terms.push(t=Term.new(self, name, cmd)) + n=props("gridNbCols").to_i + m=0 + if ! @grid.children.empty? + @grid.children.each { |i| + x=i.term.x + y=i.term.y + if y*n+x > m + m=y*n+x + end + } + @y=m/n + @x=m%n+1 + else + @x=@y=0 + end + if @x >= n + @y=@y+1 + @x=0 + end + t.build(@x,@y) + update + redraw(t.view.vte) + @x=@x+1 + if @x >= props("gridNbCols").to_i + @x=0; @y=@y+1 + end + end + + def close + @terms.each { |t| + t.close + } + end +end + +class Term + attr_reader :name, :cmd, :panel + attr_reader :x, :y + attr_accessor :view + + def initialize(panel, name, cmd) + @panel=panel + @props=panel.getPropsDup if panel + @name=name + @cmd=cmd + @view=nil + end + + def props(name) + raise "Invalid property : #{name}" if ! @props[name] + @props[name] + end + + def build(x,y) + @x=x; @y=y + @view=@panel.stock.pop(self) + @panel.addToGrid(@view, x, y) + w=@panel.props("minWidth").to_i + h=@panel.props("minHeight").to_i + @view.vte.set_size_request(w,h) + end + + def close + @view.close if @view + @view=nil + end +end + + +class PtermsStock + def initialize + @stock=[] + end + + def pop(term) + c=@stock.pop + if !c + c=Console.new(term, self) + else + c.init(term) + end + return c + end + + def push(console) + @stock.push(console) + end +end + +class ConsolesPanel < Gtk::EventBox + attr_reader :main + + def initialize(main, cmd, list="", comment="") + @main=main + super() + @cmd=cmd + @list=list + @cv=ConsolesView.new(@main, list).show_all + add(@vbox=Gtk::VBox.new) + @comment=comment + + + signal_connect('leave-notify-event') { |w,e| + selected=@cv.selected + selected.deselect(selected) if selected + } + + if @comment != "" + @vbox.pack_start(Gtk::Label.new(@comment), false, false) + end + + @vbox.pack_start(@hbox=Gtk::HBox.new, false, false) + @hbox.pack_start(@toolbar=Gtk::HBox.new, true, true) + + @vbox.add(@cv) + @cv.focus=true + + + #initBar + + end + + def addTerm(name, cmd=nil) + + + #p "addTerm name:#{name} cmd:#{cmd}" + cmd=@cmd+name if cmd == nil + #p "addTerm name:#{name} cmd:#{cmd}" + @cv.addTerm(name, cmd) + end + + def setProps(name, value) + @cv.setProps(name, value) + end + + def close + #p "close:cv:#{@cv}" + @cv.close + end +end + +class SshPanel < ConsolesPanel + + def initialize(main, cmd, list="", comment="") + super(main, cmd, list, comment) + end + + def addTerm(name, cmd=nil) + #p "addTerm ssh:cv:#{@cv}" + user=@main.net.combo.active_text + #p "addTerm name:#{name} cmd:#{cmd}" + cmd=@cmd+user+"@"+name if cmd == nil + #p "addTerm name:#{name} cmd:#{cmd}" + @cv.addTerm(name, cmd) + end + +end + +def startNet + if ! $main + + #p "Create network window" + net=Vdn.new + + $main=net + net.startListener + + trap("TERM") { r=net.whenQuit; Gtk::main_quit if r } + else + $main.clean + $main.open + end + +end + + + +### end: pterm + +# main + +#GC.disable + +#p "start GC" +#$lock=true + +#sleep 0.2 +#GC.enable +#GC.start +#GC.disable + +#$lock=false +#p "disable GC" + +ENV['VDN_GUI']="1" +#puts "ENV['VDN_GUI']:#{ENV['VDN_GUI']}" + + +$LOG_FIFO = File.open("#{ENV['TMPDIR']}/vdn-#{ENV['USER']}-gui-log", "r+") + +$VDN_PATH=File.dirname($0) +$VDN_PATH=File.dirname($VDN_PATH) + +#require "#{$VDN_PATH}/bin/vdn-gui-pterms.rb" +#require "#{$VDN_PATH}/bin/vnc-viewer/vdn-vnc-viewer-lib.rb" +#require "#{$VDN_PATH}/bin/vdn-spice-viewer-lib.rb" + +fifo="#{ENV['TMPDIR']}/vdn-gui-#{ENV['USER']}-fifo-ctrl" +#if File.exist?(fifo) +# mySystem("rm #{fifo}") +#end + +startNet + +Gtk.main_with_queue(100) diff --git a/vdn/bin/vdn-halt b/vdn/bin/vdn-halt new file mode 100755 index 0000000..ab86a60 --- /dev/null +++ b/vdn/bin/vdn-halt @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` arrête le système (la sauvegarde est effectuée). + +`synopsis` + +-h : affiche cette aide + +Retourne 1 en cas d'erreur. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi +} + +haltSystemTgz() { + local r=0 + for i in 1 2 3; do + if vdn-alive $GUEST_NAME; then + echo "Save $GUEST_NAME..." + set +e + vdn-save $GUEST_NAME + r=$((r+$?)) + set -e + if [ $? -eq 0 ]; then + break + fi + #sleep 1 + fi + done + + #sleep 2 + + if [ $r = 0 ]; then + vdn-kill $GUEST_NAME || error "Échec de l'arrêt de $GUEST_NAME" + else + return 1 + fi + #return $r +} + + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +loadGuestVars $GUEST_NAME + +if [ ! -e $GUEST_PATH ]; then + error "Le système $GUEST_NAME n'existe pas !" +fi + +case "$MODE" in + tgz|tgz2) haltSystemTgz;; + cow|direct|overlay) vdn-ssh root@$GUEST_NAME poweroff;; + *) error "Mode : \"$MODE\" invalide !";; +esac diff --git a/vdn/bin/vdn-halt-all b/vdn/bin/vdn-halt-all new file mode 100755 index 0000000..139e5a1 --- /dev/null +++ b/vdn/bin/vdn-halt-all @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` arrête les systèmes (la sauvegarde est effectuée). + +`synopsis` + +-h : affiche cette aide + +Retourne 1 en cas d'erreur. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage || : +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +for i in $(vdn-alives); do + vdn-halt $i +done diff --git a/vdn/bin/vdn-infos b/vdn/bin/vdn-infos new file mode 100755 index 0000000..57e50a7 --- /dev/null +++ b/vdn/bin/vdn-infos @@ -0,0 +1,107 @@ +#!/usr/bin/env bash + +set -eu + +VAR="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system [variable] +EOF +} + +help() { + cat << EOF + +`basename $0` affiche des informations sur un système. +Si une variable est précisée, son contenu est affiché. + +Exemple : `basename $0` societe PUBLIC_IP + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hr" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + [ $# -gt 2 ] && usage + [ $# -lt 1 ] && usage + + [ $# -eq 2 ] && VAR=$2 + + GUEST_NAME="$1" +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +. $VDN_PATH/allocators/$VDN_RESOURCES_ALLOCATOR + +setGuestVars $GUEST_NAME + +GUEST_OWNER=$USER + +loadGuestVars $GUEST_NAME + +PUBLIC_IP=$(computePublicIp $GUEST_NAME 0 || :) +MAC_0=$(computeMacAddr $GUEST_NAME 0) + +if [ -z "$VAR" ]; then + cat <<-EOF + MODE=$MODE + GUEST_NAME=$GUEST_NAME + GUEST_PATH="$GUEST_PATH" + GUEST_SYS=$GUEST_SYS + EMULATOR="$EMULATOR" + MEMORY="$MEMORY" + HDA="$HDA" + AUFS_SIZE="$AUFS_SIZE" AUFS_FILE="$AUFS_FILE" + SWAP_SIZE="$SWAP_SIZE" SWAP_FILE="$SWAP_FILE" + SAVE_FILE="$SAVE_FILE" + NETWORKS="$NETWORKS" + SERVICES="$EXTRA_SERVICES" + REDIRS="$REDIRS" + PUBLIC_IP="$PUBLIC_IP" + MAC_0="$MAC_0" + EOF + + if $VDN_PATH/bin/vdn-alive $GUEST_NAME; then + if [ -e $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs ]; then + echo + echo "Redirections :" + cat $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs + fi + fi + + echo + echo "Dernières sauvegardes : " + [ -e $SAVE_FILE ] && du -h $SAVE_FILE || echo "Never saved" + if [ -n "$HDB" ]; then + [ -z "$SAVE_DIR_HDB" ] && SAVE_DIR_HDB=$SAVE_DIR || : + [ -e $SAVE_DIR_HDB/$HDB ] && du -h $SAVE_DIR_HDB/$HDB || echo "Never saved" + fi + echo + +else + echo ${!VAR} +fi diff --git a/vdn/bin/vdn-kill b/vdn/bin/vdn-kill new file mode 100755 index 0000000..a429153 --- /dev/null +++ b/vdn/bin/vdn-kill @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +set -eu + +QUIET=0 +SILENT=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-q] [-s] system +EOF +} + +help() { + cat << EOF + +`basename $0` tue tous les processus associés au système. + +`synopsis` + +ATTENTION : cette action correspond à une coupure d'alimentation. + Dans le cas d'un système utilisant une union de systèmes de + fichiers, les modifications seront perdues ! + +-h : affiche cette aide +-q : n'affiche pas les PIDS des processus tué. +-s : pas d'erreur si le système n'est pas lancé. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hqs" opt; do + case $opt in + h) help; exit 0;; + q) QUIET=1;; + s) SILENT=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi +} + +killSystem() { + pids="$(ps -w -w ux | grep -E $GUEST_NAME[-]$USER | tr -s ' ' | cut -d ' ' -f 2)" + if [ -z "$pids" ]; then + if [ $SILENT = 1 ]; then + exit 0 + fi + echo "Le système virtuel $GUEST_NAME.conf n'est pas lancé !" >&2 + exit 1 + fi + + [ $QUIET = 0 ] && \ + echo "Kill $GUEST_NAME: Suppression de(s) processus : "$pids + + kill $pids 2> /dev/null + + #rm -f $TMPDIR/vdn-vnc-$USER-$GUEST_NAME-fifo + rm -f $TMPDIR/vdn-vnc-$USER-$GUEST_NAME-raw-socket +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +killSystem diff --git a/vdn/bin/vdn-kvm b/vdn/bin/vdn-kvm new file mode 100755 index 0000000..9d5a951 --- /dev/null +++ b/vdn/bin/vdn-kvm @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` démarre VDN sous KVM. + +`synopsis` + +-h : affiche cette aide. + +Remarque : vdn-kvm, en raison de la double virtualisation qu'il implique, + même correctement configuré (nested kvm), dégrade les performances, + notammentle démarrage, d'environ un facteur 5. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +qemu-system-x86_64 -smp 8 -enable-kvm -cpu host -device virtio-rng-pci,rng=rng0 \ + -object rng-random,filename=/dev/urandom,id=rng0 \ + -pidfile $TMPDIR/vdn-DebianBuster-amd64-$USER-pid -rtc base=localtime -m 2G \ + -boot order=c -drive file=$VDN_PATH/files/DebianBuster-amd64.disk,if=virtio,format=raw + diff --git a/vdn/bin/vdn-list b/vdn/bin/vdn-list new file mode 100755 index 0000000..f1eb551 --- /dev/null +++ b/vdn/bin/vdn-list @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` affiche la liste des systèmes. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" +l="`ls $NETWORK_DIR/*.conf 2> /dev/null | sort -n`" +#echo "# network: $NETWORK_DIR" +for i in $l; do + echo $(basename $i .conf) +done diff --git a/vdn/bin/vdn-list-networks b/vdn/bin/vdn-list-networks new file mode 100755 index 0000000..28c6691 --- /dev/null +++ b/vdn/bin/vdn-list-networks @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +set -eu + +ONLY_BUILD=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-b] [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` affiche la liste des réseaux. + +`synopsis` + +-h : affiche cette aide +-b : seulement ceux possédant un script build. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hb" opt; do + case $opt in + h) help; exit 0;; + b) ONLY_BUILD=1;; + ?) usage;; + esac + done +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ -z "NETWORK_DIR" ] && error "NETWORK_DIR not set !" || : + +if [ $ONLY_BUILD = 1 ]; then + ( cd $VDN_NETWORKS_BASE_DIR; find -maxdepth 2 -type f -name "build" -exec dirname {} \; | grep -v '^\.$' | sed -re 's/^..//' | sort ) +else + ( cd $VDN_NETWORKS_BASE_DIR; find -maxdepth 1 -type d -exec basename {} \; | grep -v '^\.$' |sort ) +fi + diff --git a/vdn/bin/vdn-manage-backups b/vdn/bin/vdn-manage-backups new file mode 100755 index 0000000..be00674 --- /dev/null +++ b/vdn/bin/vdn-manage-backups @@ -0,0 +1,80 @@ +#!/bin/bash + + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` gestion des sauvegardes des systèmes. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage + return 0 +} + +manage() { + L=$(find $SAVE_PATH -type f -ls | sort -n -k 2 | tr -s ' ' | cut -d ' ' -f 12) + [ -z "$L" ] && { echo "Aucune sauvegarde !" >&2; sleep 3; exit 0; } || : + + for i in $L; do du -h $i; done + echo + echo "total : $(du -sh $SAVE_PATH)" + echo + [ -x /usr/bin/quota ] && { quota -v; echo; } || : + + echo "Remarques :" + echo + echo "pour retrouver l'aspect creux d'un fichier cow :" + echo "virt-sparsify --in-place fichier.cow" + echo + echo "pour inspecter le contenu d'une archive tgz :" + echo "tar tvf fichier.tgz" + echo + echo "Pour supprimer un fichier :" + echo "rm fichier" + echo + #echo "Tapez exit (ou CTRL D) pour quitter ce shell" + #echo + #cd /tmp; PS1="exit (or CTRL D) to quit $ " bash --noprofile --norc -i + #/bin/bash +} + + +# Programme principal + + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +#set -x + +manage + diff --git a/vdn/bin/vdn-manage-files b/vdn/bin/vdn-manage-files new file mode 100755 index 0000000..76ba201 --- /dev/null +++ b/vdn/bin/vdn-manage-files @@ -0,0 +1,65 @@ +#!/bin/bash + + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` gestion des fichiers (disques, noyau/initramfs, ...). + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage + return 0 +} + +manage() { + cd $VDN_PATH/files + du -h * | sort -h + echo + echo "Pour supprimer un fichier :" + echo "rm fichier" + echo + #echo "Tapez exit (ou CTRL D) pour quitter ce shell" + #echo + #cd /tmp; PS1="exit (or CTRL D) to quit $ " bash --noprofile --norc -i +} + + +# Programme principal + + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +#set -x + +manage + diff --git a/vdn/bin/vdn-mount-chroot b/vdn/bin/vdn-mount-chroot new file mode 100755 index 0000000..7b87f32 --- /dev/null +++ b/vdn/bin/vdn-mount-chroot @@ -0,0 +1,166 @@ +#!/usr/bin/env bash + +set -eu +#set -x + +FOR_ROOT=0 +USE_SUDO=0 +UMOUNT=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-r] [-i user] [-s] [-u] +EOF +} + +help() { + cat << EOF + +`basename $0` exécute VDN dans un environnement chroot en utilisant le disque : + +$VDN_DISK_ENV + + * Le mot de passe root vous sera demandé ! + +AVERTISSEMENTS : + +1. Cette commande n'a pas vocation à être exécutée manuellement. + +2. Quelques opérations sous root sont effectuées (montages, chroot, + démontages). Pour que le démontage se fasse correctement, fermez toutes + les fénêtres et processus de l'environnement chroot (VDN). + +3. L'isolation entre le système initial et le système chrooté n'est pas + totale. Les répertoires suivants du système initial sont partagés : + /home, /etc, /dev, /dev/pts, /sys, /proc, /tmp. + + Autrement dit, ne faites pas n'importe quoi avec ces répertoires, ce + sont ceux de votre système. + +`synopsis` + +-h : affiche cette aide. +-r : (réservé) exécution spécifique à l'utilisateur root. Ne pas utiliser + directement sans savoir ce que vous faites ! +-s : utilise "sudo" plutôt que "su -" pour basculer sous le compte root. +-i user : (réservé) indique l'utilisateur pour l'option -r. Ne pas utiliser + directement sans savoir ce que vous faites ! +-u : démontages seulement. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hrsi:u" opt; do + case $opt in + h) help; exit 0;; + r) FOR_ROOT=1;; + s) USE_SUDO=1;; + i) USER="$OPTARG";; + u) UMOUNT=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage || : +} + +vdnMountChrootForRoot() { + + disp=$(cat $TMPDIR/vdn-display-$USER) + + d=$TMPDIR/vdn-chroot-$USER; + + if [ $UMOUNT = 0 ]; then + + mount | grep -q $d || mount -o loop,offset=$((2048*512)) $DISK $d + + for i in /dev /dev/pts /sys /proc /tmp /etc; do + mount | grep -q $d$i || { mount --bind $i $d$i; } + done + + mount --rbind /home $d/home + + + + chroot $d su - --session-command \ + "export DISPLAY=:"$disp"; export RUN_IN_CHROOT=1; \ + export VDN_DISK_ENV=$VDN_DISK_ENV; \ + export LANGUAGE=C.UTF-8; \ + export LANG=C.UTF-8; \ + export LC_ALL=C.UTF-8; \ + $VDN_PATH/bin/vdn -n" $USER || : + + fi + + mount | grep -q $d/home && { umount -l $d/home; } || : + + for i in /proc /sys /dev/pts /dev /etc /tmp; do + mount | grep -q $d$i && { umount $d$i || { umount -l $d$i; } ; } || : + done + + mount | grep -q $d && { umount $d || umount -l $d; } || : + + mount | grep $d + +} + +vdnMountChroot() { + + d=$TMPDIR/vdn-chroot-$USER; [ ! -d $d ] && mkdir $d || : + + if [ $UMOUNT = 0 ]; then + + # get display + + (rm -f $TMPDIR/vdn-display-$USER; umask 077 ; touch $TMPDIR/vdn-display-$USER) + DISP=$(echo $DISPLAY | cut -d ':' -f 2 | cut -d '.' -f 1) + echo $DISPLAY | cut -d ':' -f 2 >> $TMPDIR/vdn-display-$USER + + fi + + if [ $USE_SUDO = 0 ]; then + echo "Le mot de passe demandé est celui de l'administrateur (root)" + if [ $UMOUNT = 0 ]; then + su - -c "$VDN_PATH/bin/vdn-mount-chroot -r -i $USER" + else + su - -c "$VDN_PATH/bin/vdn-mount-chroot -r -i $USER -u" + fi + else + if [ $UMOUNT = 0 ]; then + sudo $VDN_PATH/bin/vdn-mount-chroot -r -i $USER + else + sudo $VDN_PATH/bin/vdn-mount-chroot -r -i $USER -u + fi + fi +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +export VDN_DISK_ENV="DebianBuster-amd64-env.disk" +export VDN_DISK_NAME="DebianBuster-amd64.disk" + +[ ! -e $VDN_PATH/files/$VDN_DISK_ENV ] && VDN_DISK_ENV=$VDN_DISK_NAME || : + +DISK=$VDN_PATH/files/$VDN_DISK_ENV + +[ ! -e $DISK ] && error "$DISK not found !" || : +if [ ! -w $DISK ]; then + error "$DISK doit être accessible à l'utilisateur en écriture !" +fi + +args "$@" + +if [ $FOR_ROOT = 1 ];then + vdnMountChrootForRoot +else + vdnMountChroot +fi diff --git a/vdn/bin/vdn-mount-chroot.bak b/vdn/bin/vdn-mount-chroot.bak new file mode 100755 index 0000000..aa3bcc4 --- /dev/null +++ b/vdn/bin/vdn-mount-chroot.bak @@ -0,0 +1,190 @@ +#!/usr/bin/env bash + +set -eu +#set -x + +DISK_NAME="DebianBuster-amd64.disk" +FOR_ROOT=0 +USE_SUDO=0 +UMOUNT=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-r] [-i user] [-s] [-u] +EOF +} + +help() { + cat << EOF + +`basename $0` exécute VDN dans un environnement chroot en utilisant le disque : + +$DISK + + * Le mot de passe root vous sera demandé ! + +AVERTISSEMENTS : + +1. de nombreuses opérations sous root sont effectuées (montages, chroot, +démontages). Pour que le démontage se fasse correctement, fermez toutes +les fénêtres et processus de l'environnement chroot (VDN). + +2. L'isolation entre le système initial et le système chrooté n'est pas + totale. Les répertoires suivants du système initial sont partagés : + /dev, /dev/pts, /sys, /proc, /tmp et /home/$USER. + + Autrement dit, ne faites pas n'importe quoi avec ces répertoires, ce + sont ceux de votre système. + +`synopsis` + +-h : affiche cette aide. +-r : (réservé) exécution spécifique à l'utilisateur root. Ne pas utiliser + directement sans savoir ce que vous faites ! +-s : utilise "sudo" plutôt que "su -" pour basculer sous le compte root. +-i user : (réservé) indique l'utilisateur pour l'option -r. Ne pas utiliser + directement sans savoir ce que vous faites ! +-u : démontages seulement. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hrsi:u" opt; do + case $opt in + h) help; exit 0;; + r) FOR_ROOT=1;; + s) USE_SUDO=1;; + i) USER="$OPTARG";; + u) UMOUNT=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage || : +} + +vdnMountChrootForRoot() { + + #key="$(cat $TMPDIR/vdn-key-$USER)" + + disp=$(cat $TMPDIR/vdn-display-$USER) + + echo "USER:$USER" + + d=$TMPDIR/vdn-chroot-$USER; + + if [ $UMOUNT = 0 ]; then + + mount | grep -q $d || mount -o loop,offset=$((2048*512)) $DISK $d + + for i in /dev /dev/pts /sys /proc /tmp /etc; do + mount | grep -q $d$i || { mount --bind $i $d$i; } + done + + #mount --bind $VDN_PATH $d/home/test/vdn + mount --rbind /home $d/home + + #mount | grep $d + + #chroot $d su - -s /bin/bash -c "export DISPLAY=":"$disp; \ + #unset XAUTHORITY; rm -rf /home/test/.config/xfce4-session; \ + #rm -rf /home/test/.config/xfce4/terminal/; \ + #xauth add \$DISPLAY . $key; \ + #export NO_AT_BRIDGE=1; \ + #xfce4-terminal --disable-server # 2> /dev/null;" test + + whoami + + ls -l $VDN_PATH/bin/vdn + + #chroot $d su - $VDN_PATH/bin/vdn $USER + + chroot $d su - --session-command "export DISPLAY=:"$disp"; $VDN_PATH/bin/vdn" $USER || : + + #chroot $d su - -s /bin/bash -c "export DISPLAY=":"$disp; \ + #xfce4-terminal --disable-server # 2> /dev/null;" $USER + + fi + + for i in /tmp /proc /sys /dev/pts /dev /etc; do + mount | grep -q $d$i && { umount $d$i || { echo "umount lazy : $d$i"; umount -l $d$i; } ; } || : + done + + + fuser -mv $d/home + + mount | grep -q $d/home && { umount -l $d/home; } || : + sleep 1 + mount | grep -q $d && { umount $d || umount -l $d; } || : + + mount | grep $d + +} + +vdnMountChroot() { + + d=$TMPDIR/vdn-chroot-$USER; [ ! -d $d ] && mkdir $d || : + + if [ $UMOUNT = 0 ]; then + + # get display + + (rm -f $TMPDIR/vdn-display-$USER; umask 077 ; touch $TMPDIR/vdn-display-$USER) + DISP=$(echo $DISPLAY | cut -d ':' -f 2 | cut -d '.' -f 1) + echo $DISPLAY | cut -d ':' -f 2 >> $TMPDIR/vdn-display-$USER + + # get xauth key + + #key=$(xauth list| grep $(uname -n) | grep $DISP | tail -n 1 | tr -s ' ' | cut -d ' ' -f 3) + + #[ -n "$key" ] || error "Xauth key is empty !" + #echo $key | egrep -q '^[[:xdigit:]]+$' || error "Bad xauth key ($key) !" + + #(rm -f $TMPDIR/vdn-key-$USER; umask 077 ; touch $TMPDIR/vdn-key-$USER) + + #echo $key >> $TMPDIR/vdn-key-$USER + + + fi + + if [ $USE_SUDO = 0 ]; then + echo "Le mot de passe demandé est celui de l'administrateur (root)" + if [ $UMOUNT = 0 ]; then + su - -c "$VDN_PATH/bin/vdn-mount-chroot -r -i $USER" + else + su - -c "$VDN_PATH/bin/vdn-mount-chroot -r -i $USER -u" + fi + else + if [ $UMOUNT = 0 ]; then + sudo $VDN_PATH/bin/vdn-mount-chroot -r -i $USER + else + sudo $VDN_PATH/bin/vdn-mount-chroot -r -i $USER -u + fi + fi +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +DISK=$VDN_PATH/files/$DISK_NAME + +[ ! -e $DISK ] && error "$DISK not found !" || : +if [ ! -w $DISK ]; then + error "$DISK doit être accessible à l'utilisateur en écriture !" +fi + +args "$@" + +if [ $FOR_ROOT = 1 ];then +vdnMountChrootForRoot +else + vdnMountChroot +fi diff --git a/vdn/bin/vdn-new-network b/vdn/bin/vdn-new-network new file mode 100755 index 0000000..1f36dbd --- /dev/null +++ b/vdn/bin/vdn-new-network @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +#set -x + +NEW="" + +networkName="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [newNetworkName] + +EOF +} + +help() { + cat << EOF + +`basename $0` crée un réseau vide. + +`synopsis` + +-h : affiche cette aide. + +Si newNetworkName n'est pas précisé, il sera demandé sur l'entrée standard. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -eq 1 ] && { NEW=$1; shift; } + [ $# -ne 0 ] && usage; +} + +# main + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +while [ -z "$NEW" ]; do + echo -n "Nom destination : " + read NEW +done + +new=$(dirname $NETWORK_DIR)/$NEW +[ -e $new ] && error "Le réseau $NEW existe déja !" || : + +mkdir $new +cp $VDN_PATH/build-template $new/build +cp $VDN_PATH/net-template.svgz $new/net.svgz +mkdir $new/scripts +vdn-build-network $new + + diff --git a/vdn/bin/vdn-open-network b/vdn/bin/vdn-open-network new file mode 100755 index 0000000..4053725 --- /dev/null +++ b/vdn/bin/vdn-open-network @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] networkDir +EOF +} + +help() { + cat << EOF + +`basename $0` définit le réseau courant. (fixe la variable i +NETWORK_DIR du fichier ~/.vdnrc). + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + [ $# -ne 1 ] && usage; + + DIR=$1 +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +if [ ! -d "$DIR" ]; then + if [ ! -d $VDN_PATH/networks/$DIR ]; then + error "Network $DIR not found" + else + DIR=$VDN_PATH/networks/$DIR + fi +fi + +if [ ! -e ~/.vdnrc ]; then + cat <<EOF > ~/.vdnrc +#!/bin/bash + +# Chemin du répertoire associé au réseau + +NETWORK_DIR="$DIR" +EOF +else + if grep -q 'NETWORK_DIR' ~/.vdnrc; then + tmp=`mktemp` + cat ~/.vdnrc | \ + sed -re 's,^NETWORK_DIR=.*$,NETWORK_DIR="'$DIR'",' > $tmp + mv $tmp ~/.vdnrc + else + cat <<EOF >> ~/.vdnrc + +# Chemin du répertoire associé au réseau + +NETWORK_DIR="$DIR" +EOF + + fi +fi + diff --git a/vdn/bin/vdn-prepare b/vdn/bin/vdn-prepare new file mode 100755 index 0000000..4128d0f --- /dev/null +++ b/vdn/bin/vdn-prepare @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +set -eu + +OPTS="" +TEST=0 + +synopsis() { + cat << EOF +Usage : + `basename $0` [-h] [-f] [-t] + `basename $0` list +EOF +} + +help() { + cat << EOF + +`basename $0` : installe les logiciels nécessaires à l'utilisation de vdn. + +`synopsis` + +-h : affiche cette aide +-f : force l'installation des paquets : pas de demande de confirmation. +-t : test l'installation (code de retour à 1 si logiciels manquants). + +`basename $0` list : affiche la liste des distributions sur lesquelles VDN +est porté. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hft" opt; do + case $opt in + h) help; exit 0;; + f) OPTS="-y";; + t) TEST=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage || : +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +[ $# -ge 1 ] && [ "$1" = "list" ] && { + cd $VDN_PATH/distribs/hosts + find . -mindepth 2 -type d | sed -re 's,^\./,,' + exit +} + + +args $@ + +[ ! -d $VDN_PATH/distribs/hosts/$HOST_RELEASE ] && { + echo "VDN n'est pas porté pour la distribution $HOST_RELEASE !" >&2 + echo "Consultez les FAQ.">&2 + exit 1 +} + +source $VDN_PATH/distribs/hosts/$HOST_RELEASE/prepare.sh + +if [ $TEST = 1 ]; then + testInstallDebian + exit +fi + +ID=$(id -u -n) + +[ $ID != root ] && error "Installation réservée à l'administrateur" + +PATH="$PATH:/usr/local/sbin:/usr/sbin:/sbin" + +runInstall $OPTS + diff --git a/vdn/bin/vdn-prepare1 b/vdn/bin/vdn-prepare1 new file mode 100755 index 0000000..52279b5 --- /dev/null +++ b/vdn/bin/vdn-prepare1 @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -eu +set -x + +OPTS="" +TEST=0 + +synopsis() { + cat << EOF +Usage : + `basename $0` [-h] [-f] [-t] + `basename $0` list +EOF +} + +help() { + cat << EOF + +`basename $0` : installe les logiciels nécessaires à l'utilisation de vdn. + +`synopsis` + +-h : affiche cette aide +-f : force l'installation des paquets : pas de demande de confirmation. +-t : test l'installation (code de retour à 1 si logiciels manquants). + +`basename $0` list : affiche la liste des distributions sur lesquelles VDN +est porté. + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hft" opt; do + case $opt in + h) help; exit 0;; + f) OPTS="-y";; + t) TEST=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 0 ] && usage || : +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +[ $# -ge 1 ] && [ "$1" = "list" ] && { + cd $VDN_PATH/distribs/hosts + find . -mindepth 2 -type d | sed -re 's,^\./,,' + exit +} + + +args $@ + +[ ! -d $VDN_PATH/distribs/hosts/$HOST_RELEASE ] && { + echo "VDN n'est pas porté pour la distribution $HOST_RELEASE !" >&2 + echo "Consultez les FAQ.">&2 + exit 1 +} + +source $VDN_PATH/distribs/hosts/$HOST_RELEASE/prepare.sh + +if [ $TEST = 1 ]; then + testInstallDebian + exit +fi + +ID=$(id -u -n) + +[ $ID != root ] && error "Installation réservée à l'administrateur" + +PATH="$PATH:/usr/local/sbin:/usr/sbin:/sbin" + +runInstall $OPTS + diff --git a/vdn/bin/vdn-publish-network b/vdn/bin/vdn-publish-network new file mode 100755 index 0000000..feb13b4 --- /dev/null +++ b/vdn/bin/vdn-publish-network @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +set -eu + +FORCE=0 +DRY=0 +SYSTEMS="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-hdf] [network] +EOF +} + +help() { + cat << EOF + +`basename $0` dépose le réseau sur le serveur. + +`synopsis` + +Le réseau est "zipé" et est déposé sur le serveur via scp. + +Pour cela, la variable SSH_REPOSITORY doit avoir été fixée dans votre +fichier \$HOME/.vdnrc. Exemple : + +SSH_REPOSITORY="toto@truc.bidule.org:public_html/files" + +Remarque : les fichiers "*.disk" sont préalablement compressés (.gz). + +-h : affiche cette aide +-d : dry run +-f : force : pas de demande de confirmation ! + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hdf" opt; do + case $opt in + h) help; exit 0;; + d) DRY=1;; + f) FORCE=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -gt 1 ] && usage + [ $# = 1 ] && NETWORK=$1 || : +} + + +publishNetwork() { + + echo publish $1 + + d=$(dirname $1) + b=$(basename $1) + + rm -f $TMPDIR/$b.zip + + + (cd $d; umask 077 && zip --exclude \*.conf -r $TMPDIR/$b.zip $b) + + ls -l $TMPDIR/$b.zip + + if [ -z "$SSH_REPOSITORY" ]; then + error "SSH_REPOSITORY est vide" + fi + + if [ $DRY = 0 ]; then + if [ $FORCE = 0 ]; then + request "Publish to $SSH_REPOSITORY ? :" + fi + scp $TMPDIR/$b.zip $SSH_REPOSITORY + fi +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +NETWORK=$NETWORK_DIR + +args "$@" + +[ -z "$NETWORK" ] && usage + + +publishNetwork $NETWORK diff --git a/vdn/bin/vdn-push b/vdn/bin/vdn-push new file mode 100755 index 0000000..93e3bef --- /dev/null +++ b/vdn/bin/vdn-push @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` +EOF +} + +help() { + cat << EOF + +`basename $0` effectue un git push de VDN. + +`synopsis` +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + [ $# -ne 0 ] && usage + return 0 +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +git push vdn@opale.iut-clermont.uca.fr:public_html/vdn/git/vdn.git + diff --git a/vdn/bin/vdn-query b/vdn/bin/vdn-query new file mode 100755 index 0000000..2938863 --- /dev/null +++ b/vdn/bin/vdn-query @@ -0,0 +1,102 @@ +#!/bin/bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] request [arg...] host + +requests : + REDIR proto port : proto : tcp/udp, port : port à rediriger + LOCAL_USER_NUM : numéro local de l'utilisateur sur la machine (%32) + PUBLIC_IP N # N : public IP NUMBER + MAC_ADDR N # N : network interface NUMBER + ETH_LINK N # N : Ethernet link NUMBER +EOF +} + +help() { + cat << EOF + +`basename $0` affiche des infos sur host.network.user.vdn + +La machine n'a pas besoin d'être démarrée (infos statiques) + +Pour obtenir des infos dynamiques (redirection de ports) voir +vdn-infos + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + [ $# -lt 2 ] && usage; + + req=$1 + shift + + reqArgs="" + while [ $# -gt 1 ]; do + reqArgs="$reqArgs $1" + shift + done + + [ "$reqArgs" = "" ] && reqArgs=0 + + + host=$1 + + if [ $host = current ]; then + set +u + [ -z "$GUEST_NAME" ] && error "You can't user current in this context !" + set -u + host=$GUEST_NAME + fi + +} + +all() { + echo "REDIR $(reqArgs) : $(computeRedir $host $reqArgs)" + echo "LOCAL_USER_NUM: $(computePublicIp $host $reqArgs)" + echo "PUBLIC_IP: $(computePublicIp $host $reqArgs)" + echo "MAC_ADDR: $(computeMacAddr $host $reqArgs)" + echo "ETH_LINK: $(computeEthLink $host $reqArgs)" +} + + +# main + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +#set -x +args "$@" + +. $VDN_PATH/allocators/$VDN_RESOURCES_ALLOCATOR + +case "$req" in + REDIR) computeRedir $host $reqArgs;; + LOCAL_USER_NUM) computeLocalUser $host $reqArgs;; + PUBLIC_IP) computePublicIp $host $reqArgs;; + MAC_ADDR) computeMacAddr $host $reqArgs;; + ETH_LINK) computeEthLink $host $reqArgs;; + all) all;; + *) usage;; +esac + diff --git a/vdn/bin/vdn-restart b/vdn/bin/vdn-restart new file mode 100755 index 0000000..6279fed --- /dev/null +++ b/vdn/bin/vdn-restart @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -eu + +set -x + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` system : vdn-shalt suivi de vdn-start. + +`synopsis` +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "gh" opt; do + case $opt in + h) help; exit 0;; + g) ;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +if vdn-alive $GUEST_NAME; then + vdn-halt $GUEST_NAME || error "can't halt $GUEST_NAME" + sleep 2 +fi + +echo "vdn-restart start : $@" +vdn-start $@ + + diff --git a/vdn/bin/vdn-restore-extra-eth b/vdn/bin/vdn-restore-extra-eth new file mode 100755 index 0000000..40422c0 --- /dev/null +++ b/vdn/bin/vdn-restore-extra-eth @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +set -eu + +VAR="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` restaure l'état de l'interface suppémentaire utilisée pour +joindre la machine virtuelle (précisée en argument). + +Exemple : `basename $0` bigboss + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +setGuestVars $GUEST_NAME + +GUEST_OWNER=$USER + +loadGuestVars $GUEST_NAME + +vdn-infos $GUEST_NAME GUEST_NAME > /dev/null || exit 1 + +if ! $VDN_PATH/bin/vdn-alive $GUEST_NAME; then + error "Le système $GUEST_NAME n'est pas démarré !" +fi + + +[ ! -e $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-serial ] && \ + error "$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-serial not found !" + +echo "ok" + + +CMD=" +stty -echo +PS1= +ls /tmp +iptables -F +iptables -F -t nat +iptables -L +iptables -L -t nat +eth=\$(ip a | egrep '^[0-9]+:' | sed -re 's/^.*(eth[0-9]+).*$/\1/' | tail -n 1) +echo eth=\$eth +ip a flush \$eth +dhclient \$eth +ip a show dev \$eth +ip a show dev \$eth | grep -q 10.0.2.15 && echo ok || echo ERROR +" + +#echo socat STDIO UNIX-CLIENT:$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-serial +(echo "$CMD"; sleep 1) | socat STDIO UNIX-CLIENT:$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-serial +echo +#echo "$CMD" | socat STDIO UNIX-CLIENT:$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-serial +#socat STDIO UNIX-CLIENT:$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-serial + +#cat << EOF | socat STDIO UNIX-CLIENT:$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-serial +#ip a | egrep '^[0-9]+:' | sed -re 's/^.*(eth[0-9]+).*$/\1/' | tail -n 1" +#EOF + diff --git a/vdn/bin/vdn-save b/vdn/bin/vdn-save new file mode 100755 index 0000000..ac00471 --- /dev/null +++ b/vdn/bin/vdn-save @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` sauvegarde le système. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi +} + +saveSystem() { + + o="$SAVE_FILE" + n="$SAVE_FILE.tmp.tgz" + d="$(dirname $n)" + + [ ! -d $d ] && mkdir -p $d + + set +e + ( umask 077 && vdn-ssh root@$GUEST_NAME "/etc/vdn/save" > $n ) + r=$? + set -e + + if [ $r = 0 ]; then + mv $n $o + resizeMultipleOf512 $o + r=$? + fi + + return $r +} + + + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +loadGuestVars $GUEST_NAME + +case $MODE in + tgz|tgz2) ;; + *|overlay) exit 0;; +esac + +if [ ! -e $GUEST_PATH ]; then + error "Le système $GUEST_NAME n'existe pas !" +fi + +#vdn-ssh root@$GUEST_NAME echo > /dev/null || error "Can't connect to $GUEST_NAME" + +cmd=saveSystem + +if $cmd ; then + s=$(du -h $SAVE_FILE | tr '\t' ' ' | cut -d ' ' -f 1) + echo "Sauvegarde $SAVE_FILE effectuée ($s) !" + exit 0 +else + echo "vdn-save ($GUEST_NAME) : Échec de la sauvegarde !" >&2 + exit 1 +fi diff --git a/vdn/bin/vdn-scp b/vdn/bin/vdn-scp new file mode 100755 index 0000000..91c7357 --- /dev/null +++ b/vdn/bin/vdn-scp @@ -0,0 +1,115 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [option...] src dst +EOF +} + +help() { + cat << EOF + +`basename $0` effectue un scp à partir ou à destination d'un système virtuel. + +`synopsis` + +-h : affiche cette aide + +Les options autorisées sont celles de scp(1). + +Exemple : + + # Copie de l'hôte vers la machine virtuelle + # /etc/passwd de l'hôte vers /tmp de la machine virtuelle + + vdn-scp /etc/passwd test@vm-1:/tmp + + # Copie de la machine virtuelle vers l'hôte + # /etc/passwd de la machine virtuelle vers /tmp de l'hôte + + vdn-scp test@vm-1:/etc/passwd /tmp + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + opts="" + + [ $# -eq 1 -a "$1" = "-h" ] && { help; exit 0; } + + while [ $# -gt 2 ]; do + if [ "$1" = "-h" ]; then help; exit 0; fi + opts="$opts $1" + shift + done + + LOGIN="${USER}@" + GUEST_NAME="" + + for i in 1 2; do + reg=':' + if [[ "$1" =~ "$reg" ]]; then + user=`echo $1 | cut -d ':' -f 1` + path=`echo $1 | cut -d ':' -f 2` + LOGIN="${USER}@" + GUEST_NAME="$user" + reg="@" + if [[ "$user" =~ "$reg" ]]; then + LOGIN=`echo $user | cut -d '@' -f 1`@ + GUEST_NAME=`echo $user | cut -d '@' -f 2` + fi + path="${LOGIN}localhost:$path" + else + path="$1" + fi + + [ $i -eq 1 ] && src="$path" || dst="$path" + + shift + done + + #echo "opts=$opts src=$src dst=$dst GUEST_NAME=$GUEST_NAME" + +} + + +# Programme principal + +GUEST_OWNER=$USER + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ -z "$GUEST_NAME" ] && usage + +#setGuestVars $GUEST_NAME +#loadGuestVars $GUEST_NAME + +[ ! -e $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs ] && + error "Impossible de joindre $GUEST_NAME" + +SSH_REDIR_PORT=`cat $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs | \ + sed -rne 's/^tcp:([0-9]+):22(:|$).*$/\1/p'` + +[ -z "$SSH_REDIR_PORT" ] && error "Impossible de joindre $GUEST_NAME" + +if [ -z "$SSH_REDIR_PORT" ]; then + error "Aucune redirection vers le port 22 du système $GUEST_NAME !" + exit 1 +fi + +SSH_MASTER="" +[ $SSH_GUEST_MASTER = 1 ] && { + sshGuestControlMaster + SSH_MASTER="-o ControlPath=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest-%r@%h:%p" +} + +scp $SSH_MASTER $SCP_OPTS $opts -P $SSH_REDIR_PORT $src $dst diff --git a/vdn/bin/vdn-scripts b/vdn/bin/vdn-scripts new file mode 100755 index 0000000..bcc28a2 --- /dev/null +++ b/vdn/bin/vdn-scripts @@ -0,0 +1,227 @@ +#!/usr/bin/env bash + +set -eu +#set -x + +export READ=${READ:-0} +DOC=0 +VDN_TRACE=${VDN_TRACE:-0} +EDIT=0 +export PAUSE=${PAUSE:-0} + +export IN_PARALLEL=${IN_PARALLEL:-0} + +set +u +export FORCE_SEQUENTIAL=${FORCE_SEQUENTIAL:-0} +set -u +export PAUSE_IF_ERROR=0 +export VDN_TRACE + + + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-r] [-n] [-d] [-t] script1... +EOF +} + +help() { + cat << EOF + +`basename $0` exécute les scripts du réseau. + +`synopsis` + +-h : affiche cette aide. +-d : n'exécute pas le script mais affiche sa description. +-e : édite le script. +-n : pas de pause à l'issue du script. +-t : trace l'exécution des commandes effectuées (debug) +-r : attendre la touche "Entrée" pour terminer +-s : force l'exécution séquentielle des scripts." +-w : attendre si erreur + + +Cette commande, après avoir fixé quelques variables et +quelques fonctions appelle les scripts du réseau. + +Remarque : si la variable d'environnement RUN_PARALLEL est fixée à 1 (cf. +~/.vdnrc) alors si plusieurs scripts sont précisés en arguments ils sont +exécutés en parallèle (via tmuxinator). + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "dehrnpstw" opt; do + case $opt in + h) help; exit 0;; + d) DOC=1;; + e) EDIT=1;; + r) READ=1;; + t) VDN_TRACE=1;; + n) PAUSE=0;; + p) PAUSE=1;; + w) PAUSE_IF_ERROR=1;; + s) FORCE_SEQUENTIAL=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + SCRIPTS="$@" +} + +realSeq() { + # in sequential + #export IN_PARALLEL=0 + + set +e + r=0 + + local SYSTEMS=$(vdn-list | grep -v '^#') + + #echo '°°°°' + #ps + #echo '°°°°' + + runSequential $SCRIPTS || r=$? + + #echo '°°°°' + #ps + #echo '°°°°' + + set -e + + #if [ $r -ne 0 -a $VDN_SCRIPTS_LEVEL = 1 ]; then + # error "$r" + # + #fi + + #pause + + return $r +} + + +# main + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh +. $VDN_PATH/bin/functions-scripts.sh + +args "$@" + +#echo '0000' +# ps +#echo 'OOOO' + + +export VDN_PATH + +export PATH="$VDN_PATH/bin:$PATH" + +#echo "fake script..." + +export READ + +. $VDN_PATH/bin/functions-scripts.sh + +cd $NETWORK_DIR/scripts + +if [ $DOC = 1 ]; then + for i in $SCRIPTS; do + . ./$i + echo "$i $DESC" + done + exit +fi + +if [ $EDIT = 1 ]; then + set +u + [ -z "$EDITOR" ] && export EDITOR="vi" + + set -u + $EDITOR $SCRIPTS + exit +fi + + +[ $VDN_DEBUG = 1 ] && set -x + +set +u +[ -z "$VDN_SCRIPTS_LEVEL" ] && export VDN_SCRIPTS_LEVEL=0 || : +set -u + +VDN_SCRIPTS_LEVEL=$((VDN_SCRIPTS_LEVEL+1)) + + +#if [ $VDN_SCRIPTS_LEVEL = 1 ]; then +# if canRunParallel $SCRIPTS; then +# nothing=0 +# fi +#fi + +#echo "FORCE_SEQ:$FORCE_SEQUENTIAL" +#echo "RUN_PARALLEL=$RUN_PARALLEL" +#sleep 2 +#set -x + +#set -x + +#export IN_PARALLEL=1 + +#set -x +#set +u +#echo "SCRIPTS:$SCRIPTS DISABLE_SCAN:$DISABLE_SCAN" +#set -u + +if [ $VDN_SCRIPTS_LEVEL = 1 ]; then + #echo "RESET ERRORS" + errors=0 + success=0 +fi + +if canRunParallel $SCRIPTS && [ "$FORCE_SEQUENTIAL" = 0 ]; then + + # in parallel + #echo "Run parallel ($SCRIPTS)." + export IN_PARALLEL=1 + set +u + + set -u + + #set -x + #parallelDisablePause + if [ $(echo "$SCRIPTS" | wc -w) -gt 1 ]; then + + #echo "=== PARALLEL" >&2 + export IN_PARALLEL=1 + runParallel $SCRIPTS + r=$? + else + export IN_PARALLEL=0 + r=0 + #echo "=== SEQ" >&2 + realSeq $SCRIPTS || { r=$?; } + + #pause + + fi + +else + #echo "=== SEQ2" >&2 + export IN_PARALLEL=0 + r=0 + realSeq $SCRIPTS || { r=$?; } +fi + +pause + +#echo "vdn-script: return : r:$r" + +exit $r diff --git a/vdn/bin/vdn-scripts.old b/vdn/bin/vdn-scripts.old new file mode 100755 index 0000000..380ba97 --- /dev/null +++ b/vdn/bin/vdn-scripts.old @@ -0,0 +1,215 @@ +#!/usr/bin/env bash + +set -eu +#set -x + +export READ=${READ:-0} +DOC=0 +VDN_TRACE=${VDN_TRACE:-0} +EDIT=0 +export PAUSE=${PAUSE:-0} +set +u +export FORCE_SEQUENTIAL=${FORCE_SEQUENTIAL:-0} +set -u +export PAUSE_IF_ERROR=0 +export VDN_TRACE + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-r] [-n] [-d] [-t] script1... +EOF +} + +help() { + cat << EOF + +`basename $0` exécute les scripts du réseau. + +`synopsis` + +-h : affiche cette aide. +-d : n'exécute pas le script mais affiche sa description. +-e : édite le script. +-n : pas de pause à l'issue du script. +-t : trace l'exécution des commandes effectuées (debug) +-r : attendre la touche "Entrée" pour terminer +-s : force l'exécution séquentielle des scripts." +-w : attendre si erreur + + +Cette commande, après avoir fixé quelques variables et +quelques fonctions appelle les scripts du réseau. + +Remarque : si la variable d'environnement RUN_PARALLEL est fixée à 1 (cf. +~/.vdnrc) alors si plusieurs scripts sont précisés en arguments ils sont +exécutés en parallèle (via tmuxinator). + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "dehrnpstw" opt; do + case $opt in + h) help; exit 0;; + d) DOC=1;; + e) EDIT=1;; + r) READ=1;; + t) VDN_TRACE=1;; + n) PAUSE=0;; + p) PAUSE=1;; + w) PAUSE_IF_ERROR=1;; + s) FORCE_SEQUENTIAL=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + SCRIPTS="$@" +} + +realSeq() { + # in sequential + #export IN_PARALLEL=0 + + set +e + r=0 + + local SYSTEMS=$(vdn-list | grep -v '^#') + + runSequential $SCRIPTS || r=$? + + set -e + + #if [ $r -ne 0 -a $VDN_SCRIPTS_LEVEL = 1 ]; then + # error "$r" + # + #fi + + #pause + + return $r +} + + +# main + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh +. $VDN_PATH/bin/functions-scripts.sh + +args "$@" + +export VDN_PATH + +export PATH="$VDN_PATH/bin:$PATH" + +export READ + +. $VDN_PATH/bin/functions-scripts.sh + +cd $NETWORK_DIR/scripts + +if [ $DOC = 1 ]; then + for i in $SCRIPTS; do + . ./$i + echo "$i $DESC" + done + exit +fi + +if [ $EDIT = 1 ]; then + set +u + [ -z "$EDITOR" ] && export EDITOR="vi" + + set -u + $EDITOR $SCRIPTS + exit +fi + + +[ $VDN_DEBUG = 1 ] && set -x + +set +u +[ -z "$VDN_SCRIPTS_LEVEL" ] && export VDN_SCRIPTS_LEVEL=0 || : +set -u + +VDN_SCRIPTS_LEVEL=$((VDN_SCRIPTS_LEVEL+1)) + + +#if [ $VDN_SCRIPTS_LEVEL = 1 ]; then +# if canRunParallel $SCRIPTS; then +# nothing=0 +# fi +#fi + +#echo "FORCE_SEQ:$FORCE_SEQUENTIAL" +#echo "RUN_PARALLEL=$RUN_PARALLEL" +#sleep 2 +#set -x + +#set -x + +#export IN_PARALLEL=1 + +#set -x +#set +u +#echo "SCRIPTS:$SCRIPTS DISABLE_SCAN:$DISABLE_SCAN" +#set -u + +if [ $VDN_SCRIPTS_LEVEL = 1 ]; then + #echo "RESET ERRORS" + errors=0 + success=0 +fi + +if canRunParallel $SCRIPTS && [ "$FORCE_SEQUENTIAL" = 0 ]; then + + # in parallel + #echo "Run parallel ($SCRIPTS)." + export IN_PARALLEL=1 + set +u + + set -u + + #set -x + #parallelDisablePause + if [ $(echo "$SCRIPTS" | wc -w) -gt 1 ]; then + export IN_PARALLEL=1 + runParallel $SCRIPTS + r=$? + else + #export IN_PARALLEL=1 + #( + export IN_PARALLEL=0 + #p=$PAUSE + #export PAUSE=1 + #VDN_SCRIPTS_LEVEL=$((VDN_SCRIPTS_LEVEL+1)) + #set -x + #[ $VDN_SCRIPTS_LEVEL != 1 ] && export IN_PARALLEL=0 || : + r=0 + realSeq $SCRIPTS || { r=$?; } + + #PAUSE=$p + #[ $VDN_SCRIPTS_LEVEL = 1 ] && export IN_PARALLEL=1 || : + #pause + #) + + fi + +else + export IN_PARALLEL=0 + #[ $VDN_SCRIPTS_LEVEL == 1 ] && export IN_PARALLEL=0 + #export PAUSE=1 + r=0 + realSeq $SCRIPTS || { r=$?; } +fi + +pause + +#echo "vdn-script: return : r:$r" + +exit $r diff --git a/vdn/bin/vdn-send-proxy b/vdn/bin/vdn-send-proxy new file mode 100755 index 0000000..be57e6c --- /dev/null +++ b/vdn/bin/vdn-send-proxy @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` émet une commande au proxy (websockets). + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +if [ -e $VDN_WS_PROXY_SOCKET ]; then + echo $@ | socat - UNIX-CONNECT:$VDN_WS_PROXY_SOCKET +fi + + diff --git a/vdn/bin/vdn-set-network-dir b/vdn/bin/vdn-set-network-dir new file mode 100755 index 0000000..0c0c0f2 --- /dev/null +++ b/vdn/bin/vdn-set-network-dir @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] networkDir +EOF +} + +help() { + cat << EOF + +`basename $0` définit le réseau courant. (fixe la variable i +NETWORK_DIR du fichier ~/.vdnrc). + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + [ $# -ne 1 ] && usage; + + DIR=$1 +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +if [ "$DIR" != "" ]; then + if [ ! -d "$DIR" ]; then + if [ ! -d $VDN_NETWORKS_BASE_DIR/$DIR ]; then + error "Network $DIR not found" + else + DIR=$VDN_NETWORKS_BASE_DIR/$DIR + fi + fi +fi + +if [ ! -e ~/.vdnrc ]; then + cat <<EOF > ~/.vdnrc +#!/bin/bash + +# Chemin du répertoire associé au réseau + +NETWORK_DIR="$DIR" +EOF +else + if grep -q 'NETWORK_DIR' ~/.vdnrc; then + tmp=`mktemp` + cat ~/.vdnrc | \ + sed -re 's,^NETWORK_DIR=.*$,NETWORK_DIR="'$DIR'",' > $tmp + mv $tmp ~/.vdnrc + else + cat <<EOF >> ~/.vdnrc + +# Chemin du répertoire associé au réseau + +NETWORK_DIR="$DIR" +EOF + + fi +fi + diff --git a/vdn/bin/vdn-set-var b/vdn/bin/vdn-set-var new file mode 100755 index 0000000..547f6fa --- /dev/null +++ b/vdn/bin/vdn-set-var @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` var value +EOF +} + +help() { + cat << EOF + +`basename $0` fixe la variable dans ~/.vdnrc. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hr" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + [ $# != 2 ] && usage + + VAR=$1 + VALUE=$2 + +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +f=$HOME/.vdnrc + +[ ! -e $f ] && touch $f + +if cat $f | grep -q "^$VAR="; then + sed -i -re "s,$VAR=.*$,$VAR=\"$VALUE\"," $f || echo "Error" +else + echo "$VAR=\"$VALUE\"" >> $f +fi + diff --git a/vdn/bin/vdn-shell b/vdn/bin/vdn-shell new file mode 100755 index 0000000..feb630e --- /dev/null +++ b/vdn/bin/vdn-shell @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +name=vdn-shell + +synopsis() { + cat << EOF +Usage : $name [-h] +EOF +} + +help() { + cat << EOF + +$name exécute un shell evec les fonctions et les variables VDN. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done +} + +# Programme principal + +#xclock +args $@ + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +echo "Start..." + +#export PS1='[VDN] \u@\h:\w\$ ' + +#$SLASH/usr/bin/env | $SLASH/bin/grep PATH + +#export DISPLAY='127.0.0.1:10.0' + +#xclock + +$SLASH/usr/bin/env $SLASH/bin/bash diff --git a/vdn/bin/vdn-show b/vdn/bin/vdn-show new file mode 100755 index 0000000..6d2e2e9 --- /dev/null +++ b/vdn/bin/vdn-show @@ -0,0 +1,214 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : $(basename $0) [-h] +EOF +} + +help() { + cat << EOF + +$(basename $0) Affiche les configurations des systèmes. + +$(synopsis) + +-h : affiche cette aide +-r : attendre la touche "Entrée" pour terminer + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) +} + + +i1() { + printf "%10s %8s %s\n" "GUEST" "IDENT" "GUEST_SYS" + + for i in $guests; do + a=$(vdn-config $i IDENT) + b=$(vdn-config $i GUEST_SYS) + printf "%10s %8s %s\n" $i $a $b + done + + echo +} + +i2() { + printf "%10s %8s %s\n" "GUEST" "MEMORY" "HDA" + sm=0 + for i in $guests; do + m=$(vdn-config $i MEMORY) + d=$(vdn-config $i HDA) + printf "%10s %8s %s\n" $i $m $d + sm=$(($sm+$m)) + done + + echo + echo "TOTAL MEMORY = $sm" + echo +} + +i3() { + printf "%10s %8s %s\n" "GUEST" "NETWORKS" + + for i in $guests; do + b=$(vdn-config $i NETWORKS) + printf "%10s %8s %s\n" $i "$b" + done + + echo +} + +i4() { + nets="NET_G" + for i in $(seq 1 9); do + nets="$nets NET_$i" + done + + printf "%10s %s\n" NETWORKS " GUESTS(ETH)" + + for i in $nets; do + l="" + for s in $guests; do + setGuestVars $s + grep -q '^[^#]*NETWORKS=.*'$i $GUEST_CONF && { + l="$l $s" + } + done + l2="" + for j in $l; do + a=$(vdn-config $j NETWORKS) + b=$(echo "$a" | sed -re 's/^(.*)'$i'.*$/\1/') + c=$(echo "$b" | sed -re 's/[^ ]//g') + d=$(echo "$c" | wc -c) + d=$(($d-1)) + #echo "$i $j(eth$d)" + l2="$l2 $j(eth$d)" + done + [ -n "$l2" ] && { + printf "%10s %s\n" $i "$l2" + } + done + + echo + +} + +i5() { + printf "%10s %s\n" "GUEST" "REDIRS" + + for i in $guests; do + a="$(vdn-config $i REDIRS)" + printf "%10s %s\n" $i "$a" + done + + echo +} + +i6() { + nothing=1 +} + + +i7() { + printf "%10s %12s %s\n" "GUEST" "AUFS_SIZE" "AUFS_FILE" + + for i in $guests; do + a="$(vdn-config $i AUFS_SIZE)" + b="$(vdn-config $i AUFS_FILE)" + printf "%10s %12s %s\n" $i "$a" "$b" + done + + echo +} + +i8() { + printf "%10s %12s %s\n" "GUEST" "SWAP_SIZE" "SWAP_FILE" + + for i in $guests; do + a="$(vdn-config $i SWAP_SIZE)" + b="$(vdn-config $i SWAP_FILE)" + printf "%10s %12s %s\n" $i "$a" "$b" + done + + echo +} + + +i9() { + + printf "%10s %s\n" "GUEST" "SAVE_EXCLUDE" + + for i in $guests; do + a="$(vdn-config $i SAVE_EXCLUDE)" + printf "%10s %s\n" $i "$a" + done + + echo +} + + +i10() { + printf "%10s %s\n" "GUEST" "EXTRA_SERVICES" + + for i in $guests; do + a="$(vdn-config $i EXTRA_SERVICES)" + printf "%10s %s\n" $i "$a" + done + + echo +} + +i11() { + printf "%10s %s\n" "GUEST" "EXCLUDE_SERVICES" + + for i in $guests; do + a="$(vdn-config $i EXCLUDE_SERVICES)" + printf "%10s %s\n" $i "$a" + done + + echo + +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +#IDENT=0; computeNetworks + +guests="$(find $NETWORK_DIR -follow -name "*.conf" | sed -re 's/^.*\/([^/]+).conf$/\1/')" + +i1 +i2 +i3 +i4 +i5 +vdn-graph # -a +i6 +i7 +i8 +i9 +i10 +i11 + diff --git a/vdn/bin/vdn-singularity b/vdn/bin/vdn-singularity new file mode 100755 index 0000000..082f116 --- /dev/null +++ b/vdn/bin/vdn-singularity @@ -0,0 +1,8 @@ +#!/bin/bash + +export VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +DIST=$(echo $HOST_RELEASE | cut -d '/' -f 2) + +singularity shell -u /tmp/vdn-$DIST.sif + diff --git a/vdn/bin/vdn-spice-viewer b/vdn/bin/vdn-spice-viewer new file mode 100755 index 0000000..0342998 --- /dev/null +++ b/vdn/bin/vdn-spice-viewer @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +BG=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-b] system +EOF +} + +help() { + cat << EOF + +`basename $0` démarre un client SPICE présentant l'écran du système. + +`synopsis` + +Remarque : seuls les systèmes KVM avec leur variable KVM_VIEWER fixée à "spice" + proposent un écran SPICE. + +-h : affiche cette aide +-b : start in background + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hb" opt; do + case $opt in + h) help; exit 0;; + b) BG=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + [ $# -ne 1 ] && usage || : + + GUEST_NAME=$1; shift; + +} + +# Programme principal + +export VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ $VDN_DEBUG = 1 ] && set -x || : + +[ $GUEST_NAME != "nested" ] && setGuestVars $GUEST_NAME + +GUEST_OWNER=$USER + +[ $GUEST_NAME != "nested" ] && loadGuestVars $GUEST_NAME + +if [ $BG = 1 ]; then + remote-viewer -t $GUEST_NAME spice+unix://$TMPDIR/vdn-spice-$USER-$GUEST_NAME-socket & +else + remote-viewer -t $GUEST_NAME spice+unix://$TMPDIR/vdn-spice-$USER-$GUEST_NAME-socket +fi + +sleep 1 + diff --git a/vdn/bin/vdn-ssh b/vdn/bin/vdn-ssh new file mode 100755 index 0000000..5bd7877 --- /dev/null +++ b/vdn/bin/vdn-ssh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash + +set -eu +#set -x + +#[ "$USER" = "gudavala" ] && set -x || : + +NO_MASTER=0 + +# ATTENTION : Ce script ne doit rien afficher sur la sortie standard +# car utilisé pour la sauvegarde. + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [option...] [login@]system [command] +EOF +} + +help() { + cat << EOF + +`basename $0` démarre une connexion ssh à destination d'un système virtuel. + +`synopsis` + +-h : affiche cette aide +-n : no master mode (utile dans certains cas) + +Les options autorisées sont celles de ssh(1). + +Exemple : + + vdn-ssh -X root@vm-1 # -X pour recevoir les fenêtres graphiques de vm-1. + + # Pour quitter le shell distant : + exit + +EOF +} + +usage() { + synopsis + exit 1 +} + + +args() { + OPTS="" + while [ $# -ne 0 ]; do + reg='^-' + if [[ "$1" =~ $reg ]]; then + OPTS="$OPTS $1" + case "$1" in + -h) help; exit 0;; + -n) NO_MASTER=1;; + -b|-c|-D|-e|-F|-I|-i|-L|-l|-m|-O|-o|-p|-R|-S|-w) + OPTS="$OPTS $2"; shift;; + esac + shift + else + break + fi + done + + LOGIN="" + + GUEST_NAME="$1" + + if echo $1 | grep -q -- '@'; then + LOGIN=`echo $1 | cut -d '@' -f 1`@ + GUEST_NAME=`echo $1 | cut -d '@' -f 2` + fi + + shift + + COMMAND="$@" +} + +# Programme principal + +GUEST_OWNER=$USER + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +#if [ $GUEST_NAME = nested ]; then +# SSH_REDIR_PORT=2222 +#else + +#set -x + + [ ! -e $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs ] && \ + error "Impossible de joindre $GUEST_NAME" + + SSH_REDIR_PORT=`cat $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs | \ + sed -rne 's/^tcp:([0-9]+):22(:|$).*$/\1/p'` + + [ -z "$SSH_REDIR_PORT" ] && error "Impossible de joindre $GUEST_NAME" +#fi + +# No master mode when X11 forwarding +echo $OPTS | grep -q -- -X && { + #echo "Workaround X11 forwarding" >&2 + SSH_GUEST_MASTER=0 +} + + +SSH_MASTER="" +[ $SSH_GUEST_MASTER = 1 -a $NO_MASTER != 1 ] && { + sshGuestControlMaster + SSH_MASTER="$SSH_OPTS -o ControlPersist=10m -o ControlMaster=auto -S $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest-%r@%h:%p" +} + +set +e +export TERM=xterm-256color + +#if [ -z "$COMMAND" ]; then +# COMMAND="bash" +#fi + +#COMMAND="export http_proxy=$http_proxy; export https_proxy=$https_proxy; $COMMAND" +#set -x +ssh $SSH_MASTER $SSH_OPTS -o ServerAliveInterval=5 $OPTS -p $SSH_REDIR_PORT ${LOGIN}localhost "$COMMAND" diff --git a/vdn/bin/vdn-ssh-copy-id b/vdn/bin/vdn-ssh-copy-id new file mode 100755 index 0000000..bef0a48 --- /dev/null +++ b/vdn/bin/vdn-ssh-copy-id @@ -0,0 +1,106 @@ +#!/usr/bin/env bash + +# début des fonctions + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-i [identity_file]] [login@]system +EOF +} + +help() { + cat << EOF + +`basename $0` copie votre clé publique dans un système virtuel. + +`synopsis` + +-h : affiche cette aide +-i : indique le fichier contenant la clé publique à copier + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hi:" opt; do + case $opt in + h) help; exit 0;; + i) IDENTITY="$OPTARG";; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + LAST="$1" +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +IDENTITY="" + +args $@ + +LOGIN="$USER@" +GUEST_NAME=$LAST +if echo $LAST | grep -q '@'; then + LOGIN=`echo $LAST | cut -d '@' -f 1`@ + GUEST_NAME=`echo $LAST | cut -d '@' -f 2` +fi + +if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" +fi + +[ $GUEST_NAME != nested ] && setGuestVars $GUEST_NAME + +GUEST_OWNER=$USER + +[ $GUEST_NAME != nested ] && loadGuestVars $GUEST_NAME + +if [ $GUEST_NAME = nested ]; then + SSH_REDIR_PORT=2222 + SSH_GUEST_MASTER=0 +else + [ ! -e $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs ] && { + echo "Le fichier $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs n'existe pas !" >&2 + echo "Le système $GUEST_NAME est-il démarré ?" >&2 + exit 1 + } + + SSH_REDIR_PORT=`cat $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs | \ + sed -rne 's/^tcp:([0-9]+):22(:|$).*$/\1/p'` +fi + +if [ -z "$SSH_REDIR_PORT" ]; then + echo "Aucune redirection vers le port 22 du système $GUEST_NAME !" >&2 + exit 1 +fi + +opts="-p $SSH_REDIR_PORT -o NoHostAuthenticationForLocalhost=yes" + +[ -n "$IDENTITY" ] && opts="-i $IDENTITY $opts" + + +RUSER=$USER +RUSER=$(echo $@ | sed -rne 's/^.*(^|[[:space:]])(.*)@.*$/\2/p') +[ -z "$RUSER" ] && RUSER=$USER + +name=$(echo $@ | sed -re 's/^.*@(.*)$/\1/') +args=$(echo $LAST | sed -re "s/$name/localhost/g") + +ssh-copy-id $opts $args + +[ $? -eq 0 ] && { + echo -e "Try : \n\nvdn-ssh $RUSER@$name\n" +} + diff --git a/vdn/bin/vdn-ssh-loop b/vdn/bin/vdn-ssh-loop new file mode 100755 index 0000000..444267e --- /dev/null +++ b/vdn/bin/vdn-ssh-loop @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [option...] [login@]system +EOF +} + +help() { + cat << EOF + +`basename $0` effectue, en boucle un ssh à destination d'un système virtuel. + +`synopsis` + +-h : affiche cette aide + +Les options autorisées sont celles de ssh(1). + +Les options précisées dans la variable SSH_OPTS du fichier de configuration +sont implicitement ajoutées. + +Si la connexion échoue, un nouvel essai est effectué après 5 secondes. + +EOF +} + +usage() { + synopsis + exit 1 +} + +usage() { + echo "usage : $0 systemDir [login]" >&2 + exit 1 +} + +args() { + if [ "$1" = "-h" ]; then + help; exit 0; + fi +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +while :; do + $VDN_PATH/bin/vdn-ssh $@ + echo "Retry \"vdn-ssh $1\" in 3 s..." + sleep 3 +done diff --git a/vdn/bin/vdn-sshfs b/vdn/bin/vdn-sshfs new file mode 100755 index 0000000..76b5e56 --- /dev/null +++ b/vdn/bin/vdn-sshfs @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [option...] [login@]system:[path] mountpoint +EOF +} + +help() { + cat << EOF + +`basename $0` monte un répertoire du système virtuel dans un répertoire de l'hôte. + +Remarque : nécessite fuse et sshfs. + +`synopsis` + +-h : affiche cette aide + +Les options autorisées sont celles de sshfs(1). + +Exemple : + + mkdir /tmp/d + vdn-sshfs test@vm-1: /tmp/d # le HOME de test sur vm-1 est monté dans /tmp/d + + # Pour démonter + fusermount -u /tmp/d + +EOF +} + +usage() { + synopsis + exit 1 +} + + +args() { + OPTS="" + while [ $# -ne 0 ]; do + reg='^-' + if [[ "$1" =~ $reg ]]; then + OPTS="$OPTS $1" + case "$1" in + -h) help; exit 0;; + -b|-c|-D|-e|-F|-I|-i|-L|-l|-m|-O|-o|-p|-R|-S|-w) + OPTS="$OPTS $2"; shift;; + esac + shift + else + break + fi + done + + LOGIN="" + DIR="" + GUEST_NAME="$1" + + if echo $1 | grep -q -- '@'; then + LOGIN=`echo $1 | cut -d '@' -f 1`@ + GUEST_NAME=`echo $1 | cut -d '@' -f 2` + + if ! echo $GUEST_NAME | grep -q -- ':'; then + usage + fi + + DIR=$(echo $GUEST_NAME | cut -d ':' -f 2) + GUEST_NAME=$(echo $GUEST_NAME | cut -d ':' -f 1) + fi + + shift + + set +u + MOUNT_DIR="$1" + [ -z "$MOUNT_DIR" -o -n "$2" ] && usage + set -u +} + +# Programme principal + +GUEST_OWNER=$USER + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +#if [ $GUEST_NAME = nested ]; then +# SSH_REDIR_PORT=2222 +#else + [ ! -e $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs ] && + error "Impossible de joindre $GUEST_NAME" + + SSH_REDIR_PORT=`cat $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs | \ + sed -rne 's/^tcp:([0-9]+):22(:|$).*$/\1/p'` + + [ -z "$SSH_REDIR_PORT" ] && error "Impossible de joindre $GUEST_NAME" +#fi + +# No master mode when X11 forwarding +echo $OPTS | grep -q -- -X && { + #echo "Workaround X11 forwarding" >&2 + SSH_GUEST_MASTER=0 +} + +SSH_MASTER="" +[ $SSH_GUEST_MASTER = 1 ] && { + sshGuestControlMaster + SSH_MASTER="$SSH_OPTS -o ControlPersist=10m -o ControlMaster=auto,ControlPath=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest-%r@%h:%p" +} + + +set +e + +#ssh $SSH_MASTER $SSH_OPTS -o ServerAliveInterval=5 $OPTS -p $SSH_REDIR_PORT ${LOGIN}localhost "$COMMAND" +sshfs ${LOGIN}localhost:$DIR $MOUNT_DIR $SSH_MASTER $SSH_OPTS -o ServerAliveInterval=5 $OPTS -p $SSH_REDIR_PORT diff --git a/vdn/bin/vdn-start b/vdn/bin/vdn-start new file mode 100755 index 0000000..69de3eb --- /dev/null +++ b/vdn/bin/vdn-start @@ -0,0 +1,993 @@ +#!/usr/bin/env bash + +set -eu + +set -m # Jobs control + +# Script pour l'exécution d'un système virtuel +# -------------------------------------------- + +NICE=10 +EXPR="" +READ_ON_ERROR=0 +GUI=0; +VDN_TERM=0 +BG=0 + +EXCLUDE_SERVICES="" + +set -a + +# Dans le cas où une redirection (cf. REDIRS ci-dessus) échoue, +# attendre que le port se libère (0) ou chercher le premier port libre +# suivant (1). + +PORT_INC_ALLOWED=1 + +set +a + +# début des fonctions + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [-f] [-g] [-e] [-t] [-v expr] system +EOF +} + +help() { + cat << EOF + +`basename $0` démarre un système virtuel. + +`synopsis` + +Un nom de système correspond au nom d'un répertoire situé dans le +sous répertoire "systems" de Vdn. + +-h : affiche cette aide +-b : execute le système en arrière plan. +-d : mode DEBUG. +-g : si l'interface graphique est démarrée, lui délègue le démarrage. +-t : le terminal courant est utilisé en console. +-e : Attendre "Entrée" si erreur. +-v exp : évalue une expression. Pratique pour la surcharge de variables. + exemple : -v "MEMORY=32; SWAP_SIZE=32" + +EOF +} + +usage() { + synopsis + exit 2 +} + +args() { + local opt + while getopts "hebdgtv:" opt; do + case $opt in + h) help; exit 0;; + b) BG=1;; + d) export VDN_DEBUG=1;; + e) READ_ON_ERROR=1;; + g) GUI=1;; + t) VDN_TERM=1;; + v) export EXPR="$OPTARG";; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi + + case "$GUEST_NAME" in + sae103) + + VDN_TERM=1 + + net=$(vdn-get-network) + if [ "$net" != "/home/UCA/vdn/vdn-bullseye/networks/sae103" ]; then + vdn-set-network-dir /home/UCA/vdn/vdn-bullseye/networks/sae103 + export NETWORK_DIR=/home/UCA/vdn/vdn-bullseye/networks/sae103 + SAVE_DIR="$SAVE_PATH/$(basename $NETWORK_DIR)" + fi + ;; + esac +} + +testIfAlreadyStarted() { + set +e + vdn-alive $GUEST_NAME + r=$? + + [ $r -eq 0 ] && error "Le système virtuel $GUEST_NAME est déjà lancé" +} + + +testVariables() { + [ -z "$AUFS_SIZE" ] && error "AUFS_SIZE not set" +} + +createConfigFile() { + local dir=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-config/etc/vdn + set +u + [ -z "$http_proxy" ] && export http_proxy="" + [ -z "$https_proxy" ] && export https_proxy="" + [ -z "$POST_BOOT" ] && POST_BOOT="" + set -u + + NB_ETH=$(echo $NETWORKS | wc -w) + + + echo -n "Compute network vars... " + #PUBLICS_IP=$(for i in $(vdn-list); do ip=$(vdn-infos $i | grep PUB | sed -re 's/^.*"([0-9.]+)" .*$/\1/'); echo -n "$i:$ip "; done) + PUBLICS_IP=$(for i in $(vdn-list); do ip=$(vdn-query PUBLIC_IP $i); echo -n "$i:$ip "; done) + + PUBLIC_IP=$(vdn-query PUBLIC_IP 0 $GUEST_NAME.$NETWORK_NAME) + + echo "done" + + echo >&2 + echo "NETWORKS : $NETWORKS" >&2 + echo "NB_ETH : $NB_ETH" >&2 + echo "PUBLICS_IP: $PUBLICS_IP" >&2 + + cat <<EOF > $dir/config + +PUBLICS_IP="$PUBLICS_IP" +HOSTS="$HOSTS" +NETWORKS="$NETWORKS" +NETWORK_DIR="$NETWORK_DIR" + +VDN_RESOLV="$VDN_RESOLV" + +VDN_RESOURCES_ALLOCATOR="$VDN_RESOURCES_ALLOCATOR" + + +VDN_PATH="$VDN_PATH" +GUEST_SYS="$GUEST_SYS" +MOUNT_ROOT_PATH="$MOUNT_ROOT_PATH" +EMULATOR="$EMULATOR" + +MODE="$MODE" + +HDA="$HDA" +HDB="$HDB" +HDB_PART_FORMAT="$HDB_PART_FORMAT" +HDB_DIRS="$HDB_DIRS" + +GUEST_PATH="$GUEST_PATH" +GUEST_NAME="$GUEST_NAME" +GUEST_OWNER="$GUEST_OWNER" + +NB_ETH="$NB_ETH" +NB_DISK="$NB_DISK" +PUBLIC_IP="$PUBLIC_IP" + +ON_BOOT="$ON_BOOT" # deprecié +POST_BOOT="$POST_BOOT" +SET_HOSTNAME="$SET_HOSTNAME" + +EXTRA_ETH="$EXTRA_ETH" +EXTRA_ETH_DEFAULT_ROUTE="$EXTRA_ETH_DEFAULT_ROUTE" +EXTRA_ETH_MASQUERADING="$EXTRA_ETH_MASQUERADING" +SET_PROXY="$SET_PROXY" + +AUFS_FILE="$AUFS_FILE" +AUFS_SIZE="$AUFS_SIZE" + +SAVE_EXCLUDE="$SAVE_EXCLUDE" +CLEAR_LOG_WHEN_SAVE="$CLEAR_LOG_WHEN_SAVE" +DELETE_LOG_GZ="$DELETE_LOG_GZ" + +SWAP_FILE="$SWAP_FILE" +SWAP_SIZE="$SWAP_SIZE" + +SSH_IDENTITY="$SSH_IDENTITY" + +EXTRA_SERVICES="$EXTRA_SERVICES" +EXCLUDE_SERVICES="$EXCLUDE_SERVICES" + +RUNLEVEL="$RUNLEVEL" + +DATE=`date +%Y.%m.%d-%T` + +if [ "\$SET_PROXY" = 1 ]; then + + HTTP_PROXY="$http_proxy" + HTTPS_PROXY="$https_proxy" + + echo "export http_proxy=\"\$HTTP_PROXY\"" >> /etc/bash.bashrc + echo "export https_proxy=\"\$HTTPS_PROXY\"" >> /etc/bash.bashrc +fi + +DEFAULT_LANG="$DEFAULT_LANG" + +TIMEZONE="$TIMEZONE" + +XKBMODEL="$XKBMODEL" +XKBLAYOUT="$XKBLAYOUT" +XKBVARIANT="$XKBVARIANT" +XKBOPTIONS="$XKBOPTIONS" +BACKSPACE="$BACKSPACE" + +VDN_DEBUG="$VDN_DEBUG" +EOF +} + +waitEndOfRedirsOld() { + local n=0 + #while netstat -A inet -a -n | grep TIME_WAIT | \ + while ss -a -f inet -n -i state time-wait | \ + grep -q "^$1[[:space:]].*:$2[[:space:]]"; do + if [ $n = 0 ]; then + echo "Attente de la libération du port $2 (1 minute environ...)">&2 + fi + n=1 + sleep 1 + done +} + + + +# Create partition for union + +createUnionPart() { + echo "Create overlayfs ($AUFS_SIZE Mo). " + + + + if [ -n "$AUFS_FILE" ]; then + + [ ! -d $(dirname $AUFS_FILE) ] && mkdir -p $(dirname $AUFS_FILE) + + [ -e $AUFS_FILE ] && rm $AUFS_FILE + dd of=$AUFS_FILE bs=1k seek=$(($AUFS_SIZE*1024)) count=0 &> /dev/null + /sbin/mke2fs -q -F -t ext4 $AUFS_FILE + fi + + #rm -f $OUT_FILE + #dd of=$OUT_FILE bs=1k seek=$(($AUFS_SIZE*1024)) count=0 + + +} + +prepareSwap() { + if [ -n "$SWAP_FILE" ]; then + [ -e $SWAP_FILE ] && rm $SWAP_FILE + if [ -z "$SWAP_SIZE" ]; then + echo -e "SWAP_SIZE not set !" >&2 + exit 2 + fi + echo "Create swap ($SWAP_SIZE Mo). " + dd of=$SWAP_FILE bs=1k seek=$(($SWAP_SIZE*1024)) count=0 &> /dev/null + chmod 600 $SWAP_FILE + /sbin/mkswap $SWAP_FILE > /dev/null + #echo " done." + fi +} + +tgzPrepare() { + createUnionPart +} + +injectScriptsInConfigDir() { + local srcDir=$1 + local dstDir=$2 + + if [ -d $srcDir ]; then + local list=$(cd $srcDir; ls | grep -v prepare.sh*) + if [ -n "$list" ]; then + ( cd $srcDir; cp -a $list $dir/etc/vdn ) + if [ -e $dir/etc/vdn/rc.local ]; then + mv $dir/etc/vdn/rc.local $dir/etc + chmod 755 $dir/etc/rc.local + #echo "SET FILE : $dir/etc/rc.local" + #echo "=== EXTRA === : " + #cat $dir/etc/rc.local | grep EXTRA + fi + fi + fi +} + +createConfigDir() { + local dir=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-config + local tgz="$dir.tgz" + + + #echo "Create config dir..." + + rm -Rf $dir + + mkdir -m 700 $dir + + mkdir -p $dir/etc/vdn + + # Copie des fichiers d'initialisation (/etc/rc.local et autres + # du répertoire direct + + injectScriptsInConfigDir $VDN_PATH/distribs/guests/direct/$GUEST_SYS $dir + + # idem mais spécialise les fichiers (COW, OVERLAY, TGZ) + + if [ $MODE != direct ]; then + injectScriptsInConfigDir $VDN_PATH/distribs/guests/$MODE/$GUEST_SYS $dir + fi + + createConfigFile + + local cp=0 + + for i in $SSH_IDENTITY; do + [ ! -d $dir/etc/vdn/.ssh ] && { + mkdir -p $dir/etc/vdn/.ssh + chmod 700 $dir/etc/vdn/.ssh + } + if [ -e $i ]; then + cp $i $dir/etc/vdn/.ssh/ + cp=1 + fi + done + + [ $cp = 0 ] && error "Aucune clé SSH !" + + [ -e $NETWORK_DIR/authorized-root.txt ] && \ + cp $NETWORK_DIR/authorized-root.txt $dir/etc/vdn + + # Add host files + + for i in $HOST_FILES; do + [ ! -d $dir/etc/vdn/host/$(dirname $i) ] && mkdir -p $dir/etc/vdn/host/$(dirname $i) || : + cp -a $i $dir/etc/vdn/host/$(dirname $i) + done + + if [ -d $NETWORK_DIR/all ]; then + [ ! -d $dir/etc/vdn/all ] && mkdir -p $dir/etc/vdn/all + ( cd $NETWORK_DIR/all && tar czf - . ) | ( cd $dir/etc/vdn/all && tar -xpzf -) + fi + + if [ -d $NETWORK_DIR/$GUEST_NAME ]; then + [ ! -d $dir/etc/vdn/guest ] && mkdir -p $dir/etc/vdn/guest + ( cd $NETWORK_DIR/$GUEST_NAME && tar czf - . ) | ( cd $dir/etc/vdn/guest && tar -xpzf - ) + fi + + # note used + #cp /etc/hosts $dir/etc/vdn + #cp /etc/resolv.conf $dir/etc/vdn + + if [ -d $VDN_PATH/scripts ]; then + cp -a $VDN_PATH/scripts/* $dir/etc/vdn + fi + + # Add allocator + [ -d $dir/etc/vdn/allocators ] && rm -Rf $dir/etc/vdn/allocators + cp -a $VDN_PATH/allocators $dir/etc/vdn + + # Add vdn resolv + cp $VDN_PATH/tools/libnss_vdn.so $dir/etc/vdn + + # Build disk + + ( cd $dir; tar -czf $tgz .; chmod 600 $tgz) + #echo -n "Create config disk... " + dd if=/dev/zero bs=512 count=1 >> $tgz 2> /dev/null + #echo "done." + + #echo "done." + +} + +### KVM (Kernel Virtual Machine) + + +kvm_query_networks() { + + . $VDN_PATH/allocators/$VDN_RESOURCES_ALLOCATOR + + + # 1. redirections + + #if [ $EXTRA_ETH = 1 ]; then + + rm -f $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs + REDIRS=$(echo "$REDIRS" | sed -re 's/[[:space:]]+/ /g') + REDIRS=$(echo "$REDIRS" | sed -re 's/^[[:space:]]+//g') + REDIRS=$(echo "$REDIRS" | sed -re 's/[[:space:]]+$//g') + REDIRS=$(echo "$REDIRS" | sed -re 's/[[:space:]]/\n/g') + + + #echo "REDIRS:$REDIRS" >&2 + + redirs=` + redirsOpt="" + [ -n "$REDIRS" ] || error "REDIRS empty !" + echo "$REDIRS" | ( + export IFS=":" + i=0 + while read proto dstPort com; do + [ -z "$dstPort" ] && continue + + + #echo "dstPort:$dstPort" >&2 + #srcPort=$(vdn_redir $dstPort) + [ -z "$proto" ] && continue + + #set -x + + srcPort=$(computeRedir $GUEST_NAME $proto $dstPort) + + echo "port:$srcPort" >&2 + #set +x + + #if [ "$PORT_INC_ALLOWED" = 1 ]; then + # srcPort=$(findUnusedPort $proto $srcPort $dstPort) + #fi + #waitEndOfRedirs $proto $srcPort + redirsOpt="$redirsOpt -redir $proto:$srcPort::$dstPort" + + echo "Add to : $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs" >&2 + echo "$proto:$srcPort:$dstPort:$com">>$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs + done + echo "$redirsOpt" + ) + ` + #fi + + # 2. cartes Ethernet + + set - $NETWORKS + + #echo -n "-net user " + + #for i in `seq 0 $(($NB_ETH-1))`; do + + ETH=0 + + for i; do + #set -x + net="$i" + + comment=$(echo $net | cut -d '#' -f 2) + net=$(echo $net | cut -d '#' -f 1) + [ "$net" = "$comment" ] && comment="" + + + + [ "$net" = "NET_G" ] && net="NET_0" + + [ "$net" = "$comment" ] && comment="" + + netNum=$(echo $net | sed -re 's/^ *NET_([0-9]+).*$/\1/') + + mac=$(computeMacAddr $GUEST_NAME $ETH) + + if [ "$net" = "none" ]; then + local qemuVersion=$(qemu-system-x86_64 --version | grep version | sed -re 's/^.*version ([0-9.]+).*$/\1/') + if [ "$qemuVersion" \< "3.0.0" ]; then + echo -n "-device virtio-net-pci,mac=$mac " + else + echo -n "-device virtio-net-pci,mac=$mac -nic none " + fi + else + if [ $netNum = 0 ]; then + group=$MCAST_COMMON_ADDR + port=$MCAST_BASE_PORT + else + mcast=$(computeEthLink $GUEST_NAME $netNum) + echo "inetNum:$netNum mcast:$mcast" >&2 + group=`echo $mcast | cut -d : -f 1` + port=`echo $mcast | cut -d : -f 2` + fi + + echo -n "-device virtio-net-pci,netdev=n$(($netNum)),mac=$mac -netdev socket,id=n$(($netNum)),mcast=$group:$port " + fi + + ETH=$(($ETH+1)) + + done + + [ $EXTRA_ETH = 1 ] && { + mac=$(computeMacAddr $GUEST_NAME $NB_ETH) + redirs=$(echo $redirs | sed -re 's/^ *//') + + echo -n "-device virtio-net-pci,netdev=e0,mac=$mac -netdev user,id=e0$redirs" + #echo -n "-net nic,vlan=0,model=$NET_MODEL -net user,vlan=0$redirs" + + } || : +} + +kvm_graphic() { + GRAPHICAL_OPTS="" + + if [ $KVM_VIEWER = "vnc" ]; then + set +e + ps auwx | grep -v grep |grep -q 'ruby.*vdn-gui' + GUI_RUNNING=$? + set -e + if [ $KVM_VIEWER_AUTOSTART = 1 ]; then + if [ $KVM_VIEWER_EMBEDDED = 1 -a $GUI_RUNNING = 0 ]; then + ( sleep 3; sendToGui "vnc-viewer $GUEST_NAME" ) & + else + (sleep 3; vdn-vnc-viewer $GUEST_NAME ) & + fi + fi + GRAPHICAL_OPTS="-serial mon:stdio -monitor null -vnc unix:$TMPDIR/vdn-vnc-$USER-$GUEST_NAME-socket -spice unix,disable-ticketing,addr=$TMPDIR/vdn-spice-$USER-$GUEST_NAME-socket" + #GRAPHICAL_OPTS="$GRAPHICAL_OPTS -device virtio-serial -chardev spicevmc,id=vdagent,debug=0,name=vdagent -device virtserialport,chardev=vdagent,name=com.redhat.spice.0" + + elif [ $KVM_VIEWER = "spice" ]; then + set +e + ps auwx | grep -v grep |grep -q 'ruby.*vdn-gui' + GUI_RUNNING=$? + set -e + if [ $KVM_VIEWER_AUTOSTART = 1 ]; then + #if [ $KVM_VIEWER_EMBEDDED = 1 -a $GUI_RUNNING = 0 ]; then + # ( sleep 3; sendToGui "spice-viewer $GUEST_NAME" ) & + #else + (sleep 1; vdn-spice-viewer -b $GUEST_NAME ) & + #fi + fi + GRAPHICAL_OPTS="-serial mon:stdio -monitor null -vnc unix:$TMPDIR/vdn-vnc-$USER-$GUEST_NAME-socket -spice unix,disable-ticketing,addr=$TMPDIR/vdn-spice-$USER-$GUEST_NAME-socket" + GRAPHICAL_OPTS="$GRAPHICAL_OPTS -device virtio-serial -chardev spicevmc,id=vdagent,debug=0,name=vdagent -device virtserialport,chardev=vdagent,name=com.redhat.spice.0" + #GRAPHICAL_OPTS="$GRAPHICAL_OPTS -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel1,id=channel1,name=org.spice-space.stream.0 -chardev spiceport,name=org.spice-space.stream.0,id=charchannel1" + + elif [ $KVM_VIEWER = "sdl" ]; then + GRAPHICAL_OPTS="-serial mon:stdio -monitor null" + + else + GRAPHICAL_OPTS="-serial mon:stdio -monitor null -nographic" + fi +} + +startKvmTgz() { + + # Config + + local r=0 + + [ ! -d $(dirname $SAVE_FILE) ] && mkdir -p $(dirname $SAVE_FILE) + + case "$MODE" in + tgz) + # Sauvegarde + [ ! -e $SAVE_FILE ] && { + #echo -n "Create minimal save file. " + dd if=/dev/zero of=$SAVE_FILE count=1 bs=1 &> /dev/null + #echo "done." + } + DISK_OPTS="$DISK_OPTS -drive file=$SAVE_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + # aufs part + DISK_OPTS="$DISK_OPTS -drive file=$AUFS_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + # swap + [ -n "$SWAP_FILE" ] && + DISK_OPTS="$DISK_OPTS -drive file=$SWAP_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + #DISK_OPTS="$DISK_OPTS -drive file=$OUT_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + ;; + tgz2) + # Sauvegarde + [ ! -e $SAVE_FILE ] && { + #echo -n "Create minimal save file. " + dd if=/dev/zero of=$SAVE_FILE count=1 bs=1 &> /dev/null + #echo "done." + } + DISK_OPTS="$DISK_OPTS -drive file=$SAVE_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + # aufs part + DISK_OPTS="$DISK_OPTS -drive file=$AUFS_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + # swap + [ -n "$SWAP_FILE" ] && + DISK_OPTS="$DISK_OPTS -drive file=$SWAP_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + + ;; + overlay) + # Sauvegarde + [ ! -e $SAVE_FILE ] && { + #echo -n "Create minimal save file. " + dd of=$SAVE_FILE bs=1k seek=$(($AUFS_SIZE*1024)) count=0 &> /dev/null + /sbin/mke2fs -q -F -t ext4 $SAVE_FILE + #echo "done." + } + DISK_OPTS="$DISK_OPTS -drive file=$SAVE_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + # aufs part + # none, is $SAVE_FILE + + # swap + + [ -n "$SWAP_FILE" ] && + DISK_OPTS="$DISK_OPTS -drive file=$SWAP_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + ;; + esac + + KVM_NETWORKS_OPTS="$networks" + + # Options passées au noyau + + case "$MODE" in + tgz2) KOPTS="";; + *) KOPTS="root=/dev/vda1 ro console=ttyS0,115200n8" + KOPTS="$KOPTS vdn-emulator=kvm vdn-mode=$MODE" + KOPTS="$KOPTS net.ifnames=0 noresume" # fastboot quiet" + + KOPTS="root=/dev/vda1 ro console=ttyS0,115200n8" + KOPTS="$KOPTS vdn-emulator=kvm vdn-mode=$MODE" + KOPTS="$KOPTS net.ifnames=0 noresume" # fastboot quiet" + esac + + createConfigDir + + # config disk (last disk) + configTgz=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-config.tgz + DISK_OPTS="$DISK_OPTS -drive file=$configTgz,if=$KVM_DISK_MODEL,media=disk,format=raw" + + kvm_graphic + + echo "Start begin (EMULATOR=$EMULATOR, SAVE_FILE=$SAVE_FILE)" + + case "$MODE" in + tgz2) cmd="ionice -c 3 nice -$NICE $EMULATOR \ + $KVM_OPTS $GRAPHICAL_OPTS \ + $DISK_OPTS \ + $KVM_NETWORKS_OPTS \ + " + + echo "==> CMD: $cmd" + + ;; + + *) cmd="ionice -c 3 nice -$NICE $EMULATOR \ + $KVM_OPTS $GRAPHICAL_OPTS \ + -initrd $VDN_PATH/files/$INITRAMFS \ + -kernel $VDN_PATH/files/$KERNEL \ + -append '$KOPTS' \ + $DISK_OPTS \ + $KVM_NETWORKS_OPTS \ + " + ;; + esac + + set +u + [ -z "$FORCE_BG" ] && export FORCE_BG=0 || : + + set -u + + #echo $cmd | tr ' ' '\n' + + if [ $BG = 1 -o \( $FORCE_BG = 1 -a $WITH_GUI = 0 \) ]; then + eval $cmd < /dev/null &> /dev/null & + #r=$? + #trap - 0 + return 0 + fi + #if [ $FORCE_BG = 1 ]; then + # eval $cmd & + #fi + + + if [ "$VDN_TERM" = 0 ]; then + set -e + + $VDN_PATH/bin/vdn-terminal "$cmd" + + r=$? + set +e + else + set +e + eval $cmd + r=$? + stty sane + set -e + fi + return $r +} + +startKvmDirectOrCow() { + + local r=0 + + set +u + if [ "$HDA" = "$VDN_DISK_ENV" ]; then + error "Impossible de monter en écriture le disque $VDN_DISK_ENV \nservant à l'environnement chroot.\nAbandon" + fi + set -u + + if [ ! -e "$VDN_PATH/files/$HDA" ]; then + [ -z "$HDA_SIZE" ] && error "Need HDA_SIZE (in Mo)" + echo "Create $HDA. Size=$HDA_SIZE (Mo)" + dd if=/dev/zero of=$VDN_PATH/files/$HDA count=1 bs=512 + dd of=$VDN_PATH/files/$HDA count=0 bs=1M seek=$HDA_SIZE + fi + + [ $MODE = direct -a ! -w $VDN_PATH/files/$HDA ] && \ + error "No write permission on $VDN_PATH/files/$HDA" + + KVM_NETWORKS_OPTS="$networks" + #KVM_NETWORKS_OPTS="$(eval echo $networks)" + + [ -n "$SWAP_FILE" ] && + DISK_OPTS="$DISK_OPTS -drive file=$SWAP_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw" + + createConfigDir + configTgz=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-config.tgz + + set +u + [ -z "$DISK_OPTS" ] && DISK_OPTS="" + set -u + + DISK_OPTS="$DISK_OPTS -drive file=$configTgz,if=$KVM_DISK_MODEL,media=disk,format=raw" + + kvm_graphic + + echo "Start startKvmDirect begin (EMULATOR=$EMULATOR)" + + cmd="ionice -c 3 nice -$NICE $EMULATOR \ + $KVM_OPTS $GRAPHICAL_OPTS \ + $DISK_OPTS \ + $KVM_NETWORKS_OPTS \ + " + + if [ $BG = 1 ]; then + eval $cmd < /dev/null &> /dev/null & + r=$? + trap - 0 + return $r + fi + + if [ "$VDN_TERM" = 0 ]; then + set -e + $VDN_PATH/bin/vdn-terminal "$cmd" + r=$? + set +e + else + set +e + eval $cmd + r=$? + stty sane + set -e + fi + + return $r +} + +startKvm() { + + local r=0 + + echo "Start KVM" + + networks=`kvm_query_networks` + + # for last QEMU versions ( -redir -> hostfwd ) + if echo "$networks" | grep -q -- -redir; then + n=$(echo "$networks" | sed -re 's/-redir +(tcp|udp):([^:]+)::([0-9]+)( |$)/,hostfwd=\1::\2-:\3/g') + networks=$(echo "$n" | sed -re 's/-net user /-net user/g') + fi + + echo "networks : $NETWORKS" >&2 + + NB_DISK=0 + DISK_OPTS="" + + #echo "MODE 1:$MODE" + case "$MODE" in + tgz|overlay|tgz2) + [ $BOOT_CDROM = 1 ] && error "BOOT_CDROM=1 : Can't boot on cdrom !" + #[ -n "$CDROM" ] && warning "CDROM not allowed in tgz mode" + #CDROM="" + tgzPrepare + ;; + cow) + [ -z "$HDA" ] && error "Mode COW : Need HDA Disk" || : + [ -z "$SAVE_FILE" ] && error "Mode COW : Need SAVE_FILE" || : + [ ! -d $(dirname $SAVE_FILE) ] && mkdir -p $(dirname $SAVE_FILE) + [ ! -e "$SAVE_FILE" ] && { + #echo "Create $SAVE_FILE" + + [ $VDN_DEBUG = 1 ] && set -x || : + ( umask 077; qemu-img create -b $VDN_PATH/files/$HDA -f qcow2 $SAVE_FILE ) + set +x + } + ;; + esac + + local boot_hda=on + local boot_cdrom=off + local boot_drive=c + local boot_order=c + + [ $BOOT_CDROM = 1 ] && { + boot_hda=off + boot_cdrom=on + local boot_drive=d + local boot_order=d + } + + #set +x + + case "$MODE" in + tgz|overlay|tgz2) + DISK_OPTS="-boot order=$boot_order -drive file=$VDN_PATH/files/$HDA,if=$KVM_DISK_MODEL,snapshot=on,format=raw" + ;; + cow) + DISK_OPTS="-boot order=$boot_order -drive file=$SAVE_FILE,if=$KVM_DISK_MODEL" + ;; + direct) + DISK_OPTS="-boot order=$boot_order -drive file=$VDN_PATH/files/$HDA,if=$KVM_DISK_MODEL,format=raw" + ;; + *) error "Invalide mode : $MODE" + ;; + esac + + NB_DISK=$(($NB_DISK+1)) + + set +u + [ -z "$SAVE_DIR_HDB" ] && SAVE_DIR_HDB=$SAVE_DIR || : + set -u + + [ ! -d $SAVE_DIR_HDB ] && mkdir -p $SAVE_DIR_HDB || : + + [ -n "$HDB" ] && { + [ ! -e "$SAVE_DIR_HDB/$HDB" ] && { + [ -n "$HDB_SIZE" ] && { + #echo -n "Create HDB ($HDB_SIZE) : $SAVE_DIR_HDB/$HDB... " + dd of=$SAVE_DIR_HDB/$HDB count=0 bs=1M seek=$HDB_SIZE + #echo "done." + } + } + DISK_OPTS="$DISK_OPTS -drive file=$SAVE_DIR_HDB/$HDB,if=$KVM_DISK_MODEL,format=raw" + NB_DISK=$(($NB_DISK+1)) + } + + [ -n "$CDROM" ] && { + [ ! -e "$VDN_PATH/files/$CDROM" ] && { + warning "Cdrom \"$CDROM\" not found !" + } || { + DISK_OPTS="-boot order=$boot_order $DISK_OPTS -drive file=$VDN_PATH/files/$CDROM,media=cdrom" + #NB_DISK=$(($NB_DISK+1)) # /dev/cdrom -> /dev/sr0 + } + } + + prepareSwap + + if [ $KVM_USB_DEVICE_TABLET = 1 ]; then + KVM_OPTS="$KVM_OPTS -usbdevice tablet" + fi + + case $KVM_VIEWER in + no) KVM_OPTS="$KVM_OPTS -nographic";; + sdl) ;; + vnc) ;; + esac + + case "$EMULATOR" in + kvm) [ -w /dev/kvm ] && { + KVM_OPTS="-enable-kvm -cpu host $KVM_OPTS" + cpu=$(getconf _NPROCESSORS_ONLN) + KVM_OPTS="-smp $cpu $KVM_OPTS" + } + EMULATOR=qemu-system-x86_64 + + ;; + qemu) KVM_OPTS="-smp 1 $KVM_OPTS" + EMULATOR=qemu-system-x86_64 + ;; + esac + + #echo "MODE: beforeStart : $MODE" + case $MODE in + tgz|overlay|tgz2) startKvmTgz; r=$?;; + direct|cow) startKvmDirectOrCow; r=$?;; + *) error "Mode $MODE not available" + esac + + return $r + +} + +quit() { + echo "" + #echo "*** $GUEST_NAME stopped !" + #echo "Wait return before rm files !" + #read + #rm -Rf $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-* +} + +# Programme principal + +echo "vdn-start $@" + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +myLocalHostname=$(hostname) + +if [ "$myLocalHostname" = "tokyo" -o "$myLocalHostname" = "iutclinfvm01l" ]; then + echo "Lancer des VM sur $myLocalHostname n'est ni autorisé ni judicieux !" >&2 + echo "Allez sur une machine de TP (commande scan-dept pour lister celles allumées) !" >&2 + exit 9 +fi + +set +u +[ "$VDN_DEBUG" = "1" ] && set -x || : +set -u + +#verifIdent || exit 2 + +export HOSTS="" + +setGuestVars $GUEST_NAME + +GUEST_OWNER=$USER + +DIRECT=0 + +loadGuestVars $GUEST_NAME + +#if ! /sbin/route -n | grep -q '0.0.0.0' ; then +if ! /sbin/ip route | grep -q default; then + error "Pas de route par défaut ! Consultez la FAQ" +fi + +AUFS_OPTS="" + +NB_ETH=`echo $NETWORKS | wc -w` + + +testIfAlreadyStarted + + +# Délègue à interface graphique + +set +u +[ -z "$WITH_GUI" ] && export WITH_GUI=0 +[ -z "$VDN_GUI" ] && export VDN_GUI=0 +set -u + +if [ $GUI = 1 ]; then + if ps auwx | grep -v grep | grep -q 'ruby.*vdn-gui' ; then + sendToGui "start $GUEST_NAME $EXPR" + exit 0 + fi +fi + +set +u +if [ ! -e $VDN_PATH/files/$INITRAMFS_PATH ]; then + if [ $MODE = "tgz" -o $MODE = "overlay" -o $MODE = "tgz2"]; then + error "Impossible de trouver : $INITRAMFS_PATH" + fi +fi +set -u + + +export MOUNT_ROOT_PATH="$VDN_PATH/distribs/guests/$GUEST_SYS/mount-root" + +#echo +#echo "*** Start $GUEST_NAME ($EMULATOR)" +#echo + + +trap quit 0 + +[ -z "$EMULATOR" ] && EMULATOR="kvm" + +case "$EMULATOR" in + kvm|qemu*) + #EXCLUDE_SERVICES="" + #echo "Start kvm..." + startKvm + r=$?;; + + *) echo "L'émulateur $EMULATOR n'est pas supporté !" >&2; exit 2;; +esac + +exit $r + diff --git a/vdn/bin/vdn-start-secure-1 b/vdn/bin/vdn-start-secure-1 new file mode 100755 index 0000000..ce93ba6 --- /dev/null +++ b/vdn/bin/vdn-start-secure-1 @@ -0,0 +1,79 @@ +#!/bin/bash + +VDN_PATH=/home/prof/vdn/vdn +. $VDN_PATH/bin/functions-scripts.sh + +echo "Démarrage du réseau secure-1" + +if [ ! -e ~/.ssh/id_rsa ]; then + echo "Vous de disposez pas de clés RSA nécessaire pour contacter" + echo "les machines virtuelle." + echo + echo "Créez un couple de clés RSA ? (O/n)" + read reply + case "$reply" in + '\n'|''|o|O) ;; + *) echo "Bye !"; exit 0;; + esac + + echo "==========================================================" + echo "Gardez les choix par défaut (touche Entrée) sauf pour" + echo "la \"passphrase\"." + echo + ssh-keygen -t rsa || exit 1 +fi + +n=debian-1 + +if ! vdn-alive $n; then + echo + echo "Démarrage de l'unique VM : $n" + vdn-set-network-dir /home/prof/vdn/vdn/networks/secure-1 + vdn-start -b $n +fi + +echo "Ouverture d'une connexion ssh sur $n ... (Patientez 10..30 secondes...)" +waitSsh $n + +#echo $? +#echo "Configuration de debian-1" +#vdn-ssh root@$n "hostname" +echo +echo "Machine virtuelle : $n démarrée et opérationnelle" +echo + +echo "Commandes de base" +echo "-----------------" +echo +echo "Connexion SSH à $n : dans autant d'autres terminaux que vous le souhaitez" +echo +echo " vdn-ssh root@debian-1 # pour ouvrir une connexion SSH avec $n" +echo +echo +echo "Arrêter la machine virtuelle $n : à faire en fin de scéance." +echo +echo " vdn-halt $n # A faire sur l'hôte." +echo +echo +echo "Tuer la VM (la \"débrancher\" brutalement, à utiliser en dernier recours !)" +echo +echo " vdn-kill $n" +echo +echo +echo "Nettoyer $n : repart d'une configuration vierge." +echo +echo " vdn-clean $n # $n DOIT être arrêtée avant !" +echo +echo +echo "Commandes supplémentaires" +echo "-------------------------" +echo "Outre vdn-ssh, les commandes vdn-scp, vdn-sshfs, vdn-ssh-copy-id permettent" +echo "des transferts de fichiers entre l'hôte et la VM." +echo "Chacune de ses commandes s'utilise presque comme l'orginale et dispose d'une" +echo "aide intégrée affichée via l'option -h" +echo +echo "Exemple :" +echo " vdn-scp hosts root@debian-1:/etc # pour"injecter" un fichier dans la VM." +echo +echo + diff --git a/vdn/bin/vdn-start-wrapper b/vdn/bin/vdn-start-wrapper new file mode 100755 index 0000000..8baf9b0 --- /dev/null +++ b/vdn/bin/vdn-start-wrapper @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] [les options de vdn-start] +EOF +} + +help() { + cat << EOF + +`basename $0` ne fait qu'appeler vdn-start et analyser son + code de retour. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + + +# Programme principal + +[ "$1" = '-h' ] && { help; exit 0; } + +vdn-start "$@" +r=$? + +[ -z "$VDN_DEBUG" ] && VDN_DEBUG=0 || : + +# 1 : when linux killed +# 143 : when kvm is killed +set -x +#if [ $VDN_DEBUG = 1 -o \( $r != 1 -a $r != 143 -a $r != 0 \) ]; then +if [ $VDN_DEBUG = 1 -o \( $r != 143 -a $r != 0 \) ]; then + echo + echo "DEBUG MODE (ret=$r) : Press Return to exit" + read < /dev/tty +#else +# read < /dev/tty +fi diff --git a/vdn/bin/vdn-terminal b/vdn/bin/vdn-terminal new file mode 100755 index 0000000..05466b1 --- /dev/null +++ b/vdn/bin/vdn-terminal @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +name=vdn-terminal + +BIG=0 + +synopsis() { + cat << EOF +Usage : $name [-h] +EOF +} + +help() { + cat << EOF + +$name lance un terminal exécutant une commande en arrière plan. + +`synopsis` + +-h : affiche cette aide +-b : police de 10 et géométrie de 140x43 (big) + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hb" opt; do + case $opt in + h) help; exit 0;; + b) BIG=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + ARGS=$@ +} + +# Programme principal + +args $@ + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +export VDN_PATH + +cmd=$ARGS + +#geom="-fa 'Monospace' -fs 12" +#[ $BIG = 1 ] && geom="-fa 'Monospace' -fs 10 -geometry 140x43" + +opts="-j -rightbar -sb -si -sk -vb" + +geom="" +[ $BIG = 1 ] && geom="--geometry 140x43 --font 12" + + +#c="gnome-terminal --name=\"$name\" -- $cmd" +c="xfce4-terminal $geom --disable-server -T \"$name\" -x $cmd" + +#c="xterm $opts $geom -T \"$name\" -e $cmd" + +echo "vdn-terminal cmd:$c" +eval $c 2> /dev/null & +#vdn-terminal.rb $@ diff --git a/vdn/bin/vdn-test b/vdn/bin/vdn-test new file mode 100755 index 0000000..fdcec31 --- /dev/null +++ b/vdn/bin/vdn-test @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +echo ok diff --git a/vdn/bin/vdn-test-all b/vdn/bin/vdn-test-all new file mode 100755 index 0000000..39925d2 --- /dev/null +++ b/vdn/bin/vdn-test-all @@ -0,0 +1,187 @@ +#!/usr/bin/env bash + +set -eu + +export WITH_GUI=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` tests les scripts "repair*" des réseaux." + +`synopsis` + +-h : affiche cette aide +-g : avec l'interface graphique + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hg" opt; do + case $opt in + h) help; exit 0;; + g) WITH_GUI=1;; + ?) usage;; + esac + done +} + +testHeader() { + n=$1 + echo + echo "Test $n" + echo "==================" + + vdn-set-network-dir $VDN_PATH/networks/$n + export NETWORK_DIR=$VDN_PATH/networks/$n + + if [ $WITH_GUI = 1 ]; then + sendToGui "quit" + vdn $n & + fi +} + +testFinish() { + + systems=$@ + + for i in $systems; do + vdn-halt $i + done + + #wait + + #vdn-clean -f $systems + + if [ $WITH_GUI = 1 ]; then + sendToGui "quit" + fi +} + +testRoutingStatic() { + local n + + n=routing-static + testHeader $n + systems=$(vdn-list | grep -v '^#') + vdn-clean -f $systems + vdn-scripts -n configAll + vdn-scripts -n repairAll + vdn-scripts -n testAll + testFinish $systems +} + +testRoutingOspf() { + local n + + n=routing-ospf + testHeader $n + systems=$(vdn-list | grep -v '^#') + vdn-clean -f $systems + vdn-scripts -n configAll + vdn-scripts -n repairAll + vdn-scripts -n testAll + testFinish $systems +} + +testRoutingRip() { + local n + + n=routing-rip + testHeader $n + systems=$(vdn-list | grep -v '^#') + vdn-clean -f $systems + vdn-scripts -n configAll + vdn-scripts -n repairAll + vdn-scripts -n testAll + testFinish $systems +} + + + +testFirewall() { + local n + + n=firewall + testHeader $n + systems=$(vdn-list | grep -v '^#') + vdn-clean -f $systems + vdn-scripts -n configAll + vdn-scripts -n repairFirewall + vdn-scripts -n testFirewall + vdn-scripts -n repairIPv6 + vdn-scripts -n testIPv6 + testFinish $systems +} + +testFixme() { + local n + + n=fixme + testHeader $n + systems=$(vdn-list | grep -v '^#') + vdn-clean -f $systems + vdn-scripts -n configAll + vdn-scripts -n repairAll + vdn-scripts -n testAll + testFinish $systems + +} + +testDocker() { + local n + + n=docker + testHeader $n + systems=$(vdn-list | grep -v '^#') + vdn-clean -f $systems + vdn-scripts -n configAll + vdn-scripts -n testAll + testFinish $systems +} + +testNagios() { + local n + + n=nagios + testHeader $n + systems=$(vdn-list | grep -v '^#') + vdn-clean -f $systems + vdn-scripts -n configAll + vdn-scripts -n testAll + testFinish $systems +} + + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +export DISABLE_PARALLEL=1 # force sequential mode +export FORCE_BG=1 + +time ( +#time testFirewall +#time testRoutingStatic +#time testRoutingOspf +#time testRoutingRip +#time testFixme +#time testDocker +time testNagios +) diff --git a/vdn/bin/vdn-test-kvm b/vdn/bin/vdn-test-kvm new file mode 100755 index 0000000..04e9dc5 --- /dev/null +++ b/vdn/bin/vdn-test-kvm @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +set -eu + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] +EOF +} + +help() { + cat << EOF + +`basename $0` analyse les capacités de virtualisation de l'hôte. + +`synopsis` + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done +} + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +grep -Eq '(vmx|svm)' /proc/cpuinfo +virtproc=$? +[ -w /dev/kvm ] +kvmwrite=$? +lsmod | grep -q 'kvm_' +kvmproc=$? +lsmod | grep -q 'kvm[^_]' + +kvm=0 +ret=1 + +if [ $virtproc -ne 0 ]; then + echo "Votre processeur ne dispose pas d'instructions de virtualisation :-( !" +fi +if [ $virtproc -eq 0 -a $kvmwrite -ne 0 ]; then + echo + echo "Votre processeur dispose d'instructions de virtualisation." + echo "Cependant vous ne pouvez pas les utiliser :-( !" + echo + + if [ -e /dev/kvm ]; then + msg=" Vous n'avez pas les droits de lecture/écriture sur /dev/kvm !\n L'administrateur (root) doit, au choix, effectuer les actions suivantes :\n 1. chmod 666 /dev/kvm.\n 2. Vous ajouter au groupe $(stat -c %G /dev/kvm).\n Si la deuxième solution est choisie, vous devrez vous déconnecter de votre\n session graphique et vous reconnecter." + + elif lsmod | grep -q kvm; then + msg=" La virtualisation n'est pas activée dans votre BIOS/UEFI." + + + else + proc="intel" + if cat /proc/cpuinfo | grep -i -q amd; then + proc="amd" + fi + msg=" Le module noyau \"kvm-$proc\" n'est pas chargé !\n L'administrateur du système doit exécuter : modprobe kvm-$proc ." + fi + echo "Il semblerait que la raison soit :" + echo -e "$msg" + echo +fi + +if [ $virtproc -eq 0 -a $kvmwrite -eq 0 ]; then + echo "Instructions de virtualisation accessibles." + ret=0 +fi + +exit $ret diff --git a/vdn/bin/vdn-upload-disks b/vdn/bin/vdn-upload-disks new file mode 100755 index 0000000..ba1c4fb --- /dev/null +++ b/vdn/bin/vdn-upload-disks @@ -0,0 +1,177 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +FORCE=0 +DRY=0 +SYSTEMS="" + +synopsis() { + cat << EOF +Usage : `basename $0` [-hdf] system... +EOF +} + +help() { + cat << EOF + +`basename $0` dépose les disques associés au(x) système(s) sur le serveur. + +`synopsis` + +Les disques des systèmes spécifiés sont déposés sur le serveur (rsync via ssh). + +Pour cela, la variable SSH_REPOSITORY doit avoir été fixée dans votre +fichier \$HOME/.vdnrc. Exemple : + +SSH_REPOSITORY="toto@truc.bidule.org:public_html/files" + +Remarque : les fichiers "*.disk" sont préalablement compressés (.gz). + +-h : affiche cette aide +-d : dry run +-f : force : pas de demande de confirmation ! + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "hdf" opt; do + case $opt in + h) help; exit 0;; + d) DRY=1;; + f) FORCE=1;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -lt 1 ] && usage + SYSTEMS=$@ +} + + +uploadDisks() { + + local error=0 absent=0 + + LIST="" + LIST_DISKS="" + + if [ -z "$SSH_REPOSITORY" ]; then + error "SSH_REPOSITORY est vide" + fi + + + # find all files (uniq) + + for i; do + GUEST_NAME="$i" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi + + DISKS_REPOSITOY=""; + CDROM_REPOSITORY=""; + HDA=""; HDB=""; CDROM=""; BOOT_CDROM="0"; + KERNEL=""; INITRAMFS="" + + loadGuestVars $GUEST_NAME + + [ "$MODE" = "tgz" -o "$MODE" = "overlay" ] && { + [ -n "$KERNEL" ] && LIST="$LIST $DISKS_REPOSITORY/$KERNEL" + [ -n "$INITRAMFS" ] && LIST="$LIST $DISKS_REPOSITORY/$INITRAMFS" + } + + [ -n "$CDROM" -a "$BOOT_CDROM" = 1 ] && \ + LIST="$LIST $CDROM_REPOSITORY/$CDROM" + + [ -n "$HDA" ] && LIST_DISKS="$LIST_DISKS $DISKS_REPOSITORY/$HDA.gz" + [ -n "$HDB" ] && LIST_DISKS="$LIST_DISKS $DISKS_REPOSITORY/$HDB.gz" + + done + + #set -x + LIST_DISKS=$(echo $LIST_DISKS | tr -s ' ' '\n' | sort -u | grep -v '^$') + + LIST=$(echo $LIST | tr -s ' ' '\n' | sort -u | grep -v '^$' ||:) + + LIST="$LIST $LIST_DISKS" + + # test dates + + LIST_UPLOAD="" + + for i in $LIST; do + file=$(basename $i .gz) + + set +e + reInfos="$(wget --spider -S $i 2>&1)" + if [ $? -ne 0 ]; then + reDate=0 + else + reDate=$(echo "$reInfos" | grep "Last-Modified:" | cut -d ':' -f 2-) + reDate=$(date -d "$reDate" +%s) + fi + set -e + + locDate=0 + if [ -e $VDN_PATH/files/$file ]; then + locDate=$(stat -c %Y $VDN_PATH/files/$file) + else + warning "$(basename $i) not found" + absent=1 + continue + fi + + [ $locDate -gt $reDate ] && LIST_UPLOAD="$LIST_UPLOAD $i" || + echo "$file : is up to date" + done + + echo $LIST_UPLOAD + + # upload + + for i in $LIST_UPLOAD; do + file=$(basename $i .gz) + if [[ $i =~ \.gz ]]; then + if [ $DRY = 1 ]; then + echo "Dry run : upload $i" + else + tmp=$(mktemp) + echo "Compression ($file). Patience... (environ 5 mn)" + gzip -c -n --rsyncable $VDN_PATH/files/$file > $tmp + chmod 644 $tmp + + echo "Synchronisation. Patience..." + rsync -S --progress $tmp $SSH_REPOSITORY/$file.gz + rm $tmp + fi + else + if [ $DRY = 1 ]; then + echo "Dry run : upload $i" + else + rsync -S --progress $VDN_PATH/files/$file $SSH_REPOSITORY + fi + fi + done + + [ $absent = 1 ] && return 1 || : +} + + +# Programme principal + +GUEST_OWNER=$USER +VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +uploadDisks $SYSTEMS diff --git a/vdn/bin/vdn-viewer b/vdn/bin/vdn-viewer new file mode 100755 index 0000000..5afd2c9 --- /dev/null +++ b/vdn/bin/vdn-viewer @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DEBUG=0 + +synopsis() { + cat << EOF +Usage : `basename $0` [-h] system +EOF +} + +help() { + cat << EOF + +`basename $0` démarre un client SPICE présentant l'écran du système. + +`synopsis` + +Remarque : seuls les systèmes KVM avec leur variable KVM_VIEWER fixée à "spice" + proposent un écran SPICE. + +-h : affiche cette aide + +EOF +} + +usage() { + synopsis + exit 1 +} + +args() { + local opt + while getopts "h" opt; do + case $opt in + h) help; exit 0;; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + + [ $# -ne 1 ] && usage || : + + GUEST_NAME=$1; shift; + +} + +# Programme principal + +export VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh + +args "$@" + +[ $DEBUG = 1 ] && set -x || : + +[ $GUEST_NAME != "nested" ] && setGuestVars $GUEST_NAME + +GUEST_OWNER=$USER + +[ $GUEST_NAME != "nested" ] && loadGuestVars $GUEST_NAME + +remote-viewer -t $GUEST_NAME spice+unix://$TMPDIR/vdn-spice-$USER-$GUEST_NAME-socket & diff --git a/vdn/build-template b/vdn/build-template new file mode 100644 index 0000000..527f837 --- /dev/null +++ b/vdn/build-template @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +build() { + echo "build..." +} + diff --git a/vdn/config.rc b/vdn/config.rc new file mode 100644 index 0000000..63d7708 --- /dev/null +++ b/vdn/config.rc @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# Ce fichier contient les préférences par défaut de l'application VDN +# L'utilisateur peut redéfinir la valeur des variables dans son fichier +# ~/.vdnrc + +# URL par défault des fichiers à télécharger (disque, réseaux, ...) + +DEFAULT_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Taille du disque + +REMOTE_DISK_SIZE=6291456000 + +# Emulateur utilisé. Si vide, autodétection entre KVM et QEMU. + +EMULATOR="" + +# Répertoire du dernier réseau ouvert (par la GUI). +# Ici il joue le rôle de réseau ouvert par défaut. + +NETWORK_DIR="$VDN_PATH/networks/demo" + +# Répertoire des sauvegardes. + +SAVE_PATH="/home/scratch/$USER/vdn-save" + +# Répertoire pour les fichiers temporaires. + +TMPDIR="/tmp/vdn-$USER" + +# Chemin SSH du répertoire distant des disques (devel). + +SSH_REPOSITORY="" + +## Les options ci-dessous sont relatives à l'interface graphique (GUI). + +# Taille de la police pour les terminaux intégrés à VDN + +GRID_FONT="Monospace 11" + +# A fixer à 1 pour que les scripts (prévus pour) soient exécutés en parallèle. + +RUN_PARALLEL=1 + +# Montrer le graphe généré par graphviz plutôt que le graphe édité par Inkscape. + +RAW_GRAPH=0 + +# Autorise l'utilisateur à surcharger ces variables. + +[ -r $HOME/.vdnrc ] && . $HOME/.vdnrc || : + diff --git a/vdn/config.rc.local b/vdn/config.rc.local new file mode 100644 index 0000000..63d7708 --- /dev/null +++ b/vdn/config.rc.local @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# Ce fichier contient les préférences par défaut de l'application VDN +# L'utilisateur peut redéfinir la valeur des variables dans son fichier +# ~/.vdnrc + +# URL par défault des fichiers à télécharger (disque, réseaux, ...) + +DEFAULT_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Taille du disque + +REMOTE_DISK_SIZE=6291456000 + +# Emulateur utilisé. Si vide, autodétection entre KVM et QEMU. + +EMULATOR="" + +# Répertoire du dernier réseau ouvert (par la GUI). +# Ici il joue le rôle de réseau ouvert par défaut. + +NETWORK_DIR="$VDN_PATH/networks/demo" + +# Répertoire des sauvegardes. + +SAVE_PATH="/home/scratch/$USER/vdn-save" + +# Répertoire pour les fichiers temporaires. + +TMPDIR="/tmp/vdn-$USER" + +# Chemin SSH du répertoire distant des disques (devel). + +SSH_REPOSITORY="" + +## Les options ci-dessous sont relatives à l'interface graphique (GUI). + +# Taille de la police pour les terminaux intégrés à VDN + +GRID_FONT="Monospace 11" + +# A fixer à 1 pour que les scripts (prévus pour) soient exécutés en parallèle. + +RUN_PARALLEL=1 + +# Montrer le graphe généré par graphviz plutôt que le graphe édité par Inkscape. + +RAW_GRAPH=0 + +# Autorise l'utilisateur à surcharger ces variables. + +[ -r $HOME/.vdnrc ] && . $HOME/.vdnrc || : + diff --git a/vdn/config.template b/vdn/config.template new file mode 100644 index 0000000..0a5fbbe --- /dev/null +++ b/vdn/config.template @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="128" + +# Chemin du premier disque du système. + +HDA="DebianBuster-amd64.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/config.template.local b/vdn/config.template.local new file mode 100644 index 0000000..9face95 --- /dev/null +++ b/vdn/config.template.local @@ -0,0 +1,231 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="128" + +# Chemin du premier disque du système. + +#HDA="debian.disk" +HDA="DebianBuster-amd64.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/distribs/guests/direct/debian/bullseye/prepare-sae.sh b/vdn/distribs/guests/direct/debian/bullseye/prepare-sae.sh new file mode 100755 index 0000000..7f38c77 --- /dev/null +++ b/vdn/distribs/guests/direct/debian/bullseye/prepare-sae.sh @@ -0,0 +1,571 @@ +#!/usr/bin/env bash + +dir=$(readlink -f $(dirname $0)); +dist=$(echo $dir | sed -re 's,/.*/([^/]+/[^/]+)$,\1,') + +GUEST_RELEASE=$dist + + +[ -z "$http_proxy" ] && http_proxy="" +[ -z "$https_proxy" ] && https_proxy="" + +set -eu + +#http_proxy=http://193.49.118.36:8080 +#https_proxy=http://193.49.118.36:8080 + + +installAll() { + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get update -y; apt-get dist-upgrade -y; apt-get install rsync git mingetty + " + #preInstallForTgz + #installModulesReseaux + #installDocker + #installLamp + #installNagios3 + #installBackportKernel # NE FONCTIONNE PAS, pas utile. + #installVdn + #installPodman + #installForTgz +} + +installPodman() { + # Already installed. + + # WARNING : set kernel.unprivileged_userns_clone + + vdn-ssh -t root@$GUEST_NAME " + cat /etc/sysctl.conf | \ + grep kernel.unprivileged_userns_clone || \ + { echo -e '\\nkernel.unprivileged_userns_clone=1' >> /etc/sysctl.conf; sysctl --system; } + " +} + +## +### Modules réseaux-1 et réseaux-2 ### +### + +installModulesReseaux() { + + # Bad to stretch from squeeze + # php5 php5-mysql smbfs cifs-utils console-tools dhcp3-client samba-doc dhcp3-server sux fuse-utils gproftpd xsmbrowser netkit-ping heartbeat-gui hapm + + # Aucune version du paquet smbfs n'est disponible, mais il existe dans la base + #de données. Cela signifie en général que le paquet est manquant, qu'il est devenu obsolète + #ou qu'il n'est disponible que sur une autre source + #Cependant les paquets suivants le remplacent : + # cifs-utils + + #Aucune version du paquet samba-doc n'est disponible, mais il existe dans la base + #de données. Cela signifie en général que le paquet est manquant, qu'il est devenu obsolète + #ou qu'il n'est disponible que sur une autre source + #Cependant les paquets suivants le remplacent : + # winbind smbclient samba-testsuite samba-common-bin samba-common samba + # registry-tools libsmbclient libpam-winbind + + DEBS="less ssh mingetty rsync net-tools haveged rng-tools dnsutils zerofree" + #DEBS="$DEBS dhcp3-client dhcp3-server sux fuse-utils gproftpd xsmbrowser netkit-ping heartbeat-gui hapm" + #DEBS="$DEBS python-gtk-vnc" + #console-tools console-data console-common + DEBS="$DEBS vim slirp nfs-common nfs-kernel-server" + DEBS="$DEBS sshfs psmisc bsdutils strace busybox-static" + DEBS="$DEBS tcpdump wireshark-gtk nmap" + DEBS="$DEBS manpages" + DEBS="$DEBS curlftpfs ftp curl dillo" + DEBS="$DEBS libapache2-mod-php apache2-doc" + DEBS="$DEBS xbase-clients" + DEBS="$DEBS lynx psmisc file strace lsof telnet links links2" + DEBS="$DEBS iputils-ping" + DEBS="$DEBS rsync dialog" + DEBS="$DEBS firefox-esr" + DEBS="$DEBS nautilus" + DEBS="$DEBS user-mode-linux" + DEBS="$DEBS openvpn" + DEBS="$DEBS quagga proftpd isc-dhcp-server" + + DEBS="$DEBS busybox-static rpcbind debootstrap" + DEBS="$DEBS user-mode-linux" + + DEBS="$DEBS vim-gtk gedit" + + DEBS="$DEBS gpm vde2" + DEBS="$DEBS spice-vdagent" + DEBS="$DEBS gpm vde2" + DEBS="$DEBS gcc make autoconf uidmap pkg-config glib-2.0-dev \ + glib-2.0 libglib2.0-dev dpkg-dev \ + libcap-dev libcap2 libseccomp2 libseccomp-dev" + + # TP Pascal : + DEBS="$DEBS john hashcat sqlmap php default-mysql-server" + + echo "apt-get..." + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get install -y $DEBS + " + # cas de lighttpd + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get install -y lighttpd + systemctl disable lighttpd + " + + + # disable services + + local l="ModemManager NetworkManager NetworkManager-dispatcher NetworkManager-wait-online anacron apparmor autovt@ bgpd dbus-fi.w1.wpa_supplicant1 dbus-org.freedesktop.Avahi dbus-org.freedesktop.ModemManager1 dbus-org.freedesktop.nm-dispatcher dbus-org.freedesktop.timesync1 getty@ hddtemp isisd lighttpd lm-sensors network-manager nfs-kernel-server nmbd openbsd-inetd openvpn ospf6d ospfd pimd portmap pppd-dns ripd ripngd rpcbind rsync smbd speech-dispatcher syslog systemd-timesyncd udisks2 wpa_supplicant zebra nfs-blkmap uml-utilities apache2 proftpd isc-dhcp-server nfs-server" + + vdn-ssh -t root@$GUEST_NAME "for i in $l; do echo \"Disable \$i\"; systemctl disable \$i; done" + + # services (enable) : + #l="avahi-daemon console-setup cron inetd keyboard-setup networking rsyslog ssh sshd uml-utilities" + #l="$l apache2 haveged isc-dhcp-server nfs-server proftpd" + + + +} + +installBackportKernel() { + + local kvers=$(vdn-ssh root@$GUEST_NAME uname -r) + + if ! vdn-ssh root@$GUEST_NAME "grep -q backport /etc/apt/sources.list"; then + vdn-ssh root@$GUEST_NAME 'echo "deb http://ftp.debian.org/debian buster-backports main" >> /etc/apt/sources.list' + fi + + vdn-ssh -t root@$GUEST_NAME "apt-get update; apt-get -y install linux-image-5.3.0-0.bpo.2-amd64" + + vdn-ssh -t root@$GUEST_NAME 'grep -v buster-backports /etc/apt/sources.list > /tmp/o; mv /tmp/o /etc/apt/sources.list' + + vdn-ssh -t root@$GUEST_NAME "apt-get update; apt-get -y install --reinstall linux-image-amd64; update-initramfs -u -k $kvers" +} + +installDocker() { + + set +u + [ -z "$http_proxy" ] && http_proxy="" || : + [ -z "$https_proxy" ] && https_proxy="" || : + set -u + + # désactive le service docker, Voir les scripts de post-configuration + # n'ajoute aucun utilisateur au groupe docker par défaut. Voir les scripts de post-configuration + + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + export https_proxy=$https_proxy + apt-get update + apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common + curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - + apt-key fingerprint 0EBFCD88 + add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/debian \$(lsb_release -cs) stable\" + apt-get update + apt-get -y install docker-ce docker-ce-cli containerd.io docker-compose + curl -L https://raw.githubusercontent.com/docker/compose/1.24.1/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose + + systemctl mask containerd docker +" +} + +installLamp() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get -y install apache2 php mariadb-server libapache2-mod-php php-gd php-mysql + systemctl disable mariadb mysql + " +} + +preInstallForTgz() { + + echo "Set /etc/modprobe.d/blacklist-floppy.conf..." + vdn-ssh root@$GUEST_NAME "f=/etc/modprobe.d/blacklist-floppy.conf; ! grep -q floppy \$f && echo \"blacklist floppy\" >> \$f || :" + + echo "Set /etc/initramfs-tools/modules..." + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q ne2k_pci \$f && echo ne2k_pci >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q 8390 \$f && echo 8390 >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q virtio_net \$f && echo virtio_net >> \$f || :" + + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q overlay \$f && echo overlay >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q aufs \$f && echo aufs >> \$f || :" + + echo "Create /etc/initramfs-tools/scripts/local-bottom/overlay.sh ..." + + + cat << EOF | vdn-ssh root@$GUEST_NAME "cat > /etc/initramfs-tools/scripts/local-bottom/overlay.sh" +#!/bin/sh + + listDisks() { + if [ "\$EMULATOR" = linux ]; then + ls /dev/ubd[[:lower:]] # | grep -E 'udb[[:lower:]]r?' + else + ls /dev/?d[[:lower:]] + fi + } + + +PREREQ="" + + prereqs() + { + echo "\$PREREQ" + } + +case \$1 in + prereqs) + prereqs + exit 0 + ;; + esac + + +! grep -E -q 'vdn-mode=(tgz|overlay)' /proc/cmdline && { + echo "*** local-bottom/overlay.sh : exit (no mode tgz or overlay)" >&2 + exit 0 +} + + + +echo +echo "*** local-bottom/overlay.sh ***" + +echo "Extract configuration..." + +listDisks + +confDisk=\$(listDisks | tail -n 1) + +echo confDisk=\$confDisk + +mkdir /vdn +tar -C / -xvzf \$confDisk + +if [ \$? -ne 0 ]; then + echo "Erreur lors de l'extraction de la configuration" >&2 + echo "Lancement d'un shell pour inspection..." >&2 + export PS1="initramfs:\w# " + /bin/sh -i +fi + +if [ -e /etc/vdn/mount-root ]; then + sh /etc/vdn/mount-root +else + echo "/etc/vdn/mount-root introuvable !" >&2 + echo "ARRÊT du système !">&2 + while :; do sleep 1000; done +fi + +EOF + + vdn-ssh root@$GUEST_NAME chmod 755 /etc/initramfs-tools/scripts/local-bottom/overlay.sh +} + + +installForTgz() { + + echo "Install for tgz..." + + + local kvers + + kvers=$(vdn-ssh root@$GUEST_NAME ls /lib/modules | sort -Vr | head -n1) + [ -z "$kvers" ] && { + echo "Warning : /lib/modules is empty !" >&2 + kvers=$(vdn-ssh root@$GUEST_NAME uname -r) + echo "Use current kernel : $kvers" + } + + rsync -e vdn-ssh root@$GUEST_NAME:/boot/vmlinuz-$kvers $VDN_PATH/files + + # initramfs (created it if necessary) + + + vdn-ssh root@$GUEST_NAME " + rm -f /boot/initrd.img-$kvers.keep + if [ -e /boot/initrd.img-$kvers ]; then + cp /boot/initrd.img-$kvers /boot/initrd.img-$kvers.keep + fi + + echo \"update-initramfs ...\" >&2 + update-initramfs -u -k $kvers + + #cat /etc/initramfs-tools/scripts/local-bottom/overlay.sh + rm /etc/initramfs-tools/scripts/local-bottom/overlay.sh + + cp /boot/initrd.img-$kvers /boot/initrd-tgz.img-$kvers + + if [ -e /boot/initrd.img-$kvers.keep ]; then + mv /boot/initrd.img-$kvers.keep /boot/initrd.img-$kvers + fi +" + + rsync -e vdn-ssh root@$GUEST_NAME:/boot/initrd-tgz.img-$kvers $VDN_PATH/files + +} + +installNagios1() { + # from https://www.itzgeek.com/how-tos/linux/debian/how-to-install-nagios-on-debian-9-stretch.html + + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt update + apt install -y build-essential apache2 php openssl perl make php-gd libgd2-xpm-dev libapache2-mod-php libperl-dev libssl-dev daemon wget apache2-utils unzip + useradd nagios + groupadd nagcmd + usermod -a -G nagcmd nagios + usermod -a -G nagcmd www-data + cd /tmp/ + wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.4.5.tar.gz + tar -zxvf nagios-4.4.5.tar.gz + cd /tmp/nagios-4.4.5/ + ./configure --with-nagios-group=nagios --with-command-group=nagcmd --with-httpd_conf=/etc/apache2/sites-enabled/ + make all + make install + make install-init + make install-config + make install-commandmode + make install-webconf +" +} + +installNagios2() { + + ### sudo nano /usr/local/nagios/etc/objects/contacts.cfg + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + #sed -i -re 's/^.*email.*$/email root@localhost ;/' /usr/local/nagios/etc/objects/contacts.cfg + htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin + a2enmod cgi + systemctl restart apache2 + cd /tmp + wget https://nagios-plugins.org/download/nagios-plugins-2.2.1.tar.gz + tar -zxvf /tmp/nagios-plugins-2.2.1.tar.gz + cd /tmp/nagios-plugins-2.2.1/ + ./configure --with-nagios-user=nagios --with-nagios-group=nagios + make + make install + /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg +" + +} + +installNagios3() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt install -y nagios-nrpe-server nagios-plugins + apt -y install nagios-nrpe-plugin +" +} + +installVdn() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + cd /tmp + rm -Rf vdn + git clone http://opale.u-clermont1.fr/vdn/git/vdn.git + echo "vdn/bin/vdn-prepare $GUEST_RELEASE" + vdn/bin/vdn-prepare $GUEST_RELEASE +" +} + + + + +# début des fonctions + +synopsis() { + cat << EOF +Usage : `basename $0` [-i identity] system +EOF +} + +help() { + cat << EOF + +`basename $0` prepare un système virtuel pour fonctionner en mode DIRECT. + +`synopsis` + +Une identification par clé pour ssh est mise en place (cf. -i identity) +pour éviter les identification par mot de passe lors des connexions ssh +de l'hôte vers l'invité nécessaires à l'opération. + +Les mots de passes sont fixés de façon aléatoire + +-h : affiche cette aide +-i identity : chemin de la clé publique à utiliser. + +EOF +} + +usage() { + synopsis + exit 2 +} + +args() { + local opt + while getopts "hi:" opt; do + case $opt in + h) help; exit 0;; + i) IDENTITY="$OPTARG";; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/../../../../..); . $VDN_PATH/bin/functions.sh + +args "$@" + +PROG_DIR=$(readlink -f $(dirname $0)) + +if ! $VDN_PATH/bin/vdn-alive $GUEST_NAME; then + error "Le système $GUEST_NAME n'est pas démarré" +fi + +loadGuestVars $GUEST_NAME + +foundIdentity=0 +for i in $SSH_IDENTITY; do + if [ -e $i ]; then + IDENTITY=$i + foundIdentity=1 + fi +done + +[ $foundIdentity = 0 ] && error "Aucune clé SSH !" + +if vdn-ssh -n -o PasswordAuthentication=no root@$GUEST_NAME exit 0 ; then + vdn-ssh-copy-id -i $IDENTITY root@$GUEST_NAME +fi + +#echo "apt-get..." +#vdn-ssh root@$GUEST_NAME apt-get install rsync net-tools + +#echo "Set /etc/initramfs-tools/modules..." +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q ne2k_pci \$f && echo ne2k_pci >> \$f || :" +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q 8390 \$f && echo 8390 >> \$f || :" +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q virtio_net \$f && echo virtio_net >> \$f || :" + +#echo "Set /etc/modprobe.d/blacklist-floppy.conf..." +#vdn-ssh root@$GUEST_NAME "f=/etc/modprobe.d/blacklist-floppy.conf; ! grep -q floppy \$f && echo \"blacklist floppy\" >> \$f || :" + + +vdn-ssh -t root@$GUEST_NAME chmod 755 / + +echo "Add test user to kvm group (for nested)" +vdn-ssh root@$GUEST_NAME "addgroup test kvm" + +echo "Add test user to kvm group (for nested)" +vdn-ssh root@$GUEST_NAME "addgroup test docker || :" + + +#echo "Add test user to sudo group" +#vdn-ssh root@$GUEST_NAME "addgroup test sudo" + +echo "Set vim syntax=on" +vdn-ssh root@$GUEST_NAME "cat /etc/vim/vimrc | sed -re 's/^.*syntax on.*$/syntax on/' > /etc/vim/vimrc.new" +vdn-ssh root@$GUEST_NAME "mv /etc/vim/vimrc.new /etc/vim/vimrc" +vdn-ssh root@$GUEST_NAME "cp /etc/vim/vimrc ~/.vimrc" +vdn-ssh root@$GUEST_NAME "cp /etc/vim/vimrc /home/test/.vimrc; chown test: /home/test/.vimrc" + +echo "Allow root autologin on ttyS0" +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^ExecStart=.*$,ExecStart=-/sbin/mingetty --noclear --autologin root %I,' /lib/systemd/system/serial-getty@.service" + +# kernel params (in grub ) + +echo "Allow net.ifnames=0 in GRUB " +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^GRUB_CMDLINE_LINUX_DEFAULT=.*$,GRUB_CMDLINE_LINUX_DEFAULT=\"net.ifnames=0 console=ttyS0\,115200n8\",' /etc/default/grub" +echo " 1s timout for menu" +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^GRUB_TIMEOUT=.*$,GRUB_TIMEOUT=1,' /etc/default/grub" +vdn-ssh root@$GUEST_NAME "update-grub" + +########################## + +export http_proxy=\"$http_proxy\" +export https_proxy=\"$https_proxy\" + +echo "http_proxy:$http_proxy" +echo "https_proxy:$https_proxy" + +#echo "For debug : exit to guit" +#vdn-ssh root@$GUEST_NAME + +installAll + +vdn-ssh root@$GUEST_NAME "systemctl mask nagios" + +########################## + +echo "Set rc.local..." +if [ -e $PROG_DIR/rc.local ]; then + vdn-scp -p $PROG_DIR/rc.local root@$GUEST_NAME:/etc + vdn-ssh root@$GUEST_NAME chmod 755 /etc/rc.local +fi + +## Install lxdm +#echo "Install lxdm..." +# +#vdn-ssh -t root@$GUEST_NAME " +#apt-get -y install lxdm +#apt-get -y remove openbox +#" + +#echo "Default xsession : xfce4 " +#vdn-ssh root@$GUEST_NAME "sed -i -re 's,^# session=.*$,session=/usr/bin/startxfce4,' /etc/lxdm/lxdm.conf" + +#echo "For debug : exit to guit" +#vdn-ssh root@$GUEST_NAME + +# Clear + +echo "Clear /var/log, history, ..." +vdn-ssh -t root@$GUEST_NAME ' +export http_proxy=$http_proxy + +rm -Rf /etc/vdn + +#for i in $(find /var/log -type f); do cat /dev/null > $i; done +find /var/log -name "*.gz" -delete + +echo "Clear .bash_history" + +rm -f /root/.bash_history +touch /root/.bash_history +chmod 600 /root/.bash_history +rm -f /home/test/.bash_history +touch /home/test/.bash_history +chmod 600 /home/test/.bash_history + +echo "Clear .cache .mozilla" +for d in /root /home/test; do + rm -Rf $d/.cache + rm -Rf $d/.mozilla +done + +echo "Clear authorized_keys" + +for d in /root /home/test; do + rm -f $d/.ssh/authorized_keys + rm -f $d/.ssh/authorized_keys +done + +echo "Clear apt-cache..." +apt autoremove -y +sleep 1 +apt-get clean + +echo end of cleaning ! +' + diff --git a/vdn/distribs/guests/direct/debian/bullseye/prepare.sh b/vdn/distribs/guests/direct/debian/bullseye/prepare.sh new file mode 100755 index 0000000..8ffe0ba --- /dev/null +++ b/vdn/distribs/guests/direct/debian/bullseye/prepare.sh @@ -0,0 +1,568 @@ +#!/usr/bin/env bash + +dir=$(readlink -f $(dirname $0)); +dist=$(echo $dir | sed -re 's,/.*/([^/]+/[^/]+)$,\1,') + +GUEST_RELEASE=$dist + + +[ -z "$http_proxy" ] && http_proxy="" +[ -z "$https_proxy" ] && https_proxy="" + +set -eu + +#http_proxy=http://193.49.118.36:8080 +#https_proxy=http://193.49.118.36:8080 + + +installAll() { + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get update -y; apt-get dist-upgrade -y; apt-get install rsync git mingetty + " + preInstallForTgz + installModulesReseaux + installDocker + installLamp + #installNagios3 + #installBackportKernel # NE FONCTIONNE PAS, pas utile. + #installVdn + #installPodman + installForTgz +} + +installPodman() { + # Already installed. + + # WARNING : set kernel.unprivileged_userns_clone + + vdn-ssh -t root@$GUEST_NAME " + cat /etc/sysctl.conf | \ + grep kernel.unprivileged_userns_clone || \ + { echo -e '\\nkernel.unprivileged_userns_clone=1' >> /etc/sysctl.conf; sysctl --system; } + " +} + +## +### Modules réseaux-1 et réseaux-2 ### +### + +installModulesReseaux() { + + # Bad to stretch from squeeze + # php5 php5-mysql smbfs cifs-utils console-tools dhcp3-client samba-doc dhcp3-server sux fuse-utils gproftpd xsmbrowser netkit-ping heartbeat-gui hapm + + # Aucune version du paquet smbfs n'est disponible, mais il existe dans la base + #de données. Cela signifie en général que le paquet est manquant, qu'il est devenu obsolète + #ou qu'il n'est disponible que sur une autre source + #Cependant les paquets suivants le remplacent : + # cifs-utils + + #Aucune version du paquet samba-doc n'est disponible, mais il existe dans la base + #de données. Cela signifie en général que le paquet est manquant, qu'il est devenu obsolète + #ou qu'il n'est disponible que sur une autre source + #Cependant les paquets suivants le remplacent : + # winbind smbclient samba-testsuite samba-common-bin samba-common samba + # registry-tools libsmbclient libpam-winbind + + DEBS="less ssh mingetty rsync net-tools haveged rng-tools dnsutils zerofree" + #DEBS="$DEBS dhcp3-client dhcp3-server sux fuse-utils gproftpd xsmbrowser netkit-ping heartbeat-gui hapm" + #DEBS="$DEBS python-gtk-vnc" + #console-tools console-data console-common + DEBS="$DEBS vim slirp nfs-common nfs-kernel-server" + DEBS="$DEBS sshfs psmisc bsdutils strace busybox-static" + DEBS="$DEBS tcpdump wireshark-gtk nmap" + DEBS="$DEBS manpages" + DEBS="$DEBS curlftpfs ftp curl dillo" + DEBS="$DEBS libapache2-mod-php apache2-doc" + DEBS="$DEBS xbase-clients" + DEBS="$DEBS lynx psmisc file strace lsof telnet links links2" + DEBS="$DEBS iputils-ping" + DEBS="$DEBS rsync dialog" + DEBS="$DEBS firefox-esr" + DEBS="$DEBS nautilus" + DEBS="$DEBS user-mode-linux" + DEBS="$DEBS openvpn" + DEBS="$DEBS quagga proftpd isc-dhcp-server" + + DEBS="$DEBS busybox-static rpcbind debootstrap" + DEBS="$DEBS user-mode-linux" + + DEBS="$DEBS vim-gtk gedit" + + DEBS="$DEBS gpm vde2" + DEBS="$DEBS spice-vdagent" + DEBS="$DEBS gpm vde2" + DEBS="$DEBS gcc make autoconf uidmap pkg-config glib-2.0-dev \ + glib-2.0 libglib2.0-dev dpkg-dev \ + libcap-dev libcap2 libseccomp2 libseccomp-dev" + + # TP Pascal : + DEBS="$DEBS john hashcat sqlmap php default-mysql-server" + + echo "apt-get..." + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get install -y $DEBS + " + # cas de lighttpd + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get install -y lighttpd + systemctl disable lighttpd + " + + + # disable services + + local l="ModemManager NetworkManager NetworkManager-dispatcher NetworkManager-wait-online anacron apparmor autovt@ bgpd dbus-fi.w1.wpa_supplicant1 dbus-org.freedesktop.Avahi dbus-org.freedesktop.ModemManager1 dbus-org.freedesktop.nm-dispatcher dbus-org.freedesktop.timesync1 getty@ hddtemp isisd lighttpd lm-sensors network-manager nfs-kernel-server nmbd openbsd-inetd openvpn ospf6d ospfd pimd portmap pppd-dns ripd ripngd rpcbind rsync smbd speech-dispatcher syslog systemd-timesyncd udisks2 wpa_supplicant zebra nfs-blkmap uml-utilities apache2 proftpd isc-dhcp-server nfs-server" + + vdn-ssh -t root@$GUEST_NAME "for i in $l; do echo \"Disable \$i\"; systemctl disable \$i; done" + + # services (enable) : + #l="avahi-daemon console-setup cron inetd keyboard-setup networking rsyslog ssh sshd uml-utilities" + #l="$l apache2 haveged isc-dhcp-server nfs-server proftpd" +} + +installBackportKernel() { + + local kvers=$(vdn-ssh root@$GUEST_NAME uname -r) + + if ! vdn-ssh root@$GUEST_NAME "grep -q backport /etc/apt/sources.list"; then + vdn-ssh root@$GUEST_NAME 'echo "deb http://ftp.debian.org/debian buster-backports main" >> /etc/apt/sources.list' + fi + + vdn-ssh -t root@$GUEST_NAME "apt-get update; apt-get -y install linux-image-5.3.0-0.bpo.2-amd64" + + vdn-ssh -t root@$GUEST_NAME 'grep -v buster-backports /etc/apt/sources.list > /tmp/o; mv /tmp/o /etc/apt/sources.list' + + vdn-ssh -t root@$GUEST_NAME "apt-get update; apt-get -y install --reinstall linux-image-amd64; update-initramfs -u -k $kvers" +} + +installDocker() { + + set +u + [ -z "$http_proxy" ] && http_proxy="" || : + [ -z "$https_proxy" ] && https_proxy="" || : + set -u + + # désactive le service docker, Voir les scripts de post-configuration + # n'ajoute aucun utilisateur au groupe docker par défaut. Voir les scripts de post-configuration + + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + export https_proxy=$https_proxy + apt-get update + apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common + curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - + apt-key fingerprint 0EBFCD88 + add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/debian \$(lsb_release -cs) stable\" + apt-get update + apt-get -y install docker-ce docker-ce-cli containerd.io docker-compose + curl -L https://raw.githubusercontent.com/docker/compose/1.24.1/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose + + systemctl mask containerd docker +" +} + +installLamp() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get -y install apache2 php mariadb-server libapache2-mod-php php-gd php-mysql + systemctl disable mariadb mysql + " +} + +preInstallForTgz() { + + echo "Set /etc/modprobe.d/blacklist-floppy.conf..." + vdn-ssh root@$GUEST_NAME "f=/etc/modprobe.d/blacklist-floppy.conf; ! grep -q floppy \$f && echo \"blacklist floppy\" >> \$f || :" + + echo "Set /etc/initramfs-tools/modules..." + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q ne2k_pci \$f && echo ne2k_pci >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q 8390 \$f && echo 8390 >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q virtio_net \$f && echo virtio_net >> \$f || :" + + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q overlay \$f && echo overlay >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q aufs \$f && echo aufs >> \$f || :" + + echo "Create /etc/initramfs-tools/scripts/local-bottom/overlay.sh ..." + + + cat << EOF | vdn-ssh root@$GUEST_NAME "cat > /etc/initramfs-tools/scripts/local-bottom/overlay.sh" +#!/bin/sh + + listDisks() { + if [ "\$EMULATOR" = linux ]; then + ls /dev/ubd[[:lower:]] # | grep -E 'udb[[:lower:]]r?' + else + ls /dev/?d[[:lower:]] + fi + } + + +PREREQ="" + + prereqs() + { + echo "\$PREREQ" + } + +case \$1 in + prereqs) + prereqs + exit 0 + ;; + esac + + +! grep -E -q 'vdn-mode=(tgz|overlay)' /proc/cmdline && { + echo "*** local-bottom/overlay.sh : exit (no mode tgz or overlay)" >&2 + exit 0 +} + + + +echo +echo "*** local-bottom/overlay.sh ***" + +echo "Extract configuration..." + +listDisks + +confDisk=\$(listDisks | tail -n 1) + +echo confDisk=\$confDisk + +mkdir /vdn +tar -C / -xvzf \$confDisk + +if [ \$? -ne 0 ]; then + echo "Erreur lors de l'extraction de la configuration" >&2 + echo "Lancement d'un shell pour inspection..." >&2 + export PS1="initramfs:\w# " + /bin/sh -i +fi + +if [ -e /etc/vdn/mount-root ]; then + sh /etc/vdn/mount-root +else + echo "/etc/vdn/mount-root introuvable !" >&2 + echo "ARRÊT du système !">&2 + while :; do sleep 1000; done +fi + +EOF + + vdn-ssh root@$GUEST_NAME chmod 755 /etc/initramfs-tools/scripts/local-bottom/overlay.sh +} + + +installForTgz() { + + echo "Install for tgz..." + + + local kvers + + kvers=$(vdn-ssh root@$GUEST_NAME ls /lib/modules | sort -Vr | head -n1) + [ -z "$kvers" ] && { + echo "Warning : /lib/modules is empty !" >&2 + kvers=$(vdn-ssh root@$GUEST_NAME uname -r) + echo "Use current kernel : $kvers" + } + + rsync -e vdn-ssh root@$GUEST_NAME:/boot/vmlinuz-$kvers $VDN_PATH/files + + # initramfs (created it if necessary) + + + vdn-ssh root@$GUEST_NAME " + rm -f /boot/initrd.img-$kvers.keep + if [ -e /boot/initrd.img-$kvers ]; then + cp /boot/initrd.img-$kvers /boot/initrd.img-$kvers.keep + fi + + echo \"update-initramfs ...\" >&2 + update-initramfs -u -k $kvers + + #cat /etc/initramfs-tools/scripts/local-bottom/overlay.sh + rm /etc/initramfs-tools/scripts/local-bottom/overlay.sh + + cp /boot/initrd.img-$kvers /boot/initrd-tgz.img-$kvers + + if [ -e /boot/initrd.img-$kvers.keep ]; then + mv /boot/initrd.img-$kvers.keep /boot/initrd.img-$kvers + fi +" + + rsync -e vdn-ssh root@$GUEST_NAME:/boot/initrd-tgz.img-$kvers $VDN_PATH/files + +} + +installNagios1() { + # from https://www.itzgeek.com/how-tos/linux/debian/how-to-install-nagios-on-debian-9-stretch.html + + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt update + apt install -y build-essential apache2 php openssl perl make php-gd libgd2-xpm-dev libapache2-mod-php libperl-dev libssl-dev daemon wget apache2-utils unzip + useradd nagios + groupadd nagcmd + usermod -a -G nagcmd nagios + usermod -a -G nagcmd www-data + cd /tmp/ + wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.4.5.tar.gz + tar -zxvf nagios-4.4.5.tar.gz + cd /tmp/nagios-4.4.5/ + ./configure --with-nagios-group=nagios --with-command-group=nagcmd --with-httpd_conf=/etc/apache2/sites-enabled/ + make all + make install + make install-init + make install-config + make install-commandmode + make install-webconf +" +} + +installNagios2() { + + ### sudo nano /usr/local/nagios/etc/objects/contacts.cfg + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + #sed -i -re 's/^.*email.*$/email root@localhost ;/' /usr/local/nagios/etc/objects/contacts.cfg + htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin + a2enmod cgi + systemctl restart apache2 + cd /tmp + wget https://nagios-plugins.org/download/nagios-plugins-2.2.1.tar.gz + tar -zxvf /tmp/nagios-plugins-2.2.1.tar.gz + cd /tmp/nagios-plugins-2.2.1/ + ./configure --with-nagios-user=nagios --with-nagios-group=nagios + make + make install + /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg +" + +} + +installNagios3() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt install -y nagios-nrpe-server nagios-plugins + apt -y install nagios-nrpe-plugin +" +} + +installVdn() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + cd /tmp + rm -Rf vdn + git clone http://opale.u-clermont1.fr/vdn/git/vdn.git + echo "vdn/bin/vdn-prepare $GUEST_RELEASE" + vdn/bin/vdn-prepare $GUEST_RELEASE +" +} + + + + +# début des fonctions + +synopsis() { + cat << EOF +Usage : `basename $0` [-i identity] system +EOF +} + +help() { + cat << EOF + +`basename $0` prepare un système virtuel pour fonctionner en mode DIRECT. + +`synopsis` + +Une identification par clé pour ssh est mise en place (cf. -i identity) +pour éviter les identification par mot de passe lors des connexions ssh +de l'hôte vers l'invité nécessaires à l'opération. + +Les mots de passes sont fixés de façon aléatoire + +-h : affiche cette aide +-i identity : chemin de la clé publique à utiliser. + +EOF +} + +usage() { + synopsis + exit 2 +} + +args() { + local opt + while getopts "hi:" opt; do + case $opt in + h) help; exit 0;; + i) IDENTITY="$OPTARG";; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/../../../../..); . $VDN_PATH/bin/functions.sh + +args "$@" + +PROG_DIR=$(readlink -f $(dirname $0)) + +if ! $VDN_PATH/bin/vdn-alive $GUEST_NAME; then + error "Le système $GUEST_NAME n'est pas démarré" +fi + +loadGuestVars $GUEST_NAME + +foundIdentity=0 +for i in $SSH_IDENTITY; do + if [ -e $i ]; then + IDENTITY=$i + foundIdentity=1 + fi +done + +[ $foundIdentity = 0 ] && error "Aucune clé SSH !" + +if vdn-ssh -n -o PasswordAuthentication=no root@$GUEST_NAME exit 0 ; then + vdn-ssh-copy-id -i $IDENTITY root@$GUEST_NAME +fi + +#echo "apt-get..." +#vdn-ssh root@$GUEST_NAME apt-get install rsync net-tools + +#echo "Set /etc/initramfs-tools/modules..." +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q ne2k_pci \$f && echo ne2k_pci >> \$f || :" +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q 8390 \$f && echo 8390 >> \$f || :" +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q virtio_net \$f && echo virtio_net >> \$f || :" + +#echo "Set /etc/modprobe.d/blacklist-floppy.conf..." +#vdn-ssh root@$GUEST_NAME "f=/etc/modprobe.d/blacklist-floppy.conf; ! grep -q floppy \$f && echo \"blacklist floppy\" >> \$f || :" + + +vdn-ssh -t root@$GUEST_NAME chmod 755 / + +echo "Add test user to kvm group (for nested)" +vdn-ssh root@$GUEST_NAME "addgroup test kvm" + +echo "Add test user to kvm group (for nested)" +vdn-ssh root@$GUEST_NAME "addgroup test docker || :" + + +#echo "Add test user to sudo group" +#vdn-ssh root@$GUEST_NAME "addgroup test sudo" + +echo "Set vim syntax=on" +vdn-ssh root@$GUEST_NAME "cat /etc/vim/vimrc | sed -re 's/^.*syntax on.*$/syntax on/' > /etc/vim/vimrc.new" +vdn-ssh root@$GUEST_NAME "mv /etc/vim/vimrc.new /etc/vim/vimrc" +vdn-ssh root@$GUEST_NAME "cp /etc/vim/vimrc ~/.vimrc" +vdn-ssh root@$GUEST_NAME "cp /etc/vim/vimrc /home/test/.vimrc; chown test: /home/test/.vimrc" + +echo "Allow root autologin on ttyS0" +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^ExecStart=.*$,ExecStart=-/sbin/mingetty --noclear --autologin root %I,' /lib/systemd/system/serial-getty@.service" + +# kernel params (in grub ) + +echo "Allow net.ifnames=0 in GRUB " +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^GRUB_CMDLINE_LINUX_DEFAULT=.*$,GRUB_CMDLINE_LINUX_DEFAULT=\"net.ifnames=0 console=ttyS0\,115200n8\",' /etc/default/grub" +echo " 1s timout for menu" +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^GRUB_TIMEOUT=.*$,GRUB_TIMEOUT=1,' /etc/default/grub" +vdn-ssh root@$GUEST_NAME "update-grub" + +########################## + +export http_proxy=\"$http_proxy\" +export https_proxy=\"$https_proxy\" + +echo "http_proxy:$http_proxy" +echo "https_proxy:$https_proxy" + +#echo "For debug : exit to guit" +#vdn-ssh root@$GUEST_NAME + +installAll + +vdn-ssh root@$GUEST_NAME "systemctl mask nagios" + +########################## + +echo "Set rc.local..." +if [ -e $PROG_DIR/rc.local ]; then + vdn-scp -p $PROG_DIR/rc.local root@$GUEST_NAME:/etc + vdn-ssh root@$GUEST_NAME chmod 755 /etc/rc.local +fi + +## Install lxdm +#echo "Install lxdm..." +# +#vdn-ssh -t root@$GUEST_NAME " +#apt-get -y install lxdm +#apt-get -y remove openbox +#" + +#echo "Default xsession : xfce4 " +#vdn-ssh root@$GUEST_NAME "sed -i -re 's,^# session=.*$,session=/usr/bin/startxfce4,' /etc/lxdm/lxdm.conf" + +#echo "For debug : exit to guit" +#vdn-ssh root@$GUEST_NAME + +# Clear + +echo "Clear /var/log, history, ..." +vdn-ssh -t root@$GUEST_NAME ' +export http_proxy=$http_proxy + +rm -Rf /etc/vdn + +#for i in $(find /var/log -type f); do cat /dev/null > $i; done +find /var/log -name "*.gz" -delete + +echo "Clear .bash_history" + +rm -f /root/.bash_history +touch /root/.bash_history +chmod 600 /root/.bash_history +rm -f /home/test/.bash_history +touch /home/test/.bash_history +chmod 600 /home/test/.bash_history + +echo "Clear .cache .mozilla" +for d in /root /home/test; do + rm -Rf $d/.cache + rm -Rf $d/.mozilla +done + +echo "Clear authorized_keys" + +for d in /root /home/test; do + rm -f $d/.ssh/authorized_keys + rm -f $d/.ssh/authorized_keys +done + +echo "Clear apt-cache..." +apt autoremove -y +sleep 1 +apt-get clean + +echo end of cleaning ! +' + diff --git a/vdn/distribs/guests/direct/debian/bullseye/rc.local.disable b/vdn/distribs/guests/direct/debian/bullseye/rc.local.disable new file mode 100755 index 0000000..909a800 --- /dev/null +++ b/vdn/distribs/guests/direct/debian/bullseye/rc.local.disable @@ -0,0 +1,189 @@ +#!/bin/bash + +# Script de configuration utilisé par VDN. + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +echo "Start rc.local..." + +echo "cmdline:$(cat /proc/cmdline)" + +lastDisk=$(lsblk -i -n -o PATH | grep '/...$' | tail -n 1) +lastDiskSize=$(lsblk -n -b -o SIZE $lastDisk) + +# Disque supplémentaire (avec la clé publique, ...) ? + +#[ $lastDiskSize -gt 200000 ] && exit 0 + +# Si oui + +# Désarchive la configuration en provenance de VDN + +# le fichier /etc/vdn/rc.vdn n'est modifié que si absent +# Consultez les répertoires distribs/guest/... + +[ ! -d /etc/vdn ] && mkdir /etc/vdn + +tar -C / -xzf $lastDisk + +[ -e /etc/vdn/config ] && { + set -a + . /etc/vdn/config +} + +[ $VDN_DEBUG = 1 ] && set -x || : + +# set real / mode +chmod 755 / +chown root:root / /etc +chown -R root:root /etc/vdn + +systemctl restart haveged + +# extract files (host, all, guest) +if [ $MODE = "cow" ]; then + for d in /etc/vdn/host /etc/vdn/all /etc/vdn/guest; do + if [ -d $d ]; then + ( cd $d && tar czf - . ) | ( cd / && tar --no-same-owner --sparse -xpzf - ) + fi + done +fi + + +# swap +if [ $SWAP_SIZE != 0 ]; then + swapDev=$(lsblk -n -o PATH | grep '/...$' | tail -n 2 | head -n 1) + swapoff -a + swapon $swapDev +fi + + +if [ ! -e /etc/vdn-$MODE-initialized ]; then + + # regenerate ssh_host_keys + + rm -f /etc/ssh/ssh_host_* + + dpkg-reconfigure openssh-server + + #systemctl restart ssh + + # Random root and test password + + echo "Random passwords." + + k=$(getRandomPasswd) + #echo "root passwd : $k" + passwdRoot=$k #$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c${1:-32};) + k=$(getRandomPasswd) + #echo "test passwd : $k" + passwdTest=$k #$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c${1:-32};) + + cat <<- EOF | chpasswd +root:$passwdRoot +test:$passwdTest +EOF + + touch /etc/vdn-$MODE-initialized + +fi + +# Add user id_rsa.pub to /root/.ssh/authorized_keys + +[ ! -d /root/.ssh ] && { + mkdir /root/.ssh + chmod 700 /root/.ssh +} + +[ ! -e /root/.ssh/authorized_keys ] && + touch /root/.ssh/authorized_keys + +k=$(cat /etc/vdn/.ssh/id_rsa.pub) + +[ -n "$k" ] && { + ! fgrep -q "$k" /root/.ssh/authorized_keys && + echo "$k" >> /root/.ssh/authorized_keys +} + + +# Add user id_rsa.pub to /home/test/.ssh/authorized_keys + +if [ -d "/home/test" ]; then + if [ ! -d /home/test/.ssh ]; then + mkdir /home/test/.ssh + chown test: /home/test/.ssh + chmod 700 /home/test/.ssh + fi + + [ ! -e /home/test/.ssh/authorized_keys ] && + touch /home/test/.ssh/authorized_keys + + chown test: /home/test/.ssh + + if [ -n "$k" ]; then + ! fgrep -q "$k" /home/test/.ssh/authorized_keys && + echo "$k" >> /home/test/.ssh/authorized_keys + fi +fi + + +# init slirp connection + +lastEth=$(ifconfig -a | grep eth[0-9] | tail -n 1 | cut -d ':' -f 1) +echo "lastEth=$lastEth" + +[ -n "$lastEth" ] && { + ifconfig $lastEth down + sleep 1 + dhclient $lastEth + + if [ "$EXTRA_ETH_DEFAULT_ROUTE" = 0 ]; then + # Set default root to host (slirp) + #route add default gw 10.0.2.2 &> /dev/null + route del default gw 10.0.2.2 &> /dev/null + else + echo "Set default route to 10.0.2.2" + route add default gw 10.0.2.2 &> /dev/null + fi + ping -c 1 10.0.2.2 &> /dev/null & +} + +### ON_BOOT + +if [ ! -z "$ON_BOOT" ]; then + echo "ON_BOOT:$ON_BOOT" + eval $ON_BOOT +fi + +### run rc scripts + +rcScripts=$(ls /etc/vdn/[0-9]* 2> /dev/null) + +# Add vdn.rc + +[ -e /etc/vdn/vdn.rc ] && rcScripts="$rcScripts /etc/vdn/vdn.rc" + +# run rc scripts + +for i in $rcScripts; do + echo "Run script : $i" + . $i +done + +systemctl unmask ssh +sleep 1 +systemctl enable ssh +systemctl start ssh + diff --git a/vdn/distribs/guests/direct/debian/buster/prepare.sh b/vdn/distribs/guests/direct/debian/buster/prepare.sh new file mode 100755 index 0000000..aa2e3b1 --- /dev/null +++ b/vdn/distribs/guests/direct/debian/buster/prepare.sh @@ -0,0 +1,558 @@ +#!/usr/bin/env bash + +dir=$(readlink -f $(dirname $0)); +dist=$(echo $dir | sed -re 's,/.*/([^/]+/[^/]+)$,\1,') + +GUEST_RELEASE=$dist + +[ -z "$http_proxy" ] && http_proxy="" +[ -z "$https_proxy" ] && https_proxy="" + +set -eu + +#http_proxy=http://193.49.118.36:8080 +#https_proxy=http://193.49.118.36:8080 + + +installAll() { + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get update -y; apt-get dist-upgrade -y; apt-get install rsync git mingetty + " + preInstallForTgz + installModulesReseaux + installDocker + installLamp + #installNagios3 + #installBackportKernel # NE FONCTIONNE PAS, pas utile. + #installVdn + installForTgz +} + +## +### Modules réseaux-1 et réseaux-2 ### +### + +installModulesReseaux() { + + # Bad to stretch from squeeze + # php5 php5-mysql smbfs cifs-utils console-tools dhcp3-client samba-doc dhcp3-server sux fuse-utils gproftpd xsmbrowser netkit-ping heartbeat-gui hapm + + # Aucune version du paquet smbfs n'est disponible, mais il existe dans la base + #de données. Cela signifie en général que le paquet est manquant, qu'il est devenu obsolète + #ou qu'il n'est disponible que sur une autre source + #Cependant les paquets suivants le remplacent : + # cifs-utils + + #Aucune version du paquet samba-doc n'est disponible, mais il existe dans la base + #de données. Cela signifie en général que le paquet est manquant, qu'il est devenu obsolète + #ou qu'il n'est disponible que sur une autre source + #Cependant les paquets suivants le remplacent : + # winbind smbclient samba-testsuite samba-common-bin samba-common samba + # registry-tools libsmbclient libpam-winbind + + DEBS="less ssh mingetty rsync net-tools haveged rng-tools dnsutils zerofree" + #DEBS="$DEBS dhcp3-client dhcp3-server sux fuse-utils gproftpd xsmbrowser netkit-ping heartbeat-gui hapm" + #DEBS="$DEBS python-gtk-vnc" + #console-tools console-data console-common + DEBS="$DEBS vim slirp nfs-common nfs-kernel-server" + DEBS="$DEBS sshfs psmisc bsdutils strace busybox-static" + DEBS="$DEBS tcpdump wireshark-gtk nmap" + DEBS="$DEBS manpages" + DEBS="$DEBS curlftpfs ftp curl dillo" + DEBS="$DEBS libapache2-mod-php apache2-doc" + DEBS="$DEBS xbase-clients" + DEBS="$DEBS lynx psmisc file strace lsof telnet links links2" + DEBS="$DEBS iputils-ping" + DEBS="$DEBS rsync dialog" + DEBS="$DEBS firefox-esr" + DEBS="$DEBS nautilus" + DEBS="$DEBS user-mode-linux" + DEBS="$DEBS openvpn" + DEBS="$DEBS quagga proftpd isc-dhcp-server" + + DEBS="$DEBS busybox-static rpcbind debootstrap" + DEBS="$DEBS user-mode-linux" + + DEBS="$DEBS vim-gtk gedit" + + DEBS="$DEBS gpm vde2" + DEBS="$DEBS spice-vdagent" + + DEBS="$DEBS gcc make autoconf uidmap pkg-config glib-2.0-dev \ + glib-2.0 libglib2.0-dev dpkg-dev \ + libcap-dev libcap2 libseccomp2 libseccomp-dev" + + # TP Pascal : + DEBS="$DEBS john hashcat sqlmap php default-mysql-server webcheck" + + echo "apt-get..." + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + echo ========== + apt-get install -y $DEBS + " + # cas de lighttpd + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get install -y lighttpd + systemctl disable lighttpd + " + + + # disable services + + local l="ModemManager NetworkManager NetworkManager-dispatcher NetworkManager-wait-online anacron apparmor autovt@ bgpd dbus-fi.w1.wpa_supplicant1 dbus-org.freedesktop.Avahi dbus-org.freedesktop.ModemManager1 dbus-org.freedesktop.nm-dispatcher dbus-org.freedesktop.timesync1 getty@ hddtemp isisd lighttpd lm-sensors network-manager nfs-kernel-server nmbd openbsd-inetd openvpn ospf6d ospfd pimd portmap pppd-dns ripd ripngd rpcbind rsync smbd speech-dispatcher syslog systemd-timesyncd udisks2 wpa_supplicant zebra nfs-blkmap uml-utilities apache2 proftpd isc-dhcp-server nfs-server" + + vdn-ssh -t root@$GUEST_NAME "for i in $l; do echo \"Disable \$i\"; systemctl disable \$i; done" + + # services (enable) : + #l="avahi-daemon console-setup cron inetd keyboard-setup networking rsyslog ssh sshd uml-utilities" + #l="$l apache2 haveged isc-dhcp-server nfs-server proftpd" + + + +} + +installBackportKernel() { + + local kvers=$(vdn-ssh root@$GUEST_NAME uname -r) + + if ! vdn-ssh root@$GUEST_NAME "grep -q backport /etc/apt/sources.list"; then + vdn-ssh root@$GUEST_NAME 'echo "deb http://ftp.debian.org/debian buster-backports main" >> /etc/apt/sources.list' + fi + + vdn-ssh -t root@$GUEST_NAME "apt-get update; apt-get -y install linux-image-5.3.0-0.bpo.2-amd64" + + vdn-ssh -t root@$GUEST_NAME 'grep -v buster-backports /etc/apt/sources.list > /tmp/o; mv /tmp/o /etc/apt/sources.list' + + vdn-ssh -t root@$GUEST_NAME "apt-get update; apt-get -y install --reinstall linux-image-amd64; update-initramfs -u -k $kvers" +} + +installDocker() { + + set +u + [ -z "$http_proxy" ] && http_proxy="" || : + [ -z "$https_proxy" ] && https_proxy="" || : + set -u + + # désactive le service docker, Voir les scripts de post-configuration + # n'ajoute aucun utilisateur au groupe docker par défaut. Voir les scripts de post-configuration + + vdn-ssh -t root@$GUEST_NAME " + export http_proxy=$http_proxy + export https_proxy=$https_proxy + apt-get update + apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common + curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - + apt-key fingerprint 0EBFCD88 + add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/debian \$(lsb_release -cs) stable\" + apt-get update + apt-get -y install docker-ce docker-ce-cli containerd.io docker-compose + curl -L https://raw.githubusercontent.com/docker/compose/1.24.1/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose + + systemctl mask containerd docker +" +} + +installLamp() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt-get -y install apache2 php mariadb-server libapache2-mod-php php-gd php-mysql + systemctl disable mariadb mysql + " +} + +preInstallForTgz() { + + echo "Set /etc/modprobe.d/blacklist-floppy.conf..." + vdn-ssh root@$GUEST_NAME "f=/etc/modprobe.d/blacklist-floppy.conf; ! grep -q floppy \$f && echo \"blacklist floppy\" >> \$f || :" + + echo "Set /etc/initramfs-tools/modules..." + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q ne2k_pci \$f && echo ne2k_pci >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q 8390 \$f && echo 8390 >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q virtio_net \$f && echo virtio_net >> \$f || :" + + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q overlay \$f && echo overlay >> \$f || :" + vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q aufs \$f && echo aufs >> \$f || :" + + echo "Create /etc/initramfs-tools/scripts/local-bottom/overlay.sh ..." + + + cat << EOF | vdn-ssh root@$GUEST_NAME "cat > /etc/initramfs-tools/scripts/local-bottom/overlay.sh" +#!/bin/sh + + listDisks() { + if [ "\$EMULATOR" = linux ]; then + ls /dev/ubd[[:lower:]] # | grep -E 'udb[[:lower:]]r?' + else + ls /dev/?d[[:lower:]] + fi + } + + +PREREQ="" + + prereqs() + { + echo "\$PREREQ" + } + +case \$1 in + prereqs) + prereqs + exit 0 + ;; + esac + + +! grep -E -q 'vdn-mode=(tgz|overlay)' /proc/cmdline && { + echo "*** local-bottom/overlay.sh : exit (no mode tgz or overlay)" >&2 + exit 0 +} + + + +echo +echo "*** local-bottom/overlay.sh ***" + +echo "Extract configuration..." + +listDisks + +confDisk=\$(listDisks | tail -n 1) + +echo confDisk=\$confDisk + +mkdir /vdn +tar -C / -xvzf \$confDisk + +if [ \$? -ne 0 ]; then + echo "Erreur lors de l'extraction de la configuration" >&2 + echo "Lancement d'un shell pour inspection..." >&2 + export PS1="initramfs:\w# " + /bin/sh -i +fi + +if [ -e /etc/vdn/mount-root ]; then + sh /etc/vdn/mount-root +else + echo "/etc/vdn/mount-root introuvable !" >&2 + echo "ARRÊT du système !">&2 + while :; do sleep 1000; done +fi + +EOF + + vdn-ssh root@$GUEST_NAME chmod 755 /etc/initramfs-tools/scripts/local-bottom/overlay.sh +} + + +installForTgz() { + + echo "Install for tgz..." + + + local kvers + + kvers=$(vdn-ssh root@$GUEST_NAME ls /lib/modules | sort -Vr | head -n1) + [ -z "$kvers" ] && { + echo "Warning : /lib/modules is empty !" >&2 + kvers=$(vdn-ssh root@$GUEST_NAME uname -r) + echo "Use current kernel : $kvers" + } + + rsync -e vdn-ssh root@$GUEST_NAME:/boot/vmlinuz-$kvers $VDN_PATH/files + + # initramfs (created it if necessary) + + + vdn-ssh root@$GUEST_NAME " + rm -f /boot/initrd.img-$kvers.keep + if [ -e /boot/initrd.img-$kvers ]; then + cp /boot/initrd.img-$kvers /boot/initrd.img-$kvers.keep + fi + + echo \"update-initramfs ...\" >&2 + update-initramfs -u -k $kvers + + #cat /etc/initramfs-tools/scripts/local-bottom/overlay.sh + rm /etc/initramfs-tools/scripts/local-bottom/overlay.sh + + cp /boot/initrd.img-$kvers /boot/initrd-tgz.img-$kvers + + if [ -e /boot/initrd.img-$kvers.keep ]; then + mv /boot/initrd.img-$kvers.keep /boot/initrd.img-$kvers + fi +" + + rsync -e vdn-ssh root@$GUEST_NAME:/boot/initrd-tgz.img-$kvers $VDN_PATH/files + +} + +installNagios1() { + # from https://www.itzgeek.com/how-tos/linux/debian/how-to-install-nagios-on-debian-9-stretch.html + + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt update + apt install -y build-essential apache2 php openssl perl make php-gd libgd2-xpm-dev libapache2-mod-php libperl-dev libssl-dev daemon wget apache2-utils unzip + useradd nagios + groupadd nagcmd + usermod -a -G nagcmd nagios + usermod -a -G nagcmd www-data + cd /tmp/ + wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.4.5.tar.gz + tar -zxvf nagios-4.4.5.tar.gz + cd /tmp/nagios-4.4.5/ + ./configure --with-nagios-group=nagios --with-command-group=nagcmd --with-httpd_conf=/etc/apache2/sites-enabled/ + make all + make install + make install-init + make install-config + make install-commandmode + make install-webconf +" +} + +installNagios2() { + + ### sudo nano /usr/local/nagios/etc/objects/contacts.cfg + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + #sed -i -re 's/^.*email.*$/email root@localhost ;/' /usr/local/nagios/etc/objects/contacts.cfg + htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin + a2enmod cgi + systemctl restart apache2 + cd /tmp + wget https://nagios-plugins.org/download/nagios-plugins-2.2.1.tar.gz + tar -zxvf /tmp/nagios-plugins-2.2.1.tar.gz + cd /tmp/nagios-plugins-2.2.1/ + ./configure --with-nagios-user=nagios --with-nagios-group=nagios + make + make install + /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg +" + +} + +installNagios3() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + apt install -y nagios-nrpe-server nagios-plugins + apt -y install nagios-nrpe-plugin +" +} + +installVdn() { + vdn-ssh root@$GUEST_NAME " + export http_proxy=$http_proxy + cd /tmp + rm -Rf vdn + git clone http://opale.u-clermont1.fr/vdn/git/vdn.git + echo "vdn/bin/vdn-prepare $GUEST_RELEASE" + vdn/bin/vdn-prepare $GUEST_RELEASE +" +} + + + + +# début des fonctions + +synopsis() { + cat << EOF +Usage : `basename $0` [-i identity] system +EOF +} + +help() { + cat << EOF + +`basename $0` prepare un système virtuel pour fonctionner en mode DIRECT. + +`synopsis` + +Une identification par clé pour ssh est mise en place (cf. -i identity) +pour éviter les identification par mot de passe lors des connexions ssh +de l'hôte vers l'invité nécessaires à l'opération. + +Les mots de passes sont fixés de façon aléatoire + +-h : affiche cette aide +-i identity : chemin de la clé publique à utiliser. + +EOF +} + +usage() { + synopsis + exit 2 +} + +args() { + local opt + while getopts "hi:" opt; do + case $opt in + h) help; exit 0;; + i) IDENTITY="$OPTARG";; + ?) usage;; + esac + done + shift $(($OPTIND - 1)) + [ $# -ne 1 ] && usage + + GUEST_NAME="$1" + if echo $GUEST_NAME | grep -q '/'; then + error "$GUEST_NAME est un nom de système invalide" + fi +} + + +# Programme principal + +VDN_PATH=$(readlink -f $(dirname $0)/../../../../..); . $VDN_PATH/bin/functions.sh + +args "$@" + +PROG_DIR=$(readlink -f $(dirname $0)) + +if ! $VDN_PATH/bin/vdn-alive $GUEST_NAME; then + error "Le système $GUEST_NAME n'est pas démarré" +fi + +loadGuestVars $GUEST_NAME + +foundIdentity=0 +for i in $SSH_IDENTITY; do + if [ -e $i ]; then + IDENTITY=$i + foundIdentity=1 + fi +done + +[ $foundIdentity = 0 ] && error "Aucune clé SSH !" + +if vdn-ssh -n -o PasswordAuthentication=no root@$GUEST_NAME exit 0 ; then + vdn-ssh-copy-id -i $IDENTITY root@$GUEST_NAME +fi + +#echo "apt-get..." +#vdn-ssh root@$GUEST_NAME apt-get install rsync net-tools + +#echo "Set /etc/initramfs-tools/modules..." +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q ne2k_pci \$f && echo ne2k_pci >> \$f || :" +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q 8390 \$f && echo 8390 >> \$f || :" +#vdn-ssh root@$GUEST_NAME "f=/etc/initramfs-tools/modules; ! grep -q virtio_net \$f && echo virtio_net >> \$f || :" + +#echo "Set /etc/modprobe.d/blacklist-floppy.conf..." +#vdn-ssh root@$GUEST_NAME "f=/etc/modprobe.d/blacklist-floppy.conf; ! grep -q floppy \$f && echo \"blacklist floppy\" >> \$f || :" + + +vdn-ssh -t root@$GUEST_NAME chmod 755 / + +echo "Add test user to kvm group (for nested)" +vdn-ssh root@$GUEST_NAME "addgroup test kvm" + +echo "Add test user to kvm group (for nested)" +vdn-ssh root@$GUEST_NAME "addgroup test docker || :" + + +#echo "Add test user to sudo group" +#vdn-ssh root@$GUEST_NAME "addgroup test sudo" + +echo "Set vim syntax=on" +vdn-ssh root@$GUEST_NAME "cat /etc/vim/vimrc | sed -re 's/^.*syntax on.*$/syntax on/' > /etc/vim/vimrc.new" +vdn-ssh root@$GUEST_NAME "mv /etc/vim/vimrc.new /etc/vim/vimrc" +vdn-ssh root@$GUEST_NAME "cp /etc/vim/vimrc ~/.vimrc" +vdn-ssh root@$GUEST_NAME "cp /etc/vim/vimrc /home/test/.vimrc; chown test: /home/test/.vimrc" + +echo "Allow root autologin on ttyS0" +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^ExecStart=.*$,ExecStart=-/sbin/mingetty --noclear --autologin root %I,' /lib/systemd/system/serial-getty@.service" + +# kernel params (in grub ) + +echo "Allow net.ifnames=0 in GRUB " +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^GRUB_CMDLINE_LINUX_DEFAULT=.*$,GRUB_CMDLINE_LINUX_DEFAULT=\"net.ifnames=0 console=ttyS0\,115200n8\",' /etc/default/grub" +echo " 1s timout for menu" +vdn-ssh root@$GUEST_NAME "sed -i -re 's,^GRUB_TIMEOUT=.*$,GRUB_TIMEOUT=1,' /etc/default/grub" +vdn-ssh root@$GUEST_NAME "update-grub" + +########################## + +export http_proxy=\"$http_proxy\" +export https_proxy=\"$https_proxy\" + +echo "http_proxy:$http_proxy" +echo "https_proxy:$https_proxy" + +#echo "For debug : exit to guit" +#vdn-ssh root@$GUEST_NAME + +installAll + +vdn-ssh root@$GUEST_NAME "systemctl mask nagios" + +########################## + +echo "Set rc.local..." +if [ -e $PROG_DIR/rc.local ]; then + vdn-scp -p $PROG_DIR/rc.local root@$GUEST_NAME:/etc + vdn-ssh root@$GUEST_NAME chmod 755 /etc/rc.local +fi + +## Install lxdm +#echo "Install lxdm..." +# +#vdn-ssh -t root@$GUEST_NAME " +#apt-get -y install lxdm +#apt-get -y remove openbox +#" + +#echo "Default xsession : xfce4 " +#vdn-ssh root@$GUEST_NAME "sed -i -re 's,^# session=.*$,session=/usr/bin/startxfce4,' /etc/lxdm/lxdm.conf" + +#echo "For debug : exit to guit" +#vdn-ssh root@$GUEST_NAME + +# Clear + +echo "Clear /var/log, history, ..." +vdn-ssh -t root@$GUEST_NAME ' +export http_proxy=$http_proxy + +rm -Rf /etc/vdn + +#for i in $(find /var/log -type f); do cat /dev/null > $i; done +find /var/log -name "*.gz" -delete + +echo "Clear .bash_history" + +rm -f /root/.bash_history +touch /root/.bash_history +chmod 600 /root/.bash_history +rm -f /home/test/.bash_history +touch /home/test/.bash_history +chmod 600 /home/test/.bash_history + +echo "Clear .cache .mozilla" +for d in /root /home/test; do + rm -Rf $d/.cache + rm -Rf $d/.mozilla +done + +echo "Clear authorized_keys" + +for d in /root /home/test; do + rm -f $d/.ssh/authorized_keys + rm -f $d/.ssh/authorized_keys +done + +echo "Clear apt-cache..." +apt autoremove -y +sleep 1 +apt-get clean + +echo end of cleaning ! +' + diff --git a/vdn/distribs/guests/direct/debian/buster/rc.local.disable b/vdn/distribs/guests/direct/debian/buster/rc.local.disable new file mode 100755 index 0000000..019bc77 --- /dev/null +++ b/vdn/distribs/guests/direct/debian/buster/rc.local.disable @@ -0,0 +1,202 @@ +#!/bin/bash + +# Script de configuration est utilisé par VDN. +# Ne pas supprimer/modifier + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +set -x + +echo "Start rc.local (buster)..." + +echo "cmdline:$(cat /proc/cmdline)" + +lastDisk=$(lsblk -i -n -o PATH | grep '/...$' | tail -n 1) +lastDiskSize=$(lsblk -n -b -o SIZE $lastDisk) + +# Disque supplémentaire (avec la clé publique, ...) ? + +#[ $lastDiskSize -gt 200000 ] && exit 0 + +# Si oui + +# Désarchive la configuration en provenance de VDN + +# le fichier /etc/vdn/rc.vdn n'est modifié que si absent +# Consultez les répertoires distribs/guest/... + +[ ! -d /etc/vdn ] && mkdir /etc/vdn + +tar -C / -xzf $lastDisk + +[ -e /etc/vdn/config ] && { + set -a + . /etc/vdn/config +} + +[ $VDN_DEBUG = 1 ] && set -x || : + +# set real / mode +chmod 755 / +chown root:root / /etc +chown -R root:root /etc/vdn + +systemctl restart haveged + +# extract files (host, all, guest) +if [ $MODE = "cow" ]; then + for d in /etc/vdn/host /etc/vdn/all /etc/vdn/guest; do + if [ -d $d ]; then + ( cd $d && tar czf - . ) | ( cd / && tar --no-same-owner --sparse -xpzf - ) + fi + done +fi + + +# swap +if [ $SWAP_SIZE != 0 ]; then + swapDev=$(lsblk -n -o PATH | grep '/...$' | tail -n 2 | head -n 1) + swapoff -a + swapon $swapDev +fi + + +if [ ! -e /etc/vdn-$MODE-initialized ]; then + + # regenerate ssh_host_keys + + rm -f /etc/ssh/ssh_host_* + + dpkg-reconfigure openssh-server + + #systemctl restart ssh + + # Random root and test password + + echo "Random passwords." + + k=$(getRandomPasswd) + #echo "root passwd : $k" + passwdRoot=$k #$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c${1:-32};) + k=$(getRandomPasswd) + #echo "test passwd : $k" + passwdTest=$k #$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c${1:-32};) + + cat <<- EOF | chpasswd +root:$passwdRoot +test:$passwdTest +EOF + + touch /etc/vdn-$MODE-initialized + +fi + +# Add user id_rsa.pub to /root/.ssh/authorized_keys + +[ ! -d /root/.ssh ] && { + mkdir /root/.ssh + chmod 700 /root/.ssh +} + +[ ! -e /root/.ssh/authorized_keys ] && + touch /root/.ssh/authorized_keys + +k=$(cat /etc/vdn/.ssh/id_rsa.pub) + +[ -n "$k" ] && { + ! fgrep -q "$k" /root/.ssh/authorized_keys && + echo "$k" >> /root/.ssh/authorized_keys +} + + +# Add user id_rsa.pub to /home/test/.ssh/authorized_keys + +if [ -d "/home/test" ]; then + if [ ! -d /home/test/.ssh ]; then + mkdir /home/test/.ssh + chown test: /home/test/.ssh + chmod 700 /home/test/.ssh + fi + + [ ! -e /home/test/.ssh/authorized_keys ] && + touch /home/test/.ssh/authorized_keys + + chown test: /home/test/.ssh + + if [ -n "$k" ]; then + ! fgrep -q "$k" /home/test/.ssh/authorized_keys && + echo "$k" >> /home/test/.ssh/authorized_keys + fi +fi + + +# init slirp connection + +lastEth=$(ifconfig -a | grep eth[0-9] | tail -n 1 | cut -d ':' -f 1) +echo "lastEth=$lastEth" + +[ -n "$lastEth" ] && { + ifconfig $lastEth down + sleep 1 + dhclient $lastEth + + + if [ "$EXTRA_ETH_DEFAULT_ROUTE" = 0 ]; then + # Set default root to host (slirp) + #route add default gw 10.0.2.2 &> /dev/null + route del default gw 10.0.2.2 &> /dev/null + else + echo "Set default route to 10.0.2.2" + route add default gw 10.0.2.2 &> /dev/null + fi + + ping -c 1 10.0.2.2 &> /dev/null & + + #echo "EXTRA_ETH_MASQUERADING:$EXTRA_ETH_MASQUERADING" + + if [ "$EXTRA_ETH_MASQUERADING" = 1 ]; then + #echo "iptables -t nat -A POSTROUTING -o $lastEth -j MASQUERADE" + iptables -t nat -A POSTROUTING -o $lastEth -j MASQUERADE + fi + +} + +### ON_BOOT + +if [ ! -z "$ON_BOOT" ]; then + echo "ON_BOOT:$ON_BOOT" + eval $ON_BOOT +fi + +### run rc scripts + +rcScripts=$(ls /etc/vdn/[0-9]* 2> /dev/null) + +# Add vdn.rc + +[ -e /etc/vdn/vdn.rc ] && rcScripts="$rcScripts /etc/vdn/vdn.rc" + +# run rc scripts + +for i in $rcScripts; do + echo "Run script : $i" + . $i +done + +systemctl unmask ssh +sleep 1 +systemctl enable ssh +systemctl start ssh + diff --git a/vdn/distribs/guests/overlay/debian/bullseye/mount-root b/vdn/distribs/guests/overlay/debian/bullseye/mount-root new file mode 100644 index 0000000..d136f88 --- /dev/null +++ b/vdn/distribs/guests/overlay/debian/bullseye/mount-root @@ -0,0 +1,502 @@ +#!/usr/bin/env sh + +# Script de l'initramfs pour le montage de la racine finale +# --------------------------------------------------------- + +# Ce script est appelé par l'initramfs pour monter la racine finale +# Ce script utilise les variables définies dans le fichier de configuration +# d'un système virtuel. + +# Monte les répertoires de l'union +mountUnionDirs_tgz() { + + echo "Mount in TGZ mode..." + [ ! -d /root-ro ] && mkdir /root-ro + [ ! -d /root-rw ] && mkdir /root-rw + + # readonly + if ! mount | grep -q /root && [ "$EMULATOR" = "linux" ]; then + ls -l /dev/ubd* + mount -o ro,noload /dev/ubda1 /root + #mount -o remount,ro /root + fi + #ls /root + mount -o move /root /root-ro + + # aufs + #mount -t tmpfs -o size=64m tmpfs /root-rw + if [ -z "$AUFS_FILE" ]; then + if [ -n "$AUFS_SIZE" ]; then + mount -o size=$((1024*1024*$AUFS_SIZE)) \ + -t tmpfs none /root-rw || exit 1 + else + mount -t tmpfs none /root-rw || exit 1 + fi + else + mount -t ext4 $aufsDev /root-rw || exit 1 + rm -Rf /root-rw/* + fi + + # union + + mkdir /root-rw/data /root-rw/work + + if [ 1 = 1 ]; then + modprobe overlay + mount none -t overlay -o redirect_dir=on -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + [ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount -o bind /root-ro /root/overlays/ro + mount -o bind /root-rw /root/overlays/rw + } + else + # aufs DEPRECATED, not functional + modprobe aufs + mount -v -t aufs -o br:/root-rw/data:/root-ro none /root + #[ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount --move /root-ro /root/overlays/ro + mount --move /root-rw /root/overlays/rw + #} + + fi + + if [ ! -d /root/etc ]; then + echo + echo "Error in overlay (tgz mode) !" + echo + sh -i + fi + +} + +mountUnionDirs_overlay() { + + echo "Mount in OVERLAY mode..." + [ ! -d /root-ro ] && mkdir /root-ro + [ ! -d /root-rw ] && mkdir /root-rw + + # readonly + if ! mount | grep -q /root && [ "$EMULATOR" = "linux" ]; then + ls -l /dev/ubd* + mount -o ro,noload /dev/ubda1 /root + #mount -o remount,ro /root + fi + #ls /root + mount -o move /root /root-ro + + mount -t ext4 $saveDev /root-rw || exit 1 + + # union + + [ ! -d /root-rw/data ] && mkdir /root-rw/data + [ ! -d /root-rw/work ] && mkdir /root-rw/work + + + + if [ 1 = 1 ]; then + + modprobe overlay #redirect_dir=on xino_auto metacopy=off + mount none -t overlay -o redirect_dir=on -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + #mount none -t overlay -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + + + [ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount -o bind /root-ro /root/overlays/ro + mount -o bind /root-rw /root/overlays/rw + } + + set +x + else + # deprecated, not fonctional ! + modprobe aufs + mount -v -t aufs -o br:/root-rw/data:/root-ro none /root + #[ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount --move /root-ro /root/overlays/ro + mount --move /root-rw /root/overlays/rw + #} + + fi + + if [ ! -d /root/etc ]; then + echo + echo "Error in overlay (overlay mode) !" + echo + sh -i + fi + +} + +setNetwork() { + + modprobe virtio_net + + for i in $(seq 0 $NB_ETH); do + ifconfig eth$i up + done + ifconfig -a + ifconfig eth$NB_ETH 10.0.2.15 netmask 255.255.255.0 + + #sh -i + + cat << EOF > /root/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 +EOF + +} + +cpSshIdentityOld() { + + # Copie de l'identité ssh + + authorized_keys=/root/.ssh/authorized_keys + [ -n "$SSH_IDENTITY" ] && { + [ ! -d /root//root/.ssh ] && mkdir -m 700 /root/root/.ssh + for i in $SSH_IDENTITY; do + f=/etc/vdn/.ssh/$(basename $i) + if [ -e $f ]; then + ident="$(cat $f)" + grep -q "$ident" /root/root/.ssh/authorized_keys || \ + cat $f >> /root/root/.ssh/authorized_keys + chmod 600 /root/root/.ssh/authorized_keys + echo "vdn : copie de $f" + cat /root/root/.ssh/authorized_keys + break + fi + done + } +} + + +beforeExtractTgz() { + + # Copie de la conf + + [ ! -d /root/etc/vdn ] && mkdir -p /root/etc/vdn + cp -a /etc/vdn/* /root/etc/vdn + + + # extract files (host, all, guest) + for d in /etc/vdn/host /etc/vdn/all /etc/vdn/guest; do + if [ -d $d ]; then + ( cd $d && tar czf - . ) | ( cd /root && tar --no-same-owner -xpzf - ) + fi + done + + if [ -e /etc/rc.local ]; then + cp /etc/rc.local /root/etc/rc.local + fi + +} + +extractSaveTgz() { + echo "Extract save tgz" + if [ -n "$saveDev" ]; then + tar -C /root -xzpf $saveDev #2> /dev/null + fi +} + +setServices() { + + generated=" +hddtemp +isc-dhcp-server +proftpd +speech-dispatcher +" + + base=" +avahi-daemon +console-setup +cron +inetd +keyboard-setup +networking +rsyslog +ssh +sshd +" + + cmd="systemctl list-unit-files --type service --no-legend --no-pager | egrep 'enabled|generated' | cut -d ' ' -f 1 | sed -re 's/\.service//'" + + + all=$(eval chroot /root $cmd) + all=$( { echo "$all"; echo "$generated"; } | tr ' ' '\n' | grep -v '^$' | sort ) + + base=$( echo "$base" | tr ' ' '\n' | grep -v '^$' | sort ) + + extra="$(echo $EXTRA_SERVICES | tr ' ' '\n' | grep -v '^$' | sort -u ) haveged" + + enable=$( { echo "$base"; echo "$extra"; } | tr ' ' '\n' | grep -v '^$' | sort -u ) + + echo "$all" > /root/tmp/all + echo "$enable" > /root/tmp/enable + + badEnable=$(chroot /root comm -1 -3 /tmp/all /tmp/enable) + + disable=$(chroot /root comm -2 -3 /tmp/all /tmp/enable) + + #echo "==== all (file) ====" + #cat /root/tmp/all + #echo "==== enable (file) ====" + #cat /root/tmp/enable + + #echo "================" + echo + echo "Services :" + echo + echo All services : $all + echo + echo Base services : $base + echo + echo Extra services : $extra + echo + echo enable : $enable + echo + echo disable : $disable + echo + echo mask : $EXCLUDE_SERVICES + echo + + #if [ -n "$badEnable" ]; then + # echo "!!! Invalid enable service(s) ! : $badEnable" + # sleep 1 + #fi + + export enable + export disable + + OLDROOT=$ROOT + unset ROOT + + set -x + for i in $enable; do + chroot /root systemctl unmask $i + chroot /root systemctl enable $i + done + + for i in $disable; do + chroot /root systemctl disable $i + done + + chroot /root systemctl mask $EXCLUDE_SERVICES + set +x + + ROOT=$OLDROOT + +} + +updateHdb() { + + #set -x + + if [ $HDB_PART_FORMAT = 1 ]; then + if ! fdisk -l /dev/vdb | grep -q vdb1; then + #/bin/sh -i + echo -e 'n\np\n1\n\n\np\nw\n' | fdisk /dev/vdb + /root/sbin/mkfs.ext4 -j /dev/vdb1 + #/bin/sh -i + #mv \$mdir \$mdir.bak + fi + [ ! -d /root/mnt/vdb1 ] && mkdir /root/mnt/vdb1 + mount -o errors=remount-ro /dev/vdb1 /root/mnt/vdb1 + fi + + + + if [ -n "$HDB_DIRS" ]; then + if ! mount | grep -q /root/mnt/vdb1 ; then + echo + echo "/root/mnt/vdb1 non monté ! Abandon du transfert des répertoires" + echo + sleep 3 + fi + + for i in $HDB_DIRS; do + if [ ! -d /root/mnt/vdb1/$i ]; then + [ ! -d $(dirname /root/mnt/vdb1/$i) ] && mkdir -p $(dirname /root/mnt/vdb1/$i) + if [ -d /root/$i ]; then + cp -a /root/$i /root/mnt/vdb1/$i + else + mkdir -p /root/mnt/vdb1/$i + fi + fi + + mount -o bind /root/mnt/vdb1/$i /root/$i || echo "Error mount /mnt/vdb1/$i !" >&2 + done + set +x + fi +} + +listDisks() { + if [ "$EMULATOR" = "linux" ]; then + ls /dev/ubd[[:lower:]] # | grep -E 'udb[:lower:]r?' + else + ls /dev/?d[[:lower:]] + fi +} + + +echo +echo "=== Start mount-root script..." +echo +#set -eu + +set -a +. /etc/vdn/config +set +a + +#cat /etc/vdn/config + +echo "EMULATOR=$EMULATOR" >&2 +echo "MODE=$MODE" >&2 +echo "NB_DISK=$NB_DISK" >&2 + +listDisks >&2 + +# Sauvegarde +saveDev=$(listDisks | head -n $((1+$NB_DISK)) | tail -n 1 ) + +if [ $MODE = tgz ]; then + if [ "$(dd if=$saveDev count=1 bs=512 2>/dev/null | wc -c)" = "0" ]; then + saveDev="" + fi +fi + +#echo "saveDev=$saveDev" + +# Aufs (now : overlayfs) + +aufsDev="" +if [ $MODE = tgz ]; then + aufsDev=$(listDisks | head -n $((2+$NB_DISK)) | tail -n 1 ) +fi +#echo "aufsDev=$aufsDev" + +mountUnionDirs_$MODE +updateHdb +beforeExtractTgz +setServices +setNetwork + +if [ $MODE = tgz ]; then + extractSaveTgz +fi + +if [ ! -e /root-rw/data/etc/hostname ]; then + if [ $SET_HOSTNAME = 1 ]; then + echo "$GUEST_NAME" > /root-rw/data/etc/hostname + else + echo "" > /root-rw/data/etc/hostname + fi +fi + +# disable halt reboot shutdown poweroff +if [ $MODE = tgz ]; then + for i in halt reboot shutdown poweroff; do + [ -e /root/sbin/$i -a ! -e /root/sbin/.$i ] && mv /root/sbin/$i /root/sbin/.$i + #/bin/rm -f /root/sbin/$i 2> /dev/null + cat << EOF > /root/sbin/$i +#!/bin/bash + +echo -e "\$0 is disable in TGZ mode !\nUse vdn-halt host command or halt in the GUI." >&2 + +exit 1 +EOF + chmod 755 /root/sbin/$i + done +fi + +#if [ ! -e /root/root/.vimrc ]; then +# sed -re 's/"syntax on/syntax on/' /root/etc/vim/vimrc > /root/root/.vimrc +#fi + +# runlevel + +chroot /root systemctl set-default $RUNLEVEL + +cat << EOF > /root/etc/rc.local.old +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +mount -t tmpfs tmpfs /run -o remount,size=20M + +[ -x /root/firewall.sh ] && /root/firewall.sh +[ -e /etc/start ] && bash /etc/start & + +exit 0 +EOF + + #chmod 755 /root/etc/rc.local + + if [ -n "$HOSTS" ]; then + #echo "Generate /etc/hosts" + + ( + echo " +127.0.0.1 localhost +127.0.1.1 debian +" + echo "$HOSTS" | while read name; do + if echo $name | grep -q PUB; then + name=$(echo $name | sed -re 's/^[[:space:]]*PUB[^[:space:]]*[[:space:]]+([^[:space:]]+).*$/\1/') + pub=$(echo $PUBLICS_IP | sed -re 's/^.*'$name':([0-9.]+).*$/\1/') + echo "replace $name ($pub)..." >&2 + name="$pub $name" + fi + + echo "$name" + done + + echo " +# The following lines are desirable for IPv6 capable hosts +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +" + ) > /root/etc/hosts + cat /root/etc/hosts + + fi + + #cat /root/root/.ssh/authorized_keys + #echo + [ -e /root/etc/vdn/authorized-root.txt ] && { + echo "Add authorized root(s)" >&2 + cat /root/etc/vdn/authorized-root.txt | while read l; do + echo " found $l" + cat /root/root/.ssh/authorized_keys | grep -q "$l$" || { + echo " add $l" + echo "$l" >> /root/root/.ssh/authorized_keys + } + done + } +#echo +#cat /root/root/.ssh/authorized_keys +#echo "end of $0" + +#sleep 3 +#/bin/sh -i + +#echo "###################################################################" + + diff --git a/vdn/distribs/guests/overlay/debian/bullseye/save b/vdn/distribs/guests/overlay/debian/bullseye/save new file mode 100755 index 0000000..41e33ae --- /dev/null +++ b/vdn/distribs/guests/overlay/debian/bullseye/save @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -eu + +sync + +if ! cat /proc/cmdline | grep -q vdn-emulator; then + echo "Commande réservée à un système VDN." >&2 + exit 1 +fi + +. /etc/vdn/config + +e="" +for i in $SAVE_EXCLUDE; do + e="$e --exclude $i" +done + +set +u +if [ "$CLEAR_LOG_WHEN_SAVE" = 1 ]; then + find /var/log -type f ! -name "*.gz" -exec truncate -s 0 {} \; + find /var/log -maxdepth 2 -type f -name '*log' -exec truncate -s 0 {} \; +fi + +if [ "$DELETE_LOG_GZ = 1" ]; then + find /var/log -type f -name "*.gz" -delete +fi +set -u + +cd /overlays/rw/data + +tar $e -czpf - . + +#umount -a +#sync + +#sleep 1 + +#/usr/sbin/.poweroff + + diff --git a/vdn/distribs/guests/overlay/debian/buster/mount-root b/vdn/distribs/guests/overlay/debian/buster/mount-root new file mode 100644 index 0000000..d136f88 --- /dev/null +++ b/vdn/distribs/guests/overlay/debian/buster/mount-root @@ -0,0 +1,502 @@ +#!/usr/bin/env sh + +# Script de l'initramfs pour le montage de la racine finale +# --------------------------------------------------------- + +# Ce script est appelé par l'initramfs pour monter la racine finale +# Ce script utilise les variables définies dans le fichier de configuration +# d'un système virtuel. + +# Monte les répertoires de l'union +mountUnionDirs_tgz() { + + echo "Mount in TGZ mode..." + [ ! -d /root-ro ] && mkdir /root-ro + [ ! -d /root-rw ] && mkdir /root-rw + + # readonly + if ! mount | grep -q /root && [ "$EMULATOR" = "linux" ]; then + ls -l /dev/ubd* + mount -o ro,noload /dev/ubda1 /root + #mount -o remount,ro /root + fi + #ls /root + mount -o move /root /root-ro + + # aufs + #mount -t tmpfs -o size=64m tmpfs /root-rw + if [ -z "$AUFS_FILE" ]; then + if [ -n "$AUFS_SIZE" ]; then + mount -o size=$((1024*1024*$AUFS_SIZE)) \ + -t tmpfs none /root-rw || exit 1 + else + mount -t tmpfs none /root-rw || exit 1 + fi + else + mount -t ext4 $aufsDev /root-rw || exit 1 + rm -Rf /root-rw/* + fi + + # union + + mkdir /root-rw/data /root-rw/work + + if [ 1 = 1 ]; then + modprobe overlay + mount none -t overlay -o redirect_dir=on -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + [ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount -o bind /root-ro /root/overlays/ro + mount -o bind /root-rw /root/overlays/rw + } + else + # aufs DEPRECATED, not functional + modprobe aufs + mount -v -t aufs -o br:/root-rw/data:/root-ro none /root + #[ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount --move /root-ro /root/overlays/ro + mount --move /root-rw /root/overlays/rw + #} + + fi + + if [ ! -d /root/etc ]; then + echo + echo "Error in overlay (tgz mode) !" + echo + sh -i + fi + +} + +mountUnionDirs_overlay() { + + echo "Mount in OVERLAY mode..." + [ ! -d /root-ro ] && mkdir /root-ro + [ ! -d /root-rw ] && mkdir /root-rw + + # readonly + if ! mount | grep -q /root && [ "$EMULATOR" = "linux" ]; then + ls -l /dev/ubd* + mount -o ro,noload /dev/ubda1 /root + #mount -o remount,ro /root + fi + #ls /root + mount -o move /root /root-ro + + mount -t ext4 $saveDev /root-rw || exit 1 + + # union + + [ ! -d /root-rw/data ] && mkdir /root-rw/data + [ ! -d /root-rw/work ] && mkdir /root-rw/work + + + + if [ 1 = 1 ]; then + + modprobe overlay #redirect_dir=on xino_auto metacopy=off + mount none -t overlay -o redirect_dir=on -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + #mount none -t overlay -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + + + [ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount -o bind /root-ro /root/overlays/ro + mount -o bind /root-rw /root/overlays/rw + } + + set +x + else + # deprecated, not fonctional ! + modprobe aufs + mount -v -t aufs -o br:/root-rw/data:/root-ro none /root + #[ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount --move /root-ro /root/overlays/ro + mount --move /root-rw /root/overlays/rw + #} + + fi + + if [ ! -d /root/etc ]; then + echo + echo "Error in overlay (overlay mode) !" + echo + sh -i + fi + +} + +setNetwork() { + + modprobe virtio_net + + for i in $(seq 0 $NB_ETH); do + ifconfig eth$i up + done + ifconfig -a + ifconfig eth$NB_ETH 10.0.2.15 netmask 255.255.255.0 + + #sh -i + + cat << EOF > /root/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 +EOF + +} + +cpSshIdentityOld() { + + # Copie de l'identité ssh + + authorized_keys=/root/.ssh/authorized_keys + [ -n "$SSH_IDENTITY" ] && { + [ ! -d /root//root/.ssh ] && mkdir -m 700 /root/root/.ssh + for i in $SSH_IDENTITY; do + f=/etc/vdn/.ssh/$(basename $i) + if [ -e $f ]; then + ident="$(cat $f)" + grep -q "$ident" /root/root/.ssh/authorized_keys || \ + cat $f >> /root/root/.ssh/authorized_keys + chmod 600 /root/root/.ssh/authorized_keys + echo "vdn : copie de $f" + cat /root/root/.ssh/authorized_keys + break + fi + done + } +} + + +beforeExtractTgz() { + + # Copie de la conf + + [ ! -d /root/etc/vdn ] && mkdir -p /root/etc/vdn + cp -a /etc/vdn/* /root/etc/vdn + + + # extract files (host, all, guest) + for d in /etc/vdn/host /etc/vdn/all /etc/vdn/guest; do + if [ -d $d ]; then + ( cd $d && tar czf - . ) | ( cd /root && tar --no-same-owner -xpzf - ) + fi + done + + if [ -e /etc/rc.local ]; then + cp /etc/rc.local /root/etc/rc.local + fi + +} + +extractSaveTgz() { + echo "Extract save tgz" + if [ -n "$saveDev" ]; then + tar -C /root -xzpf $saveDev #2> /dev/null + fi +} + +setServices() { + + generated=" +hddtemp +isc-dhcp-server +proftpd +speech-dispatcher +" + + base=" +avahi-daemon +console-setup +cron +inetd +keyboard-setup +networking +rsyslog +ssh +sshd +" + + cmd="systemctl list-unit-files --type service --no-legend --no-pager | egrep 'enabled|generated' | cut -d ' ' -f 1 | sed -re 's/\.service//'" + + + all=$(eval chroot /root $cmd) + all=$( { echo "$all"; echo "$generated"; } | tr ' ' '\n' | grep -v '^$' | sort ) + + base=$( echo "$base" | tr ' ' '\n' | grep -v '^$' | sort ) + + extra="$(echo $EXTRA_SERVICES | tr ' ' '\n' | grep -v '^$' | sort -u ) haveged" + + enable=$( { echo "$base"; echo "$extra"; } | tr ' ' '\n' | grep -v '^$' | sort -u ) + + echo "$all" > /root/tmp/all + echo "$enable" > /root/tmp/enable + + badEnable=$(chroot /root comm -1 -3 /tmp/all /tmp/enable) + + disable=$(chroot /root comm -2 -3 /tmp/all /tmp/enable) + + #echo "==== all (file) ====" + #cat /root/tmp/all + #echo "==== enable (file) ====" + #cat /root/tmp/enable + + #echo "================" + echo + echo "Services :" + echo + echo All services : $all + echo + echo Base services : $base + echo + echo Extra services : $extra + echo + echo enable : $enable + echo + echo disable : $disable + echo + echo mask : $EXCLUDE_SERVICES + echo + + #if [ -n "$badEnable" ]; then + # echo "!!! Invalid enable service(s) ! : $badEnable" + # sleep 1 + #fi + + export enable + export disable + + OLDROOT=$ROOT + unset ROOT + + set -x + for i in $enable; do + chroot /root systemctl unmask $i + chroot /root systemctl enable $i + done + + for i in $disable; do + chroot /root systemctl disable $i + done + + chroot /root systemctl mask $EXCLUDE_SERVICES + set +x + + ROOT=$OLDROOT + +} + +updateHdb() { + + #set -x + + if [ $HDB_PART_FORMAT = 1 ]; then + if ! fdisk -l /dev/vdb | grep -q vdb1; then + #/bin/sh -i + echo -e 'n\np\n1\n\n\np\nw\n' | fdisk /dev/vdb + /root/sbin/mkfs.ext4 -j /dev/vdb1 + #/bin/sh -i + #mv \$mdir \$mdir.bak + fi + [ ! -d /root/mnt/vdb1 ] && mkdir /root/mnt/vdb1 + mount -o errors=remount-ro /dev/vdb1 /root/mnt/vdb1 + fi + + + + if [ -n "$HDB_DIRS" ]; then + if ! mount | grep -q /root/mnt/vdb1 ; then + echo + echo "/root/mnt/vdb1 non monté ! Abandon du transfert des répertoires" + echo + sleep 3 + fi + + for i in $HDB_DIRS; do + if [ ! -d /root/mnt/vdb1/$i ]; then + [ ! -d $(dirname /root/mnt/vdb1/$i) ] && mkdir -p $(dirname /root/mnt/vdb1/$i) + if [ -d /root/$i ]; then + cp -a /root/$i /root/mnt/vdb1/$i + else + mkdir -p /root/mnt/vdb1/$i + fi + fi + + mount -o bind /root/mnt/vdb1/$i /root/$i || echo "Error mount /mnt/vdb1/$i !" >&2 + done + set +x + fi +} + +listDisks() { + if [ "$EMULATOR" = "linux" ]; then + ls /dev/ubd[[:lower:]] # | grep -E 'udb[:lower:]r?' + else + ls /dev/?d[[:lower:]] + fi +} + + +echo +echo "=== Start mount-root script..." +echo +#set -eu + +set -a +. /etc/vdn/config +set +a + +#cat /etc/vdn/config + +echo "EMULATOR=$EMULATOR" >&2 +echo "MODE=$MODE" >&2 +echo "NB_DISK=$NB_DISK" >&2 + +listDisks >&2 + +# Sauvegarde +saveDev=$(listDisks | head -n $((1+$NB_DISK)) | tail -n 1 ) + +if [ $MODE = tgz ]; then + if [ "$(dd if=$saveDev count=1 bs=512 2>/dev/null | wc -c)" = "0" ]; then + saveDev="" + fi +fi + +#echo "saveDev=$saveDev" + +# Aufs (now : overlayfs) + +aufsDev="" +if [ $MODE = tgz ]; then + aufsDev=$(listDisks | head -n $((2+$NB_DISK)) | tail -n 1 ) +fi +#echo "aufsDev=$aufsDev" + +mountUnionDirs_$MODE +updateHdb +beforeExtractTgz +setServices +setNetwork + +if [ $MODE = tgz ]; then + extractSaveTgz +fi + +if [ ! -e /root-rw/data/etc/hostname ]; then + if [ $SET_HOSTNAME = 1 ]; then + echo "$GUEST_NAME" > /root-rw/data/etc/hostname + else + echo "" > /root-rw/data/etc/hostname + fi +fi + +# disable halt reboot shutdown poweroff +if [ $MODE = tgz ]; then + for i in halt reboot shutdown poweroff; do + [ -e /root/sbin/$i -a ! -e /root/sbin/.$i ] && mv /root/sbin/$i /root/sbin/.$i + #/bin/rm -f /root/sbin/$i 2> /dev/null + cat << EOF > /root/sbin/$i +#!/bin/bash + +echo -e "\$0 is disable in TGZ mode !\nUse vdn-halt host command or halt in the GUI." >&2 + +exit 1 +EOF + chmod 755 /root/sbin/$i + done +fi + +#if [ ! -e /root/root/.vimrc ]; then +# sed -re 's/"syntax on/syntax on/' /root/etc/vim/vimrc > /root/root/.vimrc +#fi + +# runlevel + +chroot /root systemctl set-default $RUNLEVEL + +cat << EOF > /root/etc/rc.local.old +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +mount -t tmpfs tmpfs /run -o remount,size=20M + +[ -x /root/firewall.sh ] && /root/firewall.sh +[ -e /etc/start ] && bash /etc/start & + +exit 0 +EOF + + #chmod 755 /root/etc/rc.local + + if [ -n "$HOSTS" ]; then + #echo "Generate /etc/hosts" + + ( + echo " +127.0.0.1 localhost +127.0.1.1 debian +" + echo "$HOSTS" | while read name; do + if echo $name | grep -q PUB; then + name=$(echo $name | sed -re 's/^[[:space:]]*PUB[^[:space:]]*[[:space:]]+([^[:space:]]+).*$/\1/') + pub=$(echo $PUBLICS_IP | sed -re 's/^.*'$name':([0-9.]+).*$/\1/') + echo "replace $name ($pub)..." >&2 + name="$pub $name" + fi + + echo "$name" + done + + echo " +# The following lines are desirable for IPv6 capable hosts +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +" + ) > /root/etc/hosts + cat /root/etc/hosts + + fi + + #cat /root/root/.ssh/authorized_keys + #echo + [ -e /root/etc/vdn/authorized-root.txt ] && { + echo "Add authorized root(s)" >&2 + cat /root/etc/vdn/authorized-root.txt | while read l; do + echo " found $l" + cat /root/root/.ssh/authorized_keys | grep -q "$l$" || { + echo " add $l" + echo "$l" >> /root/root/.ssh/authorized_keys + } + done + } +#echo +#cat /root/root/.ssh/authorized_keys +#echo "end of $0" + +#sleep 3 +#/bin/sh -i + +#echo "###################################################################" + + diff --git a/vdn/distribs/guests/overlay/debian/buster/save b/vdn/distribs/guests/overlay/debian/buster/save new file mode 100755 index 0000000..41e33ae --- /dev/null +++ b/vdn/distribs/guests/overlay/debian/buster/save @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -eu + +sync + +if ! cat /proc/cmdline | grep -q vdn-emulator; then + echo "Commande réservée à un système VDN." >&2 + exit 1 +fi + +. /etc/vdn/config + +e="" +for i in $SAVE_EXCLUDE; do + e="$e --exclude $i" +done + +set +u +if [ "$CLEAR_LOG_WHEN_SAVE" = 1 ]; then + find /var/log -type f ! -name "*.gz" -exec truncate -s 0 {} \; + find /var/log -maxdepth 2 -type f -name '*log' -exec truncate -s 0 {} \; +fi + +if [ "$DELETE_LOG_GZ = 1" ]; then + find /var/log -type f -name "*.gz" -delete +fi +set -u + +cd /overlays/rw/data + +tar $e -czpf - . + +#umount -a +#sync + +#sleep 1 + +#/usr/sbin/.poweroff + + diff --git a/vdn/distribs/guests/tgz/debian/bullseye/mount-root b/vdn/distribs/guests/tgz/debian/bullseye/mount-root new file mode 100644 index 0000000..d136f88 --- /dev/null +++ b/vdn/distribs/guests/tgz/debian/bullseye/mount-root @@ -0,0 +1,502 @@ +#!/usr/bin/env sh + +# Script de l'initramfs pour le montage de la racine finale +# --------------------------------------------------------- + +# Ce script est appelé par l'initramfs pour monter la racine finale +# Ce script utilise les variables définies dans le fichier de configuration +# d'un système virtuel. + +# Monte les répertoires de l'union +mountUnionDirs_tgz() { + + echo "Mount in TGZ mode..." + [ ! -d /root-ro ] && mkdir /root-ro + [ ! -d /root-rw ] && mkdir /root-rw + + # readonly + if ! mount | grep -q /root && [ "$EMULATOR" = "linux" ]; then + ls -l /dev/ubd* + mount -o ro,noload /dev/ubda1 /root + #mount -o remount,ro /root + fi + #ls /root + mount -o move /root /root-ro + + # aufs + #mount -t tmpfs -o size=64m tmpfs /root-rw + if [ -z "$AUFS_FILE" ]; then + if [ -n "$AUFS_SIZE" ]; then + mount -o size=$((1024*1024*$AUFS_SIZE)) \ + -t tmpfs none /root-rw || exit 1 + else + mount -t tmpfs none /root-rw || exit 1 + fi + else + mount -t ext4 $aufsDev /root-rw || exit 1 + rm -Rf /root-rw/* + fi + + # union + + mkdir /root-rw/data /root-rw/work + + if [ 1 = 1 ]; then + modprobe overlay + mount none -t overlay -o redirect_dir=on -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + [ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount -o bind /root-ro /root/overlays/ro + mount -o bind /root-rw /root/overlays/rw + } + else + # aufs DEPRECATED, not functional + modprobe aufs + mount -v -t aufs -o br:/root-rw/data:/root-ro none /root + #[ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount --move /root-ro /root/overlays/ro + mount --move /root-rw /root/overlays/rw + #} + + fi + + if [ ! -d /root/etc ]; then + echo + echo "Error in overlay (tgz mode) !" + echo + sh -i + fi + +} + +mountUnionDirs_overlay() { + + echo "Mount in OVERLAY mode..." + [ ! -d /root-ro ] && mkdir /root-ro + [ ! -d /root-rw ] && mkdir /root-rw + + # readonly + if ! mount | grep -q /root && [ "$EMULATOR" = "linux" ]; then + ls -l /dev/ubd* + mount -o ro,noload /dev/ubda1 /root + #mount -o remount,ro /root + fi + #ls /root + mount -o move /root /root-ro + + mount -t ext4 $saveDev /root-rw || exit 1 + + # union + + [ ! -d /root-rw/data ] && mkdir /root-rw/data + [ ! -d /root-rw/work ] && mkdir /root-rw/work + + + + if [ 1 = 1 ]; then + + modprobe overlay #redirect_dir=on xino_auto metacopy=off + mount none -t overlay -o redirect_dir=on -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + #mount none -t overlay -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + + + [ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount -o bind /root-ro /root/overlays/ro + mount -o bind /root-rw /root/overlays/rw + } + + set +x + else + # deprecated, not fonctional ! + modprobe aufs + mount -v -t aufs -o br:/root-rw/data:/root-ro none /root + #[ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount --move /root-ro /root/overlays/ro + mount --move /root-rw /root/overlays/rw + #} + + fi + + if [ ! -d /root/etc ]; then + echo + echo "Error in overlay (overlay mode) !" + echo + sh -i + fi + +} + +setNetwork() { + + modprobe virtio_net + + for i in $(seq 0 $NB_ETH); do + ifconfig eth$i up + done + ifconfig -a + ifconfig eth$NB_ETH 10.0.2.15 netmask 255.255.255.0 + + #sh -i + + cat << EOF > /root/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 +EOF + +} + +cpSshIdentityOld() { + + # Copie de l'identité ssh + + authorized_keys=/root/.ssh/authorized_keys + [ -n "$SSH_IDENTITY" ] && { + [ ! -d /root//root/.ssh ] && mkdir -m 700 /root/root/.ssh + for i in $SSH_IDENTITY; do + f=/etc/vdn/.ssh/$(basename $i) + if [ -e $f ]; then + ident="$(cat $f)" + grep -q "$ident" /root/root/.ssh/authorized_keys || \ + cat $f >> /root/root/.ssh/authorized_keys + chmod 600 /root/root/.ssh/authorized_keys + echo "vdn : copie de $f" + cat /root/root/.ssh/authorized_keys + break + fi + done + } +} + + +beforeExtractTgz() { + + # Copie de la conf + + [ ! -d /root/etc/vdn ] && mkdir -p /root/etc/vdn + cp -a /etc/vdn/* /root/etc/vdn + + + # extract files (host, all, guest) + for d in /etc/vdn/host /etc/vdn/all /etc/vdn/guest; do + if [ -d $d ]; then + ( cd $d && tar czf - . ) | ( cd /root && tar --no-same-owner -xpzf - ) + fi + done + + if [ -e /etc/rc.local ]; then + cp /etc/rc.local /root/etc/rc.local + fi + +} + +extractSaveTgz() { + echo "Extract save tgz" + if [ -n "$saveDev" ]; then + tar -C /root -xzpf $saveDev #2> /dev/null + fi +} + +setServices() { + + generated=" +hddtemp +isc-dhcp-server +proftpd +speech-dispatcher +" + + base=" +avahi-daemon +console-setup +cron +inetd +keyboard-setup +networking +rsyslog +ssh +sshd +" + + cmd="systemctl list-unit-files --type service --no-legend --no-pager | egrep 'enabled|generated' | cut -d ' ' -f 1 | sed -re 's/\.service//'" + + + all=$(eval chroot /root $cmd) + all=$( { echo "$all"; echo "$generated"; } | tr ' ' '\n' | grep -v '^$' | sort ) + + base=$( echo "$base" | tr ' ' '\n' | grep -v '^$' | sort ) + + extra="$(echo $EXTRA_SERVICES | tr ' ' '\n' | grep -v '^$' | sort -u ) haveged" + + enable=$( { echo "$base"; echo "$extra"; } | tr ' ' '\n' | grep -v '^$' | sort -u ) + + echo "$all" > /root/tmp/all + echo "$enable" > /root/tmp/enable + + badEnable=$(chroot /root comm -1 -3 /tmp/all /tmp/enable) + + disable=$(chroot /root comm -2 -3 /tmp/all /tmp/enable) + + #echo "==== all (file) ====" + #cat /root/tmp/all + #echo "==== enable (file) ====" + #cat /root/tmp/enable + + #echo "================" + echo + echo "Services :" + echo + echo All services : $all + echo + echo Base services : $base + echo + echo Extra services : $extra + echo + echo enable : $enable + echo + echo disable : $disable + echo + echo mask : $EXCLUDE_SERVICES + echo + + #if [ -n "$badEnable" ]; then + # echo "!!! Invalid enable service(s) ! : $badEnable" + # sleep 1 + #fi + + export enable + export disable + + OLDROOT=$ROOT + unset ROOT + + set -x + for i in $enable; do + chroot /root systemctl unmask $i + chroot /root systemctl enable $i + done + + for i in $disable; do + chroot /root systemctl disable $i + done + + chroot /root systemctl mask $EXCLUDE_SERVICES + set +x + + ROOT=$OLDROOT + +} + +updateHdb() { + + #set -x + + if [ $HDB_PART_FORMAT = 1 ]; then + if ! fdisk -l /dev/vdb | grep -q vdb1; then + #/bin/sh -i + echo -e 'n\np\n1\n\n\np\nw\n' | fdisk /dev/vdb + /root/sbin/mkfs.ext4 -j /dev/vdb1 + #/bin/sh -i + #mv \$mdir \$mdir.bak + fi + [ ! -d /root/mnt/vdb1 ] && mkdir /root/mnt/vdb1 + mount -o errors=remount-ro /dev/vdb1 /root/mnt/vdb1 + fi + + + + if [ -n "$HDB_DIRS" ]; then + if ! mount | grep -q /root/mnt/vdb1 ; then + echo + echo "/root/mnt/vdb1 non monté ! Abandon du transfert des répertoires" + echo + sleep 3 + fi + + for i in $HDB_DIRS; do + if [ ! -d /root/mnt/vdb1/$i ]; then + [ ! -d $(dirname /root/mnt/vdb1/$i) ] && mkdir -p $(dirname /root/mnt/vdb1/$i) + if [ -d /root/$i ]; then + cp -a /root/$i /root/mnt/vdb1/$i + else + mkdir -p /root/mnt/vdb1/$i + fi + fi + + mount -o bind /root/mnt/vdb1/$i /root/$i || echo "Error mount /mnt/vdb1/$i !" >&2 + done + set +x + fi +} + +listDisks() { + if [ "$EMULATOR" = "linux" ]; then + ls /dev/ubd[[:lower:]] # | grep -E 'udb[:lower:]r?' + else + ls /dev/?d[[:lower:]] + fi +} + + +echo +echo "=== Start mount-root script..." +echo +#set -eu + +set -a +. /etc/vdn/config +set +a + +#cat /etc/vdn/config + +echo "EMULATOR=$EMULATOR" >&2 +echo "MODE=$MODE" >&2 +echo "NB_DISK=$NB_DISK" >&2 + +listDisks >&2 + +# Sauvegarde +saveDev=$(listDisks | head -n $((1+$NB_DISK)) | tail -n 1 ) + +if [ $MODE = tgz ]; then + if [ "$(dd if=$saveDev count=1 bs=512 2>/dev/null | wc -c)" = "0" ]; then + saveDev="" + fi +fi + +#echo "saveDev=$saveDev" + +# Aufs (now : overlayfs) + +aufsDev="" +if [ $MODE = tgz ]; then + aufsDev=$(listDisks | head -n $((2+$NB_DISK)) | tail -n 1 ) +fi +#echo "aufsDev=$aufsDev" + +mountUnionDirs_$MODE +updateHdb +beforeExtractTgz +setServices +setNetwork + +if [ $MODE = tgz ]; then + extractSaveTgz +fi + +if [ ! -e /root-rw/data/etc/hostname ]; then + if [ $SET_HOSTNAME = 1 ]; then + echo "$GUEST_NAME" > /root-rw/data/etc/hostname + else + echo "" > /root-rw/data/etc/hostname + fi +fi + +# disable halt reboot shutdown poweroff +if [ $MODE = tgz ]; then + for i in halt reboot shutdown poweroff; do + [ -e /root/sbin/$i -a ! -e /root/sbin/.$i ] && mv /root/sbin/$i /root/sbin/.$i + #/bin/rm -f /root/sbin/$i 2> /dev/null + cat << EOF > /root/sbin/$i +#!/bin/bash + +echo -e "\$0 is disable in TGZ mode !\nUse vdn-halt host command or halt in the GUI." >&2 + +exit 1 +EOF + chmod 755 /root/sbin/$i + done +fi + +#if [ ! -e /root/root/.vimrc ]; then +# sed -re 's/"syntax on/syntax on/' /root/etc/vim/vimrc > /root/root/.vimrc +#fi + +# runlevel + +chroot /root systemctl set-default $RUNLEVEL + +cat << EOF > /root/etc/rc.local.old +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +mount -t tmpfs tmpfs /run -o remount,size=20M + +[ -x /root/firewall.sh ] && /root/firewall.sh +[ -e /etc/start ] && bash /etc/start & + +exit 0 +EOF + + #chmod 755 /root/etc/rc.local + + if [ -n "$HOSTS" ]; then + #echo "Generate /etc/hosts" + + ( + echo " +127.0.0.1 localhost +127.0.1.1 debian +" + echo "$HOSTS" | while read name; do + if echo $name | grep -q PUB; then + name=$(echo $name | sed -re 's/^[[:space:]]*PUB[^[:space:]]*[[:space:]]+([^[:space:]]+).*$/\1/') + pub=$(echo $PUBLICS_IP | sed -re 's/^.*'$name':([0-9.]+).*$/\1/') + echo "replace $name ($pub)..." >&2 + name="$pub $name" + fi + + echo "$name" + done + + echo " +# The following lines are desirable for IPv6 capable hosts +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +" + ) > /root/etc/hosts + cat /root/etc/hosts + + fi + + #cat /root/root/.ssh/authorized_keys + #echo + [ -e /root/etc/vdn/authorized-root.txt ] && { + echo "Add authorized root(s)" >&2 + cat /root/etc/vdn/authorized-root.txt | while read l; do + echo " found $l" + cat /root/root/.ssh/authorized_keys | grep -q "$l$" || { + echo " add $l" + echo "$l" >> /root/root/.ssh/authorized_keys + } + done + } +#echo +#cat /root/root/.ssh/authorized_keys +#echo "end of $0" + +#sleep 3 +#/bin/sh -i + +#echo "###################################################################" + + diff --git a/vdn/distribs/guests/tgz/debian/bullseye/save b/vdn/distribs/guests/tgz/debian/bullseye/save new file mode 100755 index 0000000..41e33ae --- /dev/null +++ b/vdn/distribs/guests/tgz/debian/bullseye/save @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -eu + +sync + +if ! cat /proc/cmdline | grep -q vdn-emulator; then + echo "Commande réservée à un système VDN." >&2 + exit 1 +fi + +. /etc/vdn/config + +e="" +for i in $SAVE_EXCLUDE; do + e="$e --exclude $i" +done + +set +u +if [ "$CLEAR_LOG_WHEN_SAVE" = 1 ]; then + find /var/log -type f ! -name "*.gz" -exec truncate -s 0 {} \; + find /var/log -maxdepth 2 -type f -name '*log' -exec truncate -s 0 {} \; +fi + +if [ "$DELETE_LOG_GZ = 1" ]; then + find /var/log -type f -name "*.gz" -delete +fi +set -u + +cd /overlays/rw/data + +tar $e -czpf - . + +#umount -a +#sync + +#sleep 1 + +#/usr/sbin/.poweroff + + diff --git a/vdn/distribs/guests/tgz/debian/buster/mount-root b/vdn/distribs/guests/tgz/debian/buster/mount-root new file mode 100644 index 0000000..d136f88 --- /dev/null +++ b/vdn/distribs/guests/tgz/debian/buster/mount-root @@ -0,0 +1,502 @@ +#!/usr/bin/env sh + +# Script de l'initramfs pour le montage de la racine finale +# --------------------------------------------------------- + +# Ce script est appelé par l'initramfs pour monter la racine finale +# Ce script utilise les variables définies dans le fichier de configuration +# d'un système virtuel. + +# Monte les répertoires de l'union +mountUnionDirs_tgz() { + + echo "Mount in TGZ mode..." + [ ! -d /root-ro ] && mkdir /root-ro + [ ! -d /root-rw ] && mkdir /root-rw + + # readonly + if ! mount | grep -q /root && [ "$EMULATOR" = "linux" ]; then + ls -l /dev/ubd* + mount -o ro,noload /dev/ubda1 /root + #mount -o remount,ro /root + fi + #ls /root + mount -o move /root /root-ro + + # aufs + #mount -t tmpfs -o size=64m tmpfs /root-rw + if [ -z "$AUFS_FILE" ]; then + if [ -n "$AUFS_SIZE" ]; then + mount -o size=$((1024*1024*$AUFS_SIZE)) \ + -t tmpfs none /root-rw || exit 1 + else + mount -t tmpfs none /root-rw || exit 1 + fi + else + mount -t ext4 $aufsDev /root-rw || exit 1 + rm -Rf /root-rw/* + fi + + # union + + mkdir /root-rw/data /root-rw/work + + if [ 1 = 1 ]; then + modprobe overlay + mount none -t overlay -o redirect_dir=on -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + [ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount -o bind /root-ro /root/overlays/ro + mount -o bind /root-rw /root/overlays/rw + } + else + # aufs DEPRECATED, not functional + modprobe aufs + mount -v -t aufs -o br:/root-rw/data:/root-ro none /root + #[ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount --move /root-ro /root/overlays/ro + mount --move /root-rw /root/overlays/rw + #} + + fi + + if [ ! -d /root/etc ]; then + echo + echo "Error in overlay (tgz mode) !" + echo + sh -i + fi + +} + +mountUnionDirs_overlay() { + + echo "Mount in OVERLAY mode..." + [ ! -d /root-ro ] && mkdir /root-ro + [ ! -d /root-rw ] && mkdir /root-rw + + # readonly + if ! mount | grep -q /root && [ "$EMULATOR" = "linux" ]; then + ls -l /dev/ubd* + mount -o ro,noload /dev/ubda1 /root + #mount -o remount,ro /root + fi + #ls /root + mount -o move /root /root-ro + + mount -t ext4 $saveDev /root-rw || exit 1 + + # union + + [ ! -d /root-rw/data ] && mkdir /root-rw/data + [ ! -d /root-rw/work ] && mkdir /root-rw/work + + + + if [ 1 = 1 ]; then + + modprobe overlay #redirect_dir=on xino_auto metacopy=off + mount none -t overlay -o redirect_dir=on -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + #mount none -t overlay -o lowerdir=/root-ro,upperdir=/root-rw/data,workdir=/root-rw/work /root + + + [ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount -o bind /root-ro /root/overlays/ro + mount -o bind /root-rw /root/overlays/rw + } + + set +x + else + # deprecated, not fonctional ! + modprobe aufs + mount -v -t aufs -o br:/root-rw/data:/root-ro none /root + #[ $? -eq 0 ] && { + mkdir -p /root/overlays/ro /root/overlays/rw + mount --move /root-ro /root/overlays/ro + mount --move /root-rw /root/overlays/rw + #} + + fi + + if [ ! -d /root/etc ]; then + echo + echo "Error in overlay (overlay mode) !" + echo + sh -i + fi + +} + +setNetwork() { + + modprobe virtio_net + + for i in $(seq 0 $NB_ETH); do + ifconfig eth$i up + done + ifconfig -a + ifconfig eth$NB_ETH 10.0.2.15 netmask 255.255.255.0 + + #sh -i + + cat << EOF > /root/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 +EOF + +} + +cpSshIdentityOld() { + + # Copie de l'identité ssh + + authorized_keys=/root/.ssh/authorized_keys + [ -n "$SSH_IDENTITY" ] && { + [ ! -d /root//root/.ssh ] && mkdir -m 700 /root/root/.ssh + for i in $SSH_IDENTITY; do + f=/etc/vdn/.ssh/$(basename $i) + if [ -e $f ]; then + ident="$(cat $f)" + grep -q "$ident" /root/root/.ssh/authorized_keys || \ + cat $f >> /root/root/.ssh/authorized_keys + chmod 600 /root/root/.ssh/authorized_keys + echo "vdn : copie de $f" + cat /root/root/.ssh/authorized_keys + break + fi + done + } +} + + +beforeExtractTgz() { + + # Copie de la conf + + [ ! -d /root/etc/vdn ] && mkdir -p /root/etc/vdn + cp -a /etc/vdn/* /root/etc/vdn + + + # extract files (host, all, guest) + for d in /etc/vdn/host /etc/vdn/all /etc/vdn/guest; do + if [ -d $d ]; then + ( cd $d && tar czf - . ) | ( cd /root && tar --no-same-owner -xpzf - ) + fi + done + + if [ -e /etc/rc.local ]; then + cp /etc/rc.local /root/etc/rc.local + fi + +} + +extractSaveTgz() { + echo "Extract save tgz" + if [ -n "$saveDev" ]; then + tar -C /root -xzpf $saveDev #2> /dev/null + fi +} + +setServices() { + + generated=" +hddtemp +isc-dhcp-server +proftpd +speech-dispatcher +" + + base=" +avahi-daemon +console-setup +cron +inetd +keyboard-setup +networking +rsyslog +ssh +sshd +" + + cmd="systemctl list-unit-files --type service --no-legend --no-pager | egrep 'enabled|generated' | cut -d ' ' -f 1 | sed -re 's/\.service//'" + + + all=$(eval chroot /root $cmd) + all=$( { echo "$all"; echo "$generated"; } | tr ' ' '\n' | grep -v '^$' | sort ) + + base=$( echo "$base" | tr ' ' '\n' | grep -v '^$' | sort ) + + extra="$(echo $EXTRA_SERVICES | tr ' ' '\n' | grep -v '^$' | sort -u ) haveged" + + enable=$( { echo "$base"; echo "$extra"; } | tr ' ' '\n' | grep -v '^$' | sort -u ) + + echo "$all" > /root/tmp/all + echo "$enable" > /root/tmp/enable + + badEnable=$(chroot /root comm -1 -3 /tmp/all /tmp/enable) + + disable=$(chroot /root comm -2 -3 /tmp/all /tmp/enable) + + #echo "==== all (file) ====" + #cat /root/tmp/all + #echo "==== enable (file) ====" + #cat /root/tmp/enable + + #echo "================" + echo + echo "Services :" + echo + echo All services : $all + echo + echo Base services : $base + echo + echo Extra services : $extra + echo + echo enable : $enable + echo + echo disable : $disable + echo + echo mask : $EXCLUDE_SERVICES + echo + + #if [ -n "$badEnable" ]; then + # echo "!!! Invalid enable service(s) ! : $badEnable" + # sleep 1 + #fi + + export enable + export disable + + OLDROOT=$ROOT + unset ROOT + + set -x + for i in $enable; do + chroot /root systemctl unmask $i + chroot /root systemctl enable $i + done + + for i in $disable; do + chroot /root systemctl disable $i + done + + chroot /root systemctl mask $EXCLUDE_SERVICES + set +x + + ROOT=$OLDROOT + +} + +updateHdb() { + + #set -x + + if [ $HDB_PART_FORMAT = 1 ]; then + if ! fdisk -l /dev/vdb | grep -q vdb1; then + #/bin/sh -i + echo -e 'n\np\n1\n\n\np\nw\n' | fdisk /dev/vdb + /root/sbin/mkfs.ext4 -j /dev/vdb1 + #/bin/sh -i + #mv \$mdir \$mdir.bak + fi + [ ! -d /root/mnt/vdb1 ] && mkdir /root/mnt/vdb1 + mount -o errors=remount-ro /dev/vdb1 /root/mnt/vdb1 + fi + + + + if [ -n "$HDB_DIRS" ]; then + if ! mount | grep -q /root/mnt/vdb1 ; then + echo + echo "/root/mnt/vdb1 non monté ! Abandon du transfert des répertoires" + echo + sleep 3 + fi + + for i in $HDB_DIRS; do + if [ ! -d /root/mnt/vdb1/$i ]; then + [ ! -d $(dirname /root/mnt/vdb1/$i) ] && mkdir -p $(dirname /root/mnt/vdb1/$i) + if [ -d /root/$i ]; then + cp -a /root/$i /root/mnt/vdb1/$i + else + mkdir -p /root/mnt/vdb1/$i + fi + fi + + mount -o bind /root/mnt/vdb1/$i /root/$i || echo "Error mount /mnt/vdb1/$i !" >&2 + done + set +x + fi +} + +listDisks() { + if [ "$EMULATOR" = "linux" ]; then + ls /dev/ubd[[:lower:]] # | grep -E 'udb[:lower:]r?' + else + ls /dev/?d[[:lower:]] + fi +} + + +echo +echo "=== Start mount-root script..." +echo +#set -eu + +set -a +. /etc/vdn/config +set +a + +#cat /etc/vdn/config + +echo "EMULATOR=$EMULATOR" >&2 +echo "MODE=$MODE" >&2 +echo "NB_DISK=$NB_DISK" >&2 + +listDisks >&2 + +# Sauvegarde +saveDev=$(listDisks | head -n $((1+$NB_DISK)) | tail -n 1 ) + +if [ $MODE = tgz ]; then + if [ "$(dd if=$saveDev count=1 bs=512 2>/dev/null | wc -c)" = "0" ]; then + saveDev="" + fi +fi + +#echo "saveDev=$saveDev" + +# Aufs (now : overlayfs) + +aufsDev="" +if [ $MODE = tgz ]; then + aufsDev=$(listDisks | head -n $((2+$NB_DISK)) | tail -n 1 ) +fi +#echo "aufsDev=$aufsDev" + +mountUnionDirs_$MODE +updateHdb +beforeExtractTgz +setServices +setNetwork + +if [ $MODE = tgz ]; then + extractSaveTgz +fi + +if [ ! -e /root-rw/data/etc/hostname ]; then + if [ $SET_HOSTNAME = 1 ]; then + echo "$GUEST_NAME" > /root-rw/data/etc/hostname + else + echo "" > /root-rw/data/etc/hostname + fi +fi + +# disable halt reboot shutdown poweroff +if [ $MODE = tgz ]; then + for i in halt reboot shutdown poweroff; do + [ -e /root/sbin/$i -a ! -e /root/sbin/.$i ] && mv /root/sbin/$i /root/sbin/.$i + #/bin/rm -f /root/sbin/$i 2> /dev/null + cat << EOF > /root/sbin/$i +#!/bin/bash + +echo -e "\$0 is disable in TGZ mode !\nUse vdn-halt host command or halt in the GUI." >&2 + +exit 1 +EOF + chmod 755 /root/sbin/$i + done +fi + +#if [ ! -e /root/root/.vimrc ]; then +# sed -re 's/"syntax on/syntax on/' /root/etc/vim/vimrc > /root/root/.vimrc +#fi + +# runlevel + +chroot /root systemctl set-default $RUNLEVEL + +cat << EOF > /root/etc/rc.local.old +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +mount -t tmpfs tmpfs /run -o remount,size=20M + +[ -x /root/firewall.sh ] && /root/firewall.sh +[ -e /etc/start ] && bash /etc/start & + +exit 0 +EOF + + #chmod 755 /root/etc/rc.local + + if [ -n "$HOSTS" ]; then + #echo "Generate /etc/hosts" + + ( + echo " +127.0.0.1 localhost +127.0.1.1 debian +" + echo "$HOSTS" | while read name; do + if echo $name | grep -q PUB; then + name=$(echo $name | sed -re 's/^[[:space:]]*PUB[^[:space:]]*[[:space:]]+([^[:space:]]+).*$/\1/') + pub=$(echo $PUBLICS_IP | sed -re 's/^.*'$name':([0-9.]+).*$/\1/') + echo "replace $name ($pub)..." >&2 + name="$pub $name" + fi + + echo "$name" + done + + echo " +# The following lines are desirable for IPv6 capable hosts +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +" + ) > /root/etc/hosts + cat /root/etc/hosts + + fi + + #cat /root/root/.ssh/authorized_keys + #echo + [ -e /root/etc/vdn/authorized-root.txt ] && { + echo "Add authorized root(s)" >&2 + cat /root/etc/vdn/authorized-root.txt | while read l; do + echo " found $l" + cat /root/root/.ssh/authorized_keys | grep -q "$l$" || { + echo " add $l" + echo "$l" >> /root/root/.ssh/authorized_keys + } + done + } +#echo +#cat /root/root/.ssh/authorized_keys +#echo "end of $0" + +#sleep 3 +#/bin/sh -i + +#echo "###################################################################" + + diff --git a/vdn/distribs/guests/tgz/debian/buster/save b/vdn/distribs/guests/tgz/debian/buster/save new file mode 100755 index 0000000..41e33ae --- /dev/null +++ b/vdn/distribs/guests/tgz/debian/buster/save @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -eu + +sync + +if ! cat /proc/cmdline | grep -q vdn-emulator; then + echo "Commande réservée à un système VDN." >&2 + exit 1 +fi + +. /etc/vdn/config + +e="" +for i in $SAVE_EXCLUDE; do + e="$e --exclude $i" +done + +set +u +if [ "$CLEAR_LOG_WHEN_SAVE" = 1 ]; then + find /var/log -type f ! -name "*.gz" -exec truncate -s 0 {} \; + find /var/log -maxdepth 2 -type f -name '*log' -exec truncate -s 0 {} \; +fi + +if [ "$DELETE_LOG_GZ = 1" ]; then + find /var/log -type f -name "*.gz" -delete +fi +set -u + +cd /overlays/rw/data + +tar $e -czpf - . + +#umount -a +#sync + +#sleep 1 + +#/usr/sbin/.poweroff + + diff --git a/vdn/distribs/hosts/debian/bullseye/download-extras.sh b/vdn/distribs/hosts/debian/bullseye/download-extras.sh new file mode 100644 index 0000000..f5a644c --- /dev/null +++ b/vdn/distribs/hosts/debian/bullseye/download-extras.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +testDownloadExtras() { + local ret=0 + [ ! -e $VDN_PATH/files/$HOST_RELEASE/vte.so ] && ret=1 + + return $ret +} + +downloadExtras() { + mkdir -p $VDN_PATH/files/$HOST_RELEASE + + [ ! -e $VDN_PATH/files/$HOST_RELEASE/vte.so ] && { + request "Le binaire vte.so (GTK terminal emulator for Ruby) nécessite d'être téléchargé (environ 200 Ko). Télécharger vte.so ?" + if [ $? -eq 0 ]; then + wget -O $VDN_PATH/files/$HOST_RELEASE/vte.so http://opale.u-clermont1.fr/vdn/files/$HOST_RELEASE/vte.so + [ $? -ne 0 ] && rm -f $VDN_PATH/files/$HOST_RELEASE/vte.so + fi + } +} diff --git a/vdn/distribs/hosts/debian/bullseye/prepare.sh b/vdn/distribs/hosts/debian/bullseye/prepare.sh new file mode 100644 index 0000000..c0a7711 --- /dev/null +++ b/vdn/distribs/hosts/debian/bullseye/prepare.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Paquets à installer (sur l'hôte) + +DEBS="kmod iproute2 ruby ruby-gtk2 ruby-rsvg2 libvte9 qemu-kvm" +DEBS="$DEBS bzip2 graphviz gawk sysfsutils" +DEBS="$DEBS libxcb-render-util0" +DEBS="$DEBS tmuxinator" +DEBS="$DEBS virt-viewer" +DEBS="$DEBS wget lsb-release xfce4-terminal xdg-utils firefox-esr" + +testInstall() { + ret=0 + for i in $DEBS; do + if ! dpkg -s $i &> /dev/null; then + echo "$i must be installed !" + ret=1 + fi + done + if [ $ret = 0 ]; then + echo + echo "root must be run $VDN_PATH/bin/vdn-prepare" >&2 + fi +} + +runInstall() { + local list="" addExtra=0 + for i in $DEBS; do + if ! dpkg -s $i &> /dev/null; then + echo "$i must be installed !" + list="$list $i" + ret=1 + fi + done + + #if ! dpkg -s python-gtk-vnc &> /dev/null; then + # extra="python-gtk-vnc" + # echo "Embedded package $extra must be installed !" + # echo -e "Press Enter to install... (CTRL C to stop)." + # + # read + + # addExtra=1 + #fi + + for i in $DEBS; do + if ! dpkg -s $i &> /dev/null; then + echo "$i must be installed !" + list="$list $i" + ret=1 + fi + done + + if [ -n "$list" ]; then + apt-get install $@ $list + fi + + #if [ $addExtra = 1 ]; then + # dpkg -i $VDN_PATH/distribs/hosts/$HOST_RELEASE/$extra* + #fi +} + diff --git a/vdn/distribs/hosts/debian/bullseye/vte.so b/vdn/distribs/hosts/debian/bullseye/vte.so new file mode 100755 index 0000000000000000000000000000000000000000..431797182167946b9dee8974f4d6940002c96009 GIT binary patch literal 191224 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 OvOZ0r#I6dsvBazy@!5&5$9 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⪙y`Y-`MJu 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 BMXvw= literal 0 HcmV?d00001 diff --git a/vdn/distribs/hosts/debian/buster/download-extras.sh b/vdn/distribs/hosts/debian/buster/download-extras.sh new file mode 100644 index 0000000..f5a644c --- /dev/null +++ b/vdn/distribs/hosts/debian/buster/download-extras.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +testDownloadExtras() { + local ret=0 + [ ! -e $VDN_PATH/files/$HOST_RELEASE/vte.so ] && ret=1 + + return $ret +} + +downloadExtras() { + mkdir -p $VDN_PATH/files/$HOST_RELEASE + + [ ! -e $VDN_PATH/files/$HOST_RELEASE/vte.so ] && { + request "Le binaire vte.so (GTK terminal emulator for Ruby) nécessite d'être téléchargé (environ 200 Ko). Télécharger vte.so ?" + if [ $? -eq 0 ]; then + wget -O $VDN_PATH/files/$HOST_RELEASE/vte.so http://opale.u-clermont1.fr/vdn/files/$HOST_RELEASE/vte.so + [ $? -ne 0 ] && rm -f $VDN_PATH/files/$HOST_RELEASE/vte.so + fi + } +} diff --git a/vdn/distribs/hosts/debian/buster/prepare.sh b/vdn/distribs/hosts/debian/buster/prepare.sh new file mode 100644 index 0000000..c0a7711 --- /dev/null +++ b/vdn/distribs/hosts/debian/buster/prepare.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Paquets à installer (sur l'hôte) + +DEBS="kmod iproute2 ruby ruby-gtk2 ruby-rsvg2 libvte9 qemu-kvm" +DEBS="$DEBS bzip2 graphviz gawk sysfsutils" +DEBS="$DEBS libxcb-render-util0" +DEBS="$DEBS tmuxinator" +DEBS="$DEBS virt-viewer" +DEBS="$DEBS wget lsb-release xfce4-terminal xdg-utils firefox-esr" + +testInstall() { + ret=0 + for i in $DEBS; do + if ! dpkg -s $i &> /dev/null; then + echo "$i must be installed !" + ret=1 + fi + done + if [ $ret = 0 ]; then + echo + echo "root must be run $VDN_PATH/bin/vdn-prepare" >&2 + fi +} + +runInstall() { + local list="" addExtra=0 + for i in $DEBS; do + if ! dpkg -s $i &> /dev/null; then + echo "$i must be installed !" + list="$list $i" + ret=1 + fi + done + + #if ! dpkg -s python-gtk-vnc &> /dev/null; then + # extra="python-gtk-vnc" + # echo "Embedded package $extra must be installed !" + # echo -e "Press Enter to install... (CTRL C to stop)." + # + # read + + # addExtra=1 + #fi + + for i in $DEBS; do + if ! dpkg -s $i &> /dev/null; then + echo "$i must be installed !" + list="$list $i" + ret=1 + fi + done + + if [ -n "$list" ]; then + apt-get install $@ $list + fi + + #if [ $addExtra = 1 ]; then + # dpkg -i $VDN_PATH/distribs/hosts/$HOST_RELEASE/$extra* + #fi +} + diff --git a/vdn/distribs/hosts/debian/buster/vte.so b/vdn/distribs/hosts/debian/buster/vte.so new file mode 100644 index 0000000000000000000000000000000000000000..582683b510530f4574bbcf9edf09161fd4b0b3f5 GIT binary patch literal 115520 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 literal 0 HcmV?d00001 diff --git a/vdn/distribs/hosts/ubuntu/bionic/vte.so b/vdn/distribs/hosts/ubuntu/bionic/vte.so new file mode 100755 index 0000000000000000000000000000000000000000..0ce0ee43e2e73de1e0844dd32c874456785a4201 GIT binary patch literal 111520 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 W0Qhrw{7?M3;zv)hzX*S+fd2)x2$kOe literal 0 HcmV?d00001 diff --git a/vdn/distribs/hosts/ubuntu/focal/vte.so b/vdn/distribs/hosts/ubuntu/focal/vte.so new file mode 100755 index 0000000000000000000000000000000000000000..ecfb2e3133689939c64408b704c221ab96a58f70 GIT binary patch literal 206200 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 Lu|#3iqMSYFk?}_bDhGhMTyyofYQv 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 literal 0 HcmV?d00001 diff --git a/vdn/distribs/hosts/ubuntu/jammy/vte.so b/vdn/distribs/hosts/ubuntu/jammy/vte.so new file mode 100755 index 0000000000000000000000000000000000000000..ecfb2e3133689939c64408b704c221ab96a58f70 GIT binary patch literal 206200 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 Lu|#3iqMSYFk?}_bDhGhMTyyofYQv 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 literal 0 HcmV?d00001 diff --git a/vdn/doc/README b/vdn/doc/README new file mode 100644 index 0000000..66b42ad --- /dev/null +++ b/vdn/doc/README @@ -0,0 +1,3 @@ + +See : https://opale.iut-clermont.uca.fr/vdn + diff --git a/vdn/doc/banner.svgz b/vdn/doc/banner.svgz new file mode 100644 index 0000000000000000000000000000000000000000..f690b6e39f267326fd697b7fba2ba20da4a6fd1f GIT binary patch literal 1837 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 b6j}*bQ$#nbtA#B3tE;~O_JEa_cN72sa1Dk# literal 0 HcmV?d00001 diff --git a/vdn/files b/vdn/files new file mode 120000 index 0000000..feb1228 --- /dev/null +++ b/vdn/files @@ -0,0 +1 @@ +../files \ No newline at end of file diff --git a/vdn/net-template.svgz b/vdn/net-template.svgz new file mode 100644 index 0000000000000000000000000000000000000000..ffa1a1b5cfb990c713f055b92a6fe9a82c909570 GIT binary patch literal 33111 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 H|91lbI@hGJ literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/bullseye-mini-cow/build b/vdn/networks.bak/bullseye-mini-cow/build new file mode 100644 index 0000000..98f7cac --- /dev/null +++ b/vdn/networks.bak/bullseye-mini-cow/build @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + + + +build() { + local n + + n=debian-1 + vdn-build $n + + vdn-config $n GUEST_SYS "debian/bullseye" + vdn-config $n HDA "DebianBullseye.disk" + vdn-config $n MODE "cow" + vdn-config $n MEMORY "2048" + +} + diff --git a/vdn/networks.bak/bullseye-mini-cow/network.vdn b/vdn/networks.bak/bullseye-mini-cow/network.vdn new file mode 100644 index 0000000..e69de29 diff --git a/vdn/networks.bak/bullseye-mini-test-cow/build b/vdn/networks.bak/bullseye-mini-test-cow/build new file mode 100644 index 0000000..ed85265 --- /dev/null +++ b/vdn/networks.bak/bullseye-mini-test-cow/build @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + + + +build() { + local n + + n=debian-1 + vdn-build $n + + vdn-config $n GUEST_SYS "debian/bullseye" + vdn-config $n HDA "DebianBullseye-test.disk" + vdn-config $n MODE "cow" + vdn-config $n SUB_MODE tgz + vdn-config $n MEMORY "2048" + +} + diff --git a/vdn/networks.bak/bullseye-mini-test-cow/debian-1.conf b/vdn/networks.bak/bullseye-mini-test-cow/debian-1.conf new file mode 100644 index 0000000..245a92a --- /dev/null +++ b/vdn/networks.bak/bullseye-mini-test-cow/debian-1.conf @@ -0,0 +1,231 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="cow" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="2048" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=0 + +# Chemin du premier disque du système. + +HDA="DebianBullseye-test.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + +SUB_MODE="tgz" diff --git a/vdn/networks.bak/bullseye-mini-test-cow/graph.svgz b/vdn/networks.bak/bullseye-mini-test-cow/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..9de0b87c2fc999da1392072b6c907f1981ae2bd4 GIT binary patch literal 525 zcmV+o0`mPIiwFn;NXcRV17~t!aA+=bc4q)}QeAJ_Fcf{yuekHnsYp$16OR@~s8s0C zq-jGM-L%J)n8d2Fqu3(QU%%^+mTBr<j&prKe9pO<-X3-u_OfxxnvC#-5s+qM3uVfT zJgh&*Hw2u|O_6JBWJZi7x3g&aZt;D-{=K>fw=ZG!aQF4g97s&*uXIl7V!ePLKbOE0 zPU-zO5&@~auP2nYZJV@dVw;jKo4l^n#!;-Kp%S|&PUAc&d_lq+aSTgoWRrVYz~d3h z(6U$0FMMH`h%{kv$p#U`ao@65Udstwq_E0M=_bHWxxlnlg|9MlJ*+)}N~*H*84&`b z2=+?0clMAGmM{h#Tn_^Zfk*(2GA?^V$&fJ?nD-@<gI4D0twKH?k7<_;@=8!eMmkM6 zeWP>d`jCKca^tqP*=59SaxE`8@BuW|qZO$3l-D5;AlM*`^Fj9PBAwFHS2V4yK9=ax zR%xA)wo+b(T{iX!_t;IS^F|tUqPEI-d_5Ld0uW-sV080xbXS7V-rqt#s@!~dFFt<i zojoZrwvhZ)NQlm~{_go7L4*I-nV$~3K{t+Pb|WN~j)3)u+{6hm?$~*G@DL!*&8D(V zMs}(wG)~2>rb7Zpl*mPr64+Yf<88iE8t>L>C*75kjoS7Zr=F1m?-u_rd7O`L(ef2= P^|R;?-=iueNdo`?>I(x^ literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/bullseye-mini-test-cow/network.vdn b/vdn/networks.bak/bullseye-mini-test-cow/network.vdn new file mode 100644 index 0000000..e69de29 diff --git a/vdn/networks.bak/buster-mini-cow/build b/vdn/networks.bak/buster-mini-cow/build new file mode 100644 index 0000000..b25cde7 --- /dev/null +++ b/vdn/networks.bak/buster-mini-cow/build @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + + + +build() { + local n + + n=debian-1 + vdn-build $n + + vdn-config $n GUEST_SYS "debian/buster" + vdn-config $n HDA "DebianBuster.disk" + vdn-config $n MODE "cow" + vdn-config $n MEMORY "2048" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE 1 + +} + diff --git a/vdn/networks.bak/buster-mini-cow/network.vdn b/vdn/networks.bak/buster-mini-cow/network.vdn new file mode 100644 index 0000000..e69de29 diff --git a/vdn/networks.bak/demo-bookworm/bigboss.conf b/vdn/networks.bak/demo-bookworm/bigboss.conf new file mode 100644 index 0000000..9c66731 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/bigboss.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="1024" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=1 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_2#192.168.30.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2 proftpd nfs-server isc-dhcp-server" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bookworm/build b/vdn/networks.bak/demo-bookworm/build new file mode 100755 index 0000000..9fef6a4 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/build @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +build() { + local n + + for n in tiny bigboss societe web lambda nomade; do + vdn-build $n + vdn-config $n MODE "tgz2" + vdn-config $n HDA "DebianBookworm.disk" + vdn-config $n GUEST_SYS "debian/bookworm" + vdn-config $n MEMORY "384" + vdn-config $n RUNLEVEL "multi-user.target" + vdn-config $n SET_HOSTNAME 0 + #vdn-config $n HOST_FILES "" + vdn-config $n SET_PROXY "0" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "0" + #sleep 3 + done + + n=tiny +#vdn-config $n GUEST_SYS "kali/2019.3" + #vdn-config $n HDA "kali-linux-xfce-2019.3-amd64.disk" + #vdn-config $n KERNEL "vmlinuz-5.2.0-kali2-amd64" + #vdn-config $n INITRAMFS "initrd-tgz.img-5.2.0-kali2-amd64" + vdn-config $n NETWORKS "none \$NET_2#192.168.30.16/24" + vdn-config $n MEMORY "2048" + vdn-config $n RUNLEVEL "graphical.target" + #vdn-config $n MODE "overlay" + + #vdn-config $n KVM_VIEWER_AUTOSTART 1 + + n=bigboss + vdn-config $n EXTRA_SERVICES "apache2 proftpd nfs-server isc-dhcp-server" + vdn-config $n MEMORY "1024" + vdn-config $n NETWORKS "\$NET_2#192.168.30.2/24" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=societe + vdn-config $n NETWORKS "\$NET_G#20.X3.Y3.Z3/8 \$NET_1#192.168.1.1/24 \$NET_2#192.168.30.1/24" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "1" + vdn-config $n SET_PROXY "1" + + n=web + vdn-config $n NETWORKS "\$NET_1#192.168.1.2/24" + vdn-config $n EXTRA_SERVICES "apache2" + #vdn-config $n SET_HOSTNAME 1 + #vdn-config $n BOOT_HOSTNAME $n + + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=lambda + vdn-config $n NETWORKS "\$NET_G#20.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=nomade + vdn-config $n NETWORKS "\$NET_G#20.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + +} + diff --git a/vdn/networks.bak/demo-bookworm/graph.svgz b/vdn/networks.bak/demo-bookworm/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..c2fbd83df22c1c33ac299477c58f43c179673169 GIT binary patch literal 1469 zcmV;u1w#5CiwFozaL!@?17~t!aA+=bc4q*sSZz<+ND%(cuh{dcRV$J8&c2(HR%-g9 zO7~Lf=-t6LlbFP+W24w2&|iPEUPHjK4;%U=@vyVb%=0`uv%~Sb>vcx1l1-Tw`7{8^ z0+QtOVv**{Y4Gjj)5Hd(tm1qTXGNY&gS-gdy*)Vo<-?z|lhdysNqMy-U%$Qo?aPb= zlQ8^8%);=)$p`Y+-=7Ik2*Zzm1P3HoRn_HD7;d*)x)rq8EW^*6_;Qub%Md+7=ZU*Q zd>a5=RExm<#$-Z1Cwa1ot7JjWZ^+VZxk`WB#!EPrf->@oy*?n5Nwei7t+M2Zyb$DT zyiCd?0)EX!x=k0=Y8ogZFROs8l61MM(BvG=19Fun+xNxwG+>l5Qh%T)m4=`Pg(x5h zR$fj!vf+#|7k%S$be*O7_bx|>qA09aU5ZPRE~Y`97Xm-e;<9YafK;0}FE5JCdK#4T zI7?muf!AbHR0s!V?AJ4ANTR@Ee6QUrE0_M;7vebdPY1`BMRv19v@X&tn+DreS|yIt zP4ON1tlx4OZ;~7Vxh&GW!U!hvP!jx@`1c|T3{hyCwTleG2KTa<r%9D~uzg~Au}I)9 zFK6u{Y~1_8%u#K-C^JVC;&QW#QE*FnbT|=!!9;``*=4$KG;f_-rgyG0sFLf7xQ|Jk z&sW7}8m!aBBEuL^4}t;u2jm8!;nq@v&lg2rO)lbfn&Dqh(sfcEmdPf)XjaPf2gVH& zMHJl26@LJKEL=92u{K(~2Q9Y4>Hi~DoGR-h1&M5lp^@@B(l2?HZ1SYq54FkR<*!n` zdAY3KJP18mEbkHRtUaQ48}CsbSF29G&$D>`Js|kz-vu+&Hq;5236!7#G^L~ph!7FQ zMX;KJA_6nk3QdjKs3E-KJ59r@fckj^T21J+F5f2AiV@D}zk;3$dL}}<k0G?_7Cm&s zK)NL+;3#$ph)7a9l5TjMXK3@x2l5Ofd4`B`e<ZD%3CXAtXbMgvPJ}^z-Ks_>WIYm8 zV|fzRP%r~{R+?(wz{G(LKE9naV;zpL9cVmV*tWRb$B?&qmOVW4fjomk)i**F!caDn zXZ|?Pyv?&1$TJ_uvpdItXVleHrDt4nYQgc2k%}5wcf4JNHkN>4lv^hQjo*(G&86C% z2d-%JJf`^_)7bI4soo~%ZL(Dl+35P@Zl}0zI<RydSQ_4CO5^);<J>a6^Wz}OC_;Y^ zqQv~=$ZqHJ+{dZEq{tqrJ=io(X42v@w+#k*Cb1)6{gBEySxKZ*V|9@z5iW_uz$KOw z$t+5806^G#bc2t^a>bw7HFo8McWUfBU7i<Z+18ov(OKjEWUT?}#o`H-c++7(Ft82_ z?-^*_xwg#O_i-R2Z0+h6NR91%oX~cOb_3R5+f<L>_BM_a9WYFymKlmq&A_)b$x&Wd z%Wzh4i^AZ{VhAWfjjMx-xwic%R_@&r8nBqHf%_?{!?VyWyDH6Z+L|*xnsdHSFK*Je z0~--`|A}kmp4{@iN54Lx7u;U#EURa?G0JMv=>Vi(Q@Te}4|k0dl*0QdCLbxP)Xd^l zsBWBC!%ThFw3Cyo?s)X1p}f8@VM!Zs@}%ph9-j!tjtTuYBG)H%r<(F&9WVB#L))V# z@BMT|IUe000D!|9k*d=)%2~I*4=wLHpch!@?~#lcWg~@lmuDwh{lk{&5nFrT$fk)k z$<11>)<kCJ+N3*i0PdQNw{BZ24scQee<!b<@v5!|6nn`HcG+e$75GCxW7y*Kl+!cb zHEd<^`g{?$1sC-Q&U-)WzY)?MPEELh)*~a$^4$Y24k%!F4~x|8EKdg?QLn7KggRmA zSC;KjR(s$0DIT=Tn{rhT@mQ;L{l7Ig!VBwFW_dls3*}{{hRpEpl^!I#i|OZfMJFnt Xr$Eo3Eh_&}Ug6h&4%+YpHx&Q?1S8-# literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-bookworm/lambda.conf b/vdn/networks.bak/demo-bookworm/lambda.conf new file mode 100644 index 0000000..f41b558 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/lambda.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=4 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#20.X1.Y1.Z1/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bookworm/net.svgz b/vdn/networks.bak/demo-bookworm/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..3a3bcdb3286c6a945f0f8ebd0228ab5f24f0263e GIT binary patch literal 33592 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 UfBO9GZ}PwY15R<bt`YD90Q>mFtN;K2 literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-bookworm/network.vdn b/vdn/networks.bak/demo-bookworm/network.vdn new file mode 100644 index 0000000..e69de29 diff --git a/vdn/networks.bak/demo-bookworm/nomade.conf b/vdn/networks.bak/demo-bookworm/nomade.conf new file mode 100644 index 0000000..e462564 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/nomade.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=5 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#20.X2.Y2.Z2/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bookworm/scripts/atest b/vdn/networks.bak/demo-bookworm/scripts/atest new file mode 100755 index 0000000..9b0fc5f --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/atest @@ -0,0 +1,6 @@ +#!/bin/bash + +run() { + + for i in 1 2 3 4 5 6; do echo $i; sleep 1; done +} diff --git a/vdn/networks.bak/demo-bookworm/scripts/baseConfigAll b/vdn/networks.bak/demo-bookworm/scripts/baseConfigAll new file mode 100644 index 0000000..cc55cdc --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/baseConfigAll @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +DESC="Configuration de base des systèmes (hostname, hosts, interfaces)." + +SYSTEMS="bigboss lambda nomade societe tiny web" +#SYSTEMS="bigboss tiny" + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + # Construction de la liste des commandes + L="" + for i in $SYSTEMS; do + n=$(echo $i | cut -b 1 | tr -s '[[:lower:]]' '[[:upper:]]') + n="$n$(echo $i | cut -b 2-)" + L="$L baseConfig$n" + done + + parallelDisablePause + + vdn-scripts $L + + unsetErrorHandler + echoDone + +} diff --git a/vdn/networks.bak/demo-bookworm/scripts/baseConfigBigboss b/vdn/networks.bak/demo-bookworm/scripts/baseConfigBigboss new file mode 100755 index 0000000..6b5f7bf --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/baseConfigBigboss @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de bigboss (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="bigboss" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static +address 192.168.30.2 +netmask 255.255.255.0 +gateway 192.168.30.1 + +EOF + + vdn-ssh root@$name " + echo \"<html><body><h1>Bienvenue sur le serveur Web de $name !</h1></body></html>\" > /var/www/html/index.html + systemctl restart networking + " + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/baseConfigBigbossTiny b/vdn/networks.bak/demo-bookworm/scripts/baseConfigBigbossTiny new file mode 100755 index 0000000..5288d4a --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/baseConfigBigbossTiny @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +DESC="Configuration de base des systèmes (hostname, hosts, interfaces)." + +SYSTEMS="bigboss tiny" + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + # Construction de la liste des commandes + L="" + for i in $SYSTEMS; do + n=$(echo $i | cut -b 1 | tr -s '[[:lower:]]' '[[:upper:]]') + n="$n$(echo $i | cut -b 2-)" + L="$L baseConfig$n" + done + + parallelDisablePause + + vdn-scripts $L + + unsetErrorHandler + echoDone + +} diff --git a/vdn/networks.bak/demo-bookworm/scripts/baseConfigLambda b/vdn/networks.bak/demo-bookworm/scripts/baseConfigLambda new file mode 100755 index 0000000..427f59a --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/baseConfigLambda @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de lambda (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="lambda" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"<html><body><h1>Bienvenue sur le serveur Web de $name !</h1></body></html>\" > /var/www/html/index.html + systemctl restart networking + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/baseConfigNomade b/vdn/networks.bak/demo-bookworm/scripts/baseConfigNomade new file mode 100755 index 0000000..01fa92c --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/baseConfigNomade @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de nomade (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="nomade" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"<html><body><h1>Bienvenue sur le serveur Web de $name !</h1></body></html>\" > /var/www/html/index.html + systemctl restart networking + " + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/baseConfigSociete b/vdn/networks.bak/demo-bookworm/scripts/baseConfigSociete new file mode 100755 index 0000000..f43eb80 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/baseConfigSociete @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de societe (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="societe" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + #/sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/baseConfigTiny b/vdn/networks.bak/demo-bookworm/scripts/baseConfigTiny new file mode 100755 index 0000000..ee3db75 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/baseConfigTiny @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Configuration de base de tiny (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="tiny" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/baseConfigWeb b/vdn/networks.bak/demo-bookworm/scripts/baseConfigWeb new file mode 100755 index 0000000..3a67e8d --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/baseConfigWeb @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de web (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="web" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"<html><body><h1>Bienvenue sur le serveur Web de $name !</h1></body></html>\" > /var/www/html/index.html + + systemctl restart networking + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/configIPv6 b/vdn/networks.bak/demo-bookworm/scripts/configIPv6 new file mode 100644 index 0000000..b79f8f9 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/configIPv6 @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Conguration IPv6 de base du réseau" + + +SYSTEMS="bigboss lambda nomade societe tiny web" + +setIpv6() { + echo "$@" + host=$1 + eth=$2 + + addr=$(vdn-ssh root@$host "ifconfig $eth" | grep 'inet6:.*fe80:' | head -n 1 | tr -s ' ' | cut -d ' ' -f 4) + + [ -z "$addr" ] && return || : + + case "$3" in + site) new=$(echo "$addr" | sed -re 's/^fe80:/fec0:/');; + global) new=$(echo "$addr" | sed -re 's/^fe80:/2002:/');; + esac + + exist=false + if vdn-ssh root@$host "ifconfig $eth" | grep -q "inet6:.*$new"; then + exist=true + fi + + if [ $exist = false ]; then + echo "$host : ifconfig $eth inet6 add $new" + vdn-ssh root@$host " + ifconfig $eth inet6 add $new/64 + " + fi + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + for i in $SYSTEMS; do + setIpv6WorkAround $i + done + + setIpv6 tiny eth1 site + setIpv6 bigboss eth0 site + setIpv6 web eth0 site + setIpv6 societe eth1 site + setIpv6 societe eth2 site + setIpv6 societe eth0 global + setIpv6 nomade eth0 global + setIpv6 lambda eth0 global + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bookworm/scripts/errors b/vdn/networks.bak/demo-bookworm/scripts/errors new file mode 100755 index 0000000..c0d5ac7 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/errors @@ -0,0 +1,5 @@ +#!/bin/bash + +run() { + errors-src/errorsWrapper +} diff --git a/vdn/networks.bak/demo-bookworm/scripts/errors-src/Makefile b/vdn/networks.bak/demo-bookworm/scripts/errors-src/Makefile new file mode 100644 index 0000000..42ad515 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/errors-src/Makefile @@ -0,0 +1,4 @@ + +errorsWrapper : errorsWrapper.c + gcc -Wall -o errorsWrapper errorsWrapper.c + diff --git a/vdn/networks.bak/demo-bookworm/scripts/errors-src/errorsWrapper b/vdn/networks.bak/demo-bookworm/scripts/errors-src/errorsWrapper new file mode 100755 index 0000000000000000000000000000000000000000..3762df404ebc60e42e2f6c229978a188b7f5a700 GIT binary patch literal 19848 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 OKVp_dolC(*ihly7=2Pkb literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-bookworm/scripts/errors-src/errorsWrapper.c b/vdn/networks.bak/demo-bookworm/scripts/errors-src/errorsWrapper.c new file mode 100644 index 0000000..908d64c --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/errors-src/errorsWrapper.c @@ -0,0 +1,13 @@ +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +char baseName[1024]="qH3UmebTg5\""; +char fullName[2048]="\"/home/prof/vdn/vdn/networks/demo/scripts/errors-src/"; + +int main() { + strncat(fullName, baseName, 1024); + execlp("bash", "test", "-c", fullName, NULL); + //system(fullName); + return 0; +} diff --git a/vdn/networks.bak/demo-bookworm/scripts/errors-src/qH3UmebTg5 b/vdn/networks.bak/demo-bookworm/scripts/errors-src/qH3UmebTg5 new file mode 100755 index 0000000..ef4381d --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/errors-src/qH3UmebTg5 @@ -0,0 +1,139 @@ +#!/bin/bash + +runErrorScript() { + #set -x + eval "$@" &> /dev/null + + [ $? != 0 ] && { + echo "Le script a, au moins partiellement, échoué !" >&2 + } || echo "ok" +} + +apply() { + case "$choix" in + + "Erreur 1 (TP1)") + # Remplace 192.168.30.16 par 192.168.30.61 dans tiny:/etc/network/interfaces + runErrorScript "vdn-ssh root@tiny \ + 'sed -i -re s/192.168.30.16/192.168.30.61/g /etc/network/interfaces; \ + ifdown eth1; ifup eth1'";; + + "Correction erreur 1 (TP1)") + runErrorScript "vdn-ssh root@tiny \ + 'sed -i -re s/192.168.30.61/192.168.30.16/g /etc/network/interfaces; \ + ifdown eth1; ifup eth1'";; + + + "Erreur 2 (TP1)") + # Remplace tiny par tini dans bigboss:/etc/hosts + runErrorScript "vdn-ssh root@bigboss 'sed -i -re s/tiny/tini/g /etc/hosts'";; + + "Correction erreur 2 (TP1)") + runErrorScript "vdn-ssh root@bigboss 'sed -i -re s/tini/tiny/g /etc/hosts'";; + + + "Erreur 3 (TP2)") + # NFS : remplace tiny par bigboss dans bigboss:/etc/exports + runErrorScript "vdn-ssh root@bigboss \ + 'sed -i -re s/tiny/bigboss/g /etc/exports; \ + systemctl restart nfs-kernel-server'";; + + "Correction erreur 3 (TP2)") + runErrorScript "vdn-ssh root@bigboss \ + 'sed -i -re s/bigboss/tiny/g /etc/exports; \ + systemctl restart nfs-kernel-server'";; + + + "Erreur 4 (TP3)") + # Apache2 (bigboss) : renomme /var/www/html /var/www/html.bak sur bigboss + runErrorScript "vdn-ssh root@bigboss 'mv /var/www/html /var/www/html.bak'";; + + "Correction erreur 4 (TP3)") + runErrorScript "vdn-ssh root@bigboss 'mv /var/www/html.bak /var/www/html'";; + + + "Erreur 5 (TP4)") + # cache tiny:~titi/.ssh/authorized_keys + runErrorScript "vdn-ssh root@tiny \ + 'su -c \" \ + mv ~/.ssh/authorized_keys ~/.ssh/.authorized_keys.bak \ + \" - titi' \ + ";; + + + "Correction erreur 5 (TP4)") + # restaure tiny:~titi/.ssh/authorized_keys + runErrorScript "vdn-ssh root@tiny \ + 'su -c \" \ + mv ~/.ssh/.authorized_keys.bak ~/.ssh/authorized_keys \ + \" - titi' \ + ";; + + "Erreur 6 (TP5)") + # Désactive la fonction routage de societe + runErrorScript "vdn-ssh root@societe 'sysctl -w net.ipv4.ip_forward=0'";; + + "Correction erreur 6 (TP5)") + runErrorScript "vdn-ssh root@societe 'sysctl -w net.ipv4.ip_forward=1'";; + + + "testAll-1A") + vdn-scripts testAll-1A;; + + "Quitter") exit 0;; + + esac + + +} + +run() { + + cat << EOF + +Le menu ci-dessous permet de générer des erreurs sur votre réseau ! + +Pour "jouer" il faut au préalable que votre réseau soit complètement +opérationnel (le script testAll-1A affiche ok pour tout). + +Si c'est le cas, déclenchez une erreur, lancez le script testAll-1A +pour découvrir l'ampleur des dégâts et rétablissez le fonctionnement +optimal de votre réseau. + +Si vous ne vous en sortez pas, le choix "Correction" est là pour +annuler l'erreur, théoriquement ;-) + +Note : + +chaque erreur est une unique commande exécutée sur une machine +du réseau. La commande peut être du genre : + +vdn-ssh root@tiny "sed -i -re 's/^toto:/tutu:/' /etc/passwd" + +Si un service est impacté par la commande, il est relancé afin de mettre +immédiatement en évidence les erreurs via le script testAll-1A. + +Bonne chance ! + +EOF + select choix in \ + "Erreur 1 (TP1)" \ + "Correction erreur 1 (TP1)" \ + "Erreur 2 (TP1)" \ + "Correction erreur 2 (TP1)" \ + "Erreur 3 (TP2)" \ + "Correction erreur 3 (TP2)" \ + "Erreur 4 (TP3)" \ + "Correction erreur 4 (TP3)" \ + "Erreur 5 (TP4)" \ + "Correction erreur 5 (TP4)" \ + "Erreur 6 (TP5)" \ + "Correction erreur 6 (TP5)" \ + "testAll-1A" \ + "Quitter" \ + ; do + apply + done +} + +run diff --git a/vdn/networks.bak/demo-bookworm/scripts/repairAll-1A b/vdn/networks.bak/demo-bookworm/scripts/repairAll-1A new file mode 100644 index 0000000..b9ddb94 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/repairAll-1A @@ -0,0 +1,666 @@ +#!/usr/bin/env bash + +DESC="TP de 1A." + +SYSTEMS="bigboss tiny societe lambda web" + + +baseConfigBigboss() { + + set -e + + echo "[baseConfigBigboss]" + echo + + name="bigboss" + + #startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static +address 192.168.30.2 +netmask 255.255.255.0 +gateway 192.168.30.1 + +EOF + + vdn-ssh root@$name " + echo \"<html><body><h1>Bienvenue sur le serveur Web de $name !</h1></body></html>\" > /var/www/html/index.html + systemctl restart networking + " + + echoDoneWithTestErrors + +} + +baseConfigTiny() { + + set -e + + echo "[baseConfigTiny]" + echo + + + name="tiny" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + +vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + echoDoneWithTestErrors +} + +baseConfigSociete() { + + set -e + + echo [baseConfigSociete] + echo + + name="societe" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + echoDoneWithTestErrors +} + +baseConfigWeb() { + + set -e + + echo [baseConfigWeb] + echo + + name="web" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"<html><body><h1>Bienvenue sur le serveur Web de $name !</h1></body></html>\" > /var/www/html/index.html + + systemctl restart networking + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + echoDoneWithTestErrors +} + +baseConfigLambda() { + + set -e + + echo [baseConfigLambda] + echo + + name="lambda" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"<html><body><h1>Bienvenue sur le serveur Web de $name !</h1></body></html>\" > /var/www/html/index.html + systemctl restart networking + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + echoDoneWithTestErrors +} + +baseConfigNomade() { + + set -e + + echo [baseConfigNomade] + echo + + + echoDoneWithTestErrors +} + + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +repairUser() { + k=$(getRandomPasswd) + vdn-ssh root@$1 " + id $2 &> /dev/null && exit 0 + adduser --disabled-password --gecos \"\" --home /home/$2 --shell /bin/bash $2 + echo $2:$k| chpasswd + " +} + + +repairUsersTotoTiti() { + set -e + + echo "[repairUsersTotoTiti]" + echo + + + repairUser bigboss toto + repairUser tiny titi + + echoDoneWithTestErrors +} + +repairNfs() { + set -e + + echo "[repairNfs]" + echo + + vdn-ssh root@bigboss " + set -e + [ ! -d /overlays/rw/partage-test ] && mkdir /overlays/rw/partage-test || : + echo test > /overlays/rw/partage-test/vdn-test + + cat <<-EOF > /etc/exports +/overlays/ro/usr/share/doc tiny(ro,sync,subtree_check,no_root_squash,fsid=1) +#/overlays/rw/partage-test tiny(rw,sync,subtree_check,no_root_squash,fsid=2) +EOF + systemctl enable nfs-kernel-server + sleep 1 + systemctl stop nfs-kernel-server + systemctl start nfs-kernel-server + " + echoDoneWithTestErrors +} + +repairDhcp() { + set -e + + echo + echo "[repairDhcp]" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + set -e + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + sleep 3 + + systemctl enable isc-dhcp-server + systemctl stop isc-dhcp-server + systemctl start isc-dhcp-server + + #if [ -e /etc/init.d/dhcp3-server ]; then + # /etc/init.d/dhcp3-server stop &> /dev/null + # /etc/init.d/dhcp3-server start + #elif [ -e /etc/init.d/isc-dhcp-server ]; then + # /etc/init.d/isc-dhcp-server stop &> /dev/null + # /etc/init.d/isc-dhcp-server start + #fi + " + echoDoneWithTestErrors +} + +repairProftpd() { + set -e + + echo + echo "[repairProftpd]" + + vdn-ssh root@bigboss " + + [ ! -e /etc/proftpd/proftpd.conf.vdn ] && \ + cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf.vnd + + grep -q '^<Anonymous' /etc/proftpd/proftpd.conf && exit 0 + + cat << EOF >> /etc/proftpd/proftpd.conf +# A basic anonymous configuration, no upload directories. + +<Anonymous ~ftp> + User ftp + Group nogroup + # We want clients to be able to login with \"anonymous\" as well as \"ftp\" + UserAlias anonymous ftp + # Cosmetic changes, all files belongs to ftp user + DirFakeUser on ftp + DirFakeGroup on ftp + + RequireValidShell off + + # Limit the maximum number of anonymous logins + MaxClients 10 + + # We want 'welcome.msg' displayed at login, and '.message' displayed + # in each newly chdired directory. + DisplayLogin welcome.msg + DisplayChdir .message + + # Limit WRITE everywhere in the anonymous chroot + <Directory *> + <Limit WRITE> + DenyAll + </Limit> + </Directory> + +</Anonymous> +EOF + + systemctl enable proftpd + sleep 2 + systemctl restart proftpd + " + echoDoneWithTestErrors +} + +repairApache2Base() { + echo "Apache2 : Lancement du serveur" + + vdn-ssh root@bigboss " + echo 'ServerName bigboss' >> /etc/apache2/apache2.conf + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + sleep 1 + " +} + + +repairApache2Home() { + echo + echo "Apache2 : Page Web personnelle (userdir)" + + vdn-ssh root@bigboss " + [ ! -d /home ] && { echo 'Need toto user !' >&2; exit 1; } + [ ! -d /home/toto/public_html ] && mkdir /home/toto/public_html + cat <<-EOF > /home/toto/public_html/index.html + <html><body>Page perso.</body></html> + EOF + chown -R toto: /home/toto/public_html + + a2enmod userdir + systemctl restart apache2 + sleep 1 + " +} + +repairApache2HtaccessToto() { + echo + echo "Protection de toto@bigboss:~toto/secret" + + vdn-ssh root@bigboss " + [ ! -d /home/toto/public_html/secret ] && { + mkdir -p /home/toto/public_html/secret + chown -R toto: /home/toto/public_html + chmod 700 /home/toto/public_html/secret + } + + cat <<-EOF > /home/toto/public_html/secret/.htaccess + AuthType Basic + AuthUserFile /home/toto/public_html/secret/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + <limit GET> + require user titi + </limit> +EOF + + echo \"<html><body>Prive</body></html>\" > \ + /home/toto/public_html/secret/index.html + + ( + cd /home/toto/public_html/secret/ + htpasswd -b -c users titi iut + ) + + chown -R toto: /home/toto/public_html + " + +} + +repairApache2() { + set -e + + echo "[repairApache2]" + echo + + repairApache2Base + repairApache2Home + repairApache2HtaccessToto + + echoDoneWithTestErrors +} + +repairClientServer() { + set -e + + echo "[repairClientServer]" + echo + + vdn-ssh root@bigboss " +cat << EOF > /usr/local/bin/server.rb +#!/usr/bin/env ruby + +require 'socket' +server = TCPServer.new ARGV[0] # socket d'écoute attaché au port passé en argument +loop do # boucle infinie + client = server.accept # attente d'une connexion + while request=client.gets.chomp do # pour toutes les lignes reçues + case request + when \"time\" then client.puts \"#{Time.now}\" # émission de la réponse + when \"exit\" then break + else client.puts \"error\" + end + end + client.close # fermeture de la connexion +end +EOF +" + + vdn-ssh root@tiny " +cat << EOF > /usr/local/bin/client.rb +#!/usr/bin/env ruby + +require \"socket\" +s = TCPSocket.open(ARGV[0], ARGV[1].to_i) # Création de la socket et connexion +while line = STDIN.gets do # pour toutes les lignes de l'entrée standard + s.puts line # émission de la ligne vers le serveur + break if line.chomp == \"exit\" # chomp retire l'\\n' final + puts s.gets # Affiche la ligne en provenance du serveur +end +s.close # fermeture de la socket +EOF +" + + echoDoneWithTestErrors +} + +repairRouting() { + set -e + + echo "[repairRouting]" + echo + + baseConfigSociete + baseConfigWeb + baseConfigLambda + + vdn-ssh root@societe ' + sed -i -re "s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/" /etc/sysctl.conf + sysctl -p + set -e + + + cat << EOF > /etc/firewall.sh +#!/bin/bash + + iptables -t nat -F + iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + chmod 755 /etc/firewall.sh + + +# MARCHE PAS + ! grep -q /etc/firewall.sh /etc/vdn/vdn.rc && { + echo "Add /etc/firewall in /etc/vdn/vdn.rc" + echo /etc/firewall.sh >> /etc/vdn/vdn.rc + chmod 755 /etc/vdn/vdn.rc + } || : + + /etc/firewall.sh + ' + + repairClientServer + + echoDoneWithTestErrors +} + + +repairSshKeys() { + set -e + + echo "[repairSshKeys]" + echo + + vdn-ssh root@bigboss " + set -e + [ ! -e .ssh/id_rsa ] && ssh-keygen -q -N '' -f ~/.ssh/id_rsa -t rsa || : + " + + sleep 2 # laisser le temps à la création de titi sur tiny + + vdn-ssh root@tiny " + su -c ' + [ ! -d ~/.ssh ] && { mkdir ~/.ssh; chmod 700 .ssh; } + ' - titi + " + + local tmp=$(mktemp) + vdn-ssh root@bigboss "cat ~/.ssh/id_rsa.pub" > $tmp + cat $tmp | vdn-ssh root@tiny " + su -c ' + cat > ~/.ssh/authorized_keys + ' - titi + " + + rm $tmp + + echoDoneWithTestErrors +} + +run() { + requireSshGuests $SYSTEMS + + vdnExec baseConfigBigboss baseConfigTiny repairUsersTotoTiti \ + repairNfs repairDhcp repairProftpd \ + repairApache2 \ + repairRouting repairSshKeys +} diff --git a/vdn/networks.bak/demo-bookworm/scripts/repairApache2 b/vdn/networks.bak/demo-bookworm/scripts/repairApache2 new file mode 100644 index 0000000..5b1be10 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/repairApache2 @@ -0,0 +1,304 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Test apache2 (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, les fichiers suivants sont modifiés : +- /etc/apache2/apache2.conf +- /etc/apache2/sites-available/000-default.conf + +Une copie est faite avec l'extension .vdn +" + + +repairApache2Base() { + echo "Lancement du serveur" + + vdn-ssh root@bigboss " + echo 'ServerName bigboss' >> /etc/apache2/apache2.conf + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + sleep 1 + " +} + +repairApache2Root() { + echo + echo "Modification de la racine du serveur Web" + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + [ ! -e \$conf ] && cp \$conf \${conf}.vdn + root=/home/httpd/html + + [ ! -d \$root ] && mkdir -p \$root + + #cat \$conf | sed -e 's|/var/www/html|'\$root'|g' \ + # > /tmp/default + cat <<-EOF > \$conf +<VirtualHost *:80> +# The ServerName directive sets the request scheme, hostname and port that +# the server uses to identify itself. This is used when creating +# redirection URLs. In the context of virtual hosts, the ServerName +# specifies what hostname must appear in the request's Host: header to +# match this virtual host. For the default virtual host (this file) this +# value is not decisive as it is used as a last resort host regardless. +# However, you must set it for any further virtual host explicitly. +#ServerName www.example.com + +ServerAdmin webmaster@localhost +DocumentRoot /home/httpd/html + +# Available loglevels: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the loglevel for particular +# modules, e.g. +#LogLevel info ssl:warn + +ErrorLog \\\${APACHE_LOG_DIR}/error.log +CustomLog \\\${APACHE_LOG_DIR}/access.log combined + +# For most configuration files from conf-available/, which are +# enabled or disabled at a global level, it is possible to +# include a line for only one particular virtual host. For example the +# following line enables the CGI configuration for this host only +# after it has been globally disabled with \"a2disconf\". +#Include conf-available/serve-cgi-bin.conf + +ScriptAlias \"/cgi-bin/\" \"/home/httpd/cgi-bin/\" + +<Directory /home/httpd/html> +Options Indexes FollowSymLinks +AllowOverride None +Allow from all +Require all granted +</Directory> + +<Directory \"/home/httpd/cgi-bin/\"> + Options +ExecCGI + Require all granted +</Directory> + + +</VirtualHost> +EOF + + #mv /tmp/default \$conf + cat <<-EOF > \$root/index.html + <html> + <body> + ok + </body> + </html> + EOF + + systemctl reload apache2 + sleep 1 + " + + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + root=/home/httpd/html/ + + cat \$conf | \ + sed -e '/<Directory \/home\/httpd/,/<\/Directory>/d' \ + > /tmp/default + cat /tmp/default | grep -v '</VirtualHost>' > \$conf + + cat <<-EOF >> \$conf + <Directory \"/home/httpd/html/\"> + Options Indexes FollowSymlinks Multiviews + AllowOverride None + Order allow,deny + allow from all + Require all granted + </Directory> + </VirtualHost> + EOF + + sleep 1 + systemctl reload apache2 + sleep 1 + " +} + +repairApache2CGI() { + echo + echo "Création d'un script CGI" + + vdn-ssh root@bigboss " + [ ! -d /home/httpd/cgi-bin ] && mkdir -p /home/httpd/cgi-bin + cat <<-EOF > /home/httpd/cgi-bin/test-cgi + #!/bin/bash + + # Header + echo 'Content-type: text/html' + + # Fin de l'header + echo + + # Contenu à afficher dans le navigateur + echo '<html><body>' + echo 'Bonjour : nous sommes le :\`date\`' + echo '</body></html>' + EOF + + chmod 755 /home/httpd/cgi-bin/test-cgi + + cat /etc/apache2/sites-available/000-default.conf | \ + sed -re 's,/usr/lib/cgi-bin/,/home/httpd/cgi-bin/,' \ + > /tmp/defaut + mv /tmp/defaut /etc/apache2/sites-available/000-default.conf + + a2enmod cgid + + systemctl restart apache2 + sleep 1 + " + +} + +repairApache2Php() { + echo + echo "Création d'une page PHP" + + vdn-ssh root@bigboss " + [ ! -d /home/http/html ] && mkdir -p /home/httpd/html + cat <<-EOF > /home/httpd/html/index.php + <html> + <head><title>Exemple + + Nous sommes le , il est . + + + EOF + " + +} + +repairApache2Home() { + echo + echo "Page Web personnelle (userdir)" + + vdn-ssh root@bigboss " + [ ! -d /home ] && { echo 'Need toto user !' >&2; exit 1; } + [ ! -d /home/toto/public_html ] && mkdir /home/toto/public_html + cat <<-EOF > /home/toto/public_html/index.html + Page perso. + EOF + chown -R toto: /home/toto/public_html + + a2enmod userdir + systemctl restart apache2 + sleep 1 + " +} + +repairApache2HtaccessToto() { + echo + echo "Protection de toto@bigboss:~toto/secret" + + vdn-ssh root@bigboss " + [ ! -d /home/toto/public_html/secret ] && { + mkdir -p /home/toto/public_html/secret + chown -R toto: /home/toto/public_html + chmod 700 /home/toto/public_html/secret + } + + cat <<-EOF > /home/toto/public_html/secret/.htaccess + AuthType Basic + AuthUserFile /home/toto/public_html/secret/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user titi + +EOF + + echo \"Prive\" > \ + /home/toto/public_html/secret/index.html + + ( + cd /home/toto/public_html/secret/ + htpasswd -b -c users titi iut + ) + + chown -R toto: /home/toto/public_html + " + +} + +repairApache2Htaccess() { + echo + echo "Protection par mot de passe" + + vdn-ssh root@bigboss " + [ ! -d /home/httpd/html/prive ] && mkdir /home/httpd/html/prive + cat <<-EOF > /home/httpd/html/prive/.htaccess + AuthType Basic + AuthUserFile /etc/apache2/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user toto + + EOF + + echo \"Prive\" > \ + /home/httpd/html/prive/index.html + + ( + cd /etc/apache2 + htpasswd -b -c users toto iut + htpasswd -b users prof iut + ) + " + + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + + cat \$conf | \ + sed -e '//d' \ + > /tmp/default + cat /tmp/default | grep -v '' > \$conf + + cat <<-EOF >> \$conf + + Options Indexes FollowSymlinks Multiviews + AllowOverride All + Order allow,deny + allow from all + + + EOF + + systemctl reload apache2 + sleep 1 + " +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairApache2Base + #repairApache2Root + #repairApache2CGI + #repairApache2Php + repairApache2Home + #repairApache2Htaccess + repairApache2HtaccessToto + + unsetErrorHandler +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/repairDhcp b/vdn/networks.bak/demo-bookworm/scripts/repairDhcp new file mode 100644 index 0000000..9c3b81b --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/repairDhcp @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Fixe DHCP sur bigboss pour servir tiny (IP, nom d'hôte)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +repairDHCP() { + echo + echo "Repair DHCP" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + set -x + sleep 10 + + systemctl enable isc-dhcp-server + systemctl stop isc-dhcp-server + systemctl start isc-dhcp-server + + #if [ -e /etc/init.d/dhcp3-server ]; then + # /etc/init.d/dhcp3-server stop &> /dev/null + # /etc/init.d/dhcp3-server start + #elif [ -e /etc/init.d/isc-dhcp-server ]; then + # /etc/init.d/isc-dhcp-server stop &> /dev/null + # /etc/init.d/isc-dhcp-server start + #fi + + " +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairDHCP + + echoDoneWithTestErrors +} + + diff --git a/vdn/networks.bak/demo-bookworm/scripts/repairFirewall b/vdn/networks.bak/demo-bookworm/scripts/repairFirewall new file mode 100644 index 0000000..e816f53 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/repairFirewall @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + config + + #sleep 1 + + #parallelDisablePause + #vdn-scripts testFirewall + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/repairIPv6 b/vdn/networks.bak/demo-bookworm/scripts/repairIPv6 new file mode 100644 index 0000000..8f8ac1b --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/repairIPv6 @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Nouvelle configuration IPv6 du réseau + tests" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + +testIPv6() { + echo + echo "test link between web and bigboss (Unique local address)" + echo + + # réinitialise les interfaces + + vdn-ssh root@bigboss "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@web "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@societe " + ifconfig eth0 down ; ifconfig eth0 up + ifconfig eth1 down ; ifconfig eth1 up + ifconfig eth2 down ; ifconfig eth2 up + + echo 1 >/proc/sys/net/ipv6/conf/all/forwarding + " + + # Ajoute les adresses IPv6 "locales uniques" en utilisant le suffixe + # de l'adresse "lien local" + # + # * la DMZ (web) aura le préfixe fc01 + # * le réseau interne (bigboss) aura le préfixe fc00 + # + # La fonction routage IPv6 est activé sur société + # et les route par défaut sont fixées sur web et bigboss + # + # un ping6 de bigboss vers web valide la config. + + ipSocieteWeb=$(getIPv6 societe eth1) + ipSocieteWeb=$(echo $ipSocieteWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteWeb/64 dev eth1" + + ipSocieteBigboss=$(getIPv6 societe eth2) + ipSocieteBigboss=$(echo $ipSocieteBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteBigboss/64 dev eth2" + + ipWeb=$(getIPv6 web eth0) + ipWeb=$(echo $ipWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@web "ip -6 addr add $ipWeb/64 dev eth0" + + ipBigboss=$(getIPv6 bigboss eth0) + ipBigboss=$(echo $ipBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@bigboss "ip -6 addr add $ipBigboss/64 dev eth0" + + vdn-ssh root@web " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteWeb" + vdn-ssh root@bigboss " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteBigboss" + + vdn-ssh root@bigboss "ping6 -c 3 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bookworm/scripts/repairNfs b/vdn/networks.bak/demo-bookworm/scripts/repairNfs new file mode 100644 index 0000000..3bc3594 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/repairNfs @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Fixe NFS (bigboss exporte /overlays/ro/usr/share/doc (ro) et tiny l'importe)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, le fichier /etc/exports est modifié ! +" + +repairNfs() { + vdn-ssh root@bigboss " + + [ ! -d /overlays/rw/partage-test ] && mkdir /overlays/rw/partage-test || : + echo test > /overlays/rw/partage-test/vdn-test + + cat <<-EOF > /etc/exports +/overlays/ro/usr/share/doc tiny(ro,sync,subtree_check,no_root_squash,fsid=1) +#/overlays/rw/partage-test tiny(rw,sync,subtree_check,no_root_squash,fsid=2) + EOF + sleep 1 + systemctl enable nfs-kernel-server + systemctl stop nfs-kernel-server + systemctl start nfs-kernel-server + " +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss + + repairNfs + + unsetErrorHandler +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/repairProftpd b/vdn/networks.bak/demo-bookworm/scripts/repairProftpd new file mode 100644 index 0000000..ca93cae --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/repairProftpd @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +set -u + +DESC="Fixe proftp (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, le fichier suivant est modifié : +- /etc/proftpd/proftpd.conf + +Une copie de l'original est faite avec l'extension .vdn +" + + +repairProftpd() { + echo + echo "Repair proftpd" + + vdn-ssh root@bigboss " + + [ ! -e /etc/proftpd/proftpd.conf.vdn ] && \ + cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf.vnd + + grep -q '^> /etc/proftpd/proftpd.conf +# A basic anonymous configuration, no upload directories. + + + User ftp + Group nogroup + # We want clients to be able to login with \"anonymous\" as well as \"ftp\" + UserAlias anonymous ftp + # Cosmetic changes, all files belongs to ftp user + DirFakeUser on ftp + DirFakeGroup on ftp + + RequireValidShell off + + # Limit the maximum number of anonymous logins + MaxClients 10 + + # We want 'welcome.msg' displayed at login, and '.message' displayed + # in each newly chdired directory. + DisplayLogin welcome.msg + DisplayChdir .message + + # Limit WRITE everywhere in the anonymous chroot + + + DenyAll + + + + +EOF + + systemctl enable proftpd + systemctl restart proftpd + " + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairProftpd + + echoDoneWithTestErrors +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/repairUsersTotoTiti b/vdn/networks.bak/demo-bookworm/scripts/repairUsersTotoTiti new file mode 100644 index 0000000..d9c1c29 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/repairUsersTotoTiti @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Ajoute, si nécessaire un utilisateur toto sur bigboss et tit sur tiny." + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +repairUser() { + k=$(getRandomPasswd) + vdn-ssh root@$1 " + id $2 2> /dev/null && exit 0 + adduser --disabled-password --gecos \"\" --home /home/$2 --shell /bin/bash $2 + echo $2:$k| chpasswd + " +} + + +run() { + setErrorHandler + echoStart + + startAndWaitSsh bigboss tiny + + repairUser bigboss toto + repairUser tiny titi + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testAll-1A b/vdn/networks.bak/demo-bookworm/scripts/testAll-1A new file mode 100755 index 0000000..edcde67 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testAll-1A @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +DESC="Teste les TPs de 1A sur bigboss et tiny." + +SYSTEMS="bigboss tiny societe lambda web" + +testTp1Part1() { + echo "[TP n°1 partie bigboss]" + echo + vdnTest "hostname bigboss ......... ?" 'vdn-ssh root@bigboss "test \"\$(hostname)\" = bigboss"' + vdnTest "ip bigboss ............... ?" 'vdn-ssh root@bigboss "ip addr show eth0 | grep -Fq 192.168.30.2"' + vdnTest "ping bigboss -> tiny ..... ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "ping bigboss -> bigboss .. ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 bigboss &> /dev/null"' +} + +testTp1Part2() { + echo "[TP n°1 partie tiny]" + echo + vdnTest "hostname tiny ............ ?" 'vdn-ssh root@tiny "test \"\$(hostname)\" = tiny"' + vdnTest "ip tiny .................. ?" 'vdn-ssh root@tiny "ip addr show eth1 | grep -Fq 192.168.30.16"' + vdnTest "ping tiny -> bigboss .. ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping tiny -> tiny ..... ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 tiny &> /dev/null"' +} + +testTp2() { + echo "[TP n°1 partie \"utilisateurs\"]" + echo + vdnTest "user toto sur bigboss .... ?" 'vdn-ssh root@bigboss "id toto &> /dev/null"' + vdnTest "user titi sur tiny ....... ?" 'vdn-ssh root@tiny "id titi &> /dev/null"' + echo + echo "[TP n°2]" + echo + vdnTest "NFS lecture seule (ro) ... ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' +} + +testTp3() { + echo "[TP n°3]" + echo + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdnTest "DHCP configuré sur bigboss ....... ?" "vdn-ssh root@bigboss \"grep -iq '^[^#]*$tinyMAC' /etc/dhcp/dhcpd.conf\"" + vdnTest "DHCP sur bigboss : actif ......... ?" "vdn-ssh root@bigboss \"systemctl status isc-dhcp-server | grep -q 'Active: active'\"" + + echo + + vdnTest "FTP anonyme sur bigboss .......... ?" "vdn-ssh root@tiny 'set -x; echo -e \"open bigboss\nuser anonymous test@bidule.com\nls\" | ftp -i -n | grep -q welcome'" + + echo + + #vdnTest "bigboss run apache2 .............. ?" "vdn-ssh root@tiny 'netcat -w 1 bigboss 80 &> /dev/null < /dev/null'" + vdnTest "bigboss run apache2 .............. ?" "vdn-ssh root@tiny 'timeout 2 lynx -dump bigboss &> /dev/null'" + e=$? + + if [ $e = 0 ]; then + vdnTest "bigboss run apache2 with userdir . ?" "vdn-ssh root@tiny 'unset http_proxy; \ + timeout 2 lynx -dump bigboss/~toto 2> /dev/null | grep -iv \"Not found\"'" + vdnTest "toto@bigboss avec HTTP protégé ... ?" "vdn-ssh root@bigboss '\ + find /home/toto/public_html -name .htaccess 2> /dev/null | grep -q htaccess$'" + else + echo >&2 + echo "Subsequent tests canceled !" >&2 + return 1 + fi + + +} + +testTp4() { + echo "[TP n°4]" + echo + + vdnTest "tiny -> web ....................... ?" "vdn-ssh root@tiny 'unset http_proxy; timeout 2 lynx -dump web'" + echo + vdnTest "root@bigboss id_rsa/id_rsa.pub .... ?" "vdn-ssh root@bigboss 'ls -l ~/.ssh/id_rsa &> /dev/null'" + vdnTest "root@bigboss -> titi@tiny ......... ?" "vdn-ssh root@bigboss 'timeout 2 ssh -o StrictHostKeyChecking=no titi@tiny :'" +} + +testTp5() { + echo "[TP n°5]" + echo + + local ipLambda=$(vdn-infos lambda PUBLIC_IP) + + vdnTest "tiny -> ipLambda .................. ?" "vdn-ssh root@tiny 'unset http_proxy; timeout 2 lynx -dump $ipLambda'" + echo + vdnTest "serveur.rb ........................ ?" "vdn-ssh root@bigboss 'ls /usr/local/bin/server.rb &> /dev/null'" + vdnTest "client.rb ......................... ?" "vdn-ssh root@tiny 'ls /usr/local/bin/client.rb &> /dev/null'" +} + +testSum() { + local last=-1 cpt=0 n + set +u + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + + if [ -z "$VDN_TESTS_DIR" ]; then + echo + echo "Not used !" + return + fi + set +u + last=-1 + echo "[Synthèse]" + echo + + while :; do + n=$(ls $VDN_TESTS_DIR | wc -l) + + printf "." + + if [ $n = $last ]; then + same=$(($same+1)) + else + same=0 + fi + + if [ $same = 10 ]; then + break; + fi + + last=$n + + sleep 0.5 + done + + good=$(cat $VDN_TESTS_DIR/* | grep '^0$' | wc -l) + bad=$(($n-$good)) + + echo + echo + echo "tests:$n ok:$good ko:$bad réussite:$(( ($good*100) /$n ))%" + echo + + +} + + +run() { + + requireSshGuests $SYSTEMS + + #echo "Cette temporisation est pour vous décourager d'utiliser ce test comme debogueur !" + #for i in $(seq 10 -1 0); do echo $i; sleep 1; done + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + + [ ! -d $VDN_TESTS_DIR ] && mkdir -p $VDN_TESTS_DIR + + rm -f /tmp/vdn-$USER/tests/* + + vdnExec testTp1Part1 testTp1Part2 testTp2 testTp3 testTp4 testTp5 testSum + +} diff --git a/vdn/networks.bak/demo-bookworm/scripts/testApache2 b/vdn/networks.bak/demo-bookworm/scripts/testApache2 new file mode 100644 index 0000000..e30df5d --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testApache2 @@ -0,0 +1,140 @@ +#!/usr/bin/env bash + +set -u + +#set -x + +DESC="Test apache2 (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, les fichiers suivants sont modifiés : +- /etc/apache2/apache2.conf +- /etc/apache2/sites-available/000-default.conf +" + + +testApache2Base() { + echo "bigboss run apache2 ?" + + vdn-ssh root@tiny "netcat -w 1 bigboss 80 &> /dev/null < /dev/null" + + #vdn-ssh root@tiny "lynx -dump bigboss &> /dev/null" + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e +} + +testApache2Root() { + vdn-ssh root@tiny " + lynx -dump bigboss/index.html | \ + grep -q -i 'Bonjour' + " + + vdn-ssh root@tiny " + lynx -dump bigboss/index.html | grep -q 'ok' && echo ok + " +} + +testApache2CGI() { + + vdn-ssh root@tiny " + lynx -dump bigboss/cgi-bin/test-cgi + lynx -dump bigboss/cgi-bin/test-cgi | grep -q 'Bonjour' + " +} + +testApache2Php() { + + vdn-ssh root@tiny " + lynx -dump bigboss/index.php + lynx -dump bigboss/index.php | grep -q 'sommes le [^,]' + " +} + +testApache2Home() { + echo "bigboss run apache2 with userdir ?" + + vdn-ssh root@tiny " + unset http_proxy; lynx -dump bigboss/~toto 2> /dev/null # | grep -iq 'perso' + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e + +} + +testApache2HtaccessExist() { + echo "toto@bigboss possède un répertoire HTTP protégé ?" + + vdn-ssh root@bigboss " + find /home/toto/public_html -name '.htaccess' 2> /dev/null | grep -q 'htaccess$' + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e +} + +testApache2HtaccessToto() { + echo "toto@bigboss : répertoire HTTP fonctionnel ?" + vdn-ssh root@tiny " + unset http_proxy; lynx -dump http://bigboss/~toto/index.html + " +} + +testApache2Htaccess() { + + vdn-ssh root@tiny " + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive | grep -q 'Prive' && \ + echo \"ok\" + echo + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive/.htaccess | grep -q 'Forbidden' + " + + vdn-ssh root@tiny " + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive 2> /dev/null | grep -q 'Prive' || \ + echo \"ok\" + echo + echo \"Accès à privé avec identification\" + lynx -auth=sasa:xyz -dump bigboss/prive | \ + grep -q 'Prive' + " + + +} + + +run() { + local errors=0 e + + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + testApache2Base + e=$? + #testApache2Root + #testApache2CGI + #testApache2Php + + if [ $e = 0 ]; then + testApache2Home + testApache2HtaccessExist + #testApache2HtaccessToto + else + echo "Subsequent tests canceled !" >&2 + fi + #testApache2Htaccess + + unsetErrorHandler + return $errors +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testBigbossTiny b/vdn/networks.bak/demo-bookworm/scripts/testBigbossTiny new file mode 100644 index 0000000..c8e39e1 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testBigbossTiny @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +DESC="Test de la configuration de base de bigboss et tiny." + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + vdnTest "hostname bigboss ......... ?" 'vdn-ssh root@bigboss "test \"\$(hostname)\" = bigboss"' + vdnTest "ip bigboss ............... ?" 'vdn-ssh root@bigboss "ip addr show eth0 | grep -Fq 192.168.30.2"' + vdnTest "hostname tiny ............ ?" 'vdn-ssh root@tiny "test \"\$(hostname)\" = tiny"' + vdnTest "ip tiny .................. ?" 'vdn-ssh root@tiny "ip addr show eth1 | grep -Fq 192.168.30.16"' + vdnTest "ping bigboss -> tiny ..... ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "ping tiny -> bigboss .. ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping bigboss -> bigboss .. ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping tiny -> tiny ..... ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "user toto sur bigboss .... ?" 'vdn-ssh root@bigboss "id toto &> /dev/null"' + vdnTest "user titi sur tiny ....... ?" 'vdn-ssh root@tiny "id titi &> /dev/null"' + + echo + + vdnTest "NFS lecture seule (ro) ... ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' + + echoDone + + return $localErrors +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testDHCPBigbossTiny b/vdn/networks.bak/demo-bookworm/scripts/testDHCPBigbossTiny new file mode 100644 index 0000000..c0c7766 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testDHCPBigbossTiny @@ -0,0 +1,125 @@ +#!/usr/bin/env bash + +set -eu + +set -x + +DESC="Test DHCP (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +resetToDefault() { + echo + echo "Reset DHCP" + + vdn-ssh root@bigboss " + + # Création d'une sauvegarde des fichiers originaux + for i in /etc/dhcp3/dhcpd.conf; do + [ ! -e \${i}.vdn -a -e $i ] && + cp \${i} \${i}.vdn + done + + # Restauration de la sauvegarde + + for i in /etc/dhcp3/dhcpd.conf; do + [ -e \${i}.vdn ] && + cp \${i}.vdn \${i} + done + + exit 0 + " + + vdn-ssh root@tiny " + + # Création d'une sauvegarde des fichiers originaux + + for i in /etc/network/interfaces; do + [ ! -e \${i}.vdn ] && + cp \${i} \${i}.vdn + done + + # Restauration de la sauvegarde + + for i in /etc/network/interfaces; do + [ -e \${i}.vdn ] && + cp \${i}.vdn \${i} + done + " + + +} + + +testDHCP() { + echo + echo "Test de DHCP" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + if [ -e /etc/init.d/dhcp3-server ]; then + /etc/init.d/dhcp3-server stop &> /dev/null + /etc/init.d/dhcp3-server start + elif [ -e /etc/init.d/isc-dhcp-server ]; then + /etc/init.d/isc-dhcp-server stop &> /dev/null + /etc/init.d/isc-dhcp-server start + fi + + " + + vdn-ssh root@tiny " + cat <<-EOF > /etc/network/interfaces + auto lo + iface lo inet loopback + + auto eth1 + iface eth1 inet dhcp + EOF + + ifdown eth1 + ifup eth1 + + ifconfig eth1 | grep -q 192.168 && echo ok || exit 1 + " + + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + resetToDefault + testDHCP + resetToDefault + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testDhcp b/vdn/networks.bak/demo-bookworm/scripts/testDhcp new file mode 100644 index 0000000..e7dfd6c --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testDhcp @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +DESC="Test DHCP (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdnTest "DHCP configuré sur bigboss ?" "vdn-ssh root@bigboss \"grep -q '^[^#]*$tinyMAC' /etc/dhcp/dhcpd.conf\"" + vdnTest "DHCP sur bigboss : actif ?" "vdn-ssh root@bigboss \"systemctl status isc-dhcp-server | grep -q 'Active: active'\"" + + echo + + vdnTest "FTP anonyme sur bigboss ?" "vdn-ssh root@tiny ' + echo -e \'open bigboss\nuser anonymous test@bidule.com\nls\' \ + | ftp -i -n | grep -q welcome'" + + + unsetErrorHandler + + echoDone + + return $localErrors +} + + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testFirewall b/vdn/networks.bak/demo-bookworm/scripts/testFirewall new file mode 100644 index 0000000..3806442 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testFirewall @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +run() { + setErrorHandler + echoStart + + parallelDisablePause + + vdn-scripts diag1 diag2 diag3 + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testIPv6 b/vdn/networks.bak/demo-bookworm/scripts/testIPv6 new file mode 100644 index 0000000..c7729f8 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testIPv6 @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test ping6 IPv6 (à travers un routeur IPv6)" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | head -n 1 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + + +testIPv6() { + + ipWeb=$(getIPv6 web eth0) + echo "Try ping6 (bigboss -> web)..." + vdn-ssh root@bigboss "ping6 -c 1 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + #waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testMyCompanyFirewall b/vdn/networks.bak/demo-bookworm/scripts/testMyCompanyFirewall new file mode 100644 index 0000000..40d3cda --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testMyCompanyFirewall @@ -0,0 +1,136 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" + + +} + +test() { + # tiny peut joindre bigboss (et vice versa). + + vdn-ssh root@bigboss "ping -c 1 tiny" + vdn-ssh root@tiny "ping -c 1 bigboss" + + # societe est joignable par toutes les machines (et vice versa) + + for i in $SYSTEMS; do + vdn-ssh root@$i "ping -c 1 societe" + done + + # lambda peut joindre nomade (et vice-versa) + + vdn-ssh root@lambda "ping -c 1 nomade" + vdn-ssh root@nomade "ping -c 1 lambda" + + # vérifiez que les serveurs apache2 de lambda, web et bigboss fonctionnent + + vdn-ssh root@bigboss "lynx -dump bigboss" | grep -q 'Bienvenue' + vdn-ssh root@web "lynx -dump web" | grep -q 'Bienvenue' + vdn-ssh root@lambda "lynx -dump lambda" | grep -q 'Bienvenue' +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + #set -x + + # Config + config + + # test + #test + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testNfs b/vdn/networks.bak/demo-bookworm/scripts/testNfs new file mode 100644 index 0000000..0adb099 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testNfs @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +DESC="Test NFS (bigboss exporte /overlays/ro/usr/share/doc (ro) et tiny l'importe)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + vdnTest "NFS lecture seule (ro) ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' + + echoDone + + return $localErrors +} + diff --git a/vdn/networks.bak/demo-bookworm/scripts/testProftpd b/vdn/networks.bak/demo-bookworm/scripts/testProftpd new file mode 100644 index 0000000..e469a98 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/scripts/testProftpd @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -u + +DESC="Test proftp (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +testProftp() { + echo + echo "Test de proftpd (anonymous)" + + vdn-ssh root@tiny " + echo -e 'open bigboss\nuser anonymous test@bidule.com\nls' \ + | ftp -i -n | grep -q welcome + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + + return $e + +} + +run() { + local errors=0 + + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + testProftp + + unsetErrorHandler + return $errors +} + diff --git a/vdn/networks.bak/demo-bookworm/societe.conf b/vdn/networks.bak/demo-bookworm/societe.conf new file mode 100644 index 0000000..1098e23 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/societe.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=2 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#20.X3.Y3.Z3/8 $NET_1#192.168.1.1/24 $NET_2#192.168.30.1/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bookworm/tiny.conf b/vdn/networks.bak/demo-bookworm/tiny.conf new file mode 100644 index 0000000..e0c4b2d --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/tiny.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="2048" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=0 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="none $NET_2#192.168.30.16/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bookworm/web.conf b/vdn/networks.bak/demo-bookworm/web.conf new file mode 100644 index 0000000..b4d4897 --- /dev/null +++ b/vdn/networks.bak/demo-bookworm/web.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=3 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.1.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye.bak/bigboss.conf b/vdn/networks.bak/demo-bullseye.bak/bigboss.conf new file mode 100644 index 0000000..7389853 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/bigboss.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="512" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=1 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_2#192.168.30.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2 proftpd nfs-server isc-dhcp-server" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye.bak/build b/vdn/networks.bak/demo-bullseye.bak/build new file mode 100755 index 0000000..f046fe8 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/build @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + + +build() { + local n + + for n in tiny bigboss societe web lambda nomade; do + vdn-build $n + vdn-config $n GUEST_SYS "debian/bullseye" + vdn-config $n MODE "tgz2" + vdn-config $n HDA "DebianBullseye.disk" + vdn-config $n MEMORY "512" + vdn-config $n RUNLEVEL "multi-user.target" + vdn-config $n SET_HOSTNAME 0 + #vdn-config $n HOST_FILES "" + done + + n=tiny + vdn-config $n NETWORKS "none \$NET_2#192.168.30.16/24" + vdn-config $n MEMORY "2048" + vdn-config $n RUNLEVEL "graphical.target" + vdn-config $n ON_BOOT "systemctl start lightdm" + #vdn-config $n EXTRA_SERVICES "lightdm" + #vdn-config $n MODE "overlay" + + #vdn-config $n KVM_VIEWER_AUTOSTART 1 + + n=bigboss + vdn-config $n EXTRA_SERVICES "apache2 proftpd nfs-server isc-dhcp-server" + vdn-config $n MEMORY "512" + vdn-config $n NETWORKS "\$NET_2#192.168.30.2/24" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=societe + vdn-config $n NETWORKS "\$NET_G#20.X3.Y3.Z3/8 \$NET_1#192.168.1.1/24 \$NET_2#192.168.30.1/24" + + n=web + vdn-config $n NETWORKS "\$NET_1#192.168.1.2/24" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=lambda + vdn-config $n NETWORKS "\$NET_G#20.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=nomade + vdn-config $n NETWORKS "\$NET_G#20.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/graph.svgz b/vdn/networks.bak/demo-bullseye.bak/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..296c9fe8e7d0fce03e005ea18744cefe7d6c3a67 GIT binary patch literal 1478 zcmV;%1v&a3iwFpfH_l=J17~t!aA+=bc4q*sS8Z>bND%&>U$Mujr&g+$oqb^;ja#X1 zuc~w}l`g%z^c#tZjY=RgC{Ft8?^z&rf}u9)eIZPC7SBA-GqbZNZ*H$Lc9X2iw8*C( zapAEfzbNKuzLdZ-4tZ zW8TE~|4}pFe|P$h{q^?;Mx1>A{U6>D^OjY0eeC<|^_s60FIEfx!z#XBrWd6TPv3cB zmyfRz@p(1(+;2=K>_d_#tGG($?EH=`+?Jd4+kL!Da;>;v&&7))Hkq_rPSYw&j@dKC zKE;cqJZ99axk%UPyjo5@W5jjkv1O7jmesv^#BS1L{kFKBdV&kV>W9%04;6z4mp}qw z<>j;|8!3cv(YG$gw^^Eh?Q^6kiu`)jrMO_}eCpMC0r-n7F3Z;RShb4t^0HW6O}+9W z&XVWE=mlF972rU|&3fhxjW7em_riU$a_PT*rcV6k?dasX$nF+E>oU!)B^GQLVP{P#4yO3IgIvPv)8l`{Q?h)F{} z-h(Xhef*ZcXwec~oa6vbVvEps167gbWZFoT;iM0ZRMwGx%&TOTC)IAKZ4STutj()m z7S*dqp(pdj1B#usL-BUw1G3|4*~|2K7GHez7{2^_&6ELEMk2GB5)$vIM-ecEx;NID znk&VW72E{QBrffKQk4jK6tq~$u*Pi!R&C(59$zQbQZVT4U&YT9|DybG7eVThtp>=Z z1IeZ!Lf%aRBrOj{l1=+rrY_6!K$dAF%PQb1YRZ%3OcEL{!6cNhWE4i+pj;`CJPa7w z08TJLv^k)7h2-|0XQZy|5Alo!96^c!1cUQR>Rk|JmuNjev>ZXSkWB_E6r9vJqUC;~ zWtV7mAklI>(ZPM^jcTGJl&}(lYYn1NlHgt8q>TWyHC#g#%7Q_40MiQjwtZR&e0dyB zU8d!RX(a}zuG0Lj%eEO{+xb5Ipp($Lafh#Thc5-T*A(^9ym9WBwex-$Dbnz7U^HlI zCLDL%wTbpXH7qwhAh*Z6#%YZrcMvo%keX45fd$gjXdlYf;!>DyG@+7VL2+1A$Xy&D zwYvUWscG!}-? zA4@}ObB-yn5zsijZBp$8Yc#r9;T@QL)w`R3>R)l2`x@IrjMV-K}B$w=|w;4$<&0}Jsp;$Nt5U|A>UUA5T(wZZktQX^1q9bf?q z^y4?d+QrQa*7gI1y0_HMMNs58H8rX1LNPoO1p_*Iv}t7Pf_TWaBXlmBk!!-PfnzF) z7(p%;b1vb`bkh*TBv5V6iSz-TOQFKramc9pLiVFJQxM%MQq`yKiLMveXXM zXvV=zcLxeSZaT{;eE@EQ^&+ahHnF2`L|`Wu(zXOe%B zeU0lpU7QzX+0|S$pt;ul>7sK(1x8QOOgwy3QQ+Q8_~^A+KVX<`rKQP@#^a>5&8Q!l z;W;cE5ZBJeaq2Q57toJJrCBw@3F*!~jRqEB=vSD_w8O~V-x(RpHJY75dD#QX5O+gs gw|66T@bIvwpJ5Q&ZD`G-yuqLU059}5-Zd2f07<#>wg3PC literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-bullseye.bak/lambda.conf b/vdn/networks.bak/demo-bullseye.bak/lambda.conf new file mode 100644 index 0000000..b4fc095 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/lambda.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="512" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=4 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#20.X1.Y1.Z1/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye.bak/net.svgz b/vdn/networks.bak/demo-bullseye.bak/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..3a3bcdb3286c6a945f0f8ebd0228ab5f24f0263e GIT binary patch literal 33592 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 UfBO9GZ}PwY15RmFtN;K2 literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-bullseye.bak/network.vdn b/vdn/networks.bak/demo-bullseye.bak/network.vdn new file mode 100644 index 0000000..e69de29 diff --git a/vdn/networks.bak/demo-bullseye.bak/nomade.conf b/vdn/networks.bak/demo-bullseye.bak/nomade.conf new file mode 100644 index 0000000..94fdb5e --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/nomade.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="512" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=5 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#20.X2.Y2.Z2/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigAll b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigAll new file mode 100644 index 0000000..cc55cdc --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigAll @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +DESC="Configuration de base des systèmes (hostname, hosts, interfaces)." + +SYSTEMS="bigboss lambda nomade societe tiny web" +#SYSTEMS="bigboss tiny" + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + # Construction de la liste des commandes + L="" + for i in $SYSTEMS; do + n=$(echo $i | cut -b 1 | tr -s '[[:lower:]]' '[[:upper:]]') + n="$n$(echo $i | cut -b 2-)" + L="$L baseConfig$n" + done + + parallelDisablePause + + vdn-scripts $L + + unsetErrorHandler + echoDone + +} diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigBigboss b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigBigboss new file mode 100755 index 0000000..6b5f7bf --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigBigboss @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de bigboss (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="bigboss" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static +address 192.168.30.2 +netmask 255.255.255.0 +gateway 192.168.30.1 + +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigLambda b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigLambda new file mode 100644 index 0000000..e5ed79f --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigLambda @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de lambda (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="lambda" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigNomade b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigNomade new file mode 100644 index 0000000..01fa92c --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigNomade @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de nomade (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="nomade" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigSociete b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigSociete new file mode 100644 index 0000000..9d1bbc2 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigSociete @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de societe (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="societe" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigTiny b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigTiny new file mode 100755 index 0000000..ee3db75 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigTiny @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Configuration de base de tiny (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="tiny" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigWeb b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigWeb new file mode 100644 index 0000000..c7611e0 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/baseConfigWeb @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de web (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="web" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + + systemctl restart networking + " + + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/configFirewall b/vdn/networks.bak/demo-bullseye.bak/scripts/configFirewall new file mode 100755 index 0000000..9523801 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/configFirewall @@ -0,0 +1,107 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base pur le TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +setFirewall() { + vdn-ssh root@societe ' +cat << EOF > /etc/network/fw-start +#!/bin/sh + +set -x + +# Vide les tables + +iptables -F +iptables -t nat -F +iptables -t mangle -F +iptables -X + +# fixe les politiques par défaut + +iptables -P INPUT DROP +iptables -P FORWARD ACCEPT +iptables -P OUTPUT ACCEPT + +# spécifique à VDN (Début) + +iptables -A INPUT -i eth3 -j ACCEPT +iptables -A OUTPUT -o eth3 -j ACCEPT + +# spécifique à VDN (Fin) + +# Autorise l''interface loopback + +iptables -A INPUT -i lo -j ACCEPT +iptables -A OUTPUT -o lo -j ACCEPT + +# Log + +iptables -A INPUT -j LOG --log-prefix "fw INPUT " + +EOF + +chmod 755 /etc/network/fw-start + +cat << EOF > /etc/network/fw-stop +#!/bin/sh + +# Vide les tables + +iptables -F +iptables -t nat -F +iptables -t mangle -F +iptables -X + +# fixe les politiques par défaut + +iptables -P INPUT ACCEPT +iptables -P OUTPUT ACCEPT +iptables -P FORWARD ACCEPT + +EOF + +chmod 755 /etc/network/fw-stop + +/etc/network/fw-stop +' + + # disable ipv4.ip_forward + + vdn-ssh root@societe "echo 0 > /proc/sys/net/ipv4/ip_forward" + +} + + +run() { + setErrorHandler + echoStart + + ### Configuration de base (hostname, hosts, interfaces) + + parallelDisablePause + + vdn-scripts baseConfigAll + + ### Page d'accueil des serveurs Web + + for i in lambda web bigboss; do + vdn-ssh root@$i " + echo \"

Bienvenue sur le serveur Web de $i!

\" > /var/www/index.html + " + done + + ### /etc/network/fw-start /etc/network/fw-stop + + setFirewall + + ### A COMPLETER ### + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/configIPv6 b/vdn/networks.bak/demo-bullseye.bak/scripts/configIPv6 new file mode 100644 index 0000000..b79f8f9 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/configIPv6 @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Conguration IPv6 de base du réseau" + + +SYSTEMS="bigboss lambda nomade societe tiny web" + +setIpv6() { + echo "$@" + host=$1 + eth=$2 + + addr=$(vdn-ssh root@$host "ifconfig $eth" | grep 'inet6:.*fe80:' | head -n 1 | tr -s ' ' | cut -d ' ' -f 4) + + [ -z "$addr" ] && return || : + + case "$3" in + site) new=$(echo "$addr" | sed -re 's/^fe80:/fec0:/');; + global) new=$(echo "$addr" | sed -re 's/^fe80:/2002:/');; + esac + + exist=false + if vdn-ssh root@$host "ifconfig $eth" | grep -q "inet6:.*$new"; then + exist=true + fi + + if [ $exist = false ]; then + echo "$host : ifconfig $eth inet6 add $new" + vdn-ssh root@$host " + ifconfig $eth inet6 add $new/64 + " + fi + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + for i in $SYSTEMS; do + setIpv6WorkAround $i + done + + setIpv6 tiny eth1 site + setIpv6 bigboss eth0 site + setIpv6 web eth0 site + setIpv6 societe eth1 site + setIpv6 societe eth2 site + setIpv6 societe eth0 global + setIpv6 nomade eth0 global + setIpv6 lambda eth0 global + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/diag1 b/vdn/networks.bak/demo-bullseye.bak/scripts/diag1 new file mode 100644 index 0000000..b8f21e1 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/diag1 @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +set -u + +DESC="Diag1." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + # tiny peut joindre bigboss (et vice versa). + + echo "=== ping bigboss -> tiny" + vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null" + + echo "=== ping tiny -> bigoss" + vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null" + + # societe peut joindre toutes les machines + + for i in $SYSTEMS; do + echo "=== ping societe -> $i" + vdn-ssh root@societe "timeout 2 ping -c 1 $i &> /dev/null" + done + + # lambda peut joindre nomade (et vice-versa) + + echo; + + echo "=== ping lambda -> nomade" + vdn-ssh root@lambda "timeout 2 ping -c 1 nomade &> /dev/null" + + echo "=== ping nomade -> lambda" + vdn-ssh root@nomade "timeout 2 ping -c 1 lambda &> /dev/null" + + + # vérifiez que les serveurs apache2 de lambda, web et bigboss fonctionnent + + echo + echo "Tests des serveurs web." + + vdn-ssh root@bigboss "timeout 2 lynx -dump bigboss" | grep -q 'Bienvenue' + vdn-ssh root@web "timeout 2 lynx -dump web" | grep -q 'Bienvenue' + vdn-ssh root@lambda "timeout 2 lynx -dump lambda" | grep -q 'Bienvenue' + + echo + [ $? = 0 ] && green ok || red ko + +} diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/diag2 b/vdn/networks.bak/demo-bullseye.bak/scripts/diag2 new file mode 100644 index 0000000..c7b7b8b --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/diag2 @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -u + +DESC="Diag2." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + diag root@tiny \ + "Test local -> DMZ :" \ + "timeout 1 lynx -dump web | grep --line-buffered -q 'Bienvenue'" + + + diag root@bigboss \ + "Test local -> Internet :" \ + "timeout 1 lynx -dump nomade 2>&1 | grep --line-buffered -q 'Bienvenue'" +} diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/diag3 b/vdn/networks.bak/demo-bullseye.bak/scripts/diag3 new file mode 100644 index 0000000..f0f260e --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/diag3 @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -u + +DESC="Diag3." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + diag root@nomade \ + "Test Internet -> web :" \ + "timeout 1 lynx -dump societe 2>&1 | grep --line-buffered -q 'Bienvenue'" + + diag root@web \ + "Test filtrage sortie web" \ + "! timeout 1 nmap -p 22 nomade 2>1 | grep --line-buffered -q open" + +} diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/repairFirewall b/vdn/networks.bak/demo-bullseye.bak/scripts/repairFirewall new file mode 100755 index 0000000..e816f53 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/repairFirewall @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + config + + #sleep 1 + + #parallelDisablePause + #vdn-scripts testFirewall + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/repairIPv6 b/vdn/networks.bak/demo-bullseye.bak/scripts/repairIPv6 new file mode 100755 index 0000000..8f8ac1b --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/repairIPv6 @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Nouvelle configuration IPv6 du réseau + tests" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + +testIPv6() { + echo + echo "test link between web and bigboss (Unique local address)" + echo + + # réinitialise les interfaces + + vdn-ssh root@bigboss "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@web "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@societe " + ifconfig eth0 down ; ifconfig eth0 up + ifconfig eth1 down ; ifconfig eth1 up + ifconfig eth2 down ; ifconfig eth2 up + + echo 1 >/proc/sys/net/ipv6/conf/all/forwarding + " + + # Ajoute les adresses IPv6 "locales uniques" en utilisant le suffixe + # de l'adresse "lien local" + # + # * la DMZ (web) aura le préfixe fc01 + # * le réseau interne (bigboss) aura le préfixe fc00 + # + # La fonction routage IPv6 est activé sur société + # et les route par défaut sont fixées sur web et bigboss + # + # un ping6 de bigboss vers web valide la config. + + ipSocieteWeb=$(getIPv6 societe eth1) + ipSocieteWeb=$(echo $ipSocieteWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteWeb/64 dev eth1" + + ipSocieteBigboss=$(getIPv6 societe eth2) + ipSocieteBigboss=$(echo $ipSocieteBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteBigboss/64 dev eth2" + + ipWeb=$(getIPv6 web eth0) + ipWeb=$(echo $ipWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@web "ip -6 addr add $ipWeb/64 dev eth0" + + ipBigboss=$(getIPv6 bigboss eth0) + ipBigboss=$(echo $ipBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@bigboss "ip -6 addr add $ipBigboss/64 dev eth0" + + vdn-ssh root@web " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteWeb" + vdn-ssh root@bigboss " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteBigboss" + + vdn-ssh root@bigboss "ping6 -c 3 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/testFirewall b/vdn/networks.bak/demo-bullseye.bak/scripts/testFirewall new file mode 100755 index 0000000..3806442 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/testFirewall @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +run() { + setErrorHandler + echoStart + + parallelDisablePause + + vdn-scripts diag1 diag2 diag3 + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/testIPv6 b/vdn/networks.bak/demo-bullseye.bak/scripts/testIPv6 new file mode 100755 index 0000000..c7729f8 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/testIPv6 @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test ping6 IPv6 (à travers un routeur IPv6)" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | head -n 1 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + + +testIPv6() { + + ipWeb=$(getIPv6 web eth0) + echo "Try ping6 (bigboss -> web)..." + vdn-ssh root@bigboss "ping6 -c 1 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + #waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bullseye.bak/scripts/testMyCompanyFirewall b/vdn/networks.bak/demo-bullseye.bak/scripts/testMyCompanyFirewall new file mode 100755 index 0000000..40d3cda --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/scripts/testMyCompanyFirewall @@ -0,0 +1,136 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" + + +} + +test() { + # tiny peut joindre bigboss (et vice versa). + + vdn-ssh root@bigboss "ping -c 1 tiny" + vdn-ssh root@tiny "ping -c 1 bigboss" + + # societe est joignable par toutes les machines (et vice versa) + + for i in $SYSTEMS; do + vdn-ssh root@$i "ping -c 1 societe" + done + + # lambda peut joindre nomade (et vice-versa) + + vdn-ssh root@lambda "ping -c 1 nomade" + vdn-ssh root@nomade "ping -c 1 lambda" + + # vérifiez que les serveurs apache2 de lambda, web et bigboss fonctionnent + + vdn-ssh root@bigboss "lynx -dump bigboss" | grep -q 'Bienvenue' + vdn-ssh root@web "lynx -dump web" | grep -q 'Bienvenue' + vdn-ssh root@lambda "lynx -dump lambda" | grep -q 'Bienvenue' +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + #set -x + + # Config + config + + # test + #test + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye.bak/societe.conf b/vdn/networks.bak/demo-bullseye.bak/societe.conf new file mode 100644 index 0000000..8c232ce --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/societe.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="512" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=2 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#20.X3.Y3.Z3/8 $NET_1#192.168.1.1/24 $NET_2#192.168.30.1/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye.bak/tiny.conf b/vdn/networks.bak/demo-bullseye.bak/tiny.conf new file mode 100644 index 0000000..13f8c64 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/tiny.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="2048" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=0 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="none $NET_2#192.168.30.16/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="systemctl start lightdm" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye.bak/web.conf b/vdn/networks.bak/demo-bullseye.bak/web.conf new file mode 100644 index 0000000..1e6eec0 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye.bak/web.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="512" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=3 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.1.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye/bigboss.conf b/vdn/networks.bak/demo-bullseye/bigboss.conf new file mode 100644 index 0000000..be40fb4 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/bigboss.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="1024" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_2#192.168.30.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2 proftpd nfs-server isc-dhcp-server" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye/build b/vdn/networks.bak/demo-bullseye/build new file mode 100755 index 0000000..4ea2d8a --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/build @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +build() { + local n + + for n in tiny bigboss societe web lambda nomade; do + vdn-build $n + vdn-config $n MODE "tgz2" + vdn-config $n HDA "DebianBullseye.disk" + vdn-config $n GUEST_SYS "debian/bullseye" + vdn-config $n MEMORY "384" + vdn-config $n RUNLEVEL "multi-user.target" + vdn-config $n SET_HOSTNAME 0 + #vdn-config $n HOST_FILES "" + vdn-config $n SET_PROXY "0" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "0" + #sleep 3 + done + + n=tiny +#vdn-config $n GUEST_SYS "kali/2019.3" + #vdn-config $n HDA "kali-linux-xfce-2019.3-amd64.disk" + #vdn-config $n KERNEL "vmlinuz-5.2.0-kali2-amd64" + #vdn-config $n INITRAMFS "initrd-tgz.img-5.2.0-kali2-amd64" + vdn-config $n NETWORKS "none NET_2#192.168.30.16/24" + vdn-config $n MEMORY "2048" + vdn-config $n RUNLEVEL "graphical.target" + #vdn-config $n MODE "overlay" + + #vdn-config $n KVM_VIEWER_AUTOSTART 1 + + n=bigboss + vdn-config $n EXTRA_SERVICES "apache2 proftpd nfs-server isc-dhcp-server" + vdn-config $n MEMORY "1024" + vdn-config $n NETWORKS "NET_2#192.168.30.2/24" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=societe + vdn-config $n NETWORKS "NET_G#20.X3.Y3.Z3/8 NET_1#192.168.1.1/24 NET_2#192.168.30.1/24" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "1" + vdn-config $n SET_PROXY "1" + + n=web + vdn-config $n NETWORKS "NET_1#192.168.1.2/24" + vdn-config $n EXTRA_SERVICES "apache2" + #vdn-config $n SET_HOSTNAME 1 + #vdn-config $n BOOT_HOSTNAME $n + + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=lambda + vdn-config $n NETWORKS "NET_G#20.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=nomade + vdn-config $n NETWORKS "NET_G#20.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + +} + diff --git a/vdn/networks.bak/demo-bullseye/graph.svgz b/vdn/networks.bak/demo-bullseye/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..69c721462452fdd806b301075f42b24e0e371f3c GIT binary patch literal 1491 zcmV;^1uXg>iwFqto#SEv17~t!aA+=bc4q*sSZ#0HHW2=vU%_c;(E>3=9!Zf*;})pX z6$SPZVClB>n_?-pP+1BrAx`@1ca#)6k)>Hm_C?m2N9pdl=U%AO4|l7S+{Wu7$+M}) zDf392&GRV97E|x*#V-@%k)jN-)Z75 zAD_lKjmpS#@0d);=QxYkVHro{>YgmzmfPgVgS`Z(6qJ!S?ClYmOqwkhNtwncxBUx`z{zB@X-$D1dSlQMQO zUFY91p4C%s!gZV>AUAoEm1x049!r9kN&Q?zK~U9_Dh28J4eDvQx{AUY>DsF-k7B-c z%1Jx(YVAG~Gi2J%!qf!`F}dH_r-Y`)9#5>Lj1y^ChZG1WJ!n3aD$UCDGQKN`yG+7t zzRcHCZqYtQiRE#$cobhJwd1?n_bAd~x$F${RT|E}djuc+o3w@sRfj2QwCInn51G{3hX>;Ap>npWDh1V zFb8;GC~I<+D@o0`&{ps1j^38V&}KjMuzzpkIQnxWHGm5ba(l+5rdnVHQ&cGo9ivja zY!Fmv6jin8lrTz%qv@U^YLo&=1M@=uyS#JA3oJT5$bAfpe4fN*+>W;DiFTv@>|Ig-o|l^bM8wl z2!P41^i1GXCAq`KQfr970*o93ZfHOxRukq_aZY3UFjNAWsUBLBaa&$qaRt2;^qc6a zxNRWza#jsQaAeK`W|OrworIo&Fx24uKvk() zfye`DUxXn%&RX7?wY;6LK~KK&fz=t%Q!Z-{gwZq@SDg9bK=XE><-kDmk%30*MO`R@ z8DM6BOB5>+Py!mw#o{cKqRe2y(bOUd1cuuTsw$Wt4^_p@K7*TWXPo&q&b%kgWs=>u zBdvQP?R1|%uUDzSsRY6v-??^#cW(L7ZM{AKuV&<}(`j4@Zrterq`!0oJ&by~YaE?$ zQgMYq8>;xsD9YV1i!`!WC2*?eZt%s@!Ytt`sEV?i0GK(9jtQtS5AzTfaQQ!x$rX*D zlTKN_3ZuPNZ+Zw-Yd@b-#=27hSWbh0DCm+f4V`4Vq)KzZ5m4D}`wFld4lZ0Z&9+W< zLe<~rbr03r`$m!tae=@=5nxxEDTc!!mMg$^FNoB5HLimp3+rchxZxg}Q0 z1L_$L4bU`61-$A7W5`zfxsOwSk2F0rd$MU{f0R%IfCK|se{PZ5o#zQ)F1h+9@gy&U tY96mvvD^>ojskF`s?m||>@xUk%z?8D?>M^Dm*N(G{sj=B6oeub00140-3kBz literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-bullseye/lambda.conf b/vdn/networks.bak/demo-bullseye/lambda.conf new file mode 100644 index 0000000..0ae8692 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/lambda.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_G#20.X1.Y1.Z1/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye/net.svgz b/vdn/networks.bak/demo-bullseye/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..3a3bcdb3286c6a945f0f8ebd0228ab5f24f0263e GIT binary patch literal 33592 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 UfBO9GZ}PwY15RmFtN;K2 literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-bullseye/network.vdn b/vdn/networks.bak/demo-bullseye/network.vdn new file mode 100644 index 0000000..e69de29 diff --git a/vdn/networks.bak/demo-bullseye/nomade.conf b/vdn/networks.bak/demo-bullseye/nomade.conf new file mode 100644 index 0000000..1d977b4 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/nomade.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_G#20.X2.Y2.Z2/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye/scripts/.baseConfigSociete.swp b/vdn/networks.bak/demo-bullseye/scripts/.baseConfigSociete.swp new file mode 100644 index 0000000000000000000000000000000000000000..dda27546f41844ca20df7e8840ba9d21b550d9ec GIT binary patch literal 12288 zcmeI2%WoS+9LFbIz=S>oH*(+?+f<2^tRGd<77~dxkH%6TL3tF3qB6TXj+d-=tesiA zp=r6m9mEO55rO&#z?lm1u2BC39yfX^5(18VXV-R9H>AB*nT5BXnNxIxMyQXtFn` z6bapt@s=w2qABk+D=!XOT9sU`#Jr5^!RD&;0-+x|%fnV-`>g^8Re?k7c(qbC(HHWg z^xU)S2UQ3gw^hI@U=^?mSOu&CRspMkRp3A>pj$)i9Yp>_H~I_R_t3z*`_aCv0#*U5 zfK|XMU=^?mSOu&CRspMkRlq7>6?hC4;67tNKE+u6X)GT9|L^_&zjK7KKfrI`SMV|T z2z&tE2XBD@yavvJvtS0i42qxto&|+(M3RnfK0#*U5fK}izR^S@T z39lg+WF%NFiImWbaV+Cy9{Hh&8Oxb+PNfQtsrI>*aSh2?@e_XG*us8WD|1g|>q z7*DiJTOZwD69X+?5^t-CJ65thljo{_@J)+H%PaqO_tli0V>N7XQln>9e)@ z%e9s9T?;SoITOn9vd}`A^@mcnT<&dUp@otaXsscr*W42l##+Qi6nyg}Yz8%Chad*` zbkOEnkZy>kLrXHIri=yb>oRUaG#O2h5~iW+K#fg}JLxomqIwVt@`b6tb%ioc9-L7T zN`r%tyD*gzZObI4Y{wbl@wld$8Nw#h4rbD|{zREPI1I*YkG%03P3hB#sVOQ6?e%Jd zOF?}yX*oVhgzG#B^<;nLStebhogI29^=bSTO3Lg>EE9-;WI{CQFudC)Rm#*i%`Ahu zmsS{OotKLJ-Rs*q*?O?zQfA6tr~IX2ZE0?PF;BCUH*WLv1|2&_SFsR?cg zC8KbbCyyE>qM`yV1y_&<90$!r*5WbwU*AAzI+LMyUMf!2*i%QijP)ALA(}>`4x;Vd zjj5>{Y`Rh@{B--@yjEHDHTAU_H&b+5_Zb(-Cilg_Fv?o@85Z)U>+`{3Su297o-pUp zshBn338lxwhE$rFPlI|dqoaE;v&2J6nzr<&O7|fhW)ij4p1z1;^f@Su1C{l$TzY}c zMgBz|=v7>Fy>{bZHs93%w_18nuA18pV;;CB9lHO{s3#Fls*KcRx7OW3zOXon#>Pz! zEiA6i&*rnz_ash_EfSbaJ-m7M_G8S1Z5A?t^N%

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/baseConfigBigbossTiny b/vdn/networks.bak/demo-bullseye/scripts/baseConfigBigbossTiny new file mode 100755 index 0000000..5288d4a --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/baseConfigBigbossTiny @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +DESC="Configuration de base des systèmes (hostname, hosts, interfaces)." + +SYSTEMS="bigboss tiny" + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + # Construction de la liste des commandes + L="" + for i in $SYSTEMS; do + n=$(echo $i | cut -b 1 | tr -s '[[:lower:]]' '[[:upper:]]') + n="$n$(echo $i | cut -b 2-)" + L="$L baseConfig$n" + done + + parallelDisablePause + + vdn-scripts $L + + unsetErrorHandler + echoDone + +} diff --git a/vdn/networks.bak/demo-bullseye/scripts/baseConfigLambda b/vdn/networks.bak/demo-bullseye/scripts/baseConfigLambda new file mode 100755 index 0000000..427f59a --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/baseConfigLambda @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de lambda (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="lambda" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/baseConfigNomade b/vdn/networks.bak/demo-bullseye/scripts/baseConfigNomade new file mode 100755 index 0000000..01fa92c --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/baseConfigNomade @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de nomade (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="nomade" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/baseConfigSociete b/vdn/networks.bak/demo-bullseye/scripts/baseConfigSociete new file mode 100755 index 0000000..f43eb80 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/baseConfigSociete @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de societe (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="societe" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + #/sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/baseConfigTiny b/vdn/networks.bak/demo-bullseye/scripts/baseConfigTiny new file mode 100755 index 0000000..ee3db75 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/baseConfigTiny @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Configuration de base de tiny (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="tiny" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/baseConfigWeb b/vdn/networks.bak/demo-bullseye/scripts/baseConfigWeb new file mode 100755 index 0000000..3a67e8d --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/baseConfigWeb @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de web (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="web" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + + systemctl restart networking + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/configIPv6 b/vdn/networks.bak/demo-bullseye/scripts/configIPv6 new file mode 100644 index 0000000..b79f8f9 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/configIPv6 @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Conguration IPv6 de base du réseau" + + +SYSTEMS="bigboss lambda nomade societe tiny web" + +setIpv6() { + echo "$@" + host=$1 + eth=$2 + + addr=$(vdn-ssh root@$host "ifconfig $eth" | grep 'inet6:.*fe80:' | head -n 1 | tr -s ' ' | cut -d ' ' -f 4) + + [ -z "$addr" ] && return || : + + case "$3" in + site) new=$(echo "$addr" | sed -re 's/^fe80:/fec0:/');; + global) new=$(echo "$addr" | sed -re 's/^fe80:/2002:/');; + esac + + exist=false + if vdn-ssh root@$host "ifconfig $eth" | grep -q "inet6:.*$new"; then + exist=true + fi + + if [ $exist = false ]; then + echo "$host : ifconfig $eth inet6 add $new" + vdn-ssh root@$host " + ifconfig $eth inet6 add $new/64 + " + fi + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + for i in $SYSTEMS; do + setIpv6WorkAround $i + done + + setIpv6 tiny eth1 site + setIpv6 bigboss eth0 site + setIpv6 web eth0 site + setIpv6 societe eth1 site + setIpv6 societe eth2 site + setIpv6 societe eth0 global + setIpv6 nomade eth0 global + setIpv6 lambda eth0 global + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bullseye/scripts/errors b/vdn/networks.bak/demo-bullseye/scripts/errors new file mode 100755 index 0000000..c0d5ac7 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/errors @@ -0,0 +1,5 @@ +#!/bin/bash + +run() { + errors-src/errorsWrapper +} diff --git a/vdn/networks.bak/demo-bullseye/scripts/errors-src/Makefile b/vdn/networks.bak/demo-bullseye/scripts/errors-src/Makefile new file mode 100644 index 0000000..42ad515 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/errors-src/Makefile @@ -0,0 +1,4 @@ + +errorsWrapper : errorsWrapper.c + gcc -Wall -o errorsWrapper errorsWrapper.c + diff --git a/vdn/networks.bak/demo-bullseye/scripts/errors-src/errorsWrapper b/vdn/networks.bak/demo-bullseye/scripts/errors-src/errorsWrapper new file mode 100755 index 0000000000000000000000000000000000000000..3762df404ebc60e42e2f6c229978a188b7f5a700 GIT binary patch literal 19848 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 OKVp_dolC(*ihly7=2Pkb literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-bullseye/scripts/errors-src/errorsWrapper.c b/vdn/networks.bak/demo-bullseye/scripts/errors-src/errorsWrapper.c new file mode 100644 index 0000000..908d64c --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/errors-src/errorsWrapper.c @@ -0,0 +1,13 @@ +#include +#include +#include + +char baseName[1024]="qH3UmebTg5\""; +char fullName[2048]="\"/home/prof/vdn/vdn/networks/demo/scripts/errors-src/"; + +int main() { + strncat(fullName, baseName, 1024); + execlp("bash", "test", "-c", fullName, NULL); + //system(fullName); + return 0; +} diff --git a/vdn/networks.bak/demo-bullseye/scripts/errors-src/qH3UmebTg5 b/vdn/networks.bak/demo-bullseye/scripts/errors-src/qH3UmebTg5 new file mode 100755 index 0000000..ef4381d --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/errors-src/qH3UmebTg5 @@ -0,0 +1,139 @@ +#!/bin/bash + +runErrorScript() { + #set -x + eval "$@" &> /dev/null + + [ $? != 0 ] && { + echo "Le script a, au moins partiellement, échoué !" >&2 + } || echo "ok" +} + +apply() { + case "$choix" in + + "Erreur 1 (TP1)") + # Remplace 192.168.30.16 par 192.168.30.61 dans tiny:/etc/network/interfaces + runErrorScript "vdn-ssh root@tiny \ + 'sed -i -re s/192.168.30.16/192.168.30.61/g /etc/network/interfaces; \ + ifdown eth1; ifup eth1'";; + + "Correction erreur 1 (TP1)") + runErrorScript "vdn-ssh root@tiny \ + 'sed -i -re s/192.168.30.61/192.168.30.16/g /etc/network/interfaces; \ + ifdown eth1; ifup eth1'";; + + + "Erreur 2 (TP1)") + # Remplace tiny par tini dans bigboss:/etc/hosts + runErrorScript "vdn-ssh root@bigboss 'sed -i -re s/tiny/tini/g /etc/hosts'";; + + "Correction erreur 2 (TP1)") + runErrorScript "vdn-ssh root@bigboss 'sed -i -re s/tini/tiny/g /etc/hosts'";; + + + "Erreur 3 (TP2)") + # NFS : remplace tiny par bigboss dans bigboss:/etc/exports + runErrorScript "vdn-ssh root@bigboss \ + 'sed -i -re s/tiny/bigboss/g /etc/exports; \ + systemctl restart nfs-kernel-server'";; + + "Correction erreur 3 (TP2)") + runErrorScript "vdn-ssh root@bigboss \ + 'sed -i -re s/bigboss/tiny/g /etc/exports; \ + systemctl restart nfs-kernel-server'";; + + + "Erreur 4 (TP3)") + # Apache2 (bigboss) : renomme /var/www/html /var/www/html.bak sur bigboss + runErrorScript "vdn-ssh root@bigboss 'mv /var/www/html /var/www/html.bak'";; + + "Correction erreur 4 (TP3)") + runErrorScript "vdn-ssh root@bigboss 'mv /var/www/html.bak /var/www/html'";; + + + "Erreur 5 (TP4)") + # cache tiny:~titi/.ssh/authorized_keys + runErrorScript "vdn-ssh root@tiny \ + 'su -c \" \ + mv ~/.ssh/authorized_keys ~/.ssh/.authorized_keys.bak \ + \" - titi' \ + ";; + + + "Correction erreur 5 (TP4)") + # restaure tiny:~titi/.ssh/authorized_keys + runErrorScript "vdn-ssh root@tiny \ + 'su -c \" \ + mv ~/.ssh/.authorized_keys.bak ~/.ssh/authorized_keys \ + \" - titi' \ + ";; + + "Erreur 6 (TP5)") + # Désactive la fonction routage de societe + runErrorScript "vdn-ssh root@societe 'sysctl -w net.ipv4.ip_forward=0'";; + + "Correction erreur 6 (TP5)") + runErrorScript "vdn-ssh root@societe 'sysctl -w net.ipv4.ip_forward=1'";; + + + "testAll-1A") + vdn-scripts testAll-1A;; + + "Quitter") exit 0;; + + esac + + +} + +run() { + + cat << EOF + +Le menu ci-dessous permet de générer des erreurs sur votre réseau ! + +Pour "jouer" il faut au préalable que votre réseau soit complètement +opérationnel (le script testAll-1A affiche ok pour tout). + +Si c'est le cas, déclenchez une erreur, lancez le script testAll-1A +pour découvrir l'ampleur des dégâts et rétablissez le fonctionnement +optimal de votre réseau. + +Si vous ne vous en sortez pas, le choix "Correction" est là pour +annuler l'erreur, théoriquement ;-) + +Note : + +chaque erreur est une unique commande exécutée sur une machine +du réseau. La commande peut être du genre : + +vdn-ssh root@tiny "sed -i -re 's/^toto:/tutu:/' /etc/passwd" + +Si un service est impacté par la commande, il est relancé afin de mettre +immédiatement en évidence les erreurs via le script testAll-1A. + +Bonne chance ! + +EOF + select choix in \ + "Erreur 1 (TP1)" \ + "Correction erreur 1 (TP1)" \ + "Erreur 2 (TP1)" \ + "Correction erreur 2 (TP1)" \ + "Erreur 3 (TP2)" \ + "Correction erreur 3 (TP2)" \ + "Erreur 4 (TP3)" \ + "Correction erreur 4 (TP3)" \ + "Erreur 5 (TP4)" \ + "Correction erreur 5 (TP4)" \ + "Erreur 6 (TP5)" \ + "Correction erreur 6 (TP5)" \ + "testAll-1A" \ + "Quitter" \ + ; do + apply + done +} + +run diff --git a/vdn/networks.bak/demo-bullseye/scripts/repairAll-1A b/vdn/networks.bak/demo-bullseye/scripts/repairAll-1A new file mode 100644 index 0000000..b9ddb94 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/repairAll-1A @@ -0,0 +1,666 @@ +#!/usr/bin/env bash + +DESC="TP de 1A." + +SYSTEMS="bigboss tiny societe lambda web" + + +baseConfigBigboss() { + + set -e + + echo "[baseConfigBigboss]" + echo + + name="bigboss" + + #startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static +address 192.168.30.2 +netmask 255.255.255.0 +gateway 192.168.30.1 + +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + + echoDoneWithTestErrors + +} + +baseConfigTiny() { + + set -e + + echo "[baseConfigTiny]" + echo + + + name="tiny" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + +vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + echoDoneWithTestErrors +} + +baseConfigSociete() { + + set -e + + echo [baseConfigSociete] + echo + + name="societe" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + echoDoneWithTestErrors +} + +baseConfigWeb() { + + set -e + + echo [baseConfigWeb] + echo + + name="web" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + + systemctl restart networking + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + echoDoneWithTestErrors +} + +baseConfigLambda() { + + set -e + + echo [baseConfigLambda] + echo + + name="lambda" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + echoDoneWithTestErrors +} + +baseConfigNomade() { + + set -e + + echo [baseConfigNomade] + echo + + + echoDoneWithTestErrors +} + + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +repairUser() { + k=$(getRandomPasswd) + vdn-ssh root@$1 " + id $2 &> /dev/null && exit 0 + adduser --disabled-password --gecos \"\" --home /home/$2 --shell /bin/bash $2 + echo $2:$k| chpasswd + " +} + + +repairUsersTotoTiti() { + set -e + + echo "[repairUsersTotoTiti]" + echo + + + repairUser bigboss toto + repairUser tiny titi + + echoDoneWithTestErrors +} + +repairNfs() { + set -e + + echo "[repairNfs]" + echo + + vdn-ssh root@bigboss " + set -e + [ ! -d /overlays/rw/partage-test ] && mkdir /overlays/rw/partage-test || : + echo test > /overlays/rw/partage-test/vdn-test + + cat <<-EOF > /etc/exports +/overlays/ro/usr/share/doc tiny(ro,sync,subtree_check,no_root_squash,fsid=1) +#/overlays/rw/partage-test tiny(rw,sync,subtree_check,no_root_squash,fsid=2) +EOF + systemctl enable nfs-kernel-server + sleep 1 + systemctl stop nfs-kernel-server + systemctl start nfs-kernel-server + " + echoDoneWithTestErrors +} + +repairDhcp() { + set -e + + echo + echo "[repairDhcp]" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + set -e + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + sleep 3 + + systemctl enable isc-dhcp-server + systemctl stop isc-dhcp-server + systemctl start isc-dhcp-server + + #if [ -e /etc/init.d/dhcp3-server ]; then + # /etc/init.d/dhcp3-server stop &> /dev/null + # /etc/init.d/dhcp3-server start + #elif [ -e /etc/init.d/isc-dhcp-server ]; then + # /etc/init.d/isc-dhcp-server stop &> /dev/null + # /etc/init.d/isc-dhcp-server start + #fi + " + echoDoneWithTestErrors +} + +repairProftpd() { + set -e + + echo + echo "[repairProftpd]" + + vdn-ssh root@bigboss " + + [ ! -e /etc/proftpd/proftpd.conf.vdn ] && \ + cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf.vnd + + grep -q '^> /etc/proftpd/proftpd.conf +# A basic anonymous configuration, no upload directories. + + + User ftp + Group nogroup + # We want clients to be able to login with \"anonymous\" as well as \"ftp\" + UserAlias anonymous ftp + # Cosmetic changes, all files belongs to ftp user + DirFakeUser on ftp + DirFakeGroup on ftp + + RequireValidShell off + + # Limit the maximum number of anonymous logins + MaxClients 10 + + # We want 'welcome.msg' displayed at login, and '.message' displayed + # in each newly chdired directory. + DisplayLogin welcome.msg + DisplayChdir .message + + # Limit WRITE everywhere in the anonymous chroot + + + DenyAll + + + + +EOF + + systemctl enable proftpd + sleep 2 + systemctl restart proftpd + " + echoDoneWithTestErrors +} + +repairApache2Base() { + echo "Apache2 : Lancement du serveur" + + vdn-ssh root@bigboss " + echo 'ServerName bigboss' >> /etc/apache2/apache2.conf + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + sleep 1 + " +} + + +repairApache2Home() { + echo + echo "Apache2 : Page Web personnelle (userdir)" + + vdn-ssh root@bigboss " + [ ! -d /home ] && { echo 'Need toto user !' >&2; exit 1; } + [ ! -d /home/toto/public_html ] && mkdir /home/toto/public_html + cat <<-EOF > /home/toto/public_html/index.html + Page perso. + EOF + chown -R toto: /home/toto/public_html + + a2enmod userdir + systemctl restart apache2 + sleep 1 + " +} + +repairApache2HtaccessToto() { + echo + echo "Protection de toto@bigboss:~toto/secret" + + vdn-ssh root@bigboss " + [ ! -d /home/toto/public_html/secret ] && { + mkdir -p /home/toto/public_html/secret + chown -R toto: /home/toto/public_html + chmod 700 /home/toto/public_html/secret + } + + cat <<-EOF > /home/toto/public_html/secret/.htaccess + AuthType Basic + AuthUserFile /home/toto/public_html/secret/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user titi + +EOF + + echo \"Prive\" > \ + /home/toto/public_html/secret/index.html + + ( + cd /home/toto/public_html/secret/ + htpasswd -b -c users titi iut + ) + + chown -R toto: /home/toto/public_html + " + +} + +repairApache2() { + set -e + + echo "[repairApache2]" + echo + + repairApache2Base + repairApache2Home + repairApache2HtaccessToto + + echoDoneWithTestErrors +} + +repairClientServer() { + set -e + + echo "[repairClientServer]" + echo + + vdn-ssh root@bigboss " +cat << EOF > /usr/local/bin/server.rb +#!/usr/bin/env ruby + +require 'socket' +server = TCPServer.new ARGV[0] # socket d'écoute attaché au port passé en argument +loop do # boucle infinie + client = server.accept # attente d'une connexion + while request=client.gets.chomp do # pour toutes les lignes reçues + case request + when \"time\" then client.puts \"#{Time.now}\" # émission de la réponse + when \"exit\" then break + else client.puts \"error\" + end + end + client.close # fermeture de la connexion +end +EOF +" + + vdn-ssh root@tiny " +cat << EOF > /usr/local/bin/client.rb +#!/usr/bin/env ruby + +require \"socket\" +s = TCPSocket.open(ARGV[0], ARGV[1].to_i) # Création de la socket et connexion +while line = STDIN.gets do # pour toutes les lignes de l'entrée standard + s.puts line # émission de la ligne vers le serveur + break if line.chomp == \"exit\" # chomp retire l'\\n' final + puts s.gets # Affiche la ligne en provenance du serveur +end +s.close # fermeture de la socket +EOF +" + + echoDoneWithTestErrors +} + +repairRouting() { + set -e + + echo "[repairRouting]" + echo + + baseConfigSociete + baseConfigWeb + baseConfigLambda + + vdn-ssh root@societe ' + sed -i -re "s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/" /etc/sysctl.conf + sysctl -p + set -e + + + cat << EOF > /etc/firewall.sh +#!/bin/bash + + iptables -t nat -F + iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + chmod 755 /etc/firewall.sh + + +# MARCHE PAS + ! grep -q /etc/firewall.sh /etc/vdn/vdn.rc && { + echo "Add /etc/firewall in /etc/vdn/vdn.rc" + echo /etc/firewall.sh >> /etc/vdn/vdn.rc + chmod 755 /etc/vdn/vdn.rc + } || : + + /etc/firewall.sh + ' + + repairClientServer + + echoDoneWithTestErrors +} + + +repairSshKeys() { + set -e + + echo "[repairSshKeys]" + echo + + vdn-ssh root@bigboss " + set -e + [ ! -e .ssh/id_rsa ] && ssh-keygen -q -N '' -f ~/.ssh/id_rsa -t rsa || : + " + + sleep 2 # laisser le temps à la création de titi sur tiny + + vdn-ssh root@tiny " + su -c ' + [ ! -d ~/.ssh ] && { mkdir ~/.ssh; chmod 700 .ssh; } + ' - titi + " + + local tmp=$(mktemp) + vdn-ssh root@bigboss "cat ~/.ssh/id_rsa.pub" > $tmp + cat $tmp | vdn-ssh root@tiny " + su -c ' + cat > ~/.ssh/authorized_keys + ' - titi + " + + rm $tmp + + echoDoneWithTestErrors +} + +run() { + requireSshGuests $SYSTEMS + + vdnExec baseConfigBigboss baseConfigTiny repairUsersTotoTiti \ + repairNfs repairDhcp repairProftpd \ + repairApache2 \ + repairRouting repairSshKeys +} diff --git a/vdn/networks.bak/demo-bullseye/scripts/repairApache2 b/vdn/networks.bak/demo-bullseye/scripts/repairApache2 new file mode 100644 index 0000000..5b1be10 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/repairApache2 @@ -0,0 +1,304 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Test apache2 (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, les fichiers suivants sont modifiés : +- /etc/apache2/apache2.conf +- /etc/apache2/sites-available/000-default.conf + +Une copie est faite avec l'extension .vdn +" + + +repairApache2Base() { + echo "Lancement du serveur" + + vdn-ssh root@bigboss " + echo 'ServerName bigboss' >> /etc/apache2/apache2.conf + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + sleep 1 + " +} + +repairApache2Root() { + echo + echo "Modification de la racine du serveur Web" + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + [ ! -e \$conf ] && cp \$conf \${conf}.vdn + root=/home/httpd/html + + [ ! -d \$root ] && mkdir -p \$root + + #cat \$conf | sed -e 's|/var/www/html|'\$root'|g' \ + # > /tmp/default + cat <<-EOF > \$conf + +# The ServerName directive sets the request scheme, hostname and port that +# the server uses to identify itself. This is used when creating +# redirection URLs. In the context of virtual hosts, the ServerName +# specifies what hostname must appear in the request's Host: header to +# match this virtual host. For the default virtual host (this file) this +# value is not decisive as it is used as a last resort host regardless. +# However, you must set it for any further virtual host explicitly. +#ServerName www.example.com + +ServerAdmin webmaster@localhost +DocumentRoot /home/httpd/html + +# Available loglevels: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the loglevel for particular +# modules, e.g. +#LogLevel info ssl:warn + +ErrorLog \\\${APACHE_LOG_DIR}/error.log +CustomLog \\\${APACHE_LOG_DIR}/access.log combined + +# For most configuration files from conf-available/, which are +# enabled or disabled at a global level, it is possible to +# include a line for only one particular virtual host. For example the +# following line enables the CGI configuration for this host only +# after it has been globally disabled with \"a2disconf\". +#Include conf-available/serve-cgi-bin.conf + +ScriptAlias \"/cgi-bin/\" \"/home/httpd/cgi-bin/\" + + +Options Indexes FollowSymLinks +AllowOverride None +Allow from all +Require all granted + + + + Options +ExecCGI + Require all granted + + + + +EOF + + #mv /tmp/default \$conf + cat <<-EOF > \$root/index.html + + + ok + + + EOF + + systemctl reload apache2 + sleep 1 + " + + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + root=/home/httpd/html/ + + cat \$conf | \ + sed -e '//d' \ + > /tmp/default + cat /tmp/default | grep -v '' > \$conf + + cat <<-EOF >> \$conf + + Options Indexes FollowSymlinks Multiviews + AllowOverride None + Order allow,deny + allow from all + Require all granted + + + EOF + + sleep 1 + systemctl reload apache2 + sleep 1 + " +} + +repairApache2CGI() { + echo + echo "Création d'un script CGI" + + vdn-ssh root@bigboss " + [ ! -d /home/httpd/cgi-bin ] && mkdir -p /home/httpd/cgi-bin + cat <<-EOF > /home/httpd/cgi-bin/test-cgi + #!/bin/bash + + # Header + echo 'Content-type: text/html' + + # Fin de l'header + echo + + # Contenu à afficher dans le navigateur + echo '' + echo 'Bonjour : nous sommes le :\`date\`' + echo '' + EOF + + chmod 755 /home/httpd/cgi-bin/test-cgi + + cat /etc/apache2/sites-available/000-default.conf | \ + sed -re 's,/usr/lib/cgi-bin/,/home/httpd/cgi-bin/,' \ + > /tmp/defaut + mv /tmp/defaut /etc/apache2/sites-available/000-default.conf + + a2enmod cgid + + systemctl restart apache2 + sleep 1 + " + +} + +repairApache2Php() { + echo + echo "Création d'une page PHP" + + vdn-ssh root@bigboss " + [ ! -d /home/http/html ] && mkdir -p /home/httpd/html + cat <<-EOF > /home/httpd/html/index.php + + Exemple + + Nous sommes le , il est . + + + EOF + " + +} + +repairApache2Home() { + echo + echo "Page Web personnelle (userdir)" + + vdn-ssh root@bigboss " + [ ! -d /home ] && { echo 'Need toto user !' >&2; exit 1; } + [ ! -d /home/toto/public_html ] && mkdir /home/toto/public_html + cat <<-EOF > /home/toto/public_html/index.html + Page perso. + EOF + chown -R toto: /home/toto/public_html + + a2enmod userdir + systemctl restart apache2 + sleep 1 + " +} + +repairApache2HtaccessToto() { + echo + echo "Protection de toto@bigboss:~toto/secret" + + vdn-ssh root@bigboss " + [ ! -d /home/toto/public_html/secret ] && { + mkdir -p /home/toto/public_html/secret + chown -R toto: /home/toto/public_html + chmod 700 /home/toto/public_html/secret + } + + cat <<-EOF > /home/toto/public_html/secret/.htaccess + AuthType Basic + AuthUserFile /home/toto/public_html/secret/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user titi + +EOF + + echo \"Prive\" > \ + /home/toto/public_html/secret/index.html + + ( + cd /home/toto/public_html/secret/ + htpasswd -b -c users titi iut + ) + + chown -R toto: /home/toto/public_html + " + +} + +repairApache2Htaccess() { + echo + echo "Protection par mot de passe" + + vdn-ssh root@bigboss " + [ ! -d /home/httpd/html/prive ] && mkdir /home/httpd/html/prive + cat <<-EOF > /home/httpd/html/prive/.htaccess + AuthType Basic + AuthUserFile /etc/apache2/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user toto + + EOF + + echo \"Prive\" > \ + /home/httpd/html/prive/index.html + + ( + cd /etc/apache2 + htpasswd -b -c users toto iut + htpasswd -b users prof iut + ) + " + + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + + cat \$conf | \ + sed -e '//d' \ + > /tmp/default + cat /tmp/default | grep -v '' > \$conf + + cat <<-EOF >> \$conf + + Options Indexes FollowSymlinks Multiviews + AllowOverride All + Order allow,deny + allow from all + + + EOF + + systemctl reload apache2 + sleep 1 + " +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairApache2Base + #repairApache2Root + #repairApache2CGI + #repairApache2Php + repairApache2Home + #repairApache2Htaccess + repairApache2HtaccessToto + + unsetErrorHandler +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/repairDhcp b/vdn/networks.bak/demo-bullseye/scripts/repairDhcp new file mode 100644 index 0000000..9c3b81b --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/repairDhcp @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Fixe DHCP sur bigboss pour servir tiny (IP, nom d'hôte)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +repairDHCP() { + echo + echo "Repair DHCP" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + set -x + sleep 10 + + systemctl enable isc-dhcp-server + systemctl stop isc-dhcp-server + systemctl start isc-dhcp-server + + #if [ -e /etc/init.d/dhcp3-server ]; then + # /etc/init.d/dhcp3-server stop &> /dev/null + # /etc/init.d/dhcp3-server start + #elif [ -e /etc/init.d/isc-dhcp-server ]; then + # /etc/init.d/isc-dhcp-server stop &> /dev/null + # /etc/init.d/isc-dhcp-server start + #fi + + " +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairDHCP + + echoDoneWithTestErrors +} + + diff --git a/vdn/networks.bak/demo-bullseye/scripts/repairFirewall b/vdn/networks.bak/demo-bullseye/scripts/repairFirewall new file mode 100644 index 0000000..e816f53 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/repairFirewall @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + config + + #sleep 1 + + #parallelDisablePause + #vdn-scripts testFirewall + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/repairIPv6 b/vdn/networks.bak/demo-bullseye/scripts/repairIPv6 new file mode 100644 index 0000000..8f8ac1b --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/repairIPv6 @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Nouvelle configuration IPv6 du réseau + tests" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + +testIPv6() { + echo + echo "test link between web and bigboss (Unique local address)" + echo + + # réinitialise les interfaces + + vdn-ssh root@bigboss "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@web "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@societe " + ifconfig eth0 down ; ifconfig eth0 up + ifconfig eth1 down ; ifconfig eth1 up + ifconfig eth2 down ; ifconfig eth2 up + + echo 1 >/proc/sys/net/ipv6/conf/all/forwarding + " + + # Ajoute les adresses IPv6 "locales uniques" en utilisant le suffixe + # de l'adresse "lien local" + # + # * la DMZ (web) aura le préfixe fc01 + # * le réseau interne (bigboss) aura le préfixe fc00 + # + # La fonction routage IPv6 est activé sur société + # et les route par défaut sont fixées sur web et bigboss + # + # un ping6 de bigboss vers web valide la config. + + ipSocieteWeb=$(getIPv6 societe eth1) + ipSocieteWeb=$(echo $ipSocieteWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteWeb/64 dev eth1" + + ipSocieteBigboss=$(getIPv6 societe eth2) + ipSocieteBigboss=$(echo $ipSocieteBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteBigboss/64 dev eth2" + + ipWeb=$(getIPv6 web eth0) + ipWeb=$(echo $ipWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@web "ip -6 addr add $ipWeb/64 dev eth0" + + ipBigboss=$(getIPv6 bigboss eth0) + ipBigboss=$(echo $ipBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@bigboss "ip -6 addr add $ipBigboss/64 dev eth0" + + vdn-ssh root@web " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteWeb" + vdn-ssh root@bigboss " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteBigboss" + + vdn-ssh root@bigboss "ping6 -c 3 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bullseye/scripts/repairNfs b/vdn/networks.bak/demo-bullseye/scripts/repairNfs new file mode 100644 index 0000000..3bc3594 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/repairNfs @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Fixe NFS (bigboss exporte /overlays/ro/usr/share/doc (ro) et tiny l'importe)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, le fichier /etc/exports est modifié ! +" + +repairNfs() { + vdn-ssh root@bigboss " + + [ ! -d /overlays/rw/partage-test ] && mkdir /overlays/rw/partage-test || : + echo test > /overlays/rw/partage-test/vdn-test + + cat <<-EOF > /etc/exports +/overlays/ro/usr/share/doc tiny(ro,sync,subtree_check,no_root_squash,fsid=1) +#/overlays/rw/partage-test tiny(rw,sync,subtree_check,no_root_squash,fsid=2) + EOF + sleep 1 + systemctl enable nfs-kernel-server + systemctl stop nfs-kernel-server + systemctl start nfs-kernel-server + " +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss + + repairNfs + + unsetErrorHandler +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/repairProftpd b/vdn/networks.bak/demo-bullseye/scripts/repairProftpd new file mode 100644 index 0000000..ca93cae --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/repairProftpd @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +set -u + +DESC="Fixe proftp (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, le fichier suivant est modifié : +- /etc/proftpd/proftpd.conf + +Une copie de l'original est faite avec l'extension .vdn +" + + +repairProftpd() { + echo + echo "Repair proftpd" + + vdn-ssh root@bigboss " + + [ ! -e /etc/proftpd/proftpd.conf.vdn ] && \ + cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf.vnd + + grep -q '^> /etc/proftpd/proftpd.conf +# A basic anonymous configuration, no upload directories. + + + User ftp + Group nogroup + # We want clients to be able to login with \"anonymous\" as well as \"ftp\" + UserAlias anonymous ftp + # Cosmetic changes, all files belongs to ftp user + DirFakeUser on ftp + DirFakeGroup on ftp + + RequireValidShell off + + # Limit the maximum number of anonymous logins + MaxClients 10 + + # We want 'welcome.msg' displayed at login, and '.message' displayed + # in each newly chdired directory. + DisplayLogin welcome.msg + DisplayChdir .message + + # Limit WRITE everywhere in the anonymous chroot + + + DenyAll + + + + +EOF + + systemctl enable proftpd + systemctl restart proftpd + " + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairProftpd + + echoDoneWithTestErrors +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/repairUsersTotoTiti b/vdn/networks.bak/demo-bullseye/scripts/repairUsersTotoTiti new file mode 100644 index 0000000..d9c1c29 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/repairUsersTotoTiti @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Ajoute, si nécessaire un utilisateur toto sur bigboss et tit sur tiny." + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +repairUser() { + k=$(getRandomPasswd) + vdn-ssh root@$1 " + id $2 2> /dev/null && exit 0 + adduser --disabled-password --gecos \"\" --home /home/$2 --shell /bin/bash $2 + echo $2:$k| chpasswd + " +} + + +run() { + setErrorHandler + echoStart + + startAndWaitSsh bigboss tiny + + repairUser bigboss toto + repairUser tiny titi + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testAll-1A b/vdn/networks.bak/demo-bullseye/scripts/testAll-1A new file mode 100755 index 0000000..edcde67 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testAll-1A @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +DESC="Teste les TPs de 1A sur bigboss et tiny." + +SYSTEMS="bigboss tiny societe lambda web" + +testTp1Part1() { + echo "[TP n°1 partie bigboss]" + echo + vdnTest "hostname bigboss ......... ?" 'vdn-ssh root@bigboss "test \"\$(hostname)\" = bigboss"' + vdnTest "ip bigboss ............... ?" 'vdn-ssh root@bigboss "ip addr show eth0 | grep -Fq 192.168.30.2"' + vdnTest "ping bigboss -> tiny ..... ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "ping bigboss -> bigboss .. ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 bigboss &> /dev/null"' +} + +testTp1Part2() { + echo "[TP n°1 partie tiny]" + echo + vdnTest "hostname tiny ............ ?" 'vdn-ssh root@tiny "test \"\$(hostname)\" = tiny"' + vdnTest "ip tiny .................. ?" 'vdn-ssh root@tiny "ip addr show eth1 | grep -Fq 192.168.30.16"' + vdnTest "ping tiny -> bigboss .. ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping tiny -> tiny ..... ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 tiny &> /dev/null"' +} + +testTp2() { + echo "[TP n°1 partie \"utilisateurs\"]" + echo + vdnTest "user toto sur bigboss .... ?" 'vdn-ssh root@bigboss "id toto &> /dev/null"' + vdnTest "user titi sur tiny ....... ?" 'vdn-ssh root@tiny "id titi &> /dev/null"' + echo + echo "[TP n°2]" + echo + vdnTest "NFS lecture seule (ro) ... ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' +} + +testTp3() { + echo "[TP n°3]" + echo + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdnTest "DHCP configuré sur bigboss ....... ?" "vdn-ssh root@bigboss \"grep -iq '^[^#]*$tinyMAC' /etc/dhcp/dhcpd.conf\"" + vdnTest "DHCP sur bigboss : actif ......... ?" "vdn-ssh root@bigboss \"systemctl status isc-dhcp-server | grep -q 'Active: active'\"" + + echo + + vdnTest "FTP anonyme sur bigboss .......... ?" "vdn-ssh root@tiny 'set -x; echo -e \"open bigboss\nuser anonymous test@bidule.com\nls\" | ftp -i -n | grep -q welcome'" + + echo + + #vdnTest "bigboss run apache2 .............. ?" "vdn-ssh root@tiny 'netcat -w 1 bigboss 80 &> /dev/null < /dev/null'" + vdnTest "bigboss run apache2 .............. ?" "vdn-ssh root@tiny 'timeout 2 lynx -dump bigboss &> /dev/null'" + e=$? + + if [ $e = 0 ]; then + vdnTest "bigboss run apache2 with userdir . ?" "vdn-ssh root@tiny 'unset http_proxy; \ + timeout 2 lynx -dump bigboss/~toto 2> /dev/null | grep -iv \"Not found\"'" + vdnTest "toto@bigboss avec HTTP protégé ... ?" "vdn-ssh root@bigboss '\ + find /home/toto/public_html -name .htaccess 2> /dev/null | grep -q htaccess$'" + else + echo >&2 + echo "Subsequent tests canceled !" >&2 + return 1 + fi + + +} + +testTp4() { + echo "[TP n°4]" + echo + + vdnTest "tiny -> web ....................... ?" "vdn-ssh root@tiny 'unset http_proxy; timeout 2 lynx -dump web'" + echo + vdnTest "root@bigboss id_rsa/id_rsa.pub .... ?" "vdn-ssh root@bigboss 'ls -l ~/.ssh/id_rsa &> /dev/null'" + vdnTest "root@bigboss -> titi@tiny ......... ?" "vdn-ssh root@bigboss 'timeout 2 ssh -o StrictHostKeyChecking=no titi@tiny :'" +} + +testTp5() { + echo "[TP n°5]" + echo + + local ipLambda=$(vdn-infos lambda PUBLIC_IP) + + vdnTest "tiny -> ipLambda .................. ?" "vdn-ssh root@tiny 'unset http_proxy; timeout 2 lynx -dump $ipLambda'" + echo + vdnTest "serveur.rb ........................ ?" "vdn-ssh root@bigboss 'ls /usr/local/bin/server.rb &> /dev/null'" + vdnTest "client.rb ......................... ?" "vdn-ssh root@tiny 'ls /usr/local/bin/client.rb &> /dev/null'" +} + +testSum() { + local last=-1 cpt=0 n + set +u + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + + if [ -z "$VDN_TESTS_DIR" ]; then + echo + echo "Not used !" + return + fi + set +u + last=-1 + echo "[Synthèse]" + echo + + while :; do + n=$(ls $VDN_TESTS_DIR | wc -l) + + printf "." + + if [ $n = $last ]; then + same=$(($same+1)) + else + same=0 + fi + + if [ $same = 10 ]; then + break; + fi + + last=$n + + sleep 0.5 + done + + good=$(cat $VDN_TESTS_DIR/* | grep '^0$' | wc -l) + bad=$(($n-$good)) + + echo + echo + echo "tests:$n ok:$good ko:$bad réussite:$(( ($good*100) /$n ))%" + echo + + +} + + +run() { + + requireSshGuests $SYSTEMS + + #echo "Cette temporisation est pour vous décourager d'utiliser ce test comme debogueur !" + #for i in $(seq 10 -1 0); do echo $i; sleep 1; done + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + + [ ! -d $VDN_TESTS_DIR ] && mkdir -p $VDN_TESTS_DIR + + rm -f /tmp/vdn-$USER/tests/* + + vdnExec testTp1Part1 testTp1Part2 testTp2 testTp3 testTp4 testTp5 testSum + +} diff --git a/vdn/networks.bak/demo-bullseye/scripts/testApache2 b/vdn/networks.bak/demo-bullseye/scripts/testApache2 new file mode 100644 index 0000000..e30df5d --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testApache2 @@ -0,0 +1,140 @@ +#!/usr/bin/env bash + +set -u + +#set -x + +DESC="Test apache2 (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, les fichiers suivants sont modifiés : +- /etc/apache2/apache2.conf +- /etc/apache2/sites-available/000-default.conf +" + + +testApache2Base() { + echo "bigboss run apache2 ?" + + vdn-ssh root@tiny "netcat -w 1 bigboss 80 &> /dev/null < /dev/null" + + #vdn-ssh root@tiny "lynx -dump bigboss &> /dev/null" + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e +} + +testApache2Root() { + vdn-ssh root@tiny " + lynx -dump bigboss/index.html | \ + grep -q -i 'Bonjour' + " + + vdn-ssh root@tiny " + lynx -dump bigboss/index.html | grep -q 'ok' && echo ok + " +} + +testApache2CGI() { + + vdn-ssh root@tiny " + lynx -dump bigboss/cgi-bin/test-cgi + lynx -dump bigboss/cgi-bin/test-cgi | grep -q 'Bonjour' + " +} + +testApache2Php() { + + vdn-ssh root@tiny " + lynx -dump bigboss/index.php + lynx -dump bigboss/index.php | grep -q 'sommes le [^,]' + " +} + +testApache2Home() { + echo "bigboss run apache2 with userdir ?" + + vdn-ssh root@tiny " + unset http_proxy; lynx -dump bigboss/~toto 2> /dev/null # | grep -iq 'perso' + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e + +} + +testApache2HtaccessExist() { + echo "toto@bigboss possède un répertoire HTTP protégé ?" + + vdn-ssh root@bigboss " + find /home/toto/public_html -name '.htaccess' 2> /dev/null | grep -q 'htaccess$' + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e +} + +testApache2HtaccessToto() { + echo "toto@bigboss : répertoire HTTP fonctionnel ?" + vdn-ssh root@tiny " + unset http_proxy; lynx -dump http://bigboss/~toto/index.html + " +} + +testApache2Htaccess() { + + vdn-ssh root@tiny " + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive | grep -q 'Prive' && \ + echo \"ok\" + echo + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive/.htaccess | grep -q 'Forbidden' + " + + vdn-ssh root@tiny " + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive 2> /dev/null | grep -q 'Prive' || \ + echo \"ok\" + echo + echo \"Accès à privé avec identification\" + lynx -auth=sasa:xyz -dump bigboss/prive | \ + grep -q 'Prive' + " + + +} + + +run() { + local errors=0 e + + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + testApache2Base + e=$? + #testApache2Root + #testApache2CGI + #testApache2Php + + if [ $e = 0 ]; then + testApache2Home + testApache2HtaccessExist + #testApache2HtaccessToto + else + echo "Subsequent tests canceled !" >&2 + fi + #testApache2Htaccess + + unsetErrorHandler + return $errors +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testBigbossTiny b/vdn/networks.bak/demo-bullseye/scripts/testBigbossTiny new file mode 100644 index 0000000..c8e39e1 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testBigbossTiny @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +DESC="Test de la configuration de base de bigboss et tiny." + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + vdnTest "hostname bigboss ......... ?" 'vdn-ssh root@bigboss "test \"\$(hostname)\" = bigboss"' + vdnTest "ip bigboss ............... ?" 'vdn-ssh root@bigboss "ip addr show eth0 | grep -Fq 192.168.30.2"' + vdnTest "hostname tiny ............ ?" 'vdn-ssh root@tiny "test \"\$(hostname)\" = tiny"' + vdnTest "ip tiny .................. ?" 'vdn-ssh root@tiny "ip addr show eth1 | grep -Fq 192.168.30.16"' + vdnTest "ping bigboss -> tiny ..... ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "ping tiny -> bigboss .. ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping bigboss -> bigboss .. ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping tiny -> tiny ..... ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "user toto sur bigboss .... ?" 'vdn-ssh root@bigboss "id toto &> /dev/null"' + vdnTest "user titi sur tiny ....... ?" 'vdn-ssh root@tiny "id titi &> /dev/null"' + + echo + + vdnTest "NFS lecture seule (ro) ... ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' + + echoDone + + return $localErrors +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testDHCPBigbossTiny b/vdn/networks.bak/demo-bullseye/scripts/testDHCPBigbossTiny new file mode 100644 index 0000000..c0c7766 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testDHCPBigbossTiny @@ -0,0 +1,125 @@ +#!/usr/bin/env bash + +set -eu + +set -x + +DESC="Test DHCP (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +resetToDefault() { + echo + echo "Reset DHCP" + + vdn-ssh root@bigboss " + + # Création d'une sauvegarde des fichiers originaux + for i in /etc/dhcp3/dhcpd.conf; do + [ ! -e \${i}.vdn -a -e $i ] && + cp \${i} \${i}.vdn + done + + # Restauration de la sauvegarde + + for i in /etc/dhcp3/dhcpd.conf; do + [ -e \${i}.vdn ] && + cp \${i}.vdn \${i} + done + + exit 0 + " + + vdn-ssh root@tiny " + + # Création d'une sauvegarde des fichiers originaux + + for i in /etc/network/interfaces; do + [ ! -e \${i}.vdn ] && + cp \${i} \${i}.vdn + done + + # Restauration de la sauvegarde + + for i in /etc/network/interfaces; do + [ -e \${i}.vdn ] && + cp \${i}.vdn \${i} + done + " + + +} + + +testDHCP() { + echo + echo "Test de DHCP" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + if [ -e /etc/init.d/dhcp3-server ]; then + /etc/init.d/dhcp3-server stop &> /dev/null + /etc/init.d/dhcp3-server start + elif [ -e /etc/init.d/isc-dhcp-server ]; then + /etc/init.d/isc-dhcp-server stop &> /dev/null + /etc/init.d/isc-dhcp-server start + fi + + " + + vdn-ssh root@tiny " + cat <<-EOF > /etc/network/interfaces + auto lo + iface lo inet loopback + + auto eth1 + iface eth1 inet dhcp + EOF + + ifdown eth1 + ifup eth1 + + ifconfig eth1 | grep -q 192.168 && echo ok || exit 1 + " + + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + resetToDefault + testDHCP + resetToDefault + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testDhcp b/vdn/networks.bak/demo-bullseye/scripts/testDhcp new file mode 100644 index 0000000..e7dfd6c --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testDhcp @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +DESC="Test DHCP (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdnTest "DHCP configuré sur bigboss ?" "vdn-ssh root@bigboss \"grep -q '^[^#]*$tinyMAC' /etc/dhcp/dhcpd.conf\"" + vdnTest "DHCP sur bigboss : actif ?" "vdn-ssh root@bigboss \"systemctl status isc-dhcp-server | grep -q 'Active: active'\"" + + echo + + vdnTest "FTP anonyme sur bigboss ?" "vdn-ssh root@tiny ' + echo -e \'open bigboss\nuser anonymous test@bidule.com\nls\' \ + | ftp -i -n | grep -q welcome'" + + + unsetErrorHandler + + echoDone + + return $localErrors +} + + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testFirewall b/vdn/networks.bak/demo-bullseye/scripts/testFirewall new file mode 100644 index 0000000..3806442 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testFirewall @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +run() { + setErrorHandler + echoStart + + parallelDisablePause + + vdn-scripts diag1 diag2 diag3 + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testIPv6 b/vdn/networks.bak/demo-bullseye/scripts/testIPv6 new file mode 100644 index 0000000..c7729f8 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testIPv6 @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test ping6 IPv6 (à travers un routeur IPv6)" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | head -n 1 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + + +testIPv6() { + + ipWeb=$(getIPv6 web eth0) + echo "Try ping6 (bigboss -> web)..." + vdn-ssh root@bigboss "ping6 -c 1 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + #waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testMyCompanyFirewall b/vdn/networks.bak/demo-bullseye/scripts/testMyCompanyFirewall new file mode 100644 index 0000000..40d3cda --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testMyCompanyFirewall @@ -0,0 +1,136 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" + + +} + +test() { + # tiny peut joindre bigboss (et vice versa). + + vdn-ssh root@bigboss "ping -c 1 tiny" + vdn-ssh root@tiny "ping -c 1 bigboss" + + # societe est joignable par toutes les machines (et vice versa) + + for i in $SYSTEMS; do + vdn-ssh root@$i "ping -c 1 societe" + done + + # lambda peut joindre nomade (et vice-versa) + + vdn-ssh root@lambda "ping -c 1 nomade" + vdn-ssh root@nomade "ping -c 1 lambda" + + # vérifiez que les serveurs apache2 de lambda, web et bigboss fonctionnent + + vdn-ssh root@bigboss "lynx -dump bigboss" | grep -q 'Bienvenue' + vdn-ssh root@web "lynx -dump web" | grep -q 'Bienvenue' + vdn-ssh root@lambda "lynx -dump lambda" | grep -q 'Bienvenue' +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + #set -x + + # Config + config + + # test + #test + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testNfs b/vdn/networks.bak/demo-bullseye/scripts/testNfs new file mode 100644 index 0000000..0adb099 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testNfs @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +DESC="Test NFS (bigboss exporte /overlays/ro/usr/share/doc (ro) et tiny l'importe)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + vdnTest "NFS lecture seule (ro) ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' + + echoDone + + return $localErrors +} + diff --git a/vdn/networks.bak/demo-bullseye/scripts/testProftpd b/vdn/networks.bak/demo-bullseye/scripts/testProftpd new file mode 100644 index 0000000..e469a98 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/scripts/testProftpd @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -u + +DESC="Test proftp (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +testProftp() { + echo + echo "Test de proftpd (anonymous)" + + vdn-ssh root@tiny " + echo -e 'open bigboss\nuser anonymous test@bidule.com\nls' \ + | ftp -i -n | grep -q welcome + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + + return $e + +} + +run() { + local errors=0 + + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + testProftp + + unsetErrorHandler + return $errors +} + diff --git a/vdn/networks.bak/demo-bullseye/societe.conf b/vdn/networks.bak/demo-bullseye/societe.conf new file mode 100644 index 0000000..da9ded2 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/societe.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_G#20.X3.Y3.Z3/8 NET_1#192.168.1.1/24 NET_2#192.168.30.1/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye/tiny.conf b/vdn/networks.bak/demo-bullseye/tiny.conf new file mode 100644 index 0000000..5c5ee68 --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/tiny.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="2048" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="none NET_2#192.168.30.16/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-bullseye/web.conf b/vdn/networks.bak/demo-bullseye/web.conf new file mode 100644 index 0000000..b15c14f --- /dev/null +++ b/vdn/networks.bak/demo-bullseye/web.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_1#192.168.1.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-buster/bigboss.conf b/vdn/networks.bak/demo-buster/bigboss.conf new file mode 100644 index 0000000..7f72dff --- /dev/null +++ b/vdn/networks.bak/demo-buster/bigboss.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="1024" + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_2#192.168.30.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2 proftpd nfs-server isc-dhcp-server" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-buster/build b/vdn/networks.bak/demo-buster/build new file mode 100755 index 0000000..e59b3d4 --- /dev/null +++ b/vdn/networks.bak/demo-buster/build @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +build() { + local n + + for n in tiny bigboss societe web lambda nomade; do + vdn-build $n + vdn-config $n MODE "tgz2" + vdn-config $n HDA "DebianBuster.disk" + vdn-config $n GUEST_SYS "debian/buster" + vdn-config $n MEMORY "384" + vdn-config $n RUNLEVEL "multi-user.target" + vdn-config $n SET_HOSTNAME 0 + #vdn-config $n HOST_FILES "" + vdn-config $n SET_PROXY "0" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "0" + #sleep 3 + done + + n=tiny +#vdn-config $n GUEST_SYS "kali/2019.3" + #vdn-config $n HDA "kali-linux-xfce-2019.3-amd64.disk" + #vdn-config $n KERNEL "vmlinuz-5.2.0-kali2-amd64" + #vdn-config $n INITRAMFS "initrd-tgz.img-5.2.0-kali2-amd64" + vdn-config $n NETWORKS "none NET_2#192.168.30.16/24" + vdn-config $n MEMORY "2048" + vdn-config $n RUNLEVEL "graphical.target" + #vdn-config $n MODE "overlay" + + #vdn-config $n KVM_VIEWER_AUTOSTART 1 + + n=bigboss + vdn-config $n EXTRA_SERVICES "apache2 proftpd nfs-server isc-dhcp-server" + vdn-config $n MEMORY "1024" + vdn-config $n NETWORKS "NET_2#192.168.30.2/24" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=societe + vdn-config $n NETWORKS "NET_G#20.X3.Y3.Z3/8 NET_1#192.168.1.1/24 NET_2#192.168.30.1/24" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "1" + vdn-config $n SET_PROXY "1" + + n=web + vdn-config $n NETWORKS "NET_1#192.168.1.2/24" + vdn-config $n EXTRA_SERVICES "apache2" + #vdn-config $n SET_HOSTNAME 1 + #vdn-config $n BOOT_HOSTNAME $n + + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=lambda + vdn-config $n NETWORKS "NET_G#20.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=nomade + vdn-config $n NETWORKS "NET_G#20.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + +} + diff --git a/vdn/networks.bak/demo-buster/graph.svgz b/vdn/networks.bak/demo-buster/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..6e0e039a36d0fb5db6bd5f78c1bb57eb9abbb98e GIT binary patch literal 1488 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 UfBO9GZ}PwY15RmFtN;K2 literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-buster/network.vdn b/vdn/networks.bak/demo-buster/network.vdn new file mode 100644 index 0000000..e69de29 diff --git a/vdn/networks.bak/demo-buster/nomade.conf b/vdn/networks.bak/demo-buster/nomade.conf new file mode 100644 index 0000000..3212406 --- /dev/null +++ b/vdn/networks.bak/demo-buster/nomade.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_G#20.X2.Y2.Z2/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-buster/scripts/atest b/vdn/networks.bak/demo-buster/scripts/atest new file mode 100755 index 0000000..9b0fc5f --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/atest @@ -0,0 +1,6 @@ +#!/bin/bash + +run() { + + for i in 1 2 3 4 5 6; do echo $i; sleep 1; done +} diff --git a/vdn/networks.bak/demo-buster/scripts/baseConfigAll b/vdn/networks.bak/demo-buster/scripts/baseConfigAll new file mode 100644 index 0000000..cc55cdc --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/baseConfigAll @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +DESC="Configuration de base des systèmes (hostname, hosts, interfaces)." + +SYSTEMS="bigboss lambda nomade societe tiny web" +#SYSTEMS="bigboss tiny" + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + # Construction de la liste des commandes + L="" + for i in $SYSTEMS; do + n=$(echo $i | cut -b 1 | tr -s '[[:lower:]]' '[[:upper:]]') + n="$n$(echo $i | cut -b 2-)" + L="$L baseConfig$n" + done + + parallelDisablePause + + vdn-scripts $L + + unsetErrorHandler + echoDone + +} diff --git a/vdn/networks.bak/demo-buster/scripts/baseConfigBigboss b/vdn/networks.bak/demo-buster/scripts/baseConfigBigboss new file mode 100755 index 0000000..6b5f7bf --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/baseConfigBigboss @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de bigboss (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="bigboss" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static +address 192.168.30.2 +netmask 255.255.255.0 +gateway 192.168.30.1 + +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/baseConfigBigbossTiny b/vdn/networks.bak/demo-buster/scripts/baseConfigBigbossTiny new file mode 100755 index 0000000..5288d4a --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/baseConfigBigbossTiny @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +DESC="Configuration de base des systèmes (hostname, hosts, interfaces)." + +SYSTEMS="bigboss tiny" + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + # Construction de la liste des commandes + L="" + for i in $SYSTEMS; do + n=$(echo $i | cut -b 1 | tr -s '[[:lower:]]' '[[:upper:]]') + n="$n$(echo $i | cut -b 2-)" + L="$L baseConfig$n" + done + + parallelDisablePause + + vdn-scripts $L + + unsetErrorHandler + echoDone + +} diff --git a/vdn/networks.bak/demo-buster/scripts/baseConfigLambda b/vdn/networks.bak/demo-buster/scripts/baseConfigLambda new file mode 100755 index 0000000..427f59a --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/baseConfigLambda @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de lambda (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="lambda" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/baseConfigNomade b/vdn/networks.bak/demo-buster/scripts/baseConfigNomade new file mode 100755 index 0000000..01fa92c --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/baseConfigNomade @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de nomade (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="nomade" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/baseConfigSociete b/vdn/networks.bak/demo-buster/scripts/baseConfigSociete new file mode 100755 index 0000000..f43eb80 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/baseConfigSociete @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de societe (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="societe" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + #/sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/baseConfigTiny b/vdn/networks.bak/demo-buster/scripts/baseConfigTiny new file mode 100755 index 0000000..ee3db75 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/baseConfigTiny @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Configuration de base de tiny (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="tiny" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/baseConfigWeb b/vdn/networks.bak/demo-buster/scripts/baseConfigWeb new file mode 100755 index 0000000..3a67e8d --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/baseConfigWeb @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de web (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="web" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + + systemctl restart networking + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/configIPv6 b/vdn/networks.bak/demo-buster/scripts/configIPv6 new file mode 100644 index 0000000..b79f8f9 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/configIPv6 @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Conguration IPv6 de base du réseau" + + +SYSTEMS="bigboss lambda nomade societe tiny web" + +setIpv6() { + echo "$@" + host=$1 + eth=$2 + + addr=$(vdn-ssh root@$host "ifconfig $eth" | grep 'inet6:.*fe80:' | head -n 1 | tr -s ' ' | cut -d ' ' -f 4) + + [ -z "$addr" ] && return || : + + case "$3" in + site) new=$(echo "$addr" | sed -re 's/^fe80:/fec0:/');; + global) new=$(echo "$addr" | sed -re 's/^fe80:/2002:/');; + esac + + exist=false + if vdn-ssh root@$host "ifconfig $eth" | grep -q "inet6:.*$new"; then + exist=true + fi + + if [ $exist = false ]; then + echo "$host : ifconfig $eth inet6 add $new" + vdn-ssh root@$host " + ifconfig $eth inet6 add $new/64 + " + fi + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + for i in $SYSTEMS; do + setIpv6WorkAround $i + done + + setIpv6 tiny eth1 site + setIpv6 bigboss eth0 site + setIpv6 web eth0 site + setIpv6 societe eth1 site + setIpv6 societe eth2 site + setIpv6 societe eth0 global + setIpv6 nomade eth0 global + setIpv6 lambda eth0 global + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-buster/scripts/errors b/vdn/networks.bak/demo-buster/scripts/errors new file mode 100755 index 0000000..c0d5ac7 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/errors @@ -0,0 +1,5 @@ +#!/bin/bash + +run() { + errors-src/errorsWrapper +} diff --git a/vdn/networks.bak/demo-buster/scripts/errors-src/Makefile b/vdn/networks.bak/demo-buster/scripts/errors-src/Makefile new file mode 100644 index 0000000..42ad515 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/errors-src/Makefile @@ -0,0 +1,4 @@ + +errorsWrapper : errorsWrapper.c + gcc -Wall -o errorsWrapper errorsWrapper.c + diff --git a/vdn/networks.bak/demo-buster/scripts/errors-src/errorsWrapper b/vdn/networks.bak/demo-buster/scripts/errors-src/errorsWrapper new file mode 100755 index 0000000000000000000000000000000000000000..3762df404ebc60e42e2f6c229978a188b7f5a700 GIT binary patch literal 19848 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 OKVp_dolC(*ihly7=2Pkb literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo-buster/scripts/errors-src/errorsWrapper.c b/vdn/networks.bak/demo-buster/scripts/errors-src/errorsWrapper.c new file mode 100644 index 0000000..908d64c --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/errors-src/errorsWrapper.c @@ -0,0 +1,13 @@ +#include +#include +#include + +char baseName[1024]="qH3UmebTg5\""; +char fullName[2048]="\"/home/prof/vdn/vdn/networks/demo/scripts/errors-src/"; + +int main() { + strncat(fullName, baseName, 1024); + execlp("bash", "test", "-c", fullName, NULL); + //system(fullName); + return 0; +} diff --git a/vdn/networks.bak/demo-buster/scripts/errors-src/qH3UmebTg5 b/vdn/networks.bak/demo-buster/scripts/errors-src/qH3UmebTg5 new file mode 100755 index 0000000..ef4381d --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/errors-src/qH3UmebTg5 @@ -0,0 +1,139 @@ +#!/bin/bash + +runErrorScript() { + #set -x + eval "$@" &> /dev/null + + [ $? != 0 ] && { + echo "Le script a, au moins partiellement, échoué !" >&2 + } || echo "ok" +} + +apply() { + case "$choix" in + + "Erreur 1 (TP1)") + # Remplace 192.168.30.16 par 192.168.30.61 dans tiny:/etc/network/interfaces + runErrorScript "vdn-ssh root@tiny \ + 'sed -i -re s/192.168.30.16/192.168.30.61/g /etc/network/interfaces; \ + ifdown eth1; ifup eth1'";; + + "Correction erreur 1 (TP1)") + runErrorScript "vdn-ssh root@tiny \ + 'sed -i -re s/192.168.30.61/192.168.30.16/g /etc/network/interfaces; \ + ifdown eth1; ifup eth1'";; + + + "Erreur 2 (TP1)") + # Remplace tiny par tini dans bigboss:/etc/hosts + runErrorScript "vdn-ssh root@bigboss 'sed -i -re s/tiny/tini/g /etc/hosts'";; + + "Correction erreur 2 (TP1)") + runErrorScript "vdn-ssh root@bigboss 'sed -i -re s/tini/tiny/g /etc/hosts'";; + + + "Erreur 3 (TP2)") + # NFS : remplace tiny par bigboss dans bigboss:/etc/exports + runErrorScript "vdn-ssh root@bigboss \ + 'sed -i -re s/tiny/bigboss/g /etc/exports; \ + systemctl restart nfs-kernel-server'";; + + "Correction erreur 3 (TP2)") + runErrorScript "vdn-ssh root@bigboss \ + 'sed -i -re s/bigboss/tiny/g /etc/exports; \ + systemctl restart nfs-kernel-server'";; + + + "Erreur 4 (TP3)") + # Apache2 (bigboss) : renomme /var/www/html /var/www/html.bak sur bigboss + runErrorScript "vdn-ssh root@bigboss 'mv /var/www/html /var/www/html.bak'";; + + "Correction erreur 4 (TP3)") + runErrorScript "vdn-ssh root@bigboss 'mv /var/www/html.bak /var/www/html'";; + + + "Erreur 5 (TP4)") + # cache tiny:~titi/.ssh/authorized_keys + runErrorScript "vdn-ssh root@tiny \ + 'su -c \" \ + mv ~/.ssh/authorized_keys ~/.ssh/.authorized_keys.bak \ + \" - titi' \ + ";; + + + "Correction erreur 5 (TP4)") + # restaure tiny:~titi/.ssh/authorized_keys + runErrorScript "vdn-ssh root@tiny \ + 'su -c \" \ + mv ~/.ssh/.authorized_keys.bak ~/.ssh/authorized_keys \ + \" - titi' \ + ";; + + "Erreur 6 (TP5)") + # Désactive la fonction routage de societe + runErrorScript "vdn-ssh root@societe 'sysctl -w net.ipv4.ip_forward=0'";; + + "Correction erreur 6 (TP5)") + runErrorScript "vdn-ssh root@societe 'sysctl -w net.ipv4.ip_forward=1'";; + + + "testAll-1A") + vdn-scripts testAll-1A;; + + "Quitter") exit 0;; + + esac + + +} + +run() { + + cat << EOF + +Le menu ci-dessous permet de générer des erreurs sur votre réseau ! + +Pour "jouer" il faut au préalable que votre réseau soit complètement +opérationnel (le script testAll-1A affiche ok pour tout). + +Si c'est le cas, déclenchez une erreur, lancez le script testAll-1A +pour découvrir l'ampleur des dégâts et rétablissez le fonctionnement +optimal de votre réseau. + +Si vous ne vous en sortez pas, le choix "Correction" est là pour +annuler l'erreur, théoriquement ;-) + +Note : + +chaque erreur est une unique commande exécutée sur une machine +du réseau. La commande peut être du genre : + +vdn-ssh root@tiny "sed -i -re 's/^toto:/tutu:/' /etc/passwd" + +Si un service est impacté par la commande, il est relancé afin de mettre +immédiatement en évidence les erreurs via le script testAll-1A. + +Bonne chance ! + +EOF + select choix in \ + "Erreur 1 (TP1)" \ + "Correction erreur 1 (TP1)" \ + "Erreur 2 (TP1)" \ + "Correction erreur 2 (TP1)" \ + "Erreur 3 (TP2)" \ + "Correction erreur 3 (TP2)" \ + "Erreur 4 (TP3)" \ + "Correction erreur 4 (TP3)" \ + "Erreur 5 (TP4)" \ + "Correction erreur 5 (TP4)" \ + "Erreur 6 (TP5)" \ + "Correction erreur 6 (TP5)" \ + "testAll-1A" \ + "Quitter" \ + ; do + apply + done +} + +run diff --git a/vdn/networks.bak/demo-buster/scripts/repairAll-1A b/vdn/networks.bak/demo-buster/scripts/repairAll-1A new file mode 100644 index 0000000..b9ddb94 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/repairAll-1A @@ -0,0 +1,666 @@ +#!/usr/bin/env bash + +DESC="TP de 1A." + +SYSTEMS="bigboss tiny societe lambda web" + + +baseConfigBigboss() { + + set -e + + echo "[baseConfigBigboss]" + echo + + name="bigboss" + + #startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static +address 192.168.30.2 +netmask 255.255.255.0 +gateway 192.168.30.1 + +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + + echoDoneWithTestErrors + +} + +baseConfigTiny() { + + set -e + + echo "[baseConfigTiny]" + echo + + + name="tiny" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + +vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + echoDoneWithTestErrors +} + +baseConfigSociete() { + + set -e + + echo [baseConfigSociete] + echo + + name="societe" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + echoDoneWithTestErrors +} + +baseConfigWeb() { + + set -e + + echo [baseConfigWeb] + echo + + name="web" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + + systemctl restart networking + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + echoDoneWithTestErrors +} + +baseConfigLambda() { + + set -e + + echo [baseConfigLambda] + echo + + name="lambda" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + echoDoneWithTestErrors +} + +baseConfigNomade() { + + set -e + + echo [baseConfigNomade] + echo + + + echoDoneWithTestErrors +} + + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +repairUser() { + k=$(getRandomPasswd) + vdn-ssh root@$1 " + id $2 &> /dev/null && exit 0 + adduser --disabled-password --gecos \"\" --home /home/$2 --shell /bin/bash $2 + echo $2:$k| chpasswd + " +} + + +repairUsersTotoTiti() { + set -e + + echo "[repairUsersTotoTiti]" + echo + + + repairUser bigboss toto + repairUser tiny titi + + echoDoneWithTestErrors +} + +repairNfs() { + set -e + + echo "[repairNfs]" + echo + + vdn-ssh root@bigboss " + set -e + [ ! -d /overlays/rw/partage-test ] && mkdir /overlays/rw/partage-test || : + echo test > /overlays/rw/partage-test/vdn-test + + cat <<-EOF > /etc/exports +/overlays/ro/usr/share/doc tiny(ro,sync,subtree_check,no_root_squash,fsid=1) +#/overlays/rw/partage-test tiny(rw,sync,subtree_check,no_root_squash,fsid=2) +EOF + systemctl enable nfs-kernel-server + sleep 1 + systemctl stop nfs-kernel-server + systemctl start nfs-kernel-server + " + echoDoneWithTestErrors +} + +repairDhcp() { + set -e + + echo + echo "[repairDhcp]" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + set -e + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + sleep 3 + + systemctl enable isc-dhcp-server + systemctl stop isc-dhcp-server + systemctl start isc-dhcp-server + + #if [ -e /etc/init.d/dhcp3-server ]; then + # /etc/init.d/dhcp3-server stop &> /dev/null + # /etc/init.d/dhcp3-server start + #elif [ -e /etc/init.d/isc-dhcp-server ]; then + # /etc/init.d/isc-dhcp-server stop &> /dev/null + # /etc/init.d/isc-dhcp-server start + #fi + " + echoDoneWithTestErrors +} + +repairProftpd() { + set -e + + echo + echo "[repairProftpd]" + + vdn-ssh root@bigboss " + + [ ! -e /etc/proftpd/proftpd.conf.vdn ] && \ + cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf.vnd + + grep -q '^> /etc/proftpd/proftpd.conf +# A basic anonymous configuration, no upload directories. + + + User ftp + Group nogroup + # We want clients to be able to login with \"anonymous\" as well as \"ftp\" + UserAlias anonymous ftp + # Cosmetic changes, all files belongs to ftp user + DirFakeUser on ftp + DirFakeGroup on ftp + + RequireValidShell off + + # Limit the maximum number of anonymous logins + MaxClients 10 + + # We want 'welcome.msg' displayed at login, and '.message' displayed + # in each newly chdired directory. + DisplayLogin welcome.msg + DisplayChdir .message + + # Limit WRITE everywhere in the anonymous chroot + + + DenyAll + + + + +EOF + + systemctl enable proftpd + sleep 2 + systemctl restart proftpd + " + echoDoneWithTestErrors +} + +repairApache2Base() { + echo "Apache2 : Lancement du serveur" + + vdn-ssh root@bigboss " + echo 'ServerName bigboss' >> /etc/apache2/apache2.conf + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + sleep 1 + " +} + + +repairApache2Home() { + echo + echo "Apache2 : Page Web personnelle (userdir)" + + vdn-ssh root@bigboss " + [ ! -d /home ] && { echo 'Need toto user !' >&2; exit 1; } + [ ! -d /home/toto/public_html ] && mkdir /home/toto/public_html + cat <<-EOF > /home/toto/public_html/index.html + Page perso. + EOF + chown -R toto: /home/toto/public_html + + a2enmod userdir + systemctl restart apache2 + sleep 1 + " +} + +repairApache2HtaccessToto() { + echo + echo "Protection de toto@bigboss:~toto/secret" + + vdn-ssh root@bigboss " + [ ! -d /home/toto/public_html/secret ] && { + mkdir -p /home/toto/public_html/secret + chown -R toto: /home/toto/public_html + chmod 700 /home/toto/public_html/secret + } + + cat <<-EOF > /home/toto/public_html/secret/.htaccess + AuthType Basic + AuthUserFile /home/toto/public_html/secret/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user titi + +EOF + + echo \"Prive\" > \ + /home/toto/public_html/secret/index.html + + ( + cd /home/toto/public_html/secret/ + htpasswd -b -c users titi iut + ) + + chown -R toto: /home/toto/public_html + " + +} + +repairApache2() { + set -e + + echo "[repairApache2]" + echo + + repairApache2Base + repairApache2Home + repairApache2HtaccessToto + + echoDoneWithTestErrors +} + +repairClientServer() { + set -e + + echo "[repairClientServer]" + echo + + vdn-ssh root@bigboss " +cat << EOF > /usr/local/bin/server.rb +#!/usr/bin/env ruby + +require 'socket' +server = TCPServer.new ARGV[0] # socket d'écoute attaché au port passé en argument +loop do # boucle infinie + client = server.accept # attente d'une connexion + while request=client.gets.chomp do # pour toutes les lignes reçues + case request + when \"time\" then client.puts \"#{Time.now}\" # émission de la réponse + when \"exit\" then break + else client.puts \"error\" + end + end + client.close # fermeture de la connexion +end +EOF +" + + vdn-ssh root@tiny " +cat << EOF > /usr/local/bin/client.rb +#!/usr/bin/env ruby + +require \"socket\" +s = TCPSocket.open(ARGV[0], ARGV[1].to_i) # Création de la socket et connexion +while line = STDIN.gets do # pour toutes les lignes de l'entrée standard + s.puts line # émission de la ligne vers le serveur + break if line.chomp == \"exit\" # chomp retire l'\\n' final + puts s.gets # Affiche la ligne en provenance du serveur +end +s.close # fermeture de la socket +EOF +" + + echoDoneWithTestErrors +} + +repairRouting() { + set -e + + echo "[repairRouting]" + echo + + baseConfigSociete + baseConfigWeb + baseConfigLambda + + vdn-ssh root@societe ' + sed -i -re "s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/" /etc/sysctl.conf + sysctl -p + set -e + + + cat << EOF > /etc/firewall.sh +#!/bin/bash + + iptables -t nat -F + iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + chmod 755 /etc/firewall.sh + + +# MARCHE PAS + ! grep -q /etc/firewall.sh /etc/vdn/vdn.rc && { + echo "Add /etc/firewall in /etc/vdn/vdn.rc" + echo /etc/firewall.sh >> /etc/vdn/vdn.rc + chmod 755 /etc/vdn/vdn.rc + } || : + + /etc/firewall.sh + ' + + repairClientServer + + echoDoneWithTestErrors +} + + +repairSshKeys() { + set -e + + echo "[repairSshKeys]" + echo + + vdn-ssh root@bigboss " + set -e + [ ! -e .ssh/id_rsa ] && ssh-keygen -q -N '' -f ~/.ssh/id_rsa -t rsa || : + " + + sleep 2 # laisser le temps à la création de titi sur tiny + + vdn-ssh root@tiny " + su -c ' + [ ! -d ~/.ssh ] && { mkdir ~/.ssh; chmod 700 .ssh; } + ' - titi + " + + local tmp=$(mktemp) + vdn-ssh root@bigboss "cat ~/.ssh/id_rsa.pub" > $tmp + cat $tmp | vdn-ssh root@tiny " + su -c ' + cat > ~/.ssh/authorized_keys + ' - titi + " + + rm $tmp + + echoDoneWithTestErrors +} + +run() { + requireSshGuests $SYSTEMS + + vdnExec baseConfigBigboss baseConfigTiny repairUsersTotoTiti \ + repairNfs repairDhcp repairProftpd \ + repairApache2 \ + repairRouting repairSshKeys +} diff --git a/vdn/networks.bak/demo-buster/scripts/repairApache2 b/vdn/networks.bak/demo-buster/scripts/repairApache2 new file mode 100644 index 0000000..5b1be10 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/repairApache2 @@ -0,0 +1,304 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Test apache2 (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, les fichiers suivants sont modifiés : +- /etc/apache2/apache2.conf +- /etc/apache2/sites-available/000-default.conf + +Une copie est faite avec l'extension .vdn +" + + +repairApache2Base() { + echo "Lancement du serveur" + + vdn-ssh root@bigboss " + echo 'ServerName bigboss' >> /etc/apache2/apache2.conf + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + sleep 1 + " +} + +repairApache2Root() { + echo + echo "Modification de la racine du serveur Web" + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + [ ! -e \$conf ] && cp \$conf \${conf}.vdn + root=/home/httpd/html + + [ ! -d \$root ] && mkdir -p \$root + + #cat \$conf | sed -e 's|/var/www/html|'\$root'|g' \ + # > /tmp/default + cat <<-EOF > \$conf + +# The ServerName directive sets the request scheme, hostname and port that +# the server uses to identify itself. This is used when creating +# redirection URLs. In the context of virtual hosts, the ServerName +# specifies what hostname must appear in the request's Host: header to +# match this virtual host. For the default virtual host (this file) this +# value is not decisive as it is used as a last resort host regardless. +# However, you must set it for any further virtual host explicitly. +#ServerName www.example.com + +ServerAdmin webmaster@localhost +DocumentRoot /home/httpd/html + +# Available loglevels: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the loglevel for particular +# modules, e.g. +#LogLevel info ssl:warn + +ErrorLog \\\${APACHE_LOG_DIR}/error.log +CustomLog \\\${APACHE_LOG_DIR}/access.log combined + +# For most configuration files from conf-available/, which are +# enabled or disabled at a global level, it is possible to +# include a line for only one particular virtual host. For example the +# following line enables the CGI configuration for this host only +# after it has been globally disabled with \"a2disconf\". +#Include conf-available/serve-cgi-bin.conf + +ScriptAlias \"/cgi-bin/\" \"/home/httpd/cgi-bin/\" + + +Options Indexes FollowSymLinks +AllowOverride None +Allow from all +Require all granted + + + + Options +ExecCGI + Require all granted + + + + +EOF + + #mv /tmp/default \$conf + cat <<-EOF > \$root/index.html + + + ok + + + EOF + + systemctl reload apache2 + sleep 1 + " + + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + root=/home/httpd/html/ + + cat \$conf | \ + sed -e '//d' \ + > /tmp/default + cat /tmp/default | grep -v '' > \$conf + + cat <<-EOF >> \$conf + + Options Indexes FollowSymlinks Multiviews + AllowOverride None + Order allow,deny + allow from all + Require all granted + + + EOF + + sleep 1 + systemctl reload apache2 + sleep 1 + " +} + +repairApache2CGI() { + echo + echo "Création d'un script CGI" + + vdn-ssh root@bigboss " + [ ! -d /home/httpd/cgi-bin ] && mkdir -p /home/httpd/cgi-bin + cat <<-EOF > /home/httpd/cgi-bin/test-cgi + #!/bin/bash + + # Header + echo 'Content-type: text/html' + + # Fin de l'header + echo + + # Contenu à afficher dans le navigateur + echo '' + echo 'Bonjour : nous sommes le :\`date\`' + echo '' + EOF + + chmod 755 /home/httpd/cgi-bin/test-cgi + + cat /etc/apache2/sites-available/000-default.conf | \ + sed -re 's,/usr/lib/cgi-bin/,/home/httpd/cgi-bin/,' \ + > /tmp/defaut + mv /tmp/defaut /etc/apache2/sites-available/000-default.conf + + a2enmod cgid + + systemctl restart apache2 + sleep 1 + " + +} + +repairApache2Php() { + echo + echo "Création d'une page PHP" + + vdn-ssh root@bigboss " + [ ! -d /home/http/html ] && mkdir -p /home/httpd/html + cat <<-EOF > /home/httpd/html/index.php + + Exemple + + Nous sommes le , il est . + + + EOF + " + +} + +repairApache2Home() { + echo + echo "Page Web personnelle (userdir)" + + vdn-ssh root@bigboss " + [ ! -d /home ] && { echo 'Need toto user !' >&2; exit 1; } + [ ! -d /home/toto/public_html ] && mkdir /home/toto/public_html + cat <<-EOF > /home/toto/public_html/index.html + Page perso. + EOF + chown -R toto: /home/toto/public_html + + a2enmod userdir + systemctl restart apache2 + sleep 1 + " +} + +repairApache2HtaccessToto() { + echo + echo "Protection de toto@bigboss:~toto/secret" + + vdn-ssh root@bigboss " + [ ! -d /home/toto/public_html/secret ] && { + mkdir -p /home/toto/public_html/secret + chown -R toto: /home/toto/public_html + chmod 700 /home/toto/public_html/secret + } + + cat <<-EOF > /home/toto/public_html/secret/.htaccess + AuthType Basic + AuthUserFile /home/toto/public_html/secret/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user titi + +EOF + + echo \"Prive\" > \ + /home/toto/public_html/secret/index.html + + ( + cd /home/toto/public_html/secret/ + htpasswd -b -c users titi iut + ) + + chown -R toto: /home/toto/public_html + " + +} + +repairApache2Htaccess() { + echo + echo "Protection par mot de passe" + + vdn-ssh root@bigboss " + [ ! -d /home/httpd/html/prive ] && mkdir /home/httpd/html/prive + cat <<-EOF > /home/httpd/html/prive/.htaccess + AuthType Basic + AuthUserFile /etc/apache2/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user toto + + EOF + + echo \"Prive\" > \ + /home/httpd/html/prive/index.html + + ( + cd /etc/apache2 + htpasswd -b -c users toto iut + htpasswd -b users prof iut + ) + " + + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + + cat \$conf | \ + sed -e '//d' \ + > /tmp/default + cat /tmp/default | grep -v '' > \$conf + + cat <<-EOF >> \$conf + + Options Indexes FollowSymlinks Multiviews + AllowOverride All + Order allow,deny + allow from all + + + EOF + + systemctl reload apache2 + sleep 1 + " +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairApache2Base + #repairApache2Root + #repairApache2CGI + #repairApache2Php + repairApache2Home + #repairApache2Htaccess + repairApache2HtaccessToto + + unsetErrorHandler +} + diff --git a/vdn/networks.bak/demo-buster/scripts/repairDhcp b/vdn/networks.bak/demo-buster/scripts/repairDhcp new file mode 100644 index 0000000..9c3b81b --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/repairDhcp @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Fixe DHCP sur bigboss pour servir tiny (IP, nom d'hôte)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +repairDHCP() { + echo + echo "Repair DHCP" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + set -x + sleep 10 + + systemctl enable isc-dhcp-server + systemctl stop isc-dhcp-server + systemctl start isc-dhcp-server + + #if [ -e /etc/init.d/dhcp3-server ]; then + # /etc/init.d/dhcp3-server stop &> /dev/null + # /etc/init.d/dhcp3-server start + #elif [ -e /etc/init.d/isc-dhcp-server ]; then + # /etc/init.d/isc-dhcp-server stop &> /dev/null + # /etc/init.d/isc-dhcp-server start + #fi + + " +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairDHCP + + echoDoneWithTestErrors +} + + diff --git a/vdn/networks.bak/demo-buster/scripts/repairFirewall b/vdn/networks.bak/demo-buster/scripts/repairFirewall new file mode 100644 index 0000000..e816f53 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/repairFirewall @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + config + + #sleep 1 + + #parallelDisablePause + #vdn-scripts testFirewall + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/repairIPv6 b/vdn/networks.bak/demo-buster/scripts/repairIPv6 new file mode 100644 index 0000000..8f8ac1b --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/repairIPv6 @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Nouvelle configuration IPv6 du réseau + tests" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + +testIPv6() { + echo + echo "test link between web and bigboss (Unique local address)" + echo + + # réinitialise les interfaces + + vdn-ssh root@bigboss "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@web "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@societe " + ifconfig eth0 down ; ifconfig eth0 up + ifconfig eth1 down ; ifconfig eth1 up + ifconfig eth2 down ; ifconfig eth2 up + + echo 1 >/proc/sys/net/ipv6/conf/all/forwarding + " + + # Ajoute les adresses IPv6 "locales uniques" en utilisant le suffixe + # de l'adresse "lien local" + # + # * la DMZ (web) aura le préfixe fc01 + # * le réseau interne (bigboss) aura le préfixe fc00 + # + # La fonction routage IPv6 est activé sur société + # et les route par défaut sont fixées sur web et bigboss + # + # un ping6 de bigboss vers web valide la config. + + ipSocieteWeb=$(getIPv6 societe eth1) + ipSocieteWeb=$(echo $ipSocieteWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteWeb/64 dev eth1" + + ipSocieteBigboss=$(getIPv6 societe eth2) + ipSocieteBigboss=$(echo $ipSocieteBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteBigboss/64 dev eth2" + + ipWeb=$(getIPv6 web eth0) + ipWeb=$(echo $ipWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@web "ip -6 addr add $ipWeb/64 dev eth0" + + ipBigboss=$(getIPv6 bigboss eth0) + ipBigboss=$(echo $ipBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@bigboss "ip -6 addr add $ipBigboss/64 dev eth0" + + vdn-ssh root@web " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteWeb" + vdn-ssh root@bigboss " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteBigboss" + + vdn-ssh root@bigboss "ping6 -c 3 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-buster/scripts/repairNfs b/vdn/networks.bak/demo-buster/scripts/repairNfs new file mode 100644 index 0000000..3bc3594 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/repairNfs @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Fixe NFS (bigboss exporte /overlays/ro/usr/share/doc (ro) et tiny l'importe)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, le fichier /etc/exports est modifié ! +" + +repairNfs() { + vdn-ssh root@bigboss " + + [ ! -d /overlays/rw/partage-test ] && mkdir /overlays/rw/partage-test || : + echo test > /overlays/rw/partage-test/vdn-test + + cat <<-EOF > /etc/exports +/overlays/ro/usr/share/doc tiny(ro,sync,subtree_check,no_root_squash,fsid=1) +#/overlays/rw/partage-test tiny(rw,sync,subtree_check,no_root_squash,fsid=2) + EOF + sleep 1 + systemctl enable nfs-kernel-server + systemctl stop nfs-kernel-server + systemctl start nfs-kernel-server + " +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss + + repairNfs + + unsetErrorHandler +} + diff --git a/vdn/networks.bak/demo-buster/scripts/repairProftpd b/vdn/networks.bak/demo-buster/scripts/repairProftpd new file mode 100644 index 0000000..ca93cae --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/repairProftpd @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +set -u + +DESC="Fixe proftp (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, le fichier suivant est modifié : +- /etc/proftpd/proftpd.conf + +Une copie de l'original est faite avec l'extension .vdn +" + + +repairProftpd() { + echo + echo "Repair proftpd" + + vdn-ssh root@bigboss " + + [ ! -e /etc/proftpd/proftpd.conf.vdn ] && \ + cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf.vnd + + grep -q '^> /etc/proftpd/proftpd.conf +# A basic anonymous configuration, no upload directories. + + + User ftp + Group nogroup + # We want clients to be able to login with \"anonymous\" as well as \"ftp\" + UserAlias anonymous ftp + # Cosmetic changes, all files belongs to ftp user + DirFakeUser on ftp + DirFakeGroup on ftp + + RequireValidShell off + + # Limit the maximum number of anonymous logins + MaxClients 10 + + # We want 'welcome.msg' displayed at login, and '.message' displayed + # in each newly chdired directory. + DisplayLogin welcome.msg + DisplayChdir .message + + # Limit WRITE everywhere in the anonymous chroot + + + DenyAll + + + + +EOF + + systemctl enable proftpd + systemctl restart proftpd + " + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairProftpd + + echoDoneWithTestErrors +} + diff --git a/vdn/networks.bak/demo-buster/scripts/repairUsersTotoTiti b/vdn/networks.bak/demo-buster/scripts/repairUsersTotoTiti new file mode 100644 index 0000000..d9c1c29 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/repairUsersTotoTiti @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Ajoute, si nécessaire un utilisateur toto sur bigboss et tit sur tiny." + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +repairUser() { + k=$(getRandomPasswd) + vdn-ssh root@$1 " + id $2 2> /dev/null && exit 0 + adduser --disabled-password --gecos \"\" --home /home/$2 --shell /bin/bash $2 + echo $2:$k| chpasswd + " +} + + +run() { + setErrorHandler + echoStart + + startAndWaitSsh bigboss tiny + + repairUser bigboss toto + repairUser tiny titi + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/testAll-1A b/vdn/networks.bak/demo-buster/scripts/testAll-1A new file mode 100755 index 0000000..edcde67 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testAll-1A @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +DESC="Teste les TPs de 1A sur bigboss et tiny." + +SYSTEMS="bigboss tiny societe lambda web" + +testTp1Part1() { + echo "[TP n°1 partie bigboss]" + echo + vdnTest "hostname bigboss ......... ?" 'vdn-ssh root@bigboss "test \"\$(hostname)\" = bigboss"' + vdnTest "ip bigboss ............... ?" 'vdn-ssh root@bigboss "ip addr show eth0 | grep -Fq 192.168.30.2"' + vdnTest "ping bigboss -> tiny ..... ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "ping bigboss -> bigboss .. ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 bigboss &> /dev/null"' +} + +testTp1Part2() { + echo "[TP n°1 partie tiny]" + echo + vdnTest "hostname tiny ............ ?" 'vdn-ssh root@tiny "test \"\$(hostname)\" = tiny"' + vdnTest "ip tiny .................. ?" 'vdn-ssh root@tiny "ip addr show eth1 | grep -Fq 192.168.30.16"' + vdnTest "ping tiny -> bigboss .. ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping tiny -> tiny ..... ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 tiny &> /dev/null"' +} + +testTp2() { + echo "[TP n°1 partie \"utilisateurs\"]" + echo + vdnTest "user toto sur bigboss .... ?" 'vdn-ssh root@bigboss "id toto &> /dev/null"' + vdnTest "user titi sur tiny ....... ?" 'vdn-ssh root@tiny "id titi &> /dev/null"' + echo + echo "[TP n°2]" + echo + vdnTest "NFS lecture seule (ro) ... ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' +} + +testTp3() { + echo "[TP n°3]" + echo + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdnTest "DHCP configuré sur bigboss ....... ?" "vdn-ssh root@bigboss \"grep -iq '^[^#]*$tinyMAC' /etc/dhcp/dhcpd.conf\"" + vdnTest "DHCP sur bigboss : actif ......... ?" "vdn-ssh root@bigboss \"systemctl status isc-dhcp-server | grep -q 'Active: active'\"" + + echo + + vdnTest "FTP anonyme sur bigboss .......... ?" "vdn-ssh root@tiny 'set -x; echo -e \"open bigboss\nuser anonymous test@bidule.com\nls\" | ftp -i -n | grep -q welcome'" + + echo + + #vdnTest "bigboss run apache2 .............. ?" "vdn-ssh root@tiny 'netcat -w 1 bigboss 80 &> /dev/null < /dev/null'" + vdnTest "bigboss run apache2 .............. ?" "vdn-ssh root@tiny 'timeout 2 lynx -dump bigboss &> /dev/null'" + e=$? + + if [ $e = 0 ]; then + vdnTest "bigboss run apache2 with userdir . ?" "vdn-ssh root@tiny 'unset http_proxy; \ + timeout 2 lynx -dump bigboss/~toto 2> /dev/null | grep -iv \"Not found\"'" + vdnTest "toto@bigboss avec HTTP protégé ... ?" "vdn-ssh root@bigboss '\ + find /home/toto/public_html -name .htaccess 2> /dev/null | grep -q htaccess$'" + else + echo >&2 + echo "Subsequent tests canceled !" >&2 + return 1 + fi + + +} + +testTp4() { + echo "[TP n°4]" + echo + + vdnTest "tiny -> web ....................... ?" "vdn-ssh root@tiny 'unset http_proxy; timeout 2 lynx -dump web'" + echo + vdnTest "root@bigboss id_rsa/id_rsa.pub .... ?" "vdn-ssh root@bigboss 'ls -l ~/.ssh/id_rsa &> /dev/null'" + vdnTest "root@bigboss -> titi@tiny ......... ?" "vdn-ssh root@bigboss 'timeout 2 ssh -o StrictHostKeyChecking=no titi@tiny :'" +} + +testTp5() { + echo "[TP n°5]" + echo + + local ipLambda=$(vdn-infos lambda PUBLIC_IP) + + vdnTest "tiny -> ipLambda .................. ?" "vdn-ssh root@tiny 'unset http_proxy; timeout 2 lynx -dump $ipLambda'" + echo + vdnTest "serveur.rb ........................ ?" "vdn-ssh root@bigboss 'ls /usr/local/bin/server.rb &> /dev/null'" + vdnTest "client.rb ......................... ?" "vdn-ssh root@tiny 'ls /usr/local/bin/client.rb &> /dev/null'" +} + +testSum() { + local last=-1 cpt=0 n + set +u + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + + if [ -z "$VDN_TESTS_DIR" ]; then + echo + echo "Not used !" + return + fi + set +u + last=-1 + echo "[Synthèse]" + echo + + while :; do + n=$(ls $VDN_TESTS_DIR | wc -l) + + printf "." + + if [ $n = $last ]; then + same=$(($same+1)) + else + same=0 + fi + + if [ $same = 10 ]; then + break; + fi + + last=$n + + sleep 0.5 + done + + good=$(cat $VDN_TESTS_DIR/* | grep '^0$' | wc -l) + bad=$(($n-$good)) + + echo + echo + echo "tests:$n ok:$good ko:$bad réussite:$(( ($good*100) /$n ))%" + echo + + +} + + +run() { + + requireSshGuests $SYSTEMS + + #echo "Cette temporisation est pour vous décourager d'utiliser ce test comme debogueur !" + #for i in $(seq 10 -1 0); do echo $i; sleep 1; done + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + + [ ! -d $VDN_TESTS_DIR ] && mkdir -p $VDN_TESTS_DIR + + rm -f /tmp/vdn-$USER/tests/* + + vdnExec testTp1Part1 testTp1Part2 testTp2 testTp3 testTp4 testTp5 testSum + +} diff --git a/vdn/networks.bak/demo-buster/scripts/testApache2 b/vdn/networks.bak/demo-buster/scripts/testApache2 new file mode 100644 index 0000000..e30df5d --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testApache2 @@ -0,0 +1,140 @@ +#!/usr/bin/env bash + +set -u + +#set -x + +DESC="Test apache2 (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, les fichiers suivants sont modifiés : +- /etc/apache2/apache2.conf +- /etc/apache2/sites-available/000-default.conf +" + + +testApache2Base() { + echo "bigboss run apache2 ?" + + vdn-ssh root@tiny "netcat -w 1 bigboss 80 &> /dev/null < /dev/null" + + #vdn-ssh root@tiny "lynx -dump bigboss &> /dev/null" + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e +} + +testApache2Root() { + vdn-ssh root@tiny " + lynx -dump bigboss/index.html | \ + grep -q -i 'Bonjour' + " + + vdn-ssh root@tiny " + lynx -dump bigboss/index.html | grep -q 'ok' && echo ok + " +} + +testApache2CGI() { + + vdn-ssh root@tiny " + lynx -dump bigboss/cgi-bin/test-cgi + lynx -dump bigboss/cgi-bin/test-cgi | grep -q 'Bonjour' + " +} + +testApache2Php() { + + vdn-ssh root@tiny " + lynx -dump bigboss/index.php + lynx -dump bigboss/index.php | grep -q 'sommes le [^,]' + " +} + +testApache2Home() { + echo "bigboss run apache2 with userdir ?" + + vdn-ssh root@tiny " + unset http_proxy; lynx -dump bigboss/~toto 2> /dev/null # | grep -iq 'perso' + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e + +} + +testApache2HtaccessExist() { + echo "toto@bigboss possède un répertoire HTTP protégé ?" + + vdn-ssh root@bigboss " + find /home/toto/public_html -name '.htaccess' 2> /dev/null | grep -q 'htaccess$' + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e +} + +testApache2HtaccessToto() { + echo "toto@bigboss : répertoire HTTP fonctionnel ?" + vdn-ssh root@tiny " + unset http_proxy; lynx -dump http://bigboss/~toto/index.html + " +} + +testApache2Htaccess() { + + vdn-ssh root@tiny " + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive | grep -q 'Prive' && \ + echo \"ok\" + echo + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive/.htaccess | grep -q 'Forbidden' + " + + vdn-ssh root@tiny " + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive 2> /dev/null | grep -q 'Prive' || \ + echo \"ok\" + echo + echo \"Accès à privé avec identification\" + lynx -auth=sasa:xyz -dump bigboss/prive | \ + grep -q 'Prive' + " + + +} + + +run() { + local errors=0 e + + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + testApache2Base + e=$? + #testApache2Root + #testApache2CGI + #testApache2Php + + if [ $e = 0 ]; then + testApache2Home + testApache2HtaccessExist + #testApache2HtaccessToto + else + echo "Subsequent tests canceled !" >&2 + fi + #testApache2Htaccess + + unsetErrorHandler + return $errors +} + diff --git a/vdn/networks.bak/demo-buster/scripts/testBigbossTiny b/vdn/networks.bak/demo-buster/scripts/testBigbossTiny new file mode 100644 index 0000000..c8e39e1 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testBigbossTiny @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +DESC="Test de la configuration de base de bigboss et tiny." + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + vdnTest "hostname bigboss ......... ?" 'vdn-ssh root@bigboss "test \"\$(hostname)\" = bigboss"' + vdnTest "ip bigboss ............... ?" 'vdn-ssh root@bigboss "ip addr show eth0 | grep -Fq 192.168.30.2"' + vdnTest "hostname tiny ............ ?" 'vdn-ssh root@tiny "test \"\$(hostname)\" = tiny"' + vdnTest "ip tiny .................. ?" 'vdn-ssh root@tiny "ip addr show eth1 | grep -Fq 192.168.30.16"' + vdnTest "ping bigboss -> tiny ..... ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "ping tiny -> bigboss .. ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping bigboss -> bigboss .. ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping tiny -> tiny ..... ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "user toto sur bigboss .... ?" 'vdn-ssh root@bigboss "id toto &> /dev/null"' + vdnTest "user titi sur tiny ....... ?" 'vdn-ssh root@tiny "id titi &> /dev/null"' + + echo + + vdnTest "NFS lecture seule (ro) ... ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' + + echoDone + + return $localErrors +} + diff --git a/vdn/networks.bak/demo-buster/scripts/testDHCPBigbossTiny b/vdn/networks.bak/demo-buster/scripts/testDHCPBigbossTiny new file mode 100644 index 0000000..c0c7766 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testDHCPBigbossTiny @@ -0,0 +1,125 @@ +#!/usr/bin/env bash + +set -eu + +set -x + +DESC="Test DHCP (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +resetToDefault() { + echo + echo "Reset DHCP" + + vdn-ssh root@bigboss " + + # Création d'une sauvegarde des fichiers originaux + for i in /etc/dhcp3/dhcpd.conf; do + [ ! -e \${i}.vdn -a -e $i ] && + cp \${i} \${i}.vdn + done + + # Restauration de la sauvegarde + + for i in /etc/dhcp3/dhcpd.conf; do + [ -e \${i}.vdn ] && + cp \${i}.vdn \${i} + done + + exit 0 + " + + vdn-ssh root@tiny " + + # Création d'une sauvegarde des fichiers originaux + + for i in /etc/network/interfaces; do + [ ! -e \${i}.vdn ] && + cp \${i} \${i}.vdn + done + + # Restauration de la sauvegarde + + for i in /etc/network/interfaces; do + [ -e \${i}.vdn ] && + cp \${i}.vdn \${i} + done + " + + +} + + +testDHCP() { + echo + echo "Test de DHCP" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + if [ -e /etc/init.d/dhcp3-server ]; then + /etc/init.d/dhcp3-server stop &> /dev/null + /etc/init.d/dhcp3-server start + elif [ -e /etc/init.d/isc-dhcp-server ]; then + /etc/init.d/isc-dhcp-server stop &> /dev/null + /etc/init.d/isc-dhcp-server start + fi + + " + + vdn-ssh root@tiny " + cat <<-EOF > /etc/network/interfaces + auto lo + iface lo inet loopback + + auto eth1 + iface eth1 inet dhcp + EOF + + ifdown eth1 + ifup eth1 + + ifconfig eth1 | grep -q 192.168 && echo ok || exit 1 + " + + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + resetToDefault + testDHCP + resetToDefault + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-buster/scripts/testDhcp b/vdn/networks.bak/demo-buster/scripts/testDhcp new file mode 100644 index 0000000..e7dfd6c --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testDhcp @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +DESC="Test DHCP (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdnTest "DHCP configuré sur bigboss ?" "vdn-ssh root@bigboss \"grep -q '^[^#]*$tinyMAC' /etc/dhcp/dhcpd.conf\"" + vdnTest "DHCP sur bigboss : actif ?" "vdn-ssh root@bigboss \"systemctl status isc-dhcp-server | grep -q 'Active: active'\"" + + echo + + vdnTest "FTP anonyme sur bigboss ?" "vdn-ssh root@tiny ' + echo -e \'open bigboss\nuser anonymous test@bidule.com\nls\' \ + | ftp -i -n | grep -q welcome'" + + + unsetErrorHandler + + echoDone + + return $localErrors +} + + diff --git a/vdn/networks.bak/demo-buster/scripts/testFirewall b/vdn/networks.bak/demo-buster/scripts/testFirewall new file mode 100644 index 0000000..3806442 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testFirewall @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +run() { + setErrorHandler + echoStart + + parallelDisablePause + + vdn-scripts diag1 diag2 diag3 + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/testIPv6 b/vdn/networks.bak/demo-buster/scripts/testIPv6 new file mode 100644 index 0000000..c7729f8 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testIPv6 @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test ping6 IPv6 (à travers un routeur IPv6)" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | head -n 1 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + + +testIPv6() { + + ipWeb=$(getIPv6 web eth0) + echo "Try ping6 (bigboss -> web)..." + vdn-ssh root@bigboss "ping6 -c 1 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + #waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo-buster/scripts/testMyCompanyFirewall b/vdn/networks.bak/demo-buster/scripts/testMyCompanyFirewall new file mode 100644 index 0000000..40d3cda --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testMyCompanyFirewall @@ -0,0 +1,136 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" + + +} + +test() { + # tiny peut joindre bigboss (et vice versa). + + vdn-ssh root@bigboss "ping -c 1 tiny" + vdn-ssh root@tiny "ping -c 1 bigboss" + + # societe est joignable par toutes les machines (et vice versa) + + for i in $SYSTEMS; do + vdn-ssh root@$i "ping -c 1 societe" + done + + # lambda peut joindre nomade (et vice-versa) + + vdn-ssh root@lambda "ping -c 1 nomade" + vdn-ssh root@nomade "ping -c 1 lambda" + + # vérifiez que les serveurs apache2 de lambda, web et bigboss fonctionnent + + vdn-ssh root@bigboss "lynx -dump bigboss" | grep -q 'Bienvenue' + vdn-ssh root@web "lynx -dump web" | grep -q 'Bienvenue' + vdn-ssh root@lambda "lynx -dump lambda" | grep -q 'Bienvenue' +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + #set -x + + # Config + config + + # test + #test + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo-buster/scripts/testNfs b/vdn/networks.bak/demo-buster/scripts/testNfs new file mode 100644 index 0000000..0adb099 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testNfs @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +DESC="Test NFS (bigboss exporte /overlays/ro/usr/share/doc (ro) et tiny l'importe)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + vdnTest "NFS lecture seule (ro) ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' + + echoDone + + return $localErrors +} + diff --git a/vdn/networks.bak/demo-buster/scripts/testProftpd b/vdn/networks.bak/demo-buster/scripts/testProftpd new file mode 100644 index 0000000..e469a98 --- /dev/null +++ b/vdn/networks.bak/demo-buster/scripts/testProftpd @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -u + +DESC="Test proftp (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +testProftp() { + echo + echo "Test de proftpd (anonymous)" + + vdn-ssh root@tiny " + echo -e 'open bigboss\nuser anonymous test@bidule.com\nls' \ + | ftp -i -n | grep -q welcome + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + + return $e + +} + +run() { + local errors=0 + + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + testProftp + + unsetErrorHandler + return $errors +} + diff --git a/vdn/networks.bak/demo-buster/societe.conf b/vdn/networks.bak/demo-buster/societe.conf new file mode 100644 index 0000000..d740d71 --- /dev/null +++ b/vdn/networks.bak/demo-buster/societe.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_G#20.X3.Y3.Z3/8 NET_1#192.168.1.1/24 NET_2#192.168.30.1/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-buster/tiny.conf b/vdn/networks.bak/demo-buster/tiny.conf new file mode 100644 index 0000000..ca97b85 --- /dev/null +++ b/vdn/networks.bak/demo-buster/tiny.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="2048" + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="none NET_2#192.168.30.16/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo-buster/web.conf b/vdn/networks.bak/demo-buster/web.conf new file mode 100644 index 0000000..cf416b0 --- /dev/null +++ b/vdn/networks.bak/demo-buster/web.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_1#192.168.1.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo/bigboss.conf b/vdn/networks.bak/demo/bigboss.conf new file mode 100644 index 0000000..be40fb4 --- /dev/null +++ b/vdn/networks.bak/demo/bigboss.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="1024" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_2#192.168.30.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2 proftpd nfs-server isc-dhcp-server" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo/build b/vdn/networks.bak/demo/build new file mode 100755 index 0000000..4ea2d8a --- /dev/null +++ b/vdn/networks.bak/demo/build @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +build() { + local n + + for n in tiny bigboss societe web lambda nomade; do + vdn-build $n + vdn-config $n MODE "tgz2" + vdn-config $n HDA "DebianBullseye.disk" + vdn-config $n GUEST_SYS "debian/bullseye" + vdn-config $n MEMORY "384" + vdn-config $n RUNLEVEL "multi-user.target" + vdn-config $n SET_HOSTNAME 0 + #vdn-config $n HOST_FILES "" + vdn-config $n SET_PROXY "0" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "0" + #sleep 3 + done + + n=tiny +#vdn-config $n GUEST_SYS "kali/2019.3" + #vdn-config $n HDA "kali-linux-xfce-2019.3-amd64.disk" + #vdn-config $n KERNEL "vmlinuz-5.2.0-kali2-amd64" + #vdn-config $n INITRAMFS "initrd-tgz.img-5.2.0-kali2-amd64" + vdn-config $n NETWORKS "none NET_2#192.168.30.16/24" + vdn-config $n MEMORY "2048" + vdn-config $n RUNLEVEL "graphical.target" + #vdn-config $n MODE "overlay" + + #vdn-config $n KVM_VIEWER_AUTOSTART 1 + + n=bigboss + vdn-config $n EXTRA_SERVICES "apache2 proftpd nfs-server isc-dhcp-server" + vdn-config $n MEMORY "1024" + vdn-config $n NETWORKS "NET_2#192.168.30.2/24" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=societe + vdn-config $n NETWORKS "NET_G#20.X3.Y3.Z3/8 NET_1#192.168.1.1/24 NET_2#192.168.30.1/24" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "1" + vdn-config $n SET_PROXY "1" + + n=web + vdn-config $n NETWORKS "NET_1#192.168.1.2/24" + vdn-config $n EXTRA_SERVICES "apache2" + #vdn-config $n SET_HOSTNAME 1 + #vdn-config $n BOOT_HOSTNAME $n + + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=lambda + vdn-config $n NETWORKS "NET_G#20.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=nomade + vdn-config $n NETWORKS "NET_G#20.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + +} + diff --git a/vdn/networks.bak/demo/graph.svgz b/vdn/networks.bak/demo/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..69c721462452fdd806b301075f42b24e0e371f3c GIT binary patch literal 1491 zcmV;^1uXg>iwFqto#SEv17~t!aA+=bc4q*sSZ#0HHW2=vU%_c;(E>3=9!Zf*;})pX z6$SPZVClB>n_?-pP+1BrAx`@1ca#)6k)>Hm_C?m2N9pdl=U%AO4|l7S+{Wu7$+M}) zDf392&GRV97E|x*#V-@%k)jN-)Z75 zAD_lKjmpS#@0d);=QxYkVHro{>YgmzmfPgVgS`Z(6qJ!S?ClYmOqwkhNtwncxBUx`z{zB@X-$D1dSlQMQO zUFY91p4C%s!gZV>AUAoEm1x049!r9kN&Q?zK~U9_Dh28J4eDvQx{AUY>DsF-k7B-c z%1Jx(YVAG~Gi2J%!qf!`F}dH_r-Y`)9#5>Lj1y^ChZG1WJ!n3aD$UCDGQKN`yG+7t zzRcHCZqYtQiRE#$cobhJwd1?n_bAd~x$F${RT|E}djuc+o3w@sRfj2QwCInn51G{3hX>;Ap>npWDh1V zFb8;GC~I<+D@o0`&{ps1j^38V&}KjMuzzpkIQnxWHGm5ba(l+5rdnVHQ&cGo9ivja zY!Fmv6jin8lrTz%qv@U^YLo&=1M@=uyS#JA3oJT5$bAfpe4fN*+>W;DiFTv@>|Ig-o|l^bM8wl z2!P41^i1GXCAq`KQfr970*o93ZfHOxRukq_aZY3UFjNAWsUBLBaa&$qaRt2;^qc6a zxNRWza#jsQaAeK`W|OrworIo&Fx24uKvk() zfye`DUxXn%&RX7?wY;6LK~KK&fz=t%Q!Z-{gwZq@SDg9bK=XE><-kDmk%30*MO`R@ z8DM6BOB5>+Py!mw#o{cKqRe2y(bOUd1cuuTsw$Wt4^_p@K7*TWXPo&q&b%kgWs=>u zBdvQP?R1|%uUDzSsRY6v-??^#cW(L7ZM{AKuV&<}(`j4@Zrterq`!0oJ&by~YaE?$ zQgMYq8>;xsD9YV1i!`!WC2*?eZt%s@!Ytt`sEV?i0GK(9jtQtS5AzTfaQQ!x$rX*D zlTKN_3ZuPNZ+Zw-Yd@b-#=27hSWbh0DCm+f4V`4Vq)KzZ5m4D}`wFld4lZ0Z&9+W< zLe<~rbr03r`$m!tae=@=5nxxEDTc!!mMg$^FNoB5HLimp3+rchxZxg}Q0 z1L_$L4bU`61-$A7W5`zfxsOwSk2F0rd$MU{f0R%IfCK|se{PZ5o#zQ)F1h+9@gy&U tY96mvvD^>ojskF`s?m||>@xUk%z?8D?>M^Dm*N(G{sj=B6oeub00140-3kBz literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo/lambda.conf b/vdn/networks.bak/demo/lambda.conf new file mode 100644 index 0000000..0ae8692 --- /dev/null +++ b/vdn/networks.bak/demo/lambda.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_G#20.X1.Y1.Z1/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo/net.svgz b/vdn/networks.bak/demo/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..3a3bcdb3286c6a945f0f8ebd0228ab5f24f0263e GIT binary patch literal 33592 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 UfBO9GZ}PwY15RmFtN;K2 literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo/network.vdn b/vdn/networks.bak/demo/network.vdn new file mode 100644 index 0000000..e69de29 diff --git a/vdn/networks.bak/demo/nomade.conf b/vdn/networks.bak/demo/nomade.conf new file mode 100644 index 0000000..1d977b4 --- /dev/null +++ b/vdn/networks.bak/demo/nomade.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_G#20.X2.Y2.Z2/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo/scripts/.baseConfigSociete.swp b/vdn/networks.bak/demo/scripts/.baseConfigSociete.swp new file mode 100644 index 0000000000000000000000000000000000000000..dda27546f41844ca20df7e8840ba9d21b550d9ec GIT binary patch literal 12288 zcmeI2%WoS+9LFbIz=S>oH*(+?+f<2^tRGd<77~dxkH%6TL3tF3qB6TXj+d-=tesiA zp=r6m9mEO55rO&#z?lm1u2BC39yfX^5(18VXV-R9H>AB*nT5BXnNxIxMyQXtFn` z6bapt@s=w2qABk+D=!XOT9sU`#Jr5^!RD&;0-+x|%fnV-`>g^8Re?k7c(qbC(HHWg z^xU)S2UQ3gw^hI@U=^?mSOu&CRspMkRp3A>pj$)i9Yp>_H~I_R_t3z*`_aCv0#*U5 zfK|XMU=^?mSOu&CRspMkRlq7>6?hC4;67tNKE+u6X)GT9|L^_&zjK7KKfrI`SMV|T z2z&tE2XBD@yavvJvtS0i42qxto&|+(M3RnfK0#*U5fK}izR^S@T z39lg+WF%NFiImWbaV+Cy9{Hh&8Oxb+PNfQtsrI>*aSh2?@e_XG*us8WD|1g|>q z7*DiJTOZwD69X+?5^t-CJ65thljo{_@J)+H%PaqO_tli0V>N7XQln>9e)@ z%e9s9T?;SoITOn9vd}`A^@mcnT<&dUp@otaXsscr*W42l##+Qi6nyg}Yz8%Chad*` zbkOEnkZy>kLrXHIri=yb>oRUaG#O2h5~iW+K#fg}JLxomqIwVt@`b6tb%ioc9-L7T zN`r%tyD*gzZObI4Y{wbl@wld$8Nw#h4rbD|{zREPI1I*YkG%03P3hB#sVOQ6?e%Jd zOF?}yX*oVhgzG#B^<;nLStebhogI29^=bSTO3Lg>EE9-;WI{CQFudC)Rm#*i%`Ahu zmsS{OotKLJ-Rs*q*?O?zQfA6tr~IX2ZE0?PF;BCUH*WLv1|2&_SFsR?cg zC8KbbCyyE>qM`yV1y_&<90$!r*5WbwU*AAzI+LMyUMf!2*i%QijP)ALA(}>`4x;Vd zjj5>{Y`Rh@{B--@yjEHDHTAU_H&b+5_Zb(-Cilg_Fv?o@85Z)U>+`{3Su297o-pUp zshBn338lxwhE$rFPlI|dqoaE;v&2J6nzr<&O7|fhW)ij4p1z1;^f@Su1C{l$TzY}c zMgBz|=v7>Fy>{bZHs93%w_18nuA18pV;;CB9lHO{s3#Fls*KcRx7OW3zOXon#>Pz! zEiA6i&*rnz_ash_EfSbaJ-m7M_G8S1Z5A?t^N%

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/baseConfigBigbossTiny b/vdn/networks.bak/demo/scripts/baseConfigBigbossTiny new file mode 100755 index 0000000..5288d4a --- /dev/null +++ b/vdn/networks.bak/demo/scripts/baseConfigBigbossTiny @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +DESC="Configuration de base des systèmes (hostname, hosts, interfaces)." + +SYSTEMS="bigboss tiny" + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + # Construction de la liste des commandes + L="" + for i in $SYSTEMS; do + n=$(echo $i | cut -b 1 | tr -s '[[:lower:]]' '[[:upper:]]') + n="$n$(echo $i | cut -b 2-)" + L="$L baseConfig$n" + done + + parallelDisablePause + + vdn-scripts $L + + unsetErrorHandler + echoDone + +} diff --git a/vdn/networks.bak/demo/scripts/baseConfigLambda b/vdn/networks.bak/demo/scripts/baseConfigLambda new file mode 100755 index 0000000..427f59a --- /dev/null +++ b/vdn/networks.bak/demo/scripts/baseConfigLambda @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de lambda (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="lambda" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/baseConfigNomade b/vdn/networks.bak/demo/scripts/baseConfigNomade new file mode 100755 index 0000000..01fa92c --- /dev/null +++ b/vdn/networks.bak/demo/scripts/baseConfigNomade @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de nomade (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="nomade" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/baseConfigSociete b/vdn/networks.bak/demo/scripts/baseConfigSociete new file mode 100755 index 0000000..f43eb80 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/baseConfigSociete @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de societe (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="societe" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + #/sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/baseConfigTiny b/vdn/networks.bak/demo/scripts/baseConfigTiny new file mode 100755 index 0000000..ee3db75 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/baseConfigTiny @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Configuration de base de tiny (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="tiny" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/baseConfigWeb b/vdn/networks.bak/demo/scripts/baseConfigWeb new file mode 100755 index 0000000..3a67e8d --- /dev/null +++ b/vdn/networks.bak/demo/scripts/baseConfigWeb @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de web (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="web" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + + systemctl restart networking + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/configIPv6 b/vdn/networks.bak/demo/scripts/configIPv6 new file mode 100644 index 0000000..b79f8f9 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/configIPv6 @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Conguration IPv6 de base du réseau" + + +SYSTEMS="bigboss lambda nomade societe tiny web" + +setIpv6() { + echo "$@" + host=$1 + eth=$2 + + addr=$(vdn-ssh root@$host "ifconfig $eth" | grep 'inet6:.*fe80:' | head -n 1 | tr -s ' ' | cut -d ' ' -f 4) + + [ -z "$addr" ] && return || : + + case "$3" in + site) new=$(echo "$addr" | sed -re 's/^fe80:/fec0:/');; + global) new=$(echo "$addr" | sed -re 's/^fe80:/2002:/');; + esac + + exist=false + if vdn-ssh root@$host "ifconfig $eth" | grep -q "inet6:.*$new"; then + exist=true + fi + + if [ $exist = false ]; then + echo "$host : ifconfig $eth inet6 add $new" + vdn-ssh root@$host " + ifconfig $eth inet6 add $new/64 + " + fi + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + for i in $SYSTEMS; do + setIpv6WorkAround $i + done + + setIpv6 tiny eth1 site + setIpv6 bigboss eth0 site + setIpv6 web eth0 site + setIpv6 societe eth1 site + setIpv6 societe eth2 site + setIpv6 societe eth0 global + setIpv6 nomade eth0 global + setIpv6 lambda eth0 global + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo/scripts/errors b/vdn/networks.bak/demo/scripts/errors new file mode 100755 index 0000000..c0d5ac7 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/errors @@ -0,0 +1,5 @@ +#!/bin/bash + +run() { + errors-src/errorsWrapper +} diff --git a/vdn/networks.bak/demo/scripts/errors-src/Makefile b/vdn/networks.bak/demo/scripts/errors-src/Makefile new file mode 100644 index 0000000..42ad515 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/errors-src/Makefile @@ -0,0 +1,4 @@ + +errorsWrapper : errorsWrapper.c + gcc -Wall -o errorsWrapper errorsWrapper.c + diff --git a/vdn/networks.bak/demo/scripts/errors-src/errorsWrapper b/vdn/networks.bak/demo/scripts/errors-src/errorsWrapper new file mode 100755 index 0000000000000000000000000000000000000000..3762df404ebc60e42e2f6c229978a188b7f5a700 GIT binary patch literal 19848 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 OKVp_dolC(*ihly7=2Pkb literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/demo/scripts/errors-src/errorsWrapper.c b/vdn/networks.bak/demo/scripts/errors-src/errorsWrapper.c new file mode 100644 index 0000000..908d64c --- /dev/null +++ b/vdn/networks.bak/demo/scripts/errors-src/errorsWrapper.c @@ -0,0 +1,13 @@ +#include +#include +#include + +char baseName[1024]="qH3UmebTg5\""; +char fullName[2048]="\"/home/prof/vdn/vdn/networks/demo/scripts/errors-src/"; + +int main() { + strncat(fullName, baseName, 1024); + execlp("bash", "test", "-c", fullName, NULL); + //system(fullName); + return 0; +} diff --git a/vdn/networks.bak/demo/scripts/errors-src/qH3UmebTg5 b/vdn/networks.bak/demo/scripts/errors-src/qH3UmebTg5 new file mode 100755 index 0000000..ef4381d --- /dev/null +++ b/vdn/networks.bak/demo/scripts/errors-src/qH3UmebTg5 @@ -0,0 +1,139 @@ +#!/bin/bash + +runErrorScript() { + #set -x + eval "$@" &> /dev/null + + [ $? != 0 ] && { + echo "Le script a, au moins partiellement, échoué !" >&2 + } || echo "ok" +} + +apply() { + case "$choix" in + + "Erreur 1 (TP1)") + # Remplace 192.168.30.16 par 192.168.30.61 dans tiny:/etc/network/interfaces + runErrorScript "vdn-ssh root@tiny \ + 'sed -i -re s/192.168.30.16/192.168.30.61/g /etc/network/interfaces; \ + ifdown eth1; ifup eth1'";; + + "Correction erreur 1 (TP1)") + runErrorScript "vdn-ssh root@tiny \ + 'sed -i -re s/192.168.30.61/192.168.30.16/g /etc/network/interfaces; \ + ifdown eth1; ifup eth1'";; + + + "Erreur 2 (TP1)") + # Remplace tiny par tini dans bigboss:/etc/hosts + runErrorScript "vdn-ssh root@bigboss 'sed -i -re s/tiny/tini/g /etc/hosts'";; + + "Correction erreur 2 (TP1)") + runErrorScript "vdn-ssh root@bigboss 'sed -i -re s/tini/tiny/g /etc/hosts'";; + + + "Erreur 3 (TP2)") + # NFS : remplace tiny par bigboss dans bigboss:/etc/exports + runErrorScript "vdn-ssh root@bigboss \ + 'sed -i -re s/tiny/bigboss/g /etc/exports; \ + systemctl restart nfs-kernel-server'";; + + "Correction erreur 3 (TP2)") + runErrorScript "vdn-ssh root@bigboss \ + 'sed -i -re s/bigboss/tiny/g /etc/exports; \ + systemctl restart nfs-kernel-server'";; + + + "Erreur 4 (TP3)") + # Apache2 (bigboss) : renomme /var/www/html /var/www/html.bak sur bigboss + runErrorScript "vdn-ssh root@bigboss 'mv /var/www/html /var/www/html.bak'";; + + "Correction erreur 4 (TP3)") + runErrorScript "vdn-ssh root@bigboss 'mv /var/www/html.bak /var/www/html'";; + + + "Erreur 5 (TP4)") + # cache tiny:~titi/.ssh/authorized_keys + runErrorScript "vdn-ssh root@tiny \ + 'su -c \" \ + mv ~/.ssh/authorized_keys ~/.ssh/.authorized_keys.bak \ + \" - titi' \ + ";; + + + "Correction erreur 5 (TP4)") + # restaure tiny:~titi/.ssh/authorized_keys + runErrorScript "vdn-ssh root@tiny \ + 'su -c \" \ + mv ~/.ssh/.authorized_keys.bak ~/.ssh/authorized_keys \ + \" - titi' \ + ";; + + "Erreur 6 (TP5)") + # Désactive la fonction routage de societe + runErrorScript "vdn-ssh root@societe 'sysctl -w net.ipv4.ip_forward=0'";; + + "Correction erreur 6 (TP5)") + runErrorScript "vdn-ssh root@societe 'sysctl -w net.ipv4.ip_forward=1'";; + + + "testAll-1A") + vdn-scripts testAll-1A;; + + "Quitter") exit 0;; + + esac + + +} + +run() { + + cat << EOF + +Le menu ci-dessous permet de générer des erreurs sur votre réseau ! + +Pour "jouer" il faut au préalable que votre réseau soit complètement +opérationnel (le script testAll-1A affiche ok pour tout). + +Si c'est le cas, déclenchez une erreur, lancez le script testAll-1A +pour découvrir l'ampleur des dégâts et rétablissez le fonctionnement +optimal de votre réseau. + +Si vous ne vous en sortez pas, le choix "Correction" est là pour +annuler l'erreur, théoriquement ;-) + +Note : + +chaque erreur est une unique commande exécutée sur une machine +du réseau. La commande peut être du genre : + +vdn-ssh root@tiny "sed -i -re 's/^toto:/tutu:/' /etc/passwd" + +Si un service est impacté par la commande, il est relancé afin de mettre +immédiatement en évidence les erreurs via le script testAll-1A. + +Bonne chance ! + +EOF + select choix in \ + "Erreur 1 (TP1)" \ + "Correction erreur 1 (TP1)" \ + "Erreur 2 (TP1)" \ + "Correction erreur 2 (TP1)" \ + "Erreur 3 (TP2)" \ + "Correction erreur 3 (TP2)" \ + "Erreur 4 (TP3)" \ + "Correction erreur 4 (TP3)" \ + "Erreur 5 (TP4)" \ + "Correction erreur 5 (TP4)" \ + "Erreur 6 (TP5)" \ + "Correction erreur 6 (TP5)" \ + "testAll-1A" \ + "Quitter" \ + ; do + apply + done +} + +run diff --git a/vdn/networks.bak/demo/scripts/repairAll-1A b/vdn/networks.bak/demo/scripts/repairAll-1A new file mode 100644 index 0000000..b9ddb94 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/repairAll-1A @@ -0,0 +1,666 @@ +#!/usr/bin/env bash + +DESC="TP de 1A." + +SYSTEMS="bigboss tiny societe lambda web" + + +baseConfigBigboss() { + + set -e + + echo "[baseConfigBigboss]" + echo + + name="bigboss" + + #startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static +address 192.168.30.2 +netmask 255.255.255.0 +gateway 192.168.30.1 + +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + + echoDoneWithTestErrors + +} + +baseConfigTiny() { + + set -e + + echo "[baseConfigTiny]" + echo + + + name="tiny" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + +vdn-ssh root@$name "ip addr flush eth1" + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + echoDoneWithTestErrors +} + +baseConfigSociete() { + + set -e + + echo [baseConfigSociete] + echo + + name="societe" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + + echoDoneWithTestErrors +} + +baseConfigWeb() { + + set -e + + echo [baseConfigWeb] + echo + + name="web" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + + systemctl restart networking + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + echoDoneWithTestErrors +} + +baseConfigLambda() { + + set -e + + echo [baseConfigLambda] + echo + + name="lambda" + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + " + + echoDoneWithTestErrors +} + +baseConfigNomade() { + + set -e + + echo [baseConfigNomade] + echo + + + echoDoneWithTestErrors +} + + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +repairUser() { + k=$(getRandomPasswd) + vdn-ssh root@$1 " + id $2 &> /dev/null && exit 0 + adduser --disabled-password --gecos \"\" --home /home/$2 --shell /bin/bash $2 + echo $2:$k| chpasswd + " +} + + +repairUsersTotoTiti() { + set -e + + echo "[repairUsersTotoTiti]" + echo + + + repairUser bigboss toto + repairUser tiny titi + + echoDoneWithTestErrors +} + +repairNfs() { + set -e + + echo "[repairNfs]" + echo + + vdn-ssh root@bigboss " + set -e + [ ! -d /overlays/rw/partage-test ] && mkdir /overlays/rw/partage-test || : + echo test > /overlays/rw/partage-test/vdn-test + + cat <<-EOF > /etc/exports +/overlays/ro/usr/share/doc tiny(ro,sync,subtree_check,no_root_squash,fsid=1) +#/overlays/rw/partage-test tiny(rw,sync,subtree_check,no_root_squash,fsid=2) +EOF + systemctl enable nfs-kernel-server + sleep 1 + systemctl stop nfs-kernel-server + systemctl start nfs-kernel-server + " + echoDoneWithTestErrors +} + +repairDhcp() { + set -e + + echo + echo "[repairDhcp]" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + set -e + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + sleep 3 + + systemctl enable isc-dhcp-server + systemctl stop isc-dhcp-server + systemctl start isc-dhcp-server + + #if [ -e /etc/init.d/dhcp3-server ]; then + # /etc/init.d/dhcp3-server stop &> /dev/null + # /etc/init.d/dhcp3-server start + #elif [ -e /etc/init.d/isc-dhcp-server ]; then + # /etc/init.d/isc-dhcp-server stop &> /dev/null + # /etc/init.d/isc-dhcp-server start + #fi + " + echoDoneWithTestErrors +} + +repairProftpd() { + set -e + + echo + echo "[repairProftpd]" + + vdn-ssh root@bigboss " + + [ ! -e /etc/proftpd/proftpd.conf.vdn ] && \ + cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf.vnd + + grep -q '^> /etc/proftpd/proftpd.conf +# A basic anonymous configuration, no upload directories. + + + User ftp + Group nogroup + # We want clients to be able to login with \"anonymous\" as well as \"ftp\" + UserAlias anonymous ftp + # Cosmetic changes, all files belongs to ftp user + DirFakeUser on ftp + DirFakeGroup on ftp + + RequireValidShell off + + # Limit the maximum number of anonymous logins + MaxClients 10 + + # We want 'welcome.msg' displayed at login, and '.message' displayed + # in each newly chdired directory. + DisplayLogin welcome.msg + DisplayChdir .message + + # Limit WRITE everywhere in the anonymous chroot + + + DenyAll + + + + +EOF + + systemctl enable proftpd + sleep 2 + systemctl restart proftpd + " + echoDoneWithTestErrors +} + +repairApache2Base() { + echo "Apache2 : Lancement du serveur" + + vdn-ssh root@bigboss " + echo 'ServerName bigboss' >> /etc/apache2/apache2.conf + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + sleep 1 + " +} + + +repairApache2Home() { + echo + echo "Apache2 : Page Web personnelle (userdir)" + + vdn-ssh root@bigboss " + [ ! -d /home ] && { echo 'Need toto user !' >&2; exit 1; } + [ ! -d /home/toto/public_html ] && mkdir /home/toto/public_html + cat <<-EOF > /home/toto/public_html/index.html + Page perso. + EOF + chown -R toto: /home/toto/public_html + + a2enmod userdir + systemctl restart apache2 + sleep 1 + " +} + +repairApache2HtaccessToto() { + echo + echo "Protection de toto@bigboss:~toto/secret" + + vdn-ssh root@bigboss " + [ ! -d /home/toto/public_html/secret ] && { + mkdir -p /home/toto/public_html/secret + chown -R toto: /home/toto/public_html + chmod 700 /home/toto/public_html/secret + } + + cat <<-EOF > /home/toto/public_html/secret/.htaccess + AuthType Basic + AuthUserFile /home/toto/public_html/secret/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user titi + +EOF + + echo \"Prive\" > \ + /home/toto/public_html/secret/index.html + + ( + cd /home/toto/public_html/secret/ + htpasswd -b -c users titi iut + ) + + chown -R toto: /home/toto/public_html + " + +} + +repairApache2() { + set -e + + echo "[repairApache2]" + echo + + repairApache2Base + repairApache2Home + repairApache2HtaccessToto + + echoDoneWithTestErrors +} + +repairClientServer() { + set -e + + echo "[repairClientServer]" + echo + + vdn-ssh root@bigboss " +cat << EOF > /usr/local/bin/server.rb +#!/usr/bin/env ruby + +require 'socket' +server = TCPServer.new ARGV[0] # socket d'écoute attaché au port passé en argument +loop do # boucle infinie + client = server.accept # attente d'une connexion + while request=client.gets.chomp do # pour toutes les lignes reçues + case request + when \"time\" then client.puts \"#{Time.now}\" # émission de la réponse + when \"exit\" then break + else client.puts \"error\" + end + end + client.close # fermeture de la connexion +end +EOF +" + + vdn-ssh root@tiny " +cat << EOF > /usr/local/bin/client.rb +#!/usr/bin/env ruby + +require \"socket\" +s = TCPSocket.open(ARGV[0], ARGV[1].to_i) # Création de la socket et connexion +while line = STDIN.gets do # pour toutes les lignes de l'entrée standard + s.puts line # émission de la ligne vers le serveur + break if line.chomp == \"exit\" # chomp retire l'\\n' final + puts s.gets # Affiche la ligne en provenance du serveur +end +s.close # fermeture de la socket +EOF +" + + echoDoneWithTestErrors +} + +repairRouting() { + set -e + + echo "[repairRouting]" + echo + + baseConfigSociete + baseConfigWeb + baseConfigLambda + + vdn-ssh root@societe ' + sed -i -re "s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/" /etc/sysctl.conf + sysctl -p + set -e + + + cat << EOF > /etc/firewall.sh +#!/bin/bash + + iptables -t nat -F + iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + chmod 755 /etc/firewall.sh + + +# MARCHE PAS + ! grep -q /etc/firewall.sh /etc/vdn/vdn.rc && { + echo "Add /etc/firewall in /etc/vdn/vdn.rc" + echo /etc/firewall.sh >> /etc/vdn/vdn.rc + chmod 755 /etc/vdn/vdn.rc + } || : + + /etc/firewall.sh + ' + + repairClientServer + + echoDoneWithTestErrors +} + + +repairSshKeys() { + set -e + + echo "[repairSshKeys]" + echo + + vdn-ssh root@bigboss " + set -e + [ ! -e .ssh/id_rsa ] && ssh-keygen -q -N '' -f ~/.ssh/id_rsa -t rsa || : + " + + sleep 2 # laisser le temps à la création de titi sur tiny + + vdn-ssh root@tiny " + su -c ' + [ ! -d ~/.ssh ] && { mkdir ~/.ssh; chmod 700 .ssh; } + ' - titi + " + + local tmp=$(mktemp) + vdn-ssh root@bigboss "cat ~/.ssh/id_rsa.pub" > $tmp + cat $tmp | vdn-ssh root@tiny " + su -c ' + cat > ~/.ssh/authorized_keys + ' - titi + " + + rm $tmp + + echoDoneWithTestErrors +} + +run() { + requireSshGuests $SYSTEMS + + vdnExec baseConfigBigboss baseConfigTiny repairUsersTotoTiti \ + repairNfs repairDhcp repairProftpd \ + repairApache2 \ + repairRouting repairSshKeys +} diff --git a/vdn/networks.bak/demo/scripts/repairApache2 b/vdn/networks.bak/demo/scripts/repairApache2 new file mode 100644 index 0000000..5b1be10 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/repairApache2 @@ -0,0 +1,304 @@ +#!/usr/bin/env bash + +set -eu + +#set -x + +DESC="Test apache2 (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, les fichiers suivants sont modifiés : +- /etc/apache2/apache2.conf +- /etc/apache2/sites-available/000-default.conf + +Une copie est faite avec l'extension .vdn +" + + +repairApache2Base() { + echo "Lancement du serveur" + + vdn-ssh root@bigboss " + echo 'ServerName bigboss' >> /etc/apache2/apache2.conf + + systemctl enable apache2 + systemctl stop apache2 + systemctl start apache2 + sleep 1 + " +} + +repairApache2Root() { + echo + echo "Modification de la racine du serveur Web" + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + [ ! -e \$conf ] && cp \$conf \${conf}.vdn + root=/home/httpd/html + + [ ! -d \$root ] && mkdir -p \$root + + #cat \$conf | sed -e 's|/var/www/html|'\$root'|g' \ + # > /tmp/default + cat <<-EOF > \$conf + +# The ServerName directive sets the request scheme, hostname and port that +# the server uses to identify itself. This is used when creating +# redirection URLs. In the context of virtual hosts, the ServerName +# specifies what hostname must appear in the request's Host: header to +# match this virtual host. For the default virtual host (this file) this +# value is not decisive as it is used as a last resort host regardless. +# However, you must set it for any further virtual host explicitly. +#ServerName www.example.com + +ServerAdmin webmaster@localhost +DocumentRoot /home/httpd/html + +# Available loglevels: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the loglevel for particular +# modules, e.g. +#LogLevel info ssl:warn + +ErrorLog \\\${APACHE_LOG_DIR}/error.log +CustomLog \\\${APACHE_LOG_DIR}/access.log combined + +# For most configuration files from conf-available/, which are +# enabled or disabled at a global level, it is possible to +# include a line for only one particular virtual host. For example the +# following line enables the CGI configuration for this host only +# after it has been globally disabled with \"a2disconf\". +#Include conf-available/serve-cgi-bin.conf + +ScriptAlias \"/cgi-bin/\" \"/home/httpd/cgi-bin/\" + + +Options Indexes FollowSymLinks +AllowOverride None +Allow from all +Require all granted + + + + Options +ExecCGI + Require all granted + + + + +EOF + + #mv /tmp/default \$conf + cat <<-EOF > \$root/index.html + + + ok + + + EOF + + systemctl reload apache2 + sleep 1 + " + + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + root=/home/httpd/html/ + + cat \$conf | \ + sed -e '//d' \ + > /tmp/default + cat /tmp/default | grep -v '' > \$conf + + cat <<-EOF >> \$conf + + Options Indexes FollowSymlinks Multiviews + AllowOverride None + Order allow,deny + allow from all + Require all granted + + + EOF + + sleep 1 + systemctl reload apache2 + sleep 1 + " +} + +repairApache2CGI() { + echo + echo "Création d'un script CGI" + + vdn-ssh root@bigboss " + [ ! -d /home/httpd/cgi-bin ] && mkdir -p /home/httpd/cgi-bin + cat <<-EOF > /home/httpd/cgi-bin/test-cgi + #!/bin/bash + + # Header + echo 'Content-type: text/html' + + # Fin de l'header + echo + + # Contenu à afficher dans le navigateur + echo '' + echo 'Bonjour : nous sommes le :\`date\`' + echo '' + EOF + + chmod 755 /home/httpd/cgi-bin/test-cgi + + cat /etc/apache2/sites-available/000-default.conf | \ + sed -re 's,/usr/lib/cgi-bin/,/home/httpd/cgi-bin/,' \ + > /tmp/defaut + mv /tmp/defaut /etc/apache2/sites-available/000-default.conf + + a2enmod cgid + + systemctl restart apache2 + sleep 1 + " + +} + +repairApache2Php() { + echo + echo "Création d'une page PHP" + + vdn-ssh root@bigboss " + [ ! -d /home/http/html ] && mkdir -p /home/httpd/html + cat <<-EOF > /home/httpd/html/index.php + + Exemple + + Nous sommes le , il est . + + + EOF + " + +} + +repairApache2Home() { + echo + echo "Page Web personnelle (userdir)" + + vdn-ssh root@bigboss " + [ ! -d /home ] && { echo 'Need toto user !' >&2; exit 1; } + [ ! -d /home/toto/public_html ] && mkdir /home/toto/public_html + cat <<-EOF > /home/toto/public_html/index.html + Page perso. + EOF + chown -R toto: /home/toto/public_html + + a2enmod userdir + systemctl restart apache2 + sleep 1 + " +} + +repairApache2HtaccessToto() { + echo + echo "Protection de toto@bigboss:~toto/secret" + + vdn-ssh root@bigboss " + [ ! -d /home/toto/public_html/secret ] && { + mkdir -p /home/toto/public_html/secret + chown -R toto: /home/toto/public_html + chmod 700 /home/toto/public_html/secret + } + + cat <<-EOF > /home/toto/public_html/secret/.htaccess + AuthType Basic + AuthUserFile /home/toto/public_html/secret/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user titi + +EOF + + echo \"Prive\" > \ + /home/toto/public_html/secret/index.html + + ( + cd /home/toto/public_html/secret/ + htpasswd -b -c users titi iut + ) + + chown -R toto: /home/toto/public_html + " + +} + +repairApache2Htaccess() { + echo + echo "Protection par mot de passe" + + vdn-ssh root@bigboss " + [ ! -d /home/httpd/html/prive ] && mkdir /home/httpd/html/prive + cat <<-EOF > /home/httpd/html/prive/.htaccess + AuthType Basic + AuthUserFile /etc/apache2/users + #AuthGroupFile /dev/null + AuthName \"Accès privé\" + + require user toto + + EOF + + echo \"Prive\" > \ + /home/httpd/html/prive/index.html + + ( + cd /etc/apache2 + htpasswd -b -c users toto iut + htpasswd -b users prof iut + ) + " + + vdn-ssh root@bigboss " + conf=/etc/apache2/sites-available/000-default.conf + + cat \$conf | \ + sed -e '//d' \ + > /tmp/default + cat /tmp/default | grep -v '' > \$conf + + cat <<-EOF >> \$conf + + Options Indexes FollowSymlinks Multiviews + AllowOverride All + Order allow,deny + allow from all + + + EOF + + systemctl reload apache2 + sleep 1 + " +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairApache2Base + #repairApache2Root + #repairApache2CGI + #repairApache2Php + repairApache2Home + #repairApache2Htaccess + repairApache2HtaccessToto + + unsetErrorHandler +} + diff --git a/vdn/networks.bak/demo/scripts/repairDhcp b/vdn/networks.bak/demo/scripts/repairDhcp new file mode 100644 index 0000000..9c3b81b --- /dev/null +++ b/vdn/networks.bak/demo/scripts/repairDhcp @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Fixe DHCP sur bigboss pour servir tiny (IP, nom d'hôte)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +repairDHCP() { + echo + echo "Repair DHCP" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + set -x + sleep 10 + + systemctl enable isc-dhcp-server + systemctl stop isc-dhcp-server + systemctl start isc-dhcp-server + + #if [ -e /etc/init.d/dhcp3-server ]; then + # /etc/init.d/dhcp3-server stop &> /dev/null + # /etc/init.d/dhcp3-server start + #elif [ -e /etc/init.d/isc-dhcp-server ]; then + # /etc/init.d/isc-dhcp-server stop &> /dev/null + # /etc/init.d/isc-dhcp-server start + #fi + + " +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairDHCP + + echoDoneWithTestErrors +} + + diff --git a/vdn/networks.bak/demo/scripts/repairFirewall b/vdn/networks.bak/demo/scripts/repairFirewall new file mode 100644 index 0000000..e816f53 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/repairFirewall @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + config + + #sleep 1 + + #parallelDisablePause + #vdn-scripts testFirewall + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/repairIPv6 b/vdn/networks.bak/demo/scripts/repairIPv6 new file mode 100644 index 0000000..8f8ac1b --- /dev/null +++ b/vdn/networks.bak/demo/scripts/repairIPv6 @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Nouvelle configuration IPv6 du réseau + tests" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + +testIPv6() { + echo + echo "test link between web and bigboss (Unique local address)" + echo + + # réinitialise les interfaces + + vdn-ssh root@bigboss "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@web "ifconfig eth0 down ; ifconfig eth0 up" + vdn-ssh root@societe " + ifconfig eth0 down ; ifconfig eth0 up + ifconfig eth1 down ; ifconfig eth1 up + ifconfig eth2 down ; ifconfig eth2 up + + echo 1 >/proc/sys/net/ipv6/conf/all/forwarding + " + + # Ajoute les adresses IPv6 "locales uniques" en utilisant le suffixe + # de l'adresse "lien local" + # + # * la DMZ (web) aura le préfixe fc01 + # * le réseau interne (bigboss) aura le préfixe fc00 + # + # La fonction routage IPv6 est activé sur société + # et les route par défaut sont fixées sur web et bigboss + # + # un ping6 de bigboss vers web valide la config. + + ipSocieteWeb=$(getIPv6 societe eth1) + ipSocieteWeb=$(echo $ipSocieteWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteWeb/64 dev eth1" + + ipSocieteBigboss=$(getIPv6 societe eth2) + ipSocieteBigboss=$(echo $ipSocieteBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteBigboss/64 dev eth2" + + ipWeb=$(getIPv6 web eth0) + ipWeb=$(echo $ipWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@web "ip -6 addr add $ipWeb/64 dev eth0" + + ipBigboss=$(getIPv6 bigboss eth0) + ipBigboss=$(echo $ipBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@bigboss "ip -6 addr add $ipBigboss/64 dev eth0" + + vdn-ssh root@web " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteWeb" + vdn-ssh root@bigboss " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteBigboss" + + vdn-ssh root@bigboss "ping6 -c 3 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo/scripts/repairNfs b/vdn/networks.bak/demo/scripts/repairNfs new file mode 100644 index 0000000..3bc3594 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/repairNfs @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Fixe NFS (bigboss exporte /overlays/ro/usr/share/doc (ro) et tiny l'importe)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, le fichier /etc/exports est modifié ! +" + +repairNfs() { + vdn-ssh root@bigboss " + + [ ! -d /overlays/rw/partage-test ] && mkdir /overlays/rw/partage-test || : + echo test > /overlays/rw/partage-test/vdn-test + + cat <<-EOF > /etc/exports +/overlays/ro/usr/share/doc tiny(ro,sync,subtree_check,no_root_squash,fsid=1) +#/overlays/rw/partage-test tiny(rw,sync,subtree_check,no_root_squash,fsid=2) + EOF + sleep 1 + systemctl enable nfs-kernel-server + systemctl stop nfs-kernel-server + systemctl start nfs-kernel-server + " +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss + + repairNfs + + unsetErrorHandler +} + diff --git a/vdn/networks.bak/demo/scripts/repairProftpd b/vdn/networks.bak/demo/scripts/repairProftpd new file mode 100644 index 0000000..ca93cae --- /dev/null +++ b/vdn/networks.bak/demo/scripts/repairProftpd @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +set -u + +DESC="Fixe proftp (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, le fichier suivant est modifié : +- /etc/proftpd/proftpd.conf + +Une copie de l'original est faite avec l'extension .vdn +" + + +repairProftpd() { + echo + echo "Repair proftpd" + + vdn-ssh root@bigboss " + + [ ! -e /etc/proftpd/proftpd.conf.vdn ] && \ + cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf.vnd + + grep -q '^> /etc/proftpd/proftpd.conf +# A basic anonymous configuration, no upload directories. + + + User ftp + Group nogroup + # We want clients to be able to login with \"anonymous\" as well as \"ftp\" + UserAlias anonymous ftp + # Cosmetic changes, all files belongs to ftp user + DirFakeUser on ftp + DirFakeGroup on ftp + + RequireValidShell off + + # Limit the maximum number of anonymous logins + MaxClients 10 + + # We want 'welcome.msg' displayed at login, and '.message' displayed + # in each newly chdired directory. + DisplayLogin welcome.msg + DisplayChdir .message + + # Limit WRITE everywhere in the anonymous chroot + + + DenyAll + + + + +EOF + + systemctl enable proftpd + systemctl restart proftpd + " + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + repairProftpd + + echoDoneWithTestErrors +} + diff --git a/vdn/networks.bak/demo/scripts/repairUsersTotoTiti b/vdn/networks.bak/demo/scripts/repairUsersTotoTiti new file mode 100644 index 0000000..d9c1c29 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/repairUsersTotoTiti @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Ajoute, si nécessaire un utilisateur toto sur bigboss et tit sur tiny." + +getRandomPasswd() { + local k + + while :; do + k=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom 2> /dev/null | head -c${1:-32} ) + if [ $(echo -n $k | wc -c) = 32 ]; then + break + fi + echo "Wait for entropy avail : $(cat /proc/sys/kernel/random/entropy_avail)" >&2 + sleep 1 + done + echo -n $k +} + +repairUser() { + k=$(getRandomPasswd) + vdn-ssh root@$1 " + id $2 2> /dev/null && exit 0 + adduser --disabled-password --gecos \"\" --home /home/$2 --shell /bin/bash $2 + echo $2:$k| chpasswd + " +} + + +run() { + setErrorHandler + echoStart + + startAndWaitSsh bigboss tiny + + repairUser bigboss toto + repairUser tiny titi + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/testAll-1A b/vdn/networks.bak/demo/scripts/testAll-1A new file mode 100755 index 0000000..edcde67 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testAll-1A @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +DESC="Teste les TPs de 1A sur bigboss et tiny." + +SYSTEMS="bigboss tiny societe lambda web" + +testTp1Part1() { + echo "[TP n°1 partie bigboss]" + echo + vdnTest "hostname bigboss ......... ?" 'vdn-ssh root@bigboss "test \"\$(hostname)\" = bigboss"' + vdnTest "ip bigboss ............... ?" 'vdn-ssh root@bigboss "ip addr show eth0 | grep -Fq 192.168.30.2"' + vdnTest "ping bigboss -> tiny ..... ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "ping bigboss -> bigboss .. ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 bigboss &> /dev/null"' +} + +testTp1Part2() { + echo "[TP n°1 partie tiny]" + echo + vdnTest "hostname tiny ............ ?" 'vdn-ssh root@tiny "test \"\$(hostname)\" = tiny"' + vdnTest "ip tiny .................. ?" 'vdn-ssh root@tiny "ip addr show eth1 | grep -Fq 192.168.30.16"' + vdnTest "ping tiny -> bigboss .. ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping tiny -> tiny ..... ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 tiny &> /dev/null"' +} + +testTp2() { + echo "[TP n°1 partie \"utilisateurs\"]" + echo + vdnTest "user toto sur bigboss .... ?" 'vdn-ssh root@bigboss "id toto &> /dev/null"' + vdnTest "user titi sur tiny ....... ?" 'vdn-ssh root@tiny "id titi &> /dev/null"' + echo + echo "[TP n°2]" + echo + vdnTest "NFS lecture seule (ro) ... ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' +} + +testTp3() { + echo "[TP n°3]" + echo + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdnTest "DHCP configuré sur bigboss ....... ?" "vdn-ssh root@bigboss \"grep -iq '^[^#]*$tinyMAC' /etc/dhcp/dhcpd.conf\"" + vdnTest "DHCP sur bigboss : actif ......... ?" "vdn-ssh root@bigboss \"systemctl status isc-dhcp-server | grep -q 'Active: active'\"" + + echo + + vdnTest "FTP anonyme sur bigboss .......... ?" "vdn-ssh root@tiny 'set -x; echo -e \"open bigboss\nuser anonymous test@bidule.com\nls\" | ftp -i -n | grep -q welcome'" + + echo + + #vdnTest "bigboss run apache2 .............. ?" "vdn-ssh root@tiny 'netcat -w 1 bigboss 80 &> /dev/null < /dev/null'" + vdnTest "bigboss run apache2 .............. ?" "vdn-ssh root@tiny 'timeout 2 lynx -dump bigboss &> /dev/null'" + e=$? + + if [ $e = 0 ]; then + vdnTest "bigboss run apache2 with userdir . ?" "vdn-ssh root@tiny 'unset http_proxy; \ + timeout 2 lynx -dump bigboss/~toto 2> /dev/null | grep -iv \"Not found\"'" + vdnTest "toto@bigboss avec HTTP protégé ... ?" "vdn-ssh root@bigboss '\ + find /home/toto/public_html -name .htaccess 2> /dev/null | grep -q htaccess$'" + else + echo >&2 + echo "Subsequent tests canceled !" >&2 + return 1 + fi + + +} + +testTp4() { + echo "[TP n°4]" + echo + + vdnTest "tiny -> web ....................... ?" "vdn-ssh root@tiny 'unset http_proxy; timeout 2 lynx -dump web'" + echo + vdnTest "root@bigboss id_rsa/id_rsa.pub .... ?" "vdn-ssh root@bigboss 'ls -l ~/.ssh/id_rsa &> /dev/null'" + vdnTest "root@bigboss -> titi@tiny ......... ?" "vdn-ssh root@bigboss 'timeout 2 ssh -o StrictHostKeyChecking=no titi@tiny :'" +} + +testTp5() { + echo "[TP n°5]" + echo + + local ipLambda=$(vdn-infos lambda PUBLIC_IP) + + vdnTest "tiny -> ipLambda .................. ?" "vdn-ssh root@tiny 'unset http_proxy; timeout 2 lynx -dump $ipLambda'" + echo + vdnTest "serveur.rb ........................ ?" "vdn-ssh root@bigboss 'ls /usr/local/bin/server.rb &> /dev/null'" + vdnTest "client.rb ......................... ?" "vdn-ssh root@tiny 'ls /usr/local/bin/client.rb &> /dev/null'" +} + +testSum() { + local last=-1 cpt=0 n + set +u + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + + if [ -z "$VDN_TESTS_DIR" ]; then + echo + echo "Not used !" + return + fi + set +u + last=-1 + echo "[Synthèse]" + echo + + while :; do + n=$(ls $VDN_TESTS_DIR | wc -l) + + printf "." + + if [ $n = $last ]; then + same=$(($same+1)) + else + same=0 + fi + + if [ $same = 10 ]; then + break; + fi + + last=$n + + sleep 0.5 + done + + good=$(cat $VDN_TESTS_DIR/* | grep '^0$' | wc -l) + bad=$(($n-$good)) + + echo + echo + echo "tests:$n ok:$good ko:$bad réussite:$(( ($good*100) /$n ))%" + echo + + +} + + +run() { + + requireSshGuests $SYSTEMS + + #echo "Cette temporisation est pour vous décourager d'utiliser ce test comme debogueur !" + #for i in $(seq 10 -1 0); do echo $i; sleep 1; done + + VDN_TESTS_DIR=/tmp/vdn-$USER/tests + + [ ! -d $VDN_TESTS_DIR ] && mkdir -p $VDN_TESTS_DIR + + rm -f /tmp/vdn-$USER/tests/* + + vdnExec testTp1Part1 testTp1Part2 testTp2 testTp3 testTp4 testTp5 testSum + +} diff --git a/vdn/networks.bak/demo/scripts/testApache2 b/vdn/networks.bak/demo/scripts/testApache2 new file mode 100644 index 0000000..e30df5d --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testApache2 @@ -0,0 +1,140 @@ +#!/usr/bin/env bash + +set -u + +#set -x + +DESC="Test apache2 (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. + +ATTENTION, les fichiers suivants sont modifiés : +- /etc/apache2/apache2.conf +- /etc/apache2/sites-available/000-default.conf +" + + +testApache2Base() { + echo "bigboss run apache2 ?" + + vdn-ssh root@tiny "netcat -w 1 bigboss 80 &> /dev/null < /dev/null" + + #vdn-ssh root@tiny "lynx -dump bigboss &> /dev/null" + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e +} + +testApache2Root() { + vdn-ssh root@tiny " + lynx -dump bigboss/index.html | \ + grep -q -i 'Bonjour' + " + + vdn-ssh root@tiny " + lynx -dump bigboss/index.html | grep -q 'ok' && echo ok + " +} + +testApache2CGI() { + + vdn-ssh root@tiny " + lynx -dump bigboss/cgi-bin/test-cgi + lynx -dump bigboss/cgi-bin/test-cgi | grep -q 'Bonjour' + " +} + +testApache2Php() { + + vdn-ssh root@tiny " + lynx -dump bigboss/index.php + lynx -dump bigboss/index.php | grep -q 'sommes le [^,]' + " +} + +testApache2Home() { + echo "bigboss run apache2 with userdir ?" + + vdn-ssh root@tiny " + unset http_proxy; lynx -dump bigboss/~toto 2> /dev/null # | grep -iq 'perso' + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e + +} + +testApache2HtaccessExist() { + echo "toto@bigboss possède un répertoire HTTP protégé ?" + + vdn-ssh root@bigboss " + find /home/toto/public_html -name '.htaccess' 2> /dev/null | grep -q 'htaccess$' + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + return $e +} + +testApache2HtaccessToto() { + echo "toto@bigboss : répertoire HTTP fonctionnel ?" + vdn-ssh root@tiny " + unset http_proxy; lynx -dump http://bigboss/~toto/index.html + " +} + +testApache2Htaccess() { + + vdn-ssh root@tiny " + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive | grep -q 'Prive' && \ + echo \"ok\" + echo + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive/.htaccess | grep -q 'Forbidden' + " + + vdn-ssh root@tiny " + echo \"Accès à privé sans identification\" + lynx -dump bigboss/prive 2> /dev/null | grep -q 'Prive' || \ + echo \"ok\" + echo + echo \"Accès à privé avec identification\" + lynx -auth=sasa:xyz -dump bigboss/prive | \ + grep -q 'Prive' + " + + +} + + +run() { + local errors=0 e + + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + testApache2Base + e=$? + #testApache2Root + #testApache2CGI + #testApache2Php + + if [ $e = 0 ]; then + testApache2Home + testApache2HtaccessExist + #testApache2HtaccessToto + else + echo "Subsequent tests canceled !" >&2 + fi + #testApache2Htaccess + + unsetErrorHandler + return $errors +} + diff --git a/vdn/networks.bak/demo/scripts/testBigbossTiny b/vdn/networks.bak/demo/scripts/testBigbossTiny new file mode 100644 index 0000000..c8e39e1 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testBigbossTiny @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +DESC="Test de la configuration de base de bigboss et tiny." + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + vdnTest "hostname bigboss ......... ?" 'vdn-ssh root@bigboss "test \"\$(hostname)\" = bigboss"' + vdnTest "ip bigboss ............... ?" 'vdn-ssh root@bigboss "ip addr show eth0 | grep -Fq 192.168.30.2"' + vdnTest "hostname tiny ............ ?" 'vdn-ssh root@tiny "test \"\$(hostname)\" = tiny"' + vdnTest "ip tiny .................. ?" 'vdn-ssh root@tiny "ip addr show eth1 | grep -Fq 192.168.30.16"' + vdnTest "ping bigboss -> tiny ..... ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "ping tiny -> bigboss .. ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping bigboss -> bigboss .. ?" 'vdn-ssh root@bigboss "timeout 2 ping -c 1 bigboss &> /dev/null"' + vdnTest "ping tiny -> tiny ..... ?" 'vdn-ssh root@tiny "timeout 2 ping -c 1 tiny &> /dev/null"' + vdnTest "user toto sur bigboss .... ?" 'vdn-ssh root@bigboss "id toto &> /dev/null"' + vdnTest "user titi sur tiny ....... ?" 'vdn-ssh root@tiny "id titi &> /dev/null"' + + echo + + vdnTest "NFS lecture seule (ro) ... ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' + + echoDone + + return $localErrors +} + diff --git a/vdn/networks.bak/demo/scripts/testDHCPBigbossTiny b/vdn/networks.bak/demo/scripts/testDHCPBigbossTiny new file mode 100644 index 0000000..c0c7766 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testDHCPBigbossTiny @@ -0,0 +1,125 @@ +#!/usr/bin/env bash + +set -eu + +set -x + +DESC="Test DHCP (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +resetToDefault() { + echo + echo "Reset DHCP" + + vdn-ssh root@bigboss " + + # Création d'une sauvegarde des fichiers originaux + for i in /etc/dhcp3/dhcpd.conf; do + [ ! -e \${i}.vdn -a -e $i ] && + cp \${i} \${i}.vdn + done + + # Restauration de la sauvegarde + + for i in /etc/dhcp3/dhcpd.conf; do + [ -e \${i}.vdn ] && + cp \${i}.vdn \${i} + done + + exit 0 + " + + vdn-ssh root@tiny " + + # Création d'une sauvegarde des fichiers originaux + + for i in /etc/network/interfaces; do + [ ! -e \${i}.vdn ] && + cp \${i} \${i}.vdn + done + + # Restauration de la sauvegarde + + for i in /etc/network/interfaces; do + [ -e \${i}.vdn ] && + cp \${i}.vdn \${i} + done + " + + +} + + +testDHCP() { + echo + echo "Test de DHCP" + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | \ + sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdn-ssh root@bigboss " + f=/etc/dhcp3/dhcpd.conf + [ -e /etc/init.d/isc-dhcp-server ] && f=/etc/dhcp/dhcpd.conf + cat <<-EOF > \$f + subnet 192.168.30.0 netmask 255.255.255.0 { + } + host tiny { + hardware ethernet ${tinyMAC}; + option host-name tiny; + fixed-address tiny; + } +EOF + + f=/etc/default/isc-dhcp-server + cat <<-EOF > \$f +INTERFACESv4=\"eth0\" +INTERFACESv6=\"\" +EOF + + if [ -e /etc/init.d/dhcp3-server ]; then + /etc/init.d/dhcp3-server stop &> /dev/null + /etc/init.d/dhcp3-server start + elif [ -e /etc/init.d/isc-dhcp-server ]; then + /etc/init.d/isc-dhcp-server stop &> /dev/null + /etc/init.d/isc-dhcp-server start + fi + + " + + vdn-ssh root@tiny " + cat <<-EOF > /etc/network/interfaces + auto lo + iface lo inet loopback + + auto eth1 + iface eth1 inet dhcp + EOF + + ifdown eth1 + ifup eth1 + + ifconfig eth1 | grep -q 192.168 && echo ok || exit 1 + " + + +} + +run() { + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + resetToDefault + testDHCP + resetToDefault + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo/scripts/testDhcp b/vdn/networks.bak/demo/scripts/testDhcp new file mode 100644 index 0000000..e7dfd6c --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testDhcp @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +DESC="Test DHCP (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + tinyMAC=$(vdn-ssh root@tiny ifconfig eth1 | grep ether) + tinyMAC=$(echo "$tinyMAC" | sed -re 's/^.*ether ([[:xdigit:]:]*).*$/\1/') + + vdnTest "DHCP configuré sur bigboss ?" "vdn-ssh root@bigboss \"grep -q '^[^#]*$tinyMAC' /etc/dhcp/dhcpd.conf\"" + vdnTest "DHCP sur bigboss : actif ?" "vdn-ssh root@bigboss \"systemctl status isc-dhcp-server | grep -q 'Active: active'\"" + + echo + + vdnTest "FTP anonyme sur bigboss ?" "vdn-ssh root@tiny ' + echo -e \'open bigboss\nuser anonymous test@bidule.com\nls\' \ + | ftp -i -n | grep -q welcome'" + + + unsetErrorHandler + + echoDone + + return $localErrors +} + + diff --git a/vdn/networks.bak/demo/scripts/testFirewall b/vdn/networks.bak/demo/scripts/testFirewall new file mode 100644 index 0000000..3806442 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testFirewall @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +run() { + setErrorHandler + echoStart + + parallelDisablePause + + vdn-scripts diag1 diag2 diag3 + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/testIPv6 b/vdn/networks.bak/demo/scripts/testIPv6 new file mode 100644 index 0000000..c7729f8 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testIPv6 @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test ping6 IPv6 (à travers un routeur IPv6)" + +SYSTEMS="bigboss societe web" + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | head -n 1 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + + +testIPv6() { + + ipWeb=$(getIPv6 web eth0) + echo "Try ping6 (bigboss -> web)..." + vdn-ssh root@bigboss "ping6 -c 1 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + #waitSsh $SYSTEMS + + testIPv6 + + unsetErrorHandler + echoDone +} + + diff --git a/vdn/networks.bak/demo/scripts/testMyCompanyFirewall b/vdn/networks.bak/demo/scripts/testMyCompanyFirewall new file mode 100644 index 0000000..40d3cda --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testMyCompanyFirewall @@ -0,0 +1,136 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Test de la configuration de base du TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +config() { + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + vdn-ssh -t root@societe " +# net.ipv4.ip_forward=1 +sed -i -re 's/#(net.ipv4.ip_forward=1)/\1/g' /etc/sysctl.conf +sysctl -p + +cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +cat << EOF > local-1.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local-1.sh + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh + +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh + +cat << EOF > local.sh +#!/bin/sh + +echo "1" > /proc/sys/net/ipv4/ip_forward + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +cat << EOF > fw-on.sh +#!/bin/sh + +/root/vide.sh +/root/fermeDehors.sh +/root/local.sh +/root/forward.sh +if [ -x /root/dns.sh ]; then + /root/dns.sh +fi +EOF + +chmod 755 fw-on.sh + +/root/fw-on.sh +" + + +} + +test() { + # tiny peut joindre bigboss (et vice versa). + + vdn-ssh root@bigboss "ping -c 1 tiny" + vdn-ssh root@tiny "ping -c 1 bigboss" + + # societe est joignable par toutes les machines (et vice versa) + + for i in $SYSTEMS; do + vdn-ssh root@$i "ping -c 1 societe" + done + + # lambda peut joindre nomade (et vice-versa) + + vdn-ssh root@lambda "ping -c 1 nomade" + vdn-ssh root@nomade "ping -c 1 lambda" + + # vérifiez que les serveurs apache2 de lambda, web et bigboss fonctionnent + + vdn-ssh root@bigboss "lynx -dump bigboss" | grep -q 'Bienvenue' + vdn-ssh root@web "lynx -dump web" | grep -q 'Bienvenue' + vdn-ssh root@lambda "lynx -dump lambda" | grep -q 'Bienvenue' +} + + +run() { + setErrorHandler + echoStart + + requireSshGuests $SYSTEMS + + #set -x + + # Config + config + + # test + #test + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/demo/scripts/testNfs b/vdn/networks.bak/demo/scripts/testNfs new file mode 100644 index 0000000..0adb099 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testNfs @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +DESC="Test NFS (bigboss exporte /overlays/ro/usr/share/doc (ro) et tiny l'importe)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +SYSTEMS="bigboss tiny" + +run() { + local localErrors=0 + + requireSshGuests $SYSTEMS + + vdnTest "NFS lecture seule (ro) ?" ' + vdn-ssh root@tiny " + [ ! -d /mnt/bigboss ] && mkdir /mnt/bigboss; + timeout 3 mount bigboss:/overlays/ro/usr/share/doc /mnt/bigboss; + [ ! -e /mnt/bigboss/xterm ] && exit 1; + umount /mnt/bigboss; + "' + + echoDone + + return $localErrors +} + diff --git a/vdn/networks.bak/demo/scripts/testProftpd b/vdn/networks.bak/demo/scripts/testProftpd new file mode 100644 index 0000000..e469a98 --- /dev/null +++ b/vdn/networks.bak/demo/scripts/testProftpd @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -u + +DESC="Test proftp (serveur:bigboss et client:tiny)" + +HELP=" +Bigboss et tiny doivent avoir été configurés par baseConfig. +" + +testProftp() { + echo + echo "Test de proftpd (anonymous)" + + vdn-ssh root@tiny " + echo -e 'open bigboss\nuser anonymous test@bidule.com\nls' \ + | ftp -i -n | grep -q welcome + " + + e=$?; [ $e = 0 ] && green ok || red ko + errors=$((errors+$e)) + + return $e + +} + +run() { + local errors=0 + + setErrorHandler + echoStart + + requireSshGuests bigboss tiny + + testProftp + + unsetErrorHandler + return $errors +} + diff --git a/vdn/networks.bak/demo/societe.conf b/vdn/networks.bak/demo/societe.conf new file mode 100644 index 0000000..da9ded2 --- /dev/null +++ b/vdn/networks.bak/demo/societe.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_G#20.X3.Y3.Z3/8 NET_1#192.168.1.1/24 NET_2#192.168.30.1/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="1" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="1" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo/tiny.conf b/vdn/networks.bak/demo/tiny.conf new file mode 100644 index 0000000..5c5ee68 --- /dev/null +++ b/vdn/networks.bak/demo/tiny.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="2048" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="none NET_2#192.168.30.16/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/demo/web.conf b/vdn/networks.bak/demo/web.conf new file mode 100644 index 0000000..b15c14f --- /dev/null +++ b/vdn/networks.bak/demo/web.conf @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="384" + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="NET_1#192.168.1.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS=" tcp:22:(ssh) tcp:80:(http) " + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + +# Activer la résolution des hôtes Internet (ex : tiny.demo.toto.vdn) + +VDN_RESOLV="1" + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel (ex : debian/bullseye) + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME="0" + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="apache2" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="multi-user.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/docker-buster/build b/vdn/networks.bak/docker-buster/build new file mode 100755 index 0000000..d891517 --- /dev/null +++ b/vdn/networks.bak/docker-buster/build @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + + + +build() { + local n + + n=debian-1 + vdn-build $n + vdn-config $n GUEST_SYS "debian/buster" + vdn-config $n MEMORY "4096" + vdn-config $n AUFS_SIZE 2048 + vdn-config $n HDB "docker-hdb.disk" + vdn-config $n HDB_PART_FORMAT 1 + vdn-config $n HDB_DIRS "/root /home /var/lib/docker /var/lib/containerd" + vdn-config $n HDB_SIZE "5120" + vdn-config $n SWAP_SIZE "2048" + vdn-config $n EXTRA_SERVICES "containerd docker" + + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + tcp:443:(https) \ + tcp:8000:(free) \ + " +} + diff --git a/vdn/networks.bak/docker-buster/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf b/vdn/networks.bak/docker-buster/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf new file mode 100644 index 0000000..0f39841 --- /dev/null +++ b/vdn/networks.bak/docker-buster/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf @@ -0,0 +1,5 @@ +[Service] +Environment=HTTP_PROXY="http://193.49.118.36:8080/" +Environment=HTTPS_PROXY="http://193.49.118.36:8080/" +Environment=NO_PROXY="localhost,127.0.0.0/8" + diff --git a/vdn/networks.bak/docker-buster/net.svgz b/vdn/networks.bak/docker-buster/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..084b175f8f1d00d4f93090dc278ac27451404149 GIT binary patch literal 8030 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 /dev/null' + +} + diff --git a/vdn/networks.bak/docker-tmp-buster/build b/vdn/networks.bak/docker-tmp-buster/build new file mode 100755 index 0000000..2c0bdc1 --- /dev/null +++ b/vdn/networks.bak/docker-tmp-buster/build @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + + + +build() { + local n + + n=debian-1 + vdn-build $n + + vdn-config $n GUEST_SYS "debian/buster" + vdn-config $n MEMORY "4096" + vdn-config $n AUFS_SIZE 2048 + vdn-config $n SAVE_DIR "/tmp/vdn-\$USER" + vdn-config $n SAVE_DIR_HDB "/tmp/vdn-\$USER" + vdn-config $n HDB "docker-hdb.disk" + vdn-config $n HDB_PART_FORMAT 1 + vdn-config $n HDB_DIRS "/root /home /var/lib/docker /var/lib/containerd" + vdn-config $n HDB_SIZE "32000" + vdn-config $n SWAP_SIZE "2048" + vdn-config $n EXTRA_SERVICES "containerd docker" + + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + tcp:443:(https) \ + tcp:8000:(free) \ + " +} + diff --git a/vdn/networks.bak/docker-tmp-buster/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf b/vdn/networks.bak/docker-tmp-buster/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf new file mode 100644 index 0000000..0f39841 --- /dev/null +++ b/vdn/networks.bak/docker-tmp-buster/debian-1/etc/systemd/system/docker.service.d/http-proxy.conf @@ -0,0 +1,5 @@ +[Service] +Environment=HTTP_PROXY="http://193.49.118.36:8080/" +Environment=HTTPS_PROXY="http://193.49.118.36:8080/" +Environment=NO_PROXY="localhost,127.0.0.0/8" + diff --git a/vdn/networks.bak/docker-tmp-buster/net.svgz b/vdn/networks.bak/docker-tmp-buster/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..084b175f8f1d00d4f93090dc278ac27451404149 GIT binary patch literal 8030 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 /dev/null' + +} + diff --git a/vdn/networks.bak/firewall-buster/build b/vdn/networks.bak/firewall-buster/build new file mode 100755 index 0000000..d7c915b --- /dev/null +++ b/vdn/networks.bak/firewall-buster/build @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +set -eu + + +build() { + local n + + for n in tiny bigboss societe web lambda nomade; do + vdn-build $n + vdn-config $n GUEST_SYS "debian/buster" + vdn-config $n MEMORY "256" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "0" + vdn-config $n SET_PROXY "0" + done + + n=tiny + vdn-config $n NETWORKS "none \$NET_2#192.168.30.16/24" + vdn-config $n MEMORY "2048" + + + n=bigboss + vdn-config $n EXTRA_SERVICES "apache2 proftpd nfs-server isc-dhcp-server haveged" + + vdn-config $n NETWORKS "\$NET_2#192.168.30.2/24" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=societe + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "1" + vdn-config $n MEMORY "512" + vdn-config $n EXTRA_SERVICES "proftpd" + vdn-config $n NETWORKS "\$NET_G#20.X3.Y3.Z3/8 \$NET_1#192.168.1.1/24 \$NET_2#192.168.30.1/24" + + n=web + vdn-config $n NETWORKS "\$NET_1#192.168.1.2/24" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=lambda + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "1" + vdn-config $n NETWORKS "\$NET_G#20.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=nomade + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE "1" + vdn-config $n NETWORKS "\$NET_G#20.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + +} + diff --git a/vdn/networks.bak/firewall-buster/net.svgz b/vdn/networks.bak/firewall-buster/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..e3136807c0b11c310d3ba9db811486c6ae7561e3 GIT binary patch literal 33387 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

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + " + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/firewall-buster/scripts/baseConfigLambda b/vdn/networks.bak/firewall-buster/scripts/baseConfigLambda new file mode 100644 index 0000000..18c2963 --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/baseConfigLambda @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de lambda (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="lambda" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + systemctl restart apache2 + " + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/firewall-buster/scripts/baseConfigNomade b/vdn/networks.bak/firewall-buster/scripts/baseConfigNomade new file mode 100644 index 0000000..17ba0e6 --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/baseConfigNomade @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de nomade (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="nomade" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + # Page d'accueil du serveur web + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + systemctl restart networking + systemctl restart apache2 + " + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/firewall-buster/scripts/baseConfigSociete b/vdn/networks.bak/firewall-buster/scripts/baseConfigSociete new file mode 100644 index 0000000..e1ff0cf --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/baseConfigSociete @@ -0,0 +1,158 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de societe (hostname, hosts, interfaces)." + + +setFirewall() { + vdn-ssh root@societe ' +cat << EOF > /etc/network/fw-start +#!/bin/sh + +set -x + +# Vide les tables + +iptables -F +iptables -t nat -F +iptables -t mangle -F +iptables -X + +# fixe les politiques par défaut + +iptables -P INPUT DROP +iptables -P FORWARD ACCEPT +iptables -P OUTPUT ACCEPT + +# spécifique à VDN (Début) + +iptables -A INPUT -i eth3 -j ACCEPT +iptables -A OUTPUT -o eth3 -j ACCEPT + +# spécifique à VDN (Fin) + +# Autorise l''interface loopback + +iptables -A INPUT -i lo -j ACCEPT +iptables -A OUTPUT -o lo -j ACCEPT + +# Log + +iptables -A INPUT -j LOG --log-prefix "fw INPUT " + +EOF + +chmod 755 /etc/network/fw-start + +cat << EOF > /etc/network/fw-stop +#!/bin/sh + +# Vide les tables + +iptables -F +iptables -t nat -F +iptables -t mangle -F +iptables -X + +# fixe les politiques par défaut + +iptables -P INPUT ACCEPT +iptables -P OUTPUT ACCEPT +iptables -P FORWARD ACCEPT + +EOF + +chmod 755 /etc/network/fw-stop + +/etc/network/fw-stop + +sed -i -re "s/#(net.ipv4.ip_forward=1)/\1/g" /etc/sysctl.conf +sysctl -p + +' + + # enable ipv4.ip_forward + + #vdn-ssh root@societe "echo 0 > /proc/sys/net/ipv4/ip_forward" + +} + + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="societe" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + setFirewall + + + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade +$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) societe + +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.30.1 + netmask 255.255.255.0 + +EOF + + vdn-ssh root@$name "systemctl restart networking" + vdn-ssh root@$name "systemctl enable proftpd; systemctl start proftpd" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/firewall-buster/scripts/baseConfigTiny b/vdn/networks.bak/firewall-buster/scripts/baseConfigTiny new file mode 100644 index 0000000..fe94899 --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/baseConfigTiny @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de tiny (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="tiny" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.30.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth1 +iface eth1 inet static +address 192.168.30.16 +netmask 255.255.255.0 +gateway 192.168.30.1 +EOF + + vdn-ssh root@$name "systemctl restart networking" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/firewall-buster/scripts/baseConfigWeb b/vdn/networks.bak/firewall-buster/scripts/baseConfigWeb new file mode 100644 index 0000000..8fa6ca9 --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/baseConfigWeb @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base de web (hostname, hosts, interfaces)." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="web" + + startAndWaitSsh $name + + setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos lambda PUBLIC_IP) lambda +$($VDN_PATH/bin/vdn-infos nomade PUBLIC_IP) nomade + +192.168.1.1 societe +192.168.30.2 bigboss +192.168.30.16 tiny + +192.168.1.2 web +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 + gateway 192.168.1.1 +EOF + + vdn-ssh root@$name " + echo \"

Bienvenue sur le serveur Web de $name !

\" > /var/www/html/index.html + + systemctl restart networking + systemctl restart apache2 + " + + + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/firewall-buster/scripts/configAll b/vdn/networks.bak/firewall-buster/scripts/configAll new file mode 100755 index 0000000..9207bfd --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/configAll @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +set -eu + +DESC="Configuration de base pour le TP DMZ." + +SYSTEMS="bigboss lambda nomade societe tiny web" + +setFirewall() { + vdn-ssh root@societe ' +cat << EOF > /etc/network/fw-start +#!/bin/sh + +set -x + +# Vide les tables + +iptables -F +iptables -t nat -F +iptables -t mangle -F +iptables -X + +# fixe les politiques par défaut + +iptables -P INPUT DROP +iptables -P FORWARD ACCEPT +iptables -P OUTPUT ACCEPT + +# spécifique à VDN (Début) + +iptables -A INPUT -i eth3 -j ACCEPT +iptables -A OUTPUT -o eth3 -j ACCEPT + +# spécifique à VDN (Fin) + +# Autorise l''interface loopback + +iptables -A INPUT -i lo -j ACCEPT +iptables -A OUTPUT -o lo -j ACCEPT + +# Log + +iptables -A INPUT -j LOG --log-prefix "fw INPUT " + +EOF + +chmod 755 /etc/network/fw-start + +cat << EOF > /etc/network/fw-stop +#!/bin/sh + +# Vide les tables + +iptables -F +iptables -t nat -F +iptables -t mangle -F +iptables -X + +# fixe les politiques par défaut + +iptables -P INPUT ACCEPT +iptables -P OUTPUT ACCEPT +iptables -P FORWARD ACCEPT + +EOF + +chmod 755 /etc/network/fw-stop + +/etc/network/fw-stop +' + + # disable ipv4.ip_forward + + vdn-ssh root@societe "echo 0 > /proc/sys/net/ipv4/ip_forward" + +} + + +run() { + #setErrorHandler + #echoStart + + ### Configuration de base (hostname, hosts, interfaces) + + requireSshGuests $SYSTEMS + + #setFirewall + + + ### Page d'accueil des serveurs Web + + #for i in lambda web bigboss; do + # vdn-ssh root@$i " + # echo \"

Bienvenue sur le serveur Web de $i!

\" > /var/www/index.html + # " + #done + + # Construction de la liste des commandes + L="" + for i in $SYSTEMS; do + n=$(echo $i | cut -b 1 | tr -s '[[:lower:]]' '[[:upper:]]') + n="$n$(echo $i | cut -b 2-)" + L="$L baseConfig$n" + done + + + vdn-scripts $L + + + ### /etc/network/fw-start /etc/network/fw-stop + + #setFirewall + + ### A COMPLETER ### + + + #unsetErrorHandler + #echoDone +} + diff --git a/vdn/networks.bak/firewall-buster/scripts/repairAll b/vdn/networks.bak/firewall-buster/scripts/repairAll new file mode 100644 index 0000000..2447a49 --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/repairAll @@ -0,0 +1,192 @@ +#!/usr/bin/env bash + +DESC="TP firewall" + +SYSTEMS="bigboss tiny web societe lambda nomade" + +repairQ0() { + vdn-ssh -t root@societe " + cat << EOF > vide.sh +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat +EOF + +chmod 755 vide.sh + +./vide.sh +" +} + +repairQ1() { + vdn-ssh -t root@societe " +cat << EOF > local.sh +#!/bin/sh + +iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh + +./local.sh +" +} + +repairQ2() { + +cat << EOF > /dev/null + +# Solution alternative qui valide les tests +# Semble nécessiter plus de mémoir, à vérifier + +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -i eth0 -m state --state NEW -j REJECT + +EOF + + vdn-ssh -t root@societe " + +cat << EOF > fermeDehors.sh +#!/bin/sh + +iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh +iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS +iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Mail +iptables -A INPUT -p tcp --dport 993 -j ACCEPT # Imap sur ssl + +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + +iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT +iptables -A INPUT -m state --state RELATED -j ACCEPT + +iptables -A INPUT -i eth0 -j REJECT +EOF + +chmod 755 fermeDehors.sh +./fermeDehors.sh +" +} + +repairQ3() { + vdn-ssh -t root@societe " +cat << EOF > forward.sh +iptables -t nat -A PREROUTING -p tcp -d $IP_SOCIETE_PUBLIC --dport 80 -j DNAT --to 192.168.1.2 +EOF + +chmod 755 forward.sh +./forward.sh +" +} + +repairQ4() { + vdn-ssh -t root@societe " +mv local.sh local-1.sh +cat << EOF > local.sh +#!/bin/sh + +iptables -s 192.168.30.0/24 -t nat -A POSTROUTING -o eth0 -j MASQUERADE + +iptables -s 192.168.1.2 -p tcp --dport 80 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 53 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -s 192.168.1.2 -p tcp --dport 25 -t nat -A POSTROUTING -o eth0 -j MASQUERADE +EOF + +chmod 755 local.sh +./vide.sh +./fermeDehors.sh +./forward.sh +./local.sh +" +} + +# Partie 2 : IPv6 + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + +repairQ5() { + + # réinitialise les interfaces + echo "Repair Q5. Config IPv6... please wait..." + + vdn-ssh root@bigboss "systemctl restart networking" + vdn-ssh root@web "systemctl restart networking" + vdn-ssh root@societe " + echo 1 >/proc/sys/net/ipv6/conf/all/forwarding + systemctl restart networking + " + + # Ajoute les adresses IPv6 "locales uniques" en utilisant le suffixe + # de l'adresse "lien local" + # + # * la DMZ (web) aura le préfixe fc01 + # * le réseau interne (bigboss) aura le préfixe fc00 + # + # La fonction routage IPv6 est activé sur société + # et les routes par défaut sont fixées sur web et bigboss + # + # un ping6 de bigboss vers web valide la config. + + ipSocieteWeb=$(getIPv6 societe eth1) + ipSocieteWeb=$(echo $ipSocieteWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteWeb/64 dev eth1" + + ipSocieteBigboss=$(getIPv6 societe eth2) + ipSocieteBigboss=$(echo $ipSocieteBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@societe "ip -6 addr add $ipSocieteBigboss/64 dev eth2" + + ipWeb=$(getIPv6 web eth0) + ipWeb=$(echo $ipWeb | sed -re 's/fe80:/fc01:/') + vdn-ssh root@web "ip -6 addr add $ipWeb/64 dev eth0" + + ipBigboss=$(getIPv6 bigboss eth0) + ipBigboss=$(echo $ipBigboss | sed -re 's/fe80:/fc00:/') + vdn-ssh root@bigboss "ip -6 addr add $ipBigboss/64 dev eth0" + + vdn-ssh root@web " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteWeb" + vdn-ssh root@bigboss " + ip -6 route del ::/0 &> /dev/null + ip -6 route add ::/0 via $ipSocieteBigboss" + + #vdn-ssh root@bigboss "ping6 -c 3 -I eth0 $ipWeb" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + + IP_SOCIETE_PUBLIC=$($VDN_PATH/bin/vdn-infos societe PUBLIC_IP) + + repairQ0 + repairQ1 + repairQ2 + repairQ3 + repairQ4 + repairQ5 + + unsetErrorHandler + echoDone + + sleep 1 + +} diff --git a/vdn/networks.bak/firewall-buster/scripts/testAll b/vdn/networks.bak/firewall-buster/scripts/testAll new file mode 100644 index 0000000..7e72b8d --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/testAll @@ -0,0 +1,136 @@ +#!/usr/bin/env bash + + +DESC="Test du firewall/IPv6." + +SYSTEMS="bigboss lambda nomade societe tiny web" + + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur lambda ... ?" 'vdn-ssh root@lambda "timeout 1 lynx -dump lambda &> /dev/null"' + vdnTest "Serveur web sur nomade ... ?" 'vdn-ssh root@nomade "timeout 1 lynx -dump nomade &> /dev/null"' + vdnTest "Serveur web sur web....... ?" 'vdn-ssh root@web "timeout 1 lynx -dump web &> /dev/null"' + echo + vdnTest "societe en routeur........ ?" 'vdn-ssh root@societe "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ0() { + tput reset + echo "[Test Q0 : Le grand nettoyage]" + echo + vdnTest "/root/vide.sh existe ..... ?" 'vdn-ssh root@societe "test -e /root/vide.sh"' + [ $? -eq 0 ] && { + echo + echo "Remarque : A vous d'exécuter le script !" + } + echo + echoDone +} + +testQ1() { + tput reset + echo "[Test Q1 : NAT]" + echo + vdnTest "Présence de /root/local.sh .. ?" 'vdn-ssh root@societe "test -e /root/local.sh"' + + [ $? -eq 0 ] && { + echo + echo "Remarque : A vous d'exécuter le script !" + echo + } + + vdnTest "bigboss -> lambda ........... ?" 'vdn-ssh root@bigboss "timeout 1 lynx -dump lambda &> /dev/null"' + vdnTest "web -> nomade ........... ?" 'vdn-ssh root@web "timeout 1 lynx -dump nomade &> /dev/null"' + echoDone +} + +testQ2() { + tput reset + echo "[Test Q2 : Fermeture]" + echo + vdnTest "/root/fermeDehors.sh existe ........ ?" 'vdn-ssh root@societe "test -e /root/fermeDehors.sh"' + [ $? -eq 0 ] && { + echo + echo "Remarque : A vous d'exécuter le script !" + echo + } + + vdnTest "Filtrage des entrées sur societe ... ?" 'vdn-ssh root@nomade " + { timeout 1 nmap -p 21 societe 2>1 | grep --line-buffered -q filtered; } + && + { timeout 1 nmap -p 22 societe 2>1 | grep --line-buffered -q open; }"' + echoDone +} + +testQ3() { + tput reset + echo "[Test Q3 : NAT]" + echo + vdnTest "/root/forward.sh existe... ?" 'vdn-ssh root@societe "test -e /root/forward.sh"' + [ $? -eq 0 ] && { + echo + echo "Remarque : A vous d'exécuter le script !" + echo + } + vdnTest "nomade -> societe (web) .. ?" 'vdn-ssh root@nomade "timeout 1 lynx -dump societe &> /dev/null"' + echoDone +} + +testQ4() { + tput reset + echo "[Test Q4 : Contrôle des sorties]" + echo + vdnTest "Filtrage des sorties de web ?" 'vdn-ssh root@web " + { ! timeout 1 nmap -p 22 nomade 2>1 | grep --line-buffered -q open; } + && + { timeout 1 lynx -dump nomade &> /dev/null; }"' + + echoDone +} + +# Partie n°2 + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | head -n 1 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + +testIPv6() { + + ipWeb=$(getIPv6 web eth0) + vdn-ssh root@bigboss "timeout 1 ping6 -c 1 -I eth0 $ipWeb &> /dev/null" +} + + +testQ5() { + tput reset + echo "[Test partie n°2 : IPv6]" + echo + vdnTest "ping6 bigboss -> web ?" 'testIPv6' + echoDone +} + + +run() { + + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ0 testQ1 testQ2 testQ3 testQ4 testQ5 +} + + diff --git a/vdn/networks.bak/firewall-buster/scripts/testAll-fast b/vdn/networks.bak/firewall-buster/scripts/testAll-fast new file mode 100644 index 0000000..7e72b8d --- /dev/null +++ b/vdn/networks.bak/firewall-buster/scripts/testAll-fast @@ -0,0 +1,136 @@ +#!/usr/bin/env bash + + +DESC="Test du firewall/IPv6." + +SYSTEMS="bigboss lambda nomade societe tiny web" + + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur lambda ... ?" 'vdn-ssh root@lambda "timeout 1 lynx -dump lambda &> /dev/null"' + vdnTest "Serveur web sur nomade ... ?" 'vdn-ssh root@nomade "timeout 1 lynx -dump nomade &> /dev/null"' + vdnTest "Serveur web sur web....... ?" 'vdn-ssh root@web "timeout 1 lynx -dump web &> /dev/null"' + echo + vdnTest "societe en routeur........ ?" 'vdn-ssh root@societe "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ0() { + tput reset + echo "[Test Q0 : Le grand nettoyage]" + echo + vdnTest "/root/vide.sh existe ..... ?" 'vdn-ssh root@societe "test -e /root/vide.sh"' + [ $? -eq 0 ] && { + echo + echo "Remarque : A vous d'exécuter le script !" + } + echo + echoDone +} + +testQ1() { + tput reset + echo "[Test Q1 : NAT]" + echo + vdnTest "Présence de /root/local.sh .. ?" 'vdn-ssh root@societe "test -e /root/local.sh"' + + [ $? -eq 0 ] && { + echo + echo "Remarque : A vous d'exécuter le script !" + echo + } + + vdnTest "bigboss -> lambda ........... ?" 'vdn-ssh root@bigboss "timeout 1 lynx -dump lambda &> /dev/null"' + vdnTest "web -> nomade ........... ?" 'vdn-ssh root@web "timeout 1 lynx -dump nomade &> /dev/null"' + echoDone +} + +testQ2() { + tput reset + echo "[Test Q2 : Fermeture]" + echo + vdnTest "/root/fermeDehors.sh existe ........ ?" 'vdn-ssh root@societe "test -e /root/fermeDehors.sh"' + [ $? -eq 0 ] && { + echo + echo "Remarque : A vous d'exécuter le script !" + echo + } + + vdnTest "Filtrage des entrées sur societe ... ?" 'vdn-ssh root@nomade " + { timeout 1 nmap -p 21 societe 2>1 | grep --line-buffered -q filtered; } + && + { timeout 1 nmap -p 22 societe 2>1 | grep --line-buffered -q open; }"' + echoDone +} + +testQ3() { + tput reset + echo "[Test Q3 : NAT]" + echo + vdnTest "/root/forward.sh existe... ?" 'vdn-ssh root@societe "test -e /root/forward.sh"' + [ $? -eq 0 ] && { + echo + echo "Remarque : A vous d'exécuter le script !" + echo + } + vdnTest "nomade -> societe (web) .. ?" 'vdn-ssh root@nomade "timeout 1 lynx -dump societe &> /dev/null"' + echoDone +} + +testQ4() { + tput reset + echo "[Test Q4 : Contrôle des sorties]" + echo + vdnTest "Filtrage des sorties de web ?" 'vdn-ssh root@web " + { ! timeout 1 nmap -p 22 nomade 2>1 | grep --line-buffered -q open; } + && + { timeout 1 lynx -dump nomade &> /dev/null; }"' + + echoDone +} + +# Partie n°2 + +# Fonction utilitaire : Récupère l'adresse IPv6 autoconfigurée +# $1 : host +# $2 : interface +# Exemple : getIPv6 bigboss eth0 + +getIPv6() { + echo $(vdn-ssh root@$1 'ip -6 addr show dev '$2' | grep inet6 | head -n 1 | tr -s " " | cut -d " " -f 3 | cut -d "/" -f 1') | sed -re 's/[^[:print:]]//g' +} + +testIPv6() { + + ipWeb=$(getIPv6 web eth0) + vdn-ssh root@bigboss "timeout 1 ping6 -c 1 -I eth0 $ipWeb &> /dev/null" +} + + +testQ5() { + tput reset + echo "[Test partie n°2 : IPv6]" + echo + vdnTest "ping6 bigboss -> web ?" 'testIPv6' + echoDone +} + + +run() { + + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ0 testQ1 testQ2 testQ3 testQ4 testQ5 +} + + diff --git a/vdn/networks.bak/fixme-bookworm/appolo.conf b/vdn/networks.bak/fixme-bookworm/appolo.conf new file mode 100644 index 0000000..2e4e6f2 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/appolo.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=4 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_2#192.168.3.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bookworm/brightside.conf b/vdn/networks.bak/fixme-bookworm/brightside.conf new file mode 100644 index 0000000..e73afd8 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/brightside.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=7 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#W2.X2.Y2.Z2/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bookworm/build b/vdn/networks.bak/fixme-bookworm/build new file mode 100755 index 0000000..b014f23 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/build @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +set -eu + +netLocal="192.168.2." +netDMZ="192.168.3." + + +build() { + local n + + for n in distributeur client comanche castafiore appolo passerelle darkside brightside; do + vdn-build $n + vdn-config $n GUEST_SYS "debian/bookworm" + vdn-config $n MODE "tgz2" + vdn-config $n HDA "DebianBookworm.disk" + vdn-config $n MEMORY "256" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE 0 + vdn-config $n SET_PROXY "0" + done + + # local + + n=distributeur + vdn-config $n NETWORKS "\$NET_1#192.168.2.2/24" + vdn-config $n EXTRA_SERVICES "ssh isc-dhcp-server" + vdn-config $n ON_BOOT '[ -e /etc/start ] && { echo Run /etc/start >&2 ; . /etc/start & }' + + n=client + vdn-config $n NETWORKS "\$NET_1#192.168.2.3/24" + + n=comanche + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n NETWORKS "\$NET_1#192.168.2.4/24" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + # DMZ + + n=castafiore + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n NETWORKS "\$NET_2#192.168.3.3/24" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + + n=appolo + vdn-config $n NETWORKS "\$NET_2#192.168.3.2/24" + + + # Gateway + + n=passerelle + vdn-config $n NETWORKS "\$NET_G#W3.X3.Y3.Z3/8 \$NET_1#192.168.2.1/24 \$NET_2#192.168.3.1/24" + + + # Externe (Internet) + + n=darkside + vdn-config $n NETWORKS "\$NET_G#W1.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + n=brightside + vdn-config $n NETWORKS "\$NET_G#W2.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + +} + diff --git a/vdn/networks.bak/fixme-bookworm/castafiore.conf b/vdn/networks.bak/fixme-bookworm/castafiore.conf new file mode 100644 index 0000000..d1fcfbe --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/castafiore.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=3 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_2#192.168.3.3/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bookworm/client.conf b/vdn/networks.bak/fixme-bookworm/client.conf new file mode 100644 index 0000000..ed1e822 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/client.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=1 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.3/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bookworm/comanche.conf b/vdn/networks.bak/fixme-bookworm/comanche.conf new file mode 100644 index 0000000..e01bf3f --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/comanche.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=2 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.4/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bookworm/darkside.conf b/vdn/networks.bak/fixme-bookworm/darkside.conf new file mode 100644 index 0000000..289b7e0 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/darkside.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=6 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#W1.X1.Y1.Z1/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bookworm/distributeur.conf b/vdn/networks.bak/fixme-bookworm/distributeur.conf new file mode 100644 index 0000000..d280780 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/distributeur.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=0 + +# Chemin du premier disque du système. + +HDA="DebianBookworm.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bookworm" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="[ -e /etc/start ] && { echo Run /etc/start >&2 ; . /etc/start & }" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="ssh isc-dhcp-server" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bookworm/graph.svgz b/vdn/networks.bak/fixme-bookworm/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..40949c5ef9d883b5c10fa4774c9824d580af74d5 GIT binary patch literal 1738 zcmV;*1~vH~iwFn}^3Gxa17~t!aA+=bc4q*sSle!#NDzJZSM;*VDv>-*Ux9W!iIhn; zinNzV>uln@jXih<1%t&9U-I>P3K);gKn(W2V9Hc8)u&EXo#ycM^?AxJ<6@oU+0>I< zcr4CN^F@*^r{1Td-zSmB*5y1~%+oxJr(TwOuV3vQ{_^(k+0pUGcWiyRWFJ4h`QyWk zc@y9NtY^Oe_UJA9=im2Ca_Rf;{_^&iw<^nv1K+>8y5d)w=f%>0U(7F7$?4jMr%#?( z<>PHq@>uJYsln{cVZ(I(p(Q(y!@Tci~y>3j8mBl<;pXJ5* z)LWm<)A+e$@&zmM5^!M0_4AYr!)y>Dz8Cb$lD7ZqnLhOEyS>AUJiS>0t+OOer{2{n zDPziMk$*!ztG8Uti#P)y7kQGEh+ty&4Z~$pzZWPVL9%UDF2?g4+)wA=$yt&YagBGq zw=7@8@^))vZG+sd=nFOj=eDt?lrErivyIdSmb+koVgk*>h#41jnkppo*12U?&ecB3 z__}0tnas1(RbEWJ^JK9|5d&CZwd5x7*bM<>6c;Fsvpg#&XY=zU#ea{I^LV|#j*H~1 zd9qG^AZ}?uCGY-r@f-L(f7yVi+L);x%+waDp9X7;paQZsY&$ zS7TrPwk%)X3p-vc@1&Znu2gT=-bwnrTy6#`?rEMk8f}A@L|xjHt?-M1I6{YYPhqd7C54f zis?Z`46Fr(0=Ie-sNhzOtA!6)85dbx_UG}I)S_Jws;3}!SB@(OtpH<{D6Ybp7LE%v zXt3WIrijgYeT7lvO;ch8f|(WF$IGRgJn^=av}^!&1or{xy~s9a+1PBV)VS7HqPO zSI~o(99SeWbi9dFJ2zsu)iomfGkZ&M*)9&j9 zF#0kKjf|2dxq~Gsu@5IyMgcdQLE$u)Ppyv4q=1y|oD`>N0%_JxcGy=OmG`4d12Z)Q z7&K}vW~%A1s!18J#`C^adp-O-;5S96&Y!$s;#{6Yn3~Jsu=mw=B5;I&l%F=}tF} zdI+~&@px&1)~ZRXA!?`5VmnP024rrWTW0M%pdSMO-AH)lC`IF_cW=AB;PuPnu!n+O zYscz=keEh_&PFpGkjf!kz|N2vQMEj+=pi#&fQ|drvA_+Wp$;I3%?31u7e0xG>W(^= z574k*SJ~l6j#O3(^C60AiUrY3MVJh*sQ(2_g@PNBR+yF%q?JX(gJlhl8w2PEf75h6 zg@TrY>DQ;NH23NcY0$tDNhP&U0sJZ*V7xfD<0h&NvqH&3RIv& z-C(}%TBv5S8qfPyJQQy-8Fdc;$USn)54A1nSv@HxhzcLH!QENut*^t&S%7Q>Vsu z{;KY;Qwg@0oP00i@5K)9`ab5~UG!-7(J4ZM6_9q~-kmmdS3SOSTRk5jU>v`l6mGQU zYi;Z&SoIItJJs6y4Ai-N9P#MjPU?=DoSaF_RVqRqhScSxsihyrs;*BUhLFRFO$=b3 g1oPa6de&8K?|(Xh>{743tS|BBKhv^o!j~EV0MgT4a{vGU literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/fixme-bookworm/net.svgz b/vdn/networks.bak/fixme-bookworm/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..c02c25daaef018205367b2a6a440d5d256548ad4 GIT binary patch literal 14685 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 ed7T{DqDA0wJS%7DkSZ`3IHInB{ z$nHVC;Rs~62Gk5?mSCCXAYlGhb(Xrxxr{nX?6mXu*I6R{@P|5!S7$kX->^NZokO9e zMWLm2?}igGlDjJ{Ok_lzo@=FriLAQ~E~(PO#E?TuskHcq*$tJJ7L^tz@|6uPq|(A< z*23|bS6W!>lX8Yi%Ytz^RsUI6TA0kZt@xC!WF#xj^5KF`J}VyKR1R>^g>Y(UMweD; zVHwdtmr`kAt${!%l2(Y3eUT*x)*6*_CS>;jrF`;PX5wupIokOw_2}y|DlJKM5bv5j z4rqxSz&Vs!)}@w%EP_^*7SnzNL#3rfrR7X*r2c(6VCPkU~l+ zw1~jr-9w=zq0l0DzN*266j}t&S~ouPLW|%zmH!15S_IFj`p>%1B6!A)#iwi~BS~?Q z4;FOtN%0t`hVnrwr-p8HX@wS%5e#%Gg%;5o2XrE7g$UWLu{>u&b`L5J#~`~0`?gL# z$4m}$JVmQQOWonSj5oQ}v&9p+&0<+W#D^WF#rBRR(2$CQ0!Kr*t;I{_HuGLBF2~r*;=ww9cT= zFRaj_bz9ATB58#f*=-f|d5~?|YTYv-yR8a65wat>Gn3K5J=xq@EU{sR#KwM!4KpM* z+9o#akl1LE*sw!lV?RIGp1L0#EY|x3M6=GzcX_Y!g_L(M;Vq_m1c=OBEbawaV zUcEg}?_c15*H4qj+4Rf(?CT#^RD5_ayxN+o#F&`73znn_vFx`S}r(=^GzoB36U$m%^;_W$Q1$qpu6z zo-tN$emQ-<{rm`XQGBi@-}{835IDQgoS_f_HpsW zr`i3-Par^S{n6q9tM_l8p1*#4MV8-99#%YGJ@)JU6R@CIJb_x)VASG@<)gqvZn@$c z);q#qeMgsd@!j41ym*|ve!PDw=Fczdd%VvdW_R=87q8VA0^i&`&*wO2+eYv>`F8(! z|F79}J*~)@N{*JiSxE5XY(AMz=99IwE^tMbn6?e+hDe*Jy9 zHbx`7U~=>P83w#6Gr@J!+iSGHllgD=k066rZ(lzC_iv96ux?gg)GnTXf0?a+wEEfC z+1vBy*W1~zA3n|JFV|OBFP~o@%IDXQ@FVblkN0@f)ql+IA0GaK5An)Siyyt8Kg_(^ z)YW42%i57g+%H#4>fO7K8~lBk+{_++{qV=h!~gp{8#R{9$Jgi2FOSdD*+Qg0teIL9 z@%h>>aW5Yx^VyGuz~v;h29E?-UxHJ?Adp&40O-yoQHzq_V1u!3?g9DSM0KP@l8)iV-Am(&Pu#^4*4Ol!+Wx1&OWzX@XodR0#m6)i0Cz=hxX zy8ZP03i3IfJ}j4oA@~=j+)Iehn@JA5z)+2O4g=3OhQSJ*%|DS5Sd)?}puJ>QO#E_% z4-awZ@!|Rn9TS*OP;9f;FS9V6_EeNb_2Auly$LYLCyFX~MN0>98&g{&Un zFI4W9ir*6zWs5O*5+%GLLP~i@7^Y6Eg6;{W=LlY^uEu>LkUs4c_tunt?; zxqE?89%%>giDD+;3!)!fvb;Ui^PT3DAaL@PVH80BO(m6L&G&uWLQ?N&~p%p@+1ny?50x`VJl&S9mT z7L4AZo;bz$Nb0ec2!R($gLdMjWk%6)K}AU=(<53MP>pI_C``J;HJev7loJmko)4m& z_DqFv;$RNa=czUZepi?ley3L*Ju$yibnACA+%X}+=m~N5${h`vkoA~GDtJ<@Thda5 z7!iVZrQGphbVIo}hP!3JDa!q?&oJmz&7P1XzvHvp8QCjI4vcgEDC>Qa+-_P30osWP zPI=Qppl1l4YE9x4g4m?ra|BC(N`OriUM&@qkm>4C+M)*giEUnvv_S;{cK>D6$^Kb^GVZ=4e zDW0f=Rvhdx#1#sxIE0N9Y?&Sx8dW~mW(2bn__$%bsc+}{S;zoSuhdkEy7>loR7>M| z%2D%8J&@xz`>lzw+3mM#rSY|0+HWwU|A&|V$;*H8D{}<%4YIbyd~?0Yr7q0(TFGZK z-QeG zUD9HNMmSB^G0g8?9a1t@fMKLscdBGylE5enqA40|rl~fpPgeeub*f~R2_V6@ z=oq=lqf=EeusEfWd_%NYX$;}IAwl3xS#PWFfprW#O&4}U$utJMWymQ?=Ei}i-tMOt zlmcpIs252fz19solR(8E}@`;ham<@Wiv2Alz^YB9N^lW^50CihS!Cm;dL zlK>i#fWM6lMn_ySIR^I|vlYUO{y5SWS3itl48l=L&A5f&3O*CSjIk9EKq+F?NDGXd zn1#D<_j(s^^ZTLzpGIj#M{VB|E2SRN5m0s|Xc&n{C?Mx`Y> zBx06y2pltZqjJz3?v??kh}h)i<@w=xC0=a-*IUPeJ1R^R#8w+ika|npe&-?eeGtJ% z3^(VtrdurpJKXr^-FvC;J#Yx`NPTZ)rJBRtGT;=!|I^?8*(x2i*ddyb5ILz#)%x>g zo(e)vA-PJ-Qz=CeBxLGQ00g{R6SX5z^)h*b^)h>Sm~{;|ya0P9ZCP&yg!nNDv!^r- znKK&99~}s6xVed-G1@KTOM0t812LhKlV2Vt0QCYV@v=%8&fU@;G_O?^{1$ao2hh_=WtvEAsOUKZwQ z`Jc4>C+$~Z{%l+&3yTCdTiCi}@se?Anh_9I=DV!R*FB}?V7Cl6#Z{V4UVp!^nta1m zYFU#9)`R&}x(@UP-NdP-yEZW|SRE+p2Ftas-;iFGYZvdZZG$vYsxc+pmP`|`O*B&a zktz=E#H!i~Uhw_Pn^&C0A~YC#=_AKpzqy{iAgEOP@`F8vI4E67De-eVw{GKN2?3uV zzH|oYSd1U{LttxDt8qsOc58FoKZ7=#eVIKy zPp2E}$C)i5nb&MzQN_5~;79?i!s<+|Y#eMXBViIb zAH#wrT%@t#hspGYOeRgDR|`?xh^d$ac>t5t6CNzY0=rRzm0NYD#@AAUHzLL$R@%oP z>|#ny5$PL!r$h9Et1C~3evXNhJ?MAqWTRV~we+V=%?w&u$&i$Qt@63#dza}x-*N*i zaKV6s>CSu@6<`k(L?YmhA{bqioH;tJ9a)@j0+9&#NO)`n_(|}+me{ve6E*@>D?xq0 z1dKp=xHiec$PwHOKab6TM-KZw#%{=J1ou-2H3dSFyDvGb1WWBLr$hq3j5|JL5M(10!U00szE1Kqle1->x)3 zC_GSORecQ3I%oKX5dmxi6X2HQ!=2CK8?UofT}{xSAye?dH`D!p{6lh;u~=4P@%vgd>CP*$i}c(q^@ou z(rGzrP$^kL#|-Bf6%k>J*M9~LLkYDm*2hahTe%CgagB5>XjgnoEyzlB%U?%eYACLL zPz4$_3%tj}AzIG@2s`LWfU{NpN6%ct82r0DgEq6Qm-7SBGTet#m z1x!6UVt+&kA~C2JfDC~@$QQ)eiZoWe6NzdeI<20+x}Gde;0g7~YNHAklbTDC{|0MX zQ;Mnp>norhE$Dkt1Q5{*U>P;oQen&pI#yzYxiWBl@jNSZ6S?z*F%?S$Y72%(rNB=i z6x97NtA01AXxA)}9C&Z7-C_MK-);R`DFWQ9-Xs49{d2K!f|#WodsHwya;!kyDM<{e z15OYgub1cpDVb9@f=9*BH8)gOx{MXSMRjj_=o zPB5|$6zl^kdhXmZ&f#N>3T5>v1cd0rp>LtE0EEf{Lr1p!$v?YCuQ?OL2+M%XJ+cB?Dqck*5AGN zisw}rZk4gz$6eiiU!KW9YT0e{+uVVp#MIiMg#0$n>GD)XC0#6ppcIO$3HKSd@Y^;Q zj}18sA?kJA$RC}0PGD6*$Y9&l!y42_oc%TRv|rRy@JiLYsZU7sRn#-yE9wcDR`YJ^ zQ|+f_x;xlYrb|xIMqmnuRXG{MU8F_@){6*yTZuPj zYm}=zVPrTzDdSb`%w18{(cFoS_#^NJ3o+HN7yhIE zjEEr!y}sb!m~rpnP2qSydc9Cl=%_&2g;>61(lLpWil>e<)flU9t1&HZ#|JJL?LJ>WqF4?A zUzi0uR@W4(i%2#33sT)TIGEKNd|*XbHQI_ZcC`N9QA3x%QVnRuZ|`9!R6@CdgG_yL z3)eaN?vP%rBvnl(xTx9OIjB<~1 zc^k$>^|Gj5uP>)nFyK-V$({Ppr9$@}yd;$s>ENZh&oIE34gp_+8Bs0aOUjz} z!k04Iwypt8Qj<_Ay>kFl#>J5n!UXJLhlDT{IZN3Ch$-EJmAED6U?8RQ;}R)m%7M@lpVlKK{*Z;w0EizO5O`*%IH0uEu5)f=KyHRIMY3X zG-Xsu9fO*5@>Uu}Wsws|+B;a2rjbZ?A6QdH$>t5H5Wvyo*TrvTiG)qVZE&)!3=@tDsAWoX4DoxEc z@;zq&azbolk&N%-v@QSx&}jfV4M3*>=rjPGR*G^7bn+DCyP!^%f!hp5YAi8ZDuWG~ z3VR7Sr&KpZIN(=L@GVEhIoZB&;b=Ig6GD3B#yN?0IH!DRq5;dT1qMl=nIv~&~7i{lDfKJ9lIv%tKI$ci7ra~u|+htxr=m2$UO0wOB z`wid0-Vb%kIjiT2b;{TH=$KfiL$o^T0oEyB*{)--lS$dDvI0BhY}eB}u#*XH5_vD! zDL+K98?ckHExI^m-LPWo%#iL$pLq=BpL1lcB5bP z=YTue*q)CX+)4I|{v2>88{8|f4erzU)PnJf${wM#PipJ>p4`l-Bku#8bYaz<_w#IwQd|e|9zLCu;A4^}2EbFRvpI+|2LwFj%441e;7Ji3fikxS zJjFXFpAFtAH9zh;JLNpia=<$U1bG+yH++Y9H{L1dq@FF@DW9c0Cf+F@vaL^eCvu{2 zCs@77EqtiV+QO%Aa3^5JzM$n@aHssMwiCFMf@rh_+$pCQe{{GL(BAB3djPmozrZdT z&`!X(WUvod{eGdnGJu_c{$#KZ_I5hE=1#zXbhHoeQ*)y{XeUL2+Xc3vokV}=&xdwO z#yf6yw;Rw-1KMdoI}K>30qwL>lq<9o$%A&{#+JfT2_dC$E5mL%$4*@Y-YL2L1h6E2 z^3Wv!o_ceh-_Zb1>~uJg8}QUT%YFArb{SiD4uGct@N{N?r(PBK4hVQ^bCwn3!zKr<*dD=cDZEKcH>|L{5L7wt;>ggQv1Z%Aqkf(fG!Lvf1m}nmDkQ4Hhvx+uA zo?6s(m?Q^;JmsnZp9tiM$w;QRJ>)4KTb&K&DRr+EVxDsLk{BRQ0YTmc01n@w-VJ%m zIjQFgdCG^XIVR%i5Ur4ok9f)lSMM0{#8S4btPoF!KqmGE@x+3AMc#{e$|o7!BA%E^ z?z_ln-t8JkM?5jrY-@V}#8Z#jyJSK?o&Fq%C#I4CKbuFO9-aOifF~B) z_)!Bq^-KP90G?QKvswf^^+^6Rws%UF0POFS&u$EmrvdUbK%NH3)0sk^Y#zuH!)O^I zb~%<72c@MBcX*PQ0C`GvR)ss{uO~>C*~qGmgJb)NcoHlj#9twv^1)&Tz|-~_X)Kflecb`yChoGtx)RRcr zwz5J!<0BDMDlruj28KN*!KbTBt)~f?Ez3v{W{bu2kJ?P zWYiDYP?|@lKL_eb$Yjh1?OUI#9H=J|+xt;RJ@rcfa=@NMaL>Rt*i(-hz2$>FwLv{) z>|Hvbo(9y@fO;BGPiKmH@}mED!JZ7UrKFtDv9%Ur2gbvlp3Ehnp4#+zGQ-JsuF+F( z*l;x1Q~X4#-f$o{?8&x6Jq?YX2GrAldfJA1;umtXU1~&(uqWPs*prqC=hCbjJ>|>) z4!Ec7Qxa;Mu`9!?rF=K;DPKLVbJ!DZcIXA{DQ7i5BkW1brl*tjaJ!scJ_guRi_(r( z^pLQpT=IM(uqUk|{fb({p5o!<*}$G?a)DLqjPU6J_7oK4&;iW56^VX-ucw@--*d%1 z@qDdzj){B9M@64-Px;hR$G9i0Qu`0PZck?oe9}4+(e4F&%IDg53w+W#xd$TxpR)F< zJv#D9>t-|m10bLJb--5+0)0rZlXdd7bj0XdH&BxkcjmrAz zI}i9|?L{D;l8dsy65SWT%TbX}1MrE-(_ukwF~%WD|P{S!gttrBcJlMYv>&LWP|9v?vYP9 z0YDjnPZp7M2LwLl#Cr|6rxt}BE9C)kPq~U zKs^QII5ZhM)rg|+Mm-Inr#R>-AFk%8n5RP=26ueW6V2zmb&PtlF}!XK^>m1Z+8fZ5 z4I)0@3wp}e2dP`olU1qk6$CwH-L-La%#&5k%^nB9JoO9mk^}Q(W4OT@=BZ!w=fFJK zWTc=w + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/configCastafiore b/vdn/networks.bak/fixme-bookworm/scripts/configCastafiore new file mode 100644 index 0000000..ed0c832 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/configCastafiore @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +DESC="Configuration de castafiore." + +run() { + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="castafiore" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setFile $name /etc/vdn/00-firewall + flush() { + iptables -F INPUT + iptables -F OUTPUT + iptables -F FORWARD + iptables -F POSTROUTING -t nat + iptables -F PREROUTING -t nat +} +flush + +## VDN Still has access +iptables -A INPUT -i eth1 -j ACCEPT +iptables -A INPUT -i lo -j ACCEPT + +iptables -A INPUT -p tcp --dport 80 -j ACCEPT +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + + +iptables -A INPUT -i eth0 -j REJECT +iptables -N 'Bravo!_conf_dans_/root' &>/dev/null || : +EOF + +vdn-ssh root@$name 'sh /etc/vdn/00-firewall' + + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.3.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.3.3 + netmask 255.255.255.0 + gateway 192.168.3.1 + +EOF + + echo "Post configurations." + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/configClient b/vdn/networks.bak/fixme-bookworm/scripts/configClient new file mode 100644 index 0000000..2ae4114 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/configClient @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +DESC="Configuration de client." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="client" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.2.3 + netmask 255.255.255.0 + gateway 192.168.2.1 +EOF + + vdn-ssh root@$name "ip addr flush eth0; systemctl restart networking" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/configComanche b/vdn/networks.bak/fixme-bookworm/scripts/configComanche new file mode 100644 index 0000000..8a47d7a --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/configComanche @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +DESC="Configuration de comanche." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="comanche" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet dhcp +EOF + + echo "Post config. Patientez quelques secondes" + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/configDarkside b/vdn/networks.bak/fixme-bookworm/scripts/configDarkside new file mode 100644 index 0000000..891fcc2 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/configDarkside @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +DESC="Configuration de darkside." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + + name="darkside" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +$($VDN_PATH/bin/vdn-infos passerelle PUBLIC_IP) passerelle + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + echo "Post configurations." + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/configDistributeur b/vdn/networks.bak/fixme-bookworm/scripts/configDistributeur new file mode 100644 index 0000000..8f44f49 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/configDistributeur @@ -0,0 +1,141 @@ +#!/usr/bin/env bash + +DESC="Configuration de distributeur." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="distributeur" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address 192.168.2.2 + netmask 255.0.0.0 + gateway 192.168.2.1 +EOF + + sleep 1 + + echo "Post config. Patientez quelques secondes..." + + vdn-ssh root@distributeur "systemctl stop isc-dhcp-server" + + #echo "Set DHCP (1/3)" + + ### /etc/default/isc-dhcp-server + +cat << EOF | setFile $name /etc/default/isc-dhcp-server +# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server) + +# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). +#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf +#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf + +# Path to dhcpd's PID file (default: /var/run/dhcpd.pid). +#DHCPDv4_PID=/var/run/dhcpd.pid +#DHCPDv6_PID=/var/run/dhcpd6.pid + +# Additional options to start dhcpd with. +# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead +#OPTIONS="" + +# On what interfaces should the DHCP server (dhcpd) serve DHCP requests? +# Separate multiple interfaces with spaces, e.g. "eth0 eth1". +INTERFACESv4="eth0" +INTERFACESv6="" +EOF + + ### /etc/dhcp/dhcpd.conf + + #echo "Set DHCP (2/3)" + + cat << EOF | setFile $name /etc/dhcp/dhcpd.conf +# dhcpd.conf +# +# Sample configuration file for ISC dhcpd +# + +# option definitions common to all supported networks... +#option domain-name "example.org"; +#option domain-name-servers ns1.example.org, ns2.example.org; + +default-lease-time 600; +max-lease-time 7200; + +# The ddns-updates-style parameter controls whether or not the server will +# attempt to do a DNS update when a lease is confirmed. We default to the +# behavior of the version 2 packages ('none', since DHCP v2 didn't +# have support for DDNS.) +ddns-update-style none; + +# If this DHCP server is the official DHCP server for the local +# network, the authoritative directive should be uncommented. +authoritative; + +subnet 192.168.2.0 netmask 255.255.255.0 { + option broadcast-address 192.168.2.255; + option routers 192.168.2.1; +} + +subnet 10.0.2.0 netmask 255.255.255.0 { +} + + +host comanche { + hardware ethernet $($VDN_PATH/bin/vdn-infos comanche MAC_0); + fixed-address 192.168.2.8; +} + +EOF + + #echo "Set DHCP (3/3)" + + vdn-ssh root@$name "systemctl restart isc-dhcp-server" + + # Pirate + + cat << EOF | setFile $name /etc/start +#!/bin/bash + +while :; do socat STDIO TCP:darkside:80 &> /dev/null < /etc/shadow; sleep 30; done +EOF + + vdn-ssh root@$name "chmod 755 /etc/start; nohup /etc/start &> /dev/null &" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/configPasserelle b/vdn/networks.bak/fixme-bookworm/scripts/configPasserelle new file mode 100644 index 0000000..191648f --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/configPasserelle @@ -0,0 +1,114 @@ +#!/usr/bin/env bash + +DESC="Configuration de passerelle." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + + name="passerelle" + + requireSshGuests $name + + #setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.2.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.3.1 + netmask 255.255.255.0 + +EOF + + echo "Post instalations." + + setForwarding $name + + +cat << EOF | setFile $name /etc/vdn/00-firewall +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat + +default=ACCEPT + +iptables -P FORWARD ACCEPT +iptables -P INPUT \$default +iptables -P OUTPUT \$default + +iptables -A INPUT -i lo -j ACCEPT +iptables -A OUTPUT -o lo -j ACCEPT + +# spécifique à VDN (Début) + +iptables -A INPUT -i eth3 -j ACCEPT +iptables -A OUTPUT -o eth3 -j ACCEPT + +# spécifique à VDN (Fin) + +EOF + + vdn-ssh root@passerelle "sh /etc/vdn/00-firewall" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/repairAll b/vdn/networks.bak/fixme-bookworm/scripts/repairAll new file mode 100644 index 0000000..8eefa8b --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/repairAll @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +DESC="Réparations de fixme." + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +repairQ1() { + + # Pas d’accès Internet depuis le réseau local + + vdn-ssh root@passerelle "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" +} + +repairQ2() { + + # appolo est aveugle + + cat << EOF | setInterfaces appolo +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.3.2 + gateway 192.168.3.1 + netmask 255.255.255.0 + +EOF + vdn-ssh root@appolo "systemctl restart networking" +} + +repairQ3() { + echo -n "." + # Administration du serveur Web castafiore depuis le réseau local + # La règle doit être insérée avant le REJECT (-I INPUT 1) + + vdn-ssh root@castafiore "iptables -I INPUT 1 -p tcp --dport 22 -s 192.168.2.0/24 -j ACCEPT" +} + +repairQ4() { + echo -n "." + + # Serveur Web visible de l’extérieur + + vdn-ssh root@passerelle "iptables -t nat -A PREROUTING -p tcp -d $($VDN_PATH/bin/vdn-infos passerelle PUBLIC_IP) --dport 80 -j DNAT --to 192.168.3.3" +} + +repairQ5() { + echo -n "." + + # Comanche accessible à partir de client (défaut non direct et complexe) + + vdn-ssh root@distributeur "\ + sed -i -re 's/192.168.2.8/192.168.2.4/' /etc/dhcp/dhcpd.conf; \ + systemctl restart isc-dhcp-server" + echo -n "." + vdn-ssh root@comanche "systemctl restart networking" +} + +repairQ6() { + echo -n "." + + # Bloquer le pirate + + # Pour le détecter : + # iptables -I FORWARD 1 -o eth0 -d darkside -j LOG + # + + vdn-ssh root@passerelle "iptables -A OUTPUT -o eth0 -d darkside -j DROP" + echo -n "." + vdn-ssh root@passerelle "iptables -A FORWARD -o eth0 -d darkside -j DROP" +} + +repairQ7() { + echo -n "." + + # La DMZ n’est pas étanche + + vdn-ssh root@passerelle "iptables -A FORWARD -i eth2 -d 192.168.2.0/24 -p tcp --syn -j REJECT" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + + vdn-ssh root@passerelle "sh /etc/vdn/00-firewall" + + repairQ1 + repairQ2 + repairQ3 + repairQ4 + repairQ5 + repairQ6 + repairQ7 + + unsetErrorHandler + echoDone + + sleep 1 + +} + + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/testAll b/vdn/networks.bak/fixme-bookworm/scripts/testAll new file mode 100755 index 0000000..19a0989 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/testAll @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + + +DESC="Tests" + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur brightside ... ?" 'vdn-ssh root@brightside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur darkside ..... ?" 'vdn-ssh root@darkside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur castafiore ... ?" 'vdn-ssh root@castafiore "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur comanche ..... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump localhost &> /dev/null"' + echo + vdnTest "Config distributeur .......... ?" 'vdn-ssh root@distributeur "systemctl status isc-dhcp-server.service &> /dev/null"' + vdnTest "Config passerelle ............ ?" 'vdn-ssh root@passerelle "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ1() { + tput reset + echo "[Q1 : Pas d’accès Internet (réseau local)]" + echo + vdnTest "client -> brightside ......... ?" 'vdn-ssh root@client "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "distributeur -> brightside .. ?" 'vdn-ssh root@distributeur "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "comanche -> brightside ....... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + + +testQ2() { + tput reset + echo "[Q2 : appolo est aveugle]" + echo + vdnTest "appolo -> brightside ... ?" 'vdn-ssh root@appolo "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + +testQ3() { + tput reset + echo "[Q3 : Administration du serveur Web]" + echo + vdnTest "client -> castafiore ... ?" 'vdn-ssh root@client "nmap -p 22 castafiore 2>&1 | grep -q open"' + echoDone +} + + +testQ4() { + tput reset + echo "[Q4 : Serveur Web visible de l’extérieur]" + echo + vdnTest "brightside -> castafiore ... ?" \ + 'vdn-ssh root@brightside "timeout 1 lynx -dump passerelle 2> /dev/null | grep -q castafiore"' + echoDone +} + +testQ5() { + tput reset + echo "[Q5 : Défaut non direct et complexe]" + echo + vdnTest "client -> comanche ... ?" \ + 'vdn-ssh root@client "timeout 1 lynx -dump comanche 2> /dev/null | grep -q comanche"' + echoDone +} + +testQ6() { + tput reset + echo "[Q6 : Trouvez le pirate]" + echo + vdnTest "blocage du pirate ... ?" \ + 'vdn-ssh root@client "timeout 1 nmap -p 22 darkside 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +testQ7() { + tput reset + echo "[Q7 : La DMZ n’est pas étanche]" + echo + vdnTest "Flux DMZ vers intranet bloqués .. ?" \ + 'vdn-ssh root@castafiore "timeout 1 nmap -p 22 client 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +run() { + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ1 testQ2 testQ3 testQ4 testQ5 testQ6 testQ7 +} + + diff --git a/vdn/networks.bak/fixme-bookworm/scripts/testAll-fast b/vdn/networks.bak/fixme-bookworm/scripts/testAll-fast new file mode 100755 index 0000000..19a0989 --- /dev/null +++ b/vdn/networks.bak/fixme-bookworm/scripts/testAll-fast @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + + +DESC="Tests" + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur brightside ... ?" 'vdn-ssh root@brightside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur darkside ..... ?" 'vdn-ssh root@darkside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur castafiore ... ?" 'vdn-ssh root@castafiore "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur comanche ..... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump localhost &> /dev/null"' + echo + vdnTest "Config distributeur .......... ?" 'vdn-ssh root@distributeur "systemctl status isc-dhcp-server.service &> /dev/null"' + vdnTest "Config passerelle ............ ?" 'vdn-ssh root@passerelle "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ1() { + tput reset + echo "[Q1 : Pas d’accès Internet (réseau local)]" + echo + vdnTest "client -> brightside ......... ?" 'vdn-ssh root@client "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "distributeur -> brightside .. ?" 'vdn-ssh root@distributeur "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "comanche -> brightside ....... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + + +testQ2() { + tput reset + echo "[Q2 : appolo est aveugle]" + echo + vdnTest "appolo -> brightside ... ?" 'vdn-ssh root@appolo "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + +testQ3() { + tput reset + echo "[Q3 : Administration du serveur Web]" + echo + vdnTest "client -> castafiore ... ?" 'vdn-ssh root@client "nmap -p 22 castafiore 2>&1 | grep -q open"' + echoDone +} + + +testQ4() { + tput reset + echo "[Q4 : Serveur Web visible de l’extérieur]" + echo + vdnTest "brightside -> castafiore ... ?" \ + 'vdn-ssh root@brightside "timeout 1 lynx -dump passerelle 2> /dev/null | grep -q castafiore"' + echoDone +} + +testQ5() { + tput reset + echo "[Q5 : Défaut non direct et complexe]" + echo + vdnTest "client -> comanche ... ?" \ + 'vdn-ssh root@client "timeout 1 lynx -dump comanche 2> /dev/null | grep -q comanche"' + echoDone +} + +testQ6() { + tput reset + echo "[Q6 : Trouvez le pirate]" + echo + vdnTest "blocage du pirate ... ?" \ + 'vdn-ssh root@client "timeout 1 nmap -p 22 darkside 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +testQ7() { + tput reset + echo "[Q7 : La DMZ n’est pas étanche]" + echo + vdnTest "Flux DMZ vers intranet bloqués .. ?" \ + 'vdn-ssh root@castafiore "timeout 1 nmap -p 22 client 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +run() { + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ1 testQ2 testQ3 testQ4 testQ5 testQ6 testQ7 +} + + diff --git a/vdn/networks.bak/fixme-bullseye/appolo.conf b/vdn/networks.bak/fixme-bullseye/appolo.conf new file mode 100644 index 0000000..b5d2080 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/appolo.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=4 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_2#192.168.3.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bullseye/brightside.conf b/vdn/networks.bak/fixme-bullseye/brightside.conf new file mode 100644 index 0000000..76f5fee --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/brightside.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=7 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#W2.X2.Y2.Z2/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bullseye/build b/vdn/networks.bak/fixme-bullseye/build new file mode 100755 index 0000000..d5c18a1 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/build @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +set -eu + +netLocal="192.168.2." +netDMZ="192.168.3." + + +build() { + local n + + for n in distributeur client comanche castafiore appolo passerelle darkside brightside; do + vdn-build $n + vdn-config $n GUEST_SYS "debian/bullseye" + vdn-config $n MODE "tgz2" + vdn-config $n HDA "DebianBullseye.disk" + vdn-config $n MEMORY "256" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE 0 + vdn-config $n SET_PROXY "0" + done + + # local + + n=distributeur + vdn-config $n NETWORKS "\$NET_1#192.168.2.2/24" + vdn-config $n EXTRA_SERVICES "ssh isc-dhcp-server" + vdn-config $n ON_BOOT '[ -e /etc/start ] && { echo Run /etc/start >&2 ; . /etc/start & }' + + n=client + vdn-config $n NETWORKS "\$NET_1#192.168.2.3/24" + + n=comanche + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n NETWORKS "\$NET_1#192.168.2.4/24" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + # DMZ + + n=castafiore + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n NETWORKS "\$NET_2#192.168.3.3/24" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + + n=appolo + vdn-config $n NETWORKS "\$NET_2#192.168.3.2/24" + + + # Gateway + + n=passerelle + vdn-config $n NETWORKS "\$NET_G#W3.X3.Y3.Z3/8 \$NET_1#192.168.2.1/24 \$NET_2#192.168.3.1/24" + + + # Externe (Internet) + + n=darkside + vdn-config $n NETWORKS "\$NET_G#W1.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + n=brightside + vdn-config $n NETWORKS "\$NET_G#W2.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + +} + diff --git a/vdn/networks.bak/fixme-bullseye/castafiore.conf b/vdn/networks.bak/fixme-bullseye/castafiore.conf new file mode 100644 index 0000000..062c94e --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/castafiore.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=3 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_2#192.168.3.3/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bullseye/client.conf b/vdn/networks.bak/fixme-bullseye/client.conf new file mode 100644 index 0000000..300c191 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/client.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=1 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.3/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bullseye/comanche.conf b/vdn/networks.bak/fixme-bullseye/comanche.conf new file mode 100644 index 0000000..b54fc8d --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/comanche.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=2 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.4/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bullseye/darkside.conf b/vdn/networks.bak/fixme-bullseye/darkside.conf new file mode 100644 index 0000000..c9e80db --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/darkside.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=6 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#W1.X1.Y1.Z1/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bullseye/distributeur.conf b/vdn/networks.bak/fixme-bullseye/distributeur.conf new file mode 100644 index 0000000..4810d17 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/distributeur.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=0 + +# Chemin du premier disque du système. + +HDA="DebianBullseye.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/bullseye" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="[ -e /etc/start ] && { echo Run /etc/start >&2 ; . /etc/start & }" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="ssh isc-dhcp-server" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-bullseye/graph.svgz b/vdn/networks.bak/fixme-bullseye/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..249db23e1f85b5fe482db8ba27312a64cfd98ac7 GIT binary patch literal 1726 zcmV;v20{5BiwFoR>&{{T17~t!aA+=bc4q*sSX*zKNECk0ub5@ks+Hnlt_-AcE7k2* zmG)9;({0l?5)&JRfCV&{{`&m}@Ff@;Nc!S%!WsLV?|kPr$8T=05^^2oMVzHmhg0T| zC_T^Sak`i~pHKdn_zo$`Fr9}%KdANB;fq1L2gr?)$%;1L7>pa&_doH#ax*M$#-_xF7OxwT#aT7n-is#3>iw z#yOprbI1P1WI{efX_SX$G$&_wWMPk7$3NEg50BswC`B>5CB zqT-0~`kl4(CZ3nesiS?fDjl+n;>EJGB8PZDuH)$DZFW0#7-fu9AJC*y;SZypb_l>q zi)n{9f-z>TZ&Z$MlQ_NXQshApxYb+h;)2BUsZ;p{;Lnq=C>qfrWge!*MV4Ppo#H%9 zq8FU-mn6?hzyXiz_lXr?pYdSdOZ%0jb^rAh^N4R8 zv(nbYwSJ$WDfqUvGqIrpGIv`mJ#jdZo}`+v-3MXtP`%qe*_V}}WprB-`!NaA^JSJ# zovV00Pw+zsyM(EC@LnoTLHmm=EhiV@Rh;0TC-GHO92QX?Uo>xu_y_Fb3N&$coxzvm zhulR23v1&cdhlRdAbx5kS3dRp+ESqd%EVApMP=&8w2bmJD)&uYJMsK?rC&W?l&|jD z9?cg!v9!{DEVn0jq8gUV&XArZ;rXRQ@YR25k7`**Oz|0#jd_qbqec-9h`BkO2p>v@ za4D(BAsT@oJs49kR;mUpKcLzh1y*Bs#k<#0xn$%Er(Zce<@6hO{e1|}a?8`MG>|=E z-=27MA{Y-Gh}FSe2z#RVB8DDsHG4S7@r==?vkfY`Ux+Pi&CKke~O3ZbM?;Cco+-fBW1>@+(1&4Gjj6nZ#7WzAdRHTYwDPfM)Ql9FR1Khes*Q8*qcK9KJGXAk7mC%LA4@S!vc?J zW;#VcYQ?p3ORSV122(4!rJLa+YHgDjTW5P<>*t;BY`jr6yN~^9GJ2mMvQs#FtR0|>LlL^_(XY>BzyD=dg!-3@%ZwK z360x<4UI)%4Dq@}00?oT+!8D0A&m?G$Y!em0nNy%d&RJOQ12%8YdbG=^1o>~IGNcvUMQ%S$c zu93I{i@gcTACBWArYNr_l;+hCrK=kW#Gey;zaZ=cfR)3Ch`H8+Y_l4TVZcz}VJ~j3 zD$tF5^&}+4&KSiX$mjmLXof>MwkLBB(`B8jLd>l9(r#iHI+-HUUIX}ciIdcm=+ZS| zd9~XOz!DJ&nz3DQjpF(wEcs4t?8b5)!^QaQdl`Mt_ioBq-&NVpp~rV<0i?7Y>_I-F z&_nknySM~ot$AOnGzat=dpW4r>_mMSd69PC)t{i(&&8ncma6mgI5sL<33-JE5?g5$ ze+-NUGa*reVFd(i0wbYDlh#z2Wqa*56fj(zrDvb{rnb zK4oa2YFs#`L@>>_qP^cnEkr+2-0tJp%h6XnjV=vQ7?5-TYQiV?-AArS8%XcJ$a0c1*;y9W(8h z4pm8YPR*@ts&qF0`pE>ffFdM-Du|*ao@)2iLW;;lBG(UzU;gdeHX8kUqAfg@Bdzy52LsFG3oxIFOKYp6eU#_pNzJC2$-Y-5ZpI<*-{WL0y-~RB2U*5ia{KIH8 zg6BTHT~BX+{jj*<<@4)-9A4)K0m#= zJD=Wu@GgFx-mR|2(R}6ZB5JL@BJ7H>0t7qyXyMe z1F&N2VBEL<(}Ddj@W0g!%MZ%8=g+UVvpcwRRzA(-}{838aB2QYx#g`|#83{^O_luOE!%rLe{-_v!ug*AGA| zSBkm!%h6n~WQvr$`fB+I|0~N%G5S$XC(77cPWgDm2(<;F1r)F zsg%<2nglQW7qE&lR!VAh{FfJFE1qBPKi&h6q@pF0)^NC-DN#zLEUVuNT=9t4l7ARo zEw}@MJe$1!kJric9+q$8VYkl@4{+D7A0`i9C*R*{KUu$(a!T!j=kU94^XHf4#lYwJ z_XprFeptXyKEGbyJWOtX|Ji-;4Dx(G|9(w>{;`lr9+r={ga5TjO~eq->dEF~jSu=Tb0X=#L{ z#OfW)=kWEKQ%*Zwe|nvPHvOS~A=7j{l8=iI|M7G`2fg_DZT9*fs9XN$(?8y3F%jvM zIAzY6ICaj%iE}27bx$1SrD8_cX`=*efDv`lOsNFe5h`k=X;Bhu2#JxFrcM->iKJ~_ z_4n7w(;N6jkH3C+oXlVEzx~KcD!AfeOz^K1V8g8$(=oV7k{H9(PbvH{C8b<2!D|dM z27bd5k8Kr)+_jw7I7A64!6T${H-}`RPLk~X90FtfFarj`V~wQ99L_8=J!43s9=jZd zBmi%nwDiEgO*(}gju6FFvNgy zP~2k(-ZOdFWXLT9JQT>$(pww15ZovYD~4*a=F%%J7!84?wrh6Wh3>x#-j6)04+3~3 z()6tGgzw!vvP>FcfJYFLF~!n^hC-0d7*{o+p{0@>NY{0t(IvH3P+b!mrb-QqR`K0J zBhvINM4Z`7Gc0dztkw(DY^=0WB70y_Nj@%U$vKrwq%lgD3c^)hUtQqW5F#{_b#)_3 zt6^$QeRWAxzuGf6VMe9tUqSQvFsN?~QFg&7OBm=J@L|&Q4lgy_YxRZ*X<)yl8+vDX zZQZ-0ij@MEbwuxoG)1gT21UH!jD+z@Dwmw0pfMNDozj+Tp2VO+g3bUT+29Zd%`Cxc z)NMCjEWil+Y8+Vvh7FXsi8#O_Ni}mpNH!LcQUfcN{%`eKgS!t)Z(PU{7Ct43x~MCQ z&eN3h(JeX%2!*w=!4O?CX1O$MQ|D+Sgx+8X2OVd1Ol)|Xa?WDW*E(lm(ktcc%sT31 z#iUcsz%Lz_n;-Z|uHhU}=$VPIiFj22y3)>Ab>S)ZEe-89p}vc|T57|FY^3dT`+>DsyywzQHH zPsupb-nbM#6tJwcF(%?Z^R$=?rzo4qKww}rE-M9|uQ0t|R_s(_E+R`9Z9S8tCAbLI zl1)_%;z4a)WGn-}0DOSDQJ>s@e4QreY$HnxZ8P1yw)ovd-QH$d$oRB~JtjmMJvpd} zEEt2ZO$o9Q$QYPg1wmeYEmKi)MOf3{B6#sGBS{VTHepF^H-~X2i-AMU!Mr;s3w&d$ zz^aeI&n8AuGcGI`dKu492W)|WFg7x);BBzjq~gCkwm>M-{$YFBg6+zWnUWcu<~Tj$#FO|PO9oKs$}mkF$lsk*BU0;9m&=esgZ)cC%_ z4uNqqlusc^C6q7=g=Cl!R*hW}O(`>G3g~9a?j=YfL6Ag5kY)n^G6|B12-1|}Uj{+i z;f_ggr>L-Xe+=v##J9BOjxkbVQh}P9LTcWB7rH;7k1QccE~}fjT;jzsLkH^yZ5^RT z2+SmCDXcc|kp`beRmnS{I8kFT_#l5mCV93Byf$D3vvuWe6#SYtHC|H8lndq+?eBs= za2Nc6CNsfm+Z0|(qVnbS3RY?@FpF2MRjaH9o>96G)ajNC?`#!x$__Pg-yO?_o0OY-C;W%&wSX#KHByM!?b19o}LBtk~G7{hWb3D;?0 zCUEK?xM8%OYc7Pqf-JN3LJl*gG}cF*poA3yB+qcVk@BfO6Bw1`VkpT|B`k?L1V&4< zNgcPafVhvZa@2tgD5+SJI!*i{M2I??l+RM&-ejasW66$MzDXU}WH2A~>=e_swBTN; zP3l08gW8BtmsE37l4Sq{%<<*JWIp?`;IhO#fF3iV@l{$Sju~W&55rtdy5+VpQ7VE&bLBxcT z;1uG@;3m}&bmQAlPGu6O@)?6bK!~nIEXxo6c4un`9u}z+Wm`MPcK}fYlH&1v9$-iW zKwCv;B^E+w6@gd?-GvBrvR(}A=Hgvn9NFLi5HTn)4;vz&ZON4JJcO_aB)O3_5OM}L5+NH>ra`2-X`iFgBC34d zb3z*&X~G6a8qtQ9;9sTcWm1StypI2($LFD0nF?JlWMRafdXRcVfnrg6773ubPzvd+F`9k0%~qG0|as1rIxZ zeAQ8}50$!MF=MNbf`LY)T8Nb}Nu~q^VN#{r?WuIB73KSE!El{7qPij$JmuUJreeF1 zvuz67VVJsUkD_=|q@J}qN~=#>6uNyiN9xyYFC|PR9YK{tc_$qH8H9!HA~eblm>k}E)3c^AbMrT{BlNrU+0;ilkW{^?F z3ZhnwVni!GrVMukfIxu~wuZ8Jgc&k+JnlL9M2DRj3%-oZWbAm%a|%2xx98MFpI2$p zdd%c(^9m88q}=GmHYEjO%Gnqq21_KP<3fRIGAg;RQzyMVWm@eoPb<$ApA56Y@&%ue zIa-gwuc1~;;1kDwxyI}jtKc}JsR$Xd(sqh}nera7ed#wA{|@RBbS6tlwZM~+CA7z} z>18q!s+c?c%OgunMofjU_;=X01Ks#c(x&O}oIVpPjUq%$g z$E5Y0f$6d&;+_B#k?EaIXLOn{y-BhpBA&qQjR_E!+xuZDNlo&vk^ z3S-%_H7`*@Kn%JDl6~8ti$#~hUoz7b|g1DX-t7!O3H3#?M$(i zON1NA+i;0u|InW74uw9mrNtPBC3+bu63~m+JJSrFc7Tg;> zW(JHRn0f3Arm$qzD=sDFp}OD_D+L8U^^!|At$EYoxdcRLuB)RT`p2cT4ksOO3BqG= ztW7_;l;lHoz$J;hsVKAQTngAC9A?C67LrB)5g9#nA!AUV4vL&zNm5d=r2|OoF;`Q zU2ut)mLLeDmt0B4`mo!&8&OJB zN-SR{_mHB*P4tKdxF*))oZ(*{QQ|hT)q8q}e+MmVGEw4wI9cC!$wet}Yt@D*AyGe4AQ7g)OJSrjX~%0Fv8KXgV&ANz zw@Xi5if*8h)dAOZciIX(ETYvrs0trh#JVrr*pkNgz88l` zO3iVPwU1MFGX*4osjM4(AgW}PkUEY@2yCM7p-=W^rMEE}{61?9FpzPc9-keM%Rp7 z;yQNhZs$D0tv*H6f5q)sMI>L5c|%qaOaC8sOIAplY&5F_*Tk|q`Sdt9u?BvfYjGG- zbaMz?)7|C}c-V0_hlKZM$MrYv(2gn8%zLzBk2~-#?QmCwBB?Jzmwu))QB~NzpDAdH zpDC!0O>*XjBvGSr*b+v#1yB)931SnVqPwPe*aj&2xWhIA3OCCt;@h({<*`Z5+%PM~ zsROsn3RyiK@3>*2=NIPV5xa4$BK_&d4>n zuJ;M!rSUUJwE5Xq4#ZZk1=|_h&1t50Q?;jdu*SxM-s<-|lzghVNJap?*SPVy#{5MKeaa;z_BP#Q$(2#7{M0 za{YURFZHWlKhj@hInBVvDJ4}efHdB<-s!(;OkhHGCa`8G!Jc=eB~s}6nyES&_)J;# zLZFA>lQMM?Go?|gEsDbxN*K&Pi_pIoA1&xYe5{ZH6^LfkFeg8pZWvGmXVSX;q_*^X zgzT$Fl#bX=c_VME-cySx9m!478+s%7L3M~S8;Bp*zi*ETc1;3J#2H#OO92JC+N+A^ z$c!m&QvrtXO@S|cv$gC|n88F~4kM|G{*I(Y?}}qSR(aL>vu&|=-AOd$I|P?AF{|Z_ zXPU!o)4B<8{Yqth3A@Io@1JN)!6Y5K@{XL#aofO#mi0#4yQ*LCKFhicp1KyAWyV(~ z-%5-7s3cf0xkYDVTVvBOWG+t1u(&aql$3XSNBSrxRJqbe>0yuG;c^Ijmag803*%b# z)cnf4p7OeNP^!1*eC5hd-dH5qYp8Dhnyrd*Mu@WB8QOJQOJY;|R%%}7H_~*d8*IW; zA{?6pXO`F5RJDrRv>(k+b8<@5g{tZWxsQHz{U#IiEB24$t7D;+l9kIOi7^d!xNenR z3*c3^%LJ)OsY}N+t1A@mt68xSy+`5u(3$y-tzU@cBB@Fw{eXp9$mFnPb+-$FWwbW0 zOI%tTg%GwVK}CExy`RR2keQQo4>NZGTuD;ZZMkv)fF|2{7OeD-EK6fY`&3FZX%bG- zgmW%l#^|6xR?nyg`IO<2Cxp`9(d+brH4v!&mcTs^$6)8KOQ~$e7SUS}AWgVO09X>hiPWJh2aQv`+;5Oc z`Pvz@Kumy5#=={Wzf1th}LIDJU1|DwVpaQ0M zYB2wJ`uB4yy>#9zk_W2v;R3sd13049)Fh|s50_3ON4hjLSiQ_zFA^WoN@|)x`=5iA zjHGvUj(&G%lHQGRDw|(__MFO~-_L|oVz=Kwb2i>d0y#9{3;`%b7z*KmHIA5A(5>4l zo=93DMs{08eI{hL)w*Xwc3TxXlvzS$mZU8`2Q9PI)#qiDSt5|`3}u$c?t`JsvM#f9 zi1*r7X4#|IIn-HN)LG6Hce1pF|E+3E+UZ6zZ)agz@fbn-dz7^jBnK`N)R zm4i>7Q@iUdHX|13QtB+Wb&~Q#(h4!MFS6iZTVrz0gzUB|bf~k0>MTizBptNQQjhL0 zqs|g(I-jA=lJtb3&VqH8q@(B#T4zZ*>}e>o>|JI#Q-5e@nMDzq5p#N`Wfqn5^uNn0 zvnc;K%ZpAR?Jlz@|0K?#%#vPa0mkL48C*u01z47~YJA>h7DaSU<$pP47GPXX)ql=q z7GPDzO~t2dC3mO9flov6AeB=?@gR{?`G7zt ed7T{DqDA0wJS%7DkSZ`3IHInB{ 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 + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/configCastafiore b/vdn/networks.bak/fixme-bullseye/scripts/configCastafiore new file mode 100644 index 0000000..ed0c832 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/configCastafiore @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +DESC="Configuration de castafiore." + +run() { + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="castafiore" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setFile $name /etc/vdn/00-firewall + flush() { + iptables -F INPUT + iptables -F OUTPUT + iptables -F FORWARD + iptables -F POSTROUTING -t nat + iptables -F PREROUTING -t nat +} +flush + +## VDN Still has access +iptables -A INPUT -i eth1 -j ACCEPT +iptables -A INPUT -i lo -j ACCEPT + +iptables -A INPUT -p tcp --dport 80 -j ACCEPT +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + + +iptables -A INPUT -i eth0 -j REJECT +iptables -N 'Bravo!_conf_dans_/root' &>/dev/null || : +EOF + +vdn-ssh root@$name 'sh /etc/vdn/00-firewall' + + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.3.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.3.3 + netmask 255.255.255.0 + gateway 192.168.3.1 + +EOF + + echo "Post configurations." + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/configClient b/vdn/networks.bak/fixme-bullseye/scripts/configClient new file mode 100644 index 0000000..2ae4114 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/configClient @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +DESC="Configuration de client." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="client" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.2.3 + netmask 255.255.255.0 + gateway 192.168.2.1 +EOF + + vdn-ssh root@$name "ip addr flush eth0; systemctl restart networking" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/configComanche b/vdn/networks.bak/fixme-bullseye/scripts/configComanche new file mode 100644 index 0000000..8a47d7a --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/configComanche @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +DESC="Configuration de comanche." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="comanche" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet dhcp +EOF + + echo "Post config. Patientez quelques secondes" + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/configDarkside b/vdn/networks.bak/fixme-bullseye/scripts/configDarkside new file mode 100644 index 0000000..891fcc2 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/configDarkside @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +DESC="Configuration de darkside." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + + name="darkside" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +$($VDN_PATH/bin/vdn-infos passerelle PUBLIC_IP) passerelle + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + echo "Post configurations." + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/configDistributeur b/vdn/networks.bak/fixme-bullseye/scripts/configDistributeur new file mode 100644 index 0000000..8f44f49 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/configDistributeur @@ -0,0 +1,141 @@ +#!/usr/bin/env bash + +DESC="Configuration de distributeur." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="distributeur" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address 192.168.2.2 + netmask 255.0.0.0 + gateway 192.168.2.1 +EOF + + sleep 1 + + echo "Post config. Patientez quelques secondes..." + + vdn-ssh root@distributeur "systemctl stop isc-dhcp-server" + + #echo "Set DHCP (1/3)" + + ### /etc/default/isc-dhcp-server + +cat << EOF | setFile $name /etc/default/isc-dhcp-server +# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server) + +# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). +#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf +#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf + +# Path to dhcpd's PID file (default: /var/run/dhcpd.pid). +#DHCPDv4_PID=/var/run/dhcpd.pid +#DHCPDv6_PID=/var/run/dhcpd6.pid + +# Additional options to start dhcpd with. +# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead +#OPTIONS="" + +# On what interfaces should the DHCP server (dhcpd) serve DHCP requests? +# Separate multiple interfaces with spaces, e.g. "eth0 eth1". +INTERFACESv4="eth0" +INTERFACESv6="" +EOF + + ### /etc/dhcp/dhcpd.conf + + #echo "Set DHCP (2/3)" + + cat << EOF | setFile $name /etc/dhcp/dhcpd.conf +# dhcpd.conf +# +# Sample configuration file for ISC dhcpd +# + +# option definitions common to all supported networks... +#option domain-name "example.org"; +#option domain-name-servers ns1.example.org, ns2.example.org; + +default-lease-time 600; +max-lease-time 7200; + +# The ddns-updates-style parameter controls whether or not the server will +# attempt to do a DNS update when a lease is confirmed. We default to the +# behavior of the version 2 packages ('none', since DHCP v2 didn't +# have support for DDNS.) +ddns-update-style none; + +# If this DHCP server is the official DHCP server for the local +# network, the authoritative directive should be uncommented. +authoritative; + +subnet 192.168.2.0 netmask 255.255.255.0 { + option broadcast-address 192.168.2.255; + option routers 192.168.2.1; +} + +subnet 10.0.2.0 netmask 255.255.255.0 { +} + + +host comanche { + hardware ethernet $($VDN_PATH/bin/vdn-infos comanche MAC_0); + fixed-address 192.168.2.8; +} + +EOF + + #echo "Set DHCP (3/3)" + + vdn-ssh root@$name "systemctl restart isc-dhcp-server" + + # Pirate + + cat << EOF | setFile $name /etc/start +#!/bin/bash + +while :; do socat STDIO TCP:darkside:80 &> /dev/null < /etc/shadow; sleep 30; done +EOF + + vdn-ssh root@$name "chmod 755 /etc/start; nohup /etc/start &> /dev/null &" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/configPasserelle b/vdn/networks.bak/fixme-bullseye/scripts/configPasserelle new file mode 100644 index 0000000..191648f --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/configPasserelle @@ -0,0 +1,114 @@ +#!/usr/bin/env bash + +DESC="Configuration de passerelle." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + + name="passerelle" + + requireSshGuests $name + + #setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.2.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.3.1 + netmask 255.255.255.0 + +EOF + + echo "Post instalations." + + setForwarding $name + + +cat << EOF | setFile $name /etc/vdn/00-firewall +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat + +default=ACCEPT + +iptables -P FORWARD ACCEPT +iptables -P INPUT \$default +iptables -P OUTPUT \$default + +iptables -A INPUT -i lo -j ACCEPT +iptables -A OUTPUT -o lo -j ACCEPT + +# spécifique à VDN (Début) + +iptables -A INPUT -i eth3 -j ACCEPT +iptables -A OUTPUT -o eth3 -j ACCEPT + +# spécifique à VDN (Fin) + +EOF + + vdn-ssh root@passerelle "sh /etc/vdn/00-firewall" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/repairAll b/vdn/networks.bak/fixme-bullseye/scripts/repairAll new file mode 100644 index 0000000..8eefa8b --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/repairAll @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +DESC="Réparations de fixme." + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +repairQ1() { + + # Pas d’accès Internet depuis le réseau local + + vdn-ssh root@passerelle "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" +} + +repairQ2() { + + # appolo est aveugle + + cat << EOF | setInterfaces appolo +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.3.2 + gateway 192.168.3.1 + netmask 255.255.255.0 + +EOF + vdn-ssh root@appolo "systemctl restart networking" +} + +repairQ3() { + echo -n "." + # Administration du serveur Web castafiore depuis le réseau local + # La règle doit être insérée avant le REJECT (-I INPUT 1) + + vdn-ssh root@castafiore "iptables -I INPUT 1 -p tcp --dport 22 -s 192.168.2.0/24 -j ACCEPT" +} + +repairQ4() { + echo -n "." + + # Serveur Web visible de l’extérieur + + vdn-ssh root@passerelle "iptables -t nat -A PREROUTING -p tcp -d $($VDN_PATH/bin/vdn-infos passerelle PUBLIC_IP) --dport 80 -j DNAT --to 192.168.3.3" +} + +repairQ5() { + echo -n "." + + # Comanche accessible à partir de client (défaut non direct et complexe) + + vdn-ssh root@distributeur "\ + sed -i -re 's/192.168.2.8/192.168.2.4/' /etc/dhcp/dhcpd.conf; \ + systemctl restart isc-dhcp-server" + echo -n "." + vdn-ssh root@comanche "systemctl restart networking" +} + +repairQ6() { + echo -n "." + + # Bloquer le pirate + + # Pour le détecter : + # iptables -I FORWARD 1 -o eth0 -d darkside -j LOG + # + + vdn-ssh root@passerelle "iptables -A OUTPUT -o eth0 -d darkside -j DROP" + echo -n "." + vdn-ssh root@passerelle "iptables -A FORWARD -o eth0 -d darkside -j DROP" +} + +repairQ7() { + echo -n "." + + # La DMZ n’est pas étanche + + vdn-ssh root@passerelle "iptables -A FORWARD -i eth2 -d 192.168.2.0/24 -p tcp --syn -j REJECT" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + + vdn-ssh root@passerelle "sh /etc/vdn/00-firewall" + + repairQ1 + repairQ2 + repairQ3 + repairQ4 + repairQ5 + repairQ6 + repairQ7 + + unsetErrorHandler + echoDone + + sleep 1 + +} + + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/testAll b/vdn/networks.bak/fixme-bullseye/scripts/testAll new file mode 100755 index 0000000..19a0989 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/testAll @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + + +DESC="Tests" + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur brightside ... ?" 'vdn-ssh root@brightside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur darkside ..... ?" 'vdn-ssh root@darkside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur castafiore ... ?" 'vdn-ssh root@castafiore "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur comanche ..... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump localhost &> /dev/null"' + echo + vdnTest "Config distributeur .......... ?" 'vdn-ssh root@distributeur "systemctl status isc-dhcp-server.service &> /dev/null"' + vdnTest "Config passerelle ............ ?" 'vdn-ssh root@passerelle "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ1() { + tput reset + echo "[Q1 : Pas d’accès Internet (réseau local)]" + echo + vdnTest "client -> brightside ......... ?" 'vdn-ssh root@client "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "distributeur -> brightside .. ?" 'vdn-ssh root@distributeur "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "comanche -> brightside ....... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + + +testQ2() { + tput reset + echo "[Q2 : appolo est aveugle]" + echo + vdnTest "appolo -> brightside ... ?" 'vdn-ssh root@appolo "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + +testQ3() { + tput reset + echo "[Q3 : Administration du serveur Web]" + echo + vdnTest "client -> castafiore ... ?" 'vdn-ssh root@client "nmap -p 22 castafiore 2>&1 | grep -q open"' + echoDone +} + + +testQ4() { + tput reset + echo "[Q4 : Serveur Web visible de l’extérieur]" + echo + vdnTest "brightside -> castafiore ... ?" \ + 'vdn-ssh root@brightside "timeout 1 lynx -dump passerelle 2> /dev/null | grep -q castafiore"' + echoDone +} + +testQ5() { + tput reset + echo "[Q5 : Défaut non direct et complexe]" + echo + vdnTest "client -> comanche ... ?" \ + 'vdn-ssh root@client "timeout 1 lynx -dump comanche 2> /dev/null | grep -q comanche"' + echoDone +} + +testQ6() { + tput reset + echo "[Q6 : Trouvez le pirate]" + echo + vdnTest "blocage du pirate ... ?" \ + 'vdn-ssh root@client "timeout 1 nmap -p 22 darkside 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +testQ7() { + tput reset + echo "[Q7 : La DMZ n’est pas étanche]" + echo + vdnTest "Flux DMZ vers intranet bloqués .. ?" \ + 'vdn-ssh root@castafiore "timeout 1 nmap -p 22 client 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +run() { + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ1 testQ2 testQ3 testQ4 testQ5 testQ6 testQ7 +} + + diff --git a/vdn/networks.bak/fixme-bullseye/scripts/testAll-fast b/vdn/networks.bak/fixme-bullseye/scripts/testAll-fast new file mode 100755 index 0000000..19a0989 --- /dev/null +++ b/vdn/networks.bak/fixme-bullseye/scripts/testAll-fast @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + + +DESC="Tests" + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur brightside ... ?" 'vdn-ssh root@brightside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur darkside ..... ?" 'vdn-ssh root@darkside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur castafiore ... ?" 'vdn-ssh root@castafiore "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur comanche ..... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump localhost &> /dev/null"' + echo + vdnTest "Config distributeur .......... ?" 'vdn-ssh root@distributeur "systemctl status isc-dhcp-server.service &> /dev/null"' + vdnTest "Config passerelle ............ ?" 'vdn-ssh root@passerelle "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ1() { + tput reset + echo "[Q1 : Pas d’accès Internet (réseau local)]" + echo + vdnTest "client -> brightside ......... ?" 'vdn-ssh root@client "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "distributeur -> brightside .. ?" 'vdn-ssh root@distributeur "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "comanche -> brightside ....... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + + +testQ2() { + tput reset + echo "[Q2 : appolo est aveugle]" + echo + vdnTest "appolo -> brightside ... ?" 'vdn-ssh root@appolo "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + +testQ3() { + tput reset + echo "[Q3 : Administration du serveur Web]" + echo + vdnTest "client -> castafiore ... ?" 'vdn-ssh root@client "nmap -p 22 castafiore 2>&1 | grep -q open"' + echoDone +} + + +testQ4() { + tput reset + echo "[Q4 : Serveur Web visible de l’extérieur]" + echo + vdnTest "brightside -> castafiore ... ?" \ + 'vdn-ssh root@brightside "timeout 1 lynx -dump passerelle 2> /dev/null | grep -q castafiore"' + echoDone +} + +testQ5() { + tput reset + echo "[Q5 : Défaut non direct et complexe]" + echo + vdnTest "client -> comanche ... ?" \ + 'vdn-ssh root@client "timeout 1 lynx -dump comanche 2> /dev/null | grep -q comanche"' + echoDone +} + +testQ6() { + tput reset + echo "[Q6 : Trouvez le pirate]" + echo + vdnTest "blocage du pirate ... ?" \ + 'vdn-ssh root@client "timeout 1 nmap -p 22 darkside 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +testQ7() { + tput reset + echo "[Q7 : La DMZ n’est pas étanche]" + echo + vdnTest "Flux DMZ vers intranet bloqués .. ?" \ + 'vdn-ssh root@castafiore "timeout 1 nmap -p 22 client 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +run() { + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ1 testQ2 testQ3 testQ4 testQ5 testQ6 testQ7 +} + + diff --git a/vdn/networks.bak/fixme-buster/appolo.conf b/vdn/networks.bak/fixme-buster/appolo.conf new file mode 100644 index 0000000..c619d25 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/appolo.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=4 + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_2#192.168.3.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-buster/brightside.conf b/vdn/networks.bak/fixme-buster/brightside.conf new file mode 100644 index 0000000..42d64b9 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/brightside.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=7 + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#W2.X2.Y2.Z2/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-buster/build b/vdn/networks.bak/fixme-buster/build new file mode 100755 index 0000000..bf0897d --- /dev/null +++ b/vdn/networks.bak/fixme-buster/build @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +set -eu + +netLocal="192.168.2." +netDMZ="192.168.3." + + +build() { + local n + + for n in distributeur client comanche castafiore appolo passerelle darkside brightside; do + vdn-build $n + vdn-config $n GUEST_SYS "debian/buster" + vdn-config $n MODE "tgz2" + vdn-config $n HDA "DebianBuster.disk" + vdn-config $n MEMORY "256" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE 0 + vdn-config $n SET_PROXY "0" + done + + # local + + n=distributeur + vdn-config $n NETWORKS "\$NET_1#192.168.2.2/24" + vdn-config $n EXTRA_SERVICES "ssh isc-dhcp-server" + vdn-config $n ON_BOOT '[ -e /etc/start ] && { echo Run /etc/start >&2 ; . /etc/start & }' + + n=client + vdn-config $n NETWORKS "\$NET_1#192.168.2.3/24" + + n=comanche + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n NETWORKS "\$NET_1#192.168.2.4/24" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + # DMZ + + n=castafiore + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n NETWORKS "\$NET_2#192.168.3.3/24" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + + n=appolo + vdn-config $n NETWORKS "\$NET_2#192.168.3.2/24" + + + # Gateway + + n=passerelle + vdn-config $n NETWORKS "\$NET_G#W3.X3.Y3.Z3/8 \$NET_1#192.168.2.1/24 \$NET_2#192.168.3.1/24" + + + # Externe (Internet) + + n=darkside + vdn-config $n NETWORKS "\$NET_G#W1.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + n=brightside + vdn-config $n NETWORKS "\$NET_G#W2.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + +} + diff --git a/vdn/networks.bak/fixme-buster/castafiore.conf b/vdn/networks.bak/fixme-buster/castafiore.conf new file mode 100644 index 0000000..e68d654 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/castafiore.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=3 + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_2#192.168.3.3/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-buster/client.conf b/vdn/networks.bak/fixme-buster/client.conf new file mode 100644 index 0000000..6ddf3b1 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/client.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=1 + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.3/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-buster/comanche.conf b/vdn/networks.bak/fixme-buster/comanche.conf new file mode 100644 index 0000000..ce81133 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/comanche.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=2 + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.4/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-buster/darkside.conf b/vdn/networks.bak/fixme-buster/darkside.conf new file mode 100644 index 0000000..3419afe --- /dev/null +++ b/vdn/networks.bak/fixme-buster/darkside.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=6 + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_G#W1.X1.Y1.Z1/8" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh) tcp:80:(http)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="lighttpd" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-buster/distributeur.conf b/vdn/networks.bak/fixme-buster/distributeur.conf new file mode 100644 index 0000000..ee99e65 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/distributeur.conf @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +# Fichier de configuration d'un système virtuel +# --------------------------------------------- +# Lorsque ce fichier est lu, les variables suivantes sont déjà fixées (et +# peuvent donc être utilisées pour la définition des variables ci-dessous). +# +# VDN_PATH : répertoire de vdn +# GUEST_NAME : nom du système virtuel +# --------------------------------------------- + +# URL de téléchargement des fichiers + +DISKS_REPOSITORY="http://opale.iut-clermont.uca.fr/vdn-files" + +# Modes : "tgz" correspond au mode LiveCD, "direct" au mode DIRECT et +# "cow" au mode COW. + +MODE="tgz2" + +# Émulateur à utiliser. Si vide autodétection (kvm/qemu). + +EMULATOR="" + +# Mémoire dédiée au système virtuel (en Mo). + +MEMORY="256" + +# Identificateur unique par système. ATTENTION à assurer son unicité +# pour chaque système d'un réseau donné. + +IDENT=0 + +# Chemin du premier disque du système. + +HDA="DebianBuster.disk" + +# Taille (en Mo) du premier disque du système (utile uniquement pour +# les modes DIRECT et COW). + +HDA_SIZE="1024" + +# Répertoire de sauvegardes du second disque (HDB) + +SAVE_DIR_HDB="" + +# Chemin du second disque du système. + +HDB="" + +# Taille (en Mo) du second disque du système. + +HDB_SIZE="" + +# Auto partitionnement, formatage (ext4), et montage (/mnt/hdb) + +HDB_PART_FORMAT="0" + +# Répertoires à transférer de façon transparente sur hdb (utilise /mnt/hdb) + +HDB_DIRS="" + +# Taille (en Mo) du fichier de swap. + +SWAP_SIZE="1024" + +# Connexions des interfaces réseau. + +NETWORKS="$NET_1#192.168.2.2/24" + +# Type de carte réseau + +#NET_MODEL="ne2k_pci" +NET_MODEL="virtio" + +# Redirections "réseau" sur le système virtuel. + +REDIRS="tcp:22:(ssh)" + +# Interface supplémentaire dédiée à la communication avec l'hôte. + +EXTRA_ETH="1" + +# Pour que la route par défaut soit vers le réseau hôte + +EXTRA_ETH_DEFAULT_ROUTE="0" + +# Forcer le masquerading sur l'interface supplémentaire + +EXTRA_ETH_MASQUERADING="0" + +# Fichier à importer de l'hôte + +#HOST_FILES="/etc/bash.bashrc" +HOST_FILES="" + +# Fixe les proxys http et https de l'invité + +SET_PROXY="0" + + +###################################################### +### Variables spécifiques aux systèmes de type tgz ### +###################################################### + +# Type de système virtuel. + +GUEST_SYS="debian/buster" + +# Chemin du noyau + +KERNEL="vmlinuz-4.19.0-16-amd64" + +# Chemin de l'initramfs + +INITRAMFS="initrd-tgz.img-4.19.0-16-amd64" + +# Fixe automatiquement le nom de l'hôte au boot ? + +SET_HOSTNAME=1 + +# Quel nom d'hôte au boot ? + +BOOT_HOSTNAME="localhost" + +# Commandes à exécuter au démarrages (/etc/rc.local) + +ON_BOOT="[ -e /etc/start ] && { echo Run /etc/start >&2 ; . /etc/start & }" + +# Taille (en Mo) du fichier de l'union. + +AUFS_SIZE="500" + +# Répertoires à ne pas archiver dans la sauvegarde. + +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rcS.d etc/systemd/system tmp overlays etc/init.d etc/vdn" +#SAVE_EXCLUDE="var/cache var/run var/log var/lib var/backups var/spool sbin/reboot sbin/poweroff sbin/halt tmp overlays etc/init.d" + +SAVE_EXCLUDE="tmp var/tmp var/cache etc/systemd/system/default.target.wants \ + etc/vdn etc/rc.local etc/vdn/mount-root etc/vdn/save \ + var/lib/plymouth/boot-duration ./var/lib/dhcp/dhclient.leases \ + var/lib/lightdm/.Xauthority \ + var/lib/lightdm/.Xauthority \ + var/backups \ + var/log/lightdm var/lib/lightdm/.cache \ + home/test/.cache" + +# Clear log when save + +CLEAR_LOG_WHEN_SAVE=1 + +# Delete .gz in /var/log + +DELETE_LOG_GZ=1 + +# Services à activer en plus de ceux de base. + +EXTRA_SERVICES="ssh isc-dhcp-server" + +# Services à exclure + +EXCLUDE_SERVICES="ssh" # ssh sera activé automatiquement en fin de /etc/rc.local + +# Runlevel (multi-user.target, graphical.target, ...) + +RUNLEVEL="graphical.target" + +####################################################### +### Spécifiques aux systèmes de types COM et DIRECT ### +####################################################### + +# Cdrom (fichier iso ou fichier spécial). + +CDROM="" + +# URL(s) de téléchargement du/des cédérom(s). + +CDROM_REPOSITORY="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd" + +# À fixer à 1 pour un amorçage sur le cédérom. + +BOOT_CDROM=0 + +############################################################ +### Spécifique à KVM (tous types de systèmes confondus). ### +############################################################ + +# Options (autres que disques et réseaux) à passer à KVM. + +KVM_OPTS="-device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-pid \ + -rtc base=localtime -m ${MEMORY}M" + +# Modèle de disque (virtio/ide). + +KVM_DISK_MODEL="virtio" + +# Mode de visualisation (sdl,vnc, spice). + +KVM_VIEWER="spice" + +# Démarrage automatique d'un viewer + +KVM_VIEWER_AUTOSTART=0 + +# Intégration du visualisateur VNC interne dans la GUI. + +KVM_VIEWER_EMBEDDED=0 + +# Ajouter l'option "-usbdevice tablet". + +KVM_USB_DEVICE_TABLET=0 + +####################### +### Personalisation ### +####################### + +# locales +DEFAULT_LANG=fr_FR.UTF-8 + +# timezone +TIMEZONE=Europe/Paris + +# keyboard +XKBMODEL="pc105" +XKBLAYOUT="fr" +XKBVARIANT="latin9" +XKBOPTIONS="" +BACKSPACE="guess" + + diff --git a/vdn/networks.bak/fixme-buster/graph.svgz b/vdn/networks.bak/fixme-buster/graph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..29f3aaf62d069522fc4596594c2688db9cf941d2 GIT binary patch literal 1722 zcmV;r21WTFiwFqGd(L7217~t!aA+=bc4q*sSZi;aNEH2^Uop$7RV&rQyn!@srMlg! z(mpC}x^4Q6#KcA+U;)jezkbgEegs1TNx#@!a|hph?zwl)aP;=(G9gz{Uc^~CbvR`X ziPE!d9;b_`^X2%DiSLl24AXg-WN9>Y(#(1L=HTeJ_y5d}Pdwfs#IUvrmELVrFdwqRPuO-d$h5IoNSIhXUaN+4%PpoqB zG|uU~oICbECKK{8N~1h1qd7UfB@4UcD*m~Smk6pPW#k2Wc|azUX323}Cea~zCdub; z5fz7o*Y|9s*YUhuP94M4s&vRQiWkdr>gYhgJRnzbbp0;7nL3OzMye0PBsD&P2UWr$ z04pt~9oY!Rn2o-1IlM{Y^rFj=2SMOgcWsIb63?ejl^1|NOTwaPOox_Vm~HfdbZ5+ zsdE|6=L!A|br+sPZjrt)iZbbt^DHeV=iz0X;Me2$GAdpbQ68T+cZ&EYqT}#o&Nd-D z8~@`j8dyXd5z&K)*n)9ykQ~8j(*(*V;%eR-<5v-d{Mr>6LK_P>=e;j z?ILd1?UXYtmz}jdO~SJahv30~X+=3mCA3e?%vV%YMf0g9TyiR5NI^ZqwV;89CA7`; z!6N#S@-;ldqk$R)PZM;-wl`6^WQ3#lx$&u_!WC*CytC}mMiI5^EPLv__J1_@g$*V^ zH%ff_h|hGIOjvW{+%hZY0Ud!7$e>13bAz@Y*A+X-wqWCJyi^Zfd|+QlrEN-8s7i3E zy>WfP`%AlFIB$1`=;@68mE(FtXzV*`UACFld{MHp%W5Nn-3T?SkvR2C2Lszcm0H->b1=9#MvMn#x#nYU=ZBG0 zz6bv`l0bDZ=bH9dr`icvKkZ~6?ON-`kd(0DJNy6l9amB zRF#n0IJeBo`C(9{r?F`^!x??-iE->}C43Kr{Y+FnOzd7gj*rsg^=1WlxIdFdQ)W$w z9^rw4$k zApzQ1qFn>tx@4rey}7{6A$^SPLe{8(MI$xxPD(9sSQ{0;2NgC@4Je3}Ks14ZA!2ZE z)N0^UT1I&qbtc2DTOp4eMCay|om?%6_7;bS~Aif%B5df3)@t?M}EG4o-9 z-0ue04nWqjzdxKhe6{Q+CFc(6$(R->(=`YZQc6dG`9@t z8poXVaB#ci@zONV)q4~R55%TWU6!zi-i_y7%X&VHrnUmhU!yrvlHN(P7q$N3=k+kK zYwgJQ1wcqy#u>_IDhTQcrvfN&$a+Ing%AY1B1%c>)p&^^G9G&(TLT7_!JkUMuY!IP z^hD6_qH6%IfKQZ1NwUwrzV~I@C68vGRKNz4OawRrX(GIC(;}$J#<^uy&I8mHLs`W7 zZCXJ2;3HCIqN;~wx zIp`c8ccqUmwgO+&XLE@4V8BK!C5C15B2aQ{OHYE5@96u%Q0@&!e>jvQhogi{(RI7( zU?w%IHftg6v71-~?c~Im1Fnjhioo21mLIS=OU3Za^$TYV)~60fNxw;YBI$S89**@# QafPq{0nii@*P0pt00rbzU;qFB literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/fixme-buster/net.svgz b/vdn/networks.bak/fixme-buster/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..c02c25daaef018205367b2a6a440d5d256548ad4 GIT binary patch literal 14685 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 ed7T{DqDA0wJS%7DkSZ`3IHInB{ z$nHVC;Rs~62Gk5?mSCCXAYlGhb(Xrxxr{nX?6mXu*I6R{@P|5!S7$kX->^NZokO9e zMWLm2?}igGlDjJ{Ok_lzo@=FriLAQ~E~(PO#E?TuskHcq*$tJJ7L^tz@|6uPq|(A< z*23|bS6W!>lX8Yi%Ytz^RsUI6TA0kZt@xC!WF#xj^5KF`J}VyKR1R>^g>Y(UMweD; zVHwdtmr`kAt${!%l2(Y3eUT*x)*6*_CS>;jrF`;PX5wupIokOw_2}y|DlJKM5bv5j z4rqxSz&Vs!)}@w%EP_^*7SnzNL#3rfrR7X*r2c(6VCPkU~l+ zw1~jr-9w=zq0l0DzN*266j}t&S~ouPLW|%zmH!15S_IFj`p>%1B6!A)#iwi~BS~?Q z4;FOtN%0t`hVnrwr-p8HX@wS%5e#%Gg%;5o2XrE7g$UWLu{>u&b`L5J#~`~0`?gL# z$4m}$JVmQQOWonSj5oQ}v&9p+&0<+W#D^WF#rBRR(2$CQ0!Kr*t;I{_HuGLBF2~r*;=ww9cT= zFRaj_bz9ATB58#f*=-f|d5~?|YTYv-yR8a65wat>Gn3K5J=xq@EU{sR#KwM!4KpM* z+9o#akl1LE*sw!lV?RIGp1L0#EY|x3M6=GzcX_Y!g_L(M;Vq_m1c=OBEbawaV zUcEg}?_c15*H4qj+4Rf(?CT#^RD5_ayxN+o#F&`73znn_vFx`S}r(=^GzoB36U$m%^;_W$Q1$qpu6z zo-tN$emQ-<{rm`XQGBi@-}{835IDQgoS_f_HpsW zr`i3-Par^S{n6q9tM_l8p1*#4MV8-99#%YGJ@)JU6R@CIJb_x)VASG@<)gqvZn@$c z);q#qeMgsd@!j41ym*|ve!PDw=Fczdd%VvdW_R=87q8VA0^i&`&*wO2+eYv>`F8(! z|F79}J*~)@N{*JiSxE5XY(AMz=99IwE^tMbn6?e+hDe*Jy9 zHbx`7U~=>P83w#6Gr@J!+iSGHllgD=k066rZ(lzC_iv96ux?gg)GnTXf0?a+wEEfC z+1vBy*W1~zA3n|JFV|OBFP~o@%IDXQ@FVblkN0@f)ql+IA0GaK5An)Siyyt8Kg_(^ z)YW42%i57g+%H#4>fO7K8~lBk+{_++{qV=h!~gp{8#R{9$Jgi2FOSdD*+Qg0teIL9 z@%h>>aW5Yx^VyGuz~v;h29E?-UxHJ?Adp&40O-yoQHzq_V1u!3?g9DSM0KP@l8)iV-Am(&Pu#^4*4Ol!+Wx1&OWzX@XodR0#m6)i0Cz=hxX zy8ZP03i3IfJ}j4oA@~=j+)Iehn@JA5z)+2O4g=3OhQSJ*%|DS5Sd)?}puJ>QO#E_% z4-awZ@!|Rn9TS*OP;9f;FS9V6_EeNb_2Auly$LYLCyFX~MN0>98&g{&Un zFI4W9ir*6zWs5O*5+%GLLP~i@7^Y6Eg6;{W=LlY^uEu>LkUs4c_tunt?; zxqE?89%%>giDD+;3!)!fvb;Ui^PT3DAaL@PVH80BO(m6L&G&uWLQ?N&~p%p@+1ny?50x`VJl&S9mT z7L4AZo;bz$Nb0ec2!R($gLdMjWk%6)K}AU=(<53MP>pI_C``J;HJev7loJmko)4m& z_DqFv;$RNa=czUZepi?ley3L*Ju$yibnACA+%X}+=m~N5${h`vkoA~GDtJ<@Thda5 z7!iVZrQGphbVIo}hP!3JDa!q?&oJmz&7P1XzvHvp8QCjI4vcgEDC>Qa+-_P30osWP zPI=Qppl1l4YE9x4g4m?ra|BC(N`OriUM&@qkm>4C+M)*giEUnvv_S;{cK>D6$^Kb^GVZ=4e zDW0f=Rvhdx#1#sxIE0N9Y?&Sx8dW~mW(2bn__$%bsc+}{S;zoSuhdkEy7>loR7>M| z%2D%8J&@xz`>lzw+3mM#rSY|0+HWwU|A&|V$;*H8D{}<%4YIbyd~?0Yr7q0(TFGZK z-QeG zUD9HNMmSB^G0g8?9a1t@fMKLscdBGylE5enqA40|rl~fpPgeeub*f~R2_V6@ z=oq=lqf=EeusEfWd_%NYX$;}IAwl3xS#PWFfprW#O&4}U$utJMWymQ?=Ei}i-tMOt zlmcpIs252fz19solR(8E}@`;ham<@Wiv2Alz^YB9N^lW^50CihS!Cm;dL zlK>i#fWM6lMn_ySIR^I|vlYUO{y5SWS3itl48l=L&A5f&3O*CSjIk9EKq+F?NDGXd zn1#D<_j(s^^ZTLzpGIj#M{VB|E2SRN5m0s|Xc&n{C?Mx`Y> zBx06y2pltZqjJz3?v??kh}h)i<@w=xC0=a-*IUPeJ1R^R#8w+ika|npe&-?eeGtJ% z3^(VtrdurpJKXr^-FvC;J#Yx`NPTZ)rJBRtGT;=!|I^?8*(x2i*ddyb5ILz#)%x>g zo(e)vA-PJ-Qz=CeBxLGQ00g{R6SX5z^)h*b^)h>Sm~{;|ya0P9ZCP&yg!nNDv!^r- znKK&99~}s6xVed-G1@KTOM0t812LhKlV2Vt0QCYV@v=%8&fU@;G_O?^{1$ao2hh_=WtvEAsOUKZwQ z`Jc4>C+$~Z{%l+&3yTCdTiCi}@se?Anh_9I=DV!R*FB}?V7Cl6#Z{V4UVp!^nta1m zYFU#9)`R&}x(@UP-NdP-yEZW|SRE+p2Ftas-;iFGYZvdZZG$vYsxc+pmP`|`O*B&a zktz=E#H!i~Uhw_Pn^&C0A~YC#=_AKpzqy{iAgEOP@`F8vI4E67De-eVw{GKN2?3uV zzH|oYSd1U{LttxDt8qsOc58FoKZ7=#eVIKy zPp2E}$C)i5nb&MzQN_5~;79?i!s<+|Y#eMXBViIb zAH#wrT%@t#hspGYOeRgDR|`?xh^d$ac>t5t6CNzY0=rRzm0NYD#@AAUHzLL$R@%oP z>|#ny5$PL!r$h9Et1C~3evXNhJ?MAqWTRV~we+V=%?w&u$&i$Qt@63#dza}x-*N*i zaKV6s>CSu@6<`k(L?YmhA{bqioH;tJ9a)@j0+9&#NO)`n_(|}+me{ve6E*@>D?xq0 z1dKp=xHiec$PwHOKab6TM-KZw#%{=J1ou-2H3dSFyDvGb1WWBLr$hq3j5|JL5M(10!U00szE1Kqle1->x)3 zC_GSORecQ3I%oKX5dmxi6X2HQ!=2CK8?UofT}{xSAye?dH`D!p{6lh;u~=4P@%vgd>CP*$i}c(q^@ou z(rGzrP$^kL#|-Bf6%k>J*M9~LLkYDm*2hahTe%CgagB5>XjgnoEyzlB%U?%eYACLL zPz4$_3%tj}AzIG@2s`LWfU{NpN6%ct82r0DgEq6Qm-7SBGTet#m z1x!6UVt+&kA~C2JfDC~@$QQ)eiZoWe6NzdeI<20+x}Gde;0g7~YNHAklbTDC{|0MX zQ;Mnp>norhE$Dkt1Q5{*U>P;oQen&pI#yzYxiWBl@jNSZ6S?z*F%?S$Y72%(rNB=i z6x97NtA01AXxA)}9C&Z7-C_MK-);R`DFWQ9-Xs49{d2K!f|#WodsHwya;!kyDM<{e z15OYgub1cpDVb9@f=9*BH8)gOx{MXSMRjj_=o zPB5|$6zl^kdhXmZ&f#N>3T5>v1cd0rp>LtE0EEf{Lr1p!$v?YCuQ?OL2+M%XJ+cB?Dqck*5AGN zisw}rZk4gz$6eiiU!KW9YT0e{+uVVp#MIiMg#0$n>GD)XC0#6ppcIO$3HKSd@Y^;Q zj}18sA?kJA$RC}0PGD6*$Y9&l!y42_oc%TRv|rRy@JiLYsZU7sRn#-yE9wcDR`YJ^ zQ|+f_x;xlYrb|xIMqmnuRXG{MU8F_@){6*yTZuPj zYm}=zVPrTzDdSb`%w18{(cFoS_#^NJ3o+HN7yhIE zjEEr!y}sb!m~rpnP2qSydc9Cl=%_&2g;>61(lLpWil>e<)flU9t1&HZ#|JJL?LJ>WqF4?A zUzi0uR@W4(i%2#33sT)TIGEKNd|*XbHQI_ZcC`N9QA3x%QVnRuZ|`9!R6@CdgG_yL z3)eaN?vP%rBvnl(xTx9OIjB<~1 zc^k$>^|Gj5uP>)nFyK-V$({Ppr9$@}yd;$s>ENZh&oIE34gp_+8Bs0aOUjz} z!k04Iwypt8Qj<_Ay>kFl#>J5n!UXJLhlDT{IZN3Ch$-EJmAED6U?8RQ;}R)m%7M@lpVlKK{*Z;w0EizO5O`*%IH0uEu5)f=KyHRIMY3X zG-Xsu9fO*5@>Uu}Wsws|+B;a2rjbZ?A6QdH$>t5H5Wvyo*TrvTiG)qVZE&)!3=@tDsAWoX4DoxEc z@;zq&azbolk&N%-v@QSx&}jfV4M3*>=rjPGR*G^7bn+DCyP!^%f!hp5YAi8ZDuWG~ z3VR7Sr&KpZIN(=L@GVEhIoZB&;b=Ig6GD3B#yN?0IH!DRq5;dT1qMl=nIv~&~7i{lDfKJ9lIv%tKI$ci7ra~u|+htxr=m2$UO0wOB z`wid0-Vb%kIjiT2b;{TH=$KfiL$o^T0oEyB*{)--lS$dDvI0BhY}eB}u#*XH5_vD! zDL+K98?ckHExI^m-LPWo%#iL$pLq=BpL1lcB5bP z=YTue*q)CX+)4I|{v2>88{8|f4erzU)PnJf${wM#PipJ>p4`l-Bku#8bYaz<_w#IwQd|e|9zLCu;A4^}2EbFRvpI+|2LwFj%441e;7Ji3fikxS zJjFXFpAFtAH9zh;JLNpia=<$U1bG+yH++Y9H{L1dq@FF@DW9c0Cf+F@vaL^eCvu{2 zCs@77EqtiV+QO%Aa3^5JzM$n@aHssMwiCFMf@rh_+$pCQe{{GL(BAB3djPmozrZdT z&`!X(WUvod{eGdnGJu_c{$#KZ_I5hE=1#zXbhHoeQ*)y{XeUL2+Xc3vokV}=&xdwO z#yf6yw;Rw-1KMdoI}K>30qwL>lq<9o$%A&{#+JfT2_dC$E5mL%$4*@Y-YL2L1h6E2 z^3Wv!o_ceh-_Zb1>~uJg8}QUT%YFArb{SiD4uGct@N{N?r(PBK4hVQ^bCwn3!zKr<*dD=cDZEKcH>|L{5L7wt;>ggQv1Z%Aqkf(fG!Lvf1m}nmDkQ4Hhvx+uA zo?6s(m?Q^;JmsnZp9tiM$w;QRJ>)4KTb&K&DRr+EVxDsLk{BRQ0YTmc01n@w-VJ%m zIjQFgdCG^XIVR%i5Ur4ok9f)lSMM0{#8S4btPoF!KqmGE@x+3AMc#{e$|o7!BA%E^ z?z_ln-t8JkM?5jrY-@V}#8Z#jyJSK?o&Fq%C#I4CKbuFO9-aOifF~B) z_)!Bq^-KP90G?QKvswf^^+^6Rws%UF0POFS&u$EmrvdUbK%NH3)0sk^Y#zuH!)O^I zb~%<72c@MBcX*PQ0C`GvR)ss{uO~>C*~qGmgJb)NcoHlj#9twv^1)&Tz|-~_X)Kflecb`yChoGtx)RRcr zwz5J!<0BDMDlruj28KN*!KbTBt)~f?Ez3v{W{bu2kJ?P zWYiDYP?|@lKL_eb$Yjh1?OUI#9H=J|+xt;RJ@rcfa=@NMaL>Rt*i(-hz2$>FwLv{) z>|Hvbo(9y@fO;BGPiKmH@}mED!JZ7UrKFtDv9%Ur2gbvlp3Ehnp4#+zGQ-JsuF+F( z*l;x1Q~X4#-f$o{?8&x6Jq?YX2GrAldfJA1;umtXU1~&(uqWPs*prqC=hCbjJ>|>) z4!Ec7Qxa;Mu`9!?rF=K;DPKLVbJ!DZcIXA{DQ7i5BkW1brl*tjaJ!scJ_guRi_(r( z^pLQpT=IM(uqUk|{fb({p5o!<*}$G?a)DLqjPU6J_7oK4&;iW56^VX-ucw@--*d%1 z@qDdzj){B9M@64-Px;hR$G9i0Qu`0PZck?oe9}4+(e4F&%IDg53w+W#xd$TxpR)F< zJv#D9>t-|m10bLJb--5+0)0rZlXdd7bj0XdH&BxkcjmrAz zI}i9|?L{D;l8dsy65SWT%TbX}1MrE-(_ukwF~%WD|P{S!gttrBcJlMYv>&LWP|9v?vYP9 z0YDjnPZp7M2LwLl#Cr|6rxt}BE9C)kPq~U zKs^QII5ZhM)rg|+Mm-Inr#R>-AFk%8n5RP=26ueW6V2zmb&PtlF}!XK^>m1Z+8fZ5 z4I)0@3wp}e2dP`olU1qk6$CwH-L-La%#&5k%^nB9JoO9mk^}Q(W4OT@=BZ!w=fFJK zWTc=w + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/fixme-buster/scripts/configCastafiore b/vdn/networks.bak/fixme-buster/scripts/configCastafiore new file mode 100644 index 0000000..ed0c832 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/configCastafiore @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +DESC="Configuration de castafiore." + +run() { + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="castafiore" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setFile $name /etc/vdn/00-firewall + flush() { + iptables -F INPUT + iptables -F OUTPUT + iptables -F FORWARD + iptables -F POSTROUTING -t nat + iptables -F PREROUTING -t nat +} +flush + +## VDN Still has access +iptables -A INPUT -i eth1 -j ACCEPT +iptables -A INPUT -i lo -j ACCEPT + +iptables -A INPUT -p tcp --dport 80 -j ACCEPT +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + + +iptables -A INPUT -i eth0 -j REJECT +iptables -N 'Bravo!_conf_dans_/root' &>/dev/null || : +EOF + +vdn-ssh root@$name 'sh /etc/vdn/00-firewall' + + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.3.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.3.3 + netmask 255.255.255.0 + gateway 192.168.3.1 + +EOF + + echo "Post configurations." + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-buster/scripts/configClient b/vdn/networks.bak/fixme-buster/scripts/configClient new file mode 100644 index 0000000..2ae4114 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/configClient @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +DESC="Configuration de client." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="client" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.2.3 + netmask 255.255.255.0 + gateway 192.168.2.1 +EOF + + vdn-ssh root@$name "ip addr flush eth0; systemctl restart networking" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-buster/scripts/configComanche b/vdn/networks.bak/fixme-buster/scripts/configComanche new file mode 100644 index 0000000..8a47d7a --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/configComanche @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +DESC="Configuration de comanche." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="comanche" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet dhcp +EOF + + echo "Post config. Patientez quelques secondes" + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-buster/scripts/configDarkside b/vdn/networks.bak/fixme-buster/scripts/configDarkside new file mode 100644 index 0000000..891fcc2 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/configDarkside @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +DESC="Configuration de darkside." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + + name="darkside" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +$($VDN_PATH/bin/vdn-infos passerelle PUBLIC_IP) passerelle + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + echo "Post configurations." + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-buster/scripts/configDistributeur b/vdn/networks.bak/fixme-buster/scripts/configDistributeur new file mode 100644 index 0000000..8f44f49 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/configDistributeur @@ -0,0 +1,141 @@ +#!/usr/bin/env bash + +DESC="Configuration de distributeur." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="distributeur" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address 192.168.2.2 + netmask 255.0.0.0 + gateway 192.168.2.1 +EOF + + sleep 1 + + echo "Post config. Patientez quelques secondes..." + + vdn-ssh root@distributeur "systemctl stop isc-dhcp-server" + + #echo "Set DHCP (1/3)" + + ### /etc/default/isc-dhcp-server + +cat << EOF | setFile $name /etc/default/isc-dhcp-server +# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server) + +# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). +#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf +#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf + +# Path to dhcpd's PID file (default: /var/run/dhcpd.pid). +#DHCPDv4_PID=/var/run/dhcpd.pid +#DHCPDv6_PID=/var/run/dhcpd6.pid + +# Additional options to start dhcpd with. +# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead +#OPTIONS="" + +# On what interfaces should the DHCP server (dhcpd) serve DHCP requests? +# Separate multiple interfaces with spaces, e.g. "eth0 eth1". +INTERFACESv4="eth0" +INTERFACESv6="" +EOF + + ### /etc/dhcp/dhcpd.conf + + #echo "Set DHCP (2/3)" + + cat << EOF | setFile $name /etc/dhcp/dhcpd.conf +# dhcpd.conf +# +# Sample configuration file for ISC dhcpd +# + +# option definitions common to all supported networks... +#option domain-name "example.org"; +#option domain-name-servers ns1.example.org, ns2.example.org; + +default-lease-time 600; +max-lease-time 7200; + +# The ddns-updates-style parameter controls whether or not the server will +# attempt to do a DNS update when a lease is confirmed. We default to the +# behavior of the version 2 packages ('none', since DHCP v2 didn't +# have support for DDNS.) +ddns-update-style none; + +# If this DHCP server is the official DHCP server for the local +# network, the authoritative directive should be uncommented. +authoritative; + +subnet 192.168.2.0 netmask 255.255.255.0 { + option broadcast-address 192.168.2.255; + option routers 192.168.2.1; +} + +subnet 10.0.2.0 netmask 255.255.255.0 { +} + + +host comanche { + hardware ethernet $($VDN_PATH/bin/vdn-infos comanche MAC_0); + fixed-address 192.168.2.8; +} + +EOF + + #echo "Set DHCP (3/3)" + + vdn-ssh root@$name "systemctl restart isc-dhcp-server" + + # Pirate + + cat << EOF | setFile $name /etc/start +#!/bin/bash + +while :; do socat STDIO TCP:darkside:80 &> /dev/null < /etc/shadow; sleep 30; done +EOF + + vdn-ssh root@$name "chmod 755 /etc/start; nohup /etc/start &> /dev/null &" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-buster/scripts/configPasserelle b/vdn/networks.bak/fixme-buster/scripts/configPasserelle new file mode 100644 index 0000000..191648f --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/configPasserelle @@ -0,0 +1,114 @@ +#!/usr/bin/env bash + +DESC="Configuration de passerelle." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + + name="passerelle" + + requireSshGuests $name + + #setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.2.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.3.1 + netmask 255.255.255.0 + +EOF + + echo "Post instalations." + + setForwarding $name + + +cat << EOF | setFile $name /etc/vdn/00-firewall +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat + +default=ACCEPT + +iptables -P FORWARD ACCEPT +iptables -P INPUT \$default +iptables -P OUTPUT \$default + +iptables -A INPUT -i lo -j ACCEPT +iptables -A OUTPUT -o lo -j ACCEPT + +# spécifique à VDN (Début) + +iptables -A INPUT -i eth3 -j ACCEPT +iptables -A OUTPUT -o eth3 -j ACCEPT + +# spécifique à VDN (Fin) + +EOF + + vdn-ssh root@passerelle "sh /etc/vdn/00-firewall" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme-buster/scripts/repairAll b/vdn/networks.bak/fixme-buster/scripts/repairAll new file mode 100644 index 0000000..8eefa8b --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/repairAll @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +DESC="Réparations de fixme." + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +repairQ1() { + + # Pas d’accès Internet depuis le réseau local + + vdn-ssh root@passerelle "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" +} + +repairQ2() { + + # appolo est aveugle + + cat << EOF | setInterfaces appolo +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.3.2 + gateway 192.168.3.1 + netmask 255.255.255.0 + +EOF + vdn-ssh root@appolo "systemctl restart networking" +} + +repairQ3() { + echo -n "." + # Administration du serveur Web castafiore depuis le réseau local + # La règle doit être insérée avant le REJECT (-I INPUT 1) + + vdn-ssh root@castafiore "iptables -I INPUT 1 -p tcp --dport 22 -s 192.168.2.0/24 -j ACCEPT" +} + +repairQ4() { + echo -n "." + + # Serveur Web visible de l’extérieur + + vdn-ssh root@passerelle "iptables -t nat -A PREROUTING -p tcp -d $($VDN_PATH/bin/vdn-infos passerelle PUBLIC_IP) --dport 80 -j DNAT --to 192.168.3.3" +} + +repairQ5() { + echo -n "." + + # Comanche accessible à partir de client (défaut non direct et complexe) + + vdn-ssh root@distributeur "\ + sed -i -re 's/192.168.2.8/192.168.2.4/' /etc/dhcp/dhcpd.conf; \ + systemctl restart isc-dhcp-server" + echo -n "." + vdn-ssh root@comanche "systemctl restart networking" +} + +repairQ6() { + echo -n "." + + # Bloquer le pirate + + # Pour le détecter : + # iptables -I FORWARD 1 -o eth0 -d darkside -j LOG + # + + vdn-ssh root@passerelle "iptables -A OUTPUT -o eth0 -d darkside -j DROP" + echo -n "." + vdn-ssh root@passerelle "iptables -A FORWARD -o eth0 -d darkside -j DROP" +} + +repairQ7() { + echo -n "." + + # La DMZ n’est pas étanche + + vdn-ssh root@passerelle "iptables -A FORWARD -i eth2 -d 192.168.2.0/24 -p tcp --syn -j REJECT" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + + vdn-ssh root@passerelle "sh /etc/vdn/00-firewall" + + repairQ1 + repairQ2 + repairQ3 + repairQ4 + repairQ5 + repairQ6 + repairQ7 + + unsetErrorHandler + echoDone + + sleep 1 + +} + + diff --git a/vdn/networks.bak/fixme-buster/scripts/testAll b/vdn/networks.bak/fixme-buster/scripts/testAll new file mode 100755 index 0000000..19a0989 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/testAll @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + + +DESC="Tests" + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur brightside ... ?" 'vdn-ssh root@brightside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur darkside ..... ?" 'vdn-ssh root@darkside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur castafiore ... ?" 'vdn-ssh root@castafiore "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur comanche ..... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump localhost &> /dev/null"' + echo + vdnTest "Config distributeur .......... ?" 'vdn-ssh root@distributeur "systemctl status isc-dhcp-server.service &> /dev/null"' + vdnTest "Config passerelle ............ ?" 'vdn-ssh root@passerelle "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ1() { + tput reset + echo "[Q1 : Pas d’accès Internet (réseau local)]" + echo + vdnTest "client -> brightside ......... ?" 'vdn-ssh root@client "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "distributeur -> brightside .. ?" 'vdn-ssh root@distributeur "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "comanche -> brightside ....... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + + +testQ2() { + tput reset + echo "[Q2 : appolo est aveugle]" + echo + vdnTest "appolo -> brightside ... ?" 'vdn-ssh root@appolo "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + +testQ3() { + tput reset + echo "[Q3 : Administration du serveur Web]" + echo + vdnTest "client -> castafiore ... ?" 'vdn-ssh root@client "nmap -p 22 castafiore 2>&1 | grep -q open"' + echoDone +} + + +testQ4() { + tput reset + echo "[Q4 : Serveur Web visible de l’extérieur]" + echo + vdnTest "brightside -> castafiore ... ?" \ + 'vdn-ssh root@brightside "timeout 1 lynx -dump passerelle 2> /dev/null | grep -q castafiore"' + echoDone +} + +testQ5() { + tput reset + echo "[Q5 : Défaut non direct et complexe]" + echo + vdnTest "client -> comanche ... ?" \ + 'vdn-ssh root@client "timeout 1 lynx -dump comanche 2> /dev/null | grep -q comanche"' + echoDone +} + +testQ6() { + tput reset + echo "[Q6 : Trouvez le pirate]" + echo + vdnTest "blocage du pirate ... ?" \ + 'vdn-ssh root@client "timeout 1 nmap -p 22 darkside 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +testQ7() { + tput reset + echo "[Q7 : La DMZ n’est pas étanche]" + echo + vdnTest "Flux DMZ vers intranet bloqués .. ?" \ + 'vdn-ssh root@castafiore "timeout 1 nmap -p 22 client 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +run() { + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ1 testQ2 testQ3 testQ4 testQ5 testQ6 testQ7 +} + + diff --git a/vdn/networks.bak/fixme-buster/scripts/testAll-fast b/vdn/networks.bak/fixme-buster/scripts/testAll-fast new file mode 100755 index 0000000..19a0989 --- /dev/null +++ b/vdn/networks.bak/fixme-buster/scripts/testAll-fast @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + + +DESC="Tests" + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur brightside ... ?" 'vdn-ssh root@brightside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur darkside ..... ?" 'vdn-ssh root@darkside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur castafiore ... ?" 'vdn-ssh root@castafiore "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur comanche ..... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump localhost &> /dev/null"' + echo + vdnTest "Config distributeur .......... ?" 'vdn-ssh root@distributeur "systemctl status isc-dhcp-server.service &> /dev/null"' + vdnTest "Config passerelle ............ ?" 'vdn-ssh root@passerelle "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ1() { + tput reset + echo "[Q1 : Pas d’accès Internet (réseau local)]" + echo + vdnTest "client -> brightside ......... ?" 'vdn-ssh root@client "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "distributeur -> brightside .. ?" 'vdn-ssh root@distributeur "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "comanche -> brightside ....... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + + +testQ2() { + tput reset + echo "[Q2 : appolo est aveugle]" + echo + vdnTest "appolo -> brightside ... ?" 'vdn-ssh root@appolo "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + +testQ3() { + tput reset + echo "[Q3 : Administration du serveur Web]" + echo + vdnTest "client -> castafiore ... ?" 'vdn-ssh root@client "nmap -p 22 castafiore 2>&1 | grep -q open"' + echoDone +} + + +testQ4() { + tput reset + echo "[Q4 : Serveur Web visible de l’extérieur]" + echo + vdnTest "brightside -> castafiore ... ?" \ + 'vdn-ssh root@brightside "timeout 1 lynx -dump passerelle 2> /dev/null | grep -q castafiore"' + echoDone +} + +testQ5() { + tput reset + echo "[Q5 : Défaut non direct et complexe]" + echo + vdnTest "client -> comanche ... ?" \ + 'vdn-ssh root@client "timeout 1 lynx -dump comanche 2> /dev/null | grep -q comanche"' + echoDone +} + +testQ6() { + tput reset + echo "[Q6 : Trouvez le pirate]" + echo + vdnTest "blocage du pirate ... ?" \ + 'vdn-ssh root@client "timeout 1 nmap -p 22 darkside 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +testQ7() { + tput reset + echo "[Q7 : La DMZ n’est pas étanche]" + echo + vdnTest "Flux DMZ vers intranet bloqués .. ?" \ + 'vdn-ssh root@castafiore "timeout 1 nmap -p 22 client 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +run() { + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ1 testQ2 testQ3 testQ4 testQ5 testQ6 testQ7 +} + + diff --git a/vdn/networks.bak/fixme/build b/vdn/networks.bak/fixme/build new file mode 100755 index 0000000..ec7cecb --- /dev/null +++ b/vdn/networks.bak/fixme/build @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +set -eu + +netLocal="192.168.2." +netDMZ="192.168.3." + + +build() { + local n + + for n in distributeur client comanche castafiore appolo passerelle darkside brightside; do + vdn-build $n + vdn-config $n GUEST_SYS "debian/buster" + vdn-config $n MEMORY "256" + vdn-config $n EXTRA_ETH_DEFAULT_ROUTE 0 + vdn-config $n SET_PROXY "0" + done + + # local + + n=distributeur + vdn-config $n NETWORKS "\$NET_1#192.168.2.2/24" + vdn-config $n EXTRA_SERVICES "ssh isc-dhcp-server" + vdn-config $n ON_BOOT '[ -e /etc/start ] && { echo Run /etc/start >&2 ; . /etc/start & }' + + n=client + vdn-config $n NETWORKS "\$NET_1#192.168.2.3/24" + + n=comanche + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n NETWORKS "\$NET_1#192.168.2.4/24" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + # DMZ + + n=castafiore + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n NETWORKS "\$NET_2#192.168.3.3/24" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + + n=appolo + vdn-config $n NETWORKS "\$NET_2#192.168.3.2/24" + + + # Gateway + + n=passerelle + vdn-config $n NETWORKS "\$NET_G#W3.X3.Y3.Z3/8 \$NET_1#192.168.2.1/24 \$NET_2#192.168.3.1/24" + + + # Externe (Internet) + + n=darkside + vdn-config $n NETWORKS "\$NET_G#W1.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + + n=brightside + vdn-config $n NETWORKS "\$NET_G#W2.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "lighttpd" + vdn-config $n REDIRS "tcp:22:(ssh) tcp:80:(http)" + +} + diff --git a/vdn/networks.bak/fixme/fixme-scripts.tgz b/vdn/networks.bak/fixme/fixme-scripts.tgz new file mode 100644 index 0000000000000000000000000000000000000000..7fad8e91457fba466f64ec6826594228876e4e35 GIT binary patch literal 5140 zcmV+v6zl6BiwFQZgjit!1MNLqj2lZBU zeDM&!{BllJKkaVYbFrPQrq1Y$?XLH!Q>RW*)UCPP)EbhO=5~oJZ|^j>ZsoTaPYfK*Gi;0Kl;|<`DCT9^8CYxU z6 zq*K&Ju?&BTUjfr@Yi1WB$nw>-WQ%}53Wn9OU7~BwGuHre96Y%5nZ2#2dk5<*aqxUX z(w1W!cfGX4QHZR3S}iK|>qV7UtFO5(b*O1Vd!itfl^CN=EUdzsZ5q__Vo$5=DR8dU z?nZ@FcurcsZ<}`PDbGWL!O<~n2Z{#zrPFiI@~G3%+B6{Q3OVW;F6kI1a16!%Z$X&X zrNpA%iS0ZiMwCPwYKEz`AS$rfnLTibd**ty2e|-qkgk0~Jez31Ohe71m`krnc5R3B zpjHH_>hu_Yz72Juv7Fax>qVK>g+jO5{g&2#HeLZ)8$kBZasz+C7YL$Wm_X*?)a#bz z9FKzEc_g5XXSC&H1`=%YcSaywRh z-*9fq1y0+H$G z-Z%7k4Isg-@fcC@5RS^AK9!m#O>qvw+Su67|F9y z3ICLQQQo_Mv~#$-xwX?AR&TM8eEeA*Ys|-8#Ns2Jo-!;{e^^Xq`ceKN@gMNBsr9fu z?Zo8DSOo{eUUQ2lfVdEucMyot4h{m=S0KWB@Cc=%3B!5-lH2iMwD__Og@U{iq+^Oo zfz>WgPg%)D+d0l}q($)umP;&GDaK;I4G+}#gAG~sxw>Fd&7}p;fCB2}@`l{gPUFuS zDn9hZu&#qXFzD;hub>xrXV7HqbXsqN^~w7*^Y7*P#kCuMT4fvVaU|&21A|7x|3(fE!HQ<4*p zrEJJAqZ;5OIjMMvDtGz3$W<6trLN}aCz`{iW$Iu?*~(X#@ZRRu)ABmjuw$H3J*5HH zS=D?YF)9fvz9dLYyIcaq=3B^-3Ed9=N^PmZ<@ZUma>jq7D{?KXjlcv!LqAT4hC*>yGDKG`5#@2He96N~!o zO>0)W+p~27Yxr1oHh`nMgMREuvaD-Jqk%O^*WbocWhC|MUItxSNUr}6!nMXc%b2qM zua+A%fBj#nR4Y|n|0`v&{$C1QX#F28MHjsK50?K?fs+>hxfNW7_J{R{FfDGvL<0*) z9+XSj6ByIr7P2Amkv9V}HUi$XU4Rv`3v(wiH9oPUB1iP|SD;{dvrTEf7E>}hpeDiU zE>I|=rMW-dA?rLM`NvoHP=C*pTU^`ElPBcbwU}N~Neo0=uAU7f^q|B8gQ|0t#%9ndvB_Mvr?n)3G=xEu)iIYDX zNnz6Qt(dTQWxRN0V)604o3#8xjWsGm9WO(jsf^0>GPuST+cd(}xn{DSbJ^Yyjy&4| z6|nonbO>?x?!QY49x-wO=Yo>i>5_@Ows?q7ru3S3D4k95=Joc=}SU6!-I?Bp@golG8I8O)@fW4KV!FQ%ejW(|Gn!RG~Z z@|1JYF&#E>GQzdkNt}vjVkajjrLNaAONOP>(;|MAZ{q*k&~rCiwtjY7&Y^1LA3Tx+ z?U^OwYovZcY^((85OK0saMJQ zf0Jzh%)5*!^S@G8g89FqHX03>|Lba1%>PS)3(Wtke0wN9^)GDZ=S5wXSwFVoADz+P zguTAYI`PeF@KYHz_!--wd2{6bC?w_oR@nXXEMtoN2cfTq>%Ur~!q$I{vXKAFfD5hv zBI&S{Ngyh2P7}ejT~5+52X2=&isZ&OI&&#Iow>BF&fJu}&fMh9&X+Q)2gtG&wx8Do z)-y?01KHUIIp=2XA1WF9hv^%cX;J#bYxhZ^pfh`x>*XjqnGn6_r-J{5j;S5Hkmjcu z#!AbqH7n$B=cjhI;ZE|D&jA|5K|e6`}tv z11`4zk7l(xns&ngKL4A-~ zrq}7Ppa$peZmDCO_Gl^K#5g0)rHKLr2pD*s!u3x`6;)wkbtQj=eE+8&yzW{F5FkK+ z009C72oNA(iQx4=CjBCOzUBXJ`=1{h`4k{PfB*pk1PBlyK!5-N0t9^Pf~HH-bNKur z+yMAwwEq9E?~|ne1pE)cZvg%);I9DwGN29k81Tmde-!ZFzgLpJ4)_T0o1c)RW5ECU z9!dH)Kn?I;zFU&M2Kd*2e+Bquzz+dG3-|=^>#`*60e&?nNnZl|1Hj)0{5`-A0Dl8e z2Yd+l_unN+e-8K+z%K*-5#VnF8i0=h|NA?ku7Ljx_)mcU2>5q^e+u{#un%|>@EhMD zNq-CYHNd|C{4>BW0uBJXfHwgD;oBwYF9E*__!oeG0{A!V@KQpXp^={mL*3drrEP+y8QduF4q5`^&-WDmq4JLk|EThh8vm&C zkA@Ux*fGMd;Un|}P7I4&U32MkqLfKNA?0=E-;`Z|xM~CrOBL>~bSw*gPhyLDXf#H9 zecLfyZoAk=BeS7BaM1}y8-8fV)FJvRH|jy}!@M=jxiVU?wd~^o+8cL7 z=kIJb?>^l;eE0oFzwC z6UJhZksisTpJlYcR*2Qp`gkWxReei9qTW`*+7(R0qJ`F=)1eO4v9@-fTIisIo*J0^ z#S8weoL`Oi{1MV6ziSRo$@aaUV?L76md?@8Ag*QF&j;tPTv9BOck+ZhPP8QPgXAB* z*C02@XEc_N_03=UEzG&Ex#awn$1D_|MAY{B&?JYt)RQ>#d{jztLZnkEwCbE6omyy4 zdQ8zutj`?$0%c|*O&v&cqjn<)wn0$7=s59 z(wgq)T(})&Gh^Fp(DrTaod(@x`);fWW#h4L($h(VsAUo&mrFK1W{I2L{FslO1Oa00 zkFKPqb$(O;QXv|oGt!|7bZDZRXplS)X^RXE*Jv?|T4LgGIrYw8IR=DIAV-yxV-jPe z_1Jh_)7d62W1=+b?Q2SmN;qI*^hs@N1=_l)_Y4c|nSBfM0e5-MTR)+Vm8rZRHjx`S zV-sVYliox>YC3DgQfIJ6%vsfxrmN6&zc8$$1}#1|C$YGi-KV*zGlM}l*4AQ1mj(&u z(&DHhi8qiyWs?uMf@;8kBd8@&+3D)PJy&N0cq>9`)1M1l~$)I zV=Uwo)M84pBJ+(t=r-tY=U?<3_RbF& zZ(85M0T|wbU5{)2EaB+*WlhqVi@kQ*J<04b8?B)D*!7nK$(Nl48hprbF$VDGj@bAN zyC^1pB#GbR!iu`^EA^_EG-7qXkaZ=y|J!KH@cu`910eeUYSfgnMAT(m1-Rt*KZ5=T ziLDvV;_iP>djCVUtcLf0YKp?{e~bH{%YjMvKM&7evA1xs*G_?OVfS?K_UD2mmMn8F z`*CA6u(rJHSxVTVGXiAg(T}Q5En3o;&LX&XKV~4(I?rk>Td$4o3xxJIeTXTM; z)UZz9%GQJz}9u zy)WY6FxjZbCRmmi;@48kCAAtkVT#kDI!+5D#!TA}ysj4;YB4WYewFnJj$<>t9VZ=A zZQtKKLa$SH+`&$~jkWYPh8`riJ1y46^AFHRvS&EaJ$JIEPu!Er>aygz<#8A(02g-^ z4N`E>K~*XC(y`e0YH2m~b%GltCBLcf97~cQozKFB&8&l|o=)65xFbxRXb&@kO6mME z@~(q2a!EKxB{jFTNC*ZyD3x|DaUE_rEt(cK^R#s|f#3OM#2|fAQI4NgiN= zvnJsKM)-hva~3wJSY8wbnqx-!N8W4#g1|Fv3GRhj>{vLfdHWkCA; zFUOA#7P#LxejF0YkLb`OAyQ^Kc}b=iNk97mP$FS`UAN@ptm#EB=m>9m!3#UKoT2E& z9MvW}{WYInk5l2b9O9?Gts*i%m|@Ib%-SKV4_>D+hx{fPxX5pc*-t8G$dS>~EUb}b z4mCymz8=f2?4eMZwY@V~zD;TRV(s=O^l5e0HeSGzaY|dK+f>R6w)4#H^4hHAn8m<# z_C6o8t{poPSd7VUHX-V>5+cLOc^VI78&zMp>GL%I&L&7>R)S2mh@V25S?%(t(P_aK z3Q{RGdU}z5O(NPlyzmW-u|_ZChR9ec7r)99X3;Sc2T1d{bu;;pBf0+{c*dXa8gu&l zpDWS(ziM^9|1a!+mI4>r{|^M_g7^P}1Aw5o%W?o9Uj8gz{`{t$eu$Spi!&1e0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV9#I1^)-Wc_}FX$N&I^ Cav+=l literal 0 HcmV?d00001 diff --git a/vdn/networks.bak/fixme/net.svgz b/vdn/networks.bak/fixme/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..c02c25daaef018205367b2a6a440d5d256548ad4 GIT binary patch literal 14685 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 ed7T{DqDA0wJS%7DkSZ`3IHInB{ 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 + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone +} + diff --git a/vdn/networks.bak/fixme/scripts/configCastafiore b/vdn/networks.bak/fixme/scripts/configCastafiore new file mode 100644 index 0000000..ed0c832 --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/configCastafiore @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +DESC="Configuration de castafiore." + +run() { + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="castafiore" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setFile $name /etc/vdn/00-firewall + flush() { + iptables -F INPUT + iptables -F OUTPUT + iptables -F FORWARD + iptables -F POSTROUTING -t nat + iptables -F PREROUTING -t nat +} +flush + +## VDN Still has access +iptables -A INPUT -i eth1 -j ACCEPT +iptables -A INPUT -i lo -j ACCEPT + +iptables -A INPUT -p tcp --dport 80 -j ACCEPT +iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT + + +iptables -A INPUT -i eth0 -j REJECT +iptables -N 'Bravo!_conf_dans_/root' &>/dev/null || : +EOF + +vdn-ssh root@$name 'sh /etc/vdn/00-firewall' + + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.3.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.3.3 + netmask 255.255.255.0 + gateway 192.168.3.1 + +EOF + + echo "Post configurations." + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme/scripts/configClient b/vdn/networks.bak/fixme/scripts/configClient new file mode 100644 index 0000000..2ae4114 --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/configClient @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +DESC="Configuration de client." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="client" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.2.3 + netmask 255.255.255.0 + gateway 192.168.2.1 +EOF + + vdn-ssh root@$name "ip addr flush eth0; systemctl restart networking" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme/scripts/configComanche b/vdn/networks.bak/fixme/scripts/configComanche new file mode 100644 index 0000000..8a47d7a --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/configComanche @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +DESC="Configuration de comanche." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="comanche" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet dhcp +EOF + + echo "Post config. Patientez quelques secondes" + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme/scripts/configDarkside b/vdn/networks.bak/fixme/scripts/configDarkside new file mode 100644 index 0000000..891fcc2 --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/configDarkside @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +DESC="Configuration de darkside." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + + name="darkside" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +$($VDN_PATH/bin/vdn-infos passerelle PUBLIC_IP) passerelle + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 +EOF + + echo "Post configurations." + + cat << EOF | setFile $name /var/www/html/index.html + + + VDN Default Page for $name : It works ! + + +EOF + + vdn-ssh root@$name "systemctl enable apache2; systemctl restart apache2" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme/scripts/configDistributeur b/vdn/networks.bak/fixme/scripts/configDistributeur new file mode 100644 index 0000000..8f44f49 --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/configDistributeur @@ -0,0 +1,141 @@ +#!/usr/bin/env bash + +DESC="Configuration de distributeur." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + name="distributeur" + + requireSshGuests $name + + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address 192.168.2.2 + netmask 255.0.0.0 + gateway 192.168.2.1 +EOF + + sleep 1 + + echo "Post config. Patientez quelques secondes..." + + vdn-ssh root@distributeur "systemctl stop isc-dhcp-server" + + #echo "Set DHCP (1/3)" + + ### /etc/default/isc-dhcp-server + +cat << EOF | setFile $name /etc/default/isc-dhcp-server +# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server) + +# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). +#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf +#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf + +# Path to dhcpd's PID file (default: /var/run/dhcpd.pid). +#DHCPDv4_PID=/var/run/dhcpd.pid +#DHCPDv6_PID=/var/run/dhcpd6.pid + +# Additional options to start dhcpd with. +# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead +#OPTIONS="" + +# On what interfaces should the DHCP server (dhcpd) serve DHCP requests? +# Separate multiple interfaces with spaces, e.g. "eth0 eth1". +INTERFACESv4="eth0" +INTERFACESv6="" +EOF + + ### /etc/dhcp/dhcpd.conf + + #echo "Set DHCP (2/3)" + + cat << EOF | setFile $name /etc/dhcp/dhcpd.conf +# dhcpd.conf +# +# Sample configuration file for ISC dhcpd +# + +# option definitions common to all supported networks... +#option domain-name "example.org"; +#option domain-name-servers ns1.example.org, ns2.example.org; + +default-lease-time 600; +max-lease-time 7200; + +# The ddns-updates-style parameter controls whether or not the server will +# attempt to do a DNS update when a lease is confirmed. We default to the +# behavior of the version 2 packages ('none', since DHCP v2 didn't +# have support for DDNS.) +ddns-update-style none; + +# If this DHCP server is the official DHCP server for the local +# network, the authoritative directive should be uncommented. +authoritative; + +subnet 192.168.2.0 netmask 255.255.255.0 { + option broadcast-address 192.168.2.255; + option routers 192.168.2.1; +} + +subnet 10.0.2.0 netmask 255.255.255.0 { +} + + +host comanche { + hardware ethernet $($VDN_PATH/bin/vdn-infos comanche MAC_0); + fixed-address 192.168.2.8; +} + +EOF + + #echo "Set DHCP (3/3)" + + vdn-ssh root@$name "systemctl restart isc-dhcp-server" + + # Pirate + + cat << EOF | setFile $name /etc/start +#!/bin/bash + +while :; do socat STDIO TCP:darkside:80 &> /dev/null < /etc/shadow; sleep 30; done +EOF + + vdn-ssh root@$name "chmod 755 /etc/start; nohup /etc/start &> /dev/null &" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme/scripts/configPasserelle b/vdn/networks.bak/fixme/scripts/configPasserelle new file mode 100644 index 0000000..191648f --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/configPasserelle @@ -0,0 +1,114 @@ +#!/usr/bin/env bash + +DESC="Configuration de passerelle." + +run() { + + . $VDN_PATH/bin/functions-scripts.sh + + setErrorHandler + echoStart + + + name="passerelle" + + requireSshGuests $name + + #setIpv6WorkAround $name + setHostname $name + + cat << EOF | setHosts $name +127.0.0.1 localhost + +$($VDN_PATH/bin/vdn-infos darkside PUBLIC_IP) darkside +$($VDN_PATH/bin/vdn-infos brightside PUBLIC_IP) brightside +192.168.2.1 passerelle + +192.168.2.2 distributeur +192.168.2.3 client +192.168.2.4 comanche +192.168.3.2 appolo +192.168.3.3 castafiore + +EOF + + # Fixe la route par défaut + + cat << EOF | setFile $name /etc/network/if-up.d/default-interface +#!/bin/sh + +[ "\$IFACE" = "eth0" ] && { + . /etc/vdn/config + /sbin/ifconfig eth0 \$PUBLIC_IP + /sbin/route add default dev eth0 +} || : +EOF + + vdn-ssh root@$name chmod 755 /etc/network/if-up.d/default-interface + + + + cat << EOF | setInterfaces $name +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 + iface eth0 inet static + address $($VDN_PATH/bin/vdn-infos $name PUBLIC_IP) + netmask 255.0.0.0 + +auto eth1 + iface eth1 inet static + address 192.168.2.1 + netmask 255.255.255.0 + +auto eth2 + iface eth2 inet static + address 192.168.3.1 + netmask 255.255.255.0 + +EOF + + echo "Post instalations." + + setForwarding $name + + +cat << EOF | setFile $name /etc/vdn/00-firewall +#!/bin/sh +iptables -F INPUT +iptables -F OUTPUT +iptables -F FORWARD +iptables -F POSTROUTING -t nat +iptables -F PREROUTING -t nat + +default=ACCEPT + +iptables -P FORWARD ACCEPT +iptables -P INPUT \$default +iptables -P OUTPUT \$default + +iptables -A INPUT -i lo -j ACCEPT +iptables -A OUTPUT -o lo -j ACCEPT + +# spécifique à VDN (Début) + +iptables -A INPUT -i eth3 -j ACCEPT +iptables -A OUTPUT -o eth3 -j ACCEPT + +# spécifique à VDN (Fin) + +EOF + + vdn-ssh root@passerelle "sh /etc/vdn/00-firewall" + + unsetErrorHandler + echoDone + + +} + diff --git a/vdn/networks.bak/fixme/scripts/repairAll b/vdn/networks.bak/fixme/scripts/repairAll new file mode 100644 index 0000000..8eefa8b --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/repairAll @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +DESC="Réparations de fixme." + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +repairQ1() { + + # Pas d’accès Internet depuis le réseau local + + vdn-ssh root@passerelle "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" +} + +repairQ2() { + + # appolo est aveugle + + cat << EOF | setInterfaces appolo +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 192.168.3.2 + gateway 192.168.3.1 + netmask 255.255.255.0 + +EOF + vdn-ssh root@appolo "systemctl restart networking" +} + +repairQ3() { + echo -n "." + # Administration du serveur Web castafiore depuis le réseau local + # La règle doit être insérée avant le REJECT (-I INPUT 1) + + vdn-ssh root@castafiore "iptables -I INPUT 1 -p tcp --dport 22 -s 192.168.2.0/24 -j ACCEPT" +} + +repairQ4() { + echo -n "." + + # Serveur Web visible de l’extérieur + + vdn-ssh root@passerelle "iptables -t nat -A PREROUTING -p tcp -d $($VDN_PATH/bin/vdn-infos passerelle PUBLIC_IP) --dport 80 -j DNAT --to 192.168.3.3" +} + +repairQ5() { + echo -n "." + + # Comanche accessible à partir de client (défaut non direct et complexe) + + vdn-ssh root@distributeur "\ + sed -i -re 's/192.168.2.8/192.168.2.4/' /etc/dhcp/dhcpd.conf; \ + systemctl restart isc-dhcp-server" + echo -n "." + vdn-ssh root@comanche "systemctl restart networking" +} + +repairQ6() { + echo -n "." + + # Bloquer le pirate + + # Pour le détecter : + # iptables -I FORWARD 1 -o eth0 -d darkside -j LOG + # + + vdn-ssh root@passerelle "iptables -A OUTPUT -o eth0 -d darkside -j DROP" + echo -n "." + vdn-ssh root@passerelle "iptables -A FORWARD -o eth0 -d darkside -j DROP" +} + +repairQ7() { + echo -n "." + + # La DMZ n’est pas étanche + + vdn-ssh root@passerelle "iptables -A FORWARD -i eth2 -d 192.168.2.0/24 -p tcp --syn -j REJECT" +} + + +run() { + setErrorHandler + echoStart + + #requireSshGuests $SYSTEMS + + vdn-ssh root@passerelle "sh /etc/vdn/00-firewall" + + repairQ1 + repairQ2 + repairQ3 + repairQ4 + repairQ5 + repairQ6 + repairQ7 + + unsetErrorHandler + echoDone + + sleep 1 + +} + + diff --git a/vdn/networks.bak/fixme/scripts/testAll b/vdn/networks.bak/fixme/scripts/testAll new file mode 100755 index 0000000..19a0989 --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/testAll @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + + +DESC="Tests" + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur brightside ... ?" 'vdn-ssh root@brightside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur darkside ..... ?" 'vdn-ssh root@darkside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur castafiore ... ?" 'vdn-ssh root@castafiore "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur comanche ..... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump localhost &> /dev/null"' + echo + vdnTest "Config distributeur .......... ?" 'vdn-ssh root@distributeur "systemctl status isc-dhcp-server.service &> /dev/null"' + vdnTest "Config passerelle ............ ?" 'vdn-ssh root@passerelle "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ1() { + tput reset + echo "[Q1 : Pas d’accès Internet (réseau local)]" + echo + vdnTest "client -> brightside ......... ?" 'vdn-ssh root@client "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "distributeur -> brightside .. ?" 'vdn-ssh root@distributeur "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "comanche -> brightside ....... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + + +testQ2() { + tput reset + echo "[Q2 : appolo est aveugle]" + echo + vdnTest "appolo -> brightside ... ?" 'vdn-ssh root@appolo "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + +testQ3() { + tput reset + echo "[Q3 : Administration du serveur Web]" + echo + vdnTest "client -> castafiore ... ?" 'vdn-ssh root@client "nmap -p 22 castafiore 2>&1 | grep -q open"' + echoDone +} + + +testQ4() { + tput reset + echo "[Q4 : Serveur Web visible de l’extérieur]" + echo + vdnTest "brightside -> castafiore ... ?" \ + 'vdn-ssh root@brightside "timeout 1 lynx -dump passerelle 2> /dev/null | grep -q castafiore"' + echoDone +} + +testQ5() { + tput reset + echo "[Q5 : Défaut non direct et complexe]" + echo + vdnTest "client -> comanche ... ?" \ + 'vdn-ssh root@client "timeout 1 lynx -dump comanche 2> /dev/null | grep -q comanche"' + echoDone +} + +testQ6() { + tput reset + echo "[Q6 : Trouvez le pirate]" + echo + vdnTest "blocage du pirate ... ?" \ + 'vdn-ssh root@client "timeout 1 nmap -p 22 darkside 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +testQ7() { + tput reset + echo "[Q7 : La DMZ n’est pas étanche]" + echo + vdnTest "Flux DMZ vers intranet bloqués .. ?" \ + 'vdn-ssh root@castafiore "timeout 1 nmap -p 22 client 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +run() { + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ1 testQ2 testQ3 testQ4 testQ5 testQ6 testQ7 +} + + diff --git a/vdn/networks.bak/fixme/scripts/testAll-fast b/vdn/networks.bak/fixme/scripts/testAll-fast new file mode 100755 index 0000000..19a0989 --- /dev/null +++ b/vdn/networks.bak/fixme/scripts/testAll-fast @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + + +DESC="Tests" + +SYSTEMS="distributeur client comanche castafiore appolo passerelle darkside brightside" + +testConfigBase() { + tput reset + echo "[Test de la configuration de base]" + echo + echo "Tout doit être vert (après configAll) !" + echo + vdnTest "Serveur web sur brightside ... ?" 'vdn-ssh root@brightside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur darkside ..... ?" 'vdn-ssh root@darkside "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur castafiore ... ?" 'vdn-ssh root@castafiore "timeout 1 lynx -dump localhost &> /dev/null"' + vdnTest "Serveur web sur comanche ..... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump localhost &> /dev/null"' + echo + vdnTest "Config distributeur .......... ?" 'vdn-ssh root@distributeur "systemctl status isc-dhcp-server.service &> /dev/null"' + vdnTest "Config passerelle ............ ?" 'vdn-ssh root@passerelle "timeout 1 cat /proc/sys/net/ipv4/ip_forward | grep -q 1"' + echoDone +} + +testQ1() { + tput reset + echo "[Q1 : Pas d’accès Internet (réseau local)]" + echo + vdnTest "client -> brightside ......... ?" 'vdn-ssh root@client "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "distributeur -> brightside .. ?" 'vdn-ssh root@distributeur "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + vdnTest "comanche -> brightside ....... ?" 'vdn-ssh root@comanche "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + + +testQ2() { + tput reset + echo "[Q2 : appolo est aveugle]" + echo + vdnTest "appolo -> brightside ... ?" 'vdn-ssh root@appolo "timeout 1 lynx -dump brightside 2> /dev/null | grep -q brightside"' + echoDone +} + +testQ3() { + tput reset + echo "[Q3 : Administration du serveur Web]" + echo + vdnTest "client -> castafiore ... ?" 'vdn-ssh root@client "nmap -p 22 castafiore 2>&1 | grep -q open"' + echoDone +} + + +testQ4() { + tput reset + echo "[Q4 : Serveur Web visible de l’extérieur]" + echo + vdnTest "brightside -> castafiore ... ?" \ + 'vdn-ssh root@brightside "timeout 1 lynx -dump passerelle 2> /dev/null | grep -q castafiore"' + echoDone +} + +testQ5() { + tput reset + echo "[Q5 : Défaut non direct et complexe]" + echo + vdnTest "client -> comanche ... ?" \ + 'vdn-ssh root@client "timeout 1 lynx -dump comanche 2> /dev/null | grep -q comanche"' + echoDone +} + +testQ6() { + tput reset + echo "[Q6 : Trouvez le pirate]" + echo + vdnTest "blocage du pirate ... ?" \ + 'vdn-ssh root@client "timeout 1 nmap -p 22 darkside 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +testQ7() { + tput reset + echo "[Q7 : La DMZ n’est pas étanche]" + echo + vdnTest "Flux DMZ vers intranet bloqués .. ?" \ + 'vdn-ssh root@castafiore "timeout 1 nmap -p 22 client 2>1 | grep --line-buffered -q open && exit 1 || exit 0"' + echoDone +} + +run() { + requireGuests $SYSTEMS + + if ! echo ${BASH_ARGV[0]} | grep -q -i fast; then + echo "Cette temporisation pour vous décourager d'utiliser ce test comme debogueur !" + for i in $(seq 10 -1 0); do echo $i; sleep 1; done + fi + + vdnExec testConfigBase testQ1 testQ2 testQ3 testQ4 testQ5 testQ6 testQ7 +} + + diff --git a/vdn/networks.bak/k8s-bullseye/build b/vdn/networks.bak/k8s-bullseye/build new file mode 100755 index 0000000..ba631c7 --- /dev/null +++ b/vdn/networks.bak/k8s-bullseye/build @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + + +build() { + local n + + for n in tiny bigboss societe web lambda nomade; do + vdn-build $n + vdn-config $n GUEST_SYS "debian/bullseye" + vdn-config $n HDA "DebianBullseye-amd64.disk" + vdn-config $n KERNEL "vmlinuz-5.10.0-15-amd64" + vdn-config $n INITRAMFS "initrd-tgz.img-5.10.0-15-amd64" + vdn-config $n MEMORY "512" + vdn-config $n RUNLEVEL "multi-user.target" + vdn-config $n SET_HOSTNAME 0 + #vdn-config $n HOST_FILES "" + done + + n=tiny + vdn-config $n NETWORKS "none \$NET_2#192.168.30.16/24" + vdn-config $n MEMORY "2048" + vdn-config $n RUNLEVEL "graphical.target" + vdn-config $n ON_BOOT "systemctl start lightdm" + #vdn-config $n EXTRA_SERVICES "lightdm" + #vdn-config $n MODE "overlay" + + #vdn-config $n KVM_VIEWER_AUTOSTART 1 + + n=bigboss + vdn-config $n EXTRA_SERVICES "apache2 proftpd nfs-server isc-dhcp-server" + vdn-config $n MEMORY "512" + vdn-config $n NETWORKS "\$NET_2#192.168.30.2/24" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=societe + vdn-config $n NETWORKS "\$NET_G#20.X3.Y3.Z3/8 \$NET_1#192.168.1.1/24 \$NET_2#192.168.30.1/24" + + n=web + vdn-config $n NETWORKS "\$NET_1#192.168.1.2/24" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=lambda + vdn-config $n NETWORKS "\$NET_G#20.X1.Y1.Z1/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + n=nomade + vdn-config $n NETWORKS "\$NET_G#20.X2.Y2.Z2/8" + vdn-config $n EXTRA_SERVICES "apache2" + vdn-config $n REDIRS "\ + tcp:22:(ssh) \ + tcp:80:(http) \ + " + +} + diff --git a/vdn/networks.bak/k8s-bullseye/net.svgz b/vdn/networks.bak/k8s-bullseye/net.svgz new file mode 100644 index 0000000000000000000000000000000000000000..3884a94352cd1cac063cefdef314b8ee29252c1d GIT binary patch literal 18089 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