├── .gitmodules ├── COPYING ├── DEVELOPERS ├── README.md ├── automake.sh ├── autotest.sh ├── clean.sh ├── resources ├── autotest │ └── basic.exp ├── boot │ ├── grub │ │ ├── grub.cfg.casper │ │ ├── grub.cfg.doublesword │ │ └── theme │ │ │ ├── background.jpg │ │ │ ├── select_c.png │ │ │ ├── slider_c.png │ │ │ ├── slider_n.png │ │ │ ├── slider_s.png │ │ │ ├── terminal_box_c.png │ │ │ ├── terminal_box_e.png │ │ │ ├── terminal_box_n.png │ │ │ ├── terminal_box_ne.png │ │ │ ├── terminal_box_nw.png │ │ │ ├── terminal_box_s.png │ │ │ ├── terminal_box_se.png │ │ │ ├── terminal_box_sw.png │ │ │ ├── terminal_box_w.png │ │ │ └── theme.txt │ └── memtest ├── casper │ └── bin │ │ └── casper-md5check ├── etc │ ├── apt │ │ ├── sources.list.binary │ │ └── sources.list.source │ ├── dialogrc │ ├── historian.profile │ ├── internet.dialogrc │ ├── netplan │ │ ├── 01-network-container.yaml │ │ └── 01-network-host.yaml │ ├── ngircd │ │ └── ngircd.conf │ ├── scout-manage.conf │ ├── security │ │ └── limits.conf │ ├── sudo.conf │ ├── sysctl.d │ │ └── 60-net-congestion-control.conf │ ├── systemd │ │ ├── networkd.conf │ │ ├── nspawn │ │ │ └── container.nspawn │ │ └── system │ │ │ ├── container-setup.service │ │ │ ├── historian.service │ │ │ ├── host-setup.service │ │ │ ├── internet-indicator.service │ │ │ ├── internet-indicator.timer │ │ │ ├── memwatchdog.service │ │ │ ├── privexec.service │ │ │ ├── supervise.service │ │ │ └── systemd-nspawn@container.service.d │ │ │ └── override.conf │ └── vtrgb ├── gpg │ └── 871920D1991BC93C.asc ├── initrd │ └── scripts │ │ ├── casper-bottom │ │ └── 01wrtblk_all │ │ ├── doublesword │ │ └── doublesword-bottom │ │ └── 01wrtblk_all ├── irssi │ └── irssi.conf.client ├── lib │ └── udev │ │ └── 01-readonly-disks.rules ├── openvpn │ ├── ip_pool.lst │ ├── scout.conf.client │ ├── scout.conf.expert │ └── scout.conf.server ├── sbin │ ├── container-setup │ ├── historian.sh │ ├── host-iptables │ ├── host-setup │ ├── memwatchdog.sh │ ├── privexecd.sh │ └── supervised.sh ├── squashfs │ └── exclude.list ├── usr │ ├── bin │ │ ├── container-resume.sh │ │ ├── container-suspend.sh │ │ ├── internet-indicator.sh │ │ ├── privexec │ │ ├── scout-manage │ │ ├── scout-monitor │ │ ├── supervised-shell │ │ └── torcustomconfig.sh │ ├── sbin │ │ ├── wrtblk │ │ ├── wrtblk-disable │ │ └── wrtblk-ioerr │ └── share │ │ ├── bitscout │ │ ├── introduction │ │ └── scout-manage.service │ │ └── vim │ │ └── vimrc └── wireguard │ ├── wg0.conf.client │ ├── wg0.conf.expert │ └── wg0.conf.server └── scripts ├── chroot.devel_enter.sh ├── chroot_add_managementtool.sh ├── chroot_configure.sh ├── chroot_configure_irc.sh ├── chroot_configure_ssh.sh ├── chroot_configure_syslog.sh ├── chroot_configure_vpn.sh ├── chroot_create_container.sh ├── chroot_create_user.sh ├── chroot_customize.sh ├── chroot_download.sh ├── chroot_enter.sh ├── chroot_enter_devel.sh ├── chroot_install_base.sh ├── chroot_install_forensics.sh ├── chroot_install_forensics_extra.sh ├── chroot_install_kernel.sh ├── chroot_install_remoteaccess.sh ├── chroot_internet_indicator.sh ├── chroot_postdownload_setup.sh ├── chrootscreen_end.sh ├── chrootscreen_start.sh ├── deb_pack.sh ├── deb_unpack.sh ├── export_generate.sh ├── functions ├── image_build-nosquashfs-rebuild.sh ├── image_build.sh ├── image_prebuild_cleanup.sh ├── image_prepare.sh ├── initrd_doublesword.sh ├── initrd_findlivefs_fix.sh ├── initrd_integritycheck_fix.sh ├── initrd_pack.sh ├── initrd_unpack.sh ├── initrd_writeblocker.sh ├── interrupted_clean.sh ├── nspawn_container_spawn.sh ├── nspawn_enter.sh ├── nspawn_session.exp ├── skeleton.sh ├── submodules_fetch.sh └── welcome.sh /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "resources/apt-fast"] 2 | path = resources/apt-fast 3 | url = https://github.com/vitaly-kamluk/apt-fast 4 | -------------------------------------------------------------------------------- /DEVELOPERS: -------------------------------------------------------------------------------- 1 | Project Bitscout 2 | Author: Vitaly Kamluk // bitscout[at]kaspersky.com 3 | 4 | This file briefly describes the structure of the project for developers. 5 | 6 | Base system 7 | Current base system is Ubuntu 22.04 LTS. 8 | 9 | Virtualization 10 | Bitscout relies on LXC 1.0 for virtualization. One option was to use full VM, but 11 | given that we are runing from live media, it had to be something lightweight 12 | and optimal. LXC perfectly works here, because kernel becomes shared between the 13 | container and the host. Also, kernel mechanisms for IPC, such as file locking 14 | and pipes can be used for IPC between the host and the guest. We used 15 | unprivileged container that runs as user. However, we need to provide rootfs to 16 | such container and as far as we used the same source from squashfs, we had to 17 | remap uid/gid for some otherwise inaccessible files. So far the script that 18 | starts the container does this job and remaps uid/gid to subuid/subgid of the 19 | target user for the whole root filesystem. This lets us avoid data duplication 20 | in memory. 21 | 22 | Optimisation 23 | We aimed to make the system optimal in size. You may find extensive usage of 24 | overlayfs, compressed memory block device (zram) and more tuning to save space. 25 | Both host and guest system run from the same source image, but each of the 26 | system can be independently extended or modified. 27 | 28 | Extension 29 | The system is designed to be extended in memory. Both host and guest users can 30 | install additional packages in RAM. 31 | 32 | Customisation 33 | The best way to customize your own build of Bitscout is to create additional 34 | script in scripts directory. Unless you suggest a bugfix, please stick to 35 | extension of the code, rather than patching existing pieces. And you are very 36 | welcome to submit you suggested fixes and improvements. We know there is a lot 37 | to be done to improve security, stability and usability of the project. 38 | When you make a new task to modify rootfs or other things, please write in the 39 | way that doesn't apply changes twice if the same script is executed again. 40 | Current scripts follow this idea, this allows to make tiny changes and rerun the 41 | subscripts without risk to break the final system. I.e. you can make some change to 42 | the way how container is created (./scripts/chroot_create_container.sh) and then 43 | manually run ISO rebuild (./scripts/image_build.sh). That shall generate you the 44 | new ISO file with your changes applied without the need to run all other scripts. 45 | 46 | Structure and description of the files: 47 | automake.sh - this is core script that runs others. Feel free to run it whole or 48 | part of it (i.e. to avoid recurring base system download). 49 | 50 | scripts/ - this is directory with scripts to do main tasks. Some are prefixed 51 | according to current stage of execution: 52 | welcome.sh - the initial global configuration script and welcome message. 53 | chroot_* - scripts to install, configure and change root filesystem 54 | image_* - scripts to pack rootfs and generate ISO file 55 | export_generate.sh - prepare configs for other systems (VPN server, expert) 56 | initrd_* - these can pack/unpack initrd image. Used for initrd patches. 57 | chroot_enter.sh/chroot_leave.sh - these scripts can be used if you would like 58 | to run shell in chrooted environment. For the sake of automation it 59 | relies on screen tool that runs as root. To use this, run the first 60 | script and then "sudo screen -r" to join the screen session. To 61 | leave it simply run scripts/chroot_leave.sh from a separate shell. 62 | And, yes, if you know a better way to do that, please suggest! 63 | functions - this file is included by others, provides most common settings and 64 | global utility functions, i.e. running commands in chrooted screen 65 | session. 66 | 67 | 68 | Running scripts 69 | Currently all scripts have to be called from the root directory of the project, i.e. 70 | $ ./scripts/image_build.sh 71 | 72 | How to contribute 73 | We'd love to have you contribute! Our goal is to have a builder that can build 74 | the smallest Live OS useful for forensics. It would be nice to further reduce 75 | the size of the ISO file to te best possible minimum. If you are into it, look 76 | into image_prebuild_cleanup.sh. Perhaps you could bring it to a new level! 77 | One thing to consider: we need to keep essential features, which include: 78 | 1. Disk controllers' and RAID modules 79 | 2. Network devices 80 | 3. LXC support 81 | 4. Filesystems support 82 | 83 | If you want to try your ideas, make sure you read these articles first: 84 | https://wiki.debian.org/ReduceDebian 85 | https://wiki.ubuntu.com/ReducingDiskFootprint 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Project Bitscout 2 | Home page: https://bitscout-forensics.info 3 | 4 | Bitscout is a customizable live OS constructor tool written entirely in Bash. It's main purpose is to help you quickly create your own remote forensics bootable disk image. 5 | 6 | This project was created by security researchers to be able to do remote system triage, malware threat hunting, digital forensics, incident response, and more. Do not expect a common user graphical interface, and if you are not familiar with the Linux command line, it's a wise idea to learn that first. This constructor can be customized to include your tools, however one of the core ideas was to remotely assist Law Enforcement investigations as well as incident responders, which is why Bitscout by default includes a number of forensic and malware analysis tools and is focused on protecting the disk drives from accidental or intentional modifications. 7 | 8 | We recommend exploring the project home page first. However, if you are ready to start on your own, below is a little guidance to help you. 9 | 10 | ### Basic usage: 11 | 12 | 1. Build new ISO file: 13 | ``` 14 | $ ./automake.sh 15 | ``` 16 | After running this command, you may need to answer some questions such as location of your VPN server, type of build, etc. 17 | 18 | Hint: if you are not running Linux and still want to try Bitscout, you can start Ubuntu from LiveCD and build an image there. It's better to attach an external storage in this case to make sure you don't run out of memory. But previously, we managed you to build Bitscout even with 2GB of RAM. To download Ubuntu LiveCD, please go here: 19 | https://www.ubuntu.com/download/desktop 20 | Alternatively, you may try one of our pre-built images (only for demo, not production): 21 | https://bitscout-forensics.info/quick-try/prebuilt-images 22 | 23 | Bitscout build demo, as well as setup of other components, can be seen here: 24 | https://bitscout-forensics.info/docs/basic-usage 25 | Alternatively, here is some older video on Youtube that shows building Bitscout right from an Ubuntu LiveCD: 26 | https://www.youtube.com/watch?v=knA0NS9tWsY 27 | 28 | Note: the automake.sh script runs some commands as root, such as mounting local cache directories and creating new root filesystem permissions. However, all changes shall affect only current directory and subdirectories, unless your system is missing some essential packages to build the ISO (in this case they will be installed). 29 | 30 | 2. Test new ISO file: 31 | ``` 32 | $ ./autotest.sh 33 | ``` 34 | This command shall run tests against the freshly built ISO file. It verifies components' presence on the ISO and attempts to boot the ISO file using qemu to verify that all essential services are running. 35 | 36 | To better understand what Bitscout is, we suggest you read further description of users' roles in the process and the FAQ below. 37 | 38 | ### User roles: 39 | Bitscout relies on at least three components in the process of remote forensics: 40 | 1. **The owner** 41 | The owner is a user who has physical access to the target system and owns it. The owner's role is to download, verify and burn the ISO image file to a removable storage (CD-Rom or USB). After that the target system must be started from this bootable media. In case of LAN DHCP network configuration everything shall work automatically. In case of other setup, the owner has to configure network access using a simple management interface that is brought up on the physical console once Bitscout is loaded. 42 | 43 | 2. **The expert** 44 | The expert is a remote user who connects to the target system over SSH using VPN link via the expert's server. Bitscout attempts to find existing VPN configuration and SSH keys in ./config directory. If it doesn't exist it will get the default config and generate new VPN certificates and SSH keys during the build. 45 | 46 | Hint: let Bitscout generate new keys for you and populate ./config directory, which you can customize later and rebuild the ISO by running [automake.sh](https://github.com/KasperskyLab/bitscout/blob/master/automake.sh) again. 47 | 48 | 3. **Expert's server** 49 | The expert's server shall be accessible from the network of the target system. It shall run an instance of VPN software (i.e. OpenVPN or Wireguard), possibly a Syslog server for remote command logging, and IRC chat server for communication. Suggested server configuration files can be found in the ./exports directory after a successful build of ISO file. 50 | 51 | ### Bitscout Features: 52 | 1. Transparency 53 | a. You build your own live disk instead of using someone else's. The build process is rather straightforward and detailed. One of the core principles of Bitscout is to not use proprietary binary executables during the build process. 54 | b. You may choose what packages you put on Bitscout ISO. This lets you decide which binaries you trust. 55 | c. The owner can monitor what is going on in an expert's container live or via a recorded session, which can be replayed. This is useful for training or understanding of the forensic process in the court. 56 | 57 | 2. Forensics 58 | a. Bitscout is designed to not modify hard drive data or other storage media attached to the system. This is essential for forensic analysis. 59 | b. Bitscout contains most popular tools to acquire and analyze storage drives. 60 | c. The owner of the system controls which disk devices are accessible to the expert in read-only (or read-write) mode. 61 | d. Even running as root the expert cannot modify or reset access to the provided storage devices, which prevents potential data loss from the source disk. This is achieved via layers of virtualization. 62 | 63 | 3. Customization 64 | a. The set of tools available on Bitscout can be customized by editing respective scripts before running the build. You can add standard packages or your own tools. Make it available to experts, system owners or both. 65 | b. Both system owner and expert can install additional software packages on an already running (booted) system. All changes will be done independently (experts cannot change the owner's environment). All installed software exists only in RAM and will be gone when the system is restarted. This doesn't apply to Bitscout with persistence feature. 66 | c. If certain operations require more memory or a large disk which is not available on the system, the owner may attach a writable external storage device (such as fast USB flash memory) to be used for storage or swap by the expert. 67 | 68 | 4. Compact 69 | a. Bitscout project is designed to be a minimal yet universal tool to access remote systems. It contains a minimal set of packages, libraries and tools to start the system and provide most common forensic tools to the expert immediately. Certain optimizations are yet to be added to reduce size even further. If you have a nice idea to reduce the size, please share it via the Github issues section. 70 | b. The system uses no graphical interface on purpose. This reduces disk image size and RAM consumption. 71 | c. The expert's runs inside an unprivileged Linux container, which saves from overhead of full virtualization. The container relies on the same kernel as the host system, but doesn't allow kernel module manipulation. 72 | d. The container root filesystems are overlaid from the live CD rootfs. This enables us to reuse the system binaries and configuration and avoid data duplication. Yet, mapped with copy-on-write access it provides almost unlimited modification of the whole OS. The real limit is just the size of available memory and swap. As a matter of fact, fully running OS with a child OS inside the container used less than 200Mb of RAM in some of our tests in the past. 73 | 74 | ### F.A.Q: 75 | 76 | **Q: Why was the system created?** 77 | **A:** There are a lot of commercial and rather expensive forensic software suites out there. We tried several of the most popular of them and always bumped into functionality limitations and lack of transparency. While some suites provide scriptability, they lack remote analysis features that do not modify the evidence disk. Most forensic tools are not designed for remote analysis, lack flexibility and cost a fortune. We found that there was a niche for a new tool which is 78 | 1. trusted, transparent and open source (you build your own OS!) 79 | 2. customizable (you put your own tools!) 80 | 3. stable and reliable 81 | 4. rich in features and compact 82 | 5. fast and optimized for lower RAM usage 83 | 6. free of charge 84 | 7. runs on merely any hardware 85 | 86 | **Q: How was the project developed?** 87 | **A:** The project was initially developed as a hobby project. The first variant relied on full trust to the remote user, who was provided with root access to the live system. Soon we realized that the remote system owner is willing to track the progress, communicate with the expert and be able to approve access to storage media. To increase trust level between the system's owner and the remote expert we decided to isolate the expert within a virtualized container. This assured the owner of the system that the source disk information will never be tampered (unless it is permitted by the owner in case of system remediation request). 88 | 89 | **Q: Does the author provide a VPN server with this project?** 90 | **A:** No, you have to use your own server. All you need is an OpenVPN or a Wireguard instance. Both are free and open-source, and run on all platforms. For more information, see https://openvpn.net and https://www.wireguard.com. 91 | 92 | **Q: Will the product be supported?** 93 | **A:** It will be supported as long as there is a need for such a tool. We will migrate to newer LTS versions of Ubuntu as it is released. This is important to upgrade forensic tools. However, you can always update an already running live system from a newer repository and install more recent versions of certain packages. In case you have a rare case of a 32-bit CPU, look into Bitscout versions, because Canonical stopped supporting 32-bit only builds some time ago. 94 | 95 | **Q: Do I need to re-run `./automake.sh` every time I change anything, i.e. put my 96 | own VPN certificate or SSH key?** 97 | **A:** No. automake.sh script is just an easy do-everything script to build a new ISO file from scratch in one run. Feel free to copy and modify it. Comment out stages that you don't want to pass again from top to bottom and run it. Make sure you run the last stage image_build.sh to rebuild the ISO file. If you didn't modify the rootfs in the chroot directory, you can also use scripts/image_build-nosquashfs-rebuild.sh to save even more time. 98 | 99 | **Q: Is this the best forensic product to save the world?** 100 | **A:** It is not and was never meant to be so. It serves its task though and did help us in the past in some complicated circumstances and under time pressure. If it works for you we will be happy to hear your story. If not, perhaps you could suggest a clever patch? 101 | 102 | **Q: Is this project used for business?** 103 | **A:** This project was created independently of my employer's product line and outside of scope of the company's business operation. The developed tool is not limited to particular users and might be useful to researchers, high-tech crime units of Law Enforcement, and educational institutions. 104 | 105 | Credits: 106 | Kaspersky 107 | INTERPOL Digital Forensics Lab 108 | Individual contributors to Bitscout project 109 | 110 | Thanks to 111 | Linux kernel developers 112 | Canonical Ltd 113 | All those incredible authors of Linux forensics tools 114 | 115 | For more information, please visit our website at https://bitscout-forensics.info 116 | 117 | 118 | -------------------------------------------------------------------------------- /automake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file is part of Bitscout remote digital forensics project. 3 | # Copyright Kaspersky Lab. Contact: bitscout[at]kaspersky.com 4 | # Bitscout is free software: you can redistribute it and/or modify it under the 5 | # terms of the GNU General Public License as published by the Free Software 6 | # Foundation, either version 2 of the License, or (at your option) any later 7 | # version. 8 | # Bitscout is distributed in the hope that it will be useful, but WITHOUT ANY 9 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 10 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. 11 | # You should have received a copy of the GNU General Public License along with 12 | # Bitscout. If not, see . 13 | 14 | #welcome and initial settings: 15 | ( 16 | SECONDS=0 17 | scripts/welcome.sh && 18 | scripts/submodules_fetch.sh && 19 | 20 | #prepare rootfs directory: 21 | scripts/chroot_download.sh && 22 | scripts/chroot_postdownload_setup.sh && 23 | scripts/chroot_install_base.sh && 24 | scripts/chroot_install_kernel.sh && 25 | scripts/chroot_install_forensics.sh && 26 | #scripts/chroot_install_forensics_extra.sh && #several issues need to be resolved 27 | scripts/chroot_install_remoteaccess.sh && 28 | scripts/chroot_customize.sh && 29 | 30 | 31 | #configure target system: 32 | scripts/chroot_create_user.sh && 33 | scripts/chroot_create_container.sh && 34 | scripts/chroot_configure.sh && 35 | scripts/chroot_configure_vpn.sh && 36 | scripts/chroot_configure_ssh.sh && 37 | scripts/chroot_configure_irc.sh && 38 | scripts/chroot_configure_syslog.sh && 39 | 40 | #adding management tool(s): 41 | scripts/chroot_add_managementtool.sh && 42 | scripts/chroot_internet_indicator.sh && 43 | 44 | #prepare ISO files: 45 | scripts/image_prepare.sh && 46 | 47 | #reduce size of the rootfs: 48 | scripts/image_prebuild_cleanup.sh && 49 | 50 | #apply initrd/casper fixes: 51 | scripts/initrd_unpack.sh && 52 | scripts/initrd_findlivefs_fix.sh && 53 | #scripts/initrd_integritycheck_fix.sh && 54 | scripts/initrd_writeblocker.sh && 55 | scripts/initrd_doublesword.sh && 56 | scripts/initrd_pack.sh && 57 | 58 | #buld the target iso or disk image 59 | scripts/image_build.sh && 60 | 61 | #prepare exportable configs/certs/keys: 62 | scripts/export_generate.sh 63 | 64 | duration=$SECONDS 65 | echo "Process finished. Time taken: $(($duration / 60)) min. $(($duration % 60)) sec." 66 | ) 2>&1 | stdbuf -i0 -o0 -e0 tee ./automake.log 67 | 68 | #Final cleanup in case of interrupted builds 69 | scripts/interrupted_clean.sh 70 | 71 | -------------------------------------------------------------------------------- /autotest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file is part of Bitscout remote digital forensics project. 3 | # Copyright Kaspersky Lab. Contact: bitscout[at]kaspersky.com 4 | # Bitscout is free software: you can redistribute it and/or modify it under the 5 | # terms of the GNU General Public License as published by the Free Software 6 | # Foundation, either version 2 of the License, or (at your option) any later 7 | # version. 8 | # Bitscout is distributed in the hope that it will be useful, but WITHOUT ANY 9 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 10 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. 11 | # You should have received a copy of the GNU General Public License along with 12 | # Bitscout. If not, see . 13 | export SHELL=/bin/bash 14 | 15 | . ./scripts/functions 16 | 17 | ISONAME="${PROJECTNAME}-22.04-${GLOBAL_BASEARCH}.iso" 18 | TESTLOG="./autotest.log" 19 | VISIBLE=$(test -z $TERM && echo 0 || echo 1) #show tmux interface during testing 20 | VMRAM=1024 #Megabytes 21 | 22 | if [ ! -f "./$ISONAME" ] 23 | then 24 | echo "Error: couldn't find the ISO file to test at $ISONAME." 25 | exit 1 26 | fi 27 | 28 | install_required_package qemu-kvm 29 | install_required_package socat 30 | install_required_package tmux 31 | install_required_package expect 32 | 33 | [ -f "$TESTLOG" ] && rm "$TESTLOG" 34 | 35 | dprint() 36 | { 37 | echo -e "$*" | tee -a "$TESTLOG" 38 | } 39 | 40 | DATE=`TZ=UTC date +%c` 41 | dprint "autotest: Started new autotest on $DATE" 42 | 43 | TMSESSION="$PROJECTNAME" 44 | TMWINDOW="qemu" 45 | 46 | waitfor_socket() 47 | { 48 | SOCKETPATH="$1" 49 | dprint "Waiting for socket at $SOCKETPATH .." 50 | while true 51 | do 52 | if [ -S "$SOCKETPATH" ] 53 | then 54 | break 55 | else 56 | sleep 1 57 | fi 58 | done 59 | return 0 60 | } 61 | 62 | vm_keyboard_pushkeys() 63 | { 64 | while read k; 65 | do 66 | tmux send-keys -t:${TMWINDOW}.1 "sendkey $k" 67 | tmux send-keys -t:${TMWINDOW}.1 "enter" 68 | done 69 | } 70 | 71 | vm_keyboard_typetext() 72 | { 73 | while IFS="" read -r -n1 c; 74 | do 75 | case "$c" in 76 | [[:space:]]) 77 | c="spc" 78 | ;; 79 | "=") 80 | c="equal" 81 | ;; 82 | ",") 83 | c="comma" 84 | ;; 85 | [[:upper:]] ) 86 | c="shift-"${c,} 87 | ;; 88 | esac 89 | if [ -n "$c" ] 90 | then 91 | tmux send-keys -t:${TMWINDOW}.1 "sendkey $c" 92 | tmux send-keys -t:${TMWINDOW}.1 "enter" 93 | fi 94 | done 95 | } 96 | 97 | if tmux has-session -t "$TMSESSION" 2>/dev/null >/dev/null 98 | then 99 | dprint "Found $TMSESSION tmux session.\n Seems that autotest is already running or unfinished. Aborting.." 100 | exit 0; 101 | fi 102 | 103 | [ -S "./${PROJECTNAME}.monitor.sock" ] && dprint "Removing existing monitor socket.." && rm "./${PROJECTNAME}.monitor.sock" 104 | [ -S "./${PROJECTNAME}.serial.sock" ] && dprint "Removing existing serial socket.." && rm "./${PROJECTNAME}.serial.sock" 105 | 106 | dprint "Creating a new local tmux session and starting qemu.." #pane .0 107 | if [ -w /dev/kvm ] 108 | then 109 | dprint "Using hardware virtualization support.." 110 | if ! tmux new-session -d -n $TMWINDOW -s $TMSESSION "qemu-system-x86_64 -enable-kvm -name ${PROJECTNAME}-qemu -cpu host -m $VMRAM -cdrom \"./$ISONAME\" -boot order=c -spice port=2001,disable-ticketing -serial unix:./${PROJECTNAME}.serial.sock,server -chardev socket,id=monitordev,server,path=./${PROJECTNAME}.monitor.sock -mon chardev=monitordev -S; tmux wait-for -S $TMSESSION" 111 | then 112 | dprint "Failed to start qemu in tmux session. Aborting.." 113 | exit 1 114 | else 115 | dprint "Started qemu in a tmux session." 116 | fi 117 | else 118 | dprint "No hardware virtualization support found. Going for software emulation.." 119 | if ! tmux new-session -d -n $TMWINDOW -s $TMSESSION "qemu-system-x86_64 -name ${PROJECTNAME}-qemu -cpu qemu64 -m $VMRAM -cdrom \"./$ISONAME\" -boot order=c -spice port=2001,disable-ticketing -serial unix:./${PROJECTNAME}.serial.sock,server -chardev socket,id=monitordev,server,path=./${PROJECTNAME}.monitor.sock -mon chardev=monitordev -S; tmux wait-for -S $TMSESSION" 120 | then 121 | dprint "Failed to start qemu in tmux session. Aborting.." 122 | exit 1 123 | else 124 | dprint "Started qemu in tmux session." 125 | fi 126 | fi 127 | 128 | dprint "Waiting for the qemu monitor socket.." 129 | waitfor_socket "./${PROJECTNAME}.monitor.sock" 130 | 131 | dprint "Attaching to monitor socket.." #pane .1 132 | tmux split-window -v -t "$TMSESSION:$TMWINDOW" -p 90 "socat - ./${PROJECTNAME}.monitor.sock" 133 | 134 | dprint "Waiting for the serial port socket.." 135 | waitfor_socket "./${PROJECTNAME}.serial.sock" 136 | 137 | dprint "Attaching to the serial port socket.." #pane .2 138 | tmux split-window -h -t "$TMSESSION:$TMWINDOW" -p 90 "./resources/autotest/basic.exp; tmux send-keys -t:$TMWINDOW.1 \"system_powerdown\" && tmux send-keys -t:$TMWINDOW.1 \"enter\" && tmux send-keys -t:$TMWINDOW.1 \"quit\" && tmux send-keys -t:$TMWINDOW.1 \"enter\"" 139 | sleep 0.1 140 | 141 | 142 | dprint "Initiating boot process.." 143 | tmux send-keys -t:$TMWINDOW.1 "cont" 144 | tmux send-keys -t:$TMWINDOW.1 "enter" 145 | 146 | #sleep 3 147 | #dprint "Modifying kernel boot options in GRUB.." 148 | #echo -e "e\nenter\ndown\ndown\nend\nleft\nleft\nleft\nleft\nleft" | vm_keyboard_pushkeys 149 | #echo -n " console=tty0 console=ttyS0,115200" | vm_keyboard_typetext 150 | #echo -e "ctrl-x" | vm_keyboard_pushkeys 151 | 152 | dprint "To view the VM console use command:\n$ remote-viewer spice://localhost:2001" 153 | if [ $VISIBLE -eq 1 ] 154 | then 155 | dprint "Attaching to the tmux session.." 156 | tmux attach -t $TMSESSION 157 | else 158 | dprint "Waiting for autotest completion..\n(Hint: set VISIBLE=1 in $0 to see VM interaction)." 159 | tmux wait-for $TMSESSION 160 | fi 161 | 162 | echo "Autotest complete. Quick summary:" 163 | grep "^autotest: " ./autotest.log | sed 's/^autotest://g' 164 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file is part of Bitscout remote digital forensics project. 3 | # Copyright Kaspersky Lab. Contact: bitscout[at]kaspersky.com 4 | # Bitscout is free software: you can redistribute it and/or modify it under the 5 | # terms of the GNU General Public License as published by the Free Software 6 | # Foundation, either version 2 of the License, or (at your option) any later 7 | # version. 8 | # Bitscout is distributed in the hope that it will be useful, but WITHOUT ANY 9 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 10 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. 11 | # You should have received a copy of the GNU General Public License along with 12 | # Bitscout. If not, see . 13 | 14 | . ./scripts/functions 15 | builddirs=( $(find $PWD -maxdepth 1 -type d | grep 'build\.' | sed 's/^.*\.\([^.]*\)$/\1/' ) ) 16 | 17 | statusprint "Unmounting filesystems from chroot environment.." 18 | chroot_unmount_fs "./build.$GLOBAL_BASEARCH/chroot" 19 | 20 | statusprint "Removing all temporary files for each architecture, except target image/iso file(s) and configuration.." 21 | sudo rm -rf ./chroot 22 | #sudo rm -rf ./chroot ./chroot.devel ./tmp ./image ./initrd ./recycle ./cache ./autotest.log ./automake.log ./bitscout.monitor.sock ./bitscout.serial.sock 23 | 24 | if [ ${#builddirs[@]} = 1 ]; then 25 | echo "Removing: ./build.${builddirs[0]} ./autotest.log ./automake.log ./bitscout.monitor.sock ./bitscout.serial.sock ..." 26 | sudo rm -rf ./build.${builddirs[0]} ./autotest.log ./automake.log ./bitscout.monitor.sock ./bitscout.serial.sock 27 | 28 | elif [ ${#builddirs[@]} -gt 1 ]; then 29 | 30 | echo "There are more than 1 architectures found, please select which to be deleted based on the option number shown below." 31 | echo "0. ALL Architectures" 32 | for (( i=0;i<${#builddirs[@]}; i++ )); do 33 | echo $(($i+1))". ${builddirs[$i]}" 34 | done 35 | 36 | while [[ -z $choice || ! $choice =~ ^-?[0-9]+$ || "$choice" -gt "${#builddirs[@]}" || "$choice" -lt "0" ]]; 37 | do 38 | read -p "Please make your choice (Ctrl+C to abort): " choice 39 | done 40 | 41 | if [ "$choice" -ne "0" ]; then 42 | echo "Removing: ./build.${builddirs[$(($choice-1))]} ./autotest.log ./automake.log ./bitscout.monitor.sock ./bitscout.serial.sock ..." 43 | sudo rm -rf ./build.${builddirs[$(($choice-1))]} ./autotest.log ./automake.log ./bitscout.monitor.sock ./bitscout.serial.sock 44 | else 45 | echo "Removing ALL Architectures + ./autotest.log ./automake.log ./bitscout.monitor.sock ./bitscout.serial.sock ..." 46 | sudo rm -rf ./autotest.log ./automake.log ./bitscout.monitor.sock ./bitscout.serial.sock 47 | for (( i=0;i<${#builddirs[@]}; i++ )); do 48 | echo "Removing ./build.${builddirs[$(($i))]} ..." 49 | sudo rm -rf ./build.${builddirs[$(($i))]} 50 | done 51 | fi 52 | 53 | else 54 | echo "Oops, nothing to clean.." 55 | fi 56 | -------------------------------------------------------------------------------- /resources/autotest/basic.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect 2 | 3 | log_file ./autotest.log 4 | set timeout 180 5 | send_log "\nConnecting to bitscout serial socket..\n" 6 | 7 | send "Please let the system boot..\n// " 8 | spawn socat - UNIX-CONNECT:./bitscout.serial.sock 9 | set socatpid [exp_pid] 10 | 11 | if { $socatpid > 0 } { 12 | send_log "autotest: Bitscout serial port socket was opened. QEMU serial port: OK" 13 | } else { 14 | send_log "\nautotest: CRITICAL, failed to connect to bitscout serial port socket. QEMU serial port: ERROR" 15 | exit 16 | } 17 | 18 | send_log "\nBooting the system..\n" 19 | expect { 20 | "bitscout-host login:" { send_log "\nautotest: Login prompt found. System boot: OK\n"; } 21 | timeout { send_log "\nautotest: Timeout expired while waiting for login prompt. System boot: ERROR\n"; exit } 22 | } 23 | set timeout 180 24 | send "user\n" 25 | expect -re {^.*user.*@.*bitscout-host.*\$ } 26 | 27 | send_log "Becoming root..\n" 28 | send "sudo -i\n" 29 | expect -re {^.*root.*@.*bitscout-host.*\$ } 30 | 31 | #1. Test container status 32 | send_log "\nChecking if the container is running..\n" 33 | set container_started 0 34 | while { $container_started == 0 } { 35 | send "machinectl show container\n" 36 | expect { 37 | "State=running" { expect "\n"; send_log "autotest: Container is up. Container check: OK\n"; set container_started 1; break } 38 | -re {^.*root.*@bitscout-host.*\$ } { send_log "\nContainer has not started yet. Waiting..\n"; sleep 3 } 39 | timeout { send_log "autotest: CRITICAL, timeout waiting for container. Container check: ERROR"; exit } 40 | } 41 | } 42 | 43 | #2. Test services status: openvpn, ssh, privexecd, historian, ... 44 | send_log "Checking host system services status..\n" 45 | #check openvpn-client@scout.service 46 | send "systemctl --no-pager status openvpn-client@scout.service | tr -cd '\\11\\12\\15\\40-\\176' \n" 47 | expect { 48 | "Active:*failed" { expect "\n"; send_log "\nautotest: OpenVPN service is not running. OpenVPN: ERROR\n"; } 49 | "Unit openvpn*@scout.service could not be found." { expect "\n"; send_log "\nautotest: OpenVPN service is not installed. OpenVPN: ERROR\n"; } 50 | "Active:*active (running)" { expect "\n"; send_log "\nautotest: OpenVPN service is running. OpenVPN: OK\n"; } 51 | } 52 | expect "root*bitscout-host*\$ " 53 | 54 | #check privexec.service 55 | send "systemctl --no-pager status privexec.service | tr -cd '\\11\\12\\15\\40-\\176' \n" 56 | expect { 57 | "Active:*failed" { expect "\n"; send_log "\nautotest: PrivExec service is not running. PrivExec: ERROR\n"; } 58 | "Active:*active (running)" { expect "\n"; send_log "\nautotest: PrivExec service is running. PrivExec: OK\n"; } 59 | } 60 | expect "root*bitscout-host*\$ " 61 | 62 | #check historian.service 63 | send "systemctl --no-pager status historian.service | tr -cd '\\11\\12\\15\\40-\\176' \n" 64 | expect { 65 | "Active:*failed" { expect "\n"; send_log "\nautotest: Historian service is not running. Hostorian: ERROR\n"; } 66 | "Active:*active (running)" { expect "\n"; send_log "\nautotest: Historian service is running. Historian: OK\n"; } 67 | } 68 | expect "root*bitscout-host*\$ " 69 | 70 | set timeout 180 71 | set container_loaded 0 72 | while { $container_loaded == 0 } { 73 | send "systemctl show systemd-nspawn@container.service --no-pager -p StatusText \n" 74 | expect { 75 | -re {StatusText=Container running: Startup finished in.*} { expect "$ "; send_log "\n autotest: Container is booted\n"; set container_loaded 1; break; } 76 | -re {StatusText=Container running\.\r.*} { expect "$ "; sleep 5; send "systemctl show systemd-nspawn@container.service --no-pager -p StatusText \n"; } 77 | -re {StatusText=\r.*} { expect "$ "; sleep 5; send "systemctl show systemd-nspawn@container.service --no-pager -p StatusText \n"; } 78 | timeout { send_log "\n autotest: CRITICAL, timeout waiting for container to boot.\n"; exit; } 79 | } 80 | } 81 | 82 | #check guest services 83 | send_log "Checking guest system services status..\n" 84 | #interact 85 | 86 | set timeout 180 87 | #entering the guest container 88 | send "machinectl shell container /bin/bash\n" 89 | expect { 90 | -re {^.*root.*@.*bitscout[^-].*\$ } { send_log "\nautotest: Guest container shell is available. Container shell: OK\n"; } 91 | timeout { send_log "\nautotest: CRITICAL, couldn't enter the container shell. Container shell: ERROR\n"; exit; } 92 | } 93 | 94 | #check ssh.service 95 | send "systemctl --no-pager status ssh.service | tr -cd '\\11\\12\\15\\40-\\176' \n" 96 | expect { 97 | "Active: failed" { expect "\n"; send_log "\nautotest: Container's ssh service is not running. Container SSH: ERROR\n"; } 98 | "Active: active (running)" { expect "\n"; send_log "\nautotest: Container's ssh service is running. Container SSH: OK\n"; } 99 | -re "Active: inactive|Active: activating" { expect "root*bitscout*\$ "; sleep 1; send "systemctl --no-pager status ssh.service | tr -cd '\\11\\12\\15\\40-\\176' \n"; exp_continue; } 100 | timeout { send_log "\nautotest: SSH server is not running in the container. Container SSH: ERROR\n"; exit } 101 | } 102 | expect "root*bitscout*\$ " 103 | 104 | #The following is optional, uncomment the next line if you want to do manual checks 105 | #interact 106 | 107 | #exiting and shutting down the system 108 | send "exit\n" 109 | expect "root*@*bitscout*\$ " 110 | send "poweroff -f\n\n" 111 | 112 | expect { 113 | "Powering off." { send_log "\nautotest: Test graceful exit: OK\n" } 114 | timeout { send_log "\nautotest: Test graceful exit: ERROR\n" } 115 | } 116 | 117 | -------------------------------------------------------------------------------- /resources/boot/grub/grub.cfg.casper: -------------------------------------------------------------------------------- 1 | set timeout=5 2 | set default=0 3 | 4 | insmod part_msdos 5 | insmod iso9660 6 | insmod jpeg 7 | 8 | set gfxmode=1024x768x24 9 | set color_normal=white/black 10 | set color_highlight=red/black 11 | set theme=/boot/grub/theme/theme.txt 12 | 13 | insmod gfxmenu 14 | insmod gfxterm 15 | 16 | terminal_output gfxterm 17 | loadfont /boot/grub/font.pf2 18 | background_image /boot/grub/theme/background.jpg 19 | 20 | menuentry "Start " { 21 | linux /casper/vmlinuz boot=casper net.ifnames=0 biosdevname=0 hostname=-host username= initrd=/casper/initrd.img noeject noprompt loop.max_loop=32 console=tty0 console=ttyS0,115200 vga=791 -- 22 | initrd /casper/initrd.img 23 | } 24 | 25 | menuentry "Start (failsafe)" { 26 | linux /casper/vmlinuz boot=casper net.ifnames=0 biosdevname=0 hostname=-host username= initrd=/casper/initrd.img nomodeset nodma nomce noapm noapic nosplash loop.max_loop=32 vga=normal noeject console=tty0 console=ttyS0,115200 -- 27 | initrd /casper/initrd.img 28 | } 29 | 30 | menuentry "Integrity check" { 31 | linux /casper/vmlinuz integrity-check boot=casper net.ifnames=0 biosdevname=0 hostname=-host username= initrd=/casper/initrd.img noprompt noeject loop.max_loop=32 console=tty0 loop.max_loop=32 -- 32 | initrd /casper/initrd.img 33 | } 34 | 35 | menuentry "Memory Test x86+" { 36 | linux16 /casper/memtest 37 | } 38 | 39 | #menuentry "Boot MBR on first hard drive!" { 40 | # set root=(hd0) 41 | # chainloader +1 42 | #} 43 | -------------------------------------------------------------------------------- /resources/boot/grub/grub.cfg.doublesword: -------------------------------------------------------------------------------- 1 | set timeout=5 2 | set default=0 3 | 4 | insmod part_msdos 5 | insmod iso9660 6 | insmod jpeg 7 | 8 | set gfxmode=1024x768x24,auto 9 | set color_normal=white/black 10 | set color_highlight=red/black 11 | set theme=/boot/grub/theme/theme.txt 12 | 13 | insmod gfxmenu 14 | insmod gfxterm 15 | 16 | terminal_output gfxterm 17 | loadfont /boot/grub/font.pf2 18 | background_image /boot/grub/theme/background.jpg 19 | 20 | menuentry "Start " { 21 | linux /boot/vmlinuz boot=doublesword root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX persist=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX net.ifnames=0 biosdevname=0 hostname=-host username= initrd=/boot/initrd.img noeject noprompt loop.max_loop=32 console=tty0 console=ttyS0,115200 vga=791 -- 22 | initrd /boot/initrd.img 23 | } 24 | 25 | menuentry "Clean start " { 26 | linux /boot/vmlinuz boot=doublesword persistmode=cleanup root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX persist=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX net.ifnames=0 biosdevname=0 hostname=-host username= initrd=/boot/initrd.img noeject noprompt loop.max_loop=32 console=tty0 console=ttyS0,115200 vga=791 -- 27 | initrd /boot/initrd.img 28 | } 29 | 30 | menuentry "Start (failsafe)" { 31 | linux /boot/vmlinuz boot=doublesword root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX persist=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX net.ifnames=0 biosdevname=0 hostname=-host username= initrd=/boot/initrd.img nomodeset nodma nomce noapm noapic nosplash loop.max_loop=32 vga=normal noeject console=tty0 console=ttyS0,115200 -- 32 | initrd /boot/initrd.img 33 | } 34 | 35 | menuentry "Integrity check" { 36 | linux /boot/vmlinuz integrity-check boot=doublesword root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX persist=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX net.ifnames=0 biosdevname=0 hostname=-host username= initrd=/boot/initrd.img noprompt noeject loop.max_loop=32 console=tty0 console=ttyS0,115200 -- 37 | initrd /boot/initrd.img 38 | } 39 | 40 | menuentry "Memory Test x86+" { 41 | linux16 /boot/memtest 42 | } 43 | 44 | #menuentry "Boot MBR on first hard drive!" { 45 | # set root=(hd0) 46 | # chainloader +1 47 | #} 48 | -------------------------------------------------------------------------------- /resources/boot/grub/theme/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/background.jpg -------------------------------------------------------------------------------- /resources/boot/grub/theme/select_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/select_c.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/slider_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/slider_c.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/slider_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/slider_n.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/slider_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/slider_s.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_c.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_e.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_n.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_ne.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_ne.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_nw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_nw.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_s.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_se.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_sw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_sw.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/terminal_box_w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/grub/theme/terminal_box_w.png -------------------------------------------------------------------------------- /resources/boot/grub/theme/theme.txt: -------------------------------------------------------------------------------- 1 | desktop-image: "background.jpg" 2 | title-text: "Boot Menu" 3 | title-color: "215, 255, 255" 4 | terminal-box: "terminal_box_*.png" 5 | terminal-font: "DejaVu Sans 18" 6 | 7 | + boot_menu { 8 | left = 25% 9 | width = 50% 10 | top = 25% 11 | height = 50% 12 | 13 | item_font = "DejaVu Sans 24" 14 | item_color = "#0ae7ea" 15 | item_height = 48 16 | item_icon_space = 8 17 | item_spacing = 2 18 | 19 | selected_item_font = "DejaVu Sans 18" 20 | selected_item_color= "#ffffff" 21 | selected_item_pixmap_style = "select_*.png" 22 | 23 | icon_height = 48 24 | icon_width = 48 25 | 26 | scrollbar = true 27 | scrollbar_width = 20 28 | scrollbar_thumb = "slider_*.png" 29 | } 30 | 31 | + progress_bar { 32 | id = "__timeout__" 33 | left = 25% 34 | top = 85% 35 | height = 10 36 | width = 50% 37 | fg_color = "#ffffff" 38 | bg_color = "#203030" 39 | border_color = "#ffffff" 40 | } 41 | 42 | -------------------------------------------------------------------------------- /resources/boot/memtest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/boot/memtest -------------------------------------------------------------------------------- /resources/casper/bin/casper-md5check: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | clear; 3 | echo "Starting integrity check script.." 4 | cd "$1" 5 | md5sum -c "$2" && echo "Integrity check result: GOOD" || echo "Integrity check result: BAD (some files are broken)." 6 | echo "5 seconds delay before continue.." 7 | sleep 5 8 | -------------------------------------------------------------------------------- /resources/etc/apt/sources.list.binary: -------------------------------------------------------------------------------- 1 | deb http://archive.ubuntu.com/ubuntu/ main restricted universe multiverse 2 | deb http://archive.ubuntu.com/ubuntu/ -updates main restricted universe multiverse 3 | deb http://archive.ubuntu.com/ubuntu/ -security main restricted universe multiverse 4 | deb http://archive.ubuntu.com/ubuntu/ -backports main restricted universe multiverse 5 | -------------------------------------------------------------------------------- /resources/etc/apt/sources.list.source: -------------------------------------------------------------------------------- 1 | deb-src http://archive.ubuntu.com/ubuntu/ main restricted universe multiverse 2 | deb-src http://archive.ubuntu.com/ubuntu/ -updates main restricted universe multiverse 3 | deb-src http://archive.ubuntu.com/ubuntu/ -security main restricted universe multiverse 4 | deb-src http://archive.ubuntu.com/ubuntu/ -backports main restricted universe multiverse 5 | -------------------------------------------------------------------------------- /resources/etc/dialogrc: -------------------------------------------------------------------------------- 1 | # 2 | # Run-time configuration file for dialog 3 | # 4 | # Automatically generated by "dialog --create-rc " 5 | # 6 | # 7 | # Types of values: 8 | # 9 | # Number - 10 | # String - "string" 11 | # Boolean - 12 | # Attribute - (foreground,background,highlight?) 13 | 14 | # Set aspect-ration. 15 | aspect = 0 16 | 17 | # Set separator (for multiple widgets output). 18 | separate_widget = "" 19 | 20 | # Set tab-length (for textbox tab-conversion). 21 | tab_len = 0 22 | 23 | # Make tab-traversal for checklist, etc., include the list. 24 | visit_items = OFF 25 | 26 | # Shadow dialog boxes? This also turns on color. 27 | use_shadow = ON 28 | 29 | # Turn color support ON or OFF 30 | use_colors = ON 31 | 32 | # Screen color 33 | screen_color = (CYAN,BLUE,ON) 34 | 35 | # Shadow color 36 | shadow_color = (BLACK,BLACK,ON) 37 | 38 | # Dialog box color 39 | dialog_color = (BLACK,WHITE,OFF) 40 | 41 | # Dialog box title color 42 | title_color = (BLUE,WHITE,ON) 43 | 44 | # Dialog box border color 45 | border_color = (WHITE,WHITE,ON) 46 | 47 | # Active button color 48 | button_active_color = (WHITE,BLUE,ON) 49 | 50 | # Inactive button color 51 | button_inactive_color = dialog_color 52 | 53 | # Active button key color 54 | button_key_active_color = button_active_color 55 | 56 | # Inactive button key color 57 | button_key_inactive_color = (RED,WHITE,OFF) 58 | 59 | # Active button label color 60 | button_label_active_color = (YELLOW,BLUE,ON) 61 | 62 | # Inactive button label color 63 | button_label_inactive_color = (BLACK,WHITE,ON) 64 | 65 | # Input box color 66 | inputbox_color = dialog_color 67 | 68 | # Input box border color 69 | inputbox_border_color = dialog_color 70 | 71 | # Search box color 72 | searchbox_color = dialog_color 73 | 74 | # Search box title color 75 | searchbox_title_color = title_color 76 | 77 | # Search box border color 78 | searchbox_border_color = border_color 79 | 80 | # File position indicator color 81 | position_indicator_color = title_color 82 | 83 | # Menu box color 84 | menubox_color = dialog_color 85 | 86 | # Menu box border color 87 | menubox_border_color = border_color 88 | 89 | # Item color 90 | item_color = dialog_color 91 | 92 | # Selected item color 93 | item_selected_color = button_active_color 94 | 95 | # Tag color 96 | tag_color = title_color 97 | 98 | # Selected tag color 99 | tag_selected_color = button_label_active_color 100 | 101 | # Tag key color 102 | tag_key_color = button_key_inactive_color 103 | 104 | # Selected tag key color 105 | tag_key_selected_color = (RED,BLUE,ON) 106 | 107 | # Check box color 108 | check_color = dialog_color 109 | 110 | # Selected check box color 111 | check_selected_color = button_active_color 112 | 113 | # Up arrow color 114 | uarrow_color = (GREEN,WHITE,ON) 115 | 116 | # Down arrow color 117 | darrow_color = uarrow_color 118 | 119 | # Item help-text color 120 | itemhelp_color = (WHITE,BLACK,OFF) 121 | 122 | # Active form text color 123 | form_active_text_color = button_active_color 124 | 125 | # Form text color 126 | form_text_color = (WHITE,CYAN,ON) 127 | 128 | # Readonly form item color 129 | form_item_readonly_color = (CYAN,WHITE,ON) 130 | 131 | # Dialog box gauge color 132 | gauge_color = title_color 133 | 134 | # Dialog box border2 color 135 | border2_color = dialog_color 136 | 137 | # Input box border2 color 138 | inputbox_border2_color = dialog_color 139 | 140 | # Search box border2 color 141 | searchbox_border2_color = dialog_color 142 | 143 | # Menu box border2 color 144 | menubox_border2_color = dialog_color 145 | -------------------------------------------------------------------------------- /resources/etc/historian.profile: -------------------------------------------------------------------------------- 1 | 2 | #Initiates historian session from within monitored session 3 | SESSPID=$$ 4 | IPCDIR="/var/host/ipc" 5 | ( 6 | flock 8 7 | echo -e "$USER\n$SESSPID" > "$IPCDIR/historian.pipe" 8 | ( 9 | flock 9 10 | ) 9>"$IPCDIR/historian.lock" 11 | ) 8>"$HOME/.guest.lock" 12 | 13 | if test -t 0 14 | then 15 | script --timing="$IPCDIR/${USER}_$SESSPID.time" -f -q "$IPCDIR/${USER}_$SESSPID.log"; 16 | exit 17 | fi 18 | -------------------------------------------------------------------------------- /resources/etc/internet.dialogrc: -------------------------------------------------------------------------------- 1 | # 2 | # Run-time configuration file for dialog 3 | # 4 | # Automatically generated by "dialog --create-rc " 5 | # 6 | # 7 | # Types of values: 8 | # 9 | # Number - 10 | # String - "string" 11 | # Boolean - 12 | # Attribute - (foreground,background,highlight?) 13 | 14 | # Set aspect-ration. 15 | aspect = 0 16 | 17 | # Set separator (for multiple widgets output). 18 | separate_widget = "" 19 | 20 | # Set tab-length (for textbox tab-conversion). 21 | tab_len = 0 22 | 23 | # Make tab-traversal for checklist, etc., include the list. 24 | visit_items = OFF 25 | 26 | # Shadow dialog boxes? This also turns on color. 27 | use_shadow = ON 28 | 29 | # Turn color support ON or OFF 30 | use_colors = ON 31 | 32 | # Screen color 33 | screen_color = (CYAN,BLUE,ON) 34 | 35 | # Shadow color 36 | shadow_color = (BLACK,BLACK,ON) 37 | 38 | # Dialog box color 39 | dialog_color = (BLACK,WHITE,OFF) 40 | 41 | # Dialog box title color 42 | title_color = (BLUE,WHITE,ON) 43 | 44 | # Dialog box border color 45 | border_color = (WHITE,WHITE,ON) 46 | 47 | # Active button color 48 | button_active_color = (WHITE,BLUE,ON) 49 | 50 | # Inactive button color 51 | button_inactive_color = dialog_color 52 | 53 | # Active button key color 54 | button_key_active_color = button_active_color 55 | 56 | # Inactive button key color 57 | button_key_inactive_color = (RED,WHITE,OFF) 58 | 59 | # Active button label color 60 | button_label_active_color = (YELLOW,BLUE,ON) 61 | 62 | # Inactive button label color 63 | button_label_inactive_color = (BLACK,WHITE,ON) 64 | 65 | # Input box color 66 | inputbox_color = dialog_color 67 | 68 | # Input box border color 69 | inputbox_border_color = dialog_color 70 | 71 | # Search box color 72 | searchbox_color = dialog_color 73 | 74 | # Search box title color 75 | searchbox_title_color = title_color 76 | 77 | # Search box border color 78 | searchbox_border_color = border_color 79 | 80 | # File position indicator color 81 | position_indicator_color = title_color 82 | 83 | # Menu box color 84 | menubox_color = dialog_color 85 | 86 | # Menu box border color 87 | menubox_border_color = border_color 88 | 89 | # Item color 90 | item_color = dialog_color 91 | 92 | # Selected item color 93 | item_selected_color = button_active_color 94 | 95 | # Tag color 96 | tag_color = title_color 97 | 98 | # Selected tag color 99 | tag_selected_color = button_label_active_color 100 | 101 | # Tag key color 102 | tag_key_color = button_key_inactive_color 103 | 104 | # Selected tag key color 105 | tag_key_selected_color = (RED,BLUE,ON) 106 | 107 | # Check box color 108 | check_color = dialog_color 109 | 110 | # Selected check box color 111 | check_selected_color = button_active_color 112 | 113 | # Up arrow color 114 | uarrow_color = (GREEN,WHITE,ON) 115 | 116 | # Down arrow color 117 | darrow_color = uarrow_color 118 | 119 | # Item help-text color 120 | itemhelp_color = (WHITE,BLACK,OFF) 121 | 122 | # Active form text color 123 | form_active_text_color = button_active_color 124 | 125 | # Form text color 126 | form_text_color = (WHITE,CYAN,ON) 127 | 128 | # Readonly form item color 129 | form_item_readonly_color = (CYAN,WHITE,ON) 130 | 131 | # Dialog box gauge color 132 | gauge_color = title_color 133 | 134 | # Dialog box border2 color 135 | border2_color = dialog_color 136 | 137 | # Input box border2 color 138 | inputbox_border2_color = dialog_color 139 | 140 | # Search box border2 color 141 | searchbox_border2_color = dialog_color 142 | 143 | # Menu box border2 color 144 | menubox_border2_color = dialog_color 145 | -------------------------------------------------------------------------------- /resources/etc/netplan/01-network-container.yaml: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # For more information, see netplan(5). 3 | # It excludes eth0 interface described separately 4 | network: 5 | version: 2 6 | renderer: networkd 7 | ethernets: 8 | host0: 9 | dhcp4: no 10 | addresses: [10.3.0.2/24] 11 | gateway4: 10.3.0.1 12 | nameservers: 13 | addresses: [8.8.8.8,1.1.1.1] 14 | 15 | -------------------------------------------------------------------------------- /resources/etc/netplan/01-network-host.yaml: -------------------------------------------------------------------------------- 1 | # This file describes eth0 network interface available on your system 2 | # For more information, see netplan(5). 3 | network: 4 | version: 2 5 | renderer: networkd 6 | ethernets: 7 | ethX: 8 | match: 9 | name: eth* 10 | dhcp4: yes 11 | ve-container: 12 | dhcp4: no 13 | addresses: [10.3.0.1/24] 14 | -------------------------------------------------------------------------------- /resources/etc/scout-manage.conf: -------------------------------------------------------------------------------- 1 | ENABLE_LAN_ACCESS="" 2 | ENABLE_HOST_CONTROL="" 3 | ENABLE_INTERNET_TEST="1" 4 | ENABLE_APPROVAL_BYPASS="0" 5 | ENABLE_PRIVILEGED_MODE="0" 6 | ENABLE_SSH_WITH_PASSWORD="0" 7 | ENABLE_ROUTING_VIA_VPN="0" 8 | -------------------------------------------------------------------------------- /resources/etc/security/limits.conf: -------------------------------------------------------------------------------- 1 | # /etc/security/limits.conf 2 | # 3 | #Each line describes a limit for a user in the form: 4 | # 5 | # 6 | # 7 | #Where: 8 | # can be: 9 | # - a user name 10 | # - a group name, with @group syntax 11 | # - the wildcard *, for default entry 12 | # - the wildcard %, can be also used with %group syntax, 13 | # for maxlogin limit 14 | # - NOTE: group and wildcard limits are not applied to root. 15 | # To apply a limit to the root user, must be 16 | # the literal username root. 17 | # 18 | # can have the two values: 19 | # - "soft" for enforcing the soft limits 20 | # - "hard" for enforcing hard limits 21 | # 22 | # can be one of the following: 23 | # - core - limits the core file size (KB) 24 | # - data - max data size (KB) 25 | # - fsize - maximum filesize (KB) 26 | # - memlock - max locked-in-memory address space (KB) 27 | # - nofile - max number of open files 28 | # - rss - max resident set size (KB) 29 | # - stack - max stack size (KB) 30 | # - cpu - max CPU time (MIN) 31 | # - nproc - max number of processes 32 | # - as - address space limit (KB) 33 | # - maxlogins - max number of logins for this user 34 | # - maxsyslogins - max number of logins on the system 35 | # - priority - the priority to run user process with 36 | # - locks - max number of file locks the user can hold 37 | # - sigpending - max number of pending signals 38 | # - msgqueue - max memory used by POSIX message queues (bytes) 39 | # - nice - max nice priority allowed to raise to values: [-20, 19] 40 | # - rtprio - max realtime priority 41 | # - chroot - change root to directory (Debian-specific) 42 | # 43 | # 44 | # 45 | 46 | #* soft core 0 47 | #root hard core 100000 48 | #* hard rss 10000 49 | #@student hard nproc 20 50 | #@faculty soft nproc 20 51 | #@faculty hard nproc 50 52 | #ftp hard nproc 0 53 | #ftp - chroot /ftp 54 | #@student - maxlogins 4 55 | 56 | * hard nofile 60000 57 | * soft nofile 60000 58 | root hard nofile 60000 59 | root soft nofile 60000 60 | 61 | # End of file 62 | -------------------------------------------------------------------------------- /resources/etc/sudo.conf: -------------------------------------------------------------------------------- 1 | Set disable_coredump false 2 | -------------------------------------------------------------------------------- /resources/etc/sysctl.d/60-net-congestion-control.conf: -------------------------------------------------------------------------------- 1 | net.core.default_qdisc=fq 2 | net.ipv4.tcp_congestion_control=bbr 3 | -------------------------------------------------------------------------------- /resources/etc/systemd/networkd.conf: -------------------------------------------------------------------------------- 1 | # This file is part of systemd. 2 | # 3 | # systemd is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Entries in this file show the compile time defaults. 9 | # You can change settings by editing this file. 10 | # Defaults can be restored by simply deleting this file. 11 | # 12 | # See networkd.conf(5) for details 13 | 14 | [Network] 15 | #SpeedMeter=no 16 | #SpeedMeterIntervalSec=10sec 17 | 18 | [DHCP] 19 | DUIDType=link-layer 20 | #DUIDRawData= 21 | -------------------------------------------------------------------------------- /resources/etc/systemd/nspawn/container.nspawn: -------------------------------------------------------------------------------- 1 | [Files] 2 | Bind=/dev/loop8 3 | Bind=/dev/loop9 4 | Bind=/dev/loop10 5 | Bind=/dev/loop11 6 | Bind=/dev/loop12 7 | Bind=/dev/loop13 8 | Bind=/dev/loop14 9 | Bind=/dev/loop15 10 | Bind=/dev/loop16 11 | Bind=/dev/loop17 12 | Bind=/dev/loop18 13 | Bind=/dev/loop19 14 | Bind=/dev/loop20 15 | Bind=/dev/loop21 16 | Bind=/dev/loop22 17 | Bind=/dev/loop23 18 | Bind=/dev/loop24 19 | Bind=/dev/loop25 20 | Bind=/dev/loop26 21 | Bind=/dev/loop27 22 | 23 | Bind=/dev/kvm 24 | Bind=/dev/fuse 25 | Bind=/dev/nbd0 26 | Bind=/dev/nbd1 27 | Bind=/dev/nbd2 28 | Bind=/dev/sr0 29 | 30 | Bind=/mnt/container:/mnt/host 31 | Bind=/dev/container:/dev/host 32 | 33 | Bind=/opt/container/history/.profile:/etc/profile 34 | Bind=/opt/container/ipc:/var/host/ipc 35 | 36 | [Exec] 37 | MachineID=container 38 | PrivateUsers=100000:65536 39 | Parameters=/sbin/init 40 | 41 | [Network] 42 | VirtualEthernet=yes 43 | 44 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/container-setup.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Container system setup 3 | Before=networking.service 4 | 5 | [Service] 6 | Type=oneshot 7 | RemainAfterExit=yes 8 | ExecStart=/sbin/container-setup start 9 | ExecStop=/sbin/container-setup stop 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/historian.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Historian service (container session logger) 3 | After=systemd-machined.service 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/sbin/historian.sh start 8 | ExecStop=/sbin/historian.sh stop 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/host-setup.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Host system setup 3 | Requires=local-fs.target 4 | Before=systemd-machined.service 5 | After=local-fs.target NetworkManager.service 6 | 7 | [Service] 8 | Type=oneshot 9 | RemainAfterExit=yes 10 | ExecStart=/sbin/host-setup start 11 | ExecStop=/sbin/host-setup stop 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/internet-indicator.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=internet_indicator on bitscout management tool 3 | After=networking.service 4 | 5 | [Service] 6 | Type=simple 7 | 8 | ExecStart=/usr/bin/internet-indicator.sh start 9 | ExecStop= 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/internet-indicator.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=internet_indicator on bitscout management tool 3 | Requires=internet-indicator.service 4 | 5 | [Timer] 6 | Unit=internet-indicator.service 7 | OnCalendar=*:*:0/30 8 | AccuracySec=1sec 9 | 10 | [Install] 11 | WantedBy=timers.target 12 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/memwatchdog.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Memory watchdog 3 | After=systemd-machined.service 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/sbin/memwatchdog.sh 8 | KillMode=process 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/privexec.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Privileged execution service 3 | After=systemd-machined.service 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/sbin/privexecd.sh 8 | KillMode=process 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/supervise.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Supervised execution service 3 | After=systemd-machined.service 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/sbin/supervised.sh 8 | KillMode=process 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /resources/etc/systemd/system/systemd-nspawn@container.service.d/override.conf: -------------------------------------------------------------------------------- 1 | [Unit] 2 | After=host-setup.service 3 | Requires=host-setup.service 4 | 5 | [Service] 6 | DeviceAllow=/dev/fuse rwm 7 | DeviceAllow=/dev/kvm rwm 8 | DeviceAllow=/dev/nbd0 rwm 9 | DeviceAllow=/dev/nbd1 rwm 10 | DeviceAllow=/dev/nbd2 rwm 11 | DeviceAllow=/dev/sr0 rwm 12 | WatchdogSec=0 13 | -------------------------------------------------------------------------------- /resources/etc/vtrgb: -------------------------------------------------------------------------------- 1 | 0, 170, 0, 170, 30, 170, 0, 170, 85, 255, 85, 255, 85, 255, 85, 255 2 | 10, 0, 170, 85, 60, 0, 170, 180, 85, 85, 255, 255, 85, 85, 255, 255 3 | 20, 0, 0, 0, 200, 170, 170, 200, 85, 85, 85, 85, 255, 255, 255, 255 4 | -------------------------------------------------------------------------------- /resources/gpg/871920D1991BC93C.asc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KasperskyLab/bitscout/667831b85ee4f281371975d109385fc548c07510/resources/gpg/871920D1991BC93C.asc -------------------------------------------------------------------------------- /resources/initrd/scripts/casper-bottom/01wrtblk_all: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Mark all available block devices as read-only (except loop devices) 4 | find /dev -type b | grep -vE "^/dev/loop[0-9]*|^/dev/nbd[0-9]*|^/dev/zram[0-9]*" | while read device; do 5 | # Check if medium is present 6 | if blockdev --getsz "$device" > /dev/null 2>&1; then 7 | blockdev --setro "$device" && logger "wrtblk: $device was set to readonly" || logger "wrtblk: blockdev --setro $device failed!" 8 | fi 9 | done 10 | -------------------------------------------------------------------------------- /resources/initrd/scripts/doublesword: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # set -e 4 | 5 | export PATH=/usr/bin:/usr/sbin:/bin:/sbin 6 | 7 | echo "Doublesword is starting.." 8 | parse_cmdline() 9 | { 10 | for x in $(cat /proc/cmdline); do 11 | case $x in 12 | root=*) export ROOTDEVID="${x#root=}";; 13 | persist=*) export PERSDEVID="${x#persist=}";; 14 | persistmode=*) export PERSISTMODE="${x#persistmode=}";; 15 | esac 16 | done 17 | } 18 | 19 | emergency_shell() { 20 | echo "Something bad happened. Starting emergency shell.." 21 | /bin/sh -i 22 | } 23 | 24 | mountroot() 25 | { 26 | if [ -z "$ROOTDEVID" ]; then 27 | echo "Error: \"root\" kernel argument is not specified." 28 | emergency_shell 29 | fi 30 | 31 | # Scan local devices for the image 32 | echo "Searching for root device: $ROOTDEVID" 33 | i=0 34 | while [ "$i" -lt 60 ]; do 35 | ROOTDEV=$( blkid -t $ROOTDEVID -l -o device ) 36 | if [ -n "$ROOTDEV" ]; then 37 | break 38 | fi 39 | udevadm settle --timeout 1 2>/dev/null 40 | sleep 1 41 | i="$(($i + 1))" 42 | done 43 | 44 | if [ -z "$ROOTDEV" ]; then 45 | echo "Error: Failed to locate root device ($ROOTDEVID)." 46 | emergency_shell 47 | fi 48 | 49 | echo "Searching for persistence device: $PERSDEVID" 50 | if [ $( echo $PERSDEVID | cut -c1-5) = "UUID=" ]; then 51 | PERSDEV=$( blkid -t $PERSDEVID -l -o device ) 52 | fi 53 | 54 | if [ -z "$PERSDEV" ]; then 55 | echo "Error: Failed to locate persistence device ($PERSDEVID)." 56 | emergency_shell 57 | fi 58 | 59 | mkdir /rofs /persistence 60 | mount -o rw $PERSDEV /persistence 61 | [ -n $PERSISTMODE -a $PERSISTMODE = "cleanup" ] && rm -rf /persistence/* 62 | if [ ! -d "/persistence/host/overlay" ]; then 63 | mkdir -p /persistence/host/overlay/upper 2>/dev/null 64 | mkdir -p /persistence/host/overlay/work 2>/dev/null 65 | fi 66 | if [ ! -d "/persistence/container/overlay" ]; then 67 | mkdir -p /persistence/container/overlay/upper 2>/dev/null 68 | mkdir -p /persistence/container/overlay/work 2>/dev/null 69 | fi 70 | 71 | mount -o ro $ROOTDEV /rofs 72 | mount -t overlay overlay -o lowerdir=/rofs,upperdir=/persistence/host/overlay/upper,workdir=/persistence/host/overlay/work /root 73 | mount --move /persistence /root/persistence 74 | mount --move /rofs /root/rofs 75 | 76 | echo "PERSISTENCE_DEVICE=$PERSDEV" > /root/etc/wrtblk.conf 77 | /root/bin/chown 0:0 /root 78 | } 79 | 80 | parse_cmdline 81 | mountroot 82 | 83 | #/bin/sh -i 84 | -------------------------------------------------------------------------------- /resources/initrd/scripts/doublesword-bottom/01wrtblk_all: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Mark all available block devices as read-only (except loop devices, persistence and the parent) 4 | for device in /dev/* /dev/*/*; do 5 | if [ ! -h "$device" ] && [ -b "$device" ] && [ ! -z ${device##/dev/loop*} ]; then 6 | # Check if medium is present 7 | if blockdev --getsz "$device" > /dev/null 2>&1; then 8 | blockdev --setro "$device" || logger "wrtblk: blockdev --setro $device failed!" 9 | fi 10 | fi 11 | done 12 | -------------------------------------------------------------------------------- /resources/irssi/irssi.conf.client: -------------------------------------------------------------------------------- 1 | servers = ( 2 | { address = ""; port = ""; autoconnect = "yes"; chatnet="main"; } 3 | ); 4 | 5 | chatnets = { main = { type = "IRC";}; }; 6 | 7 | channels = ( 8 | { name = "#main"; chatnet="main"; autojoin = "Yes"; } 9 | ); 10 | 11 | settings = { 12 | core = { 13 | real_name = "owner"; 14 | user_name = "owner"; 15 | nick = "owner"; 16 | }; 17 | 18 | "fe-text" = { 19 | actlist_sort = "refnum"; 20 | term_force_colors = "yes"; 21 | }; 22 | "fe-common/core" = { 23 | autolog = "yes"; 24 | autolog_path = "/var/log/irssi/irc_$1.$0.%F.log"; 25 | }; 26 | }; 27 | 28 | windows = { 29 | 1 = { immortal = "yes"; name = "(status)"; level = "ALL"; }; 30 | 2 = { 31 | items = ( 32 | { 33 | type = "CHANNEL"; 34 | chat_type = "IRC"; 35 | name = "#main"; 36 | tag = "main"; 37 | } 38 | ); 39 | }; 40 | }; 41 | 42 | mainwindows = { 2 = { first_line = "1"; lines = "22"; } }; 43 | -------------------------------------------------------------------------------- /resources/lib/udev/01-readonly-disks.rules: -------------------------------------------------------------------------------- 1 | # Mark new block devices as read-only. 2 | ACTION=="add", SUBSYSTEM=="block", KERNEL!="ram*", RUN+="/usr/sbin/wrtblk $name" 3 | 4 | # A kernel marked a disk as read-write for some reason, we need to fix that. 5 | ACTION=="change", SUBSYSTEM=="block", KERNEL!="ram*", ENV{DISK_RO}=="0", RUN+="/usr/sbin/wrtblk-ioerr $name" 6 | -------------------------------------------------------------------------------- /resources/openvpn/ip_pool.lst: -------------------------------------------------------------------------------- 1 | client, 2 | expert, 3 | -------------------------------------------------------------------------------- /resources/openvpn/scout.conf.client: -------------------------------------------------------------------------------- 1 | remote #the server external IP 2 | port #the server listening port 3 | proto #the protocol following the server configuration 4 | 5 | dev-type tap 6 | dev 7 | 8 | client 9 | resolv-retry infinite 10 | mute-replay-warnings 11 | verb 3 12 | persist-tun 13 | persist-key 14 | tun-mtu 1500 15 | 16 | remote-cert-tls server 17 | 18 | cipher AES-256-CBC 19 | 20 | tls-client 21 | tls-auth "/etc/openvpn/client//ta.key" 1 22 | ca "/etc/openvpn/client//ca.crt" 23 | cert "/etc/openvpn/client//client.crt" 24 | key "/etc/openvpn/client//client.key" 25 | 26 | log-append "/var/log/openvpn..log" 27 | status "/var/run/openvpn..status" 1 28 | 29 | tls-timeout 40 30 | 31 | pull 32 | 33 | -------------------------------------------------------------------------------- /resources/openvpn/scout.conf.expert: -------------------------------------------------------------------------------- 1 | remote #the server external IP 2 | port #the server listening port 3 | proto #the protocol following the server configuration 4 | 5 | dev-type tap 6 | dev 7 | 8 | client 9 | resolv-retry infinite 10 | mute-replay-warnings 11 | verb 3 12 | persist-tun 13 | persist-key 14 | tun-mtu 1500 15 | 16 | remote-cert-tls server 17 | 18 | cipher AES-256-CBC 19 | 20 | tls-client 21 | tls-auth "/etc/openvpn/client//ta.key" 1 22 | ca "/etc/openvpn/client//ca.crt" 23 | cert "/etc/openvpn/client//expert.crt" 24 | key "/etc/openvpn/client//expert.key" 25 | 26 | log-append "/var/log/openvpn..log" 27 | status "/var/run/openvpn..status" 1 28 | 29 | tls-timeout 40 30 | 31 | pull 32 | 33 | -------------------------------------------------------------------------------- /resources/openvpn/scout.conf.server: -------------------------------------------------------------------------------- 1 | mode server 2 | 3 | local #the server external IP 4 | port #the server listening port 5 | proto #comms protocol: tcp-server or udp. udp is recommended as the fastest option! 6 | 7 | tun-mtu 1500 8 | daemon 9 | 10 | dev-type tap 11 | dev 12 | 13 | user nobody 14 | group nogroup 15 | 16 | ifconfig 255.255.255.0 17 | 18 | ifconfig-pool 19 | ifconfig-pool-persist /etc/openvpn/server//ip_pool.lst 0 20 | 21 | duplicate-cn #Allow multiple clients to use the same certificate 22 | 23 | remote-cert-tls client 24 | 25 | tls-server 26 | tls-auth /etc/openvpn/server//ta.key 0 27 | ca /etc/openvpn/server//ca.crt 28 | cert /etc/openvpn/server//server.crt 29 | key /etc/openvpn/server//server.key 30 | dh /etc/openvpn/server//dh.pem 31 | 32 | verb 3 33 | cipher AES-256-CBC 34 | 35 | persist-key 36 | persist-tun 37 | 38 | log-append /var/log/openvpn..log 39 | 40 | keepalive 60 180 41 | client-to-client 42 | max-clients 10 43 | status /var/run/openvpn..status 44 | 45 | -------------------------------------------------------------------------------- /resources/sbin/container-setup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Exit if the script was started on the host system. 4 | #It must be run only within container! 5 | if [ $# -eq 0 ] 6 | then 7 | echo "Usage $1 [start|stop]" 8 | fi 9 | 10 | if [ "$1" == "start" ] 11 | then 12 | locale-gen en_US.UTF-8 13 | fi 14 | 15 | #if [ "$1" == "stop" ] 16 | #then 17 | # umount /tmp 18 | #fi 19 | 20 | -------------------------------------------------------------------------------- /resources/sbin/historian.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Author: Vitaly Kamluk 4 | #This script is used to store history of guest container's session input/output. 5 | #It shall be started as a service. It saves history and timing information in gzip-files. 6 | 7 | LOGDIR=/opt/container/history/log 8 | IPCDIR=/opt/container/ipc 9 | 10 | validate_user() 11 | { 12 | echo "$1" | grep -q "[a-zA-Z0-9_-]\{1,32\}"; return $?; 13 | } 14 | validate_pid() 15 | { 16 | echo "$1" | grep -q "[0-9]\{1,16\}"; return $?; 17 | } 18 | 19 | 20 | historian_start() 21 | { 22 | [ ! -d "$IPCDIR" ] && mkdir -p "$IPCDIR" 23 | [ ! -p "$IPCDIR/historian.pipe" ] && mkfifo "$IPCDIR/historian.pipe" 2>&- && chmod o-r,o+w "$IPCDIR/historian.pipe" 24 | [ ! -f "$IPCDIR/historian.lock" ] && touch "$IPCDIR/historian.lock" 2>&- && chmod o+w "$IPCDIR/historian.lock" 25 | 26 | while true; 27 | do 28 | echo "Waiting for the next session.." 29 | ( 30 | flock 9 31 | mapfile -t PIPEMSG < <(cat "$IPCDIR/historian.pipe"|head -n2) 32 | [ -f "/var/run/historian.stop" ] && exit 0; 33 | GUESTUSER=${PIPEMSG[0]} 34 | GUESTPID=${PIPEMSG[1]} 35 | if validate_user "$GUESTUSER" && validate_pid "$GUESTPID" 36 | then 37 | echo "Recording history of user:$GUESTUSER pid:$GUESTPID.." 38 | PIPEFLOG="$IPCDIR/${GUESTUSER}_${GUESTPID}.log" 39 | PIPEFTIME="$IPCDIR/${GUESTUSER}_${GUESTPID}.time" 40 | FLOG="$LOGDIR/${GUESTUSER}_${GUESTPID}.log" 41 | FLOGTIME="$LOGDIR/${GUESTUSER}_${GUESTPID}.time" 42 | socat -u PIPE:"$PIPEFLOG" OPEN:"$FLOG",creat=1 & 43 | socat -u PIPE:"$PIPEFTIME" OPEN:"$FLOGTIME",creat=1 & 44 | while [ ! -p "$PIPEFLOG" -a ! -p "$PIPEFTIME" ]; do sleep 0.1; done; 45 | chmod o+w,o-r "$PIPEFLOG" "$PIPEFTIME" 46 | flock -u 9 47 | fi 48 | ) 9> "$IPCDIR/historian.lock" 49 | [ -f "/var/run/historian.stop" ] && exit 0; 50 | done 51 | } 52 | 53 | historian_stop() 54 | { 55 | touch "/var/run/historian.stop" 56 | cat /dev/null > "$IPCDIR/historian.pipe" 57 | } 58 | 59 | 60 | case $1 in 61 | start) 62 | historian_start 63 | ;; 64 | stop) 65 | historian_stop 66 | ;; 67 | esac 68 | -------------------------------------------------------------------------------- /resources/sbin/host-iptables: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IPT="/sbin/iptables" 4 | #List all eth* and wlan* interfaces and add to INET_IFACES array: 5 | I=0; while read INET_IFACE; do INET_IFACES[$I]="$INET_IFACE";((I++));done < <(ls -1 /sys/class/net/ |grep -E '^(eth|wlan)' ) 6 | CONTAINER_IFACE= 7 | CONTAINER_IP= 8 | VPN_IFACE= 9 | 10 | if [ $# -eq 0 ] 11 | then #default for no parameters. executed during system boot. 12 | # Required to enable IPv4 forwarding. 13 | # Redhat users can try setting FORWARD_IPV4 in /etc/sysconfig/network to true 14 | # Alternatively, it can be set in /etc/sysctl.conf 15 | if [ "$SYSCTL" = "" ] 16 | then 17 | echo "1" > /proc/sys/net/ipv4/ip_forward 18 | else 19 | $SYSCTL net.ipv4.ip_forward="1" 20 | fi 21 | 22 | # This enables dynamic address hacking. 23 | # This may help if you have a dynamic IP address \(e.g. slip, ppp, dhcp\). 24 | if [ "$SYSCTL" = "" ] 25 | then 26 | echo "1" > /proc/sys/net/ipv4/ip_dynaddr 27 | else 28 | $SYSCTL net.ipv4.ip_dynaddr="1" 29 | fi 30 | 31 | # Flush old rules, old custom tables 32 | $IPT --flush 33 | $IPT --delete-chain 34 | 35 | # Flush all rules 36 | $IPT -F 37 | $IPT -t nat -F 38 | $IPT -t mangle -F 39 | 40 | # Erase all non-default chains 41 | $IPT -X 42 | $IPT -t nat -X 43 | $IPT -t mangle -X 44 | 45 | # Set default policies for all three default chains 46 | $IPT -P INPUT DROP 47 | $IPT -P FORWARD DROP 48 | $IPT -P OUTPUT ACCEPT 49 | 50 | 51 | # Create new tables for port forwarding and host incoming connections 52 | $IPT -t nat -N CONTAINER_INCOMING 53 | $IPT -N HOST_INCOMING 54 | 55 | # Enable free use of loopback interfaces 56 | $IPT -A INPUT -i lo -j ACCEPT 57 | $IPT -A OUTPUT -o lo -j ACCEPT 58 | 59 | #Incoming host connections 60 | $IPT -A HOST_INCOMING -p tcp --dport 23 -j ACCEPT 61 | $IPT -A HOST_INCOMING -j RETURN 62 | 63 | 64 | # All TCP sessions should begin with SYN 65 | $IPT -A INPUT -p tcp ! --syn -m state --state NEW -s 0.0.0.0/0 -j DROP 66 | 67 | # Accept inbound ICMP messages 68 | $IPT -A INPUT -p ICMP --icmp-type 8 -s 0.0.0.0/0 -j ACCEPT 69 | $IPT -A INPUT -p ICMP --icmp-type 11 -s 0.0.0.0/0 -j ACCEPT 70 | 71 | #Accept related/established sessions 72 | $IPT -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT 73 | 74 | #Enable DHCP requests from container 75 | $IPT -A INPUT -i $CONTAINER_IFACE -p UDP --destination-port 67 -j ACCEPT 76 | 77 | $IPT -A INPUT -i $VPN_IFACE -j HOST_INCOMING 78 | 79 | 80 | #Enable NAT (container->inet) 81 | #TODO: Recheck default isolation 82 | for INET_IFACE in ${INET_IFACES[*]} 83 | do 84 | $IPT -A FORWARD -i $CONTAINER_IFACE -o $INET_IFACE -d 0.0.0.0/0 -j ACCEPT 85 | $IPT -A FORWARD -o $CONTAINER_IFACE -i $INET_IFACE -s 0.0.0.0/0 -j ACCEPT 86 | done 87 | 88 | 89 | #Setup container port forwarding 90 | $IPT -t nat -A CONTAINER_INCOMING -p tcp --dport 22 -j DNAT --to-destination $CONTAINER_IP:22 91 | 92 | for((i=0;i<10;i++)) 93 | do 94 | $IPT -t nat -A CONTAINER_INCOMING -p tcp --dport $[2000+$i] -j DNAT --to-destination $CONTAINER_IP:$[2000+$i] 95 | done 96 | 97 | for((i=0;i<10;i++)) 98 | do 99 | $IPT -t nat -A CONTAINER_INCOMING -p tcp --dport $[5900+$i] -j DNAT --to-destination $CONTAINER_IP:$[5900+$i] 100 | done 101 | 102 | $IPT -t nat -A CONTAINER_INCOMING -j RETURN 103 | 104 | 105 | #Process connections from VPN interface to container 106 | $IPT -t nat -A PREROUTING -i $VPN_IFACE -j CONTAINER_INCOMING 107 | 108 | $IPT -A FORWARD -i $CONTAINER_IFACE -o $VPN_IFACE -s $CONTAINER_IP -j ACCEPT 109 | $IPT -A FORWARD -o $CONTAINER_IFACE -i $VPN_IFACE -d $CONTAINER_IP -j ACCEPT 110 | 111 | #Enable outgoing traffic from CONTAINER to inet (for updates) 112 | $IPT -A FORWARD -i $CONTAINER_IFACE -j ACCEPT 113 | for INET_IFACE in ${INET_IFACES[*]} 114 | do 115 | $IPT -t nat -A POSTROUTING -o $INET_IFACE -j MASQUERADE 116 | done 117 | 118 | $IPT -t nat -A POSTROUTING -o $VPN_IFACE -j MASQUERADE 119 | 120 | exit 0 121 | fi 122 | 123 | 124 | if [ "$1" = "enable-access-from-lan" ] 125 | then 126 | for INET_IFACE in ${INET_IFACES[*]} 127 | do 128 | $IPT -t nat -I PREROUTING -i $INET_IFACE -j CONTAINER_INCOMING 129 | done 130 | 131 | $IPT -D INPUT -i $VPN_IFACE -j HOST_INCOMING 132 | $IPT -I INPUT -j HOST_INCOMING 133 | exit 0 134 | fi 135 | 136 | if [ "$1" = "disable-access-from-lan" ] 137 | then 138 | for INET_IFACE in ${INET_IFACES[*]} 139 | do 140 | $IPT -t nat -D PREROUTING -i $INET_IFACE -j CONTAINER_INCOMING 141 | done 142 | 143 | $IPT -D INPUT -j HOST_INCOMING 144 | $IPT -I INPUT -i $VPN_IFACE -j HOST_INCOMING 145 | exit 0 146 | fi 147 | 148 | if [ "$1" = "check-access-from-lan" ] 149 | then 150 | $IPT -C INPUT -j HOST_INCOMING 2>/dev/null && echo "Access from LAN is ON" || echo "Access from LAN is OFF" 151 | fi 152 | -------------------------------------------------------------------------------- /resources/sbin/memwatchdog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | MEMTHRESHOLD_WARN=0.06 #relative value (0.0-1.0) of free RAM to send out a warning about low RAM 3 | MEMTHRESHOLD_SUSP=0.03 #relative value (0.0-1.0) of free RAM to initiate the container suspension 4 | INTERVAL=5 #seconds to sleep between memory status checks 5 | 6 | #states: 7 | # 1 - Running normally 8 | # 2 - Issued a warning 9 | # 3 - Suspended the container 10 | free -s $INTERVAL -b | stdbuf -i0 -o0 -e0 awk 'BEGIN{ state=1; prev_state=state; threshold_warn='$MEMTHRESHOLD_WARN'; threshold_susp='$MEMTHRESHOLD_SUSP';} /^Mem:/ {if( $7/$2 <= threshold_warn && state==1 ){ state=2; printf "%0.2f%% %d\n",100*$7/$2,state;}; if( $7/$2 <= threshold_susp && state<=2 ){ state=3; printf "%0.2f%% %d\n",100*$7/$2,state;}; if($7/$2 >= threshold_susp && state==3){ if($7/$2 >= threshold_warn) {state=1} else {state=2}; printf "%0.2f%% %d\n",100*$7/$2, state; }}' | 11 | while IFS=$" " read p s; 12 | do 13 | echo "$p $s" 14 | case $s in 15 | 1) 16 | logger "RAM Watchdog: $p of RAM is available. Resuming the container.."; 17 | /usr/bin/container-resume.sh; 18 | ;; 19 | 2) 20 | logger "RAM Watchdog: $p of RAM left. Issuing a global warning.."; 21 | wall "RAM Watchdog warning: $p of RAM left"; 22 | machinectl -q shell container /usr/bin/wall "RAM Watchdog warning: $p of RAM left. The container may be suspended soon." < /dev/null; 23 | ;; 24 | 3) 25 | logger "RAM Watchdog: $p of RAM left. Suspending the container.."; 26 | wall "RAM Watchdog warning: $p of RAM left"; 27 | machinectl -q shell container /usr/bin/wall "RAM Watchdog warning: $p of RAM left. Suspending this container.." < /dev/null; 28 | /usr/bin/container-suspend.sh; 29 | ;; 30 | esac 31 | done -------------------------------------------------------------------------------- /resources/sbin/privexecd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | CONTAINERROOT=/opt/container/chroot 3 | CONTROLFILE=/var/run/privexec.enabled 4 | IPCDIR=/opt/container/ipc 5 | PRIVPIPE="$IPCDIR/privexec.pipe" 6 | PRIVLOCK="$IPCDIR/privexec.lock" 7 | PRIVLOGDIR=/opt/container/history/log 8 | PRIVLOG="$PRIVLOGDIR/privexecd.log" 9 | 10 | CMD_WHITELIST=( "/usr/bin/mount" "/usr/bin/umount" ) 11 | FS_WHITELIST=( "ntfs" "ntfs-3g" "vfat" "exfat" "ext" "ext2" "ext3" "ext4" "iso9660" "udf" "xfs" "reiserfs" "hfs" "hfsplus" ) 12 | declare -a LINE 13 | 14 | RESPONSEMSG="" 15 | response_add() 16 | { 17 | RESPONSEMSG="$RESPONSEMSG$1" 18 | } 19 | 20 | response_push() 21 | { 22 | if [ -n "$RESPONSEMSG" ] 23 | then 24 | echo -e "$RESPONSEMSG" > "$PRIVPIPE" 25 | RESPONSEMSG="" 26 | fi 27 | } 28 | 29 | 30 | log_add() 31 | { 32 | T=$(TZ=UTC date +"%H:%M:%S %Y-%m-%d") 33 | echo "$T: $1" >> "$PRIVLOG" 34 | echo "$T: $1" 35 | } 36 | 37 | privileged_usr_bin_mount() 38 | { 39 | log_add "privileged_bin_mount ${LINE[*]}" 40 | ARGLEN=${LINE[0]} 41 | if [ $ARGLEN -lt 2 -o $ARGLEN -gt 6 ] 42 | then 43 | log_add "Invalid number of arguments: $ARGLEN" 44 | return 1; 45 | fi 46 | 47 | FSTYPE="auto" 48 | MOUNTOPT="nodev,nosuid,noatime" 49 | for((i=2;i<$ARGLEN;i++)) 50 | do 51 | if [ "${LINE[$i]}" == "-t" ]; then FSTYPE=${LINE[$i+1]}; fi 52 | if [ "${LINE[$i]}" == "-o" ]; then MOUNTOPT="$MOUNTOPT,"${LINE[$i+1]}; fi 53 | done 54 | 55 | if ! is_fs_authorized "$FSTYPE"; 56 | then 57 | log_add "Prohibited filesystem $FSTYPE"; 58 | response_add "Cannot mount filesystem $FSTYPE.\n" 59 | return 1; 60 | fi; 61 | 62 | SRC="/opt/container/chroot${LINE[$ARGLEN]}" 63 | DST="/opt/container/chroot${LINE[$ARGLEN+1]}" 64 | if is_valid_path "$SRC" && is_valid_path "$DST" && is_valid_option "$MOUNTOPT" && is_valid_option "$FSTYPE" 65 | then 66 | log_add "Running: mount -t \"$FSTYPE\" -o \"$MOUNTOPT\" --source \"$SRC\" --target \"$DST\" 2>&1" 67 | mount -v -t "$FSTYPE" -o "$MOUNTOPT" --source "$SRC" --target "$DST" 2>&1 >"$PRIVPIPE" 68 | return 0; 69 | else 70 | return 1; 71 | fi 72 | } 73 | 74 | privileged_usr_bin_umount() 75 | { 76 | SRC="/opt/container/chroot${LINE[2]}" 77 | if is_valid_path "$SRC" 78 | then 79 | log_add "Running: umount \"${SRC}\" 2>&1" 80 | umount "${SRC}" 2>&1 >"$PRIVPIPE" 81 | return 0 82 | else 83 | return 1 84 | fi 85 | } 86 | 87 | is_fs_authorized() 88 | { 89 | for allowed in "${FS_WHITELIST[@]}"; do [[ "$1" == "$allowed" ]] && return 0; done; return 1; 90 | } 91 | 92 | is_cmd_authorized() 93 | { 94 | for allowed in "${CMD_WHITELIST[@]}"; do [[ "$1" == "$allowed" ]] && return 0; done; return 1; 95 | } 96 | 97 | is_valid_path() 98 | { 99 | if echo "$1" | grep -q "^[/a-zA-Z0-9_. ()=+-]\{2,256\}$" 100 | then 101 | RP=`realpath "$1"` 102 | echo $RP | grep -q "^/opt/container/chroot/" && return 0 103 | fi 104 | log_add "Path validation failed: $1" 105 | return 1 106 | } 107 | 108 | is_valid_option() 109 | { 110 | echo "$1" | grep -q "^[\/\\a-zA-Z0-9_. ()=+,:;-]\{1,256\}$" && return 0 111 | log_add "Params validation failed: $1" 112 | return 1 113 | } 114 | 115 | [ ! -d "$IPCDIR" ] && mkdir -p "$IPCDIR"; 116 | [ ! -d "$PRIVLOGDIR" ] && mkdir -p "$PRIVLOGDIR"; 117 | [ ! -p "$PRIVPIPE" ] && mkfifo "$PRIVPIPE" && chmod o+rw "$PRIVPIPE"; 118 | [ ! -p "$PRIVLOCK" ] && touch "$PRIVLOCK" && chmod o+rw "$PRIVLOCK"; 119 | 120 | while true 121 | do 122 | response_push 123 | mapfile -t LINE < <(head -n1 "$PRIVPIPE" | awk -vFPAT='([^ ]*)|("[^"]+")' -vOFS=" " '{for(i=1;i<=NF;i++){print $i;}}'| sed 's/^"//; s/"$//' ) 124 | if [ ! -f "$CONTROLFILE" ] 125 | then 126 | response_add "Privileged execution mode is not enabled.\n" 127 | CMDREQ=$(echo "${LINE[*]}" | sed 's/^[0-9]\{1,2\} //') 128 | log_add "Guest container requested privileged mode command but was denied: $CMDREQ" 129 | continue 130 | fi 131 | 132 | CMDPATH=${LINE[1]}; CMDPATH=${CMDPATH%%.priv} 133 | if is_cmd_authorized "$CMDPATH" 134 | then 135 | log_add "Request to run privileged $CMDPATH" 136 | PROCNAME=${CMDPATH////_} 137 | if ! eval "privileged$PROCNAME" 138 | then 139 | log_add "Failed to run privileged$PROCNAME" 140 | response_add "Failed to run privileged command.\n Hints:\n 1. Use \"-o ro\" option when mounting\n 2. Specify filesystem type with -t \n 3. Make sure src and dest paths exist\n" 141 | fi 142 | else 143 | log_add "Denied running $CMDPATH" 144 | echo "Couldn't process your request due to input validation." > "$PRIVPIPE" 145 | fi 146 | #declare -p LINE 147 | done 148 | 149 | -------------------------------------------------------------------------------- /resources/sbin/supervised.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | CONTAINERROOT=/opt/container/chroot 3 | SUPERVISEDROOT=/var/run/supervised 4 | IPCDIR=/opt/container/ipc 5 | COMMPIPE_IN="$IPCDIR/supervised_in.pipe" 6 | COMMPIPE_OUT="$IPCDIR/supervised_out.pipe" 7 | COMMLOCK="$IPCDIR/supervised.lock" 8 | SUPERVISEDBYPASS="$SUPERVISEDROOT/bypass" 9 | SUPERVISEDAUTHPIPE="$SUPERVISEDROOT/auth.pipe" 10 | COMMLOGDIR=/opt/container/history/log 11 | COMMLOG=$COMMLOGDIR/supervised.log 12 | 13 | log_add() 14 | { 15 | T=$(TZ=UTC date +"%H:%M:%S %Y-%m-%d") 16 | echo "$T: $1" >> "$COMMLOG" 17 | echo "$T: $1" 18 | } 19 | 20 | [ ! -d "$COMMLOGDIR" ] && mkdir -p "$COMMLOGDIR"; 21 | [ ! -d "$SUPERVISEDROOT" ] && mkdir -p "$SUPERVISEDROOT"; 22 | [ ! -d "$IPCDIR" ] && mkdir -p "$IPCDIR"; 23 | [ ! -p "$COMMPIPE_IN" ] && mkfifo "$COMMPIPE_IN" && chmod o+rw "$COMMPIPE_IN"; 24 | [ ! -p "$COMMPIPE_OUT" ] && mkfifo "$COMMPIPE_OUT" && chmod o+rw "$COMMPIPE_OUT"; 25 | [ ! -p "$COMMLOCK" ] && touch "$COMMLOCK" && chmod o+rw "$COMMLOCK"; 26 | [ ! -p "$SUPERVISEDAUTHPIPE" ] && mkfifo "$SUPERVISEDAUTHPIPE"; 27 | 28 | while true 29 | do 30 | CMD=`head -n1 $COMMPIPE_IN` 31 | log_add "Supervised command received: $CMD" 32 | if [ -f "$SUPERVISEDBYPASS" ] 33 | then 34 | eval "$CMD 2>&1" 1>$COMMPIPE_OUT 35 | else 36 | ( 37 | echo "Your command is being reviewed. Once review is complete, you shall see output here." 38 | echo "$CMD" > $SUPERVISEDAUTHPIPE 39 | RESULT=`head -n1 $SUPERVISEDAUTHPIPE` 40 | if [ "$RESULT" = "0" ] 41 | then #true 42 | eval "$CMD 2>&1" | tee -a "$COMMLOG" > $COMMPIPE_OUT 43 | else #false 44 | echo "Last command was not approved. Please talk to the owner." 45 | fi 46 | ) > "$COMMPIPE_OUT" 47 | fi 48 | done 49 | -------------------------------------------------------------------------------- /resources/squashfs/exclude.list: -------------------------------------------------------------------------------- 1 | boot/* 2 | -------------------------------------------------------------------------------- /resources/usr/bin/container-resume.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #Resume all processess withing container 3 | machinectl kill container --signal=CONT 4 | 5 | #The second pass seems to be required to restore container I/O 6 | machinectl kill container --signal=CONT 7 | -------------------------------------------------------------------------------- /resources/usr/bin/container-suspend.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | machinectl kill container --signal=STOP 3 | -------------------------------------------------------------------------------- /resources/usr/bin/internet-indicator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | CONNCHECK_HOST="bitscout-forensics.info" 3 | 4 | function run_test() { 5 | ping -n -c1 ${CONNCHECK_HOST} 6 | status=$? 7 | if [ $status -eq 0 ]; then 8 | [ ! -f /run/internet_on.status -a ! -f /run/internet_off.status ] && touch /run/internet_on.status 9 | [ -f /run/internet_off.status ] && rm /run/internet_off.status 10 | else 11 | [ ! -f /run/internet_on.status -a ! -f /run/internet_off.status ] && touch /run/internet_off.status 12 | [ -f /run/internet_on.status ] && rm /run/internet_on.status 13 | fi 14 | return 0 15 | } 16 | 17 | function clean() { 18 | rm /run/internet_{on,off}.status 2>/dev/null 19 | return 0 20 | } 21 | 22 | case "$1" in 23 | start) 24 | run_test 25 | ;; 26 | 27 | stop) 28 | clean 29 | ;; 30 | esac 31 | -------------------------------------------------------------------------------- /resources/usr/bin/privexec: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PRIVLOCK=/var/host/ipc/privexec.lock 3 | PRIVPIPE=/var/host/ipc/privexec.pipe 4 | ( 5 | flock 9 6 | S="$# $0" 7 | for arg in "$@"; do S="$S \"$arg\""; done; 8 | echo "$S" > "$PRIVPIPE" 9 | cat "$PRIVPIPE" 10 | ) 9> "$PRIVLOCK" 11 | -------------------------------------------------------------------------------- /resources/usr/bin/scout-monitor: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DELAY=5 3 | 4 | COLS=`tput cols` 5 | LINES=`tput lines` 6 | 7 | OPENVPNUP=no 8 | OPENVPNLOG=/var/log/openvpn.scout.log 9 | 10 | WGVPNUP=no 11 | if wg show scout >/dev/null; then 12 | WGVPNUP=yes 13 | fi 14 | 15 | TORHIDSERVUP=no 16 | if systemctl --no-pager status tor@default; then 17 | TORHIDSERVUP=yes 18 | fi 19 | 20 | hr() { 21 | local start=$'\e(0' end=$'\e(B' line='q' 22 | local cols=${COLUMNS:-$(tput cols)} 23 | while ((${#line} < cols)); do line+="$line"; done 24 | printf '%s%s%s\n' "$start" "${line:0:cols}" "$end" 25 | } 26 | 27 | align_center() { 28 | local msglen=`echo "$1"|wc -c` spaces="" 29 | spacecount=$[($COLS-$msglen)/2] 30 | for ((i=0;i<$spacecount;i++)); do spaces+=" "; done 31 | printf "$spaces$1$spaces\n" 32 | } 33 | 34 | monitor_new_sessions() { 35 | HISTORIANDIR=/opt/container/history 36 | TRACKLIST=/var/run/scout-monitor.$$.tracklist 37 | ls -1 "$HISTORIANDIR"/log/*.log 2>/dev/null | 38 | while read f; 39 | do 40 | LOGID="${f/*\//}"; LOGID=${LOGID%%.log}; 41 | if ! ( grep -q "$LOGID" "$TRACKLIST" 2>/dev/null || tmux list-windows -t "status:main" 2>&- | grep -q "$LOGID" ) 42 | then 43 | tmux new-window -a -t "status:main" -n "$LOGID" -d "tail -n80 -f \"$f\"" 2>&- 44 | echo "$LOGID" >> "$TRACKLIST" 45 | fi 46 | done 47 | } 48 | 49 | 50 | HOME=$(tput cup 0 0) 51 | ED=$(tput ed) 52 | EL=$(tput el) 53 | 54 | COL_RED="\x1b[01;31m" 55 | COL_GREEN="\x1b[01;32m" 56 | COL_YELLOW="\x1b[01;33m" 57 | COL_BLUE="\x1b[01;34m" 58 | COL_PURPLE="\x1b[01;35m" 59 | COL_CYAN="\x1b[01;36m" 60 | COL_WHITE="\x1b[01;37m" 61 | 62 | COL_STOP="\x1b[00m" 63 | 64 | while true 65 | do 66 | if systemctl --no-pager status openvpn-client@scout.service 2>/dev/null >/dev/null; then 67 | if [ "$OPENVPNUP" == "no" ]; then 68 | clear 69 | fi; 70 | OPENVPNUP=yes 71 | fi 72 | 73 | printf '%s%s' "$ED" "$HOME" 74 | 75 | ( 76 | hr 77 | align_center "SIMPLE STATUS MONITOR" 78 | hr 79 | echo -e "To exit press ctrl+c (one or few times), or ctrl+b and then 'd'. If you see numbered tabs at the bottom, session monitoring is available. To switch to another tab, press ctrl+b and then the tab number. To open a multi-digit tab number, press ctrl+b and then ' (single quote), enter the tab index." 80 | hr 81 | echo "Hostname: "`hostname`" Uptime: "`uptime` 82 | cat /proc/meminfo | awk '/MemTotal/ {print "Memory Total: '"$COL_GREEN"'" $2/1024" MB'"$COL_STOP"' | "}; /MemAvailable/ {print "Memory Avail: '"$COL_GREEN"'" $2/1024" MB'"$COL_STOP"'"};'| xargs echo -e 83 | hr 84 | echo "Network interfaces and their routing tables:" 85 | ip -o addr show| grep 'inet ' | awk '{print $2" "$4}' | while read iface ip; 86 | do 87 | if echo "$iface" | grep -q "^eth" 88 | then 89 | echo -e " ${iface} ${COL_BLUE}${ip}${COL_STOP}" 90 | else 91 | echo " ${iface} ${ip}" 92 | fi 93 | ip route show dev "$iface" | sed 's/^/ /g' 94 | done 95 | hr 96 | echo "Latest kernel messages:" 97 | dmesg | tail -n10 |cut -c -$COLS 98 | hr 99 | 100 | if [ $OPENVPNUP = "yes" ]; then 101 | echo "Latest OpenVPN messages:" 102 | if [ -f "$OPENVPNLOG" ] 103 | then 104 | tail -n10 "$OPENVPNLOG" | awk '{printf("%s",$0); for(i=0;i<'$COLS'-length($0);i++){printf(" ");} printf("\n");}' 105 | else 106 | echo "No VPN log file found at $OPENVPNLOG" 107 | fi 108 | elif [ $WGVPNUP = "yes" ]; then 109 | echo "Wireguard status:" 110 | wg show scout | tail -n +7 | grep -v "(hidden)" 111 | elif [ $TORHIDSERVUP = "yes" ]; then 112 | echo "TOR Hidden Network status:" 113 | journalctl -u tor@default -n 11 --no-pager 114 | fi 115 | ) 116 | #clear; echo "$frame"; 117 | 118 | monitor_new_sessions 119 | sleep $DELAY 120 | done 121 | -------------------------------------------------------------------------------- /resources/usr/bin/supervised-shell: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | COMMLOCK=/var/host/ipc/supervised.lock 3 | COMMPIPE_IN=/var/host/ipc/supervised_in.pipe 4 | COMMPIPE_OUT=/var/host/ipc/supervised_out.pipe 5 | ( 6 | flock 9 7 | while true 8 | do 9 | echo -en "\e[1;37;41msupervised>\033[00m " 10 | read CMD 11 | if [ -z "$CMD" ] 12 | then 13 | break 14 | else 15 | echo "$CMD" > $COMMPIPE_IN 16 | cat $COMMPIPE_OUT 17 | #( tail -f $COMMPIPE_OUT ) | awk '{if($0=="supervised.eof"){exit;}else{print $0;}}' 18 | fi 19 | done 20 | ) 9> "$COMMLOCK" 21 | -------------------------------------------------------------------------------- /resources/usr/bin/torcustomconfig.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo chown -R debian-tor:debian-tor /etc/tor 4 | 5 | sudo chown -R debian-tor:debian-tor /var/lib/tor 6 | 7 | systemd-run --machine container systemctl stop tor 8 | 9 | systemd-run --machine container systemctl disable tor 10 | -------------------------------------------------------------------------------- /resources/usr/sbin/wrtblk: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Mark a specified block device as read-only 4 | [ $# -eq 1 ] || exit 0 5 | [ ! -z "$1" ] || exit 0 6 | bdev="$1" 7 | [ -b "/dev/$bdev" ] || exit 0 8 | [ -z ${bdev##loop*} ] && exit 0 9 | . /etc/wrtblk.conf 10 | [ -n $PERSISTENCE_DEVICE -a -z ${PERSISTENCE_DEVICE%%/dev/$bdev*} ] && exit 0 11 | blockdev --setro "/dev/$bdev" || logger "wrtblk: blockdev --setro /dev/$bdev failed!" 12 | 13 | # Mark a parent block device as read-only 14 | bdev=$(echo "$bdev" | sed 's/\//!/g') 15 | syspath=$(echo /sys/block/*/"$bdev") 16 | [ "$syspath" = "/sys/block/*/$bdev" ] && exit 17 | dir=${syspath%/*} 18 | parent=${dir##*/} 19 | parent=$(echo "$parent" | sed 's/!/\//g') 20 | [ -n $PERSISTENCE_DEVICE -a -z ${PERSISTENCE_DEVICE%%/dev/$parent*} ] && exit 0 21 | [ -b "/dev/$parent" ] || exit 22 | blockdev --setro "/dev/$parent" || logger "wrtblk: blockdev --setro /dev/$parent failed!" 23 | -------------------------------------------------------------------------------- /resources/usr/sbin/wrtblk-disable: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Mark a specified block device as read-write 4 | [ $# -eq 1 ] || exit 5 | [ ! -z "$1" ] || exit 6 | bdev="$1" 7 | [ -b "/dev/$bdev" ] || exit 8 | [ ! -z ${bdev##loop*} ] || exit 9 | blockdev --setrw "/dev/$bdev" || logger "wrtblk: blockdev --setrw /dev/$bdev failed!" 10 | 11 | # Mark a parent block device as read-write 12 | bdev=$(echo "$bdev" | sed 's/\//!/g') 13 | syspath=$(echo /sys/block/*/"$bdev") 14 | [ "$syspath" = "/sys/block/*/$bdev" ] && exit 15 | dir=${syspath%/*} 16 | parent=${dir##*/} 17 | parent=$(echo "$parent" | sed 's/!/\//g') 18 | [ -b "/dev/$parent" ] || exit 19 | blockdev --setrw "/dev/$parent" || logger "wrtblk: blockdev --setrw /dev/$parent failed!" 20 | -------------------------------------------------------------------------------- /resources/usr/sbin/wrtblk-ioerr: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Mark a specified block device as read-only 4 | [ $# -eq 1 ] || exit 5 | [ ! -z "$1" ] || exit 6 | bdev="$1" 7 | [ -b "/dev/$bdev" ] || exit 8 | [ ! -z ${bdev##loop*} ] || exit 9 | blockdev --setro "/dev/$bdev" || logger "wrtblk: blockdev --setro /dev/$bdev failed!" 10 | 11 | # Mark all child block devices as read-only 12 | bdev=$(echo "$bdev" | sed 's/\//!/g') 13 | for child in /sys/block/"$bdev"/*/dev; do 14 | dir=${child%/*} 15 | partition=${dir##*/} 16 | [ "$partition" = '*' ] && break 17 | partition=$(echo "$partition" | sed 's/!/\//g') 18 | [ -b "/dev/$partition" ] || continue 19 | blockdev --setro "/dev/$partition" || logger "wrtblk: blockdev --setro /dev/$partition failed!" 20 | done 21 | -------------------------------------------------------------------------------- /resources/usr/share/bitscout/introduction: -------------------------------------------------------------------------------- 1 | system 2 | is the project initially created by Vitaly Kamluk 3 | for remote triage and forensic analysis of compromised systems. 4 | It is based on idea of transparent and managed remote 5 | forensic analysis which maintains trust relationship with 6 | the owner of the system. Based on live booting system it 7 | constructs a virtual container with child operating system 8 | and virtualizes super-user privileges. It automatically 9 | connects to the pre-defined VPN server and allows incoming 10 | SSH connections over VPN link directly to the container. 11 | 12 | You can use this simple tool to do some of standard 13 | operations and let the remote forensic expert work on 14 | locally attached evidence disks. 15 | 16 | Here is what you need for that: 17 | 1. Connect current system to the internet. 18 | Note: DHCP/static IP is supported 19 | LAN/WiFi is supported 20 | HTTP/SOCKS proxy is supported 21 | IPv6 is NOT supported 22 | 2. Talk to the remote expert, confirm access to the 23 | container. 24 | 25 | 3. Map physical disks (or partitions) to virtual devices 26 | in the container. 27 | Note: the disks are mapped in read-only mode. 28 | 29 | Once the session started you can monitor the progress and 30 | chat with the expert. 31 | 32 | Note: All changes will be made only to RAM or USB drives 33 | attached and authorized for writing. If the system reboots 34 | or power is off the process has to be restarted unless 35 | saved to persistence storage (remote disk or locally 36 | attached USB flash drive). 37 | 38 | For more information and documentation, please check 39 | The project website: https://bitscout-forensics.info 40 | 41 | Good luck! 42 | -------------------------------------------------------------------------------- /resources/usr/share/bitscout/scout-manage.service: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export HOME=/root 3 | [ -f "$HOME/.profile" ] && . $HOME/.profile 4 | 5 | sleep 1 6 | chvt 2 7 | /usr/bin/-manage 8 | -------------------------------------------------------------------------------- /resources/usr/share/vim/vimrc: -------------------------------------------------------------------------------- 1 | syntax on 2 | set background=dark 3 | set mouse-=a 4 | 5 | set smartindent 6 | set shiftwidth=2 7 | set expandtab 8 | set tabstop=2 9 | 10 | "set list "show special characters, i.e. end of line 11 | 12 | " Tell vim to remember certain things when we exit 13 | set viminfo='10,\"100,:20,%,n~/.viminfo 14 | " when we reload, tell vim to restore the cursor to the saved position 15 | augroup JumpCursorOnEdit 16 | autocmd BufReadPost * % 17 | if line("'\"") >= 1 && line("'\"") <= line("$") | 18 | exe "normal! g`\"" | 19 | endif 20 | augroup END 21 | 22 | set fileencodings=ucs-bom,utf-8,default,latin1 23 | "F8 menu to switch encodings 24 | set wildmenu 25 | "set wildmode 26 | set wcm= 27 | 28 | if &term =~ '^screen' 29 | " tmux will send xterm-style keys when its xterm-keys option is on 30 | execute "set =\e[1;*A" 31 | execute "set =\e[1;*B" 32 | execute "set =\e[1;*C" 33 | execute "set =\e[1;*D" 34 | endif 35 | 36 | set backspace=indent,eol,start 37 | -------------------------------------------------------------------------------- /resources/wireguard/wg0.conf.client: -------------------------------------------------------------------------------- 1 | #Wireguard client config 2 | [Interface] 3 | Address = /24 4 | PrivateKey = 5 | DNS = 8.8.8.8 6 | 7 | #Bitscout server entry 8 | [Peer] 9 | PublicKey = 10 | PresharedKey = 11 | AllowedIPs = 12 | AllowedIPs = 0.0.0.0/0 13 | Endpoint = : 14 | PersistentKeepalive = 21 15 | -------------------------------------------------------------------------------- /resources/wireguard/wg0.conf.expert: -------------------------------------------------------------------------------- 1 | #Wireguard expert config 2 | [Interface] 3 | Address = /24 4 | PrivateKey = 5 | Table = off 6 | 7 | #Bitscout server entry 8 | [Peer] 9 | PublicKey = 10 | PresharedKey = 11 | AllowedIPs = 12 | Endpoint = : 13 | PersistentKeepalive = 21 14 | -------------------------------------------------------------------------------- /resources/wireguard/wg0.conf.server: -------------------------------------------------------------------------------- 1 | #Wireguard server config 2 | #Make sure that `sysctl net.ipv4.ip_forward=1` 3 | [Interface] 4 | ListenPort = 5 | Address = /24 6 | PrivateKey = 7 | #replace eth0 with your internet interface name 8 | PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 9 | PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE 10 | 11 | #Bitscout client settings 12 | [Peer] 13 | PublicKey = 14 | PresharedKey = 15 | AllowedIPs = /32 16 | 17 | #Expert settings 18 | [Peer] 19 | PublicKey = 20 | PresharedKey = 21 | AllowedIPs = /32 22 | 23 | -------------------------------------------------------------------------------- /scripts/chroot.devel_enter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | chroot_exec build.$GLOBAL_BASEARCH/chroot.devel "/bin/bash -i" 8 | -------------------------------------------------------------------------------- /scripts/chroot_add_managementtool.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Copying scout-manage config.." 8 | sudo_file_template_copy ./resources/etc/scout-manage.conf ./build.$GLOBAL_BASEARCH/chroot/etc/scout-manage.conf 9 | 10 | statusprint "Adding management tool for system owner with autostart.." 11 | statusprint "Installing remote access packages in chroot.." 12 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'DEBIAN_FRONTEND=noninteractive; 13 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 14 | apt-get --yes install pwgen' 15 | 16 | statusprint "Adding Text-UI management and monitoring scripts.." 17 | sudo_file_template_copy resources/usr/bin/${PROJECTSHORTNAME}-manage ./build.$GLOBAL_BASEARCH/chroot/usr/bin/${PROJECTSHORTNAME}-manage 18 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/usr/bin/${PROJECTSHORTNAME}-manage 19 | 20 | sudo_file_template_copy resources/usr/bin/${PROJECTSHORTNAME}-monitor ./build.$GLOBAL_BASEARCH/chroot/usr/bin/${PROJECTSHORTNAME}-monitor 21 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/usr/bin/${PROJECTSHORTNAME}-monitor 22 | 23 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/usr/share/${PROJECTNAME} 24 | sudo_file_template_copy resources/usr/share/${PROJECTNAME}/introduction ./build.$GLOBAL_BASEARCH/chroot/usr/share/${PROJECTNAME}/introduction 25 | 26 | statusprint "Adding autostart of ${PROJECTSHORTNAME}-manage tool on tty.." 27 | echo "[Unit] 28 | Description=${PROJECTSHORTNAME}-manage on tty2 29 | After=getty.target networking.service host-system.service 30 | Conflicts=getty@tty2.service 31 | 32 | [Service] 33 | Type=oneshot 34 | RemainAfterExit=yes 35 | ExecStart=/usr/share/${PROJECTNAME}/${PROJECTSHORTNAME}-manage.service 36 | ExecStop=/bin/kill -HUP ${MAINPID} 37 | TTYPath=/dev/tty2 38 | TTYReset=yes 39 | TTYVHangup=yes 40 | StandardInput=tty 41 | StandardOutput=tty 42 | StandardError=tty 43 | 44 | [Install] 45 | WantedBy=default.target" | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/${PROJECTSHORTNAME}-manage.service >/dev/null 46 | 47 | sudo_file_template_copy resources/usr/share/${PROJECTNAME}/${PROJECTSHORTNAME}-manage.service ./build.$GLOBAL_BASEARCH/chroot/usr/share/${PROJECTNAME}/${PROJECTSHORTNAME}-manage.service 48 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/usr/share/${PROJECTNAME}/${PROJECTSHORTNAME}-manage.service 49 | sudo ln -s /etc/systemd/system/${PROJECTSHORTNAME}-manage.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/${PROJECTSHORTNAME}-manage.service 2>/dev/null 50 | 51 | 52 | statusprint "Adding container management scripts.." 53 | sudo cp -v resources/usr/bin/container-{suspend,resume}.sh ./build.$GLOBAL_BASEARCH/chroot/usr/bin/ 54 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/usr/bin/container-{suspend,resume}.sh 55 | 56 | exit 0; 57 | -------------------------------------------------------------------------------- /scripts/chroot_configure.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Setting network interface autoconfiguration timeout.." 8 | sudo sed -i 's/^TimeoutStartSec=[0-9a-z]*$/TimeoutStartSec=1min/' ./build.$GLOBAL_BASEARCH/chroot/lib/systemd/system/networking.service 9 | sudo sed -i 's/^TimeoutStartSec=[0-9a-z]*$/TimeoutStartSec=10sec/' ./build.$GLOBAL_BASEARCH/chroot/lib/systemd/system/networking.service 10 | 11 | statusprint "Replacing networkd default configuration.." 12 | sudo cp -v ./resources/etc/systemd/networkd.conf ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/ 13 | 14 | statusprint "Disabling intel_rapl module.." 15 | if ! grep -q '^blacklist intel_rapl$' ./build.$GLOBAL_BASEARCH/chroot/etc/modprobe.d/blacklist.conf 16 | then 17 | echo "blacklist intel_rapl" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/modprobe.d/blacklist.conf > /dev/null 18 | fi 19 | 20 | statusprint "Setting release name.." 21 | sudo sed -i "s#Ubuntu 22.04[^ ]\{0,3\} LTS#${PROJECTNAME}#" ./build.$GLOBAL_BASEARCH/chroot/etc/issue.net ./build.$GLOBAL_BASEARCH/chroot/etc/lsb-release ./build.$GLOBAL_BASEARCH/chroot/etc/os-release 22 | echo "${PROJECTNAME} (\m) \d \t \l" | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/issue >/dev/null 23 | 24 | statusprint "Removing extra banners and motd.." 25 | sudo rm ./build.$GLOBAL_BASEARCH/chroot/etc/update-motd.d/* 2>/dev/null 26 | cat /dev/null | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/legal >/dev/null 27 | 28 | statusprint "Setting up automounting for tmpfs.." 29 | echo -e "tmpfs\t/tmp\ttmpfs\tnosuid,nodev\t0\t0" | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/fstab >/dev/null 30 | 31 | DEFTERM=xterm-color 32 | statusprint "Setting default TERM to $DEFTERM.." 33 | echo "TERM=$DEFTERM" | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/profile.d/terminal.sh >/dev/null 34 | 35 | statusprint "Adjusting colors and color schemes.." 36 | sudo cp -v ./resources/etc/vtrgb ./build.$GLOBAL_BASEARCH/chroot/etc/console-setup/vtrgb.vga.${PROJECTSHORTNAME} 37 | sudo ln -fs /etc/console-setup/vtrgb.vga.${PROJECTSHORTNAME} ./build.$GLOBAL_BASEARCH/chroot/etc/alternatives/vtrgb 38 | sudo sed -i 's/^\(\s*\)PS1=.*/\1PS1='"'"'\${debian_chroot:\+(\$debian_chroot)}\\[\\e\[1;32m\\\]\\u\\\[\\033\[00m\\\]@\\\[\\e\[1;37;41m\\\]\\h\\\[\\033\[00m\\\]:\\\[\\033\[01;34m\\\]\\w\\\[\\033\[00m\\]\$ '"'"'/g' ./build.$GLOBAL_BASEARCH/chroot/etc/bash.bashrc ./build.$GLOBAL_BASEARCH/chroot/etc/skel/.bashrc 39 | sudo cp -v ./resources/etc/dialogrc ./build.$GLOBAL_BASEARCH/chroot/etc/dialogrc 40 | 41 | sudo cp -v ./build.$GLOBAL_BASEARCH/chroot/etc/dialogrc ./build.$GLOBAL_BASEARCH/chroot/etc/internet_off.dialogrc 42 | sudo sed -i 's/screen_color = (CYAN,BLUE,ON)/screen_color = (CYAN,RED,ON)/g' ./build.$GLOBAL_BASEARCH/chroot/etc/internet_off.dialogrc 43 | 44 | sudo rm -f ./build.$GLOBAL_BASEARCH/chroot/root/.bashrc ./build.$GLOBAL_BASEARCH/chroot/user/.bashrc 45 | 46 | statusprint "Setting ulimit values.." 47 | sudo cp -v ./resources/etc/security/limits.conf ./build.$GLOBAL_BASEARCH/chroot/etc/security/limits.conf 48 | 49 | statusprint "Fixing sudo warning.." #should be removed in the future. see https://bugzilla.redhat.com/show_bug.cgi?id=1773148 50 | sudo cp -v ./resources/etc/sudo.conf ./build.$GLOBAL_BASEARCH/chroot/etc/ 51 | 52 | statusprint "Setting up network plan for container and the host.." 53 | sudo cp -v ./resources/etc/netplan/{01-network-host.yaml,01-network-container.yaml} ./build.$GLOBAL_BASEARCH/chroot/etc/netplan/ 54 | 55 | statusprint "Setting up shell aliases.." 56 | if ! grep -q '^#some shell aliases$' ./build.$GLOBAL_BASEARCH/chroot/etc/bash.bashrc 57 | then 58 | echo " 59 | #some shell aliases 60 | alias ll='ls -alF' 61 | alias la='ls -A' 62 | alias l='ls -CF'" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/bash.bashrc >/dev/null 63 | fi 64 | 65 | statusprint "Adding custom sysctl settings.." 66 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/etc/sysctl.d/ 2>&- 67 | sudo cp -v ./resources/etc/sysctl.d/* ./build.$GLOBAL_BASEARCH/chroot/etc/sysctl.d/ 68 | 69 | statusprint "Safe-copying system-wide VIM configuration.." 70 | [ ! -d "./build.$GLOBAL_BASEARCH/chroot/usr/share/vim" ] && sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/usr/share/vim 71 | chroot_safecopy_resources -v /resources/usr/share/vim/vimrc /usr/share/vim/vimrc 72 | alias 73 | 74 | exit 0; 75 | -------------------------------------------------------------------------------- /scripts/chroot_configure_irc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | irc_template_copy() 8 | { 9 | SRCFILE="$1" 10 | DSTFILE="$2" 11 | [ ! -d "${DSTFILE%/*}" ] && $SUDO mkdir -p "${DSTFILE%/*}" 12 | echo "'$SRCFILE' -> '$DSTFILE'" 13 | sed "s//${PROJECTSHORTNAME}/g; s//${PROJECTNAME}/g; s//${IRC_SERVER}/g; s//${IRC_PORT}/g; s//$GLOBAL_IRCOPPASS/g; " "$SRCFILE" > "$DSTFILE" 14 | } 15 | 16 | if ! grep -q "^GLOBAL_IRCOPPASS" "config/${PROJECTNAME}-build.conf" 17 | then 18 | statusprint "Generating IRC operator pass.." 19 | GLOBAL_IRCOPPASS=$(dd if=/dev/urandom bs=1 count=8 2>/dev/null | xxd -pos) 20 | 21 | statusprint "Saving IRC operator pass in global config.." 22 | echo "GLOBAL_IRCOPPASS=\"${GLOBAL_IRCOPPASS}\"" >> "config/${PROJECTNAME}-build.conf" 23 | fi 24 | 25 | statusprint "Creating irssi client logs directory.." 26 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/var/log/irssi 27 | 28 | statusprint "Copying irssi client configuration.." 29 | if [ ! -f "config/irssi/irssi.conf" ] 30 | then 31 | irc_template_copy "resources/irssi/irssi.conf.client" "config/irssi/irssi.conf" 32 | fi 33 | sudo cp -v config/irssi/irssi.conf ./build.$GLOBAL_BASEARCH/chroot/etc/irssi.conf 34 | 35 | statusprint "Copying server irssi configuration.." 36 | if [ ! -f "config/ngircd/ngircd.conf" ] 37 | then 38 | irc_template_copy "resources/etc/ngircd/ngircd.conf" "config/ngircd/ngircd.conf" 39 | fi 40 | 41 | 42 | exit 0; 43 | -------------------------------------------------------------------------------- /scripts/chroot_configure_ssh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Disabling SSH server from automatic start on the host system.." 8 | sudo touch ./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_not_to_be_run 9 | 10 | statusprint "Generating SSH-keys.." 11 | if ! filelist_exists "config/ssh/"{${PROJECTSHORTNAME},${PROJECTSHORTNAME}.pub} 12 | then 13 | mkdir -p config/ssh/ 2>&- 14 | install_required_package openssh-client 15 | ssh-keygen -b ${CRYPTOKEYSIZE} -N "" -f "config/ssh/${PROJECTSHORTNAME}" 16 | else 17 | statusprint "Found existing SSH-keys. Using existing keys, new keys generation skipped." 18 | fi 19 | 20 | statusprint "Adding SSH-key to the authorized keys in chroot for normal user.." 21 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/home/user/.ssh/ 22 | cat config/ssh/*.pub | sudo tee ./build.$GLOBAL_BASEARCH/chroot/home/user/.ssh/authorized_keys > /dev/null 23 | 24 | statusprint "Adding SSH-key to the authorized keys in chroot for root.." 25 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/root/.ssh/ 26 | cat config/ssh/*.pub | sudo tee ./build.$GLOBAL_BASEARCH/chroot/root/.ssh/authorized_keys > /dev/null 27 | 28 | statusprint "Disabling password authentication for SSH.." 29 | sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' ./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_config 30 | 31 | statusprint "Enabling support for SSH RSA keys.." 32 | if ! grep -q "PubkeyAcceptedKeyTypes=+ssh-rsa" ./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_config; then 33 | echo "PubkeyAcceptedKeyTypes=+ssh-rsa" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_config 34 | fi 35 | 36 | statusprint "Uncommenting port option for SSH.." 37 | sudo sed -i 's/^#Port /Port /g' ./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_config 38 | 39 | statusprint "Setting custom SSH banner.." 40 | mkdir -p "./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_config.d" 2>/dev/null 41 | if ! grep -q "^VersionAddendum" "./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_config.d/banner.conf" 2>/dev/null; then 42 | echo "VersionAddendum ${PROJECTCAPNAME} ${PROJECTRELEASE}" | sudo tee -a "./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_config.d/banner.conf" >/dev/null 43 | fi 44 | 45 | sudo sed -i "s/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g; s/^#PermitEmptyPasswords no/PermitEmptyPasswords yes/g" ./build.$GLOBAL_BASEARCH/chroot/etc/ssh/sshd_config 46 | -------------------------------------------------------------------------------- /scripts/chroot_configure_syslog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Enable remote syslog support and compile bash with syslog support 4 | # Xavier Mertens 5 | 6 | . ./scripts/functions 7 | 8 | scriptname=`basename $0` 9 | err_report() { 10 | echo "Error in ${scriptname}, line $1" 11 | exit 1 12 | } 13 | 14 | BASHVER="5.0" 15 | SRCARCHIVE="bash-$BASHVER.tar.gz" 16 | SRCURL="https://ftp.gnu.org/gnu/bash/$SRCARCHIVE" 17 | 18 | trap 'err_report $LINENO' ERR 19 | 20 | statusprint "Enabling syslog setup for Bitscout remote activity logging.." 21 | 22 | # Create remote logging configuration if the syslog server is enabled 23 | if [ -n "${GLOBAL_SYSLOGSERVER}" -a "${GLOBAL_SYSLOGSERVER}" != "none" ] 24 | then 25 | statusprint "Configuring local rsyslog.." 26 | cat <<__END__ | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/rsyslog.d/40-remote.conf >/dev/null 27 | *.* @${GLOBAL_SYSLOGSERVER}:514 28 | __END__ 29 | [ ! -d "build.$GLOBAL_BASEARCH/tmp" ] && mkdir build.$GLOBAL_BASEARCH/tmp 30 | 31 | if [ ! -x build.$GLOBAL_BASEARCH/tmp/bash-5.0/bash ] 32 | then 33 | statusprint "Compiling bash with syslog support.." 34 | BASEDIR=`pwd` 35 | cd build.$GLOBAL_BASEARCH/tmp 36 | if [ ! -r "$SRCARCHIVE" ] 37 | then 38 | statusprint "Downloading bash sourcecode from $SRCURL.." 39 | curl -o "$SRCARCHIVE" "$SRCURL" 40 | fi 41 | 42 | if [ -r "$SRCARCHIVE" ] 43 | then 44 | statusprint "Compiling bash with syslog support.." 45 | tar xzf $SRCARCHIVE 46 | cd bash-$BASHVER 47 | export CFLAGS="-DSYSLOG_SHOPT -DSYSLOG_HISTORY" 48 | ./configure --prefix=/ 49 | make 50 | cd "$BASEDIR" 51 | else 52 | statusprint "Couldn't find bash source code. Expected in build.$GLOBAL_BASEARCH/tmp/$SRCARCHIVE" 53 | exit 1; 54 | fi 55 | else 56 | statusprint "Bash binary has already been compiled." 57 | fi 58 | 59 | statusprint "Replacing standard bash with syslog-enabled variant.." 60 | sudo cp -v build.amd64/tmp/bash-$BASHVER/bash ./build.$GLOBAL_BASEARCH/chroot/bin/ 61 | fi 62 | 63 | exit 0; 64 | -------------------------------------------------------------------------------- /scripts/chroot_create_container.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Setting up expert container.." 8 | 9 | statusprint "Adding $CONTAINERUSERNAME's subuid and sudgid for unprivileged container.." 10 | if ! grep -q "$CONTAINERUSERNAME:100000" ./build.$GLOBAL_BASEARCH/chroot/etc/subuid 11 | then 12 | echo "$CONTAINERUSERNAME:100000:65536" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/subuid >/dev/null 13 | echo "$CONTAINERUSERNAME:100000:65536" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/subgid >/dev/null 14 | fi 15 | 16 | statusprint "Adding host setup script on boot.." 17 | sudo cp -v resources/etc/systemd/system/host-setup.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/host-setup.service 18 | sudo_file_template_copy resources/sbin/host-setup ./build.$GLOBAL_BASEARCH/chroot/sbin/host-setup 19 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/sbin/host-setup 20 | sudo ln -s /etc/systemd/system/host-setup.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/host-setup.service 2>/dev/null 21 | 22 | statusprint "Adding systemd-nspawn machine configuration.." 23 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/nspawn/ 24 | sudo cp -v ./resources/etc/systemd/nspawn/container.nspawn ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/nspawn/ 25 | 26 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/systemd-nspawn@container.service.d 2>&- 27 | sudo cp -v ./resources/etc/systemd/system/systemd-nspawn@container.service.d/override.conf ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/systemd-nspawn@container.service.d/ 28 | 29 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/machines.target.wants 2>&- 30 | sudo ln -fs /etc/systemd/system/systemd-nspawn@.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/machines.target.wants/systemd-nspawn@container.service 31 | 32 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/var/lib/machines 2>&- 33 | sudo ln -fs /opt/container/chroot.user ./build.$GLOBAL_BASEARCH/chroot/var/lib/machines/container 34 | 35 | statusprint "Adding container setup script.." 36 | sudo cp -v resources/etc/systemd/system/container-setup.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/container-setup.service 37 | sudo cp -v resources/sbin/container-setup ./build.$GLOBAL_BASEARCH/chroot/sbin/container-setup 38 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/sbin/container-setup 39 | sudo ln -s /etc/systemd/system/container-setup.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/container-setup.service 2>/dev/null 40 | 41 | statusprint "Adding historian service (container commands logger).." 42 | sudo cp -v resources/etc/systemd/system/historian.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/historian.service 43 | sudo cp -v resources/sbin/historian.sh ./build.$GLOBAL_BASEARCH/chroot/sbin/historian.sh 44 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/sbin/historian.sh 45 | sudo ln -s /etc/systemd/system/historian.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/historian.service 2>/dev/null 46 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/usr/share/${PROJECTNAME}/etc/ 2>&- 47 | sudo cp -v resources/etc/historian.profile ./build.$GLOBAL_BASEARCH/chroot/usr/share/${PROJECTNAME}/etc/historian.profile 48 | 49 | statusprint "Adding iptables setup script.." 50 | sudo_file_template_copy resources/sbin/host-iptables ./build.$GLOBAL_BASEARCH/chroot/sbin/host-iptables 51 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/sbin/host-iptables 52 | 53 | statusprint "Adding privileged execution service and client.." 54 | sudo cp -v resources/sbin/privexecd.sh ./build.$GLOBAL_BASEARCH/chroot/sbin/privexecd.sh 55 | sudo cp -v resources/etc/systemd/system/privexec.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/privexec.service 56 | sudo ln -s /etc/systemd/system/privexec.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/privexec.service 2>/dev/null 57 | sudo cp -v resources/usr/bin/privexec ./build.$GLOBAL_BASEARCH/chroot/usr/bin/privexec 58 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/sbin/privexecd.sh ./build.$GLOBAL_BASEARCH/chroot/usr/bin/privexec 59 | 60 | statusprint "Adding supervised execution service and client.." 61 | sudo cp -v resources/sbin/supervised.sh ./build.$GLOBAL_BASEARCH/chroot/sbin/supervised.sh 62 | sudo cp -v resources/etc/systemd/system/supervise.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/supervise.service 63 | sudo ln -s /etc/systemd/system/supervise.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/supervise.service 2>/dev/null 64 | sudo cp -v resources/usr/bin/supervised-shell ./build.$GLOBAL_BASEARCH/chroot/usr/bin/supervised-shell 65 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/sbin/supervised.sh ./build.$GLOBAL_BASEARCH/chroot/usr/bin/supervised-shell 66 | 67 | statusprint "Adding memory watchdog.." 68 | sudo cp -v resources/sbin/memwatchdog.sh ./build.$GLOBAL_BASEARCH/chroot/sbin/memwatchdog.sh 69 | sudo cp -v resources/etc/systemd/system/memwatchdog.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/memwatchdog.service 70 | sudo ln -s /etc/systemd/system/memwatchdog.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/memwatchdog.service 2>/dev/null 71 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/sbin/memwatchdog.sh 72 | 73 | 74 | exit 0; 75 | -------------------------------------------------------------------------------- /scripts/chroot_create_user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Adding local user.." 8 | if ! grep -qF "${CONTAINERUSERNAME}:x:999:999:Local user,,,:/home/${CONTAINERUSERNAME}:/bin/bash" ./build.$GLOBAL_BASEARCH/chroot/etc/passwd 9 | then 10 | echo "${CONTAINERUSERNAME}:x:999:999:Local user,,,:/home/${CONTAINERUSERNAME}:/bin/bash" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/passwd >/dev/null 11 | fi 12 | 13 | statusprint "Adding ${CONTAINERUSERNAME} to local groups.." 14 | if ! grep -qF "${CONTAINERUSERNAME}:x:999:" ./build.$GLOBAL_BASEARCH/chroot/etc/group 15 | then 16 | sudo sed -i 's/^\(\(adm\|cdrom\|sudo\|dip\|plugdev\):.*[^:]$\)/\1,'"${CONTAINERUSERNAME}"'/; s/^\(\(adm\|cdrom\|sudo\|dip\|plugdev\):.*:$\)/\1'"${CONTAINERUSERNAME}"'/;' ./build.$GLOBAL_BASEARCH/chroot/etc/group 17 | echo "${CONTAINERUSERNAME}:x:999:" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/group >/dev/null 18 | fi 19 | 20 | statusprint "Setting empty password for \"${CONTAINERUSERNAME}\".." 21 | if ! sudo grep -qF "${CONTAINERUSERNAME}:U6aMy0wojraho:17072:0:99999:7:::" ./build.$GLOBAL_BASEARCH/chroot/etc/shadow 22 | then 23 | echo "${CONTAINERUSERNAME}:U6aMy0wojraho:17072:0:99999:7:::" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/shadow 2>/dev/null 24 | fi 25 | 26 | statusprint "Creating ${CONTAINERUSERNAME}'s home dir and default files.." 27 | sudo mkdir ./build.$GLOBAL_BASEARCH/chroot/home/${CONTAINERUSERNAME} 2>&- 28 | find ./build.$GLOBAL_BASEARCH/chroot/etc/skel -type f | xargs -I {} sudo cp -v {} ./build.$GLOBAL_BASEARCH/chroot/home/${CONTAINERUSERNAME}/ 29 | sudo chown -R 999:999 ./build.$GLOBAL_BASEARCH/chroot/home/${CONTAINERUSERNAME} 30 | 31 | exit 0; 32 | -------------------------------------------------------------------------------- /scripts/chroot_customize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | #This file contains various customization templates, i.e. adding packages, 6 | #installing python modules via pip, configuring services in chroot environment, 7 | #adding reverse proxy over SSH. 8 | 9 | 10 | . ./scripts/functions 11 | 12 | statusprint "Adding custom packages and settings in chroot.." 13 | 14 | #The following is executed as a script inside the chroot environment. 15 | #Ignore the first line required for apt-fast (a faster alternative for apt) 16 | chroot_exec build.$GLOBAL_BASEARCH/chroot \ 17 | 'export DEBIAN_FRONTEND=noninteractive; aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 18 | 19 | #apt-fast --yes install gdb chntpw libguestfs-tools 20 | #apt-fast --yes install yara samba python-pip nbd-client xnbd-client nbd-server xnbd-server 21 | #pip install --upgrade pip 22 | #pip install artifacts bencode libscca-python 23 | #systemctl disable smbd 24 | ' 25 | 26 | 27 | # ---------------------------------------------- 28 | # Proxy config 29 | # This is useful to install missing package via 30 | # a reverse-tunnel over SSH. 31 | # Uncomment if you find it useful! 32 | # Credits: Xavier Mertens 33 | # ---------------------------------------------- 34 | 35 | #statusprint "Configuring localhost proxy.." 36 | #echo -e "Acquire::http::Proxy \"http://127.0.0.1:3128/\";\n Acquire::http::Proxy \"http://127.0.0.1:3128/\";" | sudo tee "build.$GLOBAL_BASEARCH/chroot/etc/apt/apt.conf.d/proxy.conf" > /dev/null 37 | # 38 | #echo -e "export HTTP_PROXY="http://127.0.0.1:3128"\nexport HTTPS_PROXY=\"http://127.0.0.1:3128\"" | sudo tee "build.$GLOBAL_BASEARCH/chroot/etc/bash.bashrc" > /dev/null 39 | 40 | 41 | exit 0; 42 | -------------------------------------------------------------------------------- /scripts/chroot_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | PROJECTROOT=$PWD 8 | 9 | statusprint "Checking base requirements.." 10 | if [ -z "$(which dpkg-query)" ] 11 | then 12 | echo "dpkg is required to continue. Please install manually." 13 | exit 2 14 | fi 15 | 16 | apt_make_dirs() 17 | { 18 | statusprint "Creating directory structure.." && 19 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/etc/apt && 20 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/var/lib/dpkg && 21 | sudo touch ./build.$GLOBAL_BASEARCH/chroot/var/lib/dpkg/status && 22 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/etc/apt/preferences.d/ && 23 | 24 | statusprint "Creating sources.list file.." && 25 | sudo_file_template_copy resources/etc/apt/sources.list.binary ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list && 26 | if [ $GLOBAL_CUSTOMKERNEL -eq 1 ] 27 | then 28 | sudo_file_template_copy resources/etc/apt/sources.list.source ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list.src && 29 | cat ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list.src | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list >/dev/null && 30 | sudo rm ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list.src 31 | fi && 32 | statusprint "Backing up sources.list file.." && 33 | sudo cp ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list.bak 34 | } 35 | 36 | apt_update() 37 | { 38 | if statusprint "Preparing repository PGP key(s).." && 39 | KEYS=( 871920D1991BC93C ) && 40 | ( [ ! -d ./build.$GLOBAL_BASEARCH/chroot/usr/share/keyrings ] && sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/usr/share/keyrings || true ) && 41 | ( [ ! -d ./build.$GLOBAL_BASEARCH/chroot/etc/apt/trusted.gpg.d ] && sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/etc/apt/trusted.gpg.d || true ) && 42 | ( [ -f ./build.$GLOBAL_BASEARCH/chroot/usr/share/keyrings/ubuntu-archive-keyring.gpg ] && sudo rm ./build.$GLOBAL_BASEARCH/chroot/usr/share/keyrings/ubuntu-archive-keyring.gpg || true ) && 43 | ( [ -f ./build.$GLOBAL_BASEARCH/chroot/etc/apt/trusted.gpg.d/ubuntu-archive-keyring.gpg ] && sudo rm ./build.$GLOBAL_BASEARCH/chroot/etc/apt/trusted.gpg.d/ubuntu-archive-keyring.gpg || true ) && 44 | for KEY in ${KEYS[*]} 45 | do 46 | echo "Adding key $KEY.." && 47 | cat ./resources/gpg/$KEY.asc | gpg --dearmor | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/usr/share/keyrings/ubuntu-archive-keyring.gpg | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/apt/trusted.gpg.d/ubuntu-archive-keyring.gpg >/dev/null 48 | done && 49 | 50 | statusprint "Updating $BASERELEASE:$GLOBAL_BASEARCH indices for chroot.." && 51 | sudo apt-get -y -o "Dir=$PWD/build.$GLOBAL_BASEARCH/chroot" -o "APT::Architecture=$GLOBAL_BASEARCH" -o "Acquire::Languages=$LANG" update 52 | then 53 | return 0 54 | else 55 | return 1 56 | fi 57 | } 58 | 59 | apt_fast_download() 60 | { 61 | DLLIST="$PROJECTROOT/aria2c.task" && 62 | statusprint "Fetching URLs of packages to download.." && 63 | apt-get -y -o "Dir=$PROJECTROOT/build.$GLOBAL_BASEARCH/chroot" -o "APT::Architecture=$GLOBAL_BASEARCH" -o "Acquire::Languages=$LANG" --print-uris download $* | awk "/^'/,//" | awk '{gsub("^'"'"'|'"'"'$","",$1); sub("MD5Sum:","md5=",$4); sub("SHA256:","sha-256=",$4); sub("SHA512:","sha-512=",$4); print $1"\n checksum="$4" \n out="$2}' > "$DLLIST" && 64 | 65 | _MAXNUM=8 && 66 | _MAXCONPERSRV=10 && 67 | _SPLITCON=8 && 68 | _MINSPLITSZ="1M" && 69 | _PIECEALGO="default" && 70 | sudo aria2c --console-log-level=warn -c -j ${_MAXNUM} -x ${_MAXCONPERSRV} -s ${_SPLITCON} -i ${DLLIST} --min-split-size=${_MINSPLITSZ} --stream-piece-selector=${_PIECEALGO} --connect-timeout=600 --timeout=600 -m0 && 71 | rm "$DLLIST" 72 | } 73 | 74 | run_debootstrap_supervised_fast() 75 | { 76 | statusprint "Downloading $BASERELEASE:$GLOBAL_BASEARCH.. " && 77 | 78 | BASEDIR="$PWD" && 79 | statusprint "Building base root filesystem.." && 80 | DEBDIR="./build.$GLOBAL_BASEARCH/cache/debootstrap.cache/dists/$BASERELEASE/main/binary-$GLOBAL_BASEARCH" && 81 | mkdir -p "$DEBDIR" && 82 | if [ ! -d "./build.$GLOBAL_BASEARCH/tmp" ]; then mkdir -p "./build.$GLOBAL_BASEARCH/tmp"; fi && 83 | 84 | statusprint "Fetching the list of essential packages.." && 85 | pushd "./build.$GLOBAL_BASEARCH/tmp" && 86 | DEBS=$(sudo debootstrap --include=distro-info,aria2,perl,libaria2-0,libc-ares2,libssh2-1,libxml2,ca-certificates,zlib1g,localepurge,python3-apt,python3-netifaces,python-opcua-tools,python3-opcua,python3-dateutil,python3-lxml,python3-six,python3-tz,ubuntu-pro-client,ubuntu-advantage-tools --print-debs --arch=$GLOBAL_BASEARCH $BASERELEASE chroot http://archive.ubuntu.com/ubuntu ) || exit 1 && 87 | popd && rm -rf "./build.$GLOBAL_BASEARCH/tmp" && 88 | install_required_package aria2 && 89 | 90 | chroot_mount_cache "$PWD/build.$GLOBAL_BASEARCH/chroot" && 91 | apt_make_dirs && 92 | apt_update || ( chroot_unmount_cache "$PWD/build.$GLOBAL_BASEARCH/chroot"; exit 1 ) && 93 | 94 | statusprint "Downloading deb files to local cache dir.." && 95 | ( ( cd "$DEBDIR" && apt_fast_download $DEBS ) || echo "Failed to download deb files" ) && 96 | 97 | statusprint "Scanning/indexing downloaded packages.." && 98 | install_required_package dpkg-dev && 99 | ( cd "./build.$GLOBAL_BASEARCH/cache/debootstrap.cache" && dpkg-scanpackages . /dev/null > "dists/$BASERELEASE/main/binary-$GLOBAL_BASEARCH/Packages" 2>/dev/null ) && 100 | sed -i 's/^Priority: optional.*/Priority: important/g' "$DEBDIR/Packages" && 101 | 102 | PKGS_SIZE=$(stat -c %s ./build.$GLOBAL_BASEARCH/cache/debootstrap.cache/dists/$BASERELEASE/main/binary-$GLOBAL_BASEARCH/Packages) && 103 | statusprint "Building local mirror requirements.." && 104 | 105 | echo "Origin: Ubuntu 106 | Label: Ubuntu 107 | Suite: $BASERELEASE 108 | Version: 22.04 109 | Codename: $BASERELEASE 110 | Architectures: $GLOBAL_BASEARCH 111 | Components: main restricted universe multiverse 112 | Description: Ubuntu Jammy 22.04 113 | 114 | MD5Sum: 115 | $(md5sum $DEBDIR/Packages | cut -d' ' -f1) $PKGS_SIZE main/binary-$GLOBAL_BASEARCH/Packages 116 | SHA256: 117 | $(sha256sum $DEBDIR/Packages | cut -d' ' -f1) $PKGS_SIZE main/binary-$GLOBAL_BASEARCH/Packages" > "./build.$GLOBAL_BASEARCH/cache/debootstrap.cache/dists/$BASERELEASE/Release" && 118 | 119 | statusprint "Building rootfs based on local deb cache.." && 120 | sudo debootstrap --no-check-gpg --foreign --arch=$GLOBAL_BASEARCH $BASERELEASE ./build.$GLOBAL_BASEARCH/chroot "file:///$BASEDIR/build.$GLOBAL_BASEARCH/cache/debootstrap.cache" && 121 | 122 | statusprint "Fixing keyboard-configuration GDM compatibility bug (divert kbd_mode).." && 123 | TARGETDEB="./build.$GLOBAL_BASEARCH/chroot$(grep "^kbd " ./build.$GLOBAL_BASEARCH/chroot/debootstrap/debpaths | cut -d' ' -f2)" && 124 | if [ "$TARGETDEB" == "./build.$GLOBAL_BASEARCH/chroot" ] 125 | then 126 | statusprint "Failed to locate kbd package to patch. Aborting.." 127 | exit 1 128 | else 129 | statusprint "Located kbd package in $TARGETDEB" 130 | fi && 131 | sudo ./scripts/deb_unpack.sh "$TARGETDEB" && 132 | sudo cp -v "${TARGETDEB}.unp/data/bin/kbd_mode" ./build.$GLOBAL_BASEARCH/chroot/bin/kbd_mode.dist && 133 | sudo cp -v ./build.$GLOBAL_BASEARCH/chroot/bin/true "${TARGETDEB}.unp/data/bin/kbd_mode" && 134 | sudo ./scripts/deb_pack.sh "$TARGETDEB" && 135 | 136 | chroot_unmount_cache "$PWD/build.$GLOBAL_BASEARCH/chroot" && 137 | 138 | statusprint "Backing up apt lists before deboostrap (stage 2).." && 139 | sudo cp -r ./build.$GLOBAL_BASEARCH/cache/apt.lists/ ./build.$GLOBAL_BASEARCH/cache/apt.lists.bak && 140 | 141 | statusprint "Running debootstrap (stage 2).." && 142 | chroot_exec build.$GLOBAL_BASEARCH/chroot "/debootstrap/debootstrap --second-stage && apt-mark hold kbd" && 143 | 144 | statusprint "Restoring apt lists after debootstrap (stage 2).." && 145 | sudo rm -rf ./build.$GLOBAL_BASEARCH/cache/apt.lists/ && 146 | sudo mv ./build.$GLOBAL_BASEARCH/cache/apt.lists.bak ./build.$GLOBAL_BASEARCH/cache/apt.lists && 147 | 148 | statusprint "Restoring sources.list file after debootstrap (stage 2).." && 149 | sudo cp ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list.bak ./build.$GLOBAL_BASEARCH/chroot/etc/apt/sources.list && 150 | 151 | statusprint "Adding apt-fast to chroot.." && 152 | sudo cp -v ./resources/apt-fast/apt-fast ./build.$GLOBAL_BASEARCH/chroot/usr/bin/apt-fast && 153 | 154 | statusprint "Debootstrap process completed." && return 0 155 | } 156 | 157 | if [ -d "./build.$GLOBAL_BASEARCH/chroot" ] 158 | then 159 | PRINTOPTIONS=n statusprint "Found existing chroot directory. Please choose what to do:\n 1. Remove existing chroot and re-download.\n 2. Do not re-download, skip this step.\n 3. Abort.\n You choice (1|2|3): " 160 | read choice 161 | 162 | case $choice in 163 | 1) 164 | sudo rm -rf ./build.$GLOBAL_BASEARCH/chroot/ && 165 | install_required_package debootstrap && 166 | run_debootstrap_supervised_fast || exit 1 167 | ;; 168 | 2) 169 | statusprint "Download operation skipped. Build continues.." 170 | ;; 171 | *) 172 | statusprint "Operation aborted. Build stopped." 173 | exit 1; 174 | ;; 175 | esac 176 | else 177 | install_required_package debootstrap && 178 | run_debootstrap_supervised_fast || exit 1 179 | fi 180 | 181 | exit 0; 182 | -------------------------------------------------------------------------------- /scripts/chroot_enter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | CHROOTDIR="" 8 | if [ $# -eq 0 ]; then 9 | CHROOTDIR="build.$GLOBAL_BASEARCH/chroot" 10 | else 11 | CHROOTDIR="$1" 12 | fi 13 | 14 | if [ ! -d "$CHROOTDIR" ]; then statusprint "Directory $CHROOTDIR doesn't exist."; exit 1; fi; 15 | chroot_exec "$CHROOTDIR" "/bin/bash -i" 16 | -------------------------------------------------------------------------------- /scripts/chroot_enter_devel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | chrootdevel_unmount() 8 | { 9 | sudo umount "$PWD/build.$GLOBAL_BASEARCH/chroot.devel" 10 | } 11 | 12 | chrootdevel_mount() 13 | { 14 | sudo mount ./build.$GLOBAL_BASEARCH/chroot -t overlay -o "rw,relatime,lowerdir=./build.$GLOBAL_BASEARCH/chroot,upperdir=./build.$GLOBAL_BASEARCH/tmp/chroot.devel/upper,workdir=./build.$GLOBAL_BASEARCH/tmp/chroot.devel/work" ./build.$GLOBAL_BASEARCH/chroot.devel 15 | } 16 | 17 | chrootdevel_mount 18 | chroot_exec build.$GLOBAL_BASEARCH/chroot.devel "/bin/bash -i" 19 | chrootdevel_unmount 20 | -------------------------------------------------------------------------------- /scripts/chroot_install_base.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Setting up locale filter (localepurge).." && 8 | if [ -f "./build.$GLOBAL_BASEARCH/chroot/etc/locale.gen" ] 9 | then 10 | sudo sed -i 's,^# '$LANG' UTF-8$,'$LANG' UTF-8,' ./build.$GLOBAL_BASEARCH/chroot/etc/locale.gen 11 | else 12 | echo "$LANG UTF-8" | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/locale.gen >/dev/null 13 | fi && 14 | statusprint "Generating locale.." && 15 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'locale-gen "'$LANG'"' || exit 1 && 16 | 17 | statusprint "Updating CA certificates.." && 18 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'apt install ca-certificates && update-ca-certificates' || exit 1 && 19 | 20 | statusprint "Updating system and installing essential packages.." && 21 | 22 | COMMON_PACKAGES="binutils systemd-container netcat socat discover laptop-detect os-prober bindfs dialog tmux gawk ntpdate ifupdown network-manager curl wget cryptsetup lvm2 lz4" 23 | 24 | if [ $GLOBAL_TARGET = "iso" ]; then 25 | COMMON_PACKAGES="$COMMON_PACKAGES casper" 26 | else 27 | COMMON_PACKAGES="$COMMON_PACKAGES systemd-sysv" 28 | fi 29 | 30 | if [ $GLOBAL_RELEASESIZE -eq 1 ] 31 | then 32 | chroot_exec build.$GLOBAL_BASEARCH/chroot "export DEBIAN_FRONTEND=noninteractive 33 | apt-fast -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install $COMMON_PACKAGES && exit 0 || exit 1" || exit 1 34 | else 35 | chroot_exec build.$GLOBAL_BASEARCH/chroot "export DEBIAN_FRONTEND=noninteractive 36 | apt-fast -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install $COMMON_PACKAGES file hdparm iptables lshw usbutils parted lsof psmisc strace ltrace time systemd-sysv man-db dosfstools cron busybox-static rsync dmidecode bash-completion command-not-found ntfs-3g uuid-runtime vim nano less pv ifupdown nbd-server qemu-kvm fuse3 libfuse3-3 libfuse2 python3-fusepy samba && exit 0 || exit 1" || exit 1 37 | fi && 38 | 39 | #statusprint "Installing LXD using snap.." 40 | #nspawn_exec build.$GLOBAL_BASEARCH/chroot "export DEBIAN_FRONTEND=noninteractive; apt-fast -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install snapd" || exit 1 41 | #nspawn_exec build.$GLOBAL_BASEARCH/chroot "mount -o remount,rw /sys; systemctl restart systemd-udevd; snap install core; systemctl restart systemd-udevd; snap install lxd" || nspawn_exec build.$GLOBAL_BASEARCH/chroot "mount -o remount,rw /sys; systemctl restart systemd-udevd; snap install core; systemctl restart systemd-udevd; snap install lxd" || exit 1 42 | #nspawn_exec build.$GLOBAL_BASEARCH/chroot "export DEBIAN_FRONTEND=noninteractive; apt-fast -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install lxd lxd-client && exit 0 || exit 1" || exit 1 43 | 44 | statusprint "Finished installing packages." && 45 | 46 | statusprint "Upgrading kbd package." && #kbd is updated separately, because of related GDM issue/bug. 47 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'export DEBIAN_FRONTEND=noninteractive 48 | apt-mark unhold kbd && 49 | cp /bin/kbd_mode.dist /bin/kbd_mode && 50 | apt-get -y -o DPkg::options::="--force-confdef" -o DPkg::options::="--force-confold" upgrade' || exit 1 && 51 | 52 | 53 | exit 0; 54 | -------------------------------------------------------------------------------- /scripts/chroot_install_forensics.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Installing forensics packages in chroot.." 8 | case $GLOBAL_RELEASESIZE in 9 | 1) 10 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'DEBIAN_FRONTEND=noninteractive; 11 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 12 | apt-fast --yes install coreutils hexedit' || exit 1 13 | ;; 14 | 2) 15 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'DEBIAN_FRONTEND=noninteractive; 16 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 17 | apt-fast --yes install coreutils dcfldd gddrescue sleuthkit hexedit indent chntpw tcpdump' || exit 1 18 | ;; 19 | 3) 20 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'export DEBIAN_FRONTEND=noninteractive; 21 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 22 | apt-fast --yes install coreutils dcfldd gddrescue sleuthkit forensics-all indent chntpw tcpdump 23 | apt-fast --yes install bfbtester binwalk bruteforce-luks bzip2 cabextract chntpw clamav cmospwd crunch cryptmount dcfldd disktype dnsutils ethstatus ethtool exfat-fuse exfat-utils exif exiftags libimage-exiftool-perl exiv2 fatcat fdupes flasm foremost gdisk geoip-bin hexedit john less mc mdadm medusa memstat mpack nasm neopi netcat nmap ntfs-3g ophcrack-cli outguess p7zip-full parted pcapfix pdfcrack poppler-utils pecomato pev rarcrack samdump2 smb-nat snowdrop stegsnow sucrack sxiv tcpdump tcpflow tcpick tcpreplay tcpxtract telnet testdisk uni2ascii unrar-free unzip whois gdb libguestfs-tools 24 | systemctl disable clamav-freshclam' || exit 1; 25 | statusprint "Disabling network new services in chroot.." 26 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'systemctl disable clamav-freshclam && systemctl stop clamav-freshclam && 27 | systemctl disable postfix && systemctl stop postfix'; 28 | ;; 29 | esac 30 | 31 | exit 0; 32 | -------------------------------------------------------------------------------- /scripts/chroot_install_forensics_extra.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Installs extra forensics tools 4 | # Xavier Mertens 5 | 6 | . ./scripts/functions 7 | 8 | BASEDIRECTORY=`pwd` 9 | 10 | scriptname=`basename $0` 11 | err_report() { 12 | echo "Error in ${scriptname}, line $1" 13 | exit 1 14 | } 15 | 16 | trap 'err_report $LINENO' ERR 17 | 18 | case $GLOBAL_RELEASESIZE in 19 | 1) 20 | ;; 21 | 2) 22 | ;; 23 | 3) 24 | statusprint "Installing extra forensics packages in chroot.." 25 | 26 | [ ! -d "build.$GLOBAL_BASEARCH/tmp/" ] && mkdir -p build.$GLOBAL_BASEARCH/tmp 27 | [ ! -d "build.$GLOBAL_BASEARCH/chroot/opt" ] && sudo mkdir -p build.$GLOBAL_BASEARCH/chroot/opt 28 | 29 | # ------------- 30 | # Install byobu 31 | # ------------- 32 | statusprint "Installing Byobu.." 33 | if [ ! -x "build.$GLOBAL_BASEARCH/chroot/usr/bin/byobu" ] 34 | then 35 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'apt-get -y install byobu' 36 | else 37 | statusprint "Byobu already installed.." 38 | fi 39 | 40 | # -------------- 41 | # Install rip.pl 42 | # -------------- 43 | statusprint "Installing RegRipper.." 44 | if [ ! -d "build.$GLOBAL_BASEARCH/chroot/opt/regripper" ] 45 | then 46 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'export DEBIAN_FRONTEND=noninteractive; apt-get -y install libparse-win32registry-perl unzip' 47 | wget -O build.$GLOBAL_BASEARCH/tmp/master.zip https://github.com/keydet89/RegRipper3.0/archive/master.zip 48 | sudo mv -v build.$GLOBAL_BASEARCH/tmp/master.zip build.$GLOBAL_BASEARCH/chroot/opt/ 49 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'unzip -o /opt/master.zip -d /opt/ && mv /opt/RegRipper3.0-master /opt/regripper && rm /opt/master.zip' 50 | else 51 | statusprint "RegRipper already installed.." 52 | fi 53 | 54 | # ---------------------- 55 | # Install bulk_extractor 56 | # ---------------------- 57 | statusprint "Installing bulk_extractor.." 58 | if [ ! -x "/opt/bitscout/build.amd64/chroot/usr/local/bin/bulk_extractor" ] 59 | then 60 | [ -d "build.$GLOBAL_BASEARCH/chroot/opt/bulk_extractor" ] && sudo rm -rf "build.$GLOBAL_BASEARCH/chroot/opt/bulk_extractor" 61 | 62 | [ ! -d "build.$GLOBAL_BASEARCH/tmp/bulk_extractor" ] && git clone --recursive --depth=1 https://github.com/simsong/bulk_extractor.git build.$GLOBAL_BASEARCH/tmp/bulk_extractor 63 | sudo cp -r build.$GLOBAL_BASEARCH/tmp/bulk_extractor build.$GLOBAL_BASEARCH/chroot/opt/ 64 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'export DEBIAN_FRONTEND=noninteractive; aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 65 | apt-fast --yes install autoconf openjdk-11-jdk flex git libssl-dev zlib1g-dev || exit 1; 66 | cd /opt/bulk_extractor; 67 | source bootstrap.sh; 68 | ./configure --prefix=/usr/local --disable-BEViewer && 69 | make -j'$((`nproc`+1))' install && 70 | cd /opt && rm -rf /opt/bulk_extractor' 71 | else 72 | statusprint "bulk_extractor already installed.." 73 | fi 74 | 75 | # ------------ 76 | # Install Loki 77 | # ------------ 78 | statusprint "Installing Loki.." 79 | if [ ! -d "build.$GLOBAL_BASEARCH/chroot/opt/loki" ] 80 | then 81 | [ ! -d "build.$GLOBAL_BASEARCH/tmp/loki" ] && git clone --recursive --depth=1 https://github.com/Neo23x0/Loki.git build.$GLOBAL_BASEARCH/tmp/loki 82 | sudo cp -r build.$GLOBAL_BASEARCH/tmp/loki build.$GLOBAL_BASEARCH/chroot/opt/ 83 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'export DEBIAN_FRONTEND=noninteractive; \ 84 | apt-get -y install python-pip &&\ 85 | cd /opt/loki &&\ 86 | pip install -r requirements.txt &&\ 87 | rm -rf ./.git &&\ 88 | python2 ./loki-upgrader.py' 89 | else 90 | statusprint "Loki already installed.." 91 | fi 92 | 93 | ;; 94 | esac 95 | 96 | exit 0; 97 | -------------------------------------------------------------------------------- /scripts/chroot_install_kernel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | #FORCED_KERNEL_VERSION=5.15.0-75-generic 6 | #FORCED_KERNEL_SOURCE_VERSION=4.15.0.66.68 7 | 8 | . ./scripts/functions 9 | 10 | verlte() 11 | { 12 | [ "$1" = "`echo -e \"$1\n$2\" | sort -V | head -n1`" ] 13 | } 14 | 15 | chrootdevel_unmount() 16 | { 17 | sudo umount "$PWD/build.$GLOBAL_BASEARCH/chroot.devel" 18 | } 19 | 20 | chrootdevel_mount() 21 | { 22 | sudo mount ./build.$GLOBAL_BASEARCH/chroot -t overlay -o "rw,relatime,lowerdir=./build.$GLOBAL_BASEARCH/chroot,upperdir=./build.$GLOBAL_BASEARCH/tmp/chroot.devel/upper,workdir=./build.$GLOBAL_BASEARCH/tmp/chroot.devel/work" ./build.$GLOBAL_BASEARCH/chroot.devel 23 | } 24 | 25 | if [ "$GLOBAL_CUSTOMKERNEL" == "1" ] 26 | then 27 | statusprint "Building own custom kernel with forensic patches applied.." && 28 | statusprint "Setting up kernel build environment.." && 29 | #[ -d "./build.$GLOBAL_BASEARCH/chroot.devel" ] && sudo rm -rf ./build.$GLOBAL_BASEARCH/chroot.devel/ ./build.$GLOBAL_BASEARCH/tmp/chroot.devel/ 30 | mkdir ./build.$GLOBAL_BASEARCH/chroot.devel 2>&-; mkdir -p ./build.$GLOBAL_BASEARCH/tmp/chroot.devel/{upper,work} 2>&-; 31 | chrootdevel_mount && 32 | trap "chrootdevel_unmount" SIGINT SIGKILL SIGTERM && 33 | 34 | statusprint "Creating development rootfs.." && 35 | statusprint "Installing build tools and downloading kernel source.." && 36 | chroot_exec build.$GLOBAL_BASEARCH/chroot.devel "export DEBIAN_FRONTEND=noninteractive 37 | KERNELPKG=\$(apt-cache show --no-all-versions linux-image-generic| grep '^Depends:' | sed 's/^Depends: \\([^, ]*\\)[, ].*/\\1/') && 38 | KERNELUNSIGNEDPKG=\${KERNELPKG/linux-image/linux-image-unsigned}; 39 | if [ \"x$FORCED_KERNEL_VERSION\" != "x" ] 40 | then 41 | KERNELPKG=\"linux-image-$FORCED_KERNEL_VERSION\"; 42 | fi 43 | apt-fast --yes install build-essential git bc libssl-dev fakeroot; 44 | mkdir -p /opt/kernel 2>&-; chmod o+w /opt/kernel; cd /opt/kernel; 45 | KERNELVER=\$(echo \"\$KERNELPKG\"| cut -d\"-\" -f1,3 | tee /opt/kernel/kernel.version ) && 46 | apt-fast --yes build-dep \"\$KERNELUNSIGNEDPKG\" 47 | if [ \"x$FORCED_KERNEL_VERSION\" != "x" ] 48 | then 49 | apt-get --yes source linux=$FORCED_KERNEL_SOURCE_VERSION 50 | else 51 | apt-get --yes source linux 52 | fi 53 | KERNELDIR=\"/opt/kernel/\$KERNELVER\" 54 | cd \"\$KERNELDIR\" && [ ! -f debian_rules.cleaned ] && ( fakeroot debian/rules clean && touch debian_rules.cleaned ) || exit 0" || ( chrootdevel_unmount; exit 1 ) && 55 | 56 | # Apply kernel patches here. See an example below. 57 | 58 | # statusprint "Patching kernel with write-blocker patch.." && 59 | # KERNELVER=$(cat ./build.$GLOBAL_BASEARCH/chroot.devel/opt/kernel/kernel.version) && 60 | # PATCHFILE=$( ls -1 ./resources/kernel/writeblocker/kernel/*.patch | sed 's,^.*/,,'| sort -r | while read t 61 | # do 62 | # PKVER=$(echo "$t" | cut -d'-' -f1,2) 63 | # if verlte "$PKVER" "$KERNELVER" 64 | # then 65 | # echo "$t" 66 | # break; 67 | # fi 68 | # done ) && 69 | # 70 | # if [ -z "$PATCHFILE" ] 71 | # then 72 | # statusprint "No patch file selected. Aborting." 73 | # chrootdevel_unmount 74 | # exit 1 75 | # else 76 | # statusprint "Using the latest kernel patch file for current kernel: $PATCHFILE" 77 | # fi && 78 | # ( PATCHMSG=$( sudo patch --forward --batch -b -d "./build.$GLOBAL_BASEARCH/chroot.devel/opt/kernel/$KERNELVER" -p1 < "./resources/kernel/writeblocker/kernel/$PATCHFILE" 2>&1 | tail -n +2 ) 79 | # if [ -n "$PATCHMSG" ] 80 | # then 81 | # if ! echo "$PATCHMSG" | grep -q 'Reversed (or previously applied) patch detected' 82 | # then 83 | # statusprint "Error applying kernel patch.\n$PATCHMSG" 84 | # chrootdevel_unmount 85 | # exit 1 86 | # fi 87 | # fi 88 | # ) && 89 | 90 | statusprint "Building kernel.." && 91 | chroot_exec build.$GLOBAL_BASEARCH/chroot.devel "cd \"/opt/kernel/$KERNELVER\" && \ 92 | fakeroot debian/rules binary-headers binary-generic" || ( chrootdevel_unmount; exit 1) && #removed binary-perarch 93 | 94 | statusprint "Installing kernel.." && 95 | sudo cp -rv ./build.$GLOBAL_BASEARCH/chroot.devel/opt/kernel/linux-{image,modules}-*.deb "./build.$GLOBAL_BASEARCH/chroot/opt/" && 96 | chrootdevel_unmount && 97 | chroot_exec build.$GLOBAL_BASEARCH/chroot "export DEBIAN_FRONTEND=noninteractive 98 | apt-fast -y install linux-firmware 99 | dpkg -i /opt/linux-{image,modules}*.deb 100 | apt-fast --yes -f install 101 | rm /opt/linux-{image,modules}-*" && 102 | 103 | chrootdevel_unmount 104 | else 105 | statusprint "Installing stock kernel version." && 106 | if [ -n "$FORCED_KERNEL_VERSION" ] 107 | then 108 | chroot_exec build.$GLOBAL_BASEARCH/chroot "export DEBIAN_FRONTEND=noninteractive; apt-fast --yes install linux-image-$FORCED_KERNEL_VERSION linux-modules-$FORCED_KERNEL_VERSION linux-modules-extra-$FORCED_KERNEL_VERSION linux-firmware; apt-mark manual linux-modules-extra-$FORCED_KERNEL_VERSION" 109 | else 110 | chroot_exec build.$GLOBAL_BASEARCH/chroot "export DEBIAN_FRONTEND=noninteractive; apt-fast --yes install linux-image-generic linux-firmware" 111 | fi 112 | fi 113 | 114 | statusprint "Copying write-blocker udev rules.." && 115 | sudo cp -v ./resources/lib/udev/01-readonly-disks.rules ./build.$GLOBAL_BASEARCH/chroot/lib/udev/rules.d/ 116 | 117 | statusprint "Removing older kernels in ./build.$GLOBAL_BASEARCH/chroot.." 118 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'LATEST_KERNEL=`ls -1 /boot/vmlinuz-*-generic | sort | tail -n1 | cut -d"-" -f2-` 119 | count=$(ls -1 /boot/vmlinuz-*-generic | wc -l) 120 | if [ $count -gt 1 ]; then 121 | dpkg -l "linux-*" | sed '"'"'/^ii/!d; /'"'"'"${LATEST_KERNEL}"'"'"'/d; s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'"'"' | xargs sudo apt-get -y purge 122 | fi' 123 | 124 | 125 | exit 0; 126 | -------------------------------------------------------------------------------- /scripts/chroot_install_remoteaccess.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Installing remote access packages in chroot.." 8 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'DEBIAN_FRONTEND=noninteractive; 9 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 10 | apt-get --yes install openssh-server irssi' 11 | 12 | if [ -n "${GLOBAL_VPNTYPE}" -a "${GLOBAL_VPNTYPE}" = "openvpn" ] 13 | then 14 | statusprint "Installing OpenVPN.." 15 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'DEBIAN_FRONTEND=noninteractive; 16 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 17 | apt-get --yes install openvpn' 18 | 19 | elif [ -n "${GLOBAL_VPNTYPE}" -a "${GLOBAL_VPNTYPE}" = "wireguard" ]; then 20 | statusprint "Installing Wireguard VPN.." 21 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'DEBIAN_FRONTEND=noninteractive; 22 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 23 | apt-get --yes install wireguard-tools resolvconf' 24 | 25 | elif [ -n "${GLOBAL_VPNTYPE}" -a "${GLOBAL_VPNTYPE}" = "tor" ]; then 26 | statusprint "Installing TOR Hidden Service.." 27 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'DEBIAN_FRONTEND=noninteractive; 28 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 29 | apt-get -y install tor' 30 | else 31 | statusprint "No VPN will be installed: VPN type is set to \"$GLOBAL_VPNTYPE\"" 32 | fi 33 | 34 | exit 0; 35 | -------------------------------------------------------------------------------- /scripts/chroot_internet_indicator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | # This add a systemd unit called "internet_indicator.service" amd respectrive timer 6 | # The purpose is to run periodic internet connectivity test (every 30s) 7 | # This test can be disabled via bitscout management tool NETWORK->DISABLE INTERNET TEST 8 | 9 | . ./scripts/functions 10 | 11 | statusprint "Adding internet-indicator script.." 12 | sudo_file_template_copy ./resources/usr/bin/internet-indicator.sh ./build.$GLOBAL_BASEARCH/chroot/usr/bin/internet-indicator.sh 13 | sudo chmod +x ./build.$GLOBAL_BASEARCH/chroot/usr/bin/internet-indicator.sh 14 | 15 | statusprint "Setting up internet-indicator service and timer.." 16 | sudo_file_template_copy ./resources/etc/systemd/system/internet-indicator.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/internet-indicator.service 17 | sudo ln -s /etc/systemd/system/internet-indicator.service ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/internet-indicator.service 2>/dev/null 18 | 19 | sudo_file_template_copy ./resources/etc/systemd/system/internet-indicator.timer ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/internet-indicator.timer 20 | sudo ln -s /etc/systemd/system/internet-indicator.timer ./build.$GLOBAL_BASEARCH/chroot/etc/systemd/system/multi-user.target.wants/internet-indicator.timer 2>/dev/null 21 | 22 | exit 0; 23 | -------------------------------------------------------------------------------- /scripts/chroot_postdownload_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Resetting ./build.$GLOBAL_BASEARCH/chroot/etc/hosts" 8 | echo "127.0.0.1 localhost 9 | 127.0.1.1 $PROJECTNAME 10 | 11 | # The following lines are desirable for IPv6 capable hosts 12 | ::1 ip6-localhost ip6-loopback 13 | fe00::0 ip6-localnet 14 | ff00::0 ip6-mcastprefix 15 | ff02::1 ip6-allnodes 16 | ff02::2 ip6-allrouters 17 | #=========================" | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/hosts >/dev/null 18 | 19 | statusprint "Updating ./build.$GLOBAL_BASEARCH/chroot/etc/resolv.conf" 20 | echo "nameserver 8.8.8.8" | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/resolv.conf >/dev/null 21 | 22 | statusprint "Updating ./build.$GLOBAL_BASEARCH/chroot/etc/hostname" 23 | echo "$PROJECTNAME" | sudo tee ./build.$GLOBAL_BASEARCH/chroot/etc/hostname >/dev/null 24 | 25 | statusprint "Resetting root account inside new rootfs.." 26 | chroot_exec "./build.$GLOBAL_BASEARCH/chroot" "passwd -d root" 27 | 28 | exit 0; 29 | -------------------------------------------------------------------------------- /scripts/chrootscreen_end.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | 8 | statusprint "Leaving chroot.." 9 | statusprint "Uninitializing chroot environment from within.." 10 | 11 | chrootscreen_exec "rm /var/lib/dbus/machine-id 2>&- 12 | rm /sbin/initctl 13 | dpkg-divert --rename --remove /sbin/initctl 14 | apt-get clean 15 | umount -lf /dev/pts 16 | umount -lf /dev 17 | umount -lf /sys 18 | umount -lf /proc" 19 | 20 | typeinchroot "exit\n" 21 | 22 | statusprint "Leaving chroot done." 23 | 24 | 25 | -------------------------------------------------------------------------------- /scripts/chrootscreen_start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | install_required_package screen 8 | statusprint "Entering ./build.$GLOBAL_BASEARCH/chroot.." 9 | 10 | if screen -ls "${PROJECTNAME}_${GLOBAL_BASEARCH}_chroot" >/dev/null; 11 | then 12 | statusprint "Chroot session is already running." 13 | exit 1 14 | fi 15 | 16 | statusprint "Mounting build.$GLOBAL_BASEARCH/chroot/dev" 17 | if [ ! -d "./build.$GLOBAL_BASEARCH/chroot/dev" ] 18 | then 19 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/dev 20 | cd ./build.$GLOBAL_BASEARCH/chroot/dev 21 | sudo MAKEDEV std 22 | cd ../../../ 23 | fi 24 | sudo mount -t devpts devpts build.$GLOBAL_BASEARCH/chroot/dev/pts 25 | 26 | statusprint "Mounting build.$GLOBAL_BASEARCH/chroot/proc" 27 | sudo mount -t proc proc build.$GLOBAL_BASEARCH/chroot/proc 28 | 29 | statusprint "Mounting build.$GLOBAL_BASEARCH/chroot/sys" 30 | sudo mount -t sysfs sysfs build.$GLOBAL_BASEARCH/chroot/sys 31 | 32 | statusprint "Starting build.$GLOBAL_BASEARCH/chroot in a screen session.." 33 | sudo chmod o+rwX ./build.$GLOBAL_BASEARCH/chroot/tmp 34 | if sudo screen -d -m -S "${PROJECTNAME}_${GLOBAL_BASEARCH}_chroot" -U build.$GLOBAL_BASEARCH/chroot build.$GLOBAL_BASEARCH/chroot 35 | then 36 | 37 | statusprint "Initializing chroot environment from within.." 38 | chrootscreen_exec "export HOME=/root 39 | mkdir -p /var/lib/dbus 2>&- 40 | dbus-uuidgen > /var/lib/dbus/machine-id 2>&- 41 | dpkg-divert --local --rename --add /sbin/initctl 42 | ln -s /bin/true /sbin/initctl 2>&-" 43 | 44 | statusprint "Entering .build.$GLOBAL_BASEARCH/chroot done." 45 | else 46 | statusprint "Failed to start chrooted screen" 47 | exit 1 48 | fi 49 | -------------------------------------------------------------------------------- /scripts/deb_pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DEB=`basename "$1"` 3 | pushd . >/dev/null && 4 | cd "$1.unp/control" && 5 | tar --zstd --create --file ../control.tar.zst ./* && 6 | cd ../ && 7 | rm -r ./control && 8 | cd data && 9 | tar --zstd --create --file ../data.tar.zst ./* && 10 | cd ../ && 11 | rm -r ./data && 12 | ar r "../$DEB" ./* && 13 | cd ../ && 14 | rm -r "$DEB.unp/" && 15 | popd >/dev/null 16 | -------------------------------------------------------------------------------- /scripts/deb_unpack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DEB=`basename "$1"` 3 | pushd . >/dev/null && 4 | mkdir "$1.unp" && 5 | cd "$1.unp/" && 6 | ar x "../$DEB" && 7 | mkdir data control && 8 | cd data && 9 | tar xf ../data.tar.*z* && 10 | cd ../control && 11 | tar xf ../control.tar.*z* && 12 | popd >/dev/null 13 | -------------------------------------------------------------------------------- /scripts/export_generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | EXPSERVER="exports/server" 8 | EXPEXPERT="exports/expert" 9 | 10 | statusprint "Generating export files packages.." 11 | 12 | statusprint "Copying files for the server.." 13 | 14 | if [ -d "./config/openvpn" ] 15 | then 16 | mkdir -p "$EXPSERVER/etc/openvpn/${PROJECTSHORTNAME}" 2>&- 17 | cp -v "./config/openvpn/${PROJECTSHORTNAME}.conf.server" "$EXPSERVER/etc/openvpn/${PROJECTSHORTNAME}.conf" 18 | cp -v "./config/openvpn/ip_pool.lst" "$EXPSERVER/etc/openvpn/${PROJECTSHORTNAME}/" 19 | cp -v "./config/openvpn/easy-rsa/pki/"{ta.key,dh.pem,private/server.key,issued/server.crt,ca.crt} "$EXPSERVER/etc/openvpn/${PROJECTSHORTNAME}/" 20 | fi 21 | 22 | if [ -d "./config/wireguard" ] 23 | then 24 | mkdir -p "$EXPSERVER/etc/wireguard" 2>&- 25 | cp -v "./config/wireguard/${PROJECTSHORTNAME}.conf.server" "$EXPSERVER/etc/wireguard/${PROJECTSHORTNAME}.conf" 26 | fi 27 | 28 | mkdir -p "$EXPSERVER/etc/ngircd" 2>&-; cp -v "./config/ngircd/ngircd.conf" "$EXPSERVER/etc/ngircd/" 29 | 30 | statusprint "Copying files for the expert.." 31 | mkdir -p "$EXPEXPERT/etc/openvpn/${PROJECTSHORTNAME}" 32 | mkdir -p "$EXPEXPERT/etc/"{ssh,irc} 33 | 34 | if [ -d "./config/openvpn" ] 35 | then 36 | mkdir -p "$EXPEXPERT/etc/openvpn/${PROJECTSHORTNAME}" 37 | cp -v "./config/openvpn/${PROJECTSHORTNAME}.conf.expert" "$EXPEXPERT/etc/openvpn/${PROJECTSHORTNAME}.conf" 38 | cp -v "./config/openvpn/easy-rsa/pki/"{ta.key,private/expert.key,issued/expert.crt,ca.crt} "$EXPEXPERT/etc/openvpn/${PROJECTSHORTNAME}/" 39 | fi 40 | 41 | if [ -d "./config/wireguard" ] 42 | then 43 | mkdir -p "$EXPEXPERT/etc/wireguard" 2>&- 44 | cp -v "./config/wireguard/${PROJECTSHORTNAME}.conf.expert" "$EXPEXPERT/etc/wireguard/${PROJECTSHORTNAME}.conf" 45 | fi 46 | 47 | cp -v "./config/ssh/"{${PROJECTSHORTNAME},${PROJECTSHORTNAME}.pub} "$EXPEXPERT/etc/ssh" 48 | sed 's/owner/expert/g;' "./config/irssi/irssi.conf" > "$EXPEXPERT/etc/irc/irssi.conf" 49 | 50 | sudo [ -d ./build.$GLOBAL_BASEARCH/chroot/var/lib/tor/tor_hidden_service/ ] && sudo mkdir -p $EXPEXPERT/var/lib/tor && sudo cp -r ./build.$GLOBAL_BASEARCH/chroot/var/lib/tor $EXPEXPERT/var/lib/tor 51 | [ $? == '0' ] && statusprint "[SUCCESS] Copying tor config file and key to host success..." 52 | 53 | exit 0; 54 | -------------------------------------------------------------------------------- /scripts/functions: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | PROJECTNAME="bitscout" 6 | PROJECTCAPNAME="Bitscout" 7 | PROJECTRELEASE="22.04" 8 | PROJECTSHORTNAME="scout" 9 | BASERELEASE="jammy" 10 | CONTAINERNET_NAME="ve-container" 11 | CONTAINERNET_HOST_IP="10.3.0.1" 12 | CONTAINERNET_HOST_IP_CIDR="10.3.0.1/24" 13 | CONTAINERNET_GUEST_IP="10.3.0.2" 14 | CONTAINERNET_GUEST_DNS="8.8.8.8" 15 | VPNNET="10.5.0.0/24" 16 | VPNNET_SERVERIP="${VPNNET%.*}.1" 17 | VPNNET_CLIENTIP="${VPNNET%.*}.2" 18 | VPNNET_EXPERTIP="${VPNNET%.*}.3" 19 | VPNNET_IPPOOLSTART="${VPNNET%.*}.2" 20 | VPNNET_IPPOOLEND="${VPNNET%.*}.250" 21 | IRC_SERVER=$VPNNET_SERVERIP 22 | IRC_PORT=6667 23 | CONTAINERNAME="expert" 24 | CONTAINERUSERNAME="user" 25 | LANG=en_US.UTF-8 26 | HISTORIAN_ZRAM_SIZE=2048M 27 | 28 | #Support aliases throughout the scripts 29 | shopt -s expand_aliases 30 | 31 | [ -f "config/$PROJECTNAME-build.conf" ] && . "config/$PROJECTNAME-build.conf" 32 | 33 | if [ -n "$GLOBAL_TARGET" -a "$GLOBAL_TARGET" = "iso" ]; then 34 | INITRDPATH=build.$GLOBAL_BASEARCH/image/casper/initrd.img 35 | else 36 | INITRDPATH=build.$GLOBAL_BASEARCH/chroot/boot/initrd.img 37 | fi 38 | RESERVEDIR=reserve 39 | SCREENNAME=${PROJECTNAME}_${GLOBAL_BASEARCH}_chroot #creates a screen session for interactive configuration. see scripts/chroot_enter.sh and scripts/chroot_leave.sh 40 | 41 | statusprint() 42 | { 43 | if [ "$QUIET" == "true" ] 44 | then 45 | return 0 46 | else 47 | echo -e$PRINTOPTIONS "$1" 48 | fi 49 | } 50 | 51 | create_dir_safe() 52 | { 53 | [ ! -d "$1" ] && sudo mkdir -p "$1" 2>&- 54 | return 0 55 | } 56 | 57 | chroot_mount_cache() 58 | { 59 | trap "chroot_unmount_cache \"$CHROOTPATH\"" SIGINT SIGKILL SIGTERM 60 | CHROOTPATH="$1" 61 | if [ -z "$CHROOTPATH" ] 62 | then 63 | statusprint "Failed to mount cache dirs: chroot path cannot be empty!" && 64 | return 1 65 | fi 66 | statusprint "Mounting chroot cache directories into \"$CHROOTPATH\".." && 67 | 68 | statusprint "Mounting ./build.$GLOBAL_BASEARCH/cache/apt.cache.." && 69 | create_dir_safe ./build.$GLOBAL_BASEARCH/cache/apt.cache && 70 | create_dir_safe $CHROOTPATH/var/cache/apt/archives && 71 | sudo mount --bind $PWD/build.$GLOBAL_BASEARCH/cache/apt.cache $CHROOTPATH/var/cache/apt/archives && 72 | 73 | statusprint "Mounting ./build.$GLOBAL_BASEARCH/cache/apt.lists.." && 74 | create_dir_safe ./build.$GLOBAL_BASEARCH/cache/apt.lists && 75 | create_dir_safe $CHROOTPATH/var/lib/apt/lists && 76 | sudo mount --bind $PWD/build.$GLOBAL_BASEARCH/cache/apt.lists $CHROOTPATH/var/lib/apt/lists && return 0 || return 1 77 | 78 | } 79 | 80 | chroot_unmount_cache() 81 | { 82 | CHROOTPATH="$1" 83 | if [ -z "$CHROOTPATH" ] 84 | then 85 | statusprint "Failed to unmount cache dirs: chroot path cannot be empty!" && 86 | return 1 87 | fi 88 | 89 | statusprint "Unmounting chroot cache directories inside \"$CHROOTPATH\".." 90 | sudo umount -l "$CHROOTPATH/var/cache/apt/archives" "$CHROOTPATH/var/lib/apt/lists" 2>&- 91 | return 0 92 | } 93 | 94 | chroot_unmount_fs() 95 | { 96 | CHROOTPATH="$1" 97 | statusprint "Unmounting active chroot filesystems inside \"$CHROOTPATH\".." 98 | mount | grep -q "$CHROOTPATH/sys/kernel/security" && sudo umount -l "$CHROOTPATH/sys/kernel/security" 99 | sudo umount -l "$CHROOTPATH/dev/pts" "$CHROOTPATH/sys" "$CHROOTPATH/proc" 2>&- 100 | chroot_unmount_cache "$1" 101 | return 0 102 | } 103 | 104 | #decrease aria2c default verbosity 105 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c 106 | 107 | chroot_exec() 108 | { 109 | 110 | DIR="$1" 111 | CMD="$2" 112 | BASEDIR="$PWD" 113 | if [ ! -d "$DIR/dev" ] 114 | then 115 | sudo mkdir -p "$DIR/dev" && 116 | cd "$DIR/dev" && 117 | sudo MAKEDEV std && 118 | cd "$BASEDIR" 119 | fi 120 | 121 | chroot_mount_cache "$DIR" && 122 | trap "chroot_unmount_fs \"$DIR\"" SIGINT SIGKILL SIGTERM && 123 | 124 | ( [ ! -d "$DIR/tmp" ] && sudo mkdir -p "$DIR/tmp" || true ) && 125 | sudo chmod o+rwX "$DIR/tmp" && 126 | statusprint "Executing command in chroot ($DIR):" && 127 | statusprint "$CMD" && 128 | echo "#!/bin/bash 129 | export LANG=$LANG 130 | mkdir -p /dev/pts 2>&- 131 | mount -t devpts devpts /dev/pts 132 | mount -t proc proc /proc 133 | mount -t sysfs sysfs /sys 134 | export HOME=/root 135 | mkdir -p /var/lib/dbus 2>&- 136 | dbus-uuidgen > /var/lib/dbus/machine-id 2>&- 137 | dpkg-divert --local --rename --add /sbin/initctl >/dev/null 138 | ln -s /bin/true /sbin/initctl 2>&- 139 | rm /tmp/chroot_session.sh 140 | aria2c(){ /usr/bin/aria2c --console-log-level=warn \"\$@\";}; export -f aria2c 141 | $CMD 142 | CMDRETURN=\$? 143 | rm /var/lib/dbus/machine-id 2>&- 144 | rm /sbin/initctl 145 | dpkg-divert --rename --remove /sbin/initctl >/dev/null 146 | exit \$CMDRETURN " > "./$DIR/tmp/chroot_session.sh" && 147 | 148 | chmod +x "./$DIR/tmp/chroot_session.sh" && 149 | if sudo chroot "$DIR" "/tmp/chroot_session.sh" 150 | then 151 | statusprint "Info: command in chroot succeeded." 152 | chroot_unmount_fs "$DIR" && return 0 153 | else 154 | statusprint "Warning: command in chroot failed." 155 | chroot_unmount_fs "$DIR" && return 1 156 | fi && 157 | 158 | return 0 159 | } 160 | 161 | nspawn_exec() 162 | { 163 | install_required_package expect 164 | 165 | CHROOTDIR="$1" 166 | CHROOTCMD="${2:-/bin/true}" 167 | INTERACTIVE="$3" 168 | CONTAINER_SPAWN_SCRIPT="$PWD/scripts/nspawn_container_spawn.sh" 169 | 170 | chroot_mount_cache "$PWD/$CHROOTDIR" && 171 | trap "chroot_unmount_fs \"$PWD/$CHROOTDIR\"" SIGINT SIGKILL SIGTERM && 172 | echo "$CHROOTCMD" | sudo tee "$PWD/$CHROOTDIR/chroot_exec.sh" >/dev/null 173 | 174 | statusprint "Executing the following command in nspawn $CHROOTDIR:" 175 | statusprint "$CHROOTCMD" 176 | export CHROOTDIR 177 | export INTERACTIVE 178 | export CONTAINER_SPAWN_SCRIPT 179 | sudo --preserve-env=CHROOTDIR,INTERACTIVE,CONTAINER_SPAWN_SCRIPT expect $PWD/scripts/nspawn_session.exp 180 | 181 | if [ ! -f "$PWD/$CHROOTDIR/chroot_exec.retcode" ]; then return 0; fi 182 | CHROOTRET=$(cat "$PWD/$CHROOTDIR/chroot_exec.retcode") 183 | sudo rm "$PWD/$CHROOTDIR/chroot_exec.sh" "$PWD/$CHROOTDIR/chroot_exec.retcode" 2>/dev/null 184 | 185 | if [ "x$CHROOTRET" == "x0" ] 186 | then 187 | statusprint "Info: command in nspawn succeeded." 188 | chroot_unmount_fs "$PWD/$CHROOTDIR" && return 0 189 | else 190 | statusprint "Warning: command in nspawn failed. Last return code: $CHROOTRET" 191 | chroot_unmount_fs "$PWD/$CHROOTDIR" && return 1 192 | fi 193 | } 194 | 195 | unpackinitrd() 196 | { 197 | # unpackinitrd [initrd [dest dir]] 198 | if [ -n "$1" ]; then SRCPATH=$1; else SRCPATH=$INITRDPATH; fi 199 | if [ -n "$2" ]; then DSTPATH=$2; else DSTPATH=./build.$GLOBAL_BASEARCH/initrd; fi 200 | statusprint "Unpacking initrd image from $SRCPATH to $DSTPATH.." 201 | if [ -f "$SRCPATH" ] 202 | then 203 | if [ ! -f ./build.$GLOBAL_BASEARCH/usr/bin/unmkinitramfs ] 204 | then 205 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'DEBIAN_FRONTEND=noninteractive; apt install initramfs-tools-core' || exit 1 206 | fi 207 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'INITRD=$(ls -1 boot/ | grep -m1 "initrd.*-.*"); 208 | cp /usr/bin/unmkinitramfs /tmp/unmkinitramfs 209 | sed -i "s/--no-absolute-filenames//g" /tmp/unmkinitramfs 210 | echo "Unpacking $INITRD.." 211 | mkdir /tmp/initrd 212 | /tmp/unmkinitramfs /boot/$(ls -1 boot/ | grep -m1 "initrd.*-.*") /tmp/initrd' 213 | [ -n "$DSTPATH" -a -d $DSTPATH ] && sudo rm -rf $DSTPATH 214 | sudo mv -v ./build.$GLOBAL_BASEARCH/chroot/tmp/initrd $DSTPATH 215 | else 216 | echo "[ERROR]: initrd image not found in $SRCPATH." 217 | fi 218 | } 219 | 220 | packinitrd() 221 | { 222 | # packinitrd [initrd [src dir]] 223 | if [ -n "$1" ]; then DSTPATH=$1; else DSTPATH=$INITRDPATH; fi 224 | if [ -n "$2" ]; then SRCPATH=$2; else SRCPATH=./build.$GLOBAL_BASEARCH/initrd; fi 225 | statusprint "Packing initrd image from $SRCPATH into $DSTPATH.." 226 | if [ -d "$SRCPATH" ] 227 | then 228 | sudo mv -v "$SRCPATH" ./build.$GLOBAL_BASEARCH/chroot/tmp/initrd 229 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'cd /tmp/initrd 230 | ls -1 | grep "early" | while read d; 231 | do 232 | (cd "$d"; find . | cpio -o -H newc ) | tee -a /tmp/initrd.img.new >/dev/null 233 | done; 234 | (cd ./main; find . | cpio -o -H newc ) | lz4 -l -9 -c | tee -a "/tmp/initrd.img.new" >/dev/null' 235 | cat ./build.$GLOBAL_BASEARCH/chroot/tmp/initrd.img.new | sudo tee "$DSTPATH" >/dev/null 236 | sudo rm ./build.$GLOBAL_BASEARCH/chroot/tmp/initrd.img.new 237 | sudo mv -v ./build.$GLOBAL_BASEARCH/chroot/tmp/initrd "$SRCPATH" 238 | else 239 | echo "[ERROR]: initrd directory not found. Aborting." 240 | fi 241 | } 242 | 243 | install_required_package() 244 | { 245 | PKGNAME="$1" 246 | if ! dpkg-query --show --showformat='${db:Status-Status}\n' $PKGNAME | grep -q "^installed$" 247 | then 248 | statusprint "$PKGNAME was not found your system. It is required to continue.\nPlease authorize installing $PKGNAME.." 249 | if ! apt-cache search "$PKGNAME" | grep -q "$PKGNAME" 250 | then 251 | #let's check that universe repository is enabled. required for some packages, i.e. easy-rsa 252 | REPOSITORY="universe" 253 | if ! apt-cache policy | grep -q "$REPOSITORY" 254 | then 255 | statusprint "Enabling additional repository ($REPOSITORY) for your system.." 256 | OSCODENAME=`lsb_release -c| awk '{print $2}'` 257 | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu/ $OSCODENAME $REPOSITORY" 258 | 259 | statusprint "Updating host system repository index.." 260 | sudo apt -y update 261 | fi 262 | fi; 263 | if ! sudo apt -y install "$PKGNAME"; 264 | then 265 | statusprint "Updating host system repository index.." 266 | sudo apt -y update 267 | if ! sudo apt -y install "$PKGNAME"; 268 | then 269 | statusprint "ERROR: Couldn't install/find $PKGNAME. Aborting.." 270 | exit 1; 271 | fi; 272 | fi; 273 | fi 274 | } 275 | 276 | filelist_exists() 277 | { 278 | statusprint "Checking if file (filelist) exists.." 279 | for i in $@ 280 | do 281 | if [ ! -f "$i" ]; then 282 | statusprint "File is NOT FOUND: $i" 283 | return 1; 284 | else 285 | statusprint "File exists: $i" 286 | fi; 287 | done; 288 | return 0; 289 | } 290 | 291 | file_template_copy() 292 | { 293 | SRC="$1" 294 | DST="$2" 295 | statusprint "Copying template-based file: \"$1\" -> \"$2\"" 296 | [ ! -d "${DST%/*}" ] && $SUDO mkdir -p "${DST%/*}" 297 | sed "s//${PROJECTNAME}/g; s//${PROJECTCAPNAME}/g; s//${PROJECTRELEASE}/g; s//${PROJECTSHORTNAME}/g; s//${CONTAINERNAME}/g; s//${CONTAINERUSERNAME}/g; s//${BASERELEASE}/g; s//${CONTAINERNET_NAME}/g; s##${CONTAINERNET_HOST_IP_CIDR}#g; s//${CONTAINERNET_GUEST_IP}/g; s//${CONTAINERNET_HOST_IP}/g; s//${CONTAINERNET_GUEST_DNS}/g; s//$HISTORIAN_ZRAM_SIZE/g; s//${GLOBAL_HOSTSSH_ENABLED}/g; s//${GLOBAL_LANACCESS_ENABLED}/g; s//${GLOBAL_AUTOMOUNT}/ " "$SRC" | $SUDO tee "$DST" >/dev/null 298 | } 299 | 300 | sudo_file_template_copy() 301 | { 302 | SUDO="sudo" file_template_copy "$1" "$2" 303 | } 304 | 305 | chroot_safecopy_resources() 306 | { 307 | #This function is used to safe-copy files from resources to destination chroot 308 | #A simple cp ./resources/usr/share/vim/vimrc to ./build.$GLOBAL_BASEARCH/chroot/resources 309 | 310 | if [ ! -d "./build.$GLOBAL_BASEARCH/chroot/resources" ]; then 311 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/resources 312 | fi 313 | if ! mount | grep -q ./build.$GLOBAL_BASEARCH/chroot/resources; then 314 | if ! sudo mount --bind ./resources ./build.$GLOBAL_BASEARCH/chroot/resources; then 315 | echo "ERROR: Failed to mount-bind ./resources to ./build.$GLOBAL_BASEARCH/chroot/resources." 316 | return 1 317 | fi 318 | fi 319 | statusprint "Copying inside the chroot environment:" 320 | sudo chroot ./build.$GLOBAL_BASEARCH/chroot /bin/cp $* 321 | retcode=$? 322 | sudo umount ./build.$GLOBAL_BASEARCH/chroot/resources 323 | sudo rmdir ./build.$GLOBAL_BASEARCH/chroot/resources 324 | return $retcode 325 | } 326 | 327 | normalize_size() 328 | { 329 | install_required_package gawk 330 | if [ -z "$1" ]; then return; fi 331 | echo "$1" | gawk ' 332 | { 333 | v=$0; gsub(/[a-zA-Z]*$/,"",v); 334 | u=tolower($0); gsub(/^[0-9\.]*/,"",u); 335 | switch(u){ 336 | case "kib": c=1024; break; 337 | case "mib": c=1024*1024; break; 338 | case "gib": c=1024*1024*1024; break; 339 | case "kb": c=1000; break; 340 | case "mb": c=1000*1000; break; 341 | case "gb": c=1000*1000*1000; break; 342 | }; 343 | print v*c; 344 | }' 345 | } 346 | 347 | 348 | -------------------------------------------------------------------------------- /scripts/image_build-nosquashfs-rebuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Calculating files MD5 for integrity control.." 8 | cd image && find . -type f -print0 | xargs -0 sudo md5sum | grep -v "\./md5sum.txt" > md5sum.txt 9 | cd .. 10 | 11 | statusprint "Creating grub-powered image..." 12 | install_required_package grub-common 13 | install_required_package grub-pc-bin 14 | install_required_package grub-efi-ia32-bin 15 | install_required_package grub-efi-amd64-bin 16 | install_required_package mtools 17 | install_required_package xorriso 18 | 19 | if grub-mkrescue --output=/dev/null -- -as mkisofs 2>&1 | grep -q "FAILURE : -as mkisofs" 20 | then 21 | #worked while building on ubuntu 16.04 22 | sudo grub-mkrescue --modules="iso9660 linux ext2 fshelp ls boot jpeg video_bochs video_cirrus" --output=./$PROJECTNAME-22.04.iso ./image -- -r -volid "${PROJECTNAME}-${GLOBAL_BUILDID}" -partition_offset 16 -J -l -joliet-long -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -no-emul-boot # do not modify volid, it's critical to system boot 23 | else 24 | #worked while building on ubuntu 17.10 25 | sudo grub-mkrescue --modules="iso9660 linux ext2 fshelp ls boot jpeg video_bochs video_cirrus" --output=./$PROJECTNAME-22.04.iso ./image -- -as mkisofs -r -volid "${PROJECTNAME}-${GLOBAL_BUILDID}" -partition_offset 16 -J -l -joliet-long -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -no-emul-boot # do not modify volid, it's critical to system boot 26 | fi 27 | 28 | exit 0; 29 | -------------------------------------------------------------------------------- /scripts/image_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Making sure package cache and other fs are detached.." 8 | chroot_unmount_fs "./build.$GLOBAL_BASEARCH/chroot" 9 | sudo umount -l "./build.$GLOBAL_BASEARCH/image/persistence" 2>/dev/null 10 | sudo umount -l "./build.$GLOBAL_BASEARCH/image" 2>/dev/null 11 | 12 | if [ "$GLOBAL_TARGET" = "iso" ]; then 13 | GLOBAL_PARTITION_TABLE="hybrid" 14 | fi 15 | 16 | install_required_package grub-common 17 | case "$GLOBAL_PARTITION_TABLE" in 18 | "msdos") install_required_package grub-pc-bin;; 19 | 20 | "gpt") install_required_package grub-efi-ia32-bin; 21 | install_required_package grub-efi-amd64-bin;; 22 | 23 | "hybrid") 24 | install_required_package grub-pc-bin; 25 | install_required_package grub-efi-ia32-bin; 26 | install_required_package grub-efi-amd64-bin;; 27 | *) statusprint "Unsupported partition table type: $GLOBAL_PARTITION_TABLE" 28 | exit 1;; 29 | esac 30 | 31 | if [ "$GLOBAL_TARGET" = "iso" ]; then 32 | statusprint "Preparing to build an ISO image.." 33 | install_required_package squashfs-tools 34 | 35 | statusprint "Compressing chroot.." 36 | SQUASHFSIMG="./build.$GLOBAL_BASEARCH/image/casper/filesystem.squashfs" 37 | if [ -f "$SQUASHFSIMG" ] 38 | then 39 | sudo rm -f "$SQUASHFSIMG" 40 | fi 41 | 42 | printf $(sudo du -sx --block-size=1 "build.$GLOBAL_BASEARCH" | cut -f1) | sudo tee ./build.$GLOBAL_BASEARCH/image/casper/filesystem.size >/dev/null 43 | 44 | statusprint "Making squashfs image.." 45 | sudo mksquashfs ./build.$GLOBAL_BASEARCH/chroot "$SQUASHFSIMG" -e boot -wildcards -ef ./resources/squashfs/exclude.list 46 | 47 | statusprint "Calculating files MD5 for integrity control.." 48 | cd ./build.$GLOBAL_BASEARCH/image && find . -type f -print0 | xargs -0 sudo md5sum | grep -v "\./md5sum.txt" > md5sum.txt 49 | cd ../../ 50 | 51 | statusprint "Creating grub-powered image..." 52 | install_required_package mtools 53 | install_required_package xorriso 54 | 55 | sudo grub-mkrescue --modules="part_gpt iso9660 linux ext2 fshelp ls boot jpeg video_bochs video_cirrus minicmd extcmd cat" --output=./$PROJECTNAME-$PROJECTRELEASE-$GLOBAL_BASEARCH.iso ./build.$GLOBAL_BASEARCH/image -- -as mkisofs -r -volid "${PROJECTNAME}-${GLOBAL_BUILDID}" -J -l -joliet-long -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -no-emul-boot 56 | 57 | elif [ "$GLOBAL_TARGET" != "iso" ]; then 58 | statusprint "Preparing to build a raw disk image.." 59 | install_required_package gdisk 60 | 61 | case "${GLOBAL_PARTITION_TABLE}" in 62 | "msdos") 63 | ROOTPART_START_MB=1 64 | ;; 65 | "gpt") 66 | EFIPART_START_MB=1 67 | EFIPART_SIZE_MB=128 68 | ROOTPART_START_MB=$[$EFIPART_START_MB + $EFIPART_SIZE_MB] 69 | ;; 70 | "hybrid") 71 | BIOSGRUB_START_MB=1 72 | BIOSGRUB_SIZE_MB=1 73 | EFIPART_START_MB=$[$BIOSGRUB_START_MB + $BIOSGRUB_SIZE_MB] 74 | EFIPART_SIZE_MB=128 75 | ROOTPART_START_MB=$[$EFIPART_START_MB + $EFIPART_SIZE_MB] 76 | ;; 77 | esac 78 | 79 | ROOTPART_SIZE_MB=$( sudo tar c ./build.$GLOBAL_BASEARCH/chroot/ 2>&1 | wc -c | awk '{ print(int($1/(1024*1024) + 256))}' ) # more accurate estimation 80 | 81 | PERSPART_START_MB=$[ $ROOTPART_START_MB + $ROOTPART_SIZE_MB ] 82 | PERSPART_SIZE_B=$( normalize_size $GLOBAL_PERSISTSIZE ) 83 | PERSPART_SIZE_MB=$( awk '{print $0/(1024*1024)}' <<<$PERSPART_SIZE_B ) 84 | 85 | IMG_SIZE_MB=$[$PERSPART_START_MB+$PERSPART_SIZE_MB+1] 86 | IMG_SIZE_B=$[$IMG_SIZE_MB*1024*1024] 87 | IMGFILE=$PROJECTNAME-$PROJECTRELEASE-$GLOBAL_BASEARCH.raw 88 | 89 | statusprint "Target disk image size: $IMG_SIZE_B bytes" 90 | [ -f "./$IMGFILE" ] && rm -f "./$IMGFILE" 2>&1 91 | truncate -s $IMG_SIZE_B "./$IMGFILE" 92 | if [ ! -f "./$IMGFILE" ]; then statusprint "Failed to create image file at $IMGFILE"; exit 1; fi; 93 | 94 | 95 | case "${GLOBAL_PARTITION_TABLE}" in 96 | "msdos") 97 | statusprint "Building MSDOS partition table.." 98 | parted -s "./$IMGFILE" mklabel msdos 99 | parted -a optimal -s "./$IMGFILE" mkpart primary ext4 ${ROOTPART_START_MB}MiB $[${ROOTPART_START_MB}+${ROOTPART_SIZE_MB}]MiB 100 | parted -a optimal -s "./$IMGFILE" mkpart primary ext4 ${PERSPART_START_MB}MiB $[${PERSPART_START_MB}+${PERSPART_SIZE_MB}]MiB 101 | ;; 102 | "gpt") 103 | statusprint "Building GPT partition table.." 104 | #sgdisk -g "./$IMGFILE" 105 | sgdisk -n 1::+${EFIPART_SIZE_MB}M -t 1:EF00 -n 2::+${ROOTPART_SIZE_MB}M -t 2:8300 -n 3::+${PERSPART_SIZE_MB}M -t 3:8300 "./$IMGFILE" 106 | ;; 107 | "hybrid") 108 | statusprint "Building hybrid MSDOS+GPT partition table.." 109 | sgdisk -h "./$IMGFILE" 110 | sgdisk -n 1::+${BIOSGRUB_SIZE_MB}M -t 1:EF02 -n 2::+${EFIPART_SIZE_MB}M -t 2:EF00 -n 3::+${ROOTPART_SIZE_MB}M -t 3:8300 -n 4::+${PERSPART_SIZE_MB}M -t 4:8300 "./$IMGFILE" 111 | ;; 112 | esac 113 | 114 | 115 | statusprint "Preparing loop devices.." 116 | LOOPDEV_IMG=$(sudo losetup -f) 117 | if [ ! -b ${LOOPDEV_IMG} ]; then statusprint "Couldn't find spare loop device for the image.."; exit 1; fi; 118 | sudo losetup --partscan ${LOOPDEV_IMG} "./$IMGFILE" 119 | 120 | case "${GLOBAL_PARTITION_TABLE}" in 121 | "msdos") 122 | LOOPDEV_PART_ROOT=${LOOPDEV_IMG}p1 123 | LOOPDEV_PART_PERS=${LOOPDEV_IMG}p2 124 | ;; 125 | "gpt") 126 | LOOPDEV_PART_EFI=${LOOPDEV_IMG}p1 127 | LOOPDEV_PART_ROOT=${LOOPDEV_IMG}p2 128 | LOOPDEV_PART_PERS=${LOOPDEV_IMG}p3 129 | ;; 130 | "hybrid") 131 | LOOPDEV_PART_BIOS_GRUB=${LOOPDEV_IMG}p1 132 | LOOPDEV_PART_EFI=${LOOPDEV_IMG}p2 133 | LOOPDEV_PART_ROOT=${LOOPDEV_IMG}p3 134 | LOOPDEV_PART_PERS=${LOOPDEV_IMG}p4 135 | ;; 136 | esac 137 | 138 | 139 | if [ -n "$LOOPDEV_PART_EFI" ]; then 140 | statusprint "Formatting EFI partition.." 141 | sudo mkfs.fat -F32 -n EFI $LOOPDEV_PART_EFI 142 | fi 143 | 144 | statusprint "Formatting and populating root partition.." 145 | sudo mkfs -q -t ext4 -d ./build.${GLOBAL_BASEARCH}/chroot -F -e remount-ro -L / -U random $LOOPDEV_PART_ROOT 146 | 147 | statusprint "Formatting and populating persistence partition.." 148 | if [ -d ./resources/persistence ]; then 149 | sudo mkfs -q -t ext4 -d ./resources/persistence -F -L /persistence -U random $LOOPDEV_PART_PERS 150 | else 151 | sudo mkfs -q -t ext4 -F -L persistence -U random $LOOPDEV_PART_PERS 152 | fi 153 | 154 | statusprint "Getting root partition UUID.." 155 | PART_ROOT_UUID=$(sudo blkid -o udev ${LOOPDEV_PART_ROOT} | awk -F= '/ID_FS_UUID=/{print $2}') 156 | 157 | statusprint "Getting persistence partition UUID.." 158 | PART_PERS_UUID=$(sudo blkid -o udev ${LOOPDEV_PART_PERS} | awk -F= '/ID_FS_UUID=/{print $2}') 159 | 160 | statusprint "Mounting target image rootfs.." 161 | sudo mount -t ext4 ${LOOPDEV_PART_ROOT} ./build.${GLOBAL_BASEARCH}/image 162 | 163 | if [ -n "$LOOPDEV_PART_EFI" ]; then 164 | statusprint "Mounting EFI partition.." 165 | [ ! -d "./build.${GLOBAL_BASEARCH}/image/boot/efi" ] && sudo mkdir -p ./build.${GLOBAL_BASEARCH}/image/boot/efi 166 | sudo mount -t vfat ${LOOPDEV_PART_EFI} ./build.${GLOBAL_BASEARCH}/image/boot/efi 167 | fi 168 | 169 | statusprint "Mounting persistence partition.." 170 | sudo mount -t ext4 ${LOOPDEV_PART_PERS} ./build.${GLOBAL_BASEARCH}/image/persistence 171 | 172 | statusprint "Unmounting persistence filesystem.." 173 | sudo umount -l ./build.${GLOBAL_BASEARCH}/image/persistence 174 | 175 | PROJDIR=$PWD 176 | statusprint "Adding target loop devices to the mounted rootfs.." 177 | pushd /dev >/dev/null 178 | tar -cpf- ${LOOPDEV_IMG##*/} ${LOOPDEV_PART_EFI##*/} ${LOOPDEV_PART_ROOT##*/} ${LOOPDEV_PART_PERS##*/} | sudo tar -xf- -C $PROJDIR/build.$GLOBAL_BASEARCH/image/dev 179 | popd >/dev/null 180 | 181 | if [ ! -b "./build.$GLOBAL_BASEARCH/image/dev/${LOOPDEV_IMG##*/}" ]; then 182 | statusprint "Couldn't find loop device on the target rootfs."; 183 | sudo umount ./build.$GLOBAL_BASEARCH/image/boot/efi ./build.$GLOBAL_BASEARCH/image/boot ./build.$GLOBAL_BASEARCH/image 2>/dev/null 184 | sudo losetup -d $LOOPDEV_IMG 185 | exit 1; 186 | fi; 187 | 188 | statusprint "Updating partitions UUID for grub.." 189 | sudo sed -i "s/root=UUID=[0-9a-zA-Z-]*/root=UUID=${PART_ROOT_UUID}/g; s/persist=UUID=[0-9a-zA-Z-]*/persist=UUID=${PART_PERS_UUID}/g;" ./build.$GLOBAL_BASEARCH/image/boot/grub/grub.cfg 190 | 191 | if [ "$GLOBAL_PARTITION_TABLE" = "msdos" -o "$GLOBAL_PARTITION_TABLE" = "hybrid" ]; then 192 | statusprint "Installing MBR grub.." 193 | chroot_exec build.$GLOBAL_BASEARCH/image "grub-install --target i386-pc --boot-directory=/boot --modules=\"part_msdos ext2 vbe\" --install-modules=\"ahci all_video ata biosdisk minicmd extcmd ls cat disk drivemap ehci gfxmenu gfxterm halt hdparm help linux nativedisk ohci pata jpeg probe reboot scsi uhci usb_keyboard usb vbe videoinfo videotest part_msdos part_gpt fat ext2 normal\" $LOOPDEV_IMG" 194 | fi; 195 | 196 | if [ "$GLOBAL_PARTITION_TABLE" = "gpt" -o "$GLOBAL_PARTITION_TABLE" = "hybrid" ]; then 197 | statusprint "Installing EFI grub.." 198 | chroot_exec build.$GLOBAL_BASEARCH/image "grub-install --target x86_64-efi --efi-directory=/boot/efi --modules=\"part_gpt fat\" --install-modules=\"ahci all_video ata boot minicmd extcmd ls cat disk echo ehci efi_gop efi_uga font gfxmenu gfxterm_background gfxterm_menu gfxterm halt hdparm help linux linuxefi msdospart nativedisk ohci pata jpeg probe reboot scsi uhci usb_keyboard usb videoinfo videotest part_msdos part_gpt fat ext2 normal\" $LOOPDEV_IMG" 199 | fi 200 | 201 | statusprint "Unmounting image rootfs filesystem and removing loop devices.." 202 | sudo umount ./build.$GLOBAL_BASEARCH/image/boot/efi ./build.$GLOBAL_BASEARCH/image 2>/dev/null 203 | sudo losetup -d $LOOPDEV_IMG 204 | 205 | if [ -n "$GLOBAL_TARGET" -a "$GLOBAL_TARGET" != "raw" ]; then 206 | statusprint "Converting image to $GLOBAL_TARGET format.." 207 | install_required_package qemu-utils 208 | case ${GLOBAL_TARGET} in 209 | qcow2) 210 | qemu-img convert -f raw -O qcow2 $IMGFILE $PROJECTNAME-$PROJECTRELEASE-$GLOBAL_BASEARCH.qcow2 211 | rm "$IMGFILE" 212 | ;; 213 | vmdk) 214 | qemu-img convert -f raw -O vmdk $IMGFILE $PROJECTNAME-$PROJECTRELEASE-$GLOBAL_BASEARCH.vmdk 215 | rm "$IMGFILE" 216 | ;; 217 | esac 218 | fi 219 | 220 | fi 221 | 222 | exit 0; 223 | -------------------------------------------------------------------------------- /scripts/image_prebuild_cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | RECYCLEDIR="./build.$GLOBAL_BASEARCH/recycle" 8 | 9 | statusprint "Pre-build cleanup.." 10 | 11 | statusprint "Removing temporary setup files.." 12 | sudo rm ./build.$GLOBAL_BASEARCH/chroot/{chroot_exec.retcode,container_spawn.sh,chroot_exec.sh} 2>/dev/null 13 | 14 | statusprint "Removing packages which are not essential anymore.." 15 | if [ ${GLOBAL_RELEASESIZE} -le 1 ] 16 | then 17 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'export DEBIAN_FRONTEND=noninteractive; 18 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c;' 19 | fi 20 | 21 | if [ ${GLOBAL_RELEASESIZE} -le 2 ] 22 | then 23 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'export DEBIAN_FRONTEND=noninteractive; 24 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 25 | apt-fast --yes purge plymouth python-samba samba-common samba-common-bin samba-libs' 26 | fi 27 | 28 | chroot_exec build.$GLOBAL_BASEARCH/chroot 'export DEBIAN_FRONTEND=noninteractive; 29 | aria2c(){ /usr/bin/aria2c --console-log-level=warn "$@";}; export -f aria2c; 30 | apt-fast --yes install deborphan 31 | while true; do 32 | ORPHANLIST=$(deborphan --guess-all | grep -vE "linux-modules-extra-.*|python-fusepy" ) 33 | if [ -n "$ORPHANLIST" ]; then 34 | apt-fast --yes purge $ORPHANLIST 35 | else 36 | break 37 | fi 38 | done 39 | apt-fast --yes purge deborphan' 40 | 41 | statusprint "Removing .pyc files cache.." 42 | sudo find ./build.$GLOBAL_BASEARCH/chroot/usr/share/python* ./build.$GLOBAL_BASEARCH/chroot/usr/lib/python* -name "*.pyc" -delete 2>&- 43 | 44 | if [ ${GLOBAL_RELEASESIZE} -le 1 ] 45 | then 46 | mkdir "$RECYCLEDIR" 2>&- 47 | 48 | statusprint "Moving non-essential firmware files (sound,video,tuners,etc) to recycle dir.." 49 | DDIR="$RECYCLEDIR/lib/firmware" 50 | mkdir -p "$DDIR" 2>&- 51 | SDIR="./build.$GLOBAL_BASEARCH/chroot/lib/firmware" 52 | sudo mv "$SDIR/ess/" "$SDIR/korg/" "$SDIR/yamaha/" "$SDIR/ttusb-budget/" "$SDIR/keyspan/" "$SDIR/emi26/" "$SDIR/emi62/" "$SDIR/ti_3410.fw" "$SDIR/ti_5052.fw" "$SDIR/whiteheat"* "$SDIR/cpia2/" "$SDIR/vicam/" "$SDIR/dsp56k/" "$SDIR/sb16/" "$SDIR/ql2"* "$SDIR/v4l-"* "$SDIR/dvb-"* "$SDIR/yam/" "$SDIR/av7110/" "$SDIR/matrox/" "$SDIR/r128/" "$SDIR/radeon/" "$SDIR/f2255usb.bin" "$SDIR/go7007/" "$SDIR/s2250"* "$SDIR/lgs8g75.fw" "$SDIR/ueagle-atm" "$SDIR/tlg2300_firmware.bin" "$SDIR/ar3k/" "$SDIR/s5p-mfc"* "$SDIR/ea/" "$SDIR/asihpi/" "$DDIR/" 2>&- 53 | 54 | 55 | statusprint "Moving non-essential kernel drivers (gpu,media,etc) to recycle dir.." 56 | KERNELVER=`ls -1 ./build.$GLOBAL_BASEARCH/chroot/lib/modules/| head -n1` #shall be just one kernel directory anyway 57 | DDIR="$RECYCLEDIR/lib/modules/$KERNELVER/kernel/drivers" 58 | mkdir -p "$DDIR" 2>&- 59 | SDIR="./build.$GLOBAL_BASEARCH/chroot/lib/modules/$KERNELVER/kernel/drivers" 60 | sudo mv "$SDIR/media" "$SDIR/gpu" "$DDIR/" 2>&- 61 | 62 | 63 | statusprint "Moving (arguably) ambiguous files to recycle dir.." 64 | #DDIR="$RECYCLEDIR/var/lib/dpkg/info"; mkdir -p "$DDIR" 2>&-; 65 | #sudo mv ./build.$GLOBAL_BASEARCH/chroot/var/lib/dpkg/info/* "$DDIR/" 2>&- 66 | 67 | DDIR="$RECYCLEDIR/var/cache"; mkdir -p "$DDIR" 2>&-; 68 | sudo mv ./build.$GLOBAL_BASEARCH/chroot/var/cache/* "$DDIR/" 2>&- 69 | 70 | DDIR="$RECYCLEDIR/usr/share/X11"; mkdir -p "$DDIR" 2>&-; 71 | sudo mv ./build.$GLOBAL_BASEARCH/chroot/usr/share/X11/* "$DDIR/" 2>&- 72 | 73 | DDIR="$RECYCLEDIR/usr/share/grub"; mkdir -p "$DDIR" 2>&-; 74 | sudo mv ./build.$GLOBAL_BASEARCH/chroot/usr/share/grub/* "$DDIR/" 2>&- 75 | 76 | DDIR="$RECYCLEDIR/usr/share/locale"; mkdir -p "$DDIR" 2>&-; 77 | ls -Fd1 ./build.$GLOBAL_BASEARCH/chroot/usr/share/locale/*| grep "/$"| grep -v "./en/"| while read d; do sudo mv "$d" "$DDIR/" 2>&-; done 78 | 79 | fi 80 | 81 | statusprint "Removing chroot /tmp files.." 82 | sudo rm -rf ./build.$GLOBAL_BASEARCH/chroot/tmp/* 83 | 84 | sudo rm -f ./build.$GLOBAL_BASEARCH/chroot/root/.bashrc ./build.$GLOBAL_BASEARCH/chroot/home/user/.bashrc 85 | 86 | exit 0; 87 | -------------------------------------------------------------------------------- /scripts/image_prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Recreating directories for the new image.." 8 | rm -rf ./build.$GLOBAL_BASEARCH/image/ 2>&- 9 | mkdir -p ./build.$GLOBAL_BASEARCH/image/ 10 | 11 | if [ "$GLOBAL_TARGET" = "iso" ]; then 12 | mkdir -p ./build.$GLOBAL_BASEARCH/image/{casper,boot} 13 | 14 | statusprint "Copying bootloader files.." 15 | sudo cp ./build.$GLOBAL_BASEARCH/chroot/boot/vmlinuz-*-generic ./build.$GLOBAL_BASEARCH/image/casper/vmlinuz && 16 | sudo cp ./build.$GLOBAL_BASEARCH/chroot/boot/initrd.img-*-generic ./build.$GLOBAL_BASEARCH/image/casper/initrd.img && 17 | install_required_package memtest86+ && 18 | sudo cp /boot/memtest86+.bin ./build.$GLOBAL_BASEARCH/image/casper/memtest 19 | 20 | statusprint "Creating manifest.." 21 | sudo chroot ./build.$GLOBAL_BASEARCH/chroot dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee ./build.$GLOBAL_BASEARCH/image/casper/filesystem.manifest >/dev/null 22 | sudo cp -v ./build.$GLOBAL_BASEARCH/image/casper/filesystem.manifest ./build.$GLOBAL_BASEARCH/image/casper/filesystem.manifest-desktop 23 | REMOVE='ubiquity ubiquity-frontend-gtk ubiquity-frontend-kde casper live-initramfs user-setup discover1 xresprobe os-prober libdebian-installer4' 24 | for i in $REMOVE 25 | do 26 | sudo sed -i "/${i}/d" ./build.$GLOBAL_BASEARCH/image/casper/filesystem.manifest-desktop 27 | done 28 | 29 | 30 | statusprint "Setting disk properties.." 31 | ( echo "#define DISKNAME Ubuntu Remix 32 | #define TYPE binary 33 | #define TYPEbinary 1 34 | #define ARCH $GLOBAL_BASEARCH"; 35 | if [ "$GLOBAL_BASEARCH" == "i386" ] 36 | then 37 | echo "#define ARCHi386 1" 38 | else 39 | echo "#define ARCHi386 0" 40 | fi 41 | 42 | echo "#define DISKNUM 1 43 | #define DISKNUM1 1 44 | #define TOTALNUM 0 45 | #define TOTALNUM0 1" ) > ./build.$GLOBAL_BASEARCH/image/README.diskdefines 46 | 47 | statusprint "Making the image recognized as Ubuntu disk.." 48 | touch ./build.$GLOBAL_BASEARCH/image/ubuntu 49 | mkdir ./build.$GLOBAL_BASEARCH/image/.disk 50 | cd ./build.$GLOBAL_BASEARCH/image/.disk 51 | echo "live" > cd_type 52 | echo "Ubuntu Remix 22.04 \"$PROJECTCAPNAME\"" > info # Update version number to match your OS version 53 | echo "A project by Vitaly Kamluk, Kaspersky Lab (www.kaspersky.com)." > release_notes_url 54 | cd ../../../ 55 | 56 | statusprint "Copying boot configuration from resources.." 57 | cp -r ./resources/boot/ ./build.$GLOBAL_BASEARCH/image/ 58 | sudo rm ./build.$GLOBAL_BASEARCH/image/boot/grub/grub.cfg.doublesword 59 | sudo mv ./build.$GLOBAL_BASEARCH/image/boot/grub/grub.cfg.casper ./build.$GLOBAL_BASEARCH/image/boot/grub/grub.cfg 60 | sed -i "s//${PROJECTNAME}/g; s//${PROJECTCAPNAME}/g; s//${PROJECTSHORTNAME}/g; s//${CONTAINERUSERNAME}/g; s//${PROJECTRELEASE}/g;" ./build.$GLOBAL_BASEARCH/image/boot/grub/grub.cfg 61 | 62 | statusprint "Altering boot splash image.." 63 | install_required_package imagemagick 64 | convert -quiet ./build.$GLOBAL_BASEARCH/image/boot/grub/theme/background.jpg +repage ./build.$GLOBAL_BASEARCH/image/boot/grub/theme/background.tiff 65 | convert ./build.$GLOBAL_BASEARCH/image/boot/grub/theme/background.tiff \( -clone 0 -fill srgb\(255,255,255\) -colorize 100% -modulate 100,100,100 \) \( -clone 0 -blur 0x1 -fuzz 10% -fill none -draw "matte 580,630 floodfill" -channel rgba -fill black +opaque none -fill white -opaque none -blur 0x8 -auto-level -evaluate multiply 1 \) -compose over -composite -pointsize 22 -font /usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf -fill rgba\(255,255,255,0.8\) -annotate +750+580 22.04 ./build.$GLOBAL_BASEARCH/image/boot/grub/theme/background.jpg 66 | rm ./build.$GLOBAL_BASEARCH/image/boot/grub/theme/background.tiff 67 | 68 | statusprint "Preparing font for grub bootloader.." 69 | install_required_package fonts-dejavu-core 70 | install_required_package grub-common 71 | FONTNAME="DejaVuSansMono.ttf" 72 | FONTSIZE=24 73 | FONTPATH="/usr/share/fonts/truetype/dejavu/$FONTNAME" 74 | statusprint "Generating grub font from $FONTNAME.." 75 | if [ ! -f "$FONTPATH" ] 76 | then 77 | statusprint "Couldn't find required font at $FONTPATH. Aborting.." 78 | exit 1; 79 | fi 80 | grub-mkfont -s $FONTSIZE -o ./build.$GLOBAL_BASEARCH/image/boot/grub/font.pf2 "$FONTPATH" 81 | else 82 | statusprint "Installing grub package.." 83 | chroot_exec build.$GLOBAL_BASEARCH/chroot "export DEBIAN_FRONTEND=noninteractive; apt-fast --yes install grub-efi" 84 | statusprint "Preparing persistence mount directories.." 85 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/persistence/{host,container}/overlay/{work,upper} 86 | sudo mkdir -p ./build.$GLOBAL_BASEARCH/chroot/rofs 87 | 88 | statusprint "Copying boot configuration from resources.." 89 | sudo cp -rv ./resources/boot/* ./build.$GLOBAL_BASEARCH/chroot/boot/ 90 | sudo rm ./build.$GLOBAL_BASEARCH/chroot/boot/grub/grub.cfg.casper 91 | sudo mv ./build.$GLOBAL_BASEARCH/chroot/boot/grub/grub.cfg.doublesword ./build.$GLOBAL_BASEARCH/chroot/boot/grub/grub.cfg 92 | sudo sed -i "s//${PROJECTNAME}/g; s//${PROJECTCAPNAME}/g; s//${PROJECTSHORTNAME}/g; s//${CONTAINERUSERNAME}/g; s//${PROJECTRELEASE}/g;" ./build.$GLOBAL_BASEARCH/chroot/boot/grub/grub.cfg 93 | 94 | statusprint "Altering boot splash image.." 95 | install_required_package imagemagick 96 | sudo convert -quiet ./build.$GLOBAL_BASEARCH/chroot/boot/grub/theme/background.jpg +repage ./build.$GLOBAL_BASEARCH/chroot/boot/grub/theme/background.tiff 97 | sudo convert ./build.$GLOBAL_BASEARCH/chroot/boot/grub/theme/background.tiff \( -clone 0 -fill srgb\(255,255,255\) -colorize 100% -modulate 100,100,100 \) \( -clone 0 -blur 0x1 -fuzz 10% -fill none -draw "matte 580,630 floodfill" -channel rgba -fill black +opaque none -fill white -opaque none -blur 0x8 -auto-level -evaluate multiply 1 \) -compose over -composite -pointsize 22 -font /usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf -fill rgba\(255,255,255,0.8\) -annotate +750+580 22.04 ./build.$GLOBAL_BASEARCH/chroot/boot/grub/theme/background.jpg 98 | sudo rm ./build.$GLOBAL_BASEARCH/chroot/boot/grub/theme/background.tiff 99 | 100 | statusprint "Preparing font for grub bootloader.." 101 | install_required_package fonts-dejavu-core 102 | install_required_package grub-common 103 | FONTNAME="DejaVuSansMono.ttf" 104 | FONTSIZE=24 105 | FONTPATH="/usr/share/fonts/truetype/dejavu/$FONTNAME" 106 | statusprint "Generating grub font from $FONTNAME.." 107 | if [ ! -f "$FONTPATH" ] 108 | then 109 | statusprint "Couldn't find required font at $FONTPATH. Aborting.." 110 | exit 1; 111 | fi 112 | sudo grub-mkfont -s $FONTSIZE -o ./build.$GLOBAL_BASEARCH/chroot/boot/grub/font.pf2 "$FONTPATH" 113 | statusprint "Adding overlay module.." 114 | echo "overlay" | sudo tee -a ./build.$GLOBAL_BASEARCH/chroot/etc/initramfs-tools/modules 115 | chroot_exec ./build.$GLOBAL_BASEARCH/chroot 'update-initramfs -u' 116 | fi 117 | 118 | exit 0; 119 | -------------------------------------------------------------------------------- /scripts/initrd_doublesword.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | UNPACKED_INITRD=0 8 | if [ ! -d "./build.$GLOBAL_BASEARCH/initrd" ] 9 | then 10 | statusprint "Unpacking initrd.." 11 | scripts/initrd_unpack.sh 12 | UNPACKED_INITRD=1 13 | fi 14 | 15 | if [ "$GLOBAL_TARGET" != "iso" ] 16 | then 17 | statusprint "Installing doublesword init script.." 18 | sudo cp -v ./resources/initrd/scripts/doublesword ./build.$GLOBAL_BASEARCH/initrd/main/scripts/ 19 | fi 20 | 21 | if [ $UNPACKED_INITRD -eq 1 ] 22 | then 23 | statusprint "Packing initrd.." 24 | scripts/initrd_pack.sh 25 | UNPACKED_INITRD=0 26 | fi 27 | 28 | exit 0; 29 | -------------------------------------------------------------------------------- /scripts/initrd_findlivefs_fix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | UNPACKED_INITRD=0 8 | if [ ! -d "./build.$GLOBAL_BASEARCH/initrd" ] 9 | then 10 | statusprint "Unpacking initrd.." 11 | scripts/initrd_unpack.sh 12 | UNPACKED_INITRD=1 13 | fi 14 | 15 | if [ $GLOBAL_TARGET = "iso" ]; then 16 | statusprint "Fixing casper find_livefs method.." 17 | if [ -f "./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper" ] 18 | then 19 | if ! grep -q "${PROJECTNAME}-${GLOBAL_BUILDID}" ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper 20 | then 21 | sudo sed -i 's/^\( *\)\(mount -t ${fstype} -o ro,noatime "${devname}" $mountpoint || return 1\)/\1blkid "${devname}" | grep -q "'"${PROJECTNAME}-${GLOBAL_BUILDID}"'" || return 1\n\1\2/' ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper 22 | fi 23 | fi 24 | fi 25 | 26 | if [ $UNPACKED_INITRD -eq 1 ] 27 | then 28 | statusprint "Packing initrd.." 29 | scripts/initrd_pack.sh 30 | UNPACKED_INITRD=0 31 | fi 32 | 33 | exit 0; 34 | -------------------------------------------------------------------------------- /scripts/initrd_integritycheck_fix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | UNPACKED_INITRD=0 8 | if [ ! -d "./build.$GLOBAL_BASEARCH/initrd" ] 9 | then 10 | statusprint "Unpacking initrd.." 11 | scripts/initrd_unpack.sh 12 | UNPACKED_INITRD=1 13 | fi 14 | 15 | 16 | if [ $GLOBAL_TARGET = "iso" ]; then 17 | statusprint "Replacing casper-md5check with own.." 18 | #currently casper-md5check doesn't work without plymouth 19 | if [ ! -f "./build.$GLOBAL_BASEARCH/initrd/main/bin/casper-md5check.dist" ] 20 | then 21 | sudo mv ./build.$GLOBAL_BASEARCH/initrd/main/bin/casper-md5check ./build.$GLOBAL_BASEARCH/initrd/main/bin/casper-md5check.dist 22 | fi 23 | sudo cp -v ./build.$GLOBAL_BASEARCH/chroot/usr/bin/md5sum ./build.$GLOBAL_BASEARCH/initrd/main/bin/md5sum 24 | sudo cp -v resources/casper/bin/casper-md5check ./build.$GLOBAL_BASEARCH/initrd/main/bin/casper-md5check 25 | sudo chmod +x ./build.$GLOBAL_BASEARCH/initrd/main/bin/casper-md5check 26 | 27 | statusprint "Fixing I/O redirection for the script.." 28 | sudo sed -i 's,\(casper-md5check .*md5sum.txt \)< /dev/tty8 > /dev/tty8,\1,' ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper-bottom/01integrity_check 29 | fi 30 | 31 | 32 | if [ $UNPACKED_INITRD -eq 1 ] 33 | then 34 | statusprint "Packing initrd.." 35 | scripts/initrd_pack.sh 36 | UNPACKED_INITRD=0 37 | fi 38 | 39 | 40 | exit 0; 41 | -------------------------------------------------------------------------------- /scripts/initrd_pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Compressing initrd.." 8 | packinitrd 9 | -------------------------------------------------------------------------------- /scripts/initrd_unpack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Unpacking initrd.." 8 | unpackinitrd 9 | -------------------------------------------------------------------------------- /scripts/initrd_writeblocker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | UNPACKED_INITRD=0 8 | if [ ! -d "./build.$GLOBAL_BASEARCH/initrd" ] 9 | then 10 | statusprint "Unpacking initrd.." 11 | scripts/initrd_unpack.sh 12 | UNPACKED_INITRD=1 13 | fi 14 | 15 | statusprint "Installing write-blocker.." 16 | sudo cp -v ./resources/usr/sbin/{wrtblk,wrtblk-disable,wrtblk-ioerr} ./build.$GLOBAL_BASEARCH/chroot/usr/sbin/ 17 | 18 | if [ $GLOBAL_TARGET = "iso" ]; then 19 | statusprint "Installing write-blocker to casper system.." 20 | sudo cp -v ./resources/initrd/scripts/casper-bottom/01wrtblk_all ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper-bottom/ 21 | if ! grep "/scripts/casper-bottom/01wrtblk_all" ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper-bottom/ORDER; then 22 | sudo mv ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper-bottom/ORDER ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper-bottom/ORDER.old && 23 | ( echo -e '/scripts/casper-bottom/01wrtblk_all "$@"\n[ -e /conf/param.conf ] && . /conf/param.conf'; cat ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper-bottom/ORDER.old ) | sudo tee ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper-bottom/ORDER > /dev/null && 24 | sudo rm ./build.$GLOBAL_BASEARCH/initrd/main/scripts/casper-bottom/ORDER.old 25 | fi 26 | else 27 | statusprint "Installing write-blocker to doublesword system.." 28 | [ ! -d "./build.$GLOBAL_BASEARCH/initrd/main/scripts/doublesword-bottom/" ] && sudo mkdir -p ./build.$GLOBAL_BASEARCH/initrd/main/scripts/doublesword-bottom/ 29 | sudo cp -v ./resources/initrd/scripts/doublesword-bottom/01wrtblk_all ./build.$GLOBAL_BASEARCH/initrd/main/scripts/doublesword-bottom/ 30 | fi 31 | 32 | if [ $UNPACKED_INITRD -eq 1 ] 33 | then 34 | statusprint "Packing initrd.." 35 | scripts/initrd_pack.sh 36 | UNPACKED_INITRD=0 37 | fi 38 | 39 | 40 | exit 0; 41 | -------------------------------------------------------------------------------- /scripts/interrupted_clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | PROJECTROOT=$PWD 8 | 9 | ( 10 | chroot_unmount_cache "$PWD/build.$GLOBAL_BASEARCH/chroot" 11 | chroot_unmount_fs "$PWD/build.$GLOBAL_BASEARCH/chroot" 12 | ) 2>&1 > /dev/null 13 | -------------------------------------------------------------------------------- /scripts/nspawn_container_spawn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -z "$CHROOTDIR" ] 3 | then 4 | echo "Specify CHROOTDIR environment variable." 5 | exit 1 6 | else 7 | systemd-nspawn --bind=/sys/fs/cgroup --bind=/dev/fuse --property DeviceAllow='/dev/fuse rwm' -D "$CHROOTDIR" /sbin/init 8 | fi 9 | -------------------------------------------------------------------------------- /scripts/nspawn_enter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | CHROOTDIR="$PWD/build.$GLOBAL_BASEARCH/chroot" 8 | export CHROOTDIR 9 | nspawn_exec build.$GLOBAL_BASEARCH/chroot "/bin/bash -i" 1 10 | -------------------------------------------------------------------------------- /scripts/nspawn_session.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect 2 | set timeout -1 3 | 4 | send_user "Starting systemd-nspawn container for the chroot..\n" 5 | send_user "Container start script: $::env(CONTAINER_SPAWN_SCRIPT)\n" 6 | log_user 0 7 | spawn "$::env(CONTAINER_SPAWN_SCRIPT)" 8 | 9 | expect "bitscout login:" 10 | send "root\n" 11 | expect "root@bitscout:~#" 12 | 13 | log_user 1 14 | send "sh /chroot_exec.sh\n" 15 | 16 | expect "root@bitscout:~#" 17 | log_user 0 18 | send "echo $? > /chroot_exec.retcode\n" 19 | 20 | catch { 21 | if { $::env(INTERACTIVE) == 1 } { 22 | log_user 1 23 | send_user "\nEntering interactive shell. Please Ctrl-Z when finished.\n"; 24 | interact \032 return; 25 | } 26 | } 27 | 28 | log_user 0 29 | catch { 30 | send "\n" 31 | expect "root@bitscout:~#" 32 | send "poweroff\n" 33 | expect "Container .* has been shut down." 34 | } 35 | log_user 1 36 | send_user "\n" 37 | -------------------------------------------------------------------------------- /scripts/skeleton.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | #Add code here. Exit with non-zero in case of error. 8 | 9 | exit 0; 10 | -------------------------------------------------------------------------------- /scripts/submodules_fetch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | statusprint "Updating submodules.." && 8 | install_required_package git && 9 | git submodule init && 10 | git submodule update && 11 | 12 | exit 0; 13 | -------------------------------------------------------------------------------- /scripts/welcome.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Bitscout project 3 | #Copyright Kaspersky Lab 4 | 5 | . ./scripts/functions 6 | 7 | BUILDCONFPATH="config/${PROJECTNAME}-build.conf" 8 | CONFIGNAME={"GLOBAL_RELEASESIZE"} 9 | 10 | statusprint "Welcome to $PROJECTCAPNAME builder!" 11 | HOSTUNAME=$(uname -srvi) 12 | HOSTDIST=$(lsb_release -idrc 2>&-) 13 | COMMIT=$(git log -1 2>&-|head -n1 | cut -d' ' -f2) 14 | statusprint "Host OS info: $HOSTUNAME\n$HOSTDIST\nBuild Target:\t$PROJECTCAPNAME $PROJECTRELEASE\nUsing git commit:\t$COMMIT\n" 15 | 16 | validate_hostaddr() 17 | { 18 | if [ -n "$1" ] 19 | then 20 | echo "$1" | grep -qE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$|^[^.-][a-z0-9_.-]*[^.-]$' 21 | return $? 22 | else 23 | return 1 24 | fi 25 | } 26 | 27 | validate_vpntype() 28 | { 29 | echo "$1" | grep -qE "^openvpn$|^wireguard$|^tor$" 30 | return $? 31 | } 32 | 33 | validate_vpnprotocol() 34 | { 35 | echo "$1" | grep -qE "^udp$|^tcp$|^wireguard$|^tor$" 36 | return $? 37 | } 38 | 39 | validate_portnum() 40 | { 41 | if [ -n "$1" ] 42 | then 43 | test $1 -gt 0 -a $1 -lt 65536; 44 | return $? 45 | else 46 | return 1 47 | fi 48 | } 49 | 50 | validate_releasesize() 51 | { 52 | if [ -n "$1" ] 53 | then 54 | test $1 -ge 1 -a $1 -le 3; 55 | return $? 56 | else 57 | return 1; 58 | fi 59 | } 60 | 61 | validate_target() 62 | { 63 | case "$1" in 64 | "iso" | "raw" | "qcow2" | "vmdk") return 0;; 65 | *) return 1; 66 | esac 67 | } 68 | 69 | validate_ptabletype() 70 | { 71 | case "$1" in 72 | "msdos" | "gpt" | "hybrid") return 0;; 73 | *) return 1; 74 | esac 75 | } 76 | 77 | validate_automount() 78 | { 79 | case "$1" in 80 | "off" | "all") return 0;; 81 | *) return 1; 82 | esac 83 | } 84 | 85 | msg_new_config_opt="\nSome new options were not found in your config file, please answer the following question(s)\nand it will be appended to your existing config file located in config/$PROJECTNAME-build.conf.\n" 86 | 87 | if ! [ -f "$BUILDCONFPATH" ] 88 | then 89 | statusprint "Please answer some questions or place a build config in config/$PROJECTNAME-build.conf." 90 | PRINTOPTIONS=n statusprint "Proceed to interactive settings? [Y/n]: " 91 | read choice 92 | if [ ! -z "$choice" -a ! "${choice^}" = "Y" ] 93 | then 94 | echo "Build process aborted." 95 | exit 1 96 | else 97 | mkdir config 2>&- 98 | fi 99 | else 100 | . "$BUILDCONFPATH" 101 | fi 102 | 103 | target=${GLOBAL_TARGET:-iso} 104 | persistsize=${GLOBAL_PERSISTSIZE:-1GiB} 105 | lanaccess=${GLOBAL_LANACCESS_ENABLED:-0} 106 | hostssh=${GLOBAL_HOSTSSH_ENABLED:-0} 107 | ptabletype=${GLOBAL_PARTITION_TABLE:-hybrid} 108 | automount=${GLOBAL_AUTOMOUNT:-off} 109 | buildarch="amd64" 110 | 111 | if [ -z "$GLOBAL_RELEASESIZE" ] 112 | then 113 | if [ -f "$BUILDCONFPATH" ]; then PRINTOPTIONS=n statusprint "$msg_new_config_opt"; fi 114 | releasesize="" 115 | while ! validate_releasesize "$releasesize" 116 | do 117 | PRINTOPTIONS=n statusprint "\n${PROJECTNAME} builds vary in size.\nPlease choose one you prefer:\n 1. compact - minimal size, less tools and drivers.\n 2. normal - some forensic tools, all drivers, etc.\n 3. maximal - includes maximum forensic tools and frameworks.\nYour choice (1|2|3): " 118 | read releasesize 119 | if ! validate_releasesize "$releasesize" 120 | then 121 | releasesize=2 122 | statusprint "Auto-selected normal build size." 123 | fi 124 | done 125 | else 126 | releasesize=$GLOBAL_RELEASESIZE 127 | fi 128 | 129 | #Override to default generic kernel: 130 | GLOBAL_CUSTOMKERNEL=0 131 | customkernel=0 132 | if [ -z "$GLOBAL_CUSTOMKERNEL" ] 133 | then 134 | if [ -f "$BUILDCONFPATH" ]; then PRINTOPTIONS=n statusprint "$msg_new_config_opt"; fi 135 | customkernel="0" 136 | PRINTOPTIONS=n statusprint "\nWould you like to build Linux kernel from source (may take hours)? [y/N]: " 137 | read choice 138 | if [ -z "$choice" -o "${choice^}" = "N" ] 139 | then 140 | customkernel="0" 141 | else 142 | customkernel="1" 143 | fi 144 | else 145 | customkernel=$GLOBAL_CUSTOMKERNEL 146 | fi 147 | 148 | if [ -z "$GLOBAL_VPNTYPE" ] 149 | then 150 | if [ -z "$GLOBAL_VPNSERVER" ] || [ -z "$GLOBAL_VPNPROTOCOL" ] || [ -z "$GLOBAL_VPNPORT" ] 151 | then 152 | if [ -f "$BUILDCONFPATH" ]; then PRINTOPTIONS=n statusprint "$msg_new_config_opt"; fi 153 | vpntype="" 154 | vpnhost="" 155 | vpnprotocol="" 156 | vpnport="" 157 | if [ "$GLOBAL_VPNTYPE" != 'none' ] 158 | then 159 | while ! validate_vpntype "$vpntype" && ! validate_hostaddr "$vpnhost" && ! validate_vpnprotocol "$vpnprotocol" && ! validate_portnum "$vpnport" 160 | do 161 | statusprint "\nTo use ${PROJECTNAME} over the internet you will likely need a VPN server." 162 | PRINTOPTIONS=n statusprint "Just enter your protocol/host/port and we generate a VPN config template for you. You can always change it later.\nExamples:\n openvpn-udp://127.0.0.1:1234\n openvpn-tcp://myvpnserver:8080\n wireguard://myvpnserver:2600\n tor\nYour input [connection string or for none]: " 163 | read vpnuri 164 | [ "$vpnuri" == "tor" ] && vpntype="tor" && break; 165 | if [ ! -z "$vpnuri" ] 166 | then 167 | mapfile -t VPNCFG < <( echo "$vpnuri" | sed 's#^\(openvpn-udp\|openvpn-tcp\|wireguard\)://\([a-zA-Z0-9_.-]*\):\([0-9]\{1,5\}\)$#\2\n\1\n\3#' ) 168 | vpntype=${VPNCFG[1]%%-*} 169 | vpnhost="${VPNCFG[0]}" 170 | vpnprotocol="${VPNCFG[1]##*-}" 171 | vpnport="${VPNCFG[2]}" 172 | 173 | if ! validate_vpntype "$vpntype" && ! validate_hostaddr "$vpnhost" && ! validate_vpnprotocol "$vpnprotocol" && ! validate_portnum "$vpnport" 174 | then 175 | statusprint "Invalid input data format. Please try again.." 176 | fi 177 | 178 | else 179 | vpntype="none" 180 | break; 181 | fi 182 | done 183 | else 184 | vpntype="none" 185 | GLOBAL_VPNSERVER="none" 186 | fi 187 | fi 188 | else 189 | vpntype=$GLOBAL_VPNTYPE 190 | vpnhost=$GLOBAL_VPNSERVER 191 | vpnprotocol=$GLOBAL_VPNPROTOCOL 192 | vpnport=$GLOBAL_VPNPORT 193 | fi 194 | 195 | sysloghost="none" 196 | 197 | if [ -z "$GLOBAL_BUILDID" ] 198 | then 199 | if [ -f "$BUILDCONFPATH" ]; then PRINTOPTIONS=n statusprint "$msg_new_config_opt"; fi 200 | buildid=`dd if=/dev/urandom bs=1 count=4 2>&- | xxd -pos` 201 | if [ -n "$GLOBAL_BUILDID" ] && [ -f "$BUILDCONFPATH" ]; then 202 | echo "GLOBAL_BUILDID=\"$buildid\"" >> "$BUILDCONFPATH" 203 | fi 204 | else 205 | buildid=$GLOBAL_BUILDID 206 | fi 207 | 208 | if [ -z "$CRYPTOKEYSIZE" ] 209 | then 210 | cryptokeysize=2048 211 | else 212 | cryptokeysize=$CRYPTOKEYSIZE 213 | fi 214 | 215 | GLOBAL_BASEARCH=amd64 216 | 217 | EXTRA_CONFIG=0 218 | PRINTOPTIONS=n statusprint "Basic configuration complete. Build/Stop/Extra-config extra config? [B/s/e]: " 219 | read choice 220 | 221 | statusprint "\nSaving basic configuration.." 222 | echo "GLOBAL_TARGET=\"$target\" #target to build: iso, raw, qcow2, vmdk 223 | GLOBAL_PARTITION_TABLE=\"$ptabletype\" #partition table type: msdos,gpt,hybrid 224 | GLOBAL_PERSISTSIZE=\"$persistsize\" #persistence partition size for non-iso builds 225 | GLOBAL_RELEASESIZE=\"$releasesize\" 226 | GLOBAL_HOSTSSH_ENABLED=$hostssh #set to 1 to enable direct SSH access to the host system (port 23) 227 | GLOBAL_LANACCESS_ENABLED=$lanaccess #set to 1 to enable access from LAN after boot 228 | GLOBAL_VPNTYPE=\"$vpntype\" 229 | GLOBAL_VPNSERVER=\"$vpnhost\" 230 | GLOBAL_VPNPROTOCOL=\"$vpnprotocol\" 231 | GLOBAL_VPNPORT=\"$vpnport\" 232 | GLOBAL_SYSLOGSERVER=\"$sysloghost\" 233 | GLOBAL_BUILDID=\"$buildid\" 234 | GLOBAL_CUSTOMKERNEL=\"$customkernel\" 235 | GLOBAL_BASEARCH=\"$buildarch\" #amd64 (64bit) or i386 (32-bit) 236 | GLOBAL_AUTOMOUNT=\"$automount\" #map and mount all available common filesystems: off or all 237 | CRYPTOKEYSIZE=$cryptokeysize" > "$BUILDCONFPATH" 238 | 239 | if [ -z "$choice" -o "${choice^}" = "B" ] 240 | then 241 | exit 0; 242 | else 243 | if [ -z "$choice" -o "${choice^}" = "S" ]; then exit 1; fi; 244 | if [ -z "$choice" -o "${choice^}" = "E" ]; then EXTRA_CONFIG=1; fi; 245 | fi 246 | 247 | 248 | target="" 249 | while ! validate_target "$target" 250 | do 251 | PRINTOPTIONS=n statusprint "\n${PROJECTNAME} may build different targets.\nPlease choose your preference:\n iso - bootable LiveCD ISO image.\n raw - raw disk image with preinstalled system\n qcow2 - qemu/libvirt disk image with preinstalled system\n vmdk - VMware Workstation or VirtualBox disk image with preinstalled system\nYour choice [default=iso]: " 252 | read target 253 | if [ -z "$target" ]; then target="iso"; fi; 254 | if ! validate_target "$target" 255 | then 256 | statusprint "Invalid input. Please try again.." 257 | continue 258 | fi 259 | done 260 | 261 | if [ $target != 'iso' ]; then 262 | ptabletype="" 263 | while ! validate_ptabletype "$ptabletype" 264 | do 265 | PRINTOPTIONS=n statusprint "\nChoose partition table type preference:\n msdos - used for MBR bootloaders (also used for the cloud instances).\n gpt - modern EFI systems\n hybrid - msdos+gpt on one disk, should be compatible with old and new systems\nYour choice [default=hybrid]: " 266 | read ptabletype 267 | if [ -z "$ptabletype" ]; then ptabletype="hybrid"; fi; 268 | if ! validate_ptabletype "$ptabletype" 269 | then 270 | statusprint "Invalid input. Please try again.." 271 | continue 272 | fi 273 | done 274 | fi 275 | 276 | automount="" 277 | while ! validate_automount "$automount" 278 | do 279 | PRINTOPTIONS=n statusprint "\n${PROJECTNAME} may automatically discover, map and readonly-mount disk partitions to the expert container. \nPlease choose your preference:\n off - disable automount\n all - enable automount of all disks\nYour choice [default=off]: " 280 | read automount 281 | if [ -z "$automount" ]; then automount="off"; fi; 282 | if ! validate_automount "$automount" 283 | then 284 | statusprint "Invalid input. Please try again.." 285 | continue 286 | fi 287 | done 288 | 289 | if [ -z "$GLOBAL_SYSLOGSERVER" ] 290 | then 291 | if [ -f "$BUILDCONFPATH" ]; then PRINTOPTIONS=n statusprint "$msg_new_config_opt"; fi 292 | sysloghost="" 293 | while ! validate_hostaddr "$sysloghost" 294 | do 295 | statusprint "\nA remote syslog server can keep your shell history. To continue without a syslog server simply press Enter." 296 | PRINTOPTIONS=n statusprint "Your input [syslog-host|]: " 297 | read sysloghost 298 | if [ "$sysloghost" = "" ] 299 | then 300 | sysloghost="none" 301 | statusprint "Remote syslog support disabled." 302 | break 303 | fi 304 | if ! validate_hostaddr "$sysloghost" 305 | then 306 | statusprint "Invalid input data format. Please try again.." 307 | fi 308 | done 309 | else 310 | sysloghost=$GLOBAL_SYSLOGSERVER 311 | fi 312 | 313 | statusprint "\nUpdating basic configuration.." 314 | echo "GLOBAL_TARGET=\"$target\" #target to build: iso, raw, qcow2, vmdk 315 | GLOBAL_PARTITION_TABLE=\"$ptabletype\" #partition table type: msdos,gpt,hybrid 316 | GLOBAL_PERSISTSIZE=\"$persistsize\" #persistence partition size for non-iso builds 317 | GLOBAL_RELEASESIZE=\"$releasesize\" 318 | GLOBAL_HOSTSSH_ENABLED=$hostssh #set to 1 to enable direct SSH access to the host system (port 23) 319 | GLOBAL_LANACCESS_ENABLED=$lanaccess #set to 1 to enable access from LAN after boot 320 | GLOBAL_VPNTYPE=\"$vpntype\" 321 | GLOBAL_VPNSERVER=\"$vpnhost\" 322 | GLOBAL_VPNPROTOCOL=\"$vpnprotocol\" 323 | GLOBAL_VPNPORT=\"$vpnport\" 324 | GLOBAL_SYSLOGSERVER=\"$sysloghost\" 325 | GLOBAL_BUILDID=\"$buildid\" 326 | GLOBAL_CUSTOMKERNEL=\"$customkernel\" 327 | GLOBAL_BASEARCH=\"$buildarch\" #amd64 (64bit) or i386 (32-bit) 328 | GLOBAL_AUTOMOUNT=\"$automount\" #map and mount all available common filesystems: off or all 329 | CRYPTOKEYSIZE=$cryptokeysize" > "$BUILDCONFPATH" 330 | 331 | 332 | 333 | EXTRA_CONFIG=0 334 | PRINTOPTIONS=n statusprint "New configuration saved. Proceed to the building phase? [Y/n]: " 335 | read choice 336 | if [ -z "$choice" -o "${choice^}" = "Y" ] 337 | then 338 | exit 0; 339 | else 340 | exit 1; 341 | fi 342 | 343 | exit 0; 344 | --------------------------------------------------------------------------------