├── .gitignore ├── .travis.yml ├── README.rst ├── bin ├── hubservices.py ├── login_script.sh ├── reboot-ask.py ├── secalerts.py ├── secalerts.sh ├── secupdates-ask.py ├── setpass.py └── simplehttpd.py ├── debian ├── .gitignore ├── compat ├── control ├── copyright ├── inithooks.docs ├── inithooks.install ├── postinst ├── rules └── source │ └── format ├── default ├── inithooks └── turnkey-init-fence ├── docs └── RelNotes-0.9.txt ├── everyboot.d └── 01empty ├── firstboot.d ├── 01ipconfig ├── 05autogrow-fs ├── 09hostname ├── 10randomize-cronapt ├── 10randomize-crontab ├── 10regen-sshkeys ├── 15regen-sslcert ├── 29sudoadmin ├── 29tagid ├── 30rootpass ├── 30turnkey-init-fence ├── 80hub-services ├── 85secalerts ├── 95secupdates ├── 97turnkey-init-fence-disable ├── 98finalize └── 99reboot ├── libinithooks ├── __init__.py ├── dialog_wrapper.py ├── inithooks_cache.py └── inithooks_log.py ├── rsyslog.d └── inithooks.conf ├── run ├── setup.py ├── systemd └── system │ ├── container-getty@1.service.d │ └── 10-container-getty-tkl-login.conf │ └── getty@tty1.service.d │ └── 10-getty-tkl-login.conf ├── tests ├── cert.key ├── cert.pem └── test-simplehttpd.sh ├── turnkey-init ├── turnkey-init-fence ├── htdocs │ ├── index.html │ ├── style.css │ └── turnkey-init-root.png └── turnkey-init-fence ├── turnkey-install-security-updates └── turnkey-sudoadmin /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__ 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: generic 3 | 4 | services: 5 | - docker 6 | 7 | script: 8 | - wget -O- http://travis.debian.net/script.sh | sh - 9 | 10 | branches: 11 | except: 12 | - /^debian\/\d/ 13 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | =================================================== 2 | System initialization, configuration and preseeding 3 | =================================================== 4 | 5 | Introduction 6 | ============ 7 | 8 | Before we expose a TurnKey system to a hostile Internet, we first need 9 | to initialize it. This will setup passwords, install security updates, 10 | and configure key applications settings. 11 | 12 | This initialization process can be interactive or non-interactive 13 | depending on what works best given where and how the system is deployed. 14 | 15 | Interactive system initialization 16 | --------------------------------- 17 | 18 | A configuration wizard shows a short sequence of simple text dialogs 19 | that look primitive but provide a quick step-by-step process that works 20 | anywhere and requires only the bare minimum of software dependencies - a 21 | big advantage for security sensitive applications: 22 | 23 | .. image:: https://www.turnkeylinux.org/files/images/docs/inithooks/turnkey-init-root.png 24 | :alt: root password dialog 25 | :width: 650px 26 | 27 | All software is potentially buggy but we can minimize the risk by 28 | intentionally favoring simplicity over fancy eye candy. 29 | 30 | The configuration dialogs run in one of two places: 31 | 32 | 1) **The boot console on first boot** on build types (e.g., ISO, VM, 33 | VMDK) where the real or virtual machine usually provides access to 34 | an interactive system console. 35 | 36 | 2) **The first administration login** on build types running on 37 | *headless* virtual machines (e.g., AWS marketplace, OpenStack, 38 | Xen). that don't provide the option to interact with the system at 39 | boot time. 40 | 41 | After boot, a virtual fence redirects attempts to access 42 | potentially vulnerable services to a web page explaining how to SSH 43 | into the machine for the first time to initialize the system. After 44 | initialization the virtual fence comes down and all services can be 45 | accessed normally. 46 | 47 | Non-interactive system initialization 48 | ------------------------------------- 49 | 50 | The `TurnKey Hub`_ streamlines deployment by preseeding system 51 | initialization settings with values the user provides before launching 52 | an instance through the Hub's cloud deployment web app. 53 | 54 | This means when the system boots for the first time it doesn't need to 55 | interact with the user through text dialogs. 56 | 57 | Preseeding is well documented and may be used by other hosting providers 58 | or private clouds in a similar way to streamline deployment. 59 | 60 | .. _TurnKey Hub: https://hub.turnkeylinux.org/ 61 | 62 | Under the hood: everything you wanted to know but were afraid to ask 63 | ==================================================================== 64 | 65 | Users wishing to preseed headless builds (e.g. LXC) will find the 66 | `Preseeding`_ section below of value. Otherwise, the preceding introduction 67 | explained everything mere mortals need to know about the system 68 | initialization process. 69 | 70 | The rest of the documentation is intended for: 71 | 72 | - Appliance hackers interested in learning how TurnKey works under the 73 | hood and developing their own configuration hooks. 74 | 75 | - Expert users who want to understand how system initialization works in 76 | depth. 77 | 78 | - Hosting providers and private cloud fullstack ninjas interested in 79 | implementing tight integration between TurnKey and custom control 80 | panels. 81 | 82 | This isn't a requirement, just a bonus. Without any special 83 | integration, TurnKey images can be deployed like any other Debian or 84 | Debian-based image, using your existing deployments scripts. If you 85 | can deploy Debian or Ubuntu it should be trivial to deploy TurnKey. 86 | 87 | Inithooks package design goals 88 | ------------------------------ 89 | 90 | The inithooks package executes system initialization scripts 91 | which: 92 | 93 | - **Regenerate secret keys (e.g., SSH, default SSL certificate)**: This 94 | isn't just a good idea, it's necessary to avoid man in the middle 95 | attacks. 96 | 97 | - **Set passwords (e.g., root, database, application)**: necessary to avoid the risk 98 | of `hardwired default passwords `_ 99 | 100 | - **Configure basic application settings (e.g., domain, admin email)**: 101 | especially useful when configuring the application would require hunting 102 | down the format of a configuration file. 103 | 104 | Also, Inithooks provides a preseeding mechanism designed to make it easy 105 | to integrate TurnKey with custom control panels provided by various 106 | virtualization solutions and cloud hosting providers. 107 | 108 | How it works 109 | ------------ 110 | 111 | Inithooks itself is as generic and barebones as possible, leaving 112 | the bulk of functionality up to the appliance specific "hook" 113 | scripts themselves, 114 | 115 | These scripts are located in two sub-directories under 116 | /usr/lib/inithooks - everyboot.d and firstboot.d. 117 | 118 | They are executed in alphanumeric ordering. This means a script named 119 | 1-foo would be executed before 2-bar, which would itself be executed 120 | before 3-foobar. That's why scripts in these directories have funny 121 | numbers at the beginning. 122 | 123 | The inithooks top-level init script is executed early on in system 124 | initialization, at runlevel 2 15. This enables configuration of the 125 | system prior to most services starting. This should be taken into 126 | consideration when developing hook scripts. 127 | 128 | firstboot.d scripts 129 | ''''''''''''''''''' 130 | 131 | Scripts in the firstboot.d sub-directory are executed under the 132 | following conditions: 133 | 134 | #. If the user executes "turnkey-init" from a root shell. This command 135 | can be used to rerun the firstboot.d inithooks interactively to 136 | reconfigure the appliance if needed. Certain scripts such as those that 137 | regenerate secret keys are skipped. See BLACKLIST variable in 138 | /usr/sbin/turnkey-init for details. 139 | 140 | #. When the user logs in as root for the first time into a headless 141 | system. This triggers "turnkey-init" to run so that the user can 142 | interactively complete appliance initialization. 143 | 144 | #. When a TurnKey appliance boots for the first time 145 | 146 | inithooks checks whether or not this is the first boot by checking 147 | the value of the RUN\_FIRSTBOOT flag in /etc/default/inithooks. If 148 | the value is false it runs the scripts and toggles the flag to true. 149 | 150 | The firstboot scripts may run in one of two modes, interactive or 151 | non-interactive, depending on the type of build. 152 | 153 | **Interactive mode on non-headless builds - Live CD ISO, VMDK and 154 | OVF**: With these image types interactive access to the virtual 155 | console during boot is expected so some of the inithooks 156 | initialization scripts will interact with the user via text dialogs 157 | the first time the system boots (e.g., ask for passwords, 158 | application settings, etc.). These are the same scripts that get 159 | executed if you run "turnkey-init". 160 | 161 | **Non-interactive mode on headless builds - OpenStack, OpenVZ, 162 | OpenNode, Xen**: with these image types interactive access to the 163 | virtual console during boot can not be assumed. The first boot has 164 | to be capable of running non-interactively, otherwise we risk 165 | hanging the boot while it waits for user interaction that never 166 | happens. 167 | 168 | So instead of interacting with the user the system pre-initializes 169 | application settings with dummy defaults and set all passwords to a 170 | random value. If a root password has already been set (e.g., in a 171 | pre-deployment script) the headless preseeding script will not 172 | overwrite it, so your root password should work just fine. 173 | 174 | The output from the non-interactive running of the firstboot 175 | scripts is logged to /var/log/inithooks.log. 176 | 177 | Interactive appliance configuration is delayed until the first time 178 | the user logs in as root. This is accomplished with the help of the 179 | /usr/lib/inithooks/firstboot.d/29preseed hook, which only exists on 180 | headless builds:: 181 | 182 | #!/bin/bash -e 183 | # generic preseeding of inithooks.conf if it doesn't exist 184 | 185 | [ -e $INITHOOKS_CONF ] && exit 0 186 | 187 | MASTERPASS=$(mcookie | cut --bytes 1-8) 188 | 189 | cat>$INITHOOKS_CONF< deactivate initfence (service and profile.d) 232 | 233 | everyboot.d scripts 234 | ''''''''''''''''''' 235 | 236 | Scripts that are in the everyboot.d sub-directory run on every boot. We 237 | try to minimize the number of scripts that live here because they're 238 | basically a poor man's init script and real init scripts are often a 239 | better idea. 240 | 241 | Setting the root password in a headless deployment 242 | -------------------------------------------------- 243 | 244 | On headless deployments the user needs to login as root to complete the 245 | appliance initialization process, but how do you login as root? 246 | 247 | Not a problem if you're using OpenNode or ProxMox - those systems 248 | prompt you to choose a root password before deploying a TurnKey image. 249 | 250 | On OpenStack you can log in as root with your configured SSH keypair 251 | or retrieve the random root password from the "system log". 252 | 253 | Other virtualization / private cloud solutions should be able to use 254 | their existing deployment scripts to set the root password, just like 255 | they already do with Debian and Ubuntu. 256 | 257 | Another more advanced option is to "preseed" the /etc/inithooks.conf 258 | file in the apliance's filesystem before booting it for the first 259 | time. This lets you leverage inithooks to pre-configure not just the 260 | root password but also the database and application passwords, admin 261 | email, domain name, etc. 262 | 263 | However note that using preseeding deactivates the "initilization 264 | fence". If you're using preseeding TurnKey assumes you've already 265 | interacted with the user some other way (e.g., web control panel) to 266 | get the preseeded configuration values. 267 | 268 | Preseeding 269 | ---------- 270 | 271 | By default, when an appliance is run for the first time, the firstboot 272 | scripts will prompt the user interactively, through the virtual 273 | console, to choose various passwords and basic application 274 | configuration settings. 275 | 276 | It is possible to bypass this interactive configuration process by 277 | creating /etc/inithooks.conf in the appliance filesystem and 278 | writing inithooks configuration variables into it before the 279 | first system boot. For example: 280 | :: 281 | 282 | cat>/etc/inithooks.conf<