Download - Alpine Linux
-
ALPINE LINUX
TUTORIALS AND HOWTOS
http://wiki.alpinelinux.org/
NETWORKING
-
The tutorials are hands-on and the reader is expected to try and achieve the goals described in each
step, possibly with the help of a good example. The output in one step is the starting point for the
following step.
Networking
Configure Networking
Setting System Hostname
To set the system hostname, do something like the following:
echo "shortname" > /etc/hostname
Then, to activate the change, do the following:
hostname -F /etc/hostname
If you're using IPv6, you should also add the following special IPv6 addresses to your /etc/hosts file:
::1 localhost ipv6-localhost ipv6-loopback
fe00::0 ipv6-localnet
ff00::0 ipv6-mcastprefix
ff02::1 ipv6-allnodes
ff02::2 ipv6-allrouters
ff02::3 ipv6-allhosts
Tip: If you are going to use automatic IP configuration, such as IPv4 DHCP or IPv6 Stateless
Autoconfiguration, you can skip ahead to Configuring DNS. Otherwise, if you are going to use a
static IPv4 or IPv6 address, continue below.
For a static IP configuration, it's common to also add the machine's hostname you just set (above) to the
/etc/hosts file.
Here's an IPv4 example:
192.168.1.150 shortname.domain.com
And here's an IPv6 example:
Welcome to Tutorials and HowtoS
-
2001:470:ffff:ff::2 shortname.domain.com
Configuring DNS Tip: For users of IPv4 DHCP: Please note that /etc/resolv.conf will be completely overwritten
with any nameservers provided by DHCP. Also, if DHCP does not provide any nameservers, then
/etc/resolv.conf will still be overwritten, but will not contain any nameservers!
For using a static IP and static nameservers, use one of the following examples.
For IPv4 nameservers, edit your /etc/resolv.conf file to look like this:
The following example uses Google's Public DNS servers.
nameserver 8.8.8.8
nameserver 8.8.4.4
For IPv6 nameservers, edit your /etc/resolv.conf file to look like this:
The following example uses Hurricane Electric's public DNS server.
nameserver 2001:470:20::2
You can also use Hurricane Electric's public DNS server via IPv4:
nameserver 74.82.42.42
Tip: If you decide to use Hurricane Electric's nameserver, be aware that it is 'Google-whitelisted'.
What does this mean? It allows you access to many of Google's services via IPv6. (Just don't add
other, non-whitelisted, nameservers to /etc/resolv.conf ironically, such as Google's Public DNS
Servers.) Read here for more information.
Enabling IPv6 (Optional)
If you use IPv6, do the following to enable IPv6 for now and at each boot:
modprobe ipv6
echo "ipv6" >> /etc/modules
Interface Configuration
Loopback Configuration (Required)
Note: The loopback configuration must appear first in /etc/network/interfaces to prevent
networking issues.
To configure loopback, add the following to a new file /etc/network/interfaces:
auto lo
iface lo inet loopback
The above works to setup the IPv4 loopback address (127.0.0.1), and the IPv6 loopback address (::1)
if you enabled IPv6.
-
Wireless Configuration
See Connecting to a wireless access point.
Ethernet Configuration
For the following Ethernet configuration examples, we will assume that you are using Ethernet device
eth0.
Initial Configuration
Add the following to the file /etc/network/interfaces, above any IP configuration for eth0:
auto eth0
IPv4 DHCP Configuration
Add the following to the file /etc/network/interfaces, below the auto eth0 definition:
iface eth0 inet dhcp
IPv4 Static Address Configuration
Add the following to the file /etc/network/interfaces, below the auto eth0 definition:
iface eth0 inet static
address 192.168.1.150
netmask 255.255.255.0
gateway 192.168.1.1
IPv6 Stateless Autoconfiguration
Add the following to the file /etc/network/interfaces, below the auto eth0 definition:
iface eth0 inet6 manual
pre-up echo 1 > /proc/sys/net/ipv6/conf/eth0/accept_ra
Tip: The "inet6 manual" method is available in busybox 1.17.3-r3 and later.
IPv6 Static Address Configuration
Add the following to the file /etc/network/interfaces, below the auto eth0 definition:
iface eth0 inet6 static
address 2001:470:ffff:ff::2
netmask 64
gateway 2001:470:ffff:ff::1
pre-up echo 0 > /proc/sys/net/ipv6/conf/eth0/accept_ra
Example: Dual-Stack Configuration
This example shows a dual-stack configuration.
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.150
netmask 255.255.255.0
gateway 192.168.1.1
-
iface eth0 inet6 static
address 2001:470:ffff:ff::2
netmask 64
gateway 2001:470:ffff:ff::1
pre-up echo 0 > /proc/sys/net/ipv6/conf/eth0/accept_ra
Firewalling with iptables and ip6tables
See also: Alpine Wall - How-To Alpine Wall - Alpine Wall User's Guide
Install iptables/ip6tables
To install iptables:
apk add iptables
To install ip6tables:
apk add ip6tables
To install the man pages for iptables and ip6tables:
apk add iptables-doc
Configure iptables/ip6tables
Tip: Good examples of how to write iptables rules can be found at the Linux Home Networking Wiki
http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_
Using_iptables
Save Firewall Rules
For iptables
1. Set iptables to start on reboot
o rc-update add iptables
2. Write the firewall rules to disk
o /etc/init.d/iptables save
3. If you use Alpine Local Backup: 1. Save the configuration
lbu ci
-
For ip6tables
1. Set ip6tables to start on reboot
o rc-update add ip6tables
2. Write the firewall rules to disk
o /etc/init.d/ip6tables save
3. If you use Alpine Local Backup: 1. Save the configuration
lbu ci
Activating Changes and Testing Connectivity
Changes made to /etc/network/interfaces can be activated by running:
/etc/init.d/networking restart
If you did not get any errors, you can now test that networking is configured properly by attempting to
ping out:
ping www.google.com
PING www.l.google.com (74.125.47.103) 56(84) bytes of data.
64 bytes from yw-in-f103.1e100.net (74.125.47.103): icmp_seq=1 ttl=48 time=58.5 ms
64 bytes from yw-in-f103.1e100.net (74.125.47.103): icmp_seq=2 ttl=48 time=56.4 ms
64 bytes from yw-in-f103.1e100.net (74.125.47.103): icmp_seq=3 ttl=48 time=57.0 ms
64 bytes from yw-in-f103.1e100.net (74.125.47.103): icmp_seq=4 ttl=48 time=60.2 ms
^C
--- www.l.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3007ms
rtt min/avg/max/mdev = 56.411/58.069/60.256/1.501 ms
For an IPv6 traceroute (traceroute6), you will first need to install the iputils package:
apk add iputils
Then run traceroute6:
traceroute6 ipv6.google.com
traceroute to ipv6.l.google.com (2001:4860:8009::67) from 2001:470:ffff:ff::2, 30
hops max, 16 byte packets
1 2001:470:ffff:ff::1 (2001:470:ffff:ff::1) 3.49 ms 0.62 ms 0.607 ms
2 * * *
3 * * *
4 pr61.iad07.net.google.com (2001:504:0:2:0:1:5169:1) 134.313 ms 95.342 ms
88.425 ms
5 2001:4860::1:0:9ff (2001:4860::1:0:9ff) 100.759 ms 100.537 ms 89.907 ms
6 2001:4860::1:0:5db (2001:4860::1:0:5db) 115.563 ms 102.946 ms 106.191 ms
-
7 2001:4860::2:0:a7 (2001:4860::2:0:a7) 101.754 ms 100.475 ms 100.512 ms
8 2001:4860:0:1::c3 (2001:4860:0:1::c3) 99.272 ms 111.989 ms 99.835 ms
9 yw-in-x67.1e100.net (2001:4860:8009::67) 101.545 ms 109.675 ms 99.431 ms
Additional Utilities
iproute2
You may wish to install the 'iproute2' package (note that this will also install iptables if not yet
installed)
apk add iproute2
This provides the 'ss' command which is IMHO a 'better' version of netstat.
Show listening tcp ports:
ss -tl
Show listening tcp ports and associated processes:
ss -ptl
Show listening and established tcp connections:
ss -ta
Show socket usage summary:
ss -s
Show more options:
ss -h
drill
You may also wish to install 'drill' (it will also install the 'ldns' package) which is a superior (IMHO)
replacement for nslookup and dig etc:
apk add drill
Then use it as you would for dig:
-
drill alpinelinux.org @8.8.8.8
To perform a reverse lookup (get a name from an IP) use the following syntax:
drill -x 8.8.8.8 @208.67.222.222
Connecting to a wireless access point
First make sure your wireless drivers are loded properly. (if you are using a Broadcom chipset, see note
at the end of this post.)
Install wireless-tools and wpa_supplicant.
apk add wireless-tools wpa_supplicant
Bring the link up so we can look for wireless networks. (An error here means you probably need extra
drivers/firmware.)
ip link set wlan0 up
Find a network to connect to. Look for the ESSID. In this example we will use the ESSID "MyNet".
iwlist wlan0 scanning
Lets set the ESSID:
iwconfig wlan0 essid MyNet
We need to create a shared key for wpa_supplicant.
wpa_passphrase MyNet > wpa.conf
It will wait for the password from stdin. Enter the password and enter. Now you will have a wpa.conf
file with the preshared key.
Start wpa_supplicant with the generated config:
wpa_supplicant -Dwext -iwlan0 -c ./wpa.conf
From another console, start dhcpcd:
-
udhcpc -i wlan0
You should get an IP address.
You then want to make the connection process automatic on boot-up. Open
/etc/network/interfaces and add the following stanza:
auto wlan0
iface wlan0 inet dhcp
You will also need to set wpa_supplicant to start automatically on boot:
rc-update add wpa_supplicant boot
Next, create /etc/wpa_supplicant/ (permissions of 755 with root:root are fine), and move wpa.conf
into that folder, renaming it to wpa_supplicant.conf.
Reboot and check that you are associated with the access point:
iwconfig wlan0
and check that you got a DHCP lease:
ifconfig wlan0 | grep addr
Note: BROADCOM WIFI CHIPSET USERS will need to compile the firmware manually for their
chipset. First, apk add alpine-sdk, then git clone aports from git.alpinelinux.org, switch to the
aports/non-free/b43-firmware folder, then run abuild -r. Install the generated apk file. Run fwcutter,
and you should be good to go.
Bonding Note: Alpine Linux v2.4 or later is required
Installation
First, install the bonding package. This will give you support for bonding in the /etc/network/interfaces
file.
apk add bonding
Configuration
Edit the /etc/network/interfaces file:
auto bond0
iface bond0 inet static
address 192.168.0.2
-
netmask 255.255.255.0
gateway 192.168.0.1
# specify the ethernet interfaces that should be bonded
bond-slaves eth0 eth1 eth2 eth3
The keyword is bond-slaves that will make ifup add the slaves to the bond0 interface.
References: http://www.kernel.org/doc/Documentation/networking/bonding.txt
Vlan
Installation
First, install the vlan package. This will give you support for vlans in the /etc/network/interfaces file.
apk add vlan
Configuration
Edit the /etc/network/interfaces file:
auto eth0.8
iface eth0.8 inet static
address 192.168.0.2
netmask 255.255.255.0
gateway 192.168.0.1
With the vlan package installed ifup will find the trailing .8 in eth0.8 and will create a vlan interface
with vid 8 over eth0.
Alternative with vlan8 over eth0:
auto vlan8
iface vlan8 inet static
address 192.168.0.2
netmask 255.255.255.0
gateway 192.168.0.1
vlan-raw-device eth0
In those examples a static ip address was used but it works with dhcp as well.
Example with vlans over bonding
In this example we will bond eth1 and eth2 interfaces and create vlan trunks with vid 8, 64 and 96. The
gateway (ISP) is on eth0.
auto eth0
iface eth0 inet dhcp
auto bond0
# use manual because the bond0 interface should not have any ip.
iface bond0 inet manual
bond-slaves eth1 eth2
# bring up the vlans with 'ifup bond0'
up ifup bond0.8
up ifup bond0.64
-
up ifup bond0.96
down ifdown bond0.96
down ifdown bond0.64
down ifdown bond0.8
# no auto since ifup bond0 will bring this up
iface bond0.8 inet static
address 10.65.8.1
netmask 255.255.255.0
iface bond0.64 inet static
address 10.65.64.1
netmask 255.255.255.0
iface bond0.96 inet static
address 10.65.96.1
netmask 255.255.255.0
Bridge
Using brctl
Bridges are manually managed with the brctl command.
Usage: brctl COMMAND [BRIDGE [INTERFACE]]
Manage ethernet bridges
Commands:
show Show a list of bridges
addbr BRIDGE Create BRIDGE
delbr BRIDGE Delete BRIDGE
addif BRIDGE IFACE Add IFACE to BRIDGE
delif BRIDGE IFACE Delete IFACE from BRIDGE
setageing BRIDGE TIME Set ageing time
setfd BRIDGE TIME Set bridge forward delay
sethello BRIDGE TIME Set hello time
setmaxage BRIDGE TIME Set max message age
setpathcost BRIDGE COST Set path cost
setportprio BRIDGE PRIO Set port priority
setbridgeprio BRIDGE PRIO Set bridge priority
stp BRIDGE [1|0] STP on/off
To manually create a bridge interface br0:
brctl addbr br0
To add interface eth0 and eth1 to the bridge br0:
brctl addif br0 eth0
brctl addif br0 eth1
Note that you need to set the link status to up on the added interfaces.
ip link set dev eth0 up
-
ip link set dev eth1 up
Configuration file
Note: Alpine Linux v2.4 or newer is required for this
Install the scripts that configures the bridge.
apk add bridge
Bridging is then configured in /etc/network/interfaces with the bridge-ports keyword. Note that you
normally don't assign ip addresses to the bridged interfaces (eth0 and eth1 in our example) but to the
bridge itself (br0).
In this example the address 192.168.0.1/24 is used.
auto br0
iface br0 inet static
bridge-ports eth0 eth1
bridge-stp 0
address 192.168.0.1
netmask 255.255.255.0
You can set the various options with those keywords:
bridge-aging
Set ageing time
bridge-fd
Set bridge forward delay
bridge-hello
Set hello time
bridge-maxage
Set bridge max message age
bridge-pathcost
Set path cost
bridge-portprio
Set port priority
bridge-bridgeprio
Set bridge priority
bridge-stp
STP on/off
Using pre-up/post-down
For older versions of Alpine Linux, or if you want be able to control the bridge interfaces individually,
you need to use pre-up/post-down hooks.
Example /etc/network/interfaces:
-
auto br0
iface br0 inet static
pre-up brctl addbr br0
pre-up echo 0 > /proc/sys/net/bridge/bridge-nf-call-arptables
pre-up echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
pre-up echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
address 192.168.0.253
netmask 255.255.255.0
gateway 192.168.0.254
post-down brctl delbr br0
auto eth0
iface eth0 inet manual
up ip link set $IFACE up
up brctl addif br0 $IFACE
down brctl delif br0 $IFACE || true
down ip link set $IFACE down
auto eth1
iface eth1 inet manual
up ip link set $IFACE up
up brctl addif br0 $IFACE
down brctl delif br0 $IFACE || true
down ip link set $IFACE down
That way you create br0 with: ifup br0, and you can add/remove individual interfaces to the bridge with
ifup eth0, ifdown eth0.
Bridging for a Xen dom0
Bridging in a dom0 is a bit specific as it consists in bridging a real interface (i.e. ethX) with a virtual
interface (i.e. vifX.Y). At bridge creation time, the virtual interface does not exist and will be added by
the Xen toolstack when a domU is booting (see Xen documentation on how to link the virtual interface
to the correct bridge).
Particularities
- the bridge consists of a single physical interface
- the physical interface does not have an IP and is configured as manual
- the bridge will have the IP and will be auto, resulting in bringing up the physical interface
This translates to this sample config :
Example /etc/network/interfaces:
auto eth0
iface eth0 inet manual
auto br0
iface br0 inet static
address 192.168.0.253
netmask 255.255.255.0
gateway 192.168.0.254
bridge_ports eth0
bridge_stp 0
After the domU OS is started, the virtual interface wil be added and the working bridge can be checked
with
brctl show
ifconfig -a
-
OpenVSwitch
Installing OVS
apk add openvswitch
rc-update add ovs-modules
rc-update add ovsdb-server
rc-update add ovs-vswitchd
rc-service ovs-modules start
rc-service ovsdb-server start
rc-service ovs-vswitchd start
Using ovs-vsctl
Open VSwithes are manually managed with the ovs-vsctl command.
To manually create a switch named "lan":
ovs-vsctl add-br lan
To add interface eth0 to the switch "lan":
ovs-vsctl add-port lan eth0
Note that you need to set the link status to up on the added interfaces.
ip link set dev eth0 up
To see what OVS are defined:
ovs-vsctl list-br
To see what interfaces are linked to the lan OVS:
ovs-vsctl list-ports lan
To enable spanning tree (if needed):
ovs-vsctl set bridge lan stp_enable=true
LACP Timer setting 'fast' mode: ovs-vsctl set port bond0 other_config:lacp-time=fast
Using OVS appctl
ovs-appctl lacp/show bond0
Configuration file
configured in /etc/network/interfaces
-
auto eth0 lan
iface eth0 inet manual
up ifconfig eth0 0.0.0.0 up
down ifconfig eth0 down
iface lan inet dhcp
OVS and qemu
Helper scripts
ovs-ifup-
#!/bin/sh
switch=$(echo $0|/usr/bin/cut -d- -f3)
[ -z ${switch} ] && echo "Please define some symlink with suffix to use." && exit 1
[ $# -lt 1 ] && echo "Too few params. Must be 1 and is $#." && exit 2
/sbin/ifconfig $1 0.0.0.0 up
ovs-vsctl add-port ${switch} $1
logger "qemu: $1 added to ${switch} at startup of VM"
ovs-ifdown-
#!/bin/sh
switch=$(echo $0|/usr/bin/cut -d- -f3)
[ -z ${switch} ] && echo "Please define some symlink with suffix to use." && exit 1
[ $# -lt 1 ] && echo "Too few params. Must be 1 and is $#." && exit 2
/sbin/ifconfig $1 0.0.0.0 down
ovs-vsctl del-port ${switch} $1
logger "qemu: $1 removed from ${switch} at shutdown of VM"
OVS and LXC
Helper scripts
lxc-ovs-ifdown-
#!/bin/sh
switch=$(echo $0|/usr/bin/cut -d- -f4)
[ -z ${switch} ] && echo "Please define some symlink with suffix to use." && return
1
[ $# -lt 5 ] && echo "Too few params. Must be 5 and is $#." && exit 2
nic=$5
/usr/bin/ovs-vsctl del-port ${switch} ${nic}
/usr/bin/logger "lxc: ${nic} removed from ${switch} at shutdown of VM."
Caveats
Beware to have OVS package files available with no hassle at next reboot! this ca be a problem when
running from ram with no cache...
How to configure static routes
First, set the staticroute service to start automatically on boot by entering the following command:
rc-update add staticroute
-
You can now define your static routes in one of three ways:
Option 1: Edit /etc/conf.d/staticroute
Routes are added as a parameter value - the staticroute file has header information that explains the
syntax - for example:
staticroute="net 10.200.200.0 netmask 255.255.255.0 gw 192.168.202.12"
If you need to add multiple static routes, just add additional routes to the end of the text between the
quotes, with each route separated by a semicolon or a line break (press ENTER).
Option 2: Create /etc/route.conf
Use nano, vi, or your favourite installed editor to create the file /etc/route.conf and add each static route
on a separate line - for example:
net 10.200.200.0 netmask 255.255.255.0 gw 192.168.200.12
net 10.200.201.0 netmask 255.255.255.0 gw 192.168.200.13
Option 3: Setup routes in /etc/network/interfaces
If you have static network configuration in /etc/network/interfaces, you can add a static route that gets
activated when an interface gets brought up:
auto eth0
iface eth0 inet static
address 192.168.0.1
netmask 255.255.255.0
up ip route add 10.14.0.0/16 via 192.168.0.2
up ip route add 192.168.100.0/23 via 192.168.0.3
Once editing is complete, remember to save your changes if you are running the OS in RAM (eg:
booting from a USB stick) - if you are not sure how to do this, see this article: How to Boot Alpine
Linux and Save Settings on a USB Stick or Alpine_local_backup
You can verify your settings by restarting the server, or by issuing the following commands:
To add your defined static routes manually (for testing):
/etc/init.d/staticroute start
To remove your defined static routes:
/etc/init.d/staticroute stop
There is a 'restart' option to do an automatic stop/start, but it seems less reliable than using the two
above.
Alpine Wall
This sessions is a design and implementation plan for a new firewall management framework. The
new framework addresses the limitations of Shorewall, which is probably the most common
solution used with Alpine.
-
Proposal
We evaluated serveral existing open source projects, none of which satisfied our demanding taste. The
existing solutions are either too tied to specific (router) distributions, targeted to home users (with too
many assumptions built-in), or depedent on bloated frameworks (usually Perl). Moreover, we would
like to keep management of firewall settings and activation of such settings as two separate workflows,
which would facilitate centralized management of firewall rules.
As no readily available solution was found, the proposal is to implement a new management
framework for iptables, which would integrate with the Alpine Configuration Framework (ACF).
The framework is hereafter referred to as the Alpine Wall (awall).
Design
Awall would consist of three major components: data model, front-end, and back-end. It also
implements a plug-in architecture, which allows extending the data model and functionality, in order to
simplify common organization-specific administrative tasks.
The data model would describe the firewall configuration using concepts and terminology that is
roughly compatible with Shorewall. It would also borrow some useful concepts from other firewall
solutions we evaluated, such as the Service concept as defined in the Turtle Firewall (but generalized a
bit). Awall plug-ins can contain schema extension modules augmenting the basic model provided by
the framework.
The back-end is responsible for translating the model's data into configuration files, most notably the
files that can be read by iptables-restore and ip6tables-restore. Moreover, it can produce files
into e.g. /etc/modprobe.d and /etc/sysctl.d if necessary. When a plug-in extends the data model,
it must also provide a back-end module that interprets model extension and translates the data into
iptables and other rules. The framework includes a module for interpreting the base model. The
framework is responsible for ordering and aggregating the results produced by all modules into actual
configuration files.
The front-end is essentially an ACF module which allows editing the data model and activating the
changes with the help of the back-end. The front-end implements also a fallback mechanism that
prevents the operator from locking himself out by a faulty configuration. The configuration data is
stored in text files which can be directly edited. The front-end provides a command line tool for
validating and activating the configuration after manual changes.
Base Model
The basic data model could roughly look like as follows:
Zone
interface*, subnet*
Service
(protocol, port*)+
Forwarding policy
Zone:in*, Zone:out*, accept/reject/drop, masq_on/masq_off
Filtering rule
Zone:in*, Zone:out*, Service+, accept/reject/drop, conn_limit?, flow_limit?
NAT rule
snat/dnat, Zone:in*, Zone:out*, Service, ip4_range, port_range?
-
Subnets in zone definitions can be declared using IPv4/IPv6 addresses (CIDR notation), domain names,
or as references to ipsets. A domain name can resolve to one or more IP addresses. The referred ipsets
may be managed manually or by some other tool.
If a packet with source address a arrives on interface i, it is considered to originate from zone Z = (I, S)
(where I is the set of interfaces and S is the set of subnets) if and only if I includes i, and a belongs to
any subnet of S. In zone definitions, I would default to the set of all interfaces and S to {0.0.0.0/0, ::}.
The destination zone would be defined in a similar way based on the packet's destination address and
interface.
Implementation Considerations
The data model should preferably be based on some existing format, such as JSON, XML, or YAML.
In order to allow extensions to the data model, awall must define some kind of schema language. This
language would embed the necessary information the front-end needs to automatically generate a user
interface for the extension. For example, the help texts shown to the user would be placed in the
schema modules.
Ideally, the base model would be described using the very same language as the model extensions, but
it would impose quite demanding requirements on the language, e.g. support for complex data types. If
we select this approach and model the data using XML, we could use XML Schema as the basis. There
is also an (expired) Internet Draft on JSON Schema, but there seems to be no existing validator
implementation in C or Lua.
Even though elegant from architecture point of view, it is unlikely that support for complex data types
would be required by typical extensions. In most cases, a set of global variables of primitive types
would suffice. Therefore, we could just use a very simple language for declaring such variables or
implement support for a limited subset of some well-known schema language. In this alternative, the
base model would not be described using this language but rather hard-coded into the front-end.
The back-end modules are responsible for translating the configuration data into configuration file
fragments. As regards their implementation, we have two alternatives. The first alternative is to
implement them as Lua functions invoked by the framework in a defined way. The framework would
provide a library that allows the said functions to access the data model, and also otherwise assists in
their implementation. The functions would report the results back to the framework, which finally
would translate them into target files.
In the second alternative, the back-end modules would be implemented using a template language
rather than a general-purpose programming language. An example of a firewall-related template
language is ferm, which unfortunately is implemented in Perl. Ferm also lacks certain capabilities
required to implement e.g. the Zone and Service concepts conveniently. However, we could introduce a
new template language that would better suit our purposes. Such a language would eliminate some
redundancy from the back-end modules which necessarily comes with the use of a general-purpose
language. On the other hand, developing and maintaining such a language would take effort and might
make the framework initially more difficult to use.
The back-end will contain functionality for domain name resolution. In the data model, hosts of groups
thereof can be identified by their domain names. The back-end will resolve these to IP addresses, which
will be stored in the target files, so there will be no need to resolve anything when activating the
configuration during boot.
How-To Alpine Wall
Make sure you are running latest version by running the following commands:
apk update
-
apk add -u awall
apk version awall
Structure
Your AWall firewall configuration file(s) goes to /etc/awall/optional
Each such file is called Policy.
Note: AWall versions prior 0.2.12 will only look for Policy files in /usr/share/awall/optional.
From version 0.2.12 and higher, AWall will look for Policy files in both /etc/awall/optional and
/usr/share/awall/optional
You may have multiple Policy files (it is useful to have separate files for eg. HTTP,FTP and other
roles).
The Policy(s) can be enabled or disabled by using the "awall [enable|disable]" command.
Note: AWall's Policy files are not equivalent to Shorewalls /etc/shorewall/policy file.
An AWall Policy can contain definitions of:
variables (like /etc/shorewall/params) zones (like /etc/shorewall/zones) interfaces (like /etc/shorewall/interfaces) policies (like /etc/shorewall/policy) filters and NAT rules (like /etc/shorewall/rules) services (like /usr/share/shorewall/macro.HTTP)
Prerequisites
After installing AWall, you need to load the following iptables modules:
modprobe ip_tables
modprobe iptable_nat #if NAT is used
This is needed only the first time, after AWall installation.
Make the firewall autostart at boot and autoload the needed modules:
rc-update add iptables
A Basic Home Firewall
We will give a example on how you can convert a "Basic home firewall" from Shorewall to AWall.
Example firewall using Shorewall
Let's suppose you have the following Shorewall configuration:
-
/etc/shorewall/zones
inet ipv4
loc ipv4
/etc/shorewall/interfaces
inet eth0
loc eth1
/etc/shorewall/policy
fw all ACCEPT
loc inet ACCEPT
all all DROP
/etc/shorewall/masq
eth0 0.0.0.0/0
Example firewall using AWall
Now we will configure AWall to do the same thing as we just did with the above Shorewall example.
Create a new file called /etc/awall/optional/test-policy.json and add the following content to
the file.
Tip: You could call it something else as long as you save it in /etc/awall/optional/ and name it
???.json)
{
"description": "Home firewall",
"zone": {
"inet": { "iface": "eth0" },
"loc": { "iface": "eth1" }
},
"policy": [
{ "in": "_fw", "action": "accept" },
{ "in": "loc", "out": "inet", "action": "accept" }
],
"snat": [
{ "out": "inet" }
]
}
The above configuration will:
Create a description of your Policy Define zones Define policy Define snat (to masqurade the outgoing traffic)
Note: snat means "source NAT". It does not mean "static NAT".
Tip: AWall has a built-in zone named "_fw" which is the "firewall itself". This corresponds to the
Shorewall "fw" zone.
Activating/Applying a Policy
After saving the Policy you can run the following commands to activate your firewall settings:
-
awall list # Listing available 'Policy(s)' (This step is optional)
awall enable test-policy # Enables the 'Policy'
awall activate # Genereates firewall configuration from the 'Policy'
files and enables it (starts the firewall)
If you have multiple policies, after enabling or disabling them, you need to always run awall activate in
order to update the iptables rules.
Advanced Firewall settings
Assuming you have your /etc/awall/optional/test-policy.json with your "Basic home firewall"
settings, you could choose to modify that file to test the below examples.
Tip: You could create new files in /etc/awall/optional/ for testing some of the below examples
Logging
AWall will (since v0.2.7) automatically log dropped packets.
You could add the following row to the "policy" section in your Policy file in order to see the dropped
packets.
{ "in": "inet", "out": "loc", "action": "drop" }
Note: If you are using Alpine 2.4 repository (AWall v0.2.5 or below), you should use "action":
"logdrop" in order to log dropped packets .
Note: If you are adding the above content to an already existing file, then make sure you add ","
signs where they are needed!
Port-Forwarding
Let's suppose you have a local web server (192.168.1.10) that you want to make accessible from the
"inet".
With Shorewall you would have a rule like this in your /etc/shorewall/rules:
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL
# PORT(S) PORT(S) DEST
DNAT inet loc:192.168.1.10 tcp 80
Lets configure our AWall Policy file likewise by adding the following content.
"variable": {
"APACHE": "192.168.1.10",
"STATIC_IP": "1.2.3.4"
},
"filter": [
{ "in": "inet",
"dest": "$STATIC_IP",
"service": "http",
"action": "accept",
"dnat": "$APACHE"
}
]
As you can see in the above example, we create a
-
"variable" section where we specify some IP-addresses "filter" section where we do the actual port-forwarding (using the variables we just created
and using some preexisting "services" definitions)
Note: If you are adding the above content to a already existing file, then make sure you add ","
signs where they are needed!
Tip: AWall already has a "service" definition list for several services like HTTP, FTP, SNMP, etc. (see
/usr/share/awall/mandatory/services.json)
If you need to forward to a different port (e.g. 8080) you can do:
"dnat": [
{"in": "inet", "dest": "$STATIC_IP", "to-addr": "$APACHE", "service": "http",
"to-port": 8080 }
]
Create your own service definitions
You can add your own service definitions into your Policy files:
"service": {
"openvpn": { "proto": "udp", "port": 1194 }
}
Note: You can not override a "service" definition that comes from
/usr/share/awall/mandatory/services.json
Note: If you are adding the above content to a already existing file, then make sure you add ","
signs where they are needed!
Inherit services or variables
You can import a Policy into other Policy files for inheriting services or variables definitions:
"import": "myfirewall"
Specify load order
By default policies are loaded on alphabetical order.
You can change the load order with the keywords "before" and "after":
"before": "myfirewall"
"after": "someotherpolicy"
Other
Help and debugging
If you end up in some kind of trouble, you might find some commands useful when debugging:
awall # (With no parameters) Shows some basic help about awall
application
iptables -L -n # Show what's in iptables
-
Alpine Wall User's Guide
Configuration File Processing
Alpine Wall (awall) reads its configuration from multiple JSON-formatted files, called policy files. The
files located in directory /usr/share/awall/mandatory are mandatory policies shipped with APK
packages. In addition, there can be installation-specific mandatory policies in /etc/awall.
The latter directory may also contain symbolic links to policy files located in
/usr/share/awall/optional and /etc/awall/optional. These are optional policies, which can be
enabled on need basis. Such symbolic links are easily created and destroyed using the awall enable
and awall disable commands. awall list shows which optional policies are enabled and disabled.
The command also prints the description of the optional policy if defined in the file using a top-level
attribute named description.
Sometimes a policy file depends on other policy files. In this case, the policy file must have a top-level
attribute import, the value of which is a list of policy names, which correspond to the file names
without the .json suffix. The imported policies may be either optional policies or private policies,
located in /usr/share/awall/private or /etc/awall/private. By default, the policies listed there
are processed before the importing policy.
The order of the generated iptables rules generally reflects the processing order of their corresponding
awall policies. The processing order of policies can be adjusted by defining top-level attributes after
and before in policy files. These attributes are lists of policies, after or before which the declaring
policy shall be processed. Putting a policy name to either of these lists does not by itself import the
policy. The ordering directives are ignored with respect to those policies that are not enabled by the
user or imported by other policies. If not defined, after is assumed to be equal to the relative
complement of the before definition in the import definition of the policy.
As the import directive does not require the path name to be specified, awall expects policies to have
unique names, even if located in different directories. It is allowed to import optional policies that are
not explicitly enabled by the user. Such policies show up with the required status in the output of
awall list.
List Parameters
Several awall parameters are defined as lists of values. In order to facilitate manual editing of policy
files, awall also accepts single values in place of lists. Such values are semantically equivalent to lists
containing one element.
Variable Expansion
Awall allows variable definitions in policy files. The top-level attribute variable is a dictionary
containing the definitions. The value of a variable can be of any type (string, integer, list, or
dictionary).
A variable is referenced in policy files by a string which equals the variable name prepended with the $
character. If the value of the variable is a string, the reference can be embedded into a longer string in
order to substitute some part of that string (in shell style). Variable references can be used when
defining other variables, as long as the definitions are not circular.
Policy files can reference variables defined in other policy files. Policy files can also override variables
defined elsewhere by redefining them. In this case, the new definition affects all policy files, also those
processed before the overriding policy. Awall variables are in fact simple macros, since each variable
remains constant thoughout a single processing round. If multiple files define the same variable, the
definition in the file processed last takes effect.
-
If defined as an empty string, all non-embedded references to a variable evaluate as if the attribute in
question was not present in the configuration. This is also the case when a string containing embedded
variable references finally evaluates to an empty string.
Configuration Objects
Configuration objects can be divided into two main types. Auxiliary objects model high-level concepts
such as services and zones. Rule objects translate into one or more iptables rules, and are often defined
with the help of some auxiliary objects.
Services
A service represents a set of network protocols. A top-level attribute service is a dictionary that maps
service names to service definition objects, or lists thereof in more complex cases.
A service definition object contains an attribute named proto, which corresponds to the --protocol
option of iptables. The protocol can be defined as a numerical value or string as defined in
/etc/protocols. If the protocol is tcp or udp, the scope of the service definition may be constrained
by defining an attribute named port, which is a list of TCP or UDP port numbers or ranges thereof,
separated by the - character. If the protocol is icmp or icmpv6, an analogous type attribute may be
used. The replies to ICMP messages have their own type codes, which may be specified using the
reply-type attribute.
If the protocol is icmp or icmpv6, the scope of the rule is also automatically limited to IPv4 or IPv6,
respectively. There are also other services which are specific to IPv4 or IPv6. To constrain the scope of
the service definition to either protocol version, an optional family attribute can be set to value inet or
inet6, respectively.
Some services require the server or client to open additional connections to dynamically allocated ports
or even different hosts. Connection tracking helpers are used to make the firewall aware of such
additional connections. The ct-helper attribute is used to associate such a helper to a service definition
when required by the service.
All rule objects, except for policies, may have an attribute named service, constraining the rule's scope
to specific services only. This attribute is a list of service names, referring to the keys of the top-level
service dictionary.
Zones
A zone represents a set of network hosts. A top-level attribute zone is a dictionary that maps zone
names to zone objects. A zone object has an attribute named iface, addr, or both. iface is a list of
network interfaces and addr is a list of IPv4/IPv6 host and network addresses (CIDR notation). addr
may also contain domain names, which are expanded to IP addresses using DNS resolution. If not
defined, addr defaults to the entire address space and iface to all interfaces. An empty zone can be
defined by setting either addr or iface to an empty list.
Rule objects contain two attributes, in and out, which are lists of zone names. These attributes control
whether a packet matches the rule or not. If a particular zone is referenced by the in attribute, the rule
applies to packets whose ingress interface and source address are covered by the zone definition.
Correspondingly, if a zone is referenced by the out attribute, the rule applies to packets whose egress
interface and destination address are included in the zone. If both in and out are defined, the packet
must fulfill both criteria in order to match the rule.
The firewall host itself can be referred to using the special value _fw as the zone name.
By default, awall does not generate iptables rules with identical ingress and egress interfaces. This
behavior can be changed per zone by setting the optional route-back attribute of the zone to true. Note
that this attribute can have an effect also in the case where in and out attributes of a rule are not equal
-
but their definitions overlap. In this case, the route-back attribute of the out zone determines the
behavior.
Limits
A limit specifies the maximum rate for a flow of packets or new connections. Unlike the other auxiliary
objects, limits are not named members of a top-level dictionary but are embedded into other objects.
In its simplest form, a limit definition is an integer specifying the maximum number of packets or
connections per second. More complex limits are defined as objects, where the count attribute define
the maximum during an interval defined by the interval attribute. The unit of the interval attribute is
second, and the default value is 1.
The maximum rate defined by a limit may be absolute or specific to blocks of IP addresses or pairs
thereof. The number of most significant bits taken into account when mapping the source and
destination IP addresses to blocks can be specified with the mask attribute. The mask attribute is an
object with two attributes defining the prefix lengths, named src and dest. Alternatively, the mask
object may have object attributes named inet and inet6 which contain address familyspecific prefix length pairs. If mask is defined as an integer, it is interpreted as the source address prefix length.
The default value for mask depends on the type of the enclosing object. For filters, the default behavior
is to apply the limit for each source address separately. For logging classes, the limit is considered
absolute by default.
Logging Classes
A logging class specifies how packets matching certain rules are logged. A top-level attribute log is a
dictionary that maps logging class names to setting objects.
A setting object may have an attribute named mode, which specifies which logging facility to use.
Allowed values are log, nflog, and ulog. The default is log, i.e. in-kernel logging.
The following table shows the optional attributes valid for all logging modes:
Attribute Description
every Divide successive packets into groups, the size of which is specified by the value of this
attribute, and log only the first packet of each group
limit Maximum number of packets to be logged defined as limit
prefix String with which the log entries are prefixed
probability Probability for logging an individual packet (default: 1)
With the in-kernel log mode log, the level of logging may be specified using the level attribute. Log
modes nflog and ulog are about copying the packets into user space, at least partially. The following
table shows the additional attributes valid with these modes:
Attribute Description
group Netlink group to be used
range Number of bytes to be copied
threshold Number of packets to queue inside the kernel before copying them
Filter and policy rules can have an attribute named log. If it is a string, it is interpreted as a reference to
a logging class, and logging is performed according to the definitions. If the value of the log attribute is
-
true (boolean), logging is done using default settings. If the value is false (boolean), logging is
disabled for the rule. If log is not defined, logging is done using the default settings except for accept
rules, for which logging is omitted.
Default logging settings can be set by defining a logging class named _default. Normally, default
logging uses the log mode with packets limited to one per second.
Rules
There are several types of rule objects:
Filter rules Policy rules Packet Logging rules NAT rules Packet Marking rules Transparent Proxy rules MSS Clamping rules Connection Tracking Bypass rules
All rule objects can have the in and out attributes referring to zones as described in the previous
section. In addition, the scope of the rule can be further constrained with the following attributes:
Attribute Value format Effect
src Similar to addr attribute of zone
objects Packet's source address matches the value
dest Similar to addr attribute of zone
objects Packet's destination address matches the value
ipset
Object containing two attributes:
name referring to an IP set and
args, which is a list of strings in and
out
Packet matches the IP set referred here when the
match arguments are taken from the source (in) and
destination (out) address or port in the order
specified by args
ipsec in or out IPsec decapsulation perfomed on ingress (in) or
encapsulation performed on egress (out)
Rule objects are declared in type-specific top-level dictionaries in awall policy files. If a packet
matches multiple rules, the one appearing earlier in the list takes precedence. If the matching rules are
defined in different policy files, the one that was processed earlier takes precedence in the current
implementation, but this may change in future versions.
Filter Rules
Filter objects specify an action for packets fulfilling certain criteria. The top-level attribute filter is a
list of filter objects.
Filter objects must have an attribute named action, the value of which can be one of the following:
Value Action
accept Accept the packet (default)
reject Reject the packet with an ICMP error message
-
drop Silently drop the packet
tarpit
Put incoming TCP connections into persist state and ignore attempts to close them. Silently
drop non-TCP packets. (Connection tracking bypass is automatically enabled for the
matching packets.)
Filter objects, the action of which is accept, may also contain limits for packet flow or new
connections. These are specified with the flow-limit and conn-limit attributes, respectively. The values
of these attributes are limit objects. The drop action is applied to the packets exceeding the limit.
Optionally, the limit object may have an attribute named log. It defines how the dropped packets should
be logged and is semantically similar to the log attribute of rule objects.
Filter objects may have an attribute named dnat, the value of which is an IPv4 address. If defined, this
enables destination NAT for all IPv4 packets matching the rule, such that the specified address replaces
the original destination address. If also port translation is desired, the attribute may be defined as an
object consisting of attributes addr and port. The format of the port attribute is similar to that of the
to-port attribute of NAT rules. This option has no effect on IPv6 packets.
Filter objects may have a boolean attribute named no-track. If set to true, connection tracking is
bypassed for the matching packets. In addition, if action is set to accept, the corresponding packets
travelling to the reverse direction are also allowed.
If one or more connection tracking helpers are associated with the services referred to by an accept
rule, additional iptables rules are generated for the related connections detected by the helpers. The
related attribute can be used to override the default rules generated by awall. It is a list of basic rule
objects, the packets matching to which are accepted, provided that they are also detected by at least one
of the helpers.
Policy Rules
Policy objects describe the default action for packets that did not match any filter. The top-level
attribute policy is a list of policy objects.
Policy objects must have the action attribute defined. The possible values and their semantics are the
same as in filter rules.
Packet Logging Rules
Packet logging rules allow packets matching the specified criteria to be logged before any filtering
takes place. Such rules are contained in the top-level list named packet-log.
Logging class may be specified using the log attribute. Otherwise, default logging settings are used.
NAT Rules
NAT rules come in two flavors: source NAT rules and destination NAT rules. These are contained in
two top-level lists named snat and dnat, respectively.
Each NAT rule may have an attribute named to-addr that specifies the IPv4 address range to which the
original source or destination address is mapped. The value can be a single IPv4 address or a range
specified by two addresses, separated with the - character. If not defined, it defaults to the primary
address of the ingress interface in case of destination NAT, or that of the egress interface in case of
source NAT.
Optionally, a NAT rule can specify the TCP and UDP port range to which the original source or
destination port is mapped. The attribute is named to-port, and the value can be a single port number or
-
a range specified by two numbers, separated with the - character. If to-port is not specified, the original
port number is kept intact.
NAT rules, may have an action attribute set to value include or exclude. The latter means that NAT is
not performed on the matching packets (unless they match an include rule processed earlier). The
default value is include.
Packet Marking Rules
Packet marking rules are used to mark incoming packets matching the specified criteria. The mark can
be used as a basis for the routing decision. Each marking rule must specify the mark using the mark
attribute, which is a 32-bit integer.
Normal marking rules are contained by the top-level list attribute named mark.
There is another top-level list attribute, named route-track, which contains route tracking rules. These
are special marking rules which cause all the subsequent packets related to the same connection to be
marked according to the rule.
Transparent Proxy Rules
Transparent proxy rules divert the matching packets to a local proxy process without altering their
headers. Such rules are contained in the top-level list named tproxy.
In addition to the firewall configuration, using a transparent proxy requires a routing configuration
where packets marked for proxying are diverted to a local process. The awall_tproxy_mark variable
can be used to specify the mark for such packets, which defaults to 1.
Proxy rules may also have an attribute named to-port for specifying the TCP or UDP port of the proxy
if it is different from the original destination port.
MSS Clamping Rules
MSS Clamping Rules are used to deal with ISPs that block ICMP Fragmentation Needed or ICMPv6
Packet Too Big packets. An MSS clamping rule overwrites the MSS option with a value specified with
the mss attribute for the matching TCP connections. If mss is not specified, a suitable value is
automatically determined from the path MTU. The MSS clamping rules are located in the top-level
dictionary named clamp-mss.
Connection Tracking Bypass Rules
Connection tracking bypass rules are used to disable connection tracking for packets matching the
specified criteria. The top-level attribute no-track is a list of such rules.
Like NAT rules, connection tracking bypass rules may have an action attribute set to value include or
exclude.
IP Sets
Any IP set referenced by rule objects should be created by awall. Auxiliary IP set objects are used to
defined them in awall policy files. The top-level attribute ipset is a dictionary, the keys of which are IP
set names. The values are IP set objects, which have two mandatory attributes. The attribute named
type corresponds to the type argument of the ipset create command. family specifies whether the
set is for IPv4 or IPv6 addresses, and the possible values are inet and inet6, correspondingly.
For bitmap-type IP sets, the range attribute specifies the range of allowed IPv4 addresses. It may be
given as a network address or two addresses separated by the - character. It is not necessary to specify
family for bitmaps, since the kernel supports only IPv4 bitmaps.
-
Command Line Syntax
Translating Policy Files to Firewall Configuration Files awall translate [-o|--output DIRECTORY] [-V|--verify]
The --verify option makes awall verify the configuration using the test mode of iptables-restore
before overwriting the old files.
Specifying the output directory allows testing awall policies without overwriting the current iptables
and ipset configuration files. By default, awall generates the configuration to /etc/iptables and
/etc/ipset.d, which are read by the init scripts.
Run-Time Configuration of Firewall awall activate [-f|--force]
This command genereates firewall configuration from the policy files and enables it. If the user
confirms the new configuration by hitting the Return key within 10 seconds or the --force option is
used, the configuration is saved to the files. Otherwise, the old configuration is restored.
There is also a command for deleting all firewall rules:
awall flush
This command configures the firewall to drop all packets.
Optional Policies
Optional policies can be enabled or disabled using this command:
awall {enable|disable} POLICY...
Optional policies can be listed using this command:
awall list
The enabled status means that the policy has been enabled by the user. The disabled status means that
the policy is not in use. The required status means that the policy has not been enabled by the user but
is in use because it is required by another policy which is in use.
Debugging Policies
This command can be used to dump variable, zone, and other definitions as well as their source
policies:
awall dump [LEVEL]
The level is an integer in range 05 and defaults to 0. More information is displayed on higher levels.
PXE boot
Guide to options ip
Required for PXE.
Set ip=dhcp to get an IP via DHCP. (Requires af_packet.ko in the initrd, in addition to the
modules needed for your NIC.)
-
Set ip=client-ip::gateway-ip:netmask::[device]: to specify an IP manually. device is a
device name (e.g. eth0). If one is not specified, one is chosen automatically.
apkovl
Valid forms include:
An HTTP, HTTPS or FTP URL to an apkovl.tar.gz file which will be retrieved and applied.
device_name[:fs_type]:path, where device_name does not include /dev (e.g., sda). fs_type is optional (e.g. ext4). path expresses the path on the device to the apkovl.tar.gz file.
A relative path, interpreted relative to the root of the alpine_dev. If not specified, a file matching *.apkovl.tar.gz is searched for in the root of the
ovl_dev. (If more than one exists in the root of a device, all are ignored.)
alpine_dev
Required.
The alpine_dev specifies a device used for reference data which must reside on a
filesystem; currently, this is only the case for kernel modules.
This is also used to obtain APKs if a repository is not explicitly specified; see below.
Valid forms include:
A device name, not including /dev/. UUID=filesystem-uuid LABEL=filesystem-label nfs:ip-address:path, specifying an NFS export to use as the device. You may need
to add modules to the initrd.
ovl_dev
Valid forms include:
device_name[:fs_type] If not specified, various devices are searched for a file matching *.apkovl.tar.gz in
the root directory.
This argument can contain the fields {MAC} and {UUID}, which will be substituted with the
MAC address of the NIC used by Alpine and the system's DMI "Product UUID" respectively. If
these substitutions are used, the value passed to ovl_dev must be enclosed in quotes. e.g.
ovl_dev="http://.../{MAC}.apkovl.tar.gz".
alpine_repo
If set, /etc/apk/repositories will be filled with this. May be an URL. Otherwise, try and
find a directory containing the marker file .boot_repository on the alpine_dev.
modloop
if the specified file is of http/ftp or https (if wget is installed), the modloop file will be
downloaded to the /lib directory and will be mounted afterwards
ie modloop=http://192.168.1.1/pxe/alpine/grsec.modloop.squashfs in the append section of
your bootloader
-
HOWTO
Alpine can be PXE booted starting with Alpine 2.6-rc2. In order to accomplish this you must complete
the following steps:
Set up a DHCP server and configure it to support PXE boot. Set up a TFTP server to serve the PXE bootloader. Set up an HTTP server to serve the rest of the boot files. Set up an NFS server from which Alpine can load kernel modules. Configure mkinitfs to generate a PXE-bootable initrd.
This article describes a setup using gpxe as a PXE bootloader, but you could also use PXELINUX.
Standard setup of all involved services is not covered here; advice on setting up basic
DHCP/TFTP/HTTP/NFS/etc. is widely available.
Set up a DHCP server and configure it to support PXE boot
If you use the ISC DHCP server (package "dhcp"), amend your subnet block like so:
next-server 10.0.0.1;
filename "gpxe.kpxe";
Set up a TFTP server to serve the PXE bootloader
Install a TFTP server (package "tftp-hpa"). You will need to place a gPXE image at
/var/tftproot/gpxe.kpxe. You can generate an image online at ROM-o-matic.net. Select the
".kpxe" output format and the "undionly" driver. You will need to specify a custom boot script. Select
"Customize". The following boot script works well:
dhcp net0
chain http://${net0/next-server}/gpxe-script
You can include ${net0/mac} and ${uuid} in the URL for the interface MAC address and machine
UUID respectively.
Note that as of writing, ROM-o-matic appears to produce a buggy image unless it is used with the
"undionly" driver. If you require a different driver, consider building gPXE yourself, especially if you
experience inexplicable connectivity issues. Common symptoms are a seemingly correctly configured,
randomly functional network connection which appears to suffer from extreme packet loss.
Set up an HTTP server to serve the rest of the PXE boot files
Suppose you have an HTTP server configured to serve from /srv/http. Place an appropriate gPXE
script, such as the following, at /srv/http/prov/gpxe-script:
#!gpxe
kernel http://${net0/next-server}/prov/grsec ip=dhcp alpine_dev=nfs:${net0/next-
server}:/srv/nfs/depot alpine_repo=http://nl.alpinelinux.org/alpine/v2.5/main/
initrd http://${net0/next-server}/prov/pxerd
boot
ip=dhcp instructs the initrd to obtain an IP via DHCP. The NFS share specified by alpine_dev will be
mounted. alpine_repo specifies an apk repository to use.
Using lpxelinux instead of gPXE
-
Since recent version of syslinux, pxelinux also has support to boot over ftp/http.
The pxelinux.cfg/default file (or specific MAC address file name) should be in the same format as with
regular syslinux.
You will need to use a copy of the lpxelinux.0 found when installing syslinux on alpine:
/usr/share/syslinux/lpxelinux.0 and copy it to your tftp server.
Don't forget to also copy ldlinux.c32, as its a dependency of syslinux variants (see documentation).
DEFAULT alpine
LINUX http://ipaddr/grsec
INITRD http://ipaddr/grsec.gz
APPEND ip=dhcp modules=loop,squashfs,sd-mod,usb-storage alpine_repo=http://repo-url
modloop=http://ipaddr/grsec.modloop.squashfs
apkovl=http://ipaddr/localhost.apkovl.tar.gz
Using pxelinux instead of gPXE
Since recent version of syslinux, pxelinux also has support to boot over tftp.
The pxelinux.cfg/default file (or specific MAC address file name) should be in the same format as with
regular syslinux.
You will need to use a copy of the pxelinux.0 found when installing syslinux on alpine:
/usr/share/syslinux/pxelinux.0 and copy it to your tftp server.
Don't forget to also copy ldlinux.c32, as its a dependency of syslinux variants (see documentation).
PROMPT 0
TIMEOUT 3
default alpine
LABEL alpine
LINUX alpine-vmlinuz-grsec
INITRD alpine-pxerd
APPEND ip=dhcp alpine_dev=nfs:192.168.1.1:/srv/boot/alpine
modloop=http://192.168.1.1/modloop-grsec nomodeset quiet
apkovl=http://192.168.1.1/localhost.apkovl.tar.gz
vmlinuz-grsec is taken from a system running in memory from usb.
pxerd is generated on a system running in memory from usb. With network nfs and virtio_net added.
/srv/boot/alpine is a copy of /media/usb from a system running in memory from usb.
modules=loop,squashfs,sd-mod,usb-storage is not needed as loop and squashfs are hard coded into the
init script and we do not use sd nor usb.
modloop=http://ipaddr/grsec.modloop.squashfs does not seems to work. Without neither...(*)
apkovl=http://ipaddr/localhost.apkovl.tar.gz.
(*) about the modloop problem: /etc/init.d/modloop tries to load the file from /media/nfs instead of
/media/alpine and starts trying to mount it! (unsuccessfully) A fix to it is (a proposal) see
http://bugs.alpinelinux.org/issues/4015
Set up an NFS server from which Alpine can load kernel
modules
NOTE: by adding modloop with http support, this is no need for modules.
Set up an NFS share at /srv/nfs/depot and export it via /etc/exports:
/srv/nfs/depot *(ro,no_root_squash,no_subtree_check)
This export does not currently need to contain anything, unless you wish to use it to serve apks, in
which case ensure that a file ".boot_repository" is created in the directory containing architecture
subdirectories and remove alpine_repo from the kernel arguments. The repository will be autodetected
by searching for ".boot_repository". Eventually Alpine will be able to load kernel modules from this
export.
-
Configure mkinitfs to generate a PXE-bootable initrd
NOTE: There is currently a mkinitfs profile just for networking called: network. Using it will
automatically add pxe support and all ethernet drivers to the initramfs.
You need to add drivers for any Ethernet cards with which you might PXE boot to your initrd. To do
this, create /etc/mkinitfs/features.d/network.modules. List any kernel drivers you require for
your Ethernet card. If you are using an Intel E1000 card (this is used by VMware and VirtualBox, and
so is good for testing), add
kernel/drivers/net/ethernet/intel/e1000/*.ko
You also must create the following files so that the modules and scripts necessary for DHCP and NFS
are inserted into the initrd.
/etc/mkinitfs/features.d/dhcp.files, containing:
/usr/share/udhcpc/default.script
/etc/mkinitfs/features.d/dhcp.modules, containing:
kernel/net/packet/af_packet.ko
/etc/mkinitfs/features.d/nfs.modules, containing:
kernel/fs/nfs/*
Finally edit /etc/mkinitfs/mkinitfs.conf and add features squashfs, network, dhcp and nfs.
Generate a PXE-capable initrd by running
mkinitfs -o /srv/http/prov/pxerd
You should now be able to PXE-boot Alpine Linux. This feature is still in development and non-fatal
post-initrd boot errors (regarding modloop, etc.) are to be expected.
Specifying an apkovl
If you wish to specify an apkovl, simply add
apkovl=http://..../file.apkovl.tar.gz
to the kernel arguments. {MAC} and {UUID} in this parameter will be substituted with the MAC
address of the boot interface and the machine UUID respectively. If you use these parameters, ensure
you place the URL in quotes.
You can also use ovl_dev= if you want to obtain an apkovl from a device. Use either apkovl or
ovl_dev, not both.
Using serial modem
Install packages
Install required packages
apk add ppp
Load modules
Load some needed modules and make sure they get automatically loaded at next reboot
-
modprobe ppp
echo "ppp" >> /etc/modules
Configfiles
/etc/ppp/peers/serialmodem
(The filename 'serialmodem' can be changed to whatever is appropriate for you, but you will need to
remember it when running pon/poff command)
debug
/dev/ttyS0
115200
modem
crtscts
asyncmap 0
defaultroute
lock
noauth
user '{login_id}'
connect '/usr/sbin/chat -v -f /etc/ppp/chat-serialmodem'
/etc/ppp/chat-serialmodem
(The filename 'chat-serialmodem' can be changed to whatever is appropriate for you, but you will need
modify above configfile to reflect your decition)
ABORT 'BUSY'
ABORT 'ERROR'
ABORT 'NO ANSWER'
ABORT 'NO CARRIER'
ABORT 'NO DIALTONE'
ABORT 'Invalid Login'
ABORT 'Login incorrect'
REPORT 'CONNECT'
TIMEOUT '60'
'' 'ATZ'
OK 'ATDT{phonenumber}'
CONNECT '\d\c'
Username: '{login_id}'
Password: '{your_password}'
/etc/ppp/pap-secrets
When you look at the logs and see pppd report something like this:
daemon.debug pppd[5665]: rcvd [LCP ConfReq id=0xf6
]
(Note the "" section)
Then you might need to use pap-secrets file (or chap-secrets depending on what pppd reports in the
logs).
You file might in this case look something like this
# client server secret IP addresses
{login_id} * {your_password} *
If you are using 'pap-secrets' (or 'chat-secrets') you should most likely comment out 'Username:' and
'Password:' lines in your '/etc/ppp/chat-serialmodem' config.
-
Note for above example configs
Note: Replace above words {login_id}, {your_password} and {phonenumber} with what you
received from your ISP. The characters { and } should also be removed.
Note: You might need to replace the 'Username:' and 'Password:' parts to reflect the words your
ISP is using to ask you to enter your credentials
Tip: You might need to replace "CONNECT '\d\c'" with "CONNECT 'CLIENT'" in your chat-
serialmodem config
References:
http://axion.physics.ubc.ca/ppp-linux.html http://www.yolinux.com/TUTORIALS/LinuxTutorialPPP.html http://www.linux.org/docs/ldp/howto/PPP-HOWTO/options.html
Start/Stop
Start connection
pon serialmodem
Stop connection
poff serialmodem
If something goes wrong...
Check if process is running
pidof pppd
Logfile might give you a clue on what went wrong
egrep "pppd|chat" /var/log/messages
Check nic information
ifconfig ppp0
pppd has a statusinformation function that could come in handy
pppstats
-
Using HSDPA modem
Install packages
Install required packages
apk add ppp
Load modules
Now let's load the driver (using the values you just found out) and prepare it to get automatically loaded
at next reboot.
modprobe ppp
echo "ppp" >> /etc/modules
Configfiles
/etc/ppp/peers/E220
(The filename 'E220' can be changed to whatever is appropreate for you, but you will need to
remember it when running pon/poff command)
debug
/dev/ttyUSB0
460800
crtscts
modem
noauth
usepeerdns
defaultroute
noipdefault
noccp
nobsdcomp
novj
connect '/usr/sbin/chat -v -f /etc/ppp/chat-E220-pin || /usr/sbin/chat -f
/etc/ppp/chat-E220-nopin'
/etc/ppp/chat-E220-pin
(The filename 'chat-E220-pin' can be changed to whatever is appropreate for you, but you will need
modify above configfile to reflect your decition)
ABORT "BUSY"
ABORT "ERROR"
ABORT "NO CARRIER"
REPORT "CONNECT"
TIMEOUT "10"
"" "ATZ"
OK "AT+CPIN={PIN}"
OK AT+CGDCONT=1,"ip","{APN}"
OK "ATE1V1&D2&C1S0=0+IFC=2,2"
OK "AT+IPR=115200"
OK "ATE1"
TIMEOUT "60"
"" "ATD*99***1#"
CONNECT \c
-
/etc/ppp/chat-E220-nopin
(The filename 'chat-E220-nopin' can be changed to whatever is appropreate for you, but you will need
modify above configfile to reflect your decition)
ABORT "BUSY"
ABORT "ERROR"
ABORT "NO CARRIER"
REPORT "CONNECT"
TIMEOUT "10"
"" "ATZ"
OK AT+CGDCONT=1,"ip","{APN}"
OK "ATE1V1&D2&C1S0=0+IFC=2,2"
OK "AT+IPR=115200"
OK "ATE1"
TIMEOUT "60"
"" "ATD*99***1#"
CONNECT \c
Note: Replace above word {PIN} with the "PIN" of your card (typically a 4 digit code)
Note: Replace above word {APN} with the "Access Point Name" of the service you use (for instance
mine is "web.omnitel.it"). If you don't know the Internet APN, ask your service provider
Routes
Create a default gw route to your 'ppp0' device.
ip route add default dev ppp0
DNS
Figure out what DNS-servers your provider has.
egrep -i 'pppd.*dns' /var/log/messages
This might give you some useful information.
Search for a IP-address that might be your providers DNS-server and add this IP-address into
'/etc/resolv.conf'.
echo "nameserver {DNS-server-IP-address}" > /etc/resolv.conf
Start/Stop
Start connection
pon E220
Stop connection
-
poff E220
If something goes wrong...
Check if process is running
pidof pppd
Logfile might give you a clue on what went wrong
egrep "pppd|chat" /var/log/messages
Check nic information
ifconfig ppp0
pppd has a statusinformation function that could come in handy
pppstats
Huawei E378
Tested on Alpine 2.3.3.
Add usb-modeswitch (currently only in testing repo):
apk add usb-modeswitch
/etc/modules:
usbserial vendor=0x12d1 product=0x1446
/etc/usb_modeswitch.conf:
# Configuration for the usb_modeswitch package, a mode switching tool for
# USB devices providing multiple states or modes
#
# This file is evaluated by the wrapper script "usb_modeswitch_dispatcher"
# in /usr/sbin
# To enable an option, set it to "1", "yes" or "true" (case doesn't matter)
# Everything else counts as "disable"
# Disable automatic mode switching globally (e.g. to access the original
# install storage)
DisableSwitching=0
# Enable logging (results in a extensive report file in /var/log, named
# "usb_modeswitch_" (and probably others)
EnableLogging=1
-
DefaultVendor=0x12d1
DefaultProduct=0x1446
TargetVendor=0x12d1
TargetProduct=0x14ac
MessageContent="55534243000000000000000000000011060000000000000000000000000000"
CheckSuccess=5
/etc/network/interfaces
auto ppp0
iface ppp0 inet ppp
provider E378
pre-up usb_modeswitch -c /etc/usb_modeswitch.conf
/etc/ppp/peers/E378:
debug
/dev/ttyUSB0
460800
crtscts
modem
noauth
usepeerdns
defaultroute
noipdefault
noccp
nobsdcomp
novj
connect '/usr/sbin/chat -v -f /etc/ppp/peers/chat-E378-nopin'
/etc/ppp/peers/chat-E378-nopin:
ABORT "BUSY"
ABORT "ERROR"
ABORT "NO CARRIER"
REPORT "CONNECT"
TIMEOUT "10"
"" "ATZ"
OK AT+CGDCONT=1,"ip","isp.telus.com"
OK AT+CGQREQ=1,2,4,3,6,31
OK AT+CGQMIN=1,2,4,3,6,31
OK AT+CGATT=1
OK ATD*99#
CONNECT \c
Novatel MC679
Tested on Alpine 2.4.5.
Add usb-modeswitch (currently only in testing repo):
apk add usb-modeswitch
/etc/modules:
usbserial vendor=0x1410 product=0x7042
-
/etc/usb_modeswitch.conf:
# Configuration for the usb_modeswitch package, a mode switching tool for
# USB devices providing multiple states or modes
#
# This file is evaluated by the wrapper script "usb_modeswitch_dispatcher"
# in /usr/sbin
# To enable an option, set it to "1", "yes" or "true" (case doesn't matter)
# Everything else counts as "disable"
# Disable automatic mode switching globally (e.g. to access the original
# install storage)
DisableSwitching=0
# Enable logging (results in a extensive report file in /var/log, named
# "usb_modeswitch_" (and probably others)
EnableLogging=1
DefaultVendor= 0x1410
DefaultProduct=0x5059
TargetVendor= 0x1410
TargetProduct= 0x7042
MessageContent="5553424312345678000000000000061b000000020000000000000000000000"
NeedResponse=1
/etc/network/interfaces
auto ppp0
iface ppp0 inet ppp
provider MC679
pre-up usb_modeswitch -c /etc/usb_modeswitch.conf || true
/etc/ppp/peers/MC679:
debug
/dev/ttyUSB0
460800
crtscts
modem
noauth
usepeerdns
defaultroute
noipdefault
noccp
nobsdcomp
novj
connect '/usr/sbin/chat -v -f /etc/ppp/peers/chat-MC679-nopin'
/etc/ppp/peers/chat-MC679-nopin:
ABORT "BUSY"
ABORT "ERROR"
ABORT "NO CARRIER"
REPORT "CONNECT"
TIMEOUT "10"
"" "ATZ"
OK ATD*99#
CONNECT \c
-
Setting up a ssh-server If you need to administer a Alpine Linux box, you can install and use openssh. Openssh is used to
provide a secure encrypted communications between you and the host where openssh is running (the
ssh-server is called sshd and the ssh-client is called ssh).
Installation
Install package:
apk add openssh
Note: If you want the ACF-frontend for openssh, you should install 'acf-openssh' instead (assuming
that you have setup-acf)
Make it autostart
Next time you reboot your Linux box, you would probably want your sshd to automatically start.
rc-update add sshd
You can check your boot services:
rc-status
Start it up now
The reason we want to manually start sshd at this moment is that we want sshd to create some initial
files that he needs. After they are created, we can permanently save them.
Next reason is... we don't have time to wait for the box to reboot ;-)
/etc/init.d/sshd start
Note: Don't forget to permanently save your settings by using the 'lbu ci' command when you are
done.
Fine tuning
The default config that comes with openssh has pretty good default values.
But sometimes you would like to fine-tune things. We show some examples below on what you might
want to do.
-
Note: You are _not_ required to follow this #Fine_tuning section. You can skip it if you want to
make things easy!
The fine-tuning is done by editing /etc/ssh/sshd_config
"#" marks that the rest of the line should be ignored by sshd. Everything right to the "#" is treated as
comments.
UseDNS no # By setting this to no, you could increase speed when the client
starts to connect to this ssh-server
PasswordAuthentication no # Instead you could use private/public keys to
authenticate to this box (this increases security for the box)
Many other options are found in /etc/ssh/sshd_config. The describing text that comes in the same file
will guide you in your fine-tuning.
Firewalling
As default, sshd will communicate on port '22' using protocol 'TCP'.
You would need to make sure that the box where sshd is running, doesn't block your connection
attempts on 22TCP.
If you still have trouble accessing your box, make sure that there is no other firewall blocking your
connection.
Sometimes 22TCP is blocked by some firewall that you can not control. In those cases you might want
to configure sshd to communicate on some other port.
In that case you change /etc/ssh/sshd_config to reflect your needs.
But before you do so, you need to check so you don't use a port that already is in use. (You can check
this by using the command 'netstat -ln' on the box where you plan to run sshd)
Port 443 # Use whatever port number that fits your needs
You need to restart sshd after you done you modifications.
/etc/init.d/sshd restart
Save settings
If you already haven't done so, save all your settings
lbu ci
Alternative: Dropbear
Alternatively you can use Dropbear. Install it through the Alpine setup scripts, or manually with:
apk add dropbear
Start it:
-
rc-service dropbear start
And if you are happy with it, add it to the default runlevel:
rc-update add dropbear
Use the following command to check all available server options:
dropbear -h
The config file is located at /etc/conf.d/dropbear
dropbear also includes an SSH client which in its simplest form can be used like this:
dbclient x.x.x.x
(where x.x.x.x is the destination server). Use dbclient -h to see all available options.
How to setup a wireless access point
Install needed packages
apk add hostapd wireless-tools wpa_supplicant
Check that card is detected
Cat /proc/net/dev and see which cards are detected. If no cards are available, check what driver the card
uses and modprobe it. Check that the card is in master mode.
Setup Bridge
Please see Bridge for how to set up network bridges.
Setup Encryption
Edit /etc/hostapd/hostapd.wpa_psk and insert the following, replacing PASSPHRASE with the
WPA_PSK key you would like to use (remove keys that you don't want to use):
00:00:00:00:00:00 PASSPHRASE
Setup hostapd
Edit /etc/hostapd/hostapd.conf and replace entries that need to be such as interface, bridge, driver, ssid,
etc. Example file below:
-
interface=wlan0
bridge=br0
driver=hostap
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
debug=0
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=SecureSSID
#macaddr_acl=1
#accept_mac_file=/etc/hostapd/accept
auth_algs=3
eapol_key_index_workaround=0
eap_server=0
wpa=3
wpa_psk_file=/etc/hostapd/hostapd.wpa_psk
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
If you wish to use MAC address filtering, uncomment the lines starting with macaddr_acl and
accept_mac_file, create /etc/hostapd/accept (with 600 permissions) and add the allowed clients' MAC
address to the file.
Start hostapd.
/etc/init.d/hostapd start
Associate clients
Associate a few different clients to test.
Setting up a OpenVPN server This article describes how to set up an OpenVPN server with the Alpine Linux. This is an ideal
solution for allowing single users or devices to remotely connect to your network. To establish
connectivity with a Remote Office or site, Racoon/Opennhrp would provide better functionality.
It is recommended that you have a publicly routable static IP address in order for this to work. This
means that your IP address cannot be in the private IP address ranges described here: WikiPedia
If your Internet-connected machine doesn't have a static IP address, DynDNS can be used for resolving
DNS names to IP addresses.
Setup Alpine
Initial Setup
Follow Installing_Alpine to setup Alpine Linux.
Install programs
Install openvpn
apk add openvpn
-
Prepare autostart of OpenVPN
rc-update add openvpn default
modprobe tun
echo "tun" >>/etc/modules
Certificates
One of the first things that needs to be done is to make sure that you have secure keys to work with.
Alpine makes this easy by having a web interface to manage the certificates. Documentation for it can
be found here: Generating_SSL_certs_with_ACF. It is a best practice not to have your certificate server
be on the same machine as the router being used for remote connectivity.
You will need to create a server (ssl_server_cert) certificate for the server and one client
(ssl_client_cert) for each client. To use the certificates, you should download the .pfx file and extract it.
To extract the three parts of each .pfx file, use the following commands:
To get the ca cert out...
openssl pkcs12 -in PFXFILE -cacerts -nokeys -out ca.pem
To get the cert file out...
openssl pkcs12 -in PFXFILE -nokeys -clcerts -out cert.pem
To get the private key file out. Make sure this stays private.
openssl pkcs12 -in PFXFILE -nocerts -nodes -out key.pem
On the VPN server, you can also install the acf-openvpn package, which contains a web page to
automatically upload and extract the server certificate. There is also a button to automatically generate
the Diffie Hellman parameters.
If you would prefer to generate your certificates using OpenVPN utilities, see #Alternative Certificate
Method
Configure OpenVPN server
Example configuration file for server. Place the following content in /etc/openvpn/openvpn.conf:
local "Public Ip address"
port 1194
proto udp
dev tun
ca openvpn_certs/server-ca.pem
cert openvpn_certs/server-cert.pem
dh openvpn_certs/dh1024.pem #to generate by hand #openssl dhparam -out dh1024.pem
1024
-
server 10.0.0.0 255.255.255.0
ifconfig-po