├── .github ├── ISSUE_TEMPLATE │ └── issue.md └── pull_request_template.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── COPYRIGHT ├── Dockerfile ├── LICENSE-APACHE ├── LICENSE-MIT ├── Makefile ├── README.md ├── SECURITY.md ├── VERSION ├── hashes ├── bash └── musl ├── motd ├── patches └── musl │ ├── 0001-iconv-fix-erroneous-input-validation-in-EUC-KR-decod.patch │ └── 0002-iconv-harden-UTF-8-output-code-path-against-input-de.patch ├── sdk-fetch ├── sheltie ├── sshd_config ├── start_admin.sh ├── systemd-patches ├── 9500-cgroup-util-extract-cgroup-hierarchy-base-path-into-.patch ├── 9501-cgroup-util-accept-cgroup-hierarchy-base-as-option.patch ├── 9502-core-move-initialization-of-.slice-and-init.scope-in.patch ├── 9503-core-drop-.slice-from-shipped-units.patch └── 9504-core-skip-restart-when-a-JOB_STOP-job-is-pending.patch └── units ├── admin.target ├── getty@.service ├── serial-getty@.service └── sshd.service /.github/ISSUE_TEMPLATE/issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Open an issue 3 | about: Let us know about a problem or feature request 4 | --- 5 | 6 | 12 | 13 | **Image I'm using:** 14 | 15 | 16 | 17 | **Issue or Feature Request:** 18 | 19 | 20 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | **Issue number:** 8 | 9 | 10 | 11 | **Description of changes:** 12 | 13 | 14 | 15 | **Testing done:** 16 | 17 | 18 | 19 | **Terms of contribution:** 20 | 21 | By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license. 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.11.20 2 | 3 | * Rebuilt to get the latest AL2 updates. 4 | 5 | # 0.11.19 6 | 7 | * Rebuilt to get the latest AL2 updates. 8 | 9 | # 0.11.18 10 | 11 | * Bump musl version from 1.2.3 -> 1.2.5. ([#114]) 12 | * Add patches for CVE-2025-26519 in musl. ([#114]) 13 | * Rebuilt to get the latest AL2 updates. 14 | 15 | [#114]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/114 16 | 17 | # 0.11.17 18 | 19 | * Rebuilt to get the latest AL2 updates. 20 | 21 | # 0.11.16 22 | * Link Host certificates if available. ([#106]) 23 | * Rebuilt to get the latest AL2 updates. 24 | 25 | [#106]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/106 26 | 27 | # 0.11.15 28 | 29 | * Rebuilt to get the latest AL2 updates. 30 | 31 | # 0.11.14 32 | 33 | * Rebuilt to get the latest AL2 updates. 34 | 35 | # 0.11.13 36 | 37 | * Rebuilt to get the latest AL2 updates. 38 | 39 | # 0.11.12 40 | 41 | * Rebuilt to get the latest AL2 updates. 42 | 43 | # 0.11.11 44 | 45 | * Rebuilt to get the latest AL2 updates. 46 | 47 | # 0.11.10 48 | 49 | * Rebuilt to get the latest AL2 updates. 50 | 51 | # 0.11.9 52 | 53 | * Rebuilt to get the latest AL2 updates. 54 | 55 | # 0.11.8 56 | 57 | * Added systemd skip automatic restart when a JOB_STOP job is pending patch. ([#97]) 58 | * Rebuilt to get the latest AL2 updates. 59 | 60 | [#97]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/97 61 | 62 | # 0.11.7 63 | 64 | * Rebuilt to get the latest AL2 updates. 65 | 66 | # 0.11.6 67 | 68 | * Rebuilt to get the latest AL2 updates. 69 | 70 | # 0.11.5 71 | 72 | * Rebuilt to get the latest AL2 updates. 73 | 74 | # 0.11.4 75 | 76 | * Rebuilt to get the latest AL2 updates. 77 | 78 | # 0.11.3 79 | 80 | * Allow setting MACs in SSHD config. ([#91], **thanks @mlacko64!**) 81 | 82 | [#91]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/91 83 | 84 | # 0.11.2 85 | 86 | * Rebuilt to get the latest AL2 updates. 87 | 88 | # 0.11.1 89 | 90 | * Rebuilt to get the latest AL2 updates. 91 | 92 | # 0.11.0 93 | 94 | * Rebuilt to get the latest AL2 updates. 95 | * Add sshd config update to stop unnecessary reverse lookups of incoming connections ([#85]) 96 | 97 | [#85]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/85 98 | 99 | # 0.10.2 100 | 101 | * Rebuilt to get the latest AL2 updates. 102 | 103 | # 0.10.1 104 | 105 | * Rebuilt to get the latest AL2 updates. 106 | 107 | # 0.10.0 108 | 109 | * Add support for running on a host with cgroup v2 (unified cgroup hierarchy) enabled. ([#76]) 110 | * Fix systemd warning about conflicting jobs when the admin container exits. ([#79]) 111 | * Pick up latest AL2 updates. 112 | 113 | [#76]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/76 114 | [#79]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/79 115 | 116 | # 0.9.4 117 | 118 | * Rebuilt to get the latest AL2 updates. 119 | 120 | # 0.9.3 121 | 122 | * Remove check for EC2 Instance Connect hostkey harvesting. ([#71]) 123 | 124 | [#71]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/71 125 | 126 | # 0.9.2 127 | 128 | * Remove `/etc/config/selinux` from image. ([#69]) 129 | 130 | [#69]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/69 131 | 132 | # 0.9.1 133 | 134 | * Update to the latest musl release. ([#67]) 135 | 136 | [#67]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/67 137 | 138 | # 0.9.0 139 | 140 | * Add support for serial console access. ([#59]) 141 | * Symlink logger with true. ([#60]) 142 | 143 | [#59]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/59 144 | [#60]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/60 145 | 146 | # 0.8.0 147 | 148 | * Update bash to 5.1.16. ([#55]) 149 | * Add some art to MOTD. ([#53]) 150 | * Switch to ECR Public, fix multi-arch builds, and more. ([#54]) 151 | 152 | [#53]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/53 153 | [#54]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/54 154 | [#55]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/55 155 | 156 | # 0.7.4 157 | 158 | * Rebuilt to get the latest AL2 updates. ([#52]) 159 | 160 | [#52]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/52 161 | 162 | # 0.7.3 163 | 164 | * Add support for custom username. ([#45]) 165 | * Allow setting key exchange algorithms. ([#46], **thanks @willthames!**) 166 | * Add support for passing single commands through sheltie. ([#50]) 167 | 168 | [#45]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/45 169 | [#46]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/46 170 | [#50]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/50 171 | 172 | # 0.7.2 173 | 174 | * Add support for EC2 Instance Connect. ([#39], **thanks @samjo-nyang!**) 175 | * Disable root login and allow for custom SSH cipher list. ([#42], **thanks @willthames!**) 176 | 177 | [#39]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/39 178 | [#42]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/42 179 | 180 | # 0.7.1 181 | 182 | * Remove exits added to the sshd configuration script in v0.7.0. ([#33]) 183 | * Update musl to 1.2.2. ([#34]) 184 | * Pull bash and musl sources from lookaside cache, instead of from upstream. ([#35]) 185 | 186 | [#33]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/33 187 | [#34]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/34 188 | [#35]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/35 189 | 190 | # 0.7.0 191 | 192 | * Switch paths from `/.bottlerocket/host-containers/admin` to `/.bottlerocket/host-containers/current` ([#21]) 193 | * Export Bottlerocket proxy ENV variables for all login shells. ([#24]) 194 | * Add support for `user-data` settings in kebab-case (recommended default). ([#26]) 195 | * Switch from old docker build environment to docker buildkit by default. ([#14]) 196 | * Improve error handling and logging during ssh setup. ([#20]) 197 | * Fix condensed output of user data in error messages to keep intentional spaces. ([#25]) 198 | * Clean up the start sshd script to be more consistent with recent control container updates. ([#22]) 199 | 200 | [#14]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/14 201 | [#20]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/20 202 | [#21]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/21 203 | [#22]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/22 204 | [#24]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/24 205 | [#25]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/25 206 | [#26]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/26 207 | 208 | # 0.6.0 209 | 210 | * Use user-data file rather than IMDS directly to set public keys. ([#19]) 211 | 212 | [#19]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/19 213 | 214 | # 0.5.0 215 | 216 | * Use /proc to find the bash binary in sheltie. ([#8]) 217 | 218 | [#8]: https://github.com/bottlerocket-os/bottlerocket-admin-container/pull/8 219 | 220 | # 0.4.0 221 | 222 | Initial release of **bottlerocket-admin-container** - the default admin container for Bottlerocket. 223 | 224 | See the [README](README.md) for additional information. 225 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. 4 | Whether it's a bug report, new feature, correction, or additional documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary information to effectively respond to your bug report or contribution. 7 | 8 | 9 | ## Reporting Bugs/Feature Requests 10 | 11 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 12 | 13 | When filing an issue, please check [existing open](https://github.com/bottlerocket-os/bottlerocket-admin-container/issues) and [closed](https://github.com/bottlerocket-os/bottlerocket-admin-container/issues?q=is%3Aissue+is%3Aclosed) issues to make sure somebody else hasn't already reported the issue. 14 | Please try to include as much information as you can. 15 | Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. 25 | Before starting a pull request, please ensure that: 26 | 27 | 1. You open an issue first to discuss any significant work - we would hate for your time to be wasted. 28 | 2. You are working against the latest source on the *develop* branch. 29 | 3. You check existing [open](https://github.com/bottlerocket-os/bottlerocket-admin-container/pulls) and [merged](https://github.com/bottlerocket-os/bottlerocket-admin-container/pulls?q=is%3Apr+is%3Aclosed) pull requests to make sure someone else hasn't addressed the problem already. 30 | 31 | To send us a pull request, please: 32 | 33 | 1. Fork the repository. 34 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat the code, it will be hard for us to focus on your change. 35 | 3. Ensure local tests pass. 36 | 4. Commit to your fork using clear commit messages. 37 | 5. Send us a pull request, answering any default questions in the pull request interface. 38 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 39 | 40 | GitHub provides additional documentation on [forking a repository](https://help.github.com/articles/fork-a-repo/) and [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. 45 | As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/bottlerocket-os/bottlerocket-admin-container/labels/help%20wanted) issues is a great place to start. 46 | 47 | 48 | ## Code of Conduct 49 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 50 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). 55 | Please do **not** create a public GitHub issue. 56 | 57 | 58 | ## Licensing 59 | 60 | See the [COPYRIGHT](COPYRIGHT) file for our project's licensing. 61 | We will ask you to confirm the licensing of your contribution. 62 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc., its affiliates, or other contributors. All Rights Reserved. 2 | 3 | Except as otherwise noted (below and/or in individual files), Bottlerocket is dual-licensed under 4 | the Apache License, version 2.0 or the MIT license , at your option. 5 | 6 | Copyrights in Bottlerocket are retained by their contributors. No copyright assignment is required 7 | to contribute to Bottlerocket. Contributions to Bottlerocket are explicitly made under both the 8 | Apache License, version 2.0, and the MIT license. For full authorship information, see the version 9 | control history. 10 | 11 | Bottlerocket operating system images include packages written by third parties, which may carry 12 | their own copyright notices and license terms. These are available in /usr/share/licenses on the 13 | operating system images. 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Base image for all builds 3 | 4 | FROM public.ecr.aws/amazonlinux/amazonlinux:2 AS builder-base 5 | RUN yum group install -y "Development Tools" 6 | RUN useradd builder 7 | 8 | 9 | ################################################################################ 10 | # Statically linked, more recent version of bash 11 | 12 | FROM builder-base AS builder-static 13 | RUN yum install -y glibc-static 14 | 15 | ARG musl_version=1.2.5 16 | ARG bash_version=5.1.16 17 | 18 | WORKDIR /opt/build 19 | COPY ./sdk-fetch ./ 20 | 21 | WORKDIR /opt/build 22 | COPY ./hashes/musl ./hashes 23 | COPY ./patches/musl ./patches 24 | 25 | RUN \ 26 | ./sdk-fetch hashes && \ 27 | tar -xf musl-${musl_version}.tar.gz && \ 28 | rm musl-${musl_version}.tar.gz hashes && \ 29 | cd musl-${musl_version} && \ 30 | git init . && \ 31 | git apply --whitespace=nowarn ../patches/*.patch 32 | 33 | WORKDIR /opt/build/musl-${musl_version} 34 | RUN ./configure --enable-static && make -j$(nproc) && make install 35 | 36 | WORKDIR /opt/build 37 | COPY ./hashes/bash ./hashes 38 | 39 | RUN \ 40 | ./sdk-fetch hashes && \ 41 | tar -xf bash-${bash_version}.tar.gz && \ 42 | rm bash-${bash_version}.tar.gz hashes 43 | 44 | WORKDIR /opt/build/bash-${bash_version} 45 | RUN CC=""/usr/local/musl/bin/musl-gcc CFLAGS="-Os -DHAVE_DLOPEN=0" \ 46 | ./configure \ 47 | --enable-static-link \ 48 | --without-bash-malloc \ 49 | || { cat config.log; exit 1; } 50 | RUN make -j`nproc` 51 | RUN cp bash /opt/bash 52 | RUN mkdir -p /usr/share/licenses/bash && \ 53 | cp -p COPYING /usr/share/licenses/bash 54 | 55 | 56 | ################################################################################ 57 | # Rebuild of Amazon Linux 2's systemd v219 with downstream patches 58 | 59 | FROM builder-base AS builder-systemd 60 | RUN yum install -y yum-utils rpm-build 61 | RUN yum-builddep -y systemd 62 | 63 | USER builder 64 | WORKDIR /home/builder 65 | RUN yumdownloader --source systemd 66 | RUN rpm -Uv systemd-219-*.src.rpm 67 | 68 | WORKDIR /home/builder/rpmbuild/SOURCES 69 | COPY systemd-patches/*.patch ./ 70 | 71 | WORKDIR /home/builder/rpmbuild/SPECS 72 | # Recreate the spec file from three parts: everything up until the last upstream 73 | # patch, downstream patches, everything else. 74 | RUN last_patch=$(awk '/^Patch[0-9]+/ { line = NR } END { print line }' systemd.spec); \ 75 | head -n${last_patch} systemd.spec >systemd.mod.spec; \ 76 | { \ 77 | echo ;\ 78 | echo '# Bottlerocket Patches'; \ 79 | echo 'Patch9500: 9500-cgroup-util-extract-cgroup-hierarchy-base-path-into-.patch'; \ 80 | echo 'Patch9501: 9501-cgroup-util-accept-cgroup-hierarchy-base-as-option.patch'; \ 81 | echo 'Patch9502: 9502-core-move-initialization-of-.slice-and-init.scope-in.patch'; \ 82 | echo 'Patch9503: 9503-core-drop-.slice-from-shipped-units.patch'; \ 83 | echo 'Patch9504: 9504-core-skip-restart-when-a-JOB_STOP-job-is-pending.patch'; \ 84 | echo ; \ 85 | } >>systemd.mod.spec; \ 86 | tail -n+$((last_patch + 1)) systemd.spec >>systemd.mod.spec; \ 87 | mv systemd.mod.spec systemd.spec 88 | RUN rpmbuild --bb systemd.spec 89 | 90 | 91 | ################################################################################ 92 | # Actual admin container image 93 | 94 | FROM public.ecr.aws/amazonlinux/amazonlinux:2 95 | 96 | ARG IMAGE_VERSION 97 | # Make the container image version a mandatory build argument 98 | RUN test -n "$IMAGE_VERSION" 99 | LABEL "org.opencontainers.image.version"="$IMAGE_VERSION" 100 | 101 | # Install the custom systemd build in the same transaction as all original 102 | # packages to save space. For example, openssh-server pulls in systemd. This 103 | # dependency is best satisfied by the downstream build. Reinstalling it later 104 | # would result in also carrying around the original systemd in the final image 105 | # where it would remain forever hidden and unused in a lower layer. 106 | RUN --mount=type=bind,from=builder-systemd,source=/home/builder/rpmbuild/RPMS,target=/tmp/systemd-rpms \ 107 | yum update -y \ 108 | && yum install -y \ 109 | /tmp/systemd-rpms/*/systemd-{219,libs}*.rpm \ 110 | ec2-instance-connect \ 111 | jq \ 112 | openssh-server \ 113 | openssl \ 114 | procps-ng \ 115 | shadow-utils \ 116 | sudo \ 117 | util-linux \ 118 | && yum clean all 119 | 120 | # Delete SELinux config file to prevent relabeling with contexts provided by the container's image 121 | RUN rm -rf /etc/selinux/config 122 | 123 | COPY --from=builder-static /opt/bash /opt/bin/ 124 | COPY --from=builder-static /usr/share/licenses/bash /usr/share/licenses/bash 125 | 126 | RUN rm -f /etc/motd /etc/issue 127 | COPY --chown=root:root motd /etc/ 128 | 129 | COPY --chown=root:root units /etc/systemd/user/ 130 | 131 | ARG CUSTOM_PS1='[\u@admin]\$ ' 132 | RUN echo "PS1='$CUSTOM_PS1'" > "/etc/profile.d/bottlerocket-ps1.sh" \ 133 | && echo "PS1='$CUSTOM_PS1'" >> "/root/.bashrc" \ 134 | && echo "cat /etc/motd" >> "/root/.bashrc" 135 | 136 | COPY --chmod=755 start_admin.sh /usr/sbin/ 137 | COPY ./sshd_config /etc/ssh/ 138 | COPY --chmod=755 ./sheltie /usr/bin/ 139 | 140 | RUN groupadd -g 274 api 141 | 142 | # Reduces issues related to logger and our implementation of systemd. This is 143 | # necessary for scripts logging to logger, such as in EC2 Instance Connect. 144 | RUN ln -sf /usr/bin/true /usr/bin/logger 145 | 146 | CMD ["/usr/sbin/start_admin.sh"] 147 | ENTRYPOINT ["/bin/bash", "-c"] 148 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright Amazon.com, Inc., its affiliates, or other contributors. All Rights Reserved. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # IMAGE_NAME is the full name of the container image being built. 2 | IMAGE_NAME ?= $(notdir $(shell pwd -P))$(IMAGE_ARCH_SUFFIX):$(IMAGE_VERSION)$(addprefix -,$(SHORT_SHA)) 3 | # IMAGE_VERSION is the semver version that's tagged on the image. 4 | IMAGE_VERSION = $(shell cat VERSION) 5 | # SHORT_SHA is the revision that the container image was built with. 6 | SHORT_SHA ?= $(shell git describe --abbrev=8 --always --dirty='-dev' --exclude '*' || echo "unknown") 7 | # IMAGE_ARCH_SUFFIX is the runtime architecture designator for the container 8 | # image, it is appended to the IMAGE_NAME unless the name is specified. 9 | IMAGE_ARCH_SUFFIX ?= $(addprefix -,$(ARCH)) 10 | # DESTDIR is where the release artifacts will be written. 11 | DESTDIR ?= . 12 | # DISTFILE is the path to the dist target's output file - the container image 13 | # tarball. 14 | DISTFILE ?= $(subst /,,$(DESTDIR))/$(subst /,_,$(IMAGE_NAME)).tar.gz 15 | 16 | UNAME_ARCH = $(shell uname -m) 17 | ARCH ?= $(lastword $(subst :, ,$(filter $(UNAME_ARCH):%,x86_64:amd64 aarch64:arm64))) 18 | 19 | .PHONY: all build check check-static-bash 20 | 21 | # Run all build tasks for this container image. 22 | all: build check 23 | 24 | # Create a distribution container image tarball for release. 25 | dist: all 26 | @mkdir -p $(dir $(DISTFILE)) 27 | docker save $(IMAGE_NAME) | gzip > $(DISTFILE) 28 | 29 | # Build the container image. 30 | build: 31 | DOCKER_BUILDKIT=1 docker build $(DOCKER_BUILD_FLAGS) \ 32 | --tag $(IMAGE_NAME) \ 33 | --build-arg IMAGE_VERSION="$(IMAGE_VERSION)" \ 34 | -f Dockerfile . >&2 35 | 36 | # Run checks against the container image. 37 | check: check-static-bash 38 | 39 | # Check that bash can be run without dependency on shared libraries. 40 | check-static-bash: 41 | docker run $(DOCKER_RUN_FLAGS) \ 42 | --rm \ 43 | --entrypoint /opt/bin/bash \ 44 | --mount type=volume,target=/usr/lib,volume-nocopy \ 45 | --mount type=volume,target=/usr/lib64,volume-nocopy \ 46 | $(IMAGE_NAME) \ 47 | -c '/usr/bin/bash -c "echo \$$0 must not run" 2>/dev/null && exit 1 || exit 0' 48 | 49 | clean: 50 | rm -f $(DISTFILE) 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bottlerocket Admin Container 2 | 3 | This is the admin container for troubleshooting the [Bottlerocket](https://github.com/bottlerocket-os/bottlerocket) operating system. 4 | It runs outside of Bottlerocket's container orchestrator in a separate instance of `containerd`. 5 | The container hosts an SSH server to allow public key SSH access, as well as `agetty` services for serial console devices to allow console access. 6 | You can also connect to the admin container via the control container by running `enter-admin-container`. 7 | Unless otherwise specified through user-data, the default user is **ec2-user**. 8 | 9 | The admin container is disabled by default in Bottlerocket. 10 | For more information about how the admin container fits into the Bottlerocket operating system, please see the [Bottlerocket documentation](https://github.com/bottlerocket-os/bottlerocket/blob/develop/README.md#admin-container). 11 | 12 | ## Building the Container Image 13 | 14 | You'll need Docker 20.10 or later for multi-stage build, BuildKit, and chmod on COPY/ADD support. 15 | Then run `make`! 16 | 17 | ## Authenticating with the Admin Container 18 | 19 | Starting from v0.6.0, users have the option to pass in their own ssh keys rather than the admin container relying on the AWS instance metadata service (IMDS). 20 | 21 | Users can add their own keys by populating the admin container's user-data with a base64-encoded JSON block. 22 | If user-data is populated then Bottlerocket will not fetch from IMDS at all, but if user-data is not set then Bottlerocket will continue to use the keys from IMDS. 23 | 24 | To use custom public keys for `.ssh/authorized_keys` and/or custom CA keys for `/etc/ssh/trusted_user_ca_keys.pub` you will want to generate a JSON-structure like this: 25 | 26 | ```json 27 | { 28 | "ssh": { 29 | "authorized-keys": [ 30 | "ssh-rsa EXAMPLEAUTHORIZEDPUBLICKEYHERE my-key-pair" 31 | ], 32 | "trusted-user-ca-keys": [ 33 | "ssh-rsa EXAMPLETRUSTEDCAPUBLICKEYHERE authority@ssh-ca.example.com" 34 | ] 35 | } 36 | } 37 | ``` 38 | 39 | If you want to access to the admin container using [EC2 instance connect](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Connect-using-EC2-Instance-Connect.html), set `authorized-keys-command` and `authorized-keys-command-user` as follows: 40 | 41 | ```json 42 | { 43 | "ssh": { 44 | "authorized-keys-command": "/opt/aws/bin/eic_run_authorized_keys %u %f", 45 | "authorized-keys-command-user": "ec2-instance-connect" 46 | } 47 | } 48 | ``` 49 | 50 | To change allowed SSH ciphers to a specific set, you can add a ciphers section: 51 | 52 | ```json 53 | { 54 | "ssh": { 55 | "authorized-keys...", 56 | "ciphers": [ 57 | "chacha20-poly1305@openssh.com", 58 | "aes128-ctr", 59 | "aes192-ctr", 60 | "aes256-ctr", 61 | "aes128-gcm@openssh.com", 62 | "aes256-gcm@openssh.com" 63 | ] 64 | } 65 | } 66 | ``` 67 | 68 | To change allowed key exchange algorithms to a specific set, you can add a 69 | `key-exchange-algorithms` section: 70 | 71 | ```json 72 | { 73 | "ssh": { 74 | "authorized-keys...", 75 | "key-exchange-algorithms": [ 76 | "curve25519-sha256", 77 | "curve25519-sha256@libssh.org", 78 | "ecdh-sha2-nistp256", 79 | "ecdh-sha2-nistp384", 80 | "ecdh-sha2-nistp521", 81 | "diffie-hellman-group-exchange-sha256" 82 | ] 83 | } 84 | } 85 | ``` 86 | 87 | To change allowed MACs to a specific set, you can add a `macs` section: 88 | 89 | ```json 90 | { 91 | "ssh": { 92 | "authorized-keys...", 93 | "macs": [ 94 | "hmac-sha2-256", 95 | "hmac-sha2-512", 96 | "umac-64@openssh.com", 97 | "umac-128@openssh.com", 98 | "hmac-sha2-256-etm@openssh.com", 99 | "hmac-sha2-512-etm@openssh.com", 100 | "hmac-md5-etm@openssh.com", 101 | "hmac-md5-96-etm@openssh.com", 102 | "umac-64-etm@openssh.com", 103 | "umac-128-etm@openssh.com" 104 | ] 105 | } 106 | } 107 | ``` 108 | 109 | You can also tweak ciphers, key exchange algorithms and MACs following way (see https://man.openbsd.org/sshd_config for details): 110 | - If the specified list begins with a ‘+’ character, then the specified entries will be appended to the default set instead of replacing them. If the specified list begins with a ‘-’ character, then the specified entries (including wildcards) will be removed from the default set instead of replacing them. If the specified list begins with a ‘^’ character, then the specified entries will be placed at the head of the default set. 111 | 112 | By default, the admin container's local user will be `ec2-user`. If you would like to change this, you can set the user value like so: 113 | 114 | ```json 115 | { 116 | "user": "bottlerocket", 117 | "ssh": { 118 | "authorized-keys...", 119 | } 120 | } 121 | ``` 122 | 123 | For logging in via serial console, you can specify a password for the primary user like so: 124 | 125 | ```json 126 | { 127 | "user": "bottlerocket", 128 | "password-hash": "$y$jFT$NER...", 129 | "ssh": { 130 | "authorized-keys...", 131 | } 132 | } 133 | ``` 134 | 135 | Where the password-hash can be generated from: 136 | 137 | ```bash 138 | mkpasswd -m yescrypt -R 11 139 | ``` 140 | 141 | Once you've created your JSON, you'll need to base64-encode it and set it as the value of the admin host container's user-data setting in your [instance user data toml](https://github.com/bottlerocket-os/bottlerocket#using-user-data). 142 | 143 | ```toml 144 | [settings.host-containers.admin] 145 | # ex: echo '{"ssh":{"authorized-keys":[]}}' | base64 146 | user-data = "eyJzc2giOnsiYXV0aG9yaXplZC1rZXlzIjpbXX19Cg==" 147 | ``` 148 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Reporting a Vulnerability 2 | 3 | If you discover a potential security issue in this project, we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/) or directly via email to aws-security@amazon.com. 4 | Please do **not** create a public GitHub issue. 5 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | v0.11.20 2 | -------------------------------------------------------------------------------- /hashes/bash: -------------------------------------------------------------------------------- 1 | # https://ftp.gnu.org/gnu/bash/bash-5.1.16.tar.gz 2 | SHA512 (bash-5.1.16.tar.gz) = a32a343b6dde9a18eb6217602655f72c4098b0d90f04cf4e686fb21b81fc4ef26ade30f7226929fbb7c207cde34617dbad2c44f6103161d1141122bb31dc6c80 3 | -------------------------------------------------------------------------------- /hashes/musl: -------------------------------------------------------------------------------- 1 | # https://musl.libc.org/releases/musl-1.2.5.tar.gz 2 | SHA512 (musl-1.2.5.tar.gz) = 7bb7f7833923cd69c7a1a9b8a5f1784bfd5289663eb6061dcd43d583e45987df8a68a1be05d75cc1c88a3f5b610653d1a70f4a9cff4d8f7fd41ae73ee058c17c 3 | -------------------------------------------------------------------------------- /motd: -------------------------------------------------------------------------------- 1 | Welcome to Bottlerocket's admin container! 2 | ╱╲ 3 | ╱┄┄╲ This container provides access to the Bottlerocket host 4 | │▗▖│ filesystems (see /.bottlerocket/rootfs) and contains common 5 | ╱│ │╲ tools for inspection and troubleshooting. It is based on 6 | │╰╮╭╯│ Amazon Linux 2, and most things are in the same places you 7 | ╹╹ would find them on an AL2 host. 8 | 9 | To permit more intrusive troubleshooting, including actions that mutate the 10 | running state of the Bottlerocket host, we provide a tool called "sheltie" 11 | (`sudo sheltie`). When run, this tool drops you into a root shell in the 12 | Bottlerocket host's root filesystem. 13 | -------------------------------------------------------------------------------- /patches/musl/0001-iconv-fix-erroneous-input-validation-in-EUC-KR-decod.patch: -------------------------------------------------------------------------------- 1 | From e5adcd97b5196e29991b524237381a0202a60659 Mon Sep 17 00:00:00 2001 2 | From: Rich Felker 3 | Date: Sun, 9 Feb 2025 10:07:19 -0500 4 | Subject: [PATCH] iconv: fix erroneous input validation in EUC-KR decoder 5 | 6 | as a result of incorrect bounds checking on the lead byte being 7 | decoded, certain invalid inputs which should produce an encoding 8 | error, such as "\xc8\x41", instead produced out-of-bounds loads from 9 | the ksc table. 10 | 11 | in a worst case, the loaded value may not be a valid unicode scalar 12 | value, in which case, if the output encoding was UTF-8, wctomb would 13 | return (size_t)-1, causing an overflow in the output pointer and 14 | remaining buffer size which could clobber memory outside of the output 15 | buffer. 16 | 17 | bug report was submitted in private by Nick Wellnhofer on account of 18 | potential security implications. 19 | --- 20 | src/locale/iconv.c | 2 +- 21 | 1 file changed, 1 insertion(+), 1 deletion(-) 22 | 23 | diff --git a/src/locale/iconv.c b/src/locale/iconv.c 24 | index 9605c8e9..008c93f0 100644 25 | --- a/src/locale/iconv.c 26 | +++ b/src/locale/iconv.c 27 | @@ -502,7 +502,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri 28 | if (c >= 93 || d >= 94) { 29 | c += (0xa1-0x81); 30 | d += 0xa1; 31 | - if (c >= 93 || c>=0xc6-0x81 && d>0x52) 32 | + if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52) 33 | goto ilseq; 34 | if (d-'A'<26) d = d-'A'; 35 | else if (d-'a'<26) d = d-'a'+26; 36 | -- 37 | 2.47.0 38 | -------------------------------------------------------------------------------- /patches/musl/0002-iconv-harden-UTF-8-output-code-path-against-input-de.patch: -------------------------------------------------------------------------------- 1 | From c47ad25ea3b484e10326f933e927c0bc8cded3da Mon Sep 17 00:00:00 2001 2 | From: Rich Felker 3 | Date: Wed, 12 Feb 2025 17:06:30 -0500 4 | Subject: [PATCH] iconv: harden UTF-8 output code path against input decoder 5 | bugs 6 | 7 | the UTF-8 output code was written assuming an invariant that iconv's 8 | decoders only emit valid Unicode Scalar Values which wctomb can encode 9 | successfully, thereby always returning a value between 1 and 4. 10 | 11 | if this invariant is not satisfied, wctomb returns (size_t)-1, and the 12 | subsequent adjustments to the output buffer pointer and remaining 13 | output byte count overflow, moving the output position backwards, 14 | potentially past the beginning of the buffer, without storing any 15 | bytes. 16 | --- 17 | src/locale/iconv.c | 4 ++++ 18 | 1 file changed, 4 insertions(+) 19 | 20 | diff --git a/src/locale/iconv.c b/src/locale/iconv.c 21 | index 008c93f0..52178950 100644 22 | --- a/src/locale/iconv.c 23 | +++ b/src/locale/iconv.c 24 | @@ -545,6 +545,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri 25 | if (*outb < k) goto toobig; 26 | memcpy(*out, tmp, k); 27 | } else k = wctomb_utf8(*out, c); 28 | + /* This failure condition should be unreachable, but 29 | + * is included to prevent decoder bugs from translating 30 | + * into advancement outside the output buffer range. */ 31 | + if (k>4) goto ilseq; 32 | *out += k; 33 | *outb -= k; 34 | break; 35 | -- 36 | 2.47.0 37 | -------------------------------------------------------------------------------- /sdk-fetch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail 3 | # shellcheck disable=SC2046 4 | curl --fail --remote-name-all --remote-time \ 5 | $(awk -F '[ ()]' '/^SHA512 \(/ { 6 | printf "https://cache.bottlerocket.aws/%s/%s/%s\n", $3, $6, $3 7 | }' "$1") 8 | sha512sum --check "$1" 9 | -------------------------------------------------------------------------------- /sheltie: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file is part of Bottlerocket. 3 | # Copyright Amazon.com, Inc., its affiliates, or other contributors. All Rights Reserved. 4 | # SPDX-License-Identifier: Apache-2.0 OR MIT 5 | 6 | if [[ $EUID -ne 0 ]]; then 7 | echo "sheltie must be run as root, you can use 'sudo sheltie' in the admin container" 8 | exit 1 9 | fi 10 | 11 | # Location of the container's rootfs on the host filesystem 12 | # Because we have a shared pid namespace, /proc inside the container matches 13 | # /proc outside the container. The special directory 'root' inside a given 14 | # process directory in /proc contains that process's view of the filesystem. 15 | # We use ${PPID} to indicate the pid of the parent process of this script so we 16 | # can see the container's root filesystem inside this directory. 17 | ROOT_FS_PATH="/proc/${PPID}/root" 18 | BASH_PATH="/opt/bin/bash" 19 | 20 | # Start the root shell on the Bottlerocket host 21 | if [[ ${#@} -ne 0 ]]; then 22 | exec nsenter -t 1 -a -- "$@" 23 | else 24 | exec nsenter -t 1 -a "${ROOT_FS_PATH}${BASH_PATH}" 25 | fi 26 | -------------------------------------------------------------------------------- /sshd_config: -------------------------------------------------------------------------------- 1 | HostKey /.bottlerocket/host-containers/current/etc/ssh/ssh_host_rsa_key 2 | HostKey /.bottlerocket/host-containers/current/etc/ssh/ssh_host_ecdsa_key 3 | HostKey /.bottlerocket/host-containers/current/etc/ssh/ssh_host_ed25519_key 4 | 5 | PasswordAuthentication no 6 | 7 | ChallengeResponseAuthentication no 8 | 9 | UsePAM yes 10 | 11 | AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 12 | AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 13 | AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE 14 | 15 | # SFTP is enabled by default in Amazon Linux 2; keeping that behavior here. 16 | Subsystem sftp /usr/libexec/openssh/sftp-server 17 | 18 | PermitRootLogin no 19 | 20 | # Configured by user data 21 | TrustedUserCAKeys /etc/ssh/trusted_user_ca_keys.pub 22 | 23 | UseDNS no 24 | -------------------------------------------------------------------------------- /start_admin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | log() { 6 | echo "$*" >&2 7 | } 8 | 9 | declare -r PERSISTENT_STORAGE_BASE_DIR="/.bottlerocket/host-containers/current" 10 | declare -r SSH_HOST_KEY_DIR="${PERSISTENT_STORAGE_BASE_DIR}/etc/ssh" 11 | declare -r USER_DATA="${PERSISTENT_STORAGE_BASE_DIR}/user-data" 12 | declare -r HOST_CERTS="/.bottlerocket/certs" 13 | 14 | if [ ! -s "${USER_DATA}" ]; then 15 | log "Admin host-container user-data is empty, going to sleep forever" 16 | exec sleep infinity 17 | fi 18 | 19 | # Fetch user from user-data json (if any). Default to 'ec2-user' if null or invalid. 20 | if ! LOCAL_USER=$(jq -e -r '.["user"] // "ec2-user"' "${USER_DATA}" 2>/dev/null) \ 21 | || [[ ! "${LOCAL_USER}" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]]; then 22 | log "Failed to set user from user-data. Proceeding with 'ec2-user'." 23 | LOCAL_USER="ec2-user" 24 | fi 25 | 26 | # Fetch password-hash for serial console access. 27 | if ! PASSWORD_HASH=$(jq -r '.["password-hash"] // ""' "${USER_DATA}" 2>/dev/null); then 28 | PASSWORD_HASH="" 29 | fi 30 | 31 | declare -r USER_SSH_DIR="/home/${LOCAL_USER}/.ssh" 32 | declare -r SSHD_CONFIG_DIR="/etc/ssh" 33 | declare -r SSHD_CONFIG_FILE="${SSHD_CONFIG_DIR}/sshd_config" 34 | 35 | # This is a counter used to verify at least 36 | # one of the methods below is available. 37 | declare -i available_ssh_methods=0 38 | 39 | # Link host certs if present into container & run update-ca-trust 40 | link_host_certs() { 41 | for cert in $(ls -1 "${HOST_CERTS}"); do 42 | ln -s "${HOST_CERTS}/${cert}" "/etc/pki/ca-trust/source/anchors/${cert}" 43 | done 44 | # Update the CA trust to pickup the new certificates 45 | update-ca-trust 46 | } 47 | 48 | get_user_data_keys() { 49 | # Extract the keys from user-data json 50 | local raw_keys 51 | local key_type="${1:?}" 52 | # ? signifies an optional object identifier-index and doesn't return a 53 | # 'failed to iterate' error in the event that a key_type is missing. 54 | if ! raw_keys=$(jq --arg key_type "${key_type}" -e -r '.["ssh"][$key_type][]?' "${USER_DATA}"); then 55 | return 1 56 | fi 57 | 58 | # Verify jq returned key(s) 59 | if [[ -z "${raw_keys}" ]]; then 60 | return 1 61 | fi 62 | 63 | # Map the keys to avoid improper splitting 64 | local mapped_keys 65 | mapfile -t mapped_keys <<< "${raw_keys}" 66 | 67 | # Verify the keys are valid 68 | local key 69 | local -a valid_keys 70 | for key in "${mapped_keys[@]}"; do 71 | if ! echo "${key}" | ssh-keygen -lf - &>/dev/null; then 72 | log "Failed to validate ${key}" 73 | continue 74 | fi 75 | valid_keys+=( "${key}" ) 76 | done 77 | 78 | ( IFS=$'\n'; echo "${valid_keys[*]}" ) 79 | } 80 | 81 | # Export proxy environment variables for all users' login shells 82 | # Match the values of the proxy environment variables given to the admin container 83 | install_proxy_profile() { 84 | local -r proxy_profile="/etc/profile.d/bottlerocket-proxy-settings.sh" 85 | cat > "${proxy_profile}" </dev/null) 88 | EOF 89 | chmod 644 "${proxy_profile}" 90 | } 91 | 92 | # Set up agetty services for serial console access and the sshd daemon service 93 | enable_systemd_services() { 94 | # Grab `console=` parameters from the kernel command line. 95 | CONSOLES=() 96 | for opt in $(cat /proc/cmdline) ; do 97 | optarg="$(expr "${opt}" : '[^=]*=\(.*\)' 2>/dev/null ||:)" 98 | optarg="${optarg%\"}" 99 | optarg="${optarg#\"}" 100 | case "${opt}" in 101 | console=*) CONSOLES+=("${optarg%,*}") ;; 102 | esac 103 | done 104 | 105 | HOST_DEVTMPFS="/.bottlerocket/rootfs/dev" 106 | for console in "${CONSOLES[@]}" ; do 107 | # Skip devices that don't exist. 108 | [ -c "${HOST_DEVTMPFS}/${console}" ] || continue 109 | 110 | # Otherwise instantiate a service from the template unit. This is normally 111 | # done by `systemd-getty-generator`, but that skips over ordinary devices 112 | # when run inside a container. 113 | case "${console}" in 114 | ttyS*|ttyAMA*|ttyUSB*) 115 | systemctl --user enable "serial-getty@${console}.service" 116 | ;; 117 | tty*) 118 | systemctl --user enable "getty@${console}.service" 119 | ;; 120 | esac 121 | done 122 | # Enable the SSH daemon service unit so we can run it in the background 123 | systemctl --user enable "sshd.service" 124 | } 125 | 126 | # Create local user 127 | echo "${LOCAL_USER} ALL=(ALL) NOPASSWD: ALL" > "/etc/sudoers.d/${LOCAL_USER}" 128 | chmod 440 "/etc/sudoers.d/${LOCAL_USER}" 129 | # Skip user creation if the user already exists 130 | if ! id -u "${LOCAL_USER}" &>/dev/null; then 131 | useradd -m "${LOCAL_USER}" 132 | fi 133 | usermod -G users,api "${LOCAL_USER}" 134 | if [[ -z "${PASSWORD_HASH}" ]]; then 135 | usermod -L "${LOCAL_USER}" 136 | else 137 | usermod -p "${PASSWORD_HASH}" "${LOCAL_USER}" 138 | fi 139 | mkdir -p "${USER_SSH_DIR}" 140 | chmod 700 "${USER_SSH_DIR}" 141 | 142 | # Populate SSH authorized_keys with all the authorized keys found in user-data 143 | if authorized_keys=$(get_user_data_keys "authorized-keys") \ 144 | || authorized_keys=$(get_user_data_keys "authorized_keys"); then 145 | ssh_authorized_keys="${USER_SSH_DIR}/authorized_keys" 146 | touch "${ssh_authorized_keys}" 147 | chmod 600 "${ssh_authorized_keys}" 148 | echo "${authorized_keys}" > "${ssh_authorized_keys}" 149 | ((++available_ssh_methods)) 150 | fi 151 | 152 | # Populate SSH trusted_user_ca_keys with all the trusted ca keys found in user-data 153 | if trusted_user_ca_keys=$(get_user_data_keys "trusted-user-ca-keys") \ 154 | || trusted_user_ca_keys=$(get_user_data_keys "trusted_user_ca_keys"); then 155 | ssh_trusted_user_ca_keys="/etc/ssh/trusted_user_ca_keys.pub" 156 | touch "${ssh_trusted_user_ca_keys}" 157 | chmod 600 "${ssh_trusted_user_ca_keys}" 158 | echo "${trusted_user_ca_keys}" > "${ssh_trusted_user_ca_keys}" 159 | ((++available_ssh_methods)) 160 | fi 161 | 162 | # Set additional SSH configurations 163 | declare authorized_keys_command 164 | if authorized_keys_command=$(jq -e -r '.["ssh"]["authorized-keys-command"]?' "${USER_DATA}"); then 165 | echo "AuthorizedKeysCommand ${authorized_keys_command}" >> "${SSHD_CONFIG_FILE}" 166 | fi 167 | 168 | declare authorized_keys_command_user 169 | if authorized_keys_command_user=$(jq -e -r '.["ssh"]["authorized-keys-command-user"]?' "${USER_DATA}"); then 170 | echo "AuthorizedKeysCommandUser ${authorized_keys_command_user}" >> "${SSHD_CONFIG_FILE}" 171 | fi 172 | 173 | # Populate ciphers with all the ciphers found in user-data 174 | if ciphers=$(jq -r -e -c '.["ssh"]["ciphers"]? | join(",")' "${USER_DATA}" 2>/dev/null); then 175 | echo "Ciphers ${ciphers}" >> "${SSHD_CONFIG_FILE}" 176 | fi 177 | 178 | # Populate KexAlgorithms with all the key exchange algorithms found in user-data 179 | if kex_algorithms=$(jq -r -e -c '.["ssh"]["key-exchange-algorithms"]? | join(",")' "${USER_DATA}" 2>/dev/null); then 180 | echo "KexAlgorithms ${kex_algorithms}" >> "${SSHD_CONFIG_FILE}" 181 | fi 182 | 183 | # Populate MACs with all the MACs found in user-data 184 | if macs=$(jq -r -e -c '.["ssh"]["macs"]? | join(",")' "${USER_DATA}" 2>/dev/null); then 185 | echo "MACs ${macs}" >> "${SSHD_CONFIG_FILE}" 186 | fi 187 | 188 | # Check the configurations are for EC2 Instance Connect 189 | declare -i use_eic=0 190 | if [[ $authorized_keys_command == /opt/aws/bin/eic_run_authorized_keys* ]] \ 191 | && [[ $authorized_keys_command_user == "ec2-instance-connect" ]]; then 192 | use_eic=1 193 | ((++available_ssh_methods)) 194 | fi 195 | 196 | chown -R "${LOCAL_USER}:" "${USER_SSH_DIR}" 197 | 198 | # If there were no available SSH auth methods, then users cannot connect via the SSH daemon 199 | if [[ "${available_ssh_methods}" -eq 0 ]]; then 200 | log "No SSH authentication methods available in admin container user-data" 201 | fi 202 | 203 | # Generate the server keys 204 | mkdir -p "${SSH_HOST_KEY_DIR}" 205 | for key_alg in rsa ecdsa ed25519; do 206 | # If both of the keys exist, don't overwrite them 207 | if [[ -s "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key" ]] \ 208 | && [[ -s "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key.pub" ]]; then 209 | ln -sf "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key.pub" "${SSHD_CONFIG_DIR}/ssh_host_${key_alg}_key.pub" 210 | log "${key_alg} key already exists, will use existing key." 211 | continue 212 | fi 213 | 214 | rm -rf \ 215 | "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key" \ 216 | "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key.pub" 217 | if ssh-keygen -t "${key_alg}" -f "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key" -q -N ""; then 218 | chmod 600 "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key" 219 | chmod 644 "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key.pub" 220 | ln -sf "${SSH_HOST_KEY_DIR}/ssh_host_${key_alg}_key.pub" "${SSHD_CONFIG_DIR}/ssh_host_${key_alg}_key.pub" 221 | else 222 | log "Failure to generate host ${key_alg} ssh keys" 223 | fi 224 | done 225 | 226 | install_proxy_profile 227 | 228 | enable_systemd_services 229 | 230 | [[ -d "${HOST_CERTS}" ]] && link_host_certs 231 | 232 | systemd_options=() 233 | 234 | # cgroup v2 compatibility crimes: systemd 219 in the admin container only 235 | # supports cgroup v1. 236 | if [[ $(findmnt -n -o FSTYPE /sys/fs/cgroup) = cgroup2 ]]; then 237 | # Mount an extra cgroup v1 hierarchy for use by systemd in the admin 238 | # container. Vanilla systemd is hard-wired to look for it at /sys/fs/cgroup 239 | # but that path is already taken by the host's proper cgroup hierarchy. 240 | # Mounting a cgroup v1 hierarchy here might confuse the host and the systemd 241 | # documentation advises against manually interfering with anything in that 242 | # path. Therefore, mount the extra hierarchy elsewhere and tell systemd in 243 | # the admin container where to look. Requirements: 244 | # 245 | # 1. The base must be a mount point. 246 | # 2. The base must contain another mounted cgroup file system named "systemd". 247 | # 248 | # In either case there is no need to populate the file systems with any 249 | # actual cgroup controllers, since the host is expected to manage processes. 250 | readonly cgroup_base=/.bottlerocket/admin-container-cgroup 251 | mkdir -p "${cgroup_base}" 252 | mount -t tmpfs -o nosuid,nodev,noexec tmpfs "${cgroup_base}" 253 | mkdir -p "${cgroup_base}"/systemd 254 | mount -o remount,ro "${cgroup_base}" 255 | mount -t cgroup -o none,name=systemd cgroup "${cgroup_base}"/systemd 256 | systemd_options+=( --cgroup-base "${cgroup_base}" ) 257 | fi 258 | 259 | # Persuade systemd that it's OK to run as a user manager. 260 | export XDG_RUNTIME_DIR="/run/user/${UID}" 261 | mkdir -p /run/systemd/system "${XDG_RUNTIME_DIR}" 262 | exec /usr/lib/systemd/systemd "${systemd_options[@]}" --user --unit=admin.target 263 | -------------------------------------------------------------------------------- /systemd-patches/9500-cgroup-util-extract-cgroup-hierarchy-base-path-into-.patch: -------------------------------------------------------------------------------- 1 | From 1b69dcdee96284abc05072d962e99436d00042f2 Mon Sep 17 00:00:00 2001 2 | From: Markus Boehme 3 | Date: Wed, 23 Nov 2022 13:06:49 +0000 4 | Subject: [PATCH 9500/9501] cgroup-util: extract cgroup hierarchy base path 5 | into variable 6 | 7 | Just extracting the /sys/fs/cgroup path as the cgroup hierarchy base into its 8 | own definition to ease further changes. No functional changes in this commit. 9 | 10 | Signed-off-by: Markus Boehme 11 | --- 12 | src/shared/cgroup-util.c | 16 +++++++++------- 13 | 1 file changed, 9 insertions(+), 7 deletions(-) 14 | 15 | diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c 16 | index f1bed8a..b055dd8 100644 17 | --- a/src/shared/cgroup-util.c 18 | +++ b/src/shared/cgroup-util.c 19 | @@ -41,6 +41,8 @@ 20 | #include "special.h" 21 | #include "mkdir.h" 22 | 23 | +static char *cg_hierarchy_base = "/sys/fs/cgroup"; 24 | + 25 | int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { 26 | _cleanup_free_ char *fs = NULL; 27 | FILE *f; 28 | @@ -453,13 +455,13 @@ static int join_path(const char *controller, const char *path, const char *suffi 29 | 30 | if (!isempty(controller)) { 31 | if (!isempty(path) && !isempty(suffix)) 32 | - t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL); 33 | + t = strjoin(cg_hierarchy_base, "/", controller, "/", path, "/", suffix, NULL); 34 | else if (!isempty(path)) 35 | - t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL); 36 | + t = strjoin(cg_hierarchy_base, "/", controller, "/", path, NULL); 37 | else if (!isempty(suffix)) 38 | - t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL); 39 | + t = strjoin(cg_hierarchy_base, "/", controller, "/", suffix, NULL); 40 | else 41 | - t = strappend("/sys/fs/cgroup/", controller); 42 | + t = strjoin(cg_hierarchy_base, "/", controller, NULL); 43 | } else { 44 | if (!isempty(path) && !isempty(suffix)) 45 | t = strjoin(path, "/", suffix, NULL); 46 | @@ -488,7 +490,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch 47 | if (_unlikely_(!good)) { 48 | int r; 49 | 50 | - r = path_is_mount_point("/sys/fs/cgroup", false); 51 | + r = path_is_mount_point(cg_hierarchy_base, false); 52 | if (r < 0) 53 | return r; 54 | if (r == 0) 55 | @@ -512,7 +514,7 @@ static int check_hierarchy(const char *p) { 56 | return 0; 57 | 58 | /* Check if this controller actually really exists */ 59 | - cc = strjoina("/sys/fs/cgroup/", p); 60 | + cc = strjoina(cg_hierarchy_base, "/", p); 61 | if (laccess(cc, F_OK) < 0) 62 | return -errno; 63 | 64 | @@ -1043,7 +1045,7 @@ int cg_mangle_path(const char *path, char **result) { 65 | assert(result); 66 | 67 | /* First, check if it already is a filesystem path */ 68 | - if (path_startswith(path, "/sys/fs/cgroup")) { 69 | + if (path_startswith(path, cg_hierarchy_base)) { 70 | 71 | t = strdup(path); 72 | if (!t) 73 | -- 74 | 2.36.1 75 | 76 | -------------------------------------------------------------------------------- /systemd-patches/9501-cgroup-util-accept-cgroup-hierarchy-base-as-option.patch: -------------------------------------------------------------------------------- 1 | From 48de958400d2acc96dc3268c287782b33d7ae883 Mon Sep 17 00:00:00 2001 2 | From: Markus Boehme 3 | Date: Wed, 4 Jan 2023 15:33:10 +0000 4 | Subject: [PATCH 9501/9501] cgroup-util: accept cgroup hierarchy base as option 5 | 6 | On an ordinary system, the cgroup hierarchy is expected to be located at 7 | `/sys/fs/cgroup`. Introduce the `--cgroup-base` option to `systemd` to 8 | make it look for the cgroup hierarchy at another location. 9 | 10 | The cgroup base may only be moved once and, preferably only during 11 | initialization while parsing the command line arguments to avoid 12 | confusion. 13 | 14 | Signed-off-by: Markus Boehme 15 | --- 16 | src/core/main.c | 14 +++++++++++++- 17 | src/shared/cgroup-util.c | 26 ++++++++++++++++++++++++++ 18 | src/shared/cgroup-util.h | 2 ++ 19 | 3 files changed, 41 insertions(+), 1 deletion(-) 20 | 21 | diff --git a/src/core/main.c b/src/core/main.c 22 | index 2d70ed0..ce0314a 100644 23 | --- a/src/core/main.c 24 | +++ b/src/core/main.c 25 | @@ -79,6 +79,8 @@ 26 | #include "kmod-setup.h" 27 | #include "emergency-action.h" 28 | 29 | +#include "cgroup-util.h" 30 | + 31 | static enum { 32 | ACTION_RUN, 33 | ACTION_HELP, 34 | @@ -680,7 +682,8 @@ static int parse_argv(int argc, char *argv[]) { 35 | ARG_DESERIALIZE, 36 | ARG_SWITCHED_ROOT, 37 | ARG_DEFAULT_STD_OUTPUT, 38 | - ARG_DEFAULT_STD_ERROR 39 | + ARG_DEFAULT_STD_ERROR, 40 | + ARG_CGROUP_BASE, 41 | }; 42 | 43 | static const struct option options[] = { 44 | @@ -704,6 +707,7 @@ static int parse_argv(int argc, char *argv[]) { 45 | { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT }, 46 | { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, }, 47 | { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, }, 48 | + { "cgroup-base", required_argument, NULL, ARG_CGROUP_BASE, }, 49 | {} 50 | }; 51 | 52 | @@ -880,6 +884,14 @@ static int parse_argv(int argc, char *argv[]) { 53 | arg_switched_root = true; 54 | break; 55 | 56 | + case ARG_CGROUP_BASE: 57 | + r = cg_set_hierarchy_base(optarg); 58 | + if (r < 0) { 59 | + log_error_errno(r, "Failed to use cgroup hierarchy base to %s: %m", optarg); 60 | + return r; 61 | + } 62 | + break; 63 | + 64 | case 'h': 65 | arg_action = ACTION_HELP; 66 | if (arg_no_pager < 0) 67 | diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c 68 | index b055dd8..e9f8d24 100644 69 | --- a/src/shared/cgroup-util.c 70 | +++ b/src/shared/cgroup-util.c 71 | @@ -40,6 +40,7 @@ 72 | #include "fileio.h" 73 | #include "special.h" 74 | #include "mkdir.h" 75 | +#include "refcnt.h" 76 | 77 | static char *cg_hierarchy_base = "/sys/fs/cgroup"; 78 | 79 | @@ -1839,3 +1840,28 @@ int cg_blkio_weight_parse(const char *s, uint64_t *ret) { 80 | *ret = u; 81 | return 0; 82 | } 83 | + 84 | +int cg_set_hierarchy_base(const char *path) { 85 | + static RefCount base_set = REFCNT_INIT; 86 | + char *b; 87 | + int r; 88 | + 89 | + assert(path); 90 | + 91 | + r = is_dir(path, true); 92 | + if (r <= 0) 93 | + return r ? r : -ENOTDIR; 94 | + 95 | + b = strdup(path); 96 | + if (!b) 97 | + return -ENOMEM; 98 | + 99 | + if (REFCNT_INC(base_set) > 2) { 100 | + free(b); 101 | + return -EINVAL; 102 | + } 103 | + 104 | + cg_hierarchy_base = b; 105 | + 106 | + return 0; 107 | +} 108 | diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h 109 | index b6f28c5..07e6d7e 100644 110 | --- a/src/shared/cgroup-util.h 111 | +++ b/src/shared/cgroup-util.h 112 | @@ -163,3 +163,5 @@ int cg_kernel_controllers(Set *controllers); 113 | 114 | int cg_cpu_shares_parse(const char *s, uint64_t *ret); 115 | int cg_blkio_weight_parse(const char *s, uint64_t *ret); 116 | + 117 | +int cg_set_hierarchy_base(const char *path); 118 | -- 119 | 2.36.1 120 | 121 | -------------------------------------------------------------------------------- /systemd-patches/9502-core-move-initialization-of-.slice-and-init.scope-in.patch: -------------------------------------------------------------------------------- 1 | From 0b9c1623c2d51b0e1e51ec9cdbb89eee03118102 Mon Sep 17 00:00:00 2001 2 | From: Lennart Poettering 3 | Date: Mon, 24 Oct 2016 20:37:54 +0200 4 | Subject: [PATCH] core: move initialization of -.slice and init.scope into the 5 | unit_load() callbacks 6 | 7 | Previously, we'd synthesize the root slice unit and the init scope unit in the 8 | enumerator callbacks for the unit type. This is problematic if either of them 9 | is already referenced from a unit that is loaded as result of another unit 10 | type's enumerator logic. 11 | 12 | Let's clean this up and simply create the two objects from the enumerator 13 | callbacks, if they are not around yet. Do the actual filling in of the settings 14 | from the unit_load() callbacks, to match how other units are loaded. 15 | 16 | Fixes: #4322 17 | 18 | (cherry picked from commit 8e4e851f1ddc98daf69b68998afc5a096ea17893) 19 | 20 | Only retain the logic to synthesize the root slice unit. The init scope 21 | does not exist yet in v219 and only was introduced with the work to 22 | support the unified cgroup hierarchy in v226. 23 | 24 | Signed-off-by: Markus Boehme 25 | --- 26 | src/core/slice.c | 27 +++++++++++++++++++++++++++ 27 | 1 file changed, 27 insertions(+) 28 | 29 | diff --git a/src/core/slice.c b/src/core/slice.c 30 | index b0769205f6..f533efdd97 100644 31 | --- a/src/core/slice.c 32 | +++ b/src/core/slice.c 33 | @@ -129,12 +129,39 @@ static int slice_verify(Slice *s) { 34 | return 0; 35 | } 36 | 37 | +static int slice_load_root_slice(Unit *u) { 38 | + assert(u); 39 | + 40 | + if (!unit_has_name(u, SPECIAL_ROOT_SLICE)) 41 | + return 0; 42 | + 43 | + u->no_gc = true; 44 | + 45 | + /* The root slice is a bit special. For example it is always running and cannot be terminated. Because of its 46 | + * special semantics we synthesize it here, instead of relying on the unit file on disk. */ 47 | + 48 | + u->default_dependencies = false; 49 | + u->ignore_on_isolate = true; 50 | + u->refuse_manual_start = true; 51 | + u->refuse_manual_stop = true; 52 | + 53 | + if (!u->description) 54 | + u->description = strdup("Root Slice"); 55 | + if (!u->documentation) 56 | + u->documentation = strv_new("man:systemd.special(7)", NULL); 57 | + 58 | + return 1; 59 | +} 60 | + 61 | static int slice_load(Unit *u) { 62 | Slice *s = SLICE(u); 63 | int r; 64 | 65 | assert(s); 66 | 67 | + r = slice_load_root_slice(u); 68 | + if (r < 0) 69 | + return r; 70 | r = unit_load_fragment_and_dropin_optional(u); 71 | if (r < 0) 72 | return r; 73 | -- 74 | 2.39.1 75 | 76 | -------------------------------------------------------------------------------- /systemd-patches/9503-core-drop-.slice-from-shipped-units.patch: -------------------------------------------------------------------------------- 1 | From cc601c173d6bdeaf6fcc2de476db4ee7ef99607a Mon Sep 17 00:00:00 2001 2 | From: Lennart Poettering 3 | Date: Mon, 24 Oct 2016 20:49:48 +0200 4 | Subject: [PATCH] core: drop -.slice from shipped units 5 | 6 | Since this unit is synthesized anyway there's no point in actually shipping it 7 | on disk. This also has the benefit that "cd /usr/lib/systemd/system ; ls *" 8 | won't be confused by the leading dash of the file name anymore. 9 | 10 | (cherry picked from commit 828d92acbc8e6f536419cfaee10d6b5c7b0d7f82) 11 | 12 | Fixed up context to apply to v219. 13 | 14 | Signed-off-by: Markus Boehme 15 | --- 16 | Makefile.am | 12 ------------ 17 | units/x-.slice | 12 ------------ 18 | 2 files changed, 24 deletions(-) 19 | delete mode 100644 units/x-.slice 20 | 21 | diff --git a/Makefile.am b/Makefile.am 22 | index 648f54b957..13ac6fbb0c 100644 23 | --- a/Makefile.am 24 | +++ b/Makefile.am 25 | @@ -494,7 +494,6 @@ dist_systemunit_DATA = \ 26 | units/swap.target \ 27 | units/slices.target \ 28 | units/system.slice \ 29 | - units/x-.slice \ 30 | units/systemd-initctl.socket \ 31 | units/systemd-shutdownd.socket \ 32 | units/syslog.socket \ 33 | @@ -629,17 +628,6 @@ EXTRA_DIST += \ 34 | units/rc-local.service.in \ 35 | units/halt-local.service.in 36 | 37 | -# automake is broken and can't handle files with a dash in front 38 | -# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14728#8 39 | -units-install-hook: 40 | - mv $(DESTDIR)$(systemunitdir)/x-.slice $(DESTDIR)/$(systemunitdir)/-.slice 41 | - 42 | -units-uninstall-hook: 43 | - rm -f $(DESTDIR)/$(systemunitdir)/-.slice 44 | - 45 | -INSTALL_DATA_HOOKS += units-install-hook 46 | -UNINSTALL_DATA_HOOKS += units-uninstall-hook 47 | - 48 | dist_doc_DATA = \ 49 | README \ 50 | NEWS \ 51 | diff --git a/units/x-.slice b/units/x-.slice 52 | deleted file mode 100644 53 | index ac82c35874..0000000000 54 | --- a/units/x-.slice 55 | +++ /dev/null 56 | @@ -1,12 +0,0 @@ 57 | -# This file is part of systemd. 58 | -# 59 | -# systemd is free software; you can redistribute it and/or modify it 60 | -# under the terms of the GNU Lesser General Public License as published by 61 | -# the Free Software Foundation; either version 2.1 of the License, or 62 | -# (at your option) any later version. 63 | - 64 | -[Unit] 65 | -Description=Root Slice 66 | -Documentation=man:systemd.special(7) 67 | -DefaultDependencies=no 68 | -Before=slices.target 69 | -- 70 | 2.39.1 71 | 72 | -------------------------------------------------------------------------------- /systemd-patches/9504-core-skip-restart-when-a-JOB_STOP-job-is-pending.patch: -------------------------------------------------------------------------------- 1 | From c972880640ee19e89ce9265d8eae1b3aae190332 Mon Sep 17 00:00:00 2001 2 | From: Franck Bui 3 | Date: Fri, 18 Feb 2022 10:06:24 +0100 4 | Subject: [PATCH] core: really skip automatic restart when a JOB_STOP job is 5 | pending 6 | 7 | It's not clear why we rescheduled a service auto restart while a stop job for 8 | the unit was pending. The comment claims that the unit shouldn't be restarted 9 | but the code did reschedule an auto restart meanwhile. 10 | 11 | In practice that was rarely an issue because the service waited for the next 12 | auto restart to be rescheduled, letting the queued stop job to be proceed and 13 | service_stop() to be called preventing the next restart to complete. 14 | 15 | However when RestartSec=0, the timer expired right away making PID1 to 16 | reschedule the unit again, making the timer expired right away... and so 17 | on. This busy loop prevented PID1 to handle any queued jobs (and hence giving 18 | no chance to the start rate limiting to trigger), which made the busy loop last 19 | forever. 20 | 21 | This patch breaks this loop by skipping the reschedule of the unit auto restart 22 | and hence not depending on the value of u->restart_usec anymore. 23 | 24 | Fixes: #13667 25 | 26 | [kssessio: backport to v219] 27 | Signed-off-by: Kyle Sessions 28 | --- 29 | src/core/service.c | 7 +------ 30 | 1 file changed, 1 insertion(+), 6 deletions(-) 31 | 32 | diff --git a/src/core/service.c b/src/core/service.c 33 | index 15e29be..fa2af05 100644 34 | --- a/src/core/service.c 35 | +++ b/src/core/service.c 36 | @@ -1622,12 +1622,7 @@ static void service_enter_restart(Service *s) { 37 | 38 | if (UNIT(s)->job && UNIT(s)->job->type == JOB_STOP) { 39 | /* Don't restart things if we are going down anyway */ 40 | - log_unit_info(UNIT(s)->id, "Stop job pending for unit, delaying automatic restart."); 41 | - 42 | - r = service_arm_timer(s, s->restart_usec); 43 | - if (r < 0) 44 | - goto fail; 45 | - 46 | + log_unit_info(UNIT(s)->id, "Stop job pending for unit, skipping automatic restart."); 47 | return; 48 | } 49 | 50 | -- 51 | 2.40.1 52 | 53 | -------------------------------------------------------------------------------- /units/admin.target: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Admin host container 3 | -------------------------------------------------------------------------------- /units/getty@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Getty on %I 3 | DefaultDependencies=no 4 | 5 | [Service] 6 | Environment=TERM=xterm-256color 7 | ExecStart=-/sbin/agetty -o '-- \\u' --noclear - ${TERM} 8 | Type=idle 9 | Restart=always 10 | RestartSec=0 11 | UtmpIdentifier=%I 12 | StandardInput=tty 13 | StandardOutput=tty 14 | TTYPath=/.bottlerocket/rootfs/dev/%I 15 | TTYReset=yes 16 | TTYVHangup=yes 17 | TTYVTDisallocate=yes 18 | KillMode=process 19 | IgnoreSIGPIPE=no 20 | SendSIGHUP=yes 21 | 22 | [Install] 23 | WantedBy=admin.target 24 | -------------------------------------------------------------------------------- /units/serial-getty@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Serial Getty on %I 3 | DefaultDependencies=no 4 | 5 | [Service] 6 | Environment=TERM=xterm-256color 7 | ExecStart=-/sbin/agetty -o '-- \\u' --keep-baud 115200,57600,38400,9600 - ${TERM} 8 | Type=idle 9 | Restart=always 10 | RestartSec=0 11 | UtmpIdentifier=%I 12 | StandardInput=tty 13 | StandardOutput=tty 14 | TTYPath=/.bottlerocket/rootfs/dev/%I 15 | TTYReset=yes 16 | TTYVHangup=yes 17 | KillMode=process 18 | IgnoreSIGPIPE=no 19 | SendSIGHUP=yes 20 | 21 | [Install] 22 | WantedBy=admin.target 23 | -------------------------------------------------------------------------------- /units/sshd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=OpenSSH server daemon 3 | 4 | [Service] 5 | Type=notify 6 | EnvironmentFile=/etc/sysconfig/sshd 7 | ExecStart=/usr/sbin/sshd -e -D $OPTIONS 8 | ExecReload=/bin/kill -HUP $MAINPID 9 | KillMode=process 10 | Restart=on-failure 11 | RestartSec=42s 12 | 13 | [Install] 14 | WantedBy=admin.target 15 | --------------------------------------------------------------------------------