Alpine crash course on KVM
Here's a quick and messy checklist for running Alpine Linux on a KVM VPS.
-
SSH into the pre-installed OS and copy the network settings. They will be needed during network connection setup.
- Get an example IPv4 address, netmask and gateway:
ifconfig
orip link
- Get the default nameservers (or set your own):
cat /etc/resolv.conf
- Get an example IPv4 address, netmask and gateway:
-
Get the link to a suitable ISO image for your server architecture from the Alpine Linux website, e.g.
alpine-virt-3.15.0-x86_64.iso
-
Log into the VPS control panel. The exact wording may differ, but most control panels for KVM/Xen will have these features.
- ISO > Add ISO and paste the ISO link to the Virtual image
- List VPS > Manage (next to the vps name) > Settings > VPS
Configuration
- Temporarily change the boot order: 1) CD Drive 2) Hard Disk
- Select ISO: (select the custom user ISO)
- Save and reboot the VPS
-
Log into the VPS via VNC. Most control panels have a VNC address for external clients and/or a built-in web VNC client for system recovery.
-
Get the CD drive and disk device names:
df -h
- The CD drive usually has a name like
/dev/sr0
- Example of disk device name:
/dev/vda
- The CD drive usually has a name like
-
Unmount the vda device:
umount /media/vda
- This should be done before proceeding with the setup script, or it will fail during the disk partitioning with warnings about partitions not being found.
-
Run the setup script:
setup-alpine
- Example configuration for network setup:
- Available interface: eth0
- Ip address for eth0: (IPv4 address from ifconfig/ip link output)
- Netmask: (from ifconfig/ip link, e.g. 255.255.255.0)
- Gateway: (often .0 or .1 in the IPv4 address subnet, e.g. xxx.xxx.xxx.1)
- DNS nameserver(s): (enter IPs separated by commas)
- Make sure to get the network connection working or the disk setup will fail to download the utilities needed to partition the disk. If it is unable to update the repo list, it's very likely there is something wrong with the network setup — ctrl+c to exit the script and re-run the script while checking the connection details carefully.
- The
setup-disk
part of the script will create 3 partitions: boot (~105 MB), swap (~4173 MB) and root (fills the remaining space).
- Example configuration for network setup:
-
Before rebooting the VPS, go back to the VPS control panel, revert the boot order back to: 1) Hard Disk 2) CD Drive, set the ISO to none if you don't plan to reinstall again soon and save. Reboot from the control panel, as the VM may still be running on the previous boot order.
Additional setup
-
Edit the list of repos:
vi /etc/apk/repositories
- Remove the CD drive entry
/media/cdrom/apks
- Optionally uncomment the community repo and/or the edge repo URLs if you want to pull from the testing repos
- Remove the CD drive entry
- Refresh the repo index:
apk update
-
Install some essential packages, e.g. a different shell or editor:
apk add bash doas vim
-
Add a new standard user and include a SSH public key for login.
adduser $user
- From the ssh client:
ssh-copy-id -i ~/path/to/ssh/key.pub $user@$ip
-
Important: disable SSH root login and password authentication.
vi /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
- Restart sshd:
rc-service sshd restart
Firewall setup
If your VPS doesn't have IPv6, you can skip the ip6
parts.
-
Load the iptables modules:
modprobe ip_tables
modprobe ip6_tables
-
Install the packages:
apk add iptables ip6tables
-
Set services to start automatically at default runlevel:
rc-update add iptables
rc-update add ip6tables
-
Add a few simple firewall rules for IPv4, using the example to add more ports as needed:
nano /etc/iptables/ipv4.rules
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] # Allow existing connections and pings -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT # Allow ssh port -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT
-
Repeat for IPv6:
nano /etc/iptables/ipv6.rules
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j REJECT -A FORWARD -j REJECT COMMIT
-
Apply the rules:
iptables-restore < /etc/iptables/ipv4.rules
ip6tables-restore < /etc/iptables/ipv6.rules
/etc/iptables/rules-save
/etc/ip6tables/rules-save
-
To see currently active rules, use
iptables -L
andip6tables -L
. -
Start the firewall:
rc-service iptables start
rc-service ip6tables start
Troubleshooting
Changing the network connection details
-
eth0 configuration:
vi /etc/network/interfaces
iface eth0 inet static address $address netmask 255.255.255.0 gateway $gateway
-
Edit nameservers:
vi /etc/resolv.conf
nameserver $dns1 nameserver $dns2
-
Restart the network interface:
ifdown eth0
ifup eth0
Documentation
- Installation overview
- Install from an ISO to a Virtualbox machine
- setup-alpine documentation
- setup-alpine source
Further reading
- Alpine Wall — firewall frontend
- nixCraft article on Awall
- fail2ban — ban unauthorised SSH login attempts
- crazy-max/docker-fail2ban