Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document how to customize LXC fs #2

Open
3 of 4 tasks
coolaj86 opened this issue Mar 21, 2023 · 0 comments
Open
3 of 4 tasks

Document how to customize LXC fs #2

coolaj86 opened this issue Mar 21, 2023 · 0 comments

Comments

@coolaj86
Copy link
Contributor

coolaj86 commented Mar 21, 2023

This now has its own repo: https://github.com/bnnanet/bnna-customizers.

Todo:

Download Alpine Container

# "local" is a default name for storage
pveam update
pveam list local
pveam available
pveam download local alpine-3.17-default_20221129_amd64.tar.xz
pveam list local
# "cephfs0" is the name we have on cehpfs0
pveam update ; \
pveam list cephfs0 ; \
pveam available ; \
pveam download cephfs0 alpine-3.18-default_20230607_amd64.tar.xz ; \
pveam list cephfs0 ;

Copy & Unpack

pushd /var/lib/vz/template/cache/
mkdir ./alpine-3.17-custom/
pushd ./alpine-3.17-custom/
tar xvf ../alpine-3.17-ssh+webi_20221129_amd64.tar.xz
pushd /mnt/pve/cephfs0/template/cache/ ; \
mkdir ./alpine-3.18-custom/ ; \
pushd ./alpine-3.18-custom/ ; \
tar xvf ../alpine-3.18-default_20230607_amd64.tar.xz ;

Mount /dev & Chroot

cp -RPp /etc/resolv.conf ./etc/resolv.conf ; \
mount -t proc /proc proc/ ; \
mount --rbind /sys sys/ ; \
mount --make-rslave sys/ ; \
mount --rbind /dev dev/ ; \
mount --make-rslave dev/ ; \
chroot ./ /bin/sh -i ;

Modify

#
# ./etc/apk/world
#
apk --no-cache update ; \
apk --no-cache add sudo openssh libcap ; \
apk --no-cache add curl fish git htop screen vim wget xz unzip ; \
rc-update add sshd ; \
rc-update add firstboot ; \

#
# 'app' user w/ sudo
#
adduser -D -s /bin/ash -g '' 'app' app ; \
sed -i 's/app:!/app:*/' /etc/shadow ; \
adduser app wheel ; \
echo "app ALL=(ALL:ALL) NOPASSWD: ALL" | tee "/etc/sudoers.d/app" ; \
chmod 0600 /etc/sudoers.d/app ; \
vi /etc/sudoers.d/app ;
# as the 'app' user
su app
cd /home/app

mkdir -p /home/app/.ssh/
chmod 0700 /home/app/.ssh/
chown -R app:app /home/app/

echo 'screen -xRS awesome -s fish' >> .profile
ln -s .profile .bashrc

curl -sS https://webi.sh/ | sh ; \
source ~/.config/envman/PATH.env ; \
webi ssh-pubkey ssh-authorize aliasman bat rg ;\

# also add serviceman-add:
# https://github.com/therootcompany/serviceman/issues/7

