|
#!/bin/bash |
|
|
|
# NOTES: Run this as root |
|
|
|
set -euo pipefail |
|
|
|
# Variables to fill out |
|
GITHUB_ORG_NAME="Capfolio-com" |
|
LINUX_USER="" # Linux user that's used to sign in (ie admin/sudo user) |
|
PASSWORD_NEW="" |
|
PRIVATE_NETWORK_IP="" # Eg 10.88.88.1 |
|
PRIVATE_NETWORK_REGISTRY="" # Eg 10.88.88.2:5000 |
|
ACTIONS_RUNNER_TOKEN="" |
|
DOCKER_BUILDX_VERSION="v0.12.0" # https://github.com/docker/buildx/releases |
|
|
|
# Validation for said variables |
|
if [ -z "${GITHUB_ORG_NAME-}" ]; then echo "ACTIONS_RUNNER_TOKEN is not set"; exit 1; fi |
|
if [ -z "${LINUX_USER-}" ]; then echo "LINUX_USER is not set"; exit 1; fi |
|
if [ -z "${PASSWORD_NEW-}" ]; then echo "PASSWORD_NEW is not set"; exit 1; fi |
|
if [ -z "${PRIVATE_NETWORK_IP-}" ]; then echo "PRIVATE_NETWORK_IP is not set"; exit 1; fi |
|
if [ -z "${PRIVATE_NETWORK_REGISTRY-}" ]; then echo "PRIVATE_NETWORK_IP is not set"; exit 1; fi |
|
if [ -z "${ACTIONS_RUNNER_TOKEN-}" ]; then echo "ACTIONS_RUNNER_TOKEN is not set"; exit 1; fi |
|
if [ -z "${DOCKER_BUILDX_VERSION-}" ]; then echo "DOCKER_BUILDX_VERSION is not set"; exit 1; fi |
|
|
|
# Set global context |
|
export NEEDRESTART_MODE="a" |
|
|
|
# Change password |
|
echo -e "$PASSWORD_NEW\n$PASSWORD_NEW" | passwd $LINUX_USER |
|
|
|
# Base utils |
|
apt update |
|
apt dist-upgrade -y |
|
apt install -y nano wget curl screen build-essential pwgen |
|
|
|
# Create the user |
|
PASSWORD_ACTIONS="$(pwgen 16 1)" |
|
useradd -m -s /usr/sbin/nologin actions |
|
echo -e "$PASSWORD_ACTIONS\n$PASSWORD_ACTIONS" | passwd actions |
|
|
|
# Setup the actions runner |
|
cat <<EOF > /home/actions/provision.sh |
|
#!/bin/bash |
|
|
|
set -euo pipefail |
|
|
|
cd ~ |
|
mkdir actions-runner && cd actions-runner |
|
curl -o actions-runner-linux-x64-2.311.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz |
|
echo "29fc8cf2dab4c195bb147384e7e2c94cfd4d4022c793b346a6175435265aa278 actions-runner-linux-x64-2.311.0.tar.gz" | shasum -a 256 -c |
|
tar xzf ./actions-runner-linux-x64-2.311.0.tar.gz |
|
./config.sh --url https://github.com/$GITHUB_ORG_NAME --token "$ACTIONS_RUNNER_TOKEN" |
|
EOF |
|
|
|
chown actions.actions /home/actions/provision.sh |
|
chmod +x /home/actions/provision.sh |
|
su -s /bin/bash -c '/home/actions/provision.sh' actions |
|
rm /home/actions/provision.sh |
|
|
|
# Node.js -- needed by the actions |
|
apt install -y ca-certificates curl gnupg |
|
mkdir -p /etc/apt/keyrings |
|
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg |
|
NODE_MAJOR=20 |
|
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list |
|
apt update |
|
apt install nodejs -y |
|
|
|
# Yarn -- needed by the actions |
|
corepack enable |
|
|
|
# Docker plugins -- needed by actions |
|
mkdir -p /home/actions/.docker/cli-plugins |
|
wget "https://github.com/docker/buildx/releases/download/${DOCKER_BUILDX_VERSION}/buildx-${DOCKER_BUILDX_VERSION}.linux-amd64" -O /home/actions/.docker/cli-plugins/docker-buildx |
|
chmod +x /home/actions/.docker/cli-plugins/docker-buildx |
|
chown -R actions.actions /home/actions/.docker |
|
|
|
# Docker -- needed by actions |
|
apt install -y dbus-user-session uidmap iptables systemd-container |
|
machinectl shell actions@ /bin/bash -c 'curl -fsSL https://get.docker.com/rootless | sh' |
|
loginctl enable-linger actions |
|
systemctl --user -M actions@ enable docker |
|
|
|
# Automatic updates |
|
apt install -y unattended-upgrades apt-listchanges |
|
|
|
# Setup IP address for private network interface |
|
NETPLAN_CONFIG="/etc/netplan/00-installer-config.yaml" |
|
cat <<EOF > /tmp/provision-ens4_config.tmp |
|
ens4: |
|
dhcp4: false |
|
addresses: |
|
- ${PRIVATE_NETWORK_IP}/24 |
|
EOF |
|
|
|
cp $NETPLAN_CONFIG "${NETPLAN_CONFIG}.bak" |
|
sed -i '/ethernets:/r /tmp/provision-ens4_config.tmp' /etc/netplan/00-installer-config.yaml |
|
# ^ Storing in a temp file because sed doesn't like inline multiline inputs |
|
netplan apply |
|
|
|
# Pre-emptively setup the systemd service file for Github Actions |
|
cat <<EOF > /etc/systemd/system/actions-runner.service |
|
[Unit] |
|
Description="GitHub Actions Runner" |
|
Wants=network-online.target |
|
After=network-online.target |
|
|
|
[Service] |
|
Environment=PATH=/home/actions/bin:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/local/games:/snap/bin |
|
Environment=XDG_RUNTIME_DIR=/run/user/$(id -u actions) |
|
Environment=DOCKER_HOST=unix:///run/user/$(id -u actions)/docker.sock |
|
ExecStart=/home/actions/actions-runner/bin/runsvc.sh |
|
WorkingDirectory=/home/actions/actions-runner |
|
User=actions |
|
Group=actions |
|
KillMode=process |
|
KillSignal=SIGTERM |
|
TimeoutStopSec=5min |
|
Restart=always |
|
RestartSec=3s |
|
|
|
[Install] |
|
WantedBy=multi-user.target |
|
EOF |
|
|
|
systemctl daemon-reload |
|
systemctl enable actions-runner |
|
|
|
# Setup env variables |
|
cat <<EOF > /home/actions/actions-runner/.env |
|
LANG=C.UTF-8 |
|
XDG_RUNTIME_DIR=/run/user/$(id -u actions) |
|
DOCKER_HOST=unix:///run/user/$(id -u actions)/docker.sock |
|
EOF |
|
cat << 'EOF' > /home/actions/actions-runner/.path |
|
/home/actions/bin:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/local/games:/snap/bin |
|
EOF |
|
|
|
chown actions.actions /home/actions/actions-runner/.env |
|
|
|
# Harden ssh |
|
cat <<EOF >> /etc/ssh/sshd_config |
|
AllowUsers $LINUX_USER |
|
PermitRootLogin no |
|
|
|
ForceCommand /bin/false |
|
|
|
Match User $LINUX_USER |
|
ForceCommand /bin/bash |
|
EOF |
|
sudo systemctl restart ssh |
|
|
|
# Tell docker to allow insecure registry for local registry host |
|
mkdir -p /home/actions/.config/docker |
|
cat <<EOF > /home/actions/.config/docker/daemon.json |
|
{ |
|
"insecure-registries": ["$PRIVATE_NETWORK_REGISTRY"] |
|
} |
|
EOF |
|
chown -R actions.actions /home/actions/.config |
|
|
|
# Start the thing |
|
systemctl restart actions-runner |
|
systemctl --user -M actions@ restart docker |
|
systemctl status actions-runner |
|
systemctl --user -M actions@ status docker |
|
|
|
# Firewall |
|
apt install -y ufw |
|
ufw allow ssh |
|
ufw default reject |
|
ufw --force enable |