mkdir -p /home/app/bin ; \
chmod 0700 /home/app/.config /home/app/.profile /home/app/bin ; \
chmod 0750 /home/app/.local /home/app/.local/* ; \
chmod 0700 /home/app/.config/envman/ ; \
chmod 0755 /home/app/.config/envman/load.sh ; \
chmod 0600 /home/app/.config/envman/PATH.env ;

mkdir -p ~/bin/
echo 'export PATH="$HOME/bin:$PATH"' >> /home/app/.config/envman/PATH.env

echo '// prefix=/home/app/.npm/node_modules' >> ~/.npmrc
chown 0600 ~/.npmrc

~/.config/envman/alias.env:

alias rnd='xxd -l24 -p /dev/urandom | xxd -r -p | base64 | tr -d = | tr + - | tr / _'
alias rnd16='xxd -c 0 -l 40 -p /dev/urandom'
alias rnd32='xxd -c 0 -l 256 -p /dev/urandom | xxd -r -ps | base64 | tr -d [:space:]/+_=- | tr -d abcdefghijklmnopqrstuvwxyzILOU | cut -c 1-80'
alias rnd58='xxd -c 0 -l 256 -p /dev/urandom | xxd -r -ps | base64 | tr -d [:space:]/+_=- | tr -d 0IOl | cut -c 1-80'
alias rnd62='xxd -c 0 -l 256 -p /dev/urandom | xxd -r -ps | base64 | tr -d [:space:]=+/_- | cut -c 1-80'
alias rnd64='xxd -c 0 -l 256 -p /dev/urandom | xxd -r -ps | base64 | tr -d [:space:]= | tr + - | tr / _ | cut -c 1-80'
# add keys to root user
vi /etc/init.d/firstboot

# 'no' to 'PasswordAuthentication', 'KbdInteractiveAuthentication'
# prohibit-password to 'PermitRootLogin' (or just no?)
# AllowTcpForwarding no => yes
# GatewayPorts no => yes
# Banner ??
vi /etc/ssh/sshd_config
# logout of 'app'
exit

Unchroot & Unmount

# exit 'chroot'
exit
umount -R ./proc ; \
umount -R ./sys ; \
umount -R ./dev

Cleanup

rm -rf \
  ./home/app/Downloads/ \
  ./home/app/.ash_history

rm -rf \
  ./root/Downloads/ \
  ./root/.bashrc

rm -f ./root/.ash_history
rm -f ./etc/resolv.conf ./etc/group- ./etc/passwd- ./etc/shadow-
rm -f ./dev/null
rm -rf ./tmp/*

# CCYYMMDDhhmm
touch -t '202406011205' ./etc/resolv.conf
rm -f ../alpine-3.17-ssh+webi_20221129_amd64.tar.xz
tar cvf ../alpine-3.17-ssh+webi_20221129_amd64.tar .
popd
xz ./alpine-3.17-ssh+webi_20221129_amd64.tar

firstboot script

#!/sbin/openrc-run

# The first boot init service

# read kernel options
init_KOPT() {
        eval "set -- $(cat /proc/cmdline 2>/dev/null)"
        for opt; do
                case "$opt" in
                        ssh_*=*)
                                eval "KOPT_${opt%%=*}='${opt#*=}'" ;;
                esac
        done
}

start() {
        rm -f /etc/runlevels/*/$RC_SVCNAME
        init_KOPT
        local rc=0
        ebegin "Starting ${RC_SVCNAME}"

        # custom: bnna account security
        einfo "Disabling Root Password"
        sed -i 's/root:[^:]\+/root:*/' /etc/shadow

        # custom: bnna first boot update
        einfo "Updating package cache"
        apk update --no-cache

        if [ -n "$KOPT_ssh_key" ] && [ ! -f "/root/.ssh/authorized_keys" ]; then
                einfo "Fetching ssh keys"
                mkdir -pm 700 /root/.ssh
                checkpath -fm 0600 /root/.ssh/authorized_keys
                case "$KOPT_ssh_key" in
                        https://*|ftps://*|http://*)
                                wget -q "$KOPT_ssh_key" -O /root/.ssh/authorized_keys
                                rc=$?;;
                        *) echo "$KOPT_ssh_key" > /root/.ssh/authorized_keys;;
                esac
        fi

        # custom: for bnna 'app' user
        mkdir -p /home/app/.ssh
        chown 0700 /home/app/.ssh
        cp -RPp /root/.ssh/authorized_keys /home/app/.ssh/authorized_keys
        checkpath -fm 0600 /home/app/.ssh/authorized_keys
        chown -R app:app /home/app/.ssh

        eend $rc
}

~/README.md

# Welcome to Alpine, BNNA Edition

BNNA's Alpine is slightly different from the stock filesystem.

We've tried to strike a good balance between the minimalism of Alpine,
a few utilities to help you get started here, and an easy way to downsize.

## Table of Contents

- Default Shell
- Developer Utilities
- Installed Packages
- SSH Config
- Uinstall it all

## Default Shell

`screen` and `fish` are set in `~/.profile`.

- `screen` is the default session manager.
  - Next tab: ctrl+a, n
  - New tab: ctrl+a, c
- `fish` is the default shell.
  - immediate typeahead
  - search with up and down arrows

However, it is not POSIX-compatible.
If you need to paste in shell script snippets, drop down to `sh` first.

## Developer Utilities

`~/.config/envman/PATH.env` is sourced to set the `PATH`.

It includes the following:

```text
~/bin/
~/.local/bin/
```

`~/bin` is recommended for your own scripts and programs.

`~/.local/bin` and `~/.local/opt/<program>/bin` will be used
for scripts and programs you install.

### Helpful Commands & Aliases

```text
# install the latest versions of developer tools, direct from the release api
# (bun, caddy, duckdns, flutter, go, gh, hugo, jq, lsd, node, ollama,
# powershell, python, rg, rust, sclient, vim-essentials, zig, + many more)

webi
```

```text
# add aliases
aliasman

# like cat, but with syntax highlighting
bat

# show the external ip address
myip

# like grep, but respects .gitignore, .ignore, etc
rg

# creates, enables, and starts an openrc daemon for the given command
# ex: serviceman add --name 'my-app' -- node ./server.js
serviceman

# show current public key
ssh-pubkey

# add file or url to ~/.ssh/authorized_keys
ssh-authorize

# allows user programs to listen on privileged ports via libcap
setcap-netbind

# to lint shell scripts
shellcheck

# to format shell scripts
shfmt

# vim-sensible, vim-ale, and other automatic plugins
~/.vim/
```

### Aliases

```text
cat       # bat (cat with syntax highlighting)
diffy     # diff -y --suppress-common-lines
rnd       # random string
rnd16     # random hex string
rnd32     # random base32 (Crockford) string
rnd58     # random base58 (cryptocurrency) string
rnd62     # random base62 (GitHub token) string
rnd64     # random (url-safe) base64 string
rnd64rfc  # random (rfc) base64 string
ts        # timestamp as YYYY-MM-DD_hh.mm.ss
vi        # vim
```

## Installed Packages

We've added a number of packages that are not included in the Alpine base.

We document those here to prevent any surpises and to make it easier for you
to take control and make it yours.

### System Packages

DO NOT remove unless you know exactly what you're doing - otherwise your
instance may become unrecoverable.

```text
sudo       # to run any command as root
openssh    # to be able to remote into your instance
logrotate  # to prevent running out of storage from logs
```

### Convenience Packages

```text
curl fish git htop less screen vim wget xz unzip

libcap   # for setcap-netbind
```

## SSH

```text
/etc/ssh/sshd_config
~/.ssh/authorized_keys
~/.ssh/config
~/.ssh/config.d/bnna.d/example.sshconfig
```

### Keys generated on first boot

```text
~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub
~/.ssh/id_ecdsa
~/.ssh/id_ecdsa.pub
```

### Key-only login

```text
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
```

### Port Forwarding Enabled

```text
AllowTcpForwarding yes
GatewayPorts yes
```

## Uninstall it all

To uninstall the non-stock files and programs which are not necessary to use the instance:

```sh
rm -f ~/.profile ~/.bashrc ~/.npmrc
rm -rf ~/.config/envman ~/.config/fish
rm -rf ~/bin ~/.local/bin ~/.local/opt

sudo --no-cache apk del curl fish git htop less screen vim wget xz unzip

rm -f ~/README.md
```

This will keep:
- `openssh` - needed to access the instance
- `sudo` and `libcap` - needed if you keep access to a user account
- `logrotate` - needed if your services have logs

To remove the 'app' user and only run as `root`, see the SSH configuration above, and then remove the following:

```sh
sudo cp -RPp ~/.ssh /root/
sudo chown -R root:root /root/
rm /etc/sudoers.d/app
deluser --remove-home app
delgroup app
```
@coolaj86 coolaj86 changed the title document custom image Document how to customize LXC fs Mar 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